f668602000-03-02Martin Nilsson // This is a roxen module. Copyright © 1996 - 2000, Roxen IS.
e954162000-01-02Martin Nilsson //
03cbf72000-03-25Martin Nilsson constant cvs_version="$Id: graphic_text.pike,v 1.225 2000/03/25 02:30:19 nilsson Exp $";
ebf60d1997-03-08Henrik Grubbström (Grubba) 
d47cbf1996-12-02Per Hedbor #include <module.h> inherit "module"; inherit "roxenlib";
a3dfd41999-11-28Martin Nilsson  // ------------------- Module registration ---------------------
654fca1999-10-04Martin Bähr 
7e471e2000-01-05Martin Nilsson constant module_type = MODULE_PARSER; constant module_name = "Graphics text"; constant module_doc = "Generates graphical texts."; constant thread_safe = 1;
0a76aa1998-03-27David Hedbor 
d47cbf1996-12-02Per Hedbor void create() {
39af1a1998-08-26Per Hedbor  defvar("colorparse", 1, "Parse tags for document colors", TYPE_FLAG, "If set, parse the specified tags for document colors.");
a3dfd41999-11-28Martin Nilsson 
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.");
a3dfd41999-11-28Martin Nilsson  defvar("ext", 0, "Append .fmt (gif, jpeg etc) to all images",
8b6ee51999-07-10Peter Bortas  TYPE_FLAG|VAR_MORE,
9374e61999-05-18Per Hedbor  "Append .gif, .png, .gif etc to all images made by gtext. " "Normally this will only waste bandwidth");
d47cbf1996-12-02Per Hedbor }
f02c0c1999-12-11Martin Nilsson TAGDOCUMENTATION;
2e0a351999-12-09Martin Nilsson #ifdef manual
e59a5a2000-03-01Kenneth Johansson constant gtextargs=#" <attr name=afont>
7519ad2000-03-16Martin Nilsson 
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=alpha value=path> Use the specified image as an alpha channel, together with the background attribute. </attr> <attr name=background value=path> Specifies the image to use as background. </attr> <attr name=bevel value=width>
91aa992000-03-16Martin Nilsson  Draws a bevel-box around the text. <ex type=vert> <gtext bevel=\"2\">Ok</gtext> </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=bgcolor value=color> Sets the background color. Normally taken from the normal HTML tags in your document (Currently: body, table, tr or td). <p>If you set the background color, it is probably best to add the notrans attribute as well.</p>
7519ad2000-03-16Martin Nilsson  <ex type=vert> <gtext notrans=\"\" bgcolor=\"pink\">Pink</gtext> <gtext notrans=\"\" bgcolor=\"#ff0000\">Red</gtext> <gtext notrans=\"\" bgcolor=\"%50,0,100,0\">%50,0,100,0</gtext> </ex>
e59a5a2000-03-01Kenneth Johansson </attr>
7519ad2000-03-16Martin Nilsson <attr name=bgturbulence value=frequency,color;frequency,color...>
91aa992000-03-16Martin Nilsson  Apply a turbulence effect on the background.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=black> Use a black, or heavy, version of the font, if available. </attr> <attr name=bold> Use a bold version of the font, if available. </attr> <attr name=bshadow value=distance> Draw a blured black drop-shadow behind the text. Using 0 as distance does not currently place the shadow directly below the text. Using negative values for distance is possible, but you might have to add 'spacing'. <ex type=vert>
91aa992000-03-16Martin Nilsson <gtext scale=\"0.8\" fgcolor=\"#FF6600\" bshadow=\"1\">&lt;gtext bshadow=1&gt;</gtext><br /> <gtext scale=\"0.8\" fgcolor=\"#FF6600\" bshadow=\"2\">&lt;gtext bshadow=2&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=chisel> Make the text look like it has been cut into the background. <ex type=vert>
91aa992000-03-16Martin Nilsson <gtext bold=\"\" ypad=\"-40%\" xpad=\"-20%\" chisel=\"\" talign=\"center\"
7519ad2000-03-16Martin Nilsson opaque=\"70\" fgcolor=\"gold\" bevel=\"2\" background=\"tiles.jpg\"> Chisel opaque=70</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=crop> Remove all white-space around the image </attr>
91aa992000-03-16Martin Nilsson <attr name=encoding value=string> Choose with which charset the text is encoded with.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=fadein value=blur,steps,delay,initialdelay> Generates an animated GIF file of a fade-in effect. </attr> <attr name=fgcolor value=color> Sets the text color. <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext fgcolor=\"#0080FF\">#0080FF</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
91aa992000-03-16Martin Nilsson <attr name=font value=string>
e59a5a2000-03-01Kenneth Johansson  </attr>
91d6cd2000-03-21Martin Nilsson <attr name=fontsize value=number>
e59a5a2000-03-01Kenneth Johansson  </attr>
91aa992000-03-16Martin Nilsson <attr name=format value=string> Set the image format, e.g. \"png\".
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=fs> Apply floyd-steinberg dithering to the resulting image. Most of the time it is much better to increase the number of colors, instead of dithering the image, but sometimes when using very complex background images dithering is O.K. </attr> <attr name=ghost value=dist,blur,color> Apply a ghost effect. Cannot be used together with shadow or magic coloring. <ex type=vert>
91aa992000-03-16Martin Nilsson <gtext spacing=\"2\" crop=\"\" ghost=\"1,1,red\">ghost=1,1,red</gtext> <gtext spacing=\"2\" crop=\"\" ghost=\"1,3,blue\">ghost=1,3,blue</gtext>
7519ad2000-03-16Martin Nilsson <gtext spacing=\"2\" crop=\"\" bshadow=\"1\" opaque=\"90\" ghost=\"-1,1,yellow\">ghost=-1,1,yellow opaque=90 bshadow=1</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=glow value=color> Apply a 'glow' filter to the image. Quite a CPU eater. Looks much better on a dark background, where a real 'glow' effect can be achieved. <ex type=vert>
91aa992000-03-16Martin Nilsson <gtext glow=\"red\">&lt;gtext glow=red&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=italic> Use an italic version of the font, if available. </attr> <attr name=light> Use a light version of the font, if available. </attr> <attr name=maxlen value=number> Sets the maximum length of the text that will be rendered into an image, by default 300. </attr> <attr name=mirrortile> Tiles the background and foreground images around x-axis and y-axis for odd frames, creating seamless textures. </attr> <attr name=move value=x,y> Moves the text relative to the upper left corner of the background image. This will not change the size of the image. </attr> <attr name=narrow>
91aa992000-03-16Martin Nilsson  Use a narroe version of the font, if available.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=nfont value=fontname> Select a font using somewhat more memonic font-names. You can get a font-list by accessing the configuration interface. <p>There are several modifiers available: bold, italic, black and light. If the requested version of the font is available, it will be used to render the text, otherwise the closest match will be used.</p> <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext nfont=\"futura\" light=\"\" >Light</gtext> <gtext nfont=\"futura\" light=\"\" italic=\"\">Italic</gtext> <gtext nfont=\"futura\" >Normal</gtext> <gtext nfont=\"futura\" italic=\"\" >Italic</gtext> <gtext nfont=\"futura\" bold=\"\" >Bold</gtext> <gtext nfont=\"futura\" bold=\"\" italic=\"\">Italic</gtext> <gtext nfont=\"futura\" black=\"\" >Black</gtext> <gtext nfont=\"futura\" black=\"\" italic=\"\">Italic</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=notrans> Do not make the background transparent. Useful when making 'boxes' of color around the text. <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext bgcolor=\"red\">&lt;gtext bgcolor=red&gt;</gtext> <gtext bgcolor=\"red\" notrans=\"\">&lt;gtext bgcolor=red notrans&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=nowhitespace>
91aa992000-03-16Martin Nilsson  Removes all whitespaces before and after the real text.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=opaque value=percentage>
91aa992000-03-16Martin Nilsson  Sets the 'opaque' value of the color used to draw the text. Default is 100%. In the example below, notice how the text color mixes with the two background colors <ex type=vert> <gtext scale=\"0.6\" textbox=\"100,pink,-11\" bgcolor=\"lightblue\" notrans=\"\" opaque=\"40\" fgcolor=\"black\">&lt;Demonstration of opaque text&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
91aa992000-03-16Martin Nilsson <attr name=outline value=color,extra-radius> Draw an outline around the text. Quite useful when combined with textscale. <ex type=vert>
a1de512000-03-20Martin Nilsson <gtext xspacing=\"4\" quant=\"128\" textscale=\"red,red,yellow,yellow\" outline=\"black,1\">black, 2 pixels</gtext>
91aa992000-03-16Martin Nilsson  </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=pressed> Inverts the direction of the bevel box, to make it look like a button
91aa992000-03-16Martin Nilsson  that is pressed down. The magic modifier will do this automatically.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=quant value=number>
91aa992000-03-16Martin Nilsson  Quantifies the image with this number of colors. Using a lower number will decrease the image (file)size, but make the text look more 'edgy', and if you use complex backgrounds or image textures, more colors will be neded. At most 255 colors can be used, and less than 2 is quite useless. It is advisable to use powers of 2 to optimize the palette allocation. <ex type=vert> <gtext quant=\"2\">A</gtext> <gtext quant=\"6\">A</gtext> <gtext quant=\"20\">A</gtext> <gtext quant=\"200\">A</gtext> </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=rescale> Rescale the background to fill the whole image. </attr> <attr name=rotate value=angle> Rotates the image this number of degrees counter-clockwise. </attr> <attr name=scale value=number>
f668602000-03-02Martin Nilsson  Sets the scale of the image. Larger than 1.0 is enlargement.
e59a5a2000-03-01Kenneth Johansson  <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext scale=\"1.0\">&lt;gtext scale=1.0&gt;</gtext> <gtext scale=\"0.5\">&lt;gtext scale=0.5&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=scolor value=color> Use this color for the shadow. Used with the shadow attribute. </attr> <attr name=scroll value=width,steps,delay> Generate an animated GIF image of the text scrolling. </attr> <attr name=shadow value=intensity,distance>
91aa992000-03-16Martin Nilsson  Draw a blured black drop-shadow behind the text. Using 0 as distance does not currently place the shadow directly below the text. Using negative values for distance is possible, <ex type=vert> <gtext scale=\"0.8\" fgcolor=\"blue\" shadow=\"40,0\">&lt;gtext shadow=40,0&gt;</gtext><br /> <gtext scale=\"0.8\" fgcolor=\"blue\" shadow=\"40,2\">&lt;gtext shadow=40,2&gt;</gtext><br /> </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=size value=width,height> Set the size of the image. </attr> <attr name=spacing value=number> Add space around the text. </attr>
91d6cd2000-03-21Martin Nilsson <attr name=talign value=left|right|center>
e59a5a2000-03-01Kenneth Johansson  Adjust the alignment of the text. </attr> <attr name=textbelow value=color>
f2f19d2000-03-16Martin Stjernholm  Place the text centered in a box of the given color below the image area. Useful together with background to make captions for images.
91aa992000-03-16Martin Nilsson  <ex type=vert> <gtext scale=\"0.5\" background=\"internal-roxen-roxen\" textbelow=\"#c0c0c0\">Roxen</gtext> </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=textbox value=opaque,color> Draw a box with an opaque value below the text of the specified color. </attr>
91aa992000-03-16Martin Nilsson <attr name=textscale value=color,color,color,color> Apply a color filter to the text. The colors are, respectively, upper left, lower left, upper right and lower right. It is probably a good idea to increase the 'quant' value when using this argument. <ex type=vert>
a1de512000-03-20Martin Nilsson <gtext quant=\"128\" textscale=\"blue,red,black,darkgreen\">Blue, red, black, darkgreen</gtext>
91aa992000-03-16Martin Nilsson  </ex> </attr>
e59a5a2000-03-01Kenneth Johansson <attr name=texture value=path> Uses the specified images as a field texture. </attr> <attr name=tile> Tiles the background and foreground images if they are smaller than the actual image. </attr> <attr name=verbatim> Allows the gtext parser to not be typographically correct. </attr> <attr name=xpad value=percentage>
91aa992000-03-16Martin Nilsson  Sets the padding between characters. <ex type=vert> <gtext xpad=\"-30%\" scale=\"0.6\">&lt;gtext xpad=-30%&gt;</gtext><br /> <gtext xpad=\"-10%\" scale=\"0.6\">&lt;gtext xpad=-10%&gt;</gtext><br /> <gtext scale=\"0.6\">&lt;gtext&gt;</gtext><br /> <gtext xpad=\"10%\" scale=\"0.6\">&lt;gtext xpad=10%&gt;</gtext><br /> <gtext xpad=\"30%\" scale=\"0.6\">&lt;gtext xpad=30%&gt;</gtext><br /> </ex>
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=xsize value=number> Sets the width. </attr> <attr name=xspacing value=number> Sets the horizontal spacing. </attr>
91aa992000-03-16Martin Nilsson <attr name=ypad value=percentage> Sets the padding beteen lines.
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=ysize value=number> Sets the height. </attr> <attr name=yspacing value=number> Sets the vertical spacing. </attr>"; constant tagdoc=([
03cbf72000-03-25Martin Nilsson "anfang":#"<desc cont></desc> <ex type=vert><anfang crop=\"\">This is a beginning<br /> of a very short text,<br /> and here it ends.</ex> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh1":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh2":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh3":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh4":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh5":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
03cbf72000-03-25Martin Nilsson "gh6":#"<desc cont></desc> <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson  "gtext":#"<desc cont> Renders a GIF image of the contents. </desc> <attr name=alt value=string> Sets the alt attribute of the generated <tag>img</tag> tag. By default the alt attribute will be set to the contents of the <tag>gtext</tag> tag. <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext fgcolor=\"blue\" alt=\"Hello!\">Welcome!</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=border value=width,color> Draws a border around the text of the specified width and color. <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext fgcolor=\"blue\" border=\"2,red\">Red border</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=href value=URL> Link the image to the specified URL. The link color of the document will be used as the default foreground rather than the foreground color. </attr> <attr name=magic value=message> Used together with the href attribute to generate a JavaScript that will highlight the image when the mouse is moved over it. The message is shown in the browser's status bar. <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext href=\"http://www.roxen.com\" magic=\"Roxen\">www.roxen.com</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
7519ad2000-03-16Martin Nilsson <attr name=magic-attribute value=value> Same as for any
e59a5a2000-03-01Kenneth Johansson  <tag>gtext</tag> attribute, except for the highlighted image. <ex type=vert>
91aa992000-03-16Martin Nilsson <gtext fgcolor=\"blue\" magic-glow=\"yellow\" magic=\"\">Magic_attribute</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=noxml>
91aa992000-03-16Martin Nilsson  Do not terminate the image tag with \"/\".
e59a5a2000-03-01Kenneth Johansson </attr> <attr name=split> <gtext scale=0.4 split>Make each word into a separate gif image. Useful if you are writing a large text, and word wrap at the edges of the display is desired. This text is an example (try resisizing your browser window, the images should move just like normal text would)</gtext> <p>This will allow the browser to word-wrap the text, but will disable certain attributes like magic.</p> <ex type=vert>
7519ad2000-03-16Martin Nilsson <gtext scale=\"0.4\" split=\"\">Make each word..</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr> <attr name=submit> Creates a submit-button for forms. Does not work together with split or magic arguments.
7519ad2000-03-16Martin Nilsson </attr>"+gtextargs,
e59a5a2000-03-01Kenneth Johansson  "gtext-id":#"<desc tag></desc> <attr name=href value=URL> Link the image to the specified URL. The link color of the document will be used as the default foreground rather than the foreground color. </attr> <attr name=short>
7519ad2000-03-16Martin Nilsson </attr>"+gtextargs,
e59a5a2000-03-01Kenneth Johansson  "gtext-url":#"<desc cont></desc> <attr name=href value=URL> Link the image to the specified URL. The link color of the document will be used as the default foreground rather than the foreground color. </attr> <attr name=short>
03cbf72000-03-25Martin Nilsson </attr> <noex>"+gtextargs+"</noex>",]);
2e0a351999-12-09Martin Nilsson #endif
a3dfd41999-11-28Martin Nilsson  // -------------------- Image cache functions --------------------
9374e61999-05-18Per Hedbor roxen.ImageCache image_cache;
e5bad21998-02-10Per Hedbor 
e954162000-01-02Martin Nilsson string status() { array s=image_cache->status(); return sprintf("<b>Images in cache:</b> %d images<br>\n<b>Cache size:</b> %s", s[0]/2, sizetostring(s[1])); }
7e471e2000-01-05Martin Nilsson void start(int num, Configuration conf)
2468b21997-07-06Henrik Grubbström (Grubba) {
9374e61999-05-18Per Hedbor  image_cache = roxen.ImageCache( "gtext", draw_callback );
23f8eb2000-02-16Per Hedbor  roxen.dump( "etc/modules/GText.pmod" );
7e471e2000-01-05Martin Nilsson  if(query("colorparse")) module_dependencies(conf, ({ "wiretap" }) );
2468b21997-07-06Henrik Grubbström (Grubba) }
c3655b1997-01-27Per Hedbor 
b1ab8d1997-12-23Per Hedbor constant nbsp = iso88591["&nbsp;"];
db46c81999-06-10Jonas Wallden constant replace_from = indices( iso88591 )+ ({"&ss;","&lt;","&gt;","&amp;",});
a3dfd41999-11-28Martin Nilsson constant replace_to = values( iso88591 ) + ({ nbsp, "<", ">", "&", });
b1ab8d1997-12-23Per Hedbor  #define simplify_text( from ) replace(from,replace_from,replace_to)
06583f1997-09-03Per Hedbor 
a3dfd41999-11-28Martin Nilsson mixed draw_callback(mapping args, string text, RequestID id)
20ca2b1998-01-26Per Hedbor {
f02c0c1999-12-11Martin Nilsson  array data; Image.Font font;
38569c1999-12-07Martin Nilsson  Image.Image img;
9374e61999-05-18Per Hedbor 
6a9b9d1999-06-25Per Hedbor  if( objectp( text ) ) { if( !args->text ) error("Failed miserably to find a text to draw. That's not"
8b6ee51999-07-10Peter Bortas  " good.\n");
6a9b9d1999-06-25Per Hedbor  id = (object)text; text = args->text; }
9374e61999-05-18Per Hedbor  if(!args->verbatim) // typographically correct...
ba73a21996-12-10Per Hedbor  {
9374e61999-05-18Per Hedbor  text = replace(text, nbsp, " "); text = simplify_text( text ); string res="",nspace="",cspace=""; foreach(text/"\n", string line)
a5c21b1999-05-18Peter Bortas  {
38569c1999-12-07Martin Nilsson  cspace=""; nspace="";
9374e61999-05-18Per Hedbor  foreach(line/" ", string word)
e8c29c1997-09-12Johan Schön  {
9374e61999-05-18Per Hedbor  string nonum; if(strlen(word) && (nonum = replace(word, ({"1","2","3","4","5","6","7","8","9","0","."}), ({"","","","","","","","","","",""}))) == "") { cspace=nbsp+nbsp; if((strlen(word)-strlen(nonum)<strlen(word)/2) &&
38569c1999-12-07Martin Nilsson  (upper_case(word) == word))
9374e61999-05-18Per Hedbor  word=((word/"")*nbsp); }
38569c1999-12-07Martin Nilsson  else if(cspace!="") cspace=" ";
9374e61999-05-18Per Hedbor  res+=(nspace==cspace?nspace:" ")+word;
38569c1999-12-07Martin Nilsson  if(cspace!="") nspace=cspace; else nspace=" ";
1cd5eb1998-03-20Per Hedbor  }
9374e61999-05-18Per Hedbor  res+="\n";
1cd5eb1998-03-20Per Hedbor  }
9374e61999-05-18Per Hedbor  text=replace(res[..strlen(res)-2], ({"!","?",": "}),({ nbsp+"!",nbsp+"?",nbsp+": "}));
a3dfd41999-11-28Martin Nilsson  text=replace(replace(replace(text,({". ",". "+nbsp}),
9374e61999-05-18Per Hedbor  ({"\000","\001"})),".","."+nbsp+nbsp), ({"\000","\001"}),({". ","."+nbsp})); }
e8c29c1997-09-12Johan Schön 
9374e61999-05-18Per Hedbor  if( args->afont )
a1de512000-03-20Martin Nilsson  font = resolve_font((args->afont||args->font)+" "+(args["fontsize"]||32));
9374e61999-05-18Per Hedbor  else
a5c21b1999-05-18Peter Bortas  {
38569c1999-12-07Martin Nilsson  int bold=0, italic=0;
5fe8d82000-01-30Per Hedbor  if(args->nfont) args->font = args->nfont;
9374e61999-05-18Per Hedbor  if(args->bold) bold=1; if(args->light) bold=-1; if(args->black) bold=2; if(args->italic) italic=1;
5fe8d82000-01-30Per Hedbor  font = get_font(args->font||"default",
a1de512000-03-20Martin Nilsson  (int)args["fontsize"]||32,
5fe8d82000-01-30Per Hedbor  bold, italic,
9374e61999-05-18Per Hedbor  lower_case(args->talign||"left"),
5fe8d82000-01-30Per Hedbor  (float)args->xpad, (float)args->ypad);
a5c21b1999-05-18Peter Bortas  }
5fe8d82000-01-30Per Hedbor  if(!font) font = resolve_font(0);
974b2a1997-10-02Peter Bortas 
f02c0c1999-12-11Martin Nilsson  if (!font)
5fe8d82000-01-30Per Hedbor  error("gtext: No font (tried "+ (args->afont||args->font||args->nfont)+ ")!\n");
1a67581997-09-26Henrik Grubbström (Grubba) 
9374e61999-05-18Per Hedbor  // Fonts and such are now initialized.
6cd13a2000-03-14Martin Stjernholm  [img, Image.Image alpha] = GText.make_text_image(args, font, text, id);
9558e31998-07-04Per Hedbor 
e954162000-01-02Martin Nilsson  // Now we have the image in 'img'.
a5c21b1999-05-18Peter Bortas 
9374e61999-05-18Per Hedbor  if( !args->scroll && !args->fadein ) { if(!args->notrans)
a5c21b1999-05-18Peter Bortas  {
9374e61999-05-18Per Hedbor  return ([ "img":img, "alpha":alpha ]);
a5c21b1999-05-18Peter Bortas  }
9374e61999-05-18Per Hedbor  return img; }
a5c21b1999-05-18Peter Bortas 
9374e61999-05-18Per Hedbor  if(args->fadein)
a5c21b1999-05-18Peter Bortas  {
9374e61999-05-18Per Hedbor  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)
a5c21b1999-05-18Peter Bortas  {
f02c0c1999-12-11Martin Nilsson  Image.Image foo=Image.Image(img->xsize(),img->ysize(),@parse_color(args->bgcolor));
9374e61999-05-18Per Hedbor  res += foo->gif_add(0,0,initialdelay);
a5c21b1999-05-18Peter Bortas  }
9374e61999-05-18Per Hedbor  for(int i = 0; i<(steps-1); i++) {
f02c0c1999-12-11Martin Nilsson  Image.Image foo=img->clone();
742aab1999-12-14Martin Nilsson  foo = foo->apply_matrix(GText.make_matrix(( (int)((steps-i)*amount))));
9374e61999-05-18Per Hedbor  res += foo->gif_add(0,0,delay);
a5c21b1999-05-18Peter Bortas  }
f02c0c1999-12-11Martin Nilsson  res += img->gif_add(0,0,delay);
9374e61999-05-18Per Hedbor  res += img->gif_end(); data = ({ res, ({ img->xsize(), img->ysize() }) });
a5c21b1999-05-18Peter Bortas  }
a3dfd41999-11-28Martin Nilsson  else
a5c21b1999-05-18Peter Bortas  {
9374e61999-05-18Per Hedbor  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(),
b89ccb1999-11-28Martin Nilsson  @parse_color(args->bgcolor))->gif_add(0,0,delay);
9374e61999-05-18Per Hedbor  } res += img->gif_end(); data = ({ res, ({ len, img->ysize() }) });
a5c21b1999-05-18Peter Bortas  }
a3dfd41999-11-28Martin Nilsson  return ([ "data":data[0],
df8c031999-05-25Per Hedbor  "meta":
9374e61999-05-18Per Hedbor  ([ "xsize":data[1][0], "ysize":data[1][1],
a3dfd41999-11-28Martin Nilsson  "type":(args->format?id->conf->type_from_filename("x."+args->format):"image/gif"),
9374e61999-05-18Per Hedbor  ]) ]);
68e0301997-08-19Per Hedbor }
f02c0c1999-12-11Martin Nilsson mapping find_internal(string f, RequestID id)
a5c21b1999-05-18Peter Bortas {
a3dfd41999-11-28Martin Nilsson  if( strlen(f)>4 && query("ext") && f[-4]=='.') // Remove .ext
9374e61999-05-18Per Hedbor  f = f[..strlen(f)-5];
0ee5ab1999-09-05Per Hedbor  if( strlen(f) && f[0]=='$' )
8b6ee51999-07-10Peter Bortas  { array id_text = f/"/"; if( sizeof(id_text)==2 ) { // It's a gtext-id
0ee5ab1999-09-05Per Hedbor  string second_key = roxen->argcache->store( (["":id_text[1]]) );
f02c0c1999-12-11Martin Nilsson  return image_cache->http_file_answer( id_text[0][1..] +"$"+ second_key, id );
8b6ee51999-07-10Peter Bortas  } }
f02c0c1999-12-11Martin Nilsson  return image_cache->http_file_answer( f, id );
a5c21b1999-05-18Peter Bortas }
d47cbf1996-12-02Per Hedbor 
a3dfd41999-11-28Martin Nilsson // -------------- helpfunctions to gtext tags and containers -----------------
b89ccb1999-11-28Martin Nilsson constant filearg=({"background","texture","alpha","magic-texture","magic-background","magic-alpha"});
a3dfd41999-11-28Martin Nilsson constant textarg=({"afont", "alpha", "bevel",
b89ccb1999-11-28Martin Nilsson  "bgcolor",
fc9c282000-01-12Martin Nilsson  "bgturbulence",
a3dfd41999-11-28Martin Nilsson  "black", "bold", "bshadow", "chisel", "encoding", "fadein",
b89ccb1999-11-28Martin Nilsson  "fgcolor",
a3dfd41999-11-28Martin Nilsson  "font",
a1de512000-03-20Martin Nilsson  "fontsize",
a3dfd41999-11-28Martin Nilsson  "ghost", "glow", "italic", "light", "mirrortile",
c3aacd1999-12-06Peter Bortas  "move",
a3dfd41999-11-28Martin Nilsson  "narrow", "nfont", "notrans", "opaque", "outline", "pressed", "rescale", "rotate", "scale", "scolor", "scroll", "shadow", "size", "spacing", "talign", "tile", "textbox", "textbelow", "textscale", "verbatim", "xpad", "xsize", "xspacing", "ypad", "ysize",
319dec2000-03-18Per Hedbor  "yspacing", "border",
d7e7f82000-03-18Per Hedbor  /* generic argcache arguments */ "crop", "format", "quant", "dither", "fs", "*-*", "gamma",
a3dfd41999-11-28Martin Nilsson });
7e471e2000-01-05Martin Nilsson constant theme=({"fgcolor","bgcolor","font"});
22cbbd2000-02-29Martin Nilsson constant hreffilter=(["split":1,"magic":1,"noxml":1,"alt":1]);
d7e7f82000-03-18Per Hedbor mapping mk_gtext_arg(mapping arg, RequestID id) {
a3dfd41999-11-28Martin Nilsson  mapping p=([]); //Picture rendering arguments.
22cbbd2000-02-29Martin Nilsson  m_delete(arg,"src"); m_delete(arg,"width"); m_delete(arg,"height");
8538c12000-03-18Per Hedbor  foreach(filearg, string tmp)
319dec2000-03-18Per Hedbor  if(arg[tmp]) { p[tmp]=fix_relative(arg[tmp],id); m_delete(arg,tmp); }
d47cbf1996-12-02Per Hedbor 
319dec2000-03-18Per Hedbor // if(arg->border && (search(arg->border,",")!=-1)) // { // p->border=arg->border; // m_delete(arg,"border"); // }
b89ccb1999-11-28Martin Nilsson 
d7e7f82000-03-18Per Hedbor  array i = indices( arg );
a3dfd41999-11-28Martin Nilsson  foreach(textarg, string tmp)
d7e7f82000-03-18Per Hedbor  foreach( glob( tmp, i ), string a ) {
fd79ff2000-03-21Martin Nilsson  if(a[0..5]!="magic-") { p[a]=arg[a]; // ,id i-=({a}); m_delete(arg,a); }
a3dfd41999-11-28Martin Nilsson  }
d47cbf1996-12-02Per Hedbor 
7e471e2000-01-05Martin Nilsson  foreach(theme, string tmp) if( (id->misc->defines[tmp] || id->misc->defines["theme_"+tmp]) && !p[tmp]) p[tmp]=id->misc->defines["theme_"+tmp] || id->misc->defines[tmp];
9821152000-03-16Martin Nilsson  if(!p->fgcolor) p->fgcolor="#000000"; if(!p->bgcolor) p->bgcolor="#ffffff";
d7e7f82000-03-18Per Hedbor  if(id->misc->defines->nfont && !p->nfont) p->nfont=id->misc->gtext_nfont; if(id->misc->defines->afont && !p->afont) p->afont=id->misc->gtext_afont; if(id->misc->defines->bold && !p->bold) p->bold=id->misc->gtext_bold;
7e471e2000-01-05Martin Nilsson  if(id->misc->defines->italic && !p->italic) p->italic=id->misc->gtext_italic;
d7e7f82000-03-18Per Hedbor  if(id->misc->defines->black && !p->black) p->black=id->misc->gtext_black;
7e471e2000-01-05Martin Nilsson  if(id->misc->defines->narrow && !p->narrow) p->narrow=id->misc->gtext_narrow;
a3dfd41999-11-28Martin Nilsson  return p;
d47cbf1996-12-02Per Hedbor }
a3dfd41999-11-28Martin Nilsson string fix_text(string c, mapping m, RequestID id) {
b91fd51996-12-10Per Hedbor 
a3dfd41999-11-28Martin Nilsson  if(m->nowhitespace)
b91fd51996-12-10Per Hedbor  {
04cd2a2000-02-19Martin Nilsson  c=String.trim_all_whites(c);
a3dfd41999-11-28Martin Nilsson  m_delete(m, "nowhitespace"); }
7519ad2000-03-16Martin Nilsson  m_delete(m, "noparse"); m_delete(m, "preparse");
a3dfd41999-11-28Martin Nilsson 
dccfb52000-03-01Martin Nilsson  c=replace(c, replace_entities+({" "," ", "\n\n\n", "\n\n", "\r"}), replace_values+({" ", " ", "\n", "\n", ""}));
04cd2a2000-02-19Martin Nilsson  if(m->maxlen) { c = c[..(((int)m->maxlen||QUERY(deflen))-1)]; m_delete(m, "maxlen"); }
a3dfd41999-11-28Martin Nilsson  return c;
b91fd51996-12-10Per Hedbor }
a3dfd41999-11-28Martin Nilsson  // ----------------- gtext tags and containers -------------------
7519ad2000-03-16Martin Nilsson string simpletag_gtext_url(string t, mapping arg, string c, RequestID id) {
a3dfd41999-11-28Martin Nilsson  c=fix_text(c,arg,id); mapping p=mk_gtext_arg(arg,id);
e954162000-01-02Martin Nilsson  if(arg->href && !p->fgcolor) p->fgcolor=id->misc->gtext_link||"#0000ff";
a3dfd41999-11-28Martin Nilsson  string ext=""; if(query("ext")) ext="."+(p->format || "gif"); if(!arg->short) return query_internal_location()+image_cache->store( ({p,c}), id )+ext;
f02c0c1999-12-11Martin Nilsson  return "+"+image_cache->store( ({p,c}), id )+ext;
8b6ee51999-07-10Peter Bortas }
7519ad2000-03-16Martin Nilsson string simpletag_gtext_id(string t, mapping arg, string c, RequestID id) {
a3dfd41999-11-28Martin Nilsson  mapping p=mk_gtext_arg(arg,id);
e954162000-01-02Martin Nilsson  if(arg->href && !p->fgcolor) p->fgcolor=id->misc->gtext_link||"#0000ff";
a3dfd41999-11-28Martin Nilsson  if(!arg->short) return query_internal_location()+"$"+image_cache->store(p, id)+"/";
f02c0c1999-12-11Martin Nilsson  return "+"+image_cache->store(p, id )+"/foo";
07969c1997-02-25Per Hedbor }
7519ad2000-03-16Martin Nilsson string simpletag_gtext(string t, mapping arg, string c, RequestID id)
62d8c41997-10-16Per Hedbor {
e954162000-01-02Martin Nilsson  if((c-" ")=="") return "";
033c7e1997-02-27Per Hedbor 
a3dfd41999-11-28Martin Nilsson  c=fix_text(c,arg,id); mapping p=mk_gtext_arg(arg,id);
d47cbf1996-12-02Per Hedbor 
a3dfd41999-11-28Martin Nilsson  string ext=""; if(query("ext")) ext="."+(p->format || "gif");
bfc7071997-01-13Per Hedbor 
a3dfd41999-11-28Martin Nilsson  string lp="%s", url="", ea="";
38dca81996-12-10Per Hedbor 
e954162000-01-02Martin Nilsson  int input=0;
38dca81996-12-10Per Hedbor  if(arg->submit) { input=1; m_delete(arg,"submit"); }
bfc7071997-01-13Per Hedbor 
d47cbf1996-12-02Per Hedbor  if(arg->href) { url = arg->href;
22cbbd2000-02-29Martin Nilsson  lp = replace(make_tag("a",arg-hreffilter),"%","%%")+"%s</a>";
e954162000-01-02Martin Nilsson  if(!p->fgcolor) p->fgcolor=id->misc->gtext_link||"#0000ff";
0943711997-02-25Per Hedbor  m_delete(arg, "href");
d47cbf1996-12-02Per Hedbor  }
22cbbd2000-02-29Martin Nilsson  if(!arg->noxml) { arg["/"]="/"; m_delete(arg, "noxml"); } if(!arg->border) arg->border=arg->border||"0";
d47cbf1996-12-02Per Hedbor  if(arg->split) {
a3dfd41999-11-28Martin Nilsson  string res="",split=arg->split; if(lower_case(split)=="split") split=" ";
d47cbf1996-12-02Per Hedbor  m_delete(arg,"split");
a3dfd41999-11-28Martin Nilsson  c=replace(c, "\n", " "); int setalt=!arg->alt; foreach(c/split-({""}), string word)
d47cbf1996-12-02Per Hedbor  {
a3dfd41999-11-28Martin Nilsson  string fn = image_cache->store( ({ p, word }),id );
9374e61999-05-18Per Hedbor  mapping size = image_cache->metadata( fn, id, 1 );
a3dfd41999-11-28Martin Nilsson  if(setalt) arg->alt=word; arg->src=query_internal_location()+fn+ext;
9374e61999-05-18Per Hedbor  if( size ) {
a3dfd41999-11-28Martin Nilsson  arg->width = (string)size->xsize; arg->height = (string)size->ysize;
1bd5c91997-09-26Henrik Grubbström (Grubba)  }
a3dfd41999-11-28Martin Nilsson  res+=make_tag( "img", arg )+" ";
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson  return sprintf(lp,res);
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson  string num = image_cache->store( ({ p, c }), id );
6a9b9d1999-06-25Per Hedbor  mapping size = image_cache->metadata( num, id, 1 );
a3dfd41999-11-28Martin Nilsson  if(!arg->alt) arg->alt=replace(c,"\"","'");
f1be801998-02-22Per Hedbor 
a3dfd41999-11-28Martin Nilsson  arg->src=query_internal_location()+num+ext; if(size) {
7e471e2000-01-05Martin Nilsson  arg->width=(string)size->xsize; arg->height=(string)size->ysize;
a3dfd41999-11-28Martin Nilsson  } if(arg->magic)
d47cbf1996-12-02Per Hedbor  {
a3dfd41999-11-28Martin Nilsson  string magic=replace(arg->magic,"'","`"); m_delete(arg,"magic"); if(p->bevel) p->pressed=1;
7519ad2000-03-16Martin Nilsson  m_delete(p, "fgcolor");
fd79ff2000-03-21Martin Nilsson  foreach(glob("magic-*", indices(arg)), string q)
20ca2b1998-01-26Per Hedbor  {
fd79ff2000-03-21Martin Nilsson  p[q[6..]]=arg[q]; m_delete(arg, q);
20ca2b1998-01-26Per Hedbor  }
a3dfd41999-11-28Martin Nilsson 
7519ad2000-03-16Martin Nilsson  if(!p->fgcolor) p->fgcolor=id->misc->defines->theme_alink||
22cbbd2000-02-29Martin Nilsson  id->misc->defines->alink||"#ff0000";
a3dfd41999-11-28Martin Nilsson  string num2 = image_cache->store( ({ p, c }),id );
6a9b9d1999-06-25Per Hedbor  size = image_cache->metadata( num2, id );
a3dfd41999-11-28Martin Nilsson  if(size) {
7e471e2000-01-05Martin Nilsson  arg->width=(string)max(arg->xsize,size->xsize); arg->height=(string)max(arg->ysize,size->ysize);
a3dfd41999-11-28Martin Nilsson  } if(!id->supports->images) return sprintf(lp,arg->alt);
0943711997-02-25Per Hedbor 
e954162000-01-02Martin Nilsson  string sn="i"+id->misc->gtext_mi++;
1702532000-03-15Marcus Wellhardh  if(!id->supports->js_image_object) {
a3dfd41999-11-28Martin Nilsson  return (!input)? ("<a "+ea+"href=\""+url+"\">"+make_tag("img",arg+(["name":sn]))+"</a>"): make_tag("input",arg+(["type":"image"])); } arg->name=sn;
e954162000-01-02Martin Nilsson  string res="\n<script>\n"; if(!id->misc->gtext_magic_java) {
a3dfd41999-11-28Martin Nilsson  res += "function i(ri,hi,txt)\n" "{\n" " document.images[ri].src = hi.src;\n"
3dff862000-03-20Per Hedbor  " if( txt != 0 )\n" " setTimeout(\"top.window.status = '\"+txt+\"'\", 100);\n"
a3dfd41999-11-28Martin Nilsson  "}\n";
e954162000-01-02Martin Nilsson  } id->misc->gtext_magic_java="yes";
a3dfd41999-11-28Martin Nilsson  return res+ " "+sn+"l = new Image("+arg->width+", "+arg->height+");"+sn+"l.src = \""+arg->src+"\";\n" " "+sn+"h = new Image("+arg->width+", "+arg->height+");"+sn+"h.src = \""+query_internal_location()+num2+ext+"\";\n"
e954162000-01-02Martin Nilsson  "</script>\n"+
a3dfd41999-11-28Martin Nilsson  "<a "+ea+"href=\""+url+"\" "+ (input?"onClick='document.forms[0].submit();' ":"")
3dff862000-03-20Per Hedbor  +"onMouseover=\"i('"+sn+"',"+sn+"h,"+((strlen(magic) && magic != "magic")? "'"+replace(magic,"'","`")+"'": "0")+"); return true;\" " "onMouseout=\"document.images['"+sn+"'].src = "+sn+"l.src;\">"
a3dfd41999-11-28Martin Nilsson  +make_tag("img",arg)+"</a>";
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson 
ca0f081997-02-22Per Hedbor  if(input)
a3dfd41999-11-28Martin Nilsson  return make_tag("input",arg+(["type":"image"])); return sprintf(lp,make_tag("img",arg));
d47cbf1996-12-02Per Hedbor }
7519ad2000-03-16Martin Nilsson array(string) simpletag_gh(string t, mapping m, string c, RequestID id) {
a3dfd41999-11-28Martin Nilsson  int i; if(sscanf(t, "%s%d", t, i)==2 && i>1) m->scale = (string)(1.0 / ((float)i*0.6)); if(!m->valign) m->valign="top";
9821152000-03-16Martin Nilsson  return ({ "<p>"+simpletag_gtext("",m,c,id)+"</p><br />" });
a3dfd41999-11-28Martin Nilsson }
7519ad2000-03-16Martin Nilsson array(string) simpletag_anfang(string t, mapping m, string c, RequestID id) {
a3dfd41999-11-28Martin Nilsson  if(!m->align) m->align="left";
9821152000-03-16Martin Nilsson  return ({ "<br clear=\"left\" />"+simpletag_gtext("",m,c[0..0],id)+c[1..] });
a3dfd41999-11-28Martin Nilsson } // --------------- tag and container registration ----------------------
7519ad2000-03-16Martin Nilsson mapping query_simpletag_callers() { return ([ "gtext-id" : ({ RXML.FLAG_EMPTY_ELEMENT, simpletag_gtext_id }), "gtext-url" : ({ 0, simpletag_gtext_url }), "anfang" : ({ 0, simpletag_anfang }), "gh1" : ({ 0, simpletag_gh }), "gh2" : ({ 0, simpletag_gh }), "gh3" : ({ 0, simpletag_gh }), "gh4" : ({ 0, simpletag_gh }), "gh5" : ({ 0, simpletag_gh }), "gh6" : ({ 0, simpletag_gh }), "gtext" : ({ 0, simpletag_gtext }), ]);
d47cbf1996-12-02Per Hedbor }