eb0b9a1998-03-10Henrik Grubbström (Grubba) constant cvs_version="$Id: graphic_text.pike,v 1.116 1998/03/10 22:23:12 grubba Exp $";
85e8321997-08-31Peter Bortas constant thread_safe=1;
ebf60d1997-03-08Henrik Grubbström (Grubba) 
d47cbf1996-12-02Per Hedbor #include <module.h>
e5bad21998-02-10Per Hedbor #include <stat.h>
d47cbf1996-12-02Per Hedbor inherit "module"; inherit "roxenlib";
3992de1997-09-28Henrik Grubbström (Grubba) #ifndef VAR_MORE #define VAR_MORE 0 #endif /* VAR_MORE */
610bf91998-03-07Fredrik Noring static private int loaded; static private string doc() { return !loaded?"":replace(Stdio.read_bytes("modules/tags/doc/graphic_text") ||"", ({ "{", "}" }), ({ "&lt;", "&gt;" })); }
d47cbf1996-12-02Per Hedbor array register_module() { return ({ MODULE_LOCATION | MODULE_PARSER, "Graphics text",
610bf91998-03-07Fredrik Noring  ("Generates graphical texts.<p>" "See <tt>&lt;gtext help&gt;&lt;/gtext&gt;</tt> for " "more information.\n<p>"+doc()), #if 0
a55a121997-05-30Per Hedbor  "Defines a few new containers, which all render text to gifs " "using the image module in pike.\n<p>"
676c231996-12-06Per Hedbor  "<b>&lt;gh1&gt;</b> to <b>&lt;gh6&gt;:</b> Headers<br>\n" "<b>&lt;gh&gt;:</b> Header<br>\n" "<b>&lt;gtext&gt;:</b> Graphical text<br>\n"
a55a121997-05-30Per Hedbor  "<b>&lt;anfang&gt;:</b> Make the first character a "
43191e1997-09-07Henrik Grubbström (Grubba)  "graphical one. Not all that useful, really.<br>\n"
a97f5d1996-12-10Per Hedbor  "<br>\n" "<b>Common arguments:</b>\n <pre>"
f7d9811997-09-12Per Hedbor  " verbatim Do not try to be typographically correct\n"
bfc7071997-01-13Per Hedbor  " bg=color Use this background, default taken from the\n"
d47cbf1996-12-02Per Hedbor  " &lt;body&gt; tag, if any\n"
bfc7071997-01-13Per Hedbor  " fg=color Use this foreground, default taken from the\n"
d47cbf1996-12-02Per Hedbor  " &lt;body&gt; tag, if any\n"
a55a121997-05-30Per Hedbor  " nfont=fnt Use this font. The fonts can be found in the\n"
d47cbf1996-12-02Per Hedbor  " directory specified in the configuration\n" " interface.\n" " If no font is specified, the one from the\n"
a55a121997-05-30Per Hedbor  " define 'nfont' is used, or if there is no\n"
d47cbf1996-12-02Per Hedbor  " define, the default font will be used.\n"
a55a121997-05-30Per Hedbor  " bold Try to find a bold version of the font.\n" " italic Try to find an italic version of the font.\n" " black Try to find a black (heavy) version of the font.\n" " light Try to find a light version of the font.\n"
d47cbf1996-12-02Per Hedbor  " scale=float Scale to this font, mostly useful in the &lt;gtext&gt;\n" " tag, will not work at all in the &lt;gh[number]&gt;\n" " tags.\n" " 2 3 4 5 6 Short for scale=1.0/([number]*0.6)\n" " notrans Do _not_ make the background color transparent\n" " split Make each word into a separate gif image\n"
1bd5c91997-09-26Henrik Grubbström (Grubba)  " split=char Split the string also at CHAR\n"
d47cbf1996-12-02Per Hedbor  " href=url Link the image to the specified URL\n" " The 'link' color of the document will be\n" " used as the default foreground of the text\n"
eab4221997-09-19Johan Schön  " alt=message Sets the 'alt' attribute.\n"
c866651997-09-19Johan Schön  " Use alt=\"\" if no alternate message is wanted.\n"
d47cbf1996-12-02Per Hedbor  " quant=cols Use this number of colors\n" " magic[=message] Modifier to href, more flashy links\n" " Does <b>not</b> work with 'split'\n"
4af24d1997-10-27Per Hedbor  " magicbg=bg As background, but for the 'magic' image\n"
20ca2b1998-01-26Per Hedbor  " magic_X same as X, where X is any other argument,\n" " but for the 'magic' image.\n"
bfc7071997-01-13Per Hedbor  " fuzz[=color] Apply the 'glow' effect to the result\n" " fs Use floyd-steinberg dithering\n" " border=int,col. Draw an border (width is the first argument\n"
d47cbf1996-12-02Per Hedbor  " in the specified color\n" " spacing=int Add this amount of spacing around the text\n"
3950bb1996-12-10Per Hedbor  " xspacing=int like spacing, but only horizontal\n" " yspacing=int like spacing, but only vertical\n" " size=int,int Use this (absolute) size\n" " xsize=int Use this (absolute) size\n" " ysize=int Use this (absolute) size\n"
d47cbf1996-12-02Per Hedbor  " bevel=int Draw a bevel box (width is the argument)\n"
38dca81996-12-10Per Hedbor  " pressed Invert the \"direction\" of the bevel box\n" " talign=dir Justify the text to the left, right, or center\n"
bfc7071997-01-13Per Hedbor  " textbox=al,col. Use 'al' as opaque value to draw a box below\n"
d47cbf1996-12-02Per Hedbor  " the text with the specified color.\n"
38dca81996-12-10Per Hedbor  " xpad=X% Increase padding between characters with X%\n" " xpad=Y% Increase padding between lines with Y%\n"
4dfdeb1996-12-04Per Hedbor  " shadow=int,dist Draw a drop-shadow (variable distance/intensity)\n"
5f0d911997-02-27Per Hedbor  " bshadow=dist Draw a blured drop-shadow (variable distance)\n"
291a801997-07-10Per Hedbor  " scolor=color Use this color as the shadow color.\n"
f6d62d1997-03-26Per Hedbor  " ghost=dist,blur,col\n"
a55a121997-05-30Per Hedbor  " Do a 'ghost text'. Do NOT use together with\n" " 'shadow'. Magic coloring won't work with it.\n"
bfc7071997-01-13Per Hedbor  " glow=color Draw a 'glow' outline around the text.\n"
d47cbf1996-12-02Per Hedbor  " opaque=0-100% Draw with more or less opaque text (100%\n" " is default)\n" " rotate=ang(deg.)Rotate the finished image\n" " background=file Use the specifed file as a background\n"
e8790b1998-02-19Per Hedbor  " Supported file-formats: gif and ppm, jpeg if\n" " the jpeg library was available when roxen was\n" " compiled\n"
d47cbf1996-12-02Per Hedbor  " texture=file Use the specified file as text texture\n"
e8790b1998-02-19Per Hedbor  " tile Tile the background and foreground images\n" " if they are smaller than the actual image\n" " mirrortile same as above, but mirror around x and y axis\n" " for odd frames, creating seamless textures\n"
38dca81996-12-10Per Hedbor  " turbulence=args args is: frequency,color;freq,col;freq,col\n"
3642ac1996-12-10Per Hedbor  " Apply a turbulence filter, and use this as the\n"
38dca81996-12-10Per Hedbor  " background.\n"
bfc7071997-01-13Per Hedbor  " maxlen=arg The maximum length of the rendered text will be\n" " the specified argument. The default is 300, this\n"
44e3371997-06-12Per Hedbor  " is used to safeguard against mistakes like\n" " &lt;gh1&gt;&lt;/gh&gt;, which would otherwise\n" " parse the whole document.\n" " help Display this text\n"
e493e81997-07-11Per Hedbor  " scroll=width,steps,delay Make a horrible scrolltext\n"
e8c29c1997-09-12Johan Schön  " fadein=blur,steps,delay,initialdelay Make a (somewhat less) horrible fadein\n"
3642ac1996-12-10Per Hedbor  "\n"
a97f5d1996-12-10Per Hedbor  "<b>Arguments passed on the the &lt;a&gt; tag (if href is specified):</b>\n "
1ce8c31996-12-10Per Hedbor  " target=...\n" " onClick=...\n"
4dd97c1996-12-04Per Hedbor  "</pre>\n",
610bf91998-03-07Fredrik Noring #endif
4dd97c1996-12-04Per Hedbor  0, 1,
d47cbf1996-12-02Per Hedbor  }); } array (string) list_fonts() {
4dd97c1996-12-04Per Hedbor  array fnts; catch(fnts = get_dir("fonts/32/") - ({".",".."})); if(!fnts) { return ({}); } return fnts;
d47cbf1996-12-02Per Hedbor } void create() {
8afc811998-02-04Per Hedbor  defvar("cache_dir", "../gtext_cache", "Cache directory for gtext images",
20ca2b1998-01-26Per Hedbor  TYPE_DIR, "The gtext tag saves images when they are calculated in this " "directory. We currently do not clean this directory.");
e5bad21998-02-10Per Hedbor  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.");
4267991997-08-23Per Hedbor  defvar("speedy", 0, "Avoid automatic detection of document colors", TYPE_FLAG|VAR_MORE, "If this flag is set, the tags 'body', 'tr', 'td', 'font' and 'th' " " 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;");
9b9f701997-08-12Per Hedbor  defvar("deflen", 300, "Default maximum text-length", TYPE_INT|VAR_MORE,
bfc7071997-01-13Per Hedbor  "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.");
9b9f701997-08-12Per Hedbor  defvar("location", "/gtext/", "Mountpoint", TYPE_LOCATION|VAR_MORE,
f6d62d1997-03-26Per Hedbor  "The URL-prefix for the graphic characters.");
d47cbf1996-12-02Per Hedbor  defvar("cols", 16, "Default number of colors per image", TYPE_INT_LIST, "The default number of colors to use. 16 seems to be enough. " "The size of the image depends on the number of colors", ({ 1,2,3,4,5,6,7,8,10,16,32,64,128,256 }));
8e727d1997-03-11Per Hedbor 
974b2a1997-10-02Peter Bortas  defvar("gif", 0, "Append .gif to all images", TYPE_FLAG|VAR_MORE, "Append .gif to all images made by gtext. Normally this will " "only waste bandwidth");
8e727d1997-03-11Per Hedbor 
48fa361997-04-05Per Hedbor #ifdef TYPE_FONT
8e727d1997-03-11Per Hedbor  // compatibility variables... defvar("default_size", 32, 0, TYPE_INT,0,0,1); defvar("default_font", "urw_itc_avant_garde-demi-r",0,TYPE_STRING,0,0,1);
48fa361997-04-05Per Hedbor #else
d47cbf1996-12-02Per Hedbor  defvar("default_size", 32, "Default font size", TYPE_INT_LIST, "The default size for the font. This is used for the 'base' size, " "and can be scaled up or down in the tags.", ({ 16, 32, 64 }));
48fa361997-04-05Per Hedbor 
d47cbf1996-12-02Per Hedbor  defvar("default_font", "urw_itc_avant_garde-demi-r", "Default font", TYPE_STRING_LIST, "The default font. The 'font dir' will be prepended to the path", list_fonts());
48fa361997-04-05Per Hedbor #endif
d47cbf1996-12-02Per Hedbor } string query_location() { return query("location"); }
e5bad21998-02-10Per Hedbor object load_font(string name, string justification, int xs, int ys)
d47cbf1996-12-02Per Hedbor {
e5bad21998-02-10Per Hedbor  object fnt = Image.font();
38dca81996-12-10Per Hedbor 
52a7d21997-09-01Per Hedbor  if ((!name)||(name == "")) {
9e0c5f1997-09-01Per Hedbor  return get_font("default",32,0,0,lower_case(justification||"left"),
52a7d21997-09-01Per Hedbor  (float)xs, (float)ys);
b677b71997-02-22Henrik Grubbström (Grubba)  } else if(sscanf(name, "%*s/%*s") != 2) {
38dca81996-12-10Per Hedbor  name=QUERY(default_size)+"/"+name;
b677b71997-02-22Henrik Grubbström (Grubba)  }
d47cbf1996-12-02Per Hedbor  name = "fonts/" + name;
38dca81996-12-10Per Hedbor  if(!fnt->load( name )) {
52a7d21997-09-01Per Hedbor  report_debug("Failed to load the compatibility font "+name+ ", using the default font.\n");
9e0c5f1997-09-01Per Hedbor  return get_font("default",32,0,0,lower_case(justification||"left"),
52a7d21997-09-01Per Hedbor  (float)xs, (float)ys);
38dca81996-12-10Per Hedbor  }
52a7d21997-09-01Per Hedbor  catch {
9d16ce1997-03-01Per Hedbor  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); };
d47cbf1996-12-02Per Hedbor  return fnt; } static private mapping (int:mapping(string:mixed)) cached_args = ([ ]); #define MAX(a,b) ((a)<(b)?(b):(a))
48fa361997-04-05Per Hedbor #if !efun(make_matrix)
d47cbf1996-12-02Per Hedbor 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; int j;
e5bad21998-02-10Per Hedbor  res = Array.map(allocate(size), lambda(int s, int size){
d47cbf1996-12-02Per Hedbor  return allocate(size); }, size); for(i=0; i<size; i++) for(j=0; j<size; j++) res[i][j] = (int)MAX((float)size/2.0-sqrt((size/2-i)*(size/2-i) + (size/2-j)*(size/2-j)),0); return matrixes[size] = res; }
48fa361997-04-05Per Hedbor #endif
d47cbf1996-12-02Per Hedbor 
9d16ce1997-03-01Per Hedbor string fix_relative(string file, object id)
033c7e1997-02-27Per Hedbor {
9d16ce1997-03-01Per Hedbor  if(file != "" && file[0] == '/') return file; file = combine_path(dirname(id->not_query) + "/", file); return file;
033c7e1997-02-27Per Hedbor }
d47cbf1996-12-02Per Hedbor 
9d16ce1997-03-01Per Hedbor object last_image; // Cache the last image for a while.
e439c01996-12-10Per Hedbor string last_image_name;
d1f9661997-04-09Per Hedbor object load_image(string f,object id)
d47cbf1996-12-02Per Hedbor {
85e8321997-08-31Peter Bortas  if(last_image_name == f && last_image) return last_image->copy();
d47cbf1996-12-02Per Hedbor  string data;
033c7e1997-02-27Per Hedbor  object file;
e8790b1998-02-19Per Hedbor  object img #if !constant(Image.PNM) =Image.image() #endif ;
9d16ce1997-03-01Per Hedbor  if(!(data=roxen->try_get_file(fix_relative(f, id),id)))
522b871997-09-03Per Hedbor  if(!(file=open(f,"r")) || (!(data=file->read())))
033c7e1997-02-27Per Hedbor  return 0;
3a4d7e1997-09-03Per Hedbor //werror("Read "+strlen(data)+" bytes.\n");
15edc21998-02-19Fredrik Noring #if constant(Image.PNM.decode)
e8790b1998-02-19Per Hedbor  catch { if(!img) img = Image.PNM.decode( data ); };
15edc21998-02-19Fredrik Noring #endif #if constant(Image.GIF.decode)
e8790b1998-02-19Per Hedbor  catch { if(!img) img = Image.GIF.decode( data ); };
15edc21998-02-19Fredrik Noring #endif #if constant(Image.JPEG.decode)
e8790b1998-02-19Per Hedbor  catch { if(!img) img = Image.JPEG.decode( data ); };
15edc21998-02-19Fredrik Noring #endif #if !constant(Image.PNM.decode)
b4da8e1997-11-09Henrik Grubbström (Grubba)  if (catch { if(!img->frompnm(data)) return 0;}) return 0;
e8790b1998-02-19Per Hedbor #endif if(!img) return 0;
85e8321997-08-31Peter Bortas  last_image = img; last_image_name = f;
9d16ce1997-03-01Per Hedbor  return img->copy();
d47cbf1996-12-02Per Hedbor }
e5bad21998-02-10Per Hedbor object blur(object img, int amnt)
d47cbf1996-12-02Per Hedbor {
bfc7071997-01-13Per Hedbor  img->setcolor(0,0,0); img = img->autocrop(amnt, 0,0,0,0, 0,0,0);
d47cbf1996-12-02Per Hedbor  for(int i=0; i<amnt; i++)
bfc7071997-01-13Per Hedbor  img = img->apply_matrix( make_matrix((int)sqrt(img->ysize()+20)));
d47cbf1996-12-02Per Hedbor  return img; }
e5bad21998-02-10Per Hedbor object outline(object on, object with,
bfc7071997-01-13Per Hedbor  array (int) color, int radie, int x, int y) { int steps=10; for(int j=0; j<=steps; j++)
48fa361997-04-05Per Hedbor  on->paste_alpha_color(with, @color, (int)(0.5+x-(sin((float)j/steps*3.145*2)*radie)), (int)(0.5+y-(cos((float)j/steps*3.145*2)*radie)));
bfc7071997-01-13Per Hedbor  return on; }
5e89211997-02-13Per Hedbor array white = ({ 255,255,255 }); array lgrey = ({ 200,200,200 }); array grey = ({ 128,128,128 }); array black = ({ 0,0,0 });
d47cbf1996-12-02Per Hedbor 
5e89211997-02-13Per Hedbor array wwwb = ({ lgrey,lgrey,grey,black });
e5bad21998-02-10Per Hedbor object bevel(object in, int width, int|void invert)
d47cbf1996-12-02Per Hedbor {
4dfdeb1996-12-04Per Hedbor  int h=in->ysize(); int w=in->xsize();
d47cbf1996-12-02Per Hedbor 
e5bad21998-02-10Per Hedbor  object corner = Image.image(width+1,width+1); object corner2 = Image.image(width+1,width+1); object pix = Image.image(1,1);
38dca81996-12-10Per Hedbor 
88e1cb1996-12-07David Hedbor  for(int i=-1; i<=width; i++) { corner->line(i,width-i,i,-1, @white); corner2->setpixel(width-i, width-i, @white); in->paste_alpha(pix, 185, w - width + i+1, h - width + i+1); }
38dca81996-12-10Per Hedbor  if(!invert) {
e5bad21998-02-10Per Hedbor  in->paste_alpha(Image.image(width,h-width*2,@white), 160, 0, width); in->paste_alpha(Image.image(width,h-width*2,@black), 128, in->xsize()-width, width); in->paste_alpha(Image.image(w-width,width,@white), 160, 0, 0); in->paste_alpha(Image.image(w-width,width,@black), 128, width, in->ysize()-width);
38dca81996-12-10Per Hedbor  } else { corner=corner->invert(); corner2=corner2->invert();
e5bad21998-02-10Per Hedbor  in->paste_alpha(Image.image(width,h-width*2,@black), 160, 0, width); in->paste_alpha(Image.image(width,h-width*2,@white), 128, in->xsize()-width, width); in->paste_alpha(Image.image(w-width,width,@black), 160, 0, 0); in->paste_alpha(Image.image(w-width,width,@white), 128, width, in->ysize()-width);
38dca81996-12-10Per Hedbor  } in->paste_mask(corner, corner->color(95,95,95), in->xsize()-width,-1); in->paste_mask(corner, corner->invert()->color(128,128,128),
88e1cb1996-12-07David Hedbor  in->xsize()-width,-1);
38dca81996-12-10Per Hedbor  in->paste_mask(corner, corner->color(95,95,95), -1, in->ysize()-width);
88e1cb1996-12-07David Hedbor  in->paste_mask(corner, corner->invert()->color(128,128,128),
38dca81996-12-10Per Hedbor  -1, in->ysize()-width);
48fa361997-04-05Per Hedbor  corner=0;
38dca81996-12-10Per Hedbor  in->paste_mask(corner2, corner2->color(70,70,70), -1, -1);
88e1cb1996-12-07David Hedbor 
48fa361997-04-05Per Hedbor  corner2 = pix = 0;
d47cbf1996-12-02Per Hedbor  return in; }
e5bad21998-02-10Per Hedbor object make_text_image(mapping args, object font, string text,object id)
d47cbf1996-12-02Per Hedbor {
d1f9661997-04-09Per Hedbor  object text_alpha=font->write(@(text/"\n"));
d47cbf1996-12-02Per Hedbor  int xoffset=0, yoffset=0;
bfc7071997-01-13Per Hedbor  if(!text_alpha->xsize() || !text_alpha->ysize())
e5bad21998-02-10Per Hedbor  text_alpha = Image.image(10,10, 0,0,0);
bfc7071997-01-13Per Hedbor  // perror("Making image of '%s', args=%O\n", text, args);
d47cbf1996-12-02Per Hedbor  if(int op=((((int)args->opaque)*255)/100)) // Transparent text... text_alpha=text_alpha->color(op,op,op); int txsize=text_alpha->xsize(); int tysize=text_alpha->ysize(); // Size of the text, in pixels.
5e89211997-02-13Per Hedbor  int xsize=txsize; // image size, in pixels
d47cbf1996-12-02Per Hedbor  int ysize=tysize;
bfc7071997-01-13Per Hedbor // perror("Xsize=%d; ysize=%d\n",xsize,ysize);
d47cbf1996-12-02Per Hedbor  if(args->bevel) { xoffset += (int)args->bevel; yoffset += (int)args->bevel; xsize += ((int)args->bevel)*2; ysize += ((int)args->bevel)*2; } if(args->spacing) { xoffset += (int)args->spacing; yoffset += (int)args->spacing; xsize += ((int)args->spacing)*2; ysize += ((int)args->spacing)*2; } if(args->yspacing) { yoffset += (int)args->yspacing; ysize += ((int)args->yspacing)*2; }
4dfdeb1996-12-04Per Hedbor  if(args->shadow) { xsize+=((int)(args->shadow/",")[-1])+2; ysize+=((int)(args->shadow/",")[-1])+2; }
5f0d911997-02-27Per Hedbor  if(args->bshadow) {
ae2ddd1997-02-27Per Hedbor  xsize+=(int)args->bshadow+3; ysize+=(int)args->bshadow+3;
5f0d911997-02-27Per Hedbor  }
e8c29c1997-09-12Johan Schön  if(args->fadein) { xsize+=6; ysize+=6; xoffset+=3; yoffset+=3; }
6ec4501997-02-19Per Hedbor  if(args->move) { int dx,dy; sscanf(args->move, "%d,%d", dx, dy); xoffset += dx; yoffset += dy; }
f6d62d1997-03-26Per Hedbor  if(args->ghost) { int howmuch=(int)args->ghost; xsize+=howmuch*2+10; xoffset += 3; ysize+=howmuch*2+10; }
d47cbf1996-12-02Per Hedbor  if(args->xspacing) { xoffset += (int)args->xspacing; xsize += ((int)args->xspacing)*2; } if(args->border) { xoffset += (int)args->border; yoffset += (int)args->border; xsize += ((int)args->border)*2; ysize += ((int)args->border)*2; }
4dd97c1996-12-04Per Hedbor  array (int) bgcolor = parse_color(args->bg); array (int) fgcolor = parse_color(args->fg);
d47cbf1996-12-02Per Hedbor  object background,foreground;
e8790b1998-02-19Per Hedbor  if(args->texture) { foreground = load_image(args->texture,id); if(args->tile) { object b2 = Image.image(xsize,ysize); for(int x=0; x<xsize; x+=foreground->xsize()) for(int y=0; y<ysize; y+=foreground->ysize()) b2->paste(foreground, x, y); foreground = b2; } else if(args->mirrortile) { object b2 = Image.image(xsize,ysize); object b3 = Image.image(foreground->xsize()*2,foreground->ysize()*2); b3->paste(foreground,0,0); b3->paste(foreground->mirrorx(),foreground->xsize(),0); b3->paste(foreground->mirrory(),0,foreground->ysize()); b3->paste(foreground->mirrorx()->mirrory(),foreground->xsize(), foreground->ysize()); foreground = b3; for(int x=0; x<xsize; x+=foreground->xsize()) { for(int y=0; y<ysize; y+=foreground->ysize()) if(y%2) b2->paste(foreground->mirrory(), x, y); else b2->paste(foreground, x, y); foreground = foreground->mirrorx(); } foreground = b2; } }
d47cbf1996-12-02Per Hedbor 
e30a591997-03-01Henrik Grubbström (Grubba)  if((args->background) && (background = load_image(args->background, id))) {
85e8321997-08-31Peter Bortas  background = background;
522b871997-09-03Per Hedbor  if((float)args->scale >= 0.1) background = background->scale(1.0/(float)args->scale);
e8790b1998-02-19Per Hedbor  if(args->tile) { object b2 = Image.image(xsize,ysize); for(int x=0; x<xsize; x+=background->xsize()) for(int y=0; y<ysize; y+=background->ysize()) b2->paste(background, x, y); background = b2; } else if(args->mirrortile) { object b2 = Image.image(xsize,ysize); object b3 = Image.image(background->xsize()*2,background->ysize()*2); b3->paste(background,0,0); b3->paste(background->mirrorx(),background->xsize(),0); b3->paste(background->mirrory(),0,background->ysize()); b3->paste(background->mirrorx()->mirrory(),background->xsize(), background->ysize()); background = b3; for(int x=0; x<xsize; x+=background->xsize()) { for(int y=0; y<ysize; y+=background->ysize()) if(y%2) b2->paste(background->mirrory(), x, y); else b2->paste(background, x, y); background = background->mirrorx(); } background = b2; }
522b871997-09-03Per Hedbor 
4dfdeb1996-12-04Per Hedbor  xsize = background->xsize(); ysize = background->ysize();
0cb13a1997-02-15Henrik Grubbström (Grubba)  switch(lower_case(args->talign||"left")) { case "center":
38dca81996-12-10Per Hedbor  xoffset = (xsize/2 - txsize/2);
9d16ce1997-03-01Per Hedbor  yoffset = (ysize/2 - tysize/2);
38dca81996-12-10Per Hedbor  break;
0cb13a1997-02-15Henrik Grubbström (Grubba)  case "right":
38dca81996-12-10Per Hedbor  xoffset = (xsize - txsize); break;
0cb13a1997-02-15Henrik Grubbström (Grubba)  case "left":
38dca81996-12-10Per Hedbor  }
4dfdeb1996-12-04Per Hedbor  } else
e5bad21998-02-10Per Hedbor  background = Image.image(xsize, ysize, @bgcolor);
7866701996-12-10Per Hedbor 
bfc7071997-01-13Per Hedbor  if(args->border) { int b = (int)args->border; background->setcolor(@parse_color((args->border/",")[-1])); for(--b;b>=0;b--) { // upper left -- upper right background->line(b,b, xsize-b-1, b); // lower left -- lower right background->line(b,ysize-b-1, xsize-b-1, ysize-b-1); // upper left -- lower left background->line(b,b, b, ysize-b-1); // upper right -- lower right background->line(xsize-b-1,b, xsize-b-1, ysize-b-1); } }
3950bb1996-12-10Per Hedbor  background->setcolor(@bgcolor);
7866701996-12-10Per Hedbor 
3950bb1996-12-10Per Hedbor  if(args->size || args->xsize || args->ysize) { int xs=background->xsize(), ys=background->ysize(); if(args->size) { xs=(int)args->size; ys=(int)(args->size/",")[-1]; } if(args->xsize) xs=(int)args->xsize; if(args->ysize) ys=(int)args->ysize;
7866701996-12-10Per Hedbor  background = background->copy(0,0,xs,ys);
3950bb1996-12-10Per Hedbor  }
d47cbf1996-12-02Per Hedbor 
3950bb1996-12-10Per Hedbor 
38dca81996-12-10Per Hedbor  if(args->turbulence) { array (float|array(int)) arg=({}); foreach((args->turbulence/";"), string s) { array q= s/","; if(sizeof(q)<2) args+=({ ((float)s)||0.2, ({ 255,255,255 }) }); arg+=({ ((float)q[0])||0.2, parse_color(q[1]) }); } background=background->turbulence(arg); } if(args->bevel) background = bevel(background,(int)args->bevel,!!args->pressed);
d47cbf1996-12-02Per Hedbor  if(args->textbox) // Draw a text-box on the background. {
4dfdeb1996-12-04Per Hedbor  int alpha,border;
d47cbf1996-12-02Per Hedbor  string bg; sscanf(args->textbox, "%d,%s", alpha, bg);
4dfdeb1996-12-04Per Hedbor  sscanf(bg,"%s,%d", bg,border);
e5bad21998-02-10Per Hedbor  background->paste_alpha(Image.image(txsize+border*2,tysize+border*2,
38dca81996-12-10Per Hedbor  @parse_color(bg)), 255-(alpha*255/100),xoffset-border,yoffset-border);
d47cbf1996-12-02Per Hedbor  }
f6d62d1997-03-26Per Hedbor  if(args->ghost) { // Francesco.. int sdist = (int)args->ghost; int bl=(int)(args->ghost/",")[1]; array(int)clr=parse_color((args->ghost/",")[-1]); int j; object ta = text_alpha->copy(); for (j=0;j<bl;j++) ta=ta->apply_matrix(({ ({6,7,7,7,6}),({7,8,8,8,7}),({7,8,8,8,7}),({7,8,8,8,7}),({6,7,7,7,6}) }));
48fa361997-04-05Per Hedbor  background->paste_alpha_color(ta,@clr,xoffset+sdist,yoffset+sdist);
f6d62d1997-03-26Per Hedbor  fgcolor=bgcolor; }
bfc7071997-01-13Per Hedbor 
4dfdeb1996-12-04Per Hedbor  if(args->shadow) { int sd = ((int)args->shadow+10)*2; int sdist = ((int)(args->shadow/",")[-1])+2; object ta = text_alpha->copy(); ta = ta->color(256-sd,256-sd,256-sd);
291a801997-07-10Per Hedbor  array sc = parse_color(args->scolor||"black"); background->paste_alpha_color(ta,sc[0],sc[1],sc[2], xoffset+sdist,yoffset+sdist);
4dfdeb1996-12-04Per Hedbor  }
5f0d911997-02-27Per Hedbor #define MIN(x,y) ((x)<(y)?(x):(y)) if(args->bshadow) { int sdist = (int)(args->bshadow)+1;
ae2ddd1997-02-27Per Hedbor  int xs,ys; xs = text_alpha->xsize()+sdist*2+4; ys = text_alpha->ysize()+sdist*2+4;
e5bad21998-02-10Per Hedbor  object ta = Image.image(xs+sdist*2,ys+sdist*2);
291a801997-07-10Per Hedbor  array sc = parse_color(args->scolor||"black"); ta->paste_alpha_color(text_alpha,255,255,255,sdist,sdist);
5f0d911997-02-27Per Hedbor  ta = blur(ta, MIN((sdist/2),1))->color(256,256,256);
291a801997-07-10Per Hedbor  background->paste_alpha_color(ta,sc[0],sc[1],sc[2], xoffset+sdist,yoffset+sdist);
5f0d911997-02-27Per Hedbor  }
bfc7071997-01-13Per Hedbor  if(args->glow) { int amnt = (int)(args->glow/",")[-1]+2; array (int) blurc = parse_color((args->glow/",")[0]);
48fa361997-04-05Per Hedbor  background->paste_alpha_color(blur(text_alpha, amnt),@blurc, xoffset-amnt, yoffset-amnt);
bfc7071997-01-13Per Hedbor  }
38dca81996-12-10Per Hedbor  if(args->chisel)
d1f9661997-04-09Per Hedbor  foreground=text_alpha->apply_matrix(({ ({8,1,0}), ({1,0,-1}), ({0,-1,-8}) }), 128,128,128, 15 )
38dca81996-12-10Per Hedbor  ->color(@fgcolor);
e5bad21998-02-10Per Hedbor  if(!foreground) foreground=Image.image(txsize, tysize, @fgcolor);
bfc7071997-01-13Per Hedbor  if(args->textscale) { string c1="black",c2="black",c3="black",c4="black"; sscanf(args->textscale, "%s,%s,%s,%s", c1, c2, c3, c4); foreground->tuned_box(0,0, txsize,tysize, ({parse_color(c1),parse_color(c2),parse_color(c3), parse_color(c4)})); } if(args->outline) outline(background, text_alpha, parse_color((args->outline/",")[0]), ((int)(args->outline/",")[-1])+1, xoffset, yoffset);
d47cbf1996-12-02Per Hedbor 
4dfdeb1996-12-04Per Hedbor  background->paste_mask(foreground, text_alpha, xoffset, yoffset);
d47cbf1996-12-02Per Hedbor  if(args->scale) if((float)args->scale <= 2.0) background = background->scale((float)args->scale);
522b871997-09-03Per Hedbor  foreground = text_alpha = 0;
d47cbf1996-12-02Per Hedbor  if(args->rotate) { string c;
bfc7071997-01-13Per Hedbor  if(sscanf(args->rotate, "%*d,%s", c)==2)
4dd97c1996-12-04Per Hedbor  background->setcolor(@parse_color(c));
d47cbf1996-12-02Per Hedbor  else background->setcolor(@bgcolor); background = background->rotate((float)args->rotate); }
4dfdeb1996-12-04Per Hedbor  if(args->crop) background = background->autocrop();
d47cbf1996-12-02Per Hedbor  return background; }
2468b21997-07-06Henrik Grubbström (Grubba) string base_key;
fe21a71997-08-25Per Hedbor object mc;
2468b21997-07-06Henrik Grubbström (Grubba) 
e5bad21998-02-10Per Hedbor  array to_clean = ({}); void clean_cache_dir() { if(!sizeof(to_clean)) to_clean = get_dir(query("cache_dir")); if(!sizeof(to_clean)) return; int md = file_stat(query("cache_dir")+to_clean[0])[ST_ATIME]; if((time() - md) > (query("cache_age")*3600)) rm(query("cache_dir")+to_clean[0]); to_clean = to_clean[1..]; if(sizeof(to_clean)) call_out(clean_cache_dir, 0.1); else call_out(clean_cache_dir, 3600); }
08df121997-08-19Henrik Grubbström (Grubba) void start(int|void val, object|void conf)
2468b21997-07-06Henrik Grubbström (Grubba) {
610bf91998-03-07Fredrik Noring  loaded = 1;
fe21a71997-08-25Per Hedbor  if(conf) {
eb0b9a1998-03-10Henrik Grubbström (Grubba)  mkdirhier( query( "cache_dir" )+"/.foo" );
c79b261998-02-05Johan Schön #ifndef __NT__
8afc811998-02-04Per Hedbor #if efun(chmod)
4c35411998-03-10Henrik Grubbström (Grubba)  // FIXME: Should this error be propagated? catch { chmod( query( "cache_dir" ), 0777 ); };
c79b261998-02-05Johan Schön #endif
8afc811998-02-04Per Hedbor #endif
e5bad21998-02-10Per Hedbor  remove_call_out(clean_cache_dir); call_out(clean_cache_dir, 10);
fe21a71997-08-25Per Hedbor  mc = conf; base_key = "gtext:"+(conf?conf->name:roxen->current_configuration->name); }
2468b21997-07-06Henrik Grubbström (Grubba) }
c3655b1997-01-27Per Hedbor 
d1f9661997-04-09Per Hedbor #ifdef QUANT_DEBUG void print_colors(array from) { #if efun(color_name) for(int i=0; i<sizeof(from); i++) perror("%d: %s\n", i, color_name(from[i])); #endif } #endif
d47cbf1996-12-02Per Hedbor 
68e0301997-08-19Per Hedbor int number=0; mapping find_cached_args(int num);
d249951996-12-10Per Hedbor 
20ca2b1998-01-26Per Hedbor  #if !constant(iso88591) constant iso88591 =([ "&nbsp;": " ", "&iexcl;": "¡", "&cent;": "¢", "&pound;": "£", "&curren;": "¤", "&yen;": "¥", "&brvbar;": "¦", "&sect;": "§", "&uml;": "¨", "&copy;": "©", "&ordf;": "ª", "&laquo;": "«", "&not;": "¬", "&shy;": "­", "&reg;": "®", "&macr;": "¯", "&deg;": "°", "&plusmn;": "±", "&sup2;": "²", "&sup3;": "³", "&acute;": "´", "&micro;": "µ", "&para;": "¶", "&middot;": "·", "&cedil;": "¸", "&sup1;": "¹", "&ordm;": "º", "&raquo;": "»", "&frac14;": "¼", "&frac12;": "½", "&frac34;": "¾", "&iquest;": "¿", "&Agrave;": "À", "&Aacute;": "Á", "&Acirc;": "Â", "&Atilde;": "Ã", "&Auml;": "Ä", "&Aring;": "Å", "&AElig;": "Æ", "&Ccedil;": "Ç", "&Egrave;": "È", "&Eacute;": "É", "&Ecirc;": "Ê", "&Euml;": "Ë", "&Igrave;": "Ì", "&Iacute;": "Í", "&Icirc;": "Î", "&Iuml;": "Ï", "&ETH;": "Ð", "&Ntilde;": "Ñ", "&Ograve;": "Ò", "&Oacute;": "Ó", "&Ocirc;": "Ô", "&Otilde;": "Õ", "&Ouml;": "Ö", "&times;": "×", "&Oslash;": "Ø", "&Ugrave;": "Ù", "&Uacute;": "Ú", "&Ucirc;": "Û", "&Uuml;": "Ü", "&Yacute;": "Ý", "&THORN;": "Þ", "&szlig;": "ß", "&agrave;": "à", "&aacute;": "á", "&acirc;": "â", "&atilde;": "ã", "&auml;": "ä", "&aring;": "å", "&aelig;": "æ", "&ccedil;": "ç", "&egrave;": "è", "&eacute;": "é", "&ecirc;": "ê", "&euml;": "ë", "&igrave;": "ì", "&iacute;": "í", "&icirc;": "î", "&iuml;": "ï", "&eth;": "ð", "&ntilde;": "ñ", "&ograve;": "ò", "&oacute;": "ó", "&ocirc;": "ô", "&otilde;": "õ", "&ouml;": "ö", "&divide;": "÷", "&oslash;": "ø", "&ugrave;": "ù", "&uacute;": "ú", "&ucirc;": "û", "&uuml;": "ü", "&yacute;": "ý", "&thorn;": "þ", "&yuml;": "ÿ", ]); #endif
b1ab8d1997-12-23Per Hedbor 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)
06583f1997-09-03Per Hedbor 
8afc811998-02-04Per Hedbor #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..])))
20ca2b1998-01-26Per Hedbor  array get_cache_file(string a, string b) {
8afc811998-02-04Per Hedbor  object fd = open(FNAME(a,b), "r");
20ca2b1998-01-26Per Hedbor  if(!fd) return 0; array r = decode_value(fd->read()); if(r[0]==a && r[1]==b) return r[2]; } void store_cache_file(string a, string b, array data) {
8afc811998-02-04Per Hedbor  object fd = open(FNAME(a,b), "wct");
c79b261998-02-05Johan Schön #ifndef __NT__
8afc811998-02-04Per Hedbor #if efun(chmod)
4c35411998-03-10Henrik Grubbström (Grubba)  // FIXME: Should this error be propagated? catch { chmod( FNAME(a,b), 0666 ); };
c79b261998-02-05Johan Schön #endif
8afc811998-02-04Per Hedbor #endif
20ca2b1998-01-26Per Hedbor  if(!fd) return; fd->write(encode_value(({a,b,data}))); destruct(fd); }
8afc811998-02-04Per Hedbor array(int)|string write_text(int _args, string text, int size, object id)
d47cbf1996-12-02Per Hedbor {
68e0301997-08-19Per Hedbor  string key = base_key+_args;
7faa951997-09-01Per Hedbor  array err;
420fd91998-02-27Per Hedbor  string orig_text = text; mixed data; mapping args = find_cached_args(_args);
86352a1998-03-01Per Hedbor  if(!args) { throw( ({ "Internal error in gtext: Got request for non-existant gtext class", backtrace() }) ); }
420fd91998-02-27Per Hedbor  if(data = cache_lookup(key, text)) { if(args->nocache) // Remove from cache. Very useful for access counters cache_remove(key, text); if(size) return data[1]; return data[0]; } else if(data = get_cache_file( key, text )) { cache_set(key, text, data); if(size) return data[1];
86352a1998-03-01Per Hedbor  return data[0];
420fd91998-02-27Per Hedbor  }
86352a1998-03-01Per Hedbor  // So. We have to actually draw the thing...
7faa951997-09-01Per Hedbor  err = catch
ba73a21996-12-10Per Hedbor  {
7faa951997-09-01Per Hedbor  object img; if(!args) {
420fd91998-02-27Per Hedbor  args=(["fg":"black","bg":"white","notrans":"1"]);
7faa951997-09-01Per Hedbor  text="Please reload this page"; }
ce9d8d1997-09-06Per Hedbor 
06583f1997-09-03Per Hedbor  if(!args->verbatim) {
b1ab8d1997-12-23Per Hedbor  text = replace(text, nbsp, " "); text = simplify_text( text );
4b64471997-09-04Henrik Grubbström (Grubba)  string res="",nspace="",cspace="";
06583f1997-09-03Per Hedbor  foreach(text/"\n", string line) { cspace="";nspace=""; foreach(line/" ", string word) {
4b64471997-09-04Henrik Grubbström (Grubba)  string nonum;
06583f1997-09-03Per Hedbor  if(strlen(word) &&
4b64471997-09-04Henrik Grubbström (Grubba)  (nonum = replace(word, ({"1","2","3","4","5","6","7","8","9","0","."}), ({"","","","","","","","","","",""}))) == "") {
06583f1997-09-03Per Hedbor  cspace=nbsp+nbsp;
4b64471997-09-04Henrik Grubbström (Grubba)  if((strlen(word)-strlen(nonum)<strlen(word)/2) && (upper_case(word) == word)) { word=((word/"")*nbsp); } } else if(cspace!="") {
06583f1997-09-03Per Hedbor  cspace=" ";
4b64471997-09-04Henrik Grubbström (Grubba)  }
06583f1997-09-03Per Hedbor  res+=(nspace==cspace?nspace:" ")+word; if(cspace!="") nspace=cspace; 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})); }
20ca2b1998-01-26Per Hedbor 
420fd91998-02-27Per Hedbor // cache_set(key, text, "rendering");
b551e11996-12-10Per Hedbor 
48fa361997-04-05Per Hedbor #if efun(get_font)
7faa951997-09-01Per Hedbor  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); }
3a4d7e1997-09-03Per Hedbor  else if(args->font)
7faa951997-09-01Per Hedbor  {
3a4d7e1997-09-03Per Hedbor #endif
7faa951997-09-01Per Hedbor  string fkey = args->font+"/"+args->talign+"/"+args->xpad+"/"+args->ypad;
420fd91998-02-27Per Hedbor // data = cache_lookup("fonts", fkey); // if(!data) // {
7faa951997-09-01Per Hedbor  data = load_font(args->font, lower_case(args->talign||"left"), (int)args->xpad,(int)args->ypad);
420fd91998-02-27Per Hedbor // cache_set("fonts", fkey, data); // }
3a4d7e1997-09-03Per Hedbor #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;
dbcf851997-09-05Henrik Grubbström (Grubba)  data = get_font(roxen->QUERY(default_font),32,bold,italic,
3a4d7e1997-09-03Per Hedbor  lower_case(args->talign||"left"), (float)(int)args->xpad, (float)(int)args->ypad);
8e727d1997-03-11Per Hedbor  }
3a4d7e1997-09-03Per Hedbor #endif
d47cbf1996-12-02Per Hedbor 
dbcf851997-09-05Henrik Grubbström (Grubba)  if (!data) { roxen_perror("gtext: No font!\n");
20ca2b1998-01-26Per Hedbor // werror("no font found! < "+_args+" <"+text+">\n");
420fd91998-02-27Per Hedbor // cache_set(key, orig_text, 0);
dbcf851997-09-05Henrik Grubbström (Grubba)  return(0); }
7faa951997-09-01Per Hedbor  // Fonts and such are now initialized. img = make_text_image(args,data,text,id);
d47cbf1996-12-02Per Hedbor 
7faa951997-09-01Per Hedbor  // Now we have the image in 'img', or nothing.
20ca2b1998-01-26Per Hedbor  if(!img) { // werror("error while drawing image? (no image) < "+_args+" <"+text+">\n");
420fd91998-02-27Per Hedbor // cache_set(key, orig_text, 0);
20ca2b1998-01-26Per Hedbor  return 0; }
d47cbf1996-12-02Per Hedbor 
7faa951997-09-01Per Hedbor  int q = (int)args->quant||(args->background||args->texture?250:QUERY(cols));
c3655b1997-01-27Per Hedbor 
7faa951997-09-01Per Hedbor  if(q>255) q=255; if(q<3) q=3;
c3655b1997-01-27Per Hedbor 
d1f9661997-04-09Per Hedbor // Quantify
7faa951997-09-01Per Hedbor  if(!args->fs) {
d1f9661997-04-09Per Hedbor #ifdef QUANT_DEBUG
7faa951997-09-01Per Hedbor  print_colors(img->select_colors(q-1)+({parse_color(args->bg)}));
d1f9661997-04-09Per Hedbor #endif
7faa951997-09-01Per Hedbor  img = img->map_closest(img->select_colors(q-1)+({parse_color(args->bg)})); }
d1f9661997-04-09Per Hedbor 
7faa951997-09-01Per Hedbor  if(!args->scroll)
e8c29c1997-09-12Johan Schön  if(args->fadein)
7faa951997-09-01Per Hedbor  {
e8c29c1997-09-12Johan Schön  int amount=2, steps=10, delay=10, initialdelay=0, ox; string res = img->gif_begin(); sscanf(args->fadein, "%d,%d,%d,%d", amount, steps, delay, initialdelay); if(initialdelay) {
e5bad21998-02-10Per Hedbor  object foo=Image.image(img->xsize(),img->ysize(),@parse_color(args->bg));
e8c29c1997-09-12Johan Schön  res += foo->gif_add(0,0,initialdelay); }
29c5841997-10-03Johan Schön  for(int i = 0; i<(steps-1); i++)
e8c29c1997-09-12Johan Schön  { object foo=img->clone(); foo = foo->apply_matrix(make_matrix(( (int)((steps-i)*amount)))); res += foo->gif_add(0,0,delay); } res+= img->gif_add(0,0,delay); res += img->gif_end(); data = ({ res, ({ img->xsize(), img->ysize() }) });
7faa951997-09-01Per Hedbor  }
e8c29c1997-09-12Johan Schön  else { if(args->fs) data=({ img->togif_fs(@(args->notrans?({}):parse_color(args->bg))), ({img->xsize(),img->ysize()})}); else data=({ img->togif(@(args->notrans?({}):parse_color(args->bg))), ({img->xsize(),img->ysize()})}); img=0; } else { int len=100, steps=30, delay=5, ox; string res = img->gif_begin() + img->gif_netscape_loop(); sscanf(args->scroll, "%d,%d,%d", len, steps, delay); img=img->copy(0,0,(ox=img->xsize())+len-1,img->ysize()-1); img->paste(img, ox, 0); for(int i = 0; i<steps; i++) { int xp = i*ox/steps; res += img->copy(xp, 0, xp+len, img->ysize(), @parse_color(args->bg))->gif_add(0,0,delay); } res += img->gif_end(); data = ({ res, ({ len, img->ysize() }) });
85a2e51997-06-23Per Hedbor  }
e8c29c1997-09-12Johan Schön 
420fd91998-02-27Per Hedbor // place in caches, as a gif image. if(!args->nocache) store_cache_file( key, orig_text, data ); cache_set(key, orig_text, data);
7faa951997-09-01Per Hedbor  if(size) return data[1]; return data[0]; };
20ca2b1998-01-26Per Hedbor // werror("Got error < "+_args+" <"+text+">\n");
7faa951997-09-01Per Hedbor  cache_set(key, text, 0); throw(err);
d47cbf1996-12-02Per Hedbor }
f3a6b11998-02-22David Hedbor mapping find_file(string f, object rid); // Pike 0.5... void restore_cached_args(); // Pike 0.5...
41d0f91998-02-20Per Hedbor array stat_file(string f, object rid) { if(f[-1]=='/') f = f[..strlen(f)-2]; if(sizeof(f/"/")==1) return ({ 509,-3,time(),time(),time(),0,0 }); int len=4711; catch(len= strlen(find_file(f,rid)->data)); return ({ 33204,len,time(),time(),time(),0,0 }); } array find_dir(string f, object rid) { if(!strlen(f)) { restore_cached_args(); return Array.map(indices(cached_args), lambda(mixed m){return (string)m;}); } return ({"Example"}); }
d47cbf1996-12-02Per Hedbor  mapping find_file(string f, object rid) {
f6d62d1997-03-26Per Hedbor  int id;
41d0f91998-02-20Per Hedbor  if(rid->method != "GET") return 0;
d47cbf1996-12-02Per Hedbor  sscanf(f,"%d/%s", id, f);
974b2a1997-10-02Peter Bortas  if( query("gif") ) //Remove .gif f = f[..strlen(f)-5];
b8e11a1997-09-26Henrik Grubbström (Grubba)  if (sizeof(f)) { object g;
eb63921997-09-26Henrik Grubbström (Grubba)  if (f[0] == '$') { // Illegal in BASE64
1a67581997-09-26Henrik Grubbström (Grubba)  f = f[1..];
b8e11a1997-09-26Henrik Grubbström (Grubba)  } else if (sizeof(indices(g=Gz))) { catch(f = g->inflate()->inflate(MIME.decode_base64(f))); } else if (sizeof(f)) {
1a67581997-09-26Henrik Grubbström (Grubba)  catch(f = MIME.decode_base64(f)); }
7019771997-09-24Henrik Grubbström (Grubba)  }
1a67581997-09-26Henrik Grubbström (Grubba) 
f6d62d1997-03-26Per Hedbor  return http_string_answer(write_text(id,f,0,rid), "image/gif");
d47cbf1996-12-02Per Hedbor }
ce9d8d1997-09-06Per Hedbor mapping url_cache = ([]);
d47cbf1996-12-02Per Hedbor string quote(string in) {
7019771997-09-24Henrik Grubbström (Grubba)  string option;
1a67581997-09-26Henrik Grubbström (Grubba)  if(option = url_cache[in]) return option; object g;
7019771997-09-24Henrik Grubbström (Grubba)  if (sizeof(indices(g=Gz))) { option=MIME.encode_base64(g->deflate()->deflate(in)); } else { option=MIME.encode_base64(in); }
1a67581997-09-26Henrik Grubbström (Grubba)  if(search(in,"/")!=-1) return url_cache[in]=option;
eb63921997-09-26Henrik Grubbström (Grubba)  string res="$"; // Illegal in BASE64
d47cbf1996-12-02Per Hedbor  for(int i=0; i<strlen(in); i++) switch(in[i]) { case 'a'..'z': case 'A'..'Z': case '0'..'9':
06583f1997-09-03Per Hedbor  case '.': case ',': case '!':
d47cbf1996-12-02Per Hedbor  res += in[i..i]; break; default: res += sprintf("%%%02x", in[i]); }
ce9d8d1997-09-06Per Hedbor  if(strlen(res) < strlen(option)) return url_cache[in]=res; return url_cache[in]=option;
d47cbf1996-12-02Per Hedbor }
8afc811998-02-04Per Hedbor #define ARGHASH query("cache_dir")+"ARGS_"+hash(mc->name)
68e0301997-08-19Per Hedbor int args_restored = 0; void restore_cached_args() { args_restored = 1;
8afc811998-02-04Per Hedbor  object o = open(ARGHASH, "r");
68e0301997-08-19Per Hedbor  if(o) { string data = o->read(); catch {
d7b0871997-08-31Per Hedbor  object q; if(sizeof(indices(q=Gz))) data=q->inflate()->inflate(data);
68e0301997-08-19Per Hedbor  }; catch { cached_args |= decode_value(data); }; }
4f57021997-09-03Henrik Grubbström (Grubba)  if (cached_args && sizeof(cached_args)) {
06583f1997-09-03Per Hedbor  number = sort(indices(cached_args))[-1]+1;
4f57021997-09-03Henrik Grubbström (Grubba)  } else { cached_args = ([]); number = 0; }
68e0301997-08-19Per Hedbor } void save_cached_args() {
f7d9811997-09-12Per Hedbor  int on; on = number;
68e0301997-08-19Per Hedbor  restore_cached_args();
f7d9811997-09-12Per Hedbor  if(on > number) number=on;
8afc811998-02-04Per Hedbor  object o = open(ARGHASH, "wct");
c79b261998-02-05Johan Schön #ifndef __NT__
8afc811998-02-04Per Hedbor #if efun(chmod)
4c35411998-03-10Henrik Grubbström (Grubba)  // FIXME: Should this error be propagated? catch { chmod( ARGHASH, 0666 ); };
c79b261998-02-05Johan Schön #endif
8afc811998-02-04Per Hedbor #endif
68e0301997-08-19Per Hedbor  string data=encode_value(cached_args); catch {
d7b0871997-08-31Per Hedbor  object q; if(sizeof(indices(q=Gz))) data=q->deflate()->deflate(data);
68e0301997-08-19Per Hedbor  }; o->write(data); } mapping find_cached_args(int num) { if(!args_restored) restore_cached_args(); if(cached_args[num]) return cached_args[num]; restore_cached_args(); if(cached_args[num]) return cached_args[num]; return 0; }
d47cbf1996-12-02Per Hedbor  int find_or_insert(mapping find) {
f1be801998-02-22Per Hedbor  mapping f2 = copy_value(find); foreach(glob("magic_*", indices(f2)), string q) m_delete(f2,q);
8840de1998-02-27Per Hedbor  if(!args_restored) restore_cached_args();
d47cbf1996-12-02Per Hedbor  array a = indices(cached_args); array b = values(cached_args); int i;
f1be801998-02-22Per Hedbor 
df8d711998-02-27Per Hedbor  for(i=0; i<sizeof(a); i++) if(equal(f2, b[i])) return a[i]; restore_cached_args(); for(i=0; i<sizeof(a); i++) if(equal(f2, b[i])) return a[i];
d47cbf1996-12-02Per Hedbor  cached_args[number]=find;
68e0301997-08-19Per Hedbor  remove_call_out(save_cached_args); call_out(save_cached_args, 10);
d47cbf1996-12-02Per Hedbor  return number++; } string magic_javascript_header(object id) {
273a9a1997-10-17Johan Schön  if(!id->supports->netscape_javascript || !id->supports->images) return "";
d47cbf1996-12-02Per Hedbor  return
0943711997-02-25Per Hedbor  ("\n<script>\n"
e8790b1998-02-19Per Hedbor  "function i(ri,hi,txt)\n"
d47cbf1996-12-02Per Hedbor  "{\n"
0943711997-02-25Per Hedbor  " document.images[ri].src = hi.src;\n" " setTimeout(\"top.window.status = '\"+txt+\"'\", 100);\n"
d47cbf1996-12-02Per Hedbor  "}\n" "</script>\n");
6909c91997-09-22Johan Schön 
d47cbf1996-12-02Per Hedbor } string magic_image(string url, int xs, int ys, string sn, string image_1, string image_2, string alt,
b91fd51996-12-10Per Hedbor  string mess,object id,string input,string extra_args)
d47cbf1996-12-02Per Hedbor { if(!id->supports->images) return alt;
273a9a1997-10-17Johan Schön  if(!id->supports->netscape_javascript)
38dca81996-12-10Per Hedbor  return (!input)?
41d0f91998-02-20Per Hedbor  ("<a "+extra_args+"href=\""+url+"\"><img src=\""+image_1+"\" name="+sn+" border=0 "+
eab4221997-09-19Johan Schön  "alt=\""+alt+"\"></a>\n"):
f6d62d1997-03-26Per Hedbor  ("<input type=image "+extra_args+" src=\""+image_1+"\" name="+input+">");
d47cbf1996-12-02Per Hedbor  return ("<script>\n"
e8790b1998-02-19Per Hedbor  " "+sn+"l = new Image("+xs+", "+ys+");"+sn+"l.src = \""+image_1+"\";\n" " "+sn+"h = new Image("+xs+", "+ys+");"+sn+"h.src = \""+image_2+"\";\n"
38dca81996-12-10Per Hedbor  "</script>\n"+
ca0f081997-02-22Per Hedbor  ("<a "+extra_args+"href=\""+url+"\" "+ (input?"onClick='document.forms[0].submit();' ":"")
e8790b1998-02-19Per Hedbor  +"onMouseover=\"i('"+sn+"',"+sn+"h,'"+(mess||url)+"'); return true;\"\n"
41d0f91998-02-20Per Hedbor  "onMouseout='top.window.status=\"\";document.images[\""+sn+"\"].src = "+sn+"l.src;'><img " "width="+xs+" height="+ys+" src=\""+image_1+"\" name="+sn+
0943711997-02-25Per Hedbor  " border=0 alt=\""+alt+"\" ></a>\n"));
d47cbf1996-12-02Per Hedbor }
b91fd51996-12-10Per Hedbor  string extra_args(mapping in) { string s=""; foreach(indices(in), string i) { switch(i) { case "target":
bfc7071997-01-13Per Hedbor  case "hspace": case "vspace": case "onclick":
80739c1996-12-10Per Hedbor  s+=i+"='"+in[i]+"' ";
b91fd51996-12-10Per Hedbor  m_delete(in, i); break; } } return s; }
07969c1997-02-25Per Hedbor string tag_gtext_id(string t, mapping arg, object id, object foo, mapping defines) { int short=!!arg->short;
fc57521998-03-06Per Hedbor  if(arg->help) return "Arguments are identical to the argumets to &lt;gtext&gt;. This tag returns a url-prefix that can be used to generate gtexts.";
07969c1997-02-25Per Hedbor  m_delete(arg, "short"); m_delete(arg, "maxlen"); m_delete(arg,"magic"); m_delete(arg,"submit"); extra_args(arg); m_delete(arg,"split"); if(defines->fg && !arg->fg) arg->fg=defines->fg; if(defines->bg && !arg->bg) arg->bg=defines->bg;
48fa361997-04-05Per Hedbor #if efun(get_font)
f6d62d1997-03-26Per Hedbor  if(!arg->nfont) arg->nfont=defines->nfont;
48fa361997-04-05Per Hedbor #endif
3a4d7e1997-09-03Per Hedbor  if(!arg->font) arg->font=defines->font #if !efun(get_font) ||QUERY(default_font) #endif ;
07969c1997-02-25Per Hedbor  int num = find_or_insert( arg ); if(!short) return query_location()+num+"/"; else return (string)num; }
62d8c41997-10-16Per Hedbor string tag_graphicstext(string t, mapping arg, string contents, object id, object foo, mapping defines) { //Allow <accessed> and others inside <gtext>.
fc57521998-03-06Per Hedbor  if(t=="gtext" && arg->help)
610bf91998-03-07Fredrik Noring  return doc();
fc57521998-03-06Per Hedbor  else if(arg->help) return "This tag calls &lt;gtext&gt; with different default values.";
41d0f91998-02-20Per Hedbor  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);
974b2a1997-10-02Peter Bortas  string gif="";
62d8c41997-10-16Per Hedbor  if(query("gif")) gif=".gif";
974b2a1997-10-02Peter Bortas 
033c7e1997-02-27Per Hedbor #if efun(_static_modules) contents = parse_rxml(contents, id, foo, defines); #else contents = parse_rxml(contents, id, foo); #endif
62d8c41997-10-16Per Hedbor  string lp, url, ea;
d47cbf1996-12-02Per Hedbor  string pre, post, defalign, gt, rest, magic;
1bd5c91997-09-26Henrik Grubbström (Grubba)  int i; string split;
d47cbf1996-12-02Per Hedbor 
f1be801998-02-22Per Hedbor  // No images here, let's generate an alternative..
d47cbf1996-12-02Per Hedbor  if(!id->supports->images || id->prestate->noimages) { if(!arg->split) contents=replace(contents,"\n", "\n<br>\n");
974b2a1997-10-02Peter Bortas  if(arg->submit) return "<input type=submit name=\""+(arg->name+".x") + "\" value=\""+contents+"\">";
d47cbf1996-12-02Per Hedbor  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; } }
bfc7071997-01-13Per Hedbor  contents = contents[..((int)arg->maxlen||QUERY(deflen))]; m_delete(arg, "maxlen");
d47cbf1996-12-02Per Hedbor  if(arg->magic) {
d23e421997-05-08Per Hedbor  magic=replace(arg->magic,"'","`");
d47cbf1996-12-02Per Hedbor  m_delete(arg,"magic"); }
38dca81996-12-10Per Hedbor  int input; if(arg->submit) { input=1; m_delete(arg,"submit"); }
d47cbf1996-12-02Per Hedbor 
bfc7071997-01-13Per Hedbor 
80739c1996-12-10Per Hedbor  ea = extra_args(arg);
bfc7071997-01-13Per Hedbor 
0943711997-02-25Per Hedbor  // Modify the 'arg' mapping...
d47cbf1996-12-02Per Hedbor  if(arg->href) { url = arg->href;
80739c1996-12-10Per Hedbor  lp = "<a href=\""+arg->href+"\" "+ea+">";
d47cbf1996-12-02Per Hedbor  if(!arg->fg) arg->fg=defines->link||"#0000ff";
0943711997-02-25Per Hedbor  m_delete(arg, "href");
d47cbf1996-12-02Per Hedbor  } if(defines->fg && !arg->fg) arg->fg=defines->fg; if(defines->bg && !arg->bg) arg->bg=defines->bg;
f6d62d1997-03-26Per Hedbor  if(!arg->nfont) arg->nfont=defines->nfont;
f1be801998-02-22Per Hedbor  if(!arg->font) arg->font=defines->font;
f6d62d1997-03-26Per Hedbor  if(!arg->bold) arg->bold=defines->bold; if(!arg->italic) arg->italic=defines->italic; if(!arg->black) arg->black=defines->black; if(!arg->narrow) arg->narrow=defines->narrow;
d47cbf1996-12-02Per Hedbor  if(arg->split) {
f1be801998-02-22Per Hedbor  if (sizeof(split=arg->split) != 1)
1bd5c91997-09-26Henrik Grubbström (Grubba)  split = " ";
d47cbf1996-12-02Per Hedbor  m_delete(arg,"split"); } // Support for <gh 2> like things. for(i=2; i<10; i++) if(arg[(string)i]) { arg->scale = 1.0 / ((float)i*0.6); m_delete(arg, (string)i);
9d16ce1997-03-01Per Hedbor  break;
d47cbf1996-12-02Per Hedbor  } // Support for <gh1> like things. if(sscanf(t, "%s%d", t, i)==2) if(i > 1) arg->scale = 1.0 / ((float)i*0.6);
0943711997-02-25Per Hedbor  string na = arg->name, al=arg->align; m_delete(arg, "name"); m_delete(arg, "align");
d47cbf1996-12-02Per Hedbor  // Now the 'args' mapping is modified enough.. int num = find_or_insert( arg ); gt=contents; rest="";
f6d62d1997-03-26Per Hedbor  switch(t) { case "gh1": case "gh2": case "gh3": case "gh4": case "gh5": case "gh6": case "gh7": case "gh": pre="<p>"; post="<br>"; defalign="top"; break; case "gtext": pre=""; post=""; defalign="bottom"; break; case "anfang": gt=contents[0..0]; rest=contents[1..]; pre="<br clear=left>"; post=""; defalign="left"; break; }
d47cbf1996-12-02Per Hedbor  if(split) { string word;
bfb80b1997-09-26Henrik Grubbström (Grubba)  array res = ({ pre }); string pre = query_location() + num + "/";
d47cbf1996-12-02Per Hedbor  if(lp) res+=({ lp }); gt=replace(gt, "\n", " "); foreach(gt/" "-({""}), word) {
1bd5c91997-09-26Henrik Grubbström (Grubba)  if (split != " ") { array arr = word/split; int i;
f1be801998-02-22Per Hedbor  for (i = sizeof(arr)-1; i--;)
1bd5c91997-09-26Henrik Grubbström (Grubba)  arr[i] += split;
f1be801998-02-22Per Hedbor  if (arr[-1] == "")
1bd5c91997-09-26Henrik Grubbström (Grubba)  arr = arr[..sizeof(arr)-2]; foreach (arr, word) { array size = write_text(num,word,1,id);
41d0f91998-02-20Per Hedbor  res += ({ "<img border=0 alt=\"" +
bfb80b1997-09-26Henrik Grubbström (Grubba)  replace(arg->alt || word, "\"", "'") +
974b2a1997-10-02Peter Bortas  "\" src=\"" + pre + quote(word) + gif + "\" width=" +
bfb80b1997-09-26Henrik Grubbström (Grubba)  size[0] + " height=" + size[1] + " " + ea + ">"
1bd5c91997-09-26Henrik Grubbström (Grubba)  }); }
bfb80b1997-09-26Henrik Grubbström (Grubba)  res += ({"\n"});
1bd5c91997-09-26Henrik Grubbström (Grubba)  } else { array size = write_text(num,word,1,id);
41d0f91998-02-20Per Hedbor  res += ({ "<img border=0 alt=\"" +
bfb80b1997-09-26Henrik Grubbström (Grubba)  replace(arg->alt || word, "\"", "'") +
974b2a1997-10-02Peter Bortas  "\" src=\"" + pre + quote(word) + gif + "\" width=" +
bfb80b1997-09-26Henrik Grubbström (Grubba)  size[0] + " height=" + size[1] + " " + ea + ">\n"
1bd5c91997-09-26Henrik Grubbström (Grubba)  }); }
d47cbf1996-12-02Per Hedbor  }
bfb80b1997-09-26Henrik Grubbström (Grubba)  if(lp) res += ({ "</a>"+post });
d47cbf1996-12-02Per Hedbor  return res*""; }
9d16ce1997-03-01Per Hedbor  array size = write_text(num,gt,1,id);
f1be801998-02-22Per Hedbor  if(!size)
f7d9811997-09-12Per Hedbor  return ("<font size=+1><b>Missing font or other similar error -- " "failed to render text</b></font>");
f1be801998-02-22Per Hedbor 
d47cbf1996-12-02Per Hedbor  if(magic) { string res = "";
bfc7071997-01-13Per Hedbor  if(!arg->fg) arg->fg=defines->link||"#0000ff";
d47cbf1996-12-02Per Hedbor  arg = mkmapping(indices(arg), values(arg));
bfc7071997-01-13Per Hedbor  if(arg->fuzz) if(arg->fuzz != "fuzz") arg->glow = arg->fuzz; else arg->glow = arg->fg;
d47cbf1996-12-02Per Hedbor  arg->fg = defines->alink||"#ff0000";
9f67f31997-10-27Per Hedbor  if(arg->magicbg) arg->background = arg->magicbg;
38dca81996-12-10Per Hedbor  if(arg->bevel) arg->pressed=1;
0943711997-02-25Per Hedbor 
20ca2b1998-01-26Per Hedbor  foreach(glob("magic_*", indices(arg)), string q) { arg[q[6..]]=arg[q]; m_delete(arg, q); }
d47cbf1996-12-02Per Hedbor  int num2 = find_or_insert(arg);
9d16ce1997-03-01Per Hedbor  array size = write_text(num2,gt,1,id);
0943711997-02-25Per Hedbor 
38dca81996-12-10Per Hedbor  if(!defines->magic_java) res = magic_javascript_header(id);
d47cbf1996-12-02Per Hedbor  defines->magic_java="yes";
0943711997-02-25Per Hedbor 
e8790b1998-02-19Per Hedbor  return replace(res + magic_image(url||"", size[0], size[1], "i"+(defines->mi++), query_location()+num+"/"+quote(gt)+gif, query_location()+num2+"/"+quote(gt)+gif, (arg->alt?arg->alt:replace(gt, "\"","'")), (magic=="magic"?0:magic), id,input?na||"submit":0,ea), "</script>\n<script>","");
d47cbf1996-12-02Per Hedbor  }
ca0f081997-02-22Per Hedbor  if(input)
0943711997-02-25Per Hedbor  return (pre+"<input type=image name=\""+na+"\" border=0 alt=\""+
eab4221997-09-19Johan Schön  (arg->alt?arg->alt:replace(gt,"\"","'"))+
974b2a1997-10-02Peter Bortas  "\" src="+query_location()+num+"/"+quote(gt)+gif
0943711997-02-25Per Hedbor  +" align="+(al || defalign)+ea+
38dca81996-12-10Per Hedbor  " width="+size[0]+" height="+size[1]+">"+rest+post);
974b2a1997-10-02Peter Bortas  return (pre+(lp?lp:"")
41d0f91998-02-20Per Hedbor  + "<img border=0 alt=\""
219eec1998-02-02Jens Utbult  + (arg->alt?arg->alt:replace(gt,"\"","'"))
974b2a1997-10-02Peter Bortas  + "\" src=\"" + query_location()+num+"/"+quote(gt)+gif+"\" "+ea + " align="+(al || defalign) + " width="+size[0]+" height="+size[1]+">"+rest+(lp?"</a>":"")+post);
d47cbf1996-12-02Per Hedbor }
bfc7071997-01-13Per Hedbor inline string ns_color(array (int) col) { if(!arrayp(col)||sizeof(col)!=3) return "#000000"; return sprintf("#%02x%02x%02x", col[0],col[1],col[2]); } string make_args(mapping in) { array a=indices(in), b=values(in); for(int i=0; i<sizeof(a); i++) if(lower_case(b[i])!=a[i]) if(search(b,"\"")==-1) a[i]+="=\""+b[i]+"\""; else a[i]+="='"+b[i]+"'"; return a*" "; }
fc57521998-03-06Per Hedbor string|array (string) tag_body(string t, mapping args, object id, object file, mapping defines)
d47cbf1996-12-02Per Hedbor {
bfc7071997-01-13Per Hedbor  int cols,changed;
fc57521998-03-06Per Hedbor  if(args->help) return "This tag is parsed by &lt;gtext&gt; to get the document colors.";
bfc7071997-01-13Per Hedbor  if(args->bgcolor||args->text||args->link||args->alink ||args->background||args->vlink) cols=1;
40325f1997-12-17Henrik Grubbström (Grubba) #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)
bfc7071997-01-13Per Hedbor 
0ee0851997-02-08Per Hedbor  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); }
0fb7be1998-02-27Per Hedbor  if(changed) return ({make_tag("body", args) });
d47cbf1996-12-02Per Hedbor }
196dac1997-02-22Per Hedbor 
fc57521998-03-06Per Hedbor string|array(string) tag_fix_color(string tagname, mapping args, object id, object file, mapping defines)
bfc7071997-01-13Per Hedbor { int changed;
196dac1997-02-22Per Hedbor 
fc57521998-03-06Per Hedbor  if(args->help) return "This tag is parsed by &lt;gtext&gt; to get the document colors.";
196dac1997-02-22Per Hedbor  if(!id->misc->colors)
5f0d911997-02-27Per Hedbor  id->misc->colors = ({ ({ defines->fg, defines->bg, tagname }) });
196dac1997-02-22Per Hedbor  else
5f0d911997-02-27Per Hedbor  id->misc->colors += ({ ({ defines->fg, defines->bg, tagname }) });
f7d9811997-09-12Per Hedbor #undef FIX
52c8541997-12-19Henrik Grubbström (Grubba) #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;}}
bfc7071997-01-13Per Hedbor  FIX(bgcolor,bg); FIX(text,fg); FIX(color,fg);
41d0f91998-02-20Per Hedbor  if(changed) return ({"<"+tagname+" "+make_args(args)+">"});
bfc7071997-01-13Per Hedbor  return 0; }
d47cbf1996-12-02Per Hedbor 
fc57521998-03-06Per Hedbor string|void pop_color(string tagname,mapping args,object id,object file,
196dac1997-02-22Per Hedbor  mapping defines) { array c = id->misc->colors;
fc57521998-03-06Per Hedbor  if(args->help) return "This end-tag is parsed by &lt;gtext&gt; to get the document colors.";
2892dd1998-02-27Per Hedbor  if(!c ||!sizeof(c)) return;
df8d711998-02-27Per Hedbor  int i; tagname = tagname[1..]; for(i=0;i<sizeof(c);i++) if(c[-i-1][2]==tagname)
5f0d911997-02-27Per Hedbor  {
df8d711998-02-27Per Hedbor  defines->fg = c[-i-1][0]; defines->bg = c[-i-1][1];
5f0d911997-02-27Per Hedbor  break; }
df8d711998-02-27Per Hedbor  c = c[..-i-2];
5f0d911997-02-27Per Hedbor  id->misc->colors = c;
196dac1997-02-22Per Hedbor }
bfc7071997-01-13Per Hedbor mapping query_tag_callers()
d47cbf1996-12-02Per Hedbor {
fe21a71997-08-25Per Hedbor  return ([ "gtext-id":tag_gtext_id, ]) | (query("speedy")?([]):
f7d9811997-09-12Per Hedbor  (["font":tag_fix_color, "body":tag_body,
bfc7071997-01-13Per Hedbor  "table":tag_fix_color,
196dac1997-02-22Per Hedbor  "tr":tag_fix_color, "td":tag_fix_color,
5f0d911997-02-27Per Hedbor  "layer":tag_fix_color, "ilayer":tag_fix_color,
196dac1997-02-22Per Hedbor  "/td":pop_color, "/tr":pop_color, "/font":pop_color, "/body":pop_color, "/table":pop_color,
5f0d911997-02-27Per Hedbor  "/layer":pop_color,
f7d9811997-09-12Per Hedbor  "/ilayer":pop_color, ]));
d47cbf1996-12-02Per Hedbor } mapping query_container_callers() { return ([ "anfang":tag_graphicstext, "gh":tag_graphicstext,
bfc7071997-01-13Per Hedbor  "gh1":tag_graphicstext, "gh2":tag_graphicstext, "gh3":tag_graphicstext, "gh4":tag_graphicstext, "gh5":tag_graphicstext, "gh6":tag_graphicstext,
d47cbf1996-12-02Per Hedbor  "gtext":tag_graphicstext, ]); }