Roxen.git / server / modules / graphics / graphic_text.pike

version» Context lines:

Roxen.git/server/modules/graphics/graphic_text.pike:1: - constant cvs_version="$Id: graphic_text.pike,v 1.144 1998/08/18 10:52:43 neotron Exp $"; + constant cvs_version="$Id: graphic_text.pike,v 1.145 1998/08/20 07:39:28 per Exp $";   constant thread_safe=1;      #include <module.h>   #include <stat.h>   inherit "module";   inherit "roxenlib";      #ifndef VAR_MORE   #define VAR_MORE 0   #endif /* VAR_MORE */
Roxen.git/server/modules/graphics/graphic_text.pike:49:    "The gtext tag saves images when they are calculated in this "    "directory.");       defvar("cache_age", 48, "Cache max age",       TYPE_INT,       "If the images in the cache have not been accessed for this "    "number of hours they are removed.");    -  defvar("speedy", 0, "Avoid automatic detection of document colors in tables", -  TYPE_FLAG|VAR_MORE, -  "If this flag is set, the tags 'table', 'th', 'tr', 'td', 'font'" -  " 'layer' and 'ilayer'" -  " will <b>not</b> be parsed to automatically detect the colors of" -  " a document. You will then have to specify all colors in all calls" -  " to &lt;gtext&gt; or in the 'body' tag"); +     -  defvar("nobody", 0, "Avoid automatic detection of document colors from body", -  TYPE_FLAG|VAR_MORE, -  "If this flag is set, the 'body' tag" -  " will <b>not</b> be parsed to automatically detect the colors of " -  " a document. You will then have to specify all colors in all calls " -  " to &lt;gtext&gt;"); +  defvar("colorparsing", ({"body", "td", "layer", "ilayer", "table"}), +  "Tags to parse for color", +  TYPE_STRING_LIST, +  "Which tags should be parsed for document colors? " +  "This will affect documents without gtext as well as documents " +  "with it, the parsing time is relative to the number of parsed " +  "tags in a document. You have to reload this module or restart " +  "roxen for changes of this variable to take effect.");    -  +  defvar("colormode", 1, "Normalize colors in parsed tags", TYPE_FLAG, +  "If set, replace 'roxen' colors (@c,m,y,k etc) with " +  "'netscape' colors (#rrggbb). Setting this to off will make the " +  "performance impact of the 'Tags to parse for color' option quite" +  " dramatically. You can try this out with the &lt;gauge&gt; tag."); +  + // defvar("notspeedy", 0, "Automaticaly detect colors in tables", + // TYPE_FLAG, + // "If this flag is set, the tags 'table', 'th', 'tr', 'td', 'font'" + // " 'layer' and 'ilayer'" + // " will be parsed to automatically detect the colors of" + // " a document. This will slow down the parser in a noticeable way, " + // "but it will be easier to use &lt;gtext&gt; since the colors " + // "will almost always have the correct default values"); +  + // defvar("body", 1, "Automatically detect colors in the &lt;body&gt; tag", + // TYPE_FLAG, + // "If this flag is not set, the 'body' tag" + // " will <b>not</b> be parsed to automatically detect the colors of " + // " a document. You will then have to specify all colors in all calls " + // " to &lt;gtext&gt;"); +     defvar("deflen", 300, "Default maximum text-length", TYPE_INT|VAR_MORE,    "The module will, per default, not try to render texts "    "longer than this. This is a safeguard for things like "    "&lt;gh1&gt;&lt;/gh&gt;, which would otherwise parse the"    " whole document. This can be overrided with maxlen=... in the "    "tag.");       defvar("location", "/gtext/", "Mountpoint", TYPE_LOCATION|VAR_MORE,    "The URL-prefix for the graphic characters.");   
Roxen.git/server/modules/graphics/graphic_text.pike:133:    catch    {    if(justification=="right") fnt->right();    if(justification=="center") fnt->center();    if(xs)fnt->set_x_spacing((100.0+(float)xs)/100.0);    if(ys)fnt->set_y_spacing((100.0+(float)ys)/100.0);    };    return fnt;   }    - static private mapping (int:mapping(string:mixed)) cached_args = ([ ]); + static private mapping cached_args = ([ ]);      #define MAX(a,b) ((a)<(b)?(b):(a))      #if !efun(make_matrix)   static private mapping (int:array(array(int))) matrixes = ([]);   array (array(int)) make_matrix(int size)   {    if(matrixes[size]) return matrixes[size];    array res;    int i;
Roxen.git/server/modules/graphics/graphic_text.pike:741:            constant nbsp = iso88591["&nbsp;"];      constant replace_from = indices( iso88591 )+ ({"&ss;","&lt;","&gt;","&amp",});   constant replace_to = values( iso88591 ) + ({ nbsp, "<", ">", "&", });      #define simplify_text( from ) replace(from,replace_from,replace_to)    + #define CACHE_SIZE 2048 +    #define FNAME(a,b) (query("cache_dir")+sprintf("%x",hash(reverse(a[6..])))+sprintf("%x",hash(b))+sprintf("%x",hash(reverse(b-" ")))+sprintf("%x",hash(b[12..])))      array get_cache_file(string a, string b)   {    object fd = open(FNAME(a,b), "r");    if(!fd) return 0;    array r = decode_value(fd->read());    if(r[0]==a && r[1]==b) return r[2];   }   
Roxen.git/server/modules/graphics/graphic_text.pike:835:    else nspace=" ";    }    res+="\n";    }    text = replace(res[..strlen(res)-2], ({ "!","?",": " }), ({ nbsp+"!",nbsp+"?",nbsp+": " }));    text = replace(replace(replace(text,({". ",". "+nbsp}), ({"\000","\001"})),".","."+nbsp+nbsp),({"\000","\001"}),({". ","."+nbsp}));    }      // cache_set(key, text, "rendering");    - #if efun(get_font) +     if(args->nfont)    {    int bold, italic;    if(args->bold) bold=1;    if(args->light) bold=-1;    if(args->italic) italic=1;    if(args->black) bold=2;    data = get_font(args->nfont,(int)args->font_size||32,bold,italic,    lower_case(args->talign||"left"),    (float)(int)args->xpad, (float)(int)args->ypad);    }    else if(args->font)    { - #endif -  string fkey = args->font+"/"+args->talign+"/"+args->xpad+"/"+args->ypad; - // data = cache_lookup("fonts", fkey); - // if(!data) - // { +  int bold, italic; +  if(args->bold) bold=1; +  if(args->light) bold=-1; +  if(args->italic) italic=1; +  if(args->black) bold=2; +  data = get_font(args->nfont,(int)args->font_size||32,bold,italic, +  lower_case(args->talign||"left"), +  (float)(int)args->xpad, (float)(int)args->ypad); +  if(!data)    data = load_font(args->font, lower_case(args->talign||"left"),    (int)args->xpad,(int)args->ypad); - // cache_set("fonts", fkey, data); - // } - #if efun(get_font) +     } else {    int bold, italic;    if(args->bold) bold=1;    if(args->light) bold=-1;    if(args->italic) italic=1;    if(args->black) bold=2;    data = get_font(roxen->QUERY(default_font),32,bold,italic,    lower_case(args->talign||"left"),    (float)(int)args->xpad, (float)(int)args->ypad);    } - #endif +        if (!data) {    roxen_perror("gtext: No font!\n");   // werror("no font found! < "+_args+" <"+text+">\n");   // cache_set(key, orig_text, 0);    return(0);    }       // Fonts and such are now initialized.    img = make_text_image(args,data,text,id);
Roxen.git/server/modules/graphics/graphic_text.pike:1045:    break;    default:    res += sprintf("%%%02x", in[i]);    }    if(strlen(res) < strlen(option)) return url_cache[in]=res;    return url_cache[in]=option;   }      #define ARGHASH query("cache_dir")+"ARGS_"+hash(mc->name)    + int last_argstat; +    void restore_cached_args()   {    args_restored = 1; -  +  array a = file_stat(ARGHASH); +  if(a && (a[ST_MTIME] > last_argstat)) +  { +  last_argstat = a[ST_MTIME];    object o = open(ARGHASH, "r");    if(o)    {    string data = o->read();    catch {    object q;    if(sizeof(indices(q=Gz)))    data=q->inflate()->inflate(data);    };    catch {    cached_args |= decode_value(data);    };    }    if (cached_args && sizeof(cached_args)) {    number = sort(indices(cached_args))[-1]+1;    } else {    cached_args = ([]);    number = 0;    }    } -  + }      void save_cached_args()   {    int on;    on = number;    if(!args_restored) restore_cached_args();    if(on > number) number=on;    object o = open(ARGHASH, "wct");   #ifndef __NT__   #if efun(chmod)
Roxen.git/server/modules/graphics/graphic_text.pike:1095:    if(sizeof(indices(q=Gz)))    data=q->deflate()->deflate(data);    };    o->write(data);   }      mapping find_cached_args(int num)   {    if(!args_restored) restore_cached_args();    if(cached_args[num]) return cached_args[num]; - #if 0 -  This can be really slow. If the args are restored, we should be happy anyway. -  restore_cached_args(); +  restore_cached_args(); /* Not slow anymore, checks with stat... */    if(cached_args[num]) return cached_args[num]; - #endif +     return 0;   }            int find_or_insert(mapping find)   {    mapping f2 = copy_value(find); -  foreach(glob("magic_*", indices(f2)), string q) m_delete(f2,q); -  if(!args_restored) restore_cached_args(); -  array a = indices(cached_args); -  array b = values(cached_args); -  int i; -  for(i=0; i<sizeof(a); i++) if(equal(f2, b[i])) return a[i]; - #if 0 -  Again often a bad idea. Maybe should be a configurable option -  (could be useful if you run several servers against the same cache fiel, -  which you 2 -  restore_cached_args(); -  for(i=0; i<sizeof(a); i++) if(equal(f2, b[i])) return a[i]; - #endif -  cached_args[number]=f2; // Save the same that you try to restore, please. +  int res; +  string q; +  +  foreach(glob("magic_*", indices(f2)), q) +  m_delete(f2,q); +  +  if(!args_restored) +  restore_cached_args( ); +  +  array a=indices(f2),b=values(f2); +  sort(a,b); +  q = a*""+b*""; +  +  if(res = cached_args[ q ]) +  return res; +  +  restore_cached_args(); /* Not slow now, checks with stat.. */ +  +  if(res = cached_args[ q ]) +  return res; +  +  cached_args[ number ] = f2; +  cached_args[ q ] = number; +     remove_call_out(save_cached_args);    call_out(save_cached_args, 10);    return number++;   }         string magic_javascript_header(object id)   {    if(!id->supports->netscape_javascript || !id->supports->images) return "";    return
Roxen.git/server/modules/graphics/graphic_text.pike:1208: Inside #if efun(get_font)
   if(defines->bg && !arg->bg) arg->bg=defines->bg;   #if efun(get_font)    if(!arg->nfont) arg->nfont=defines->nfont;   #endif    if(!arg->font) arg->font=defines->font   #if !efun(get_font)    ||QUERY(default_font)   #endif    ;    +  if(arg->background) +  arg->background = fix_relative(arg->background,id); +  if(arg->texture) +  arg->texture = fix_relative(arg->texture,id); +  if(arg->magic_texture) +  arg->magic_texture=fix_relative(arg->magic_texture,id); +  if(arg->magic_background) +  arg->magic_background=fix_relative(arg->magic_background,id); +  if(arg->magicbg) +  arg->magicbg = fix_relative(arg->magicbg,id); +  if(arg->alpha) +  arg->alpha = fix_relative(arg->alpha,id); +     int num = find_or_insert( arg );       if(!short)    return query_location()+num+"/";    else    return (string)num;   }      string tag_graphicstext(string t, mapping arg, string contents,    object id, object foo, mapping defines)
Roxen.git/server/modules/graphics/graphic_text.pike:1255:    contents = parse_rxml(contents, id, foo, defines);   #else    contents = parse_rxml(contents, id, foo);   #endif       string lp, url, ea;    string pre, post, defalign, gt, rest, magic;    int i;    string split;    -  // No images here, let's generate an alternative.. -  if(!id->supports->images || id->prestate->noimages) -  { -  if(!arg->split) contents=replace(contents,"\n", "\n<br>\n"); -  if(arg->submit) return "<input type=submit name=\""+(arg->name+".x") -  + "\" value=\""+contents+"\">"; -  switch(t) -  { -  case "gtext": -  case "anfang": -  if(arg->href) -  return "<a href=\""+arg->href+"\">"+contents+"</a>"; -  return contents; -  default: -  if(sscanf(t, "%s%d", t, i)==2) -  rest="<h"+i+">"+contents+"</h"+i+">"; -  else -  rest="<h1>"+contents+"</h1>"; -  if(arg->href) -  return "<a href=\""+arg->href+"\">"+rest+"</a>"; -  return rest; -  -  } -  } -  +     contents = contents[..((int)arg->maxlen||QUERY(deflen))];    m_delete(arg, "maxlen");       if(arg->magic)    {    magic=replace(arg->magic,"'","`");    m_delete(arg,"magic");    }       int input;
Roxen.git/server/modules/graphics/graphic_text.pike:1486:      string|array (string) tag_body(string t, mapping args, object id, object file,    mapping defines)   {    int cols,changed;    if(args->help) return "This tag is parsed by &lt;gtext&gt; to get the document colors.";    if(args->bgcolor||args->text||args->link||args->alink    ||args->background||args->vlink)    cols=1;    - #define FIX(Y,Z,X) do{if(!args->Y || args->Y==""){if(cols){defines->X=Z;args->Y=Z;changed=1;}}else{defines->X=args->Y;if(args->Y[0]!='#'){args->Y=ns_color(parse_color(args->Y));changed=1;}}}while(0) + #define FIX(Y,Z,X) do{if(!args->Y || args->Y==""){if(cols){defines->X=Z;args->Y=Z;changed=1;}}else{defines->X=args->Y;if(QUERY(colormode)&&args->Y[0]!='#'){args->Y=ns_color(parse_color(args->Y));changed=1;}}}while(0)       if(!search((id->client||({}))*"","Mosaic"))    {    FIX(bgcolor,"#bfbfbf",bg);    FIX(text, "#000000",fg);    FIX(link, "#0000b0",link);    FIX(alink, "#3f0f7b",alink);    FIX(vlink, "#ff0000",vlink);    } else {    FIX(bgcolor,"#c0c0c0",bg);    FIX(text, "#000000",fg);    FIX(link, "#0000ee",link);    FIX(alink, "#ff0000",alink);    FIX(vlink, "#551a8b",vlink);    } -  if(changed) return ({make_tag("body", args) }); +  if(changed && QUERY(colormode)) +  return ({make_tag("body", args) });   }         string|array(string) tag_fix_color(string tagname, mapping args, object id,    object file, mapping defines)   {    int changed;       if(args->help) return "This tag is parsed by &lt;gtext&gt; to get the document colors.";    if(!id->misc->colors)    id->misc->colors = ({ ({ defines->fg, defines->bg, tagname }) });    else    id->misc->colors += ({ ({ defines->fg, defines->bg, tagname }) });   #undef FIX - #define FIX(X,Y) if(args->X && args->X!=""){defines->Y=args->X;if(args->X[0]!='#'){args->X=ns_color(parse_color(args->X));changed = 1;}} + #define FIX(X,Y) if(args->X && args->X!=""){defines->Y=args->X;if(QUERY(colormode) && args->X[0]!='#'){args->X=ns_color(parse_color(args->X));changed = 1;}}       FIX(bgcolor,bg);    FIX(text,fg);    FIX(color,fg); -  + #undef FIX    -  if(changed) return ({ make_tag(tagname, args) }); +  if(changed && QUERY(colormode)) +  return ({ make_tag(tagname, args) });    return 0;   }      string|void pop_color(string tagname,mapping args,object id,object file,    mapping defines)   { -  array c = id->misc->colors; +     if(args->help) return "This end-tag is parsed by &lt;gtext&gt; to get the document colors."; -  +  array c = id->misc->colors;    if(!c ||!sizeof(c))    return;       int i;    tagname = tagname[1..];       for(i=0;i<sizeof(c);i++)    if(c[-i-1][2]==tagname)    {    defines->fg = c[-i-1][0];    defines->bg = c[-i-1][1];    break;    }    c = c[..sizeof(c)-i-2];    id->misc->colors = c; -  +    }      mapping query_tag_callers()   { -  return ([ "gtext-id":tag_gtext_id, ]) -  | (query("nobody")?([]):(["body":tag_body])) -  // No reson to pop the end of body "/body":pop_color])) -  | (query("speedy")?([]): -  (["font":tag_fix_color, -  "table":tag_fix_color, -  "tr":tag_fix_color, -  "td":tag_fix_color, -  "layer":tag_fix_color, -  "ilayer":tag_fix_color, -  "/td":pop_color, -  "/tr":pop_color, -  "/font":pop_color, -  "/table":pop_color, -  "/layer":pop_color, -  "/ilayer":pop_color, -  ])); +  mapping tags = ([ "gtext-id":tag_gtext_id]); +  foreach(query("colorparsing"), string t) +  { +  switch(t) +  { +  case "body": +  tags[t] = tag_body; +  break; +  default: +  tags[t] = tag_fix_color; +  tags["/"+t]=pop_color;    } -  +  } +  return tags; + }         mapping query_container_callers()   {    return ([ "anfang":tag_graphicstext,    "gh":tag_graphicstext,    "gh1":tag_graphicstext, "gh2":tag_graphicstext,    "gh3":tag_graphicstext, "gh4":tag_graphicstext,    "gh5":tag_graphicstext, "gh6":tag_graphicstext,    "gtext":tag_graphicstext, ]);   }