f41b982009-05-07Martin Stjernholm // This is a roxen module. Copyright © 1996 - 2009, Roxen IS.
e954162000-01-02Martin Nilsson //
0917d32013-03-04Anders Johansson constant cvs_version="$Id$";
ebf60d1997-03-08Henrik Grubbström (Grubba) 
d47cbf1996-12-02Per Hedbor #include <module.h> inherit "module";
a3dfd41999-11-28Martin Nilsson  // ------------------- Module registration ---------------------
654fca1999-10-04Martin Bähr 
b3281f2000-09-10Martin Nilsson constant module_type = MODULE_TAG;
bc0fa02001-03-08Per Hedbor constant module_name = "Graphics: Graphic text";
76fd092000-04-06Mattias Wingstedt constant module_doc =
7afcdd2000-05-03Martin Nilsson #"Provides the <tt>&lt;gtext&gt;&lt;/gtext&gt;</tt> tag that is used to generate text into graphical images.";
7e471e2000-01-05Martin Nilsson constant thread_safe = 1;
0a76aa1998-03-27David Hedbor 
d47cbf1996-12-02Per Hedbor void create() {
25b3322000-09-19Martin Nilsson  defvar("colorparse", 0, "Parse tags for document colors",
82f9da2000-09-16Per Hedbor  TYPE_FLAG|VAR_NOT_CFIF,
76fd092000-04-06Mattias Wingstedt  "If set, it will use the <i>HTML color wiretrap</i> module to parse "
81129f2000-09-11Martin Nilsson  "figure out the document colors by parsing tags that set colors. " "If you try to disable the <i>HTML color wiretap</i> module while " "this option is on, it will be readded every time the " "<i>Graphis text</i> module is reloaded.");
a3dfd41999-11-28Martin Nilsson 
82f9da2000-09-16Per Hedbor  defvar("deflen", 300, "Default maximum length of text", TYPE_INT|VAR_MORE|VAR_NOT_CFIF,
76fd092000-04-06Mattias Wingstedt  "Per default, it will not be possible to render texts longer than " "this. This is a safeguard so that a simple RXML error doesn't " "cause a huge image to be generated. It can be turned of at a per " "tag bases, with the <i>maxlen</i> attribute.");
bfc7071997-01-13Per Hedbor 
76fd092000-04-06Mattias Wingstedt  defvar("ext", 0, "Append format to generated images",
82f9da2000-09-16Per Hedbor  TYPE_FLAG|VAR_MORE|VAR_NOT_CFIF,
17cb462000-09-28Martin Nilsson  "Append the image format (.gif, .png, .jpg, etc) to the generated "
76fd092000-04-06Mattias Wingstedt  "images. This is not necessary, but might seem nicer.");
339e542003-04-22Anders Johansson  defvar("honor_supports", 1, "Honor supports", TYPE_FLAG|VAR_MORE, "Normally javascript tags generated by the 'magic' attribute are not " "sent to clients that don't support javascript image objects. " "This check can be disabled to always output those javascript tags.");
d47cbf1996-12-02Per Hedbor }
f02c0c1999-12-11Martin Nilsson TAGDOCUMENTATION;
2e0a351999-12-09Martin Nilsson #ifdef manual
e59a5a2000-03-01Kenneth Johansson constant gtextargs=#"
64269f2001-08-23Martin Nilsson <attr name='verbatim'><p> By default the gtext tag will try to make typographical enhancements to the text to make the resulting image as eye pleasing as possible. If you want to turn this feature off, add this attribute to the tag.</p> </attr>
9b03652001-03-07Kenneth Johansson <attr name='alpha' value='path'><p>
e59a5a2000-03-01Kenneth Johansson  Use the specified image as an alpha channel, together with the
9b03652001-03-07Kenneth Johansson  background attribute.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='background' value='path'><p> Specifies the image to use as background.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='tile'><p> Tiles the background and foreground images if they are smaller than the actual image.</p> </attr> <attr name='mirrortile'><p> Tiles the background and foreground images around x-axis and y-axis for odd frames, creating seamless textures.</p> </attr> <attr name='bevel' value='width'><p> Draws a bevel-box around the text.</p>
3dabab2001-08-30Johan Sundström  <ex>
91aa992000-03-16Martin Nilsson <gtext bevel=\"2\">Ok</gtext> </ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='bgcolor' value='color'><p>
31a43e2001-08-13Martin Stjernholm  Sets the background color. If the module \"HTML color wiretap\" is loaded, they are taken from the normal HTML tags in your document, like body, table, tr and td.</p>
e59a5a2000-03-01Kenneth Johansson  <p>If you set the background color, it is probably best to add the notrans attribute as well.</p>
3dabab2001-08-30Johan Sundström  <ex>
7519ad2000-03-16Martin Nilsson <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>
9b03652001-03-07Kenneth Johansson <attr name='bgturbulence' value='frequency,color;frequency,color...'><p> Apply a turbulence effect on the background.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='bold'><p>
4498052000-09-13Martin Nilsson  Use a bold version of the font, if available. Can not be used
9b03652001-03-07Kenneth Johansson  together with the black or light attributes.</p>
3dabab2001-08-30Johan Sundström <ex>
4498052000-09-13Martin Nilsson <gtext font='lucida'>Aa3</gtext><br /> <gtext font='lucida' bold=''>Aa3</gtext><br />
a804412000-09-22Martin Nilsson <gtext font='lucida' italic=''>Aa3</gtext><br />
4498052000-09-13Martin Nilsson <gtext font='lucida' bold='' italic=''>Aa3</gtext><br /> </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='black'><p>
4498052000-09-13Martin Nilsson  Use a black, or heavy, version of the font, if available. Can
9b03652001-03-07Kenneth Johansson  not be used together with the bold or light attributes.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='light'><p>
4498052000-09-13Martin Nilsson  Use a light version of the font, if available. Can not be used
9b03652001-03-07Kenneth Johansson  together with the bold or black attributes.</p>
4498052000-09-13Martin Nilsson </attr>
9b03652001-03-07Kenneth Johansson <attr name='italic'><p> Use an italic version of the font, if available.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='bshadow' value='distance'><p>
e59a5a2000-03-01Kenneth Johansson  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
9b03652001-03-07Kenneth Johansson  'spacing'.</p>
3dabab2001-08-30Johan Sundström  <ex>
281d722001-07-25Johan Sundström <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>
9b03652001-03-07Kenneth Johansson <attr name='chisel'><p> Make the text look like it has been cut into the background.</p>
3dabab2001-08-30Johan Sundström  <ex>
3ce82d2000-09-13Martin Nilsson <gtext font=\"lucida\" bold=\"\" chisel=\"\" talign=\"center\" tile=\"\"
9b03652001-03-07Kenneth Johansson opaque=\"70\" fgcolor=\"gold\" bevel=\"2\" background=\"/internal-roxen-squares\"> Chisel opaque=\"70\"</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='crop'><p> Remove all white-space around the image.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='encoding' value='string'><p> Choose with which charset the text is encoded with.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='fadein' value='blur,steps,delay,initialdelay'><p> Generates an animated GIF file of a fade-in effect.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='fgcolor' value='color'><p> Sets the text color.</p>
3dabab2001-08-30Johan Sundström  <ex>
7519ad2000-03-16Martin Nilsson <gtext fgcolor=\"#0080FF\">#0080FF</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='font' value='string'><p>
4498052000-09-13Martin Nilsson  Selects which font to use. You can get a list of all available fonts by using the list fonts task in the administration interface, or by
9b03652001-03-07Kenneth Johansson  using the <xref href='../output/emit_fonts.tag' /> plugin.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='fontsize' value='number'><p> Selects which size of the font that should be used.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='format' value='string'><p> Set the image format, e.g. \"png\".</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='fs'><p>
e59a5a2000-03-01Kenneth Johansson  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
9b03652001-03-07Kenneth Johansson  images dithering is O.K.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='ghost' value='dist,blur,color'><p>
e59a5a2000-03-01Kenneth Johansson  Apply a ghost effect. Cannot be used together with shadow or magic
9b03652001-03-07Kenneth Johansson  coloring.</p>
3dabab2001-08-30Johan Sundström  <ex><gtext spacing=\"2\" crop=\"\" ghost=\"1,1,red\">ghost=1,1,red</gtext></ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='glow' value='color'><p>
e59a5a2000-03-01Kenneth Johansson  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
9b03652001-03-07Kenneth Johansson  achieved.</p>
3dabab2001-08-30Johan Sundström  <ex>
91aa992000-03-16Martin Nilsson <gtext glow=\"red\">&lt;gtext glow=red&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='maxlen' value='number'><p>
e59a5a2000-03-01Kenneth Johansson  Sets the maximum length of the text that will be rendered into an
9b03652001-03-07Kenneth Johansson  image, by default 300.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='move' value='x,y'><p>
e59a5a2000-03-01Kenneth Johansson  Moves the text relative to the upper left corner of the background
9b03652001-03-07Kenneth Johansson  image. This will not change the size of the image.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='narrow'><p> Use a narroe version of the font, if available.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='notrans'><p>
e59a5a2000-03-01Kenneth Johansson  Do not make the background transparent. Useful when making 'boxes' of
9b03652001-03-07Kenneth Johansson  color around the text.</p>
3dabab2001-08-30Johan Sundström  <ex>
9b03652001-03-07Kenneth Johansson <gtext bgcolor=\"red\">&lt;gtext bgcolor=red&gt;</gtext><br /> <gtext bgcolor=\"red\" notrans=\"\">&lt;gtext bgcolor=red notrans&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='nowhitespace'><p> Removes all whitespaces before and after the real text.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='opaque' value='percentage'><p> 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.</p>
3dabab2001-08-30Johan Sundström  <ex>
91aa992000-03-16Martin Nilsson <gtext scale=\"0.6\" textbox=\"100,pink,-11\" bgcolor=\"lightblue\"
9b03652001-03-07Kenneth Johansson notrans=\"\" opaque=\"40\" fgcolor=\"black\" >&lt;Demonstration of opaque text&gt;</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='outline' value='color,extra-radius'><p> Draw an outline around the text. Quite useful when combined with textscale.</p>
3dabab2001-08-30Johan Sundström  <ex>
9b03652001-03-07Kenneth Johansson <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>
9b03652001-03-07Kenneth Johansson <attr name='pressed'><p>
e59a5a2000-03-01Kenneth Johansson  Inverts the direction of the bevel box, to make it look like a button
9b03652001-03-07Kenneth Johansson  that is pressed down. The magic modifier will do this automatically.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='quant' value='number'><p> 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.</p>
3dabab2001-08-30Johan Sundström  <ex>
91aa992000-03-16Martin Nilsson <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>
9b03652001-03-07Kenneth Johansson <attr name='rescale'><p> Rescale the background to fill the whole image.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='rotate' value='angle'><p> Rotates the image this number of degrees counter-clockwise.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='scale' value='number'><p> Sets the scale of the image. Larger than 1.0 is enlargement.</p>
3dabab2001-08-30Johan Sundström  <ex>
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>
9b03652001-03-07Kenneth Johansson <attr name='scolor' value='color'><p> Use this color for the shadow. Used with the shadow attribute.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='scroll' value='width,steps,delay'><p> Generate an animated GIF image of the text scrolling.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='shadow' value='intensity,distance'><p>
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
9b03652001-03-07Kenneth Johansson  values for distance is possible,</p>
3dabab2001-08-30Johan Sundström  <ex><gtext scale=\"0.8\" fgcolor=\"blue\"
281d722001-07-25Johan Sundström 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></ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='size' value='width,height'><p> Set the size of the image.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='spacing' value='number'><p> Add space around the text.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='talign' value='left|right|center'><p> Adjust the alignment of the text.</p>
4d4ef02000-09-19Kenneth Johansson </attr>
e59a5a2000-03-01Kenneth Johansson 
9b03652001-03-07Kenneth Johansson <attr name='textbelow' value='color'><p>
f2f19d2000-03-16Martin Stjernholm  Place the text centered in a box of the given color below the image
9b03652001-03-07Kenneth Johansson  area. Useful together with background to make captions for images.</p>
3dabab2001-08-30Johan Sundström  <ex>
ad409a2000-09-16Martin Nilsson <img src=\"/internal-roxen-roxen\" /> &nbsp;
9b03652001-03-07Kenneth Johansson <gtext scale=\"0.5\" background=\"/internal-roxen-roxen\" textbelow=\"#c0c0c0\">Roxen</gtext>
91aa992000-03-16Martin Nilsson  </ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='textbox' value='opaque,color'><p> Draw a box with an opaque value below the text of the specified color.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='textscale' value='color,color,color,color'><p>
91aa992000-03-16Martin Nilsson  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
9b03652001-03-07Kenneth Johansson  using this argument.</p>
3dabab2001-08-30Johan Sundström  <ex>
281d722001-07-25Johan Sundström <gtext quant=\"128\" textscale=\"blue,white,red,darkgreen\" >Blue, white, red, darkgreen</gtext>
91aa992000-03-16Martin Nilsson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='texture' value='path'><p> Uses the specified images as a field texture.</p>
3dabab2001-08-30Johan Sundström <ex>
ace2d82001-10-10Martin Nilsson <gtext texture=\"/internal-roxen-squares\" tile=\"1\" fontsize=\"100\">A</gtext>
ad409a2000-09-16Martin Nilsson </ex>
e59a5a2000-03-01Kenneth Johansson </attr>
ce8fb02001-09-21Johan Sundström <attr name='tile'>
20e25f2001-10-08Johan Sundström  <p>Tiles the background and foreground images if they are smaller than the actual image.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
accd7f2001-09-03Martin Nilsson <attr name='xpad' value='percentage|integer ended with \"px\"'><p>
9b03652001-03-07Kenneth Johansson  Sets the padding between characters. The value can either be an
accd7f2001-09-03Martin Nilsson  relative change, in percent, or an absolute number of pixels, ended with the string \"px\". Note that
9b03652001-03-07Kenneth Johansson  different fonts reacts differently on these values and for some it will not have any effect at all. This depends on the type of the font and the font implementation.</p>
e59a5a2000-03-01Kenneth Johansson 
3dabab2001-08-30Johan Sundström <ex>
343f042001-08-23Martin Nilsson <gtext font=\"niquel\">HELLO ROXEN</gtext><br />
accd7f2001-09-03Martin Nilsson <gtext xpad=\"4px\" font=\"niquel\">HELLO ROXEN</gtext><br />
343f042001-08-23Martin Nilsson <gtext xpad=\"50%\" font=\"niquel\">HELLO ROXEN</gtext><br />
7785452001-01-02Martin Nilsson </ex> </attr>
e59a5a2000-03-01Kenneth Johansson 
9b03652001-03-07Kenneth Johansson <attr name='xsize' value='number'><p> Sets the width.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='xspacing' value='number'><p> Sets the horizontal spacing.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
accd7f2001-09-03Martin Nilsson <attr name='ypad' value='percentage|integer ended with \"px\"'><p> Sets the padding beteen lines. Works as xpad.</p>
4d4ef02000-09-19Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson  <attr name='ysize' value='number'><p> Sets the height.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='yspacing' value='number'><p> Sets the vertical spacing.</p>
5adc582009-11-30Henrik Grubbström (Grubba) </attr> <h1>Timeout</h1> <p>The generated image will by default never expire, but in some circumstances it may be pertinent to limit the time the image and its associated data is kept. Its possible to set an (advisory) timeout on the image data using the following attributes.</p> <attr name='unix-time' value='number'><p> Set the base expiry time to this absolute time.</p><p> If left out, the other attributes are relative to current time.</p> </attr> <attr name='years' value='number'><p> Add this number of years to the time this entry is valid.</p> </attr> <attr name='months' value='number'><p> Add this number of months to the time this entry is valid.</p> </attr> <attr name='weeks' value='number'><p> Add this number of weeks to the time this entry is valid.</p> </attr> <attr name='days' value='number'><p> Add this number of days to the time this entry is valid.</p> </attr> <attr name='hours' value='number'><p> Add this number of hours to the time this entry is valid.</p> </attr> <attr name='beats' value='number'><p> Add this number of beats to the time this entry is valid.</p> </attr> <attr name='minutes' value='number'><p> Add this number of minutes to the time this entry is valid.</p> </attr> <attr name='seconds' value='number'><p> Add this number of seconds to the time this entry is valid.</p>
e59a5a2000-03-01Kenneth Johansson </attr>";
0d86502000-09-18Kenneth Johansson 
e59a5a2000-03-01Kenneth Johansson constant tagdoc=([
ce8fb02001-09-21Johan Sundström "anfang":#"<desc type='cont'><p><short>
9b03652001-03-07Kenneth Johansson  Creates an anfang in the beginning of a text.</short> This tag takes
7209722012-05-09Jenny Dalenius  the same attributes as <xref href='gtext.tag' />. </p>
9b03652001-03-07Kenneth Johansson 
3dabab2001-08-30Johan Sundström  <ex>
9b03652001-03-07Kenneth Johansson  <anfang crop=\"\">This is a beginning<br /> of a very short text,<br /> and here it ends. </anfang> </ex> </desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh":#"<desc type='cont'><p><short>
9b03652001-03-07Kenneth Johansson  Creates a graphical header.</short> <tag>gh</tag> takes the same attributes as <xref href='gtext.tag' />. <tag>gh</tag> comes in six flavors, from <tag>gh1</tag> through <tag>gh6</tag> and are the RXML counterpart to the HTML tags <tag>h1</tag> through <tag>h6</tag>.</p>
dbdf722000-09-18Kenneth Johansson </desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh1":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh2":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh3":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh4":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh5":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gh6":#"<desc type='cont'></desc>
03cbf72000-03-25Martin Nilsson <noex>"+gtextargs+"</noex>",
e59a5a2000-03-01Kenneth Johansson 
ce8fb02001-09-21Johan Sundström "gtext":#"<desc type='cont'><p><short>
9b03652001-03-07Kenneth Johansson  Creates an image with the tag content texts.</short> It is possible to pass attributes, such as the target attribute, to the resulting tags by including them in the gtext tag.</p>
e59a5a2000-03-01Kenneth Johansson </desc>
9b03652001-03-07Kenneth Johansson <attr name='alt' value='string'><p>
e59a5a2000-03-01Kenneth Johansson  Sets the alt attribute of the generated <tag>img</tag> tag. By default the alt attribute will be set to the contents of the
9b03652001-03-07Kenneth Johansson  <tag>gtext</tag> tag.</p>
3dabab2001-08-30Johan Sundström  <ex>
9b03652001-03-07Kenneth Johansson  <gtext fgcolor=\"blue\" alt=\"Hello!\">Welcome!</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='border' value='width,color'><p> Draws a border around the text of the specified width and color.</p>
3dabab2001-08-30Johan Sundström  <ex>
7519ad2000-03-16Martin Nilsson <gtext fgcolor=\"blue\" border=\"2,red\">Red border</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='href' value='URL'><p>
e59a5a2000-03-01Kenneth Johansson  Link the image to the specified URL. The link color of the document will be used as the default foreground rather than the foreground
9b03652001-03-07Kenneth Johansson  color.</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='magic' value='message'><p>
e59a5a2000-03-01Kenneth Johansson  Used together with the href attribute to generate a JavaScript that will highlight the image when the mouse is moved over it. The message
9b03652001-03-07Kenneth Johansson  is shown in the browser's status bar.</p>
3dabab2001-08-30Johan Sundström  <ex>
7519ad2000-03-16Martin Nilsson <gtext href=\"http://www.roxen.com\" magic=\"Roxen\">www.roxen.com</gtext>
e59a5a2000-03-01Kenneth Johansson  </ex> </attr>
9b03652001-03-07Kenneth Johansson <attr name='magic-attribute' value='value'><p> Same as for any <tag>gtext</tag> attribute, except for the highlighted image.</p>
3dabab2001-08-30Johan Sundström <ex><gtext fgcolor=\"blue\" magic=\"\"
4cac722008-08-14Edwin van de Pol magic-glow=\"red\" magic-fgcolor=\"white\">Mouse me!</gtext></ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='noxml'><p> Do not terminate the image tag with \"/\".</p>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='split'> <p>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.</p>
e59a5a2000-03-01Kenneth Johansson 
3dabab2001-08-30Johan Sundström <ex>
9b03652001-03-07Kenneth Johansson  <gtext scale='0.4' split='split'> Useful if you are writing a large text, and word wrap at the edges of the display is desired. </gtext> </ex>
e59a5a2000-03-01Kenneth Johansson 
9b03652001-03-07Kenneth Johansson  <p>This will allow the browser to word-wrap the text, but will disable certain attributes like <att>magic</att>. Note that the word wraping functionality of this example cannot be shown as the size of the browser window is determined by the largest example box. </p>
3dabab2001-08-30Johan Sundström  <ex><gtext scale=\"0.4\" split=\"\">One image per character.</gtext></ex>
e59a5a2000-03-01Kenneth Johansson </attr>
9b03652001-03-07Kenneth Johansson <attr name='submit'><p> Creates a submit-button for forms. Does not work together with <att>split</att> or <att>magic</att> attributes.</p>
7519ad2000-03-16Martin Nilsson </attr>"+gtextargs,
e59a5a2000-03-01Kenneth Johansson 
9b03652001-03-07Kenneth Johansson "gtext-id":#"<desc tag='tag'><p><short>
a066a72001-03-21Johan Sundström  Returns an internal URL to an image with the specified gtext attributes applied.</short> Rendering a text image with the given arguments is accomplished by concatenating the text of your choice to the end of the URL returned by the tag, as in \"<tag>gtext-id/</tag>Hello%20World!\".</p> <p>Be aware that this tag could be abused for denial of service attacks by malicious users swarming your server with requests for images of great length that the server would happily try to render for them. Hence this tag should only be used in environments where you trust all your users, e.g. Intranets.</p> <p>In most cases the tag <tag>gtext-url</tag> solves this problem, but if you would like to generate new text images live without reloading some RXML page, you need this tag. An example application:</p>
ce8fb02001-09-21Johan Sundström <ex-box><define variable='var.id' preparse='' trimwhites=''>
a066a72001-03-21Johan Sundström <gtext-id font='FranklinGothicDemi' fgcolor='blue'/> </define> <img src='&var.id;Please type some text here:'
ce8fb02001-09-21Johan Sundström  alt='' name='banner' width='468' height='60' />
a066a72001-03-21Johan Sundström  <script language='javascript'> var image = document.images.banner; function alter_image(label) { image.src = '&var.id:js;' + escape(label.value); label.focus(); return false; } </script>
9b03652001-03-07Kenneth Johansson 
a066a72001-03-21Johan Sundström <form onsubmit='return alter_image(this.label);'> <input type='text' size='40' name='label' />
ce8fb02001-09-21Johan Sundström </form></ex-box></desc>
9b03652001-03-07Kenneth Johansson 
2eeaaa2001-03-14Kenneth Johansson <attr name='short'><p> Returns a relative path to the image, i.e. a shorter one. </p>
7519ad2000-03-16Martin Nilsson </attr>"+gtextargs,
e59a5a2000-03-01Kenneth Johansson 
750d632005-05-19Stefan Wallström "gtext-js":#"<desc tag='tag'><p><short>
7209722012-05-09Jenny Dalenius  Inserts javascript functions that are used by gtext when using
63085e2006-05-03Anders Johansson  the magic attributes.</short>
750d632005-05-19Stefan Wallström  This is normally inserted at the first instance of a gtext, but it may be necessary to insert the gtext using this tag if the first gtext in a page may be hidden, for example if contained in an if tag.
63085e2006-05-03Anders Johansson  </p>
750d632005-05-19Stefan Wallström </desc>",
ce8fb02001-09-21Johan Sundström "gtext-url":#"<desc type='cont'><p><short>
829e722001-03-13Kenneth Johansson  Returns an internal URL to an image with the specified attributes
2eeaaa2001-03-14Kenneth Johansson  applied.</short></p>
9b03652001-03-07Kenneth Johansson </desc> <attr name='short'><p>
2eeaaa2001-03-14Kenneth Johansson  Returns a relative path to the image, i.e. a shorter one.
9b03652001-03-07Kenneth Johansson </p>
03cbf72000-03-25Martin Nilsson </attr> <noex>"+gtextargs+"</noex>",]);
2e0a351999-12-09Martin Nilsson #endif
a3dfd41999-11-28Martin Nilsson  // -------------------- Image cache functions --------------------
783e1b2001-07-10Martin Nilsson private roxen.ImageCache image_cache; private string compat_level;
339e542003-04-22Anders Johansson private int honor_supports;
e5bad21998-02-10Per Hedbor 
e954162000-01-02Martin Nilsson string status() { array s=image_cache->status();
482ba72000-12-30Per Hedbor  return sprintf("<b>Images in cache:</b> %d images<br />\n" "<b>Cache size:</b> %s", s[0], Roxen.sizetostring(s[1]));
e954162000-01-02Martin Nilsson }
7afcdd2000-05-03Martin Nilsson mapping(string:function) query_action_buttons() {
da43042005-12-16Jonas Wallden  return ([ "Clear Cache":flush_cache ]);
a54b4d2000-06-03Martin Nilsson } void flush_cache() { image_cache->flush();
7afcdd2000-05-03Martin Nilsson }
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" }) );
05776d2001-07-08Martin Nilsson  compat_level = conf->query("compat_level");
339e542003-04-22Anders Johansson  honor_supports = query("honor_supports");
2468b21997-07-06Henrik Grubbström (Grubba) }
c3655b1997-01-27Per Hedbor 
c7ba992010-04-27Henrik Grubbström (Grubba) void stop() { destruct(image_cache); }
783e1b2001-07-10Martin Nilsson private constant nbsp = Roxen.iso88591["&nbsp;"];
06583f1997-09-03Per Hedbor 
783e1b2001-07-10Martin Nilsson private Image.Image|mapping 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; }
64269f2001-08-23Martin Nilsson 
b530172000-09-19Per Hedbor  if( !mappingp( args ) || !stringp( text )) // errors in the argument cache. Not all that unsusual when using the // relay module. return 0;
64269f2001-08-23Martin Nilsson 
9374e61999-05-18Per Hedbor  if(!args->verbatim) // typographically correct...
ba73a21996-12-10Per Hedbor  {
64269f2001-08-23Martin Nilsson  text = replace(text, ([ nbsp:" ", "&ss;":nbsp, "\000":"", "\001":"" ])); text = Parser.parse_html_entities(text);
9374e61999-05-18Per Hedbor  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  }
64269f2001-08-23Martin Nilsson 
9374e61999-05-18Per Hedbor  text=replace(res[..strlen(res)-2], ({"!","?",": "}),({ nbsp+"!",nbsp+"?",nbsp+": "}));
64269f2001-08-23Martin Nilsson  text=replace(replace( replace(text,({". ",". "+nbsp}),({"\000","\001"})), ".", "."+nbsp+nbsp),
9374e61999-05-18Per Hedbor  ({"\000","\001"}),({". ","."+nbsp})); }
e8c29c1997-09-12Johan Schön 
9374e61999-05-18Per Hedbor  if( args->afont )
05776d2001-07-08Martin Nilsson  font = resolve_font(args->afont+" "+args->fontsize);
9374e61999-05-18Per Hedbor  else
a5c21b1999-05-18Peter Bortas  {
38569c1999-12-07Martin Nilsson  int bold=0, italic=0;
9374e61999-05-18Per Hedbor  if(args->bold) bold=1; if(args->light) bold=-1; if(args->black) bold=2; if(args->italic) italic=1;
05776d2001-07-08Martin Nilsson 
7785452001-01-02Martin Nilsson  int|float xpad=0.0;
a8b0b82001-01-01Martin Nilsson  if(args->xpad)
accd7f2001-09-03Martin Nilsson  if(args->xpad[-1]=='x' && args->xpad[-2]=='p')
a8b0b82001-01-01Martin Nilsson  xpad = (int)args->xpad;
accd7f2001-09-03Martin Nilsson  else xpad = (float)args->xpad;
05776d2001-07-08Martin Nilsson 
7785452001-01-02Martin Nilsson  int|float ypad=0.0;
a8b0b82001-01-01Martin Nilsson  if(args->ypad)
accd7f2001-09-03Martin Nilsson  if(args->ypad[-1]=='x' && args->ypad[-2]=='p')
a8b0b82001-01-01Martin Nilsson  ypad = (int)args->ypad;
accd7f2001-09-03Martin Nilsson  else ypad = (float)args->ypad;
05776d2001-07-08Martin Nilsson  font = get_font(args->font, (int)args->fontsize||32,
5fe8d82000-01-30Per Hedbor  bold, italic,
9374e61999-05-18Per Hedbor  lower_case(args->talign||"left"),
a8b0b82001-01-01Martin Nilsson  xpad, ypad);
a5c21b1999-05-18Peter Bortas  }
974b2a1997-10-02Peter Bortas 
f02c0c1999-12-11Martin Nilsson  if (!font)
78b9122012-06-21Martin Stjernholm  RXML.parse_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.
ef3b2b2009-04-29Jonas Wallden  array|mapping make_res = GText.make_text_image(args, font, text, id); if (mappingp(make_res)) return make_res; [img, Image.Image alpha] = make_res;
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  {
cf6bc22008-05-21Martin Stjernholm  int amount=2, steps=10, delay=10, initialdelay=0;
9374e61999-05-18Per Hedbor  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 {
b530172000-09-19Per Hedbor  if( strlen(f)>4 && query("ext") && f[-4]=='.') // Remove .ext f = f[..strlen(f)-5]; if( strlen(f) && f[0]=='$' ) { array id_text = f/"/"; if( sizeof(id_text)==2 )
9363fa2009-11-24Henrik Grubbström (Grubba)  { // It's a gtext-id, let it live for an hour. string second_key = roxen->argcache->store( (["":id_text[1]]), 3600 ); return image_cache->http_file_answer( id_text[0][1..] +"$"+ second_key, id, UNDEFINED, 3600 );
b530172000-09-19Per Hedbor  }
8b6ee51999-07-10Peter Bortas  }
b530172000-09-19Per Hedbor  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 -----------------
783e1b2001-07-10Martin Nilsson private constant filearg = ({ "background", "texture", "alpha", "magic-texture", "magic-background", "magic-alpha" });
d7e7f82000-03-18Per Hedbor 
783e1b2001-07-10Martin Nilsson private constant textarg = ({ "afont", "alpha",
59696c2006-09-06Stefan Wallström  "baselineoffset",
783e1b2001-07-10Martin Nilsson  "bevel", "bgcolor", "bgturbulence", "black", "bold", "bshadow", "chisel", "encoding", "fadein", "fgcolor", "font", "fontsize", "ghost", "glow", "italic", "light", "mirrortile", "move", "narrow",
3e35152006-09-06Stefan Wallström  "no-auto-alpha",
783e1b2001-07-10Martin Nilsson  "notrans", "opaque", "outline",
59696c2006-09-06Stefan Wallström  "oversampling",
783e1b2001-07-10Martin Nilsson  "pressed", "rescale", "rotate", "scale", "scolor", "scroll", "shadow", "size", "spacing", "talign", "tile", "textbox", "textbelow", "textscale", "verbatim", "xpad", "xsize", "xspacing", "ypad", "ysize", "yspacing", "border", // generic argcache arguments "crop", "format", "quant", "dither", "fs", "*-*", "gamma",
a3dfd41999-11-28Martin Nilsson });
783e1b2001-07-10Martin Nilsson private constant theme = ({ "fgcolor", "bgcolor", "font" });
7e471e2000-01-05Martin Nilsson 
783e1b2001-07-10Martin Nilsson private constant hreffilter = ([ "split":1, "magic":1, "noxml":1, "alt":1 ]);
22cbbd2000-02-29Martin Nilsson 
750d632005-05-19Stefan Wallström string gtext_javascript(RequestID id) { string res=""; if(!id->root_id->misc->gtext_magic_java) { res += "function gtext_mo(ri,hi,txt)\n" "{\n" " document.images[ri].src = hi.src;\n" " if( txt != 0 )\n" " setTimeout(\"top.window.status = '\"+txt+\"'\", 100);\n" "}"; id->root_id->misc->gtext_magic_java="yes"; } return res; }
ef3b2b2009-04-29Jonas Wallden private int get_file_stat( string f, RequestID id ) { int res; mapping stat_cache; // -1 is used to cache negative results. When SiteBuilder crawler runs // we must let the stat_file() run unconditionally to register // dependencies properly. if (stat_cache = id->misc->gtext_statcache) { if (!id->misc->persistent_cache_crawler) if (res = stat_cache[f]) return (res > 0) && res; } else stat_cache = id->misc->gtext_statcache = ([ ]); int was_internal = id->misc->internal_get; id->misc->internal_get = 1; res = stat_cache[ f ] = (id->conf->stat_file( f,id ) || ({ 0,0,0,0 }) )[ST_MTIME] || -1; if (!was_internal) m_delete(id->misc, "internal_get"); return (res > 0) && res; }
783e1b2001-07-10Martin Nilsson private mapping mk_gtext_arg(mapping arg, RequestID id)
d7e7f82000-03-18Per Hedbor {
a3dfd41999-11-28Martin Nilsson  mapping p=([]); //Picture rendering arguments.
05776d2001-07-08Martin Nilsson #if ROXEN_COMPAT < 2.2 if(compat_level < "2.2") { p->compat = compat_level; p->font = m_delete(arg, "nfont"); } #endif
22cbbd2000-02-29Martin Nilsson  m_delete(arg,"src"); m_delete(arg,"width"); m_delete(arg,"height");
e94a152000-09-13Jonas Wallden #if !constant(Image.GIF) || !constant(Image.GIF.encode) // fadein or scroll not supported without GIF m_delete(arg, "fadein"); m_delete(arg, "scroll"); #endif // Make format selection explicit since fallback may vary depending on // encoders present in this installation. if (!arg->format) #if constant(Image.GIF) && constant(Image.GIF.encode) arg->format = "gif"; #else arg->format = "jpg"; #endif
8538c12000-03-18Per Hedbor  foreach(filearg, string tmp)
ef3b2b2009-04-29Jonas Wallden  if(string path = arg[tmp])
319dec2000-03-18Per Hedbor  {
ed9f2a2011-01-21Jonas Wallden  // Reject empty file paths for sufficiently high compat_level if (path == "" && compat_level >= "5.2") RXML.parse_error("Empty " + tmp + " attribute not allowed.");
ef3b2b2009-04-29Jonas Wallden  if (!has_prefix(tmp, "magic-")) { p[tmp] = Roxen.fix_relative(path, id); p[tmp + "_stat"] = get_file_stat(path, id); #if constant(Sitebuilder) // The file we called get_file_stat() on above may be a SiteBuilder // file. If so we need to extend the argument data with e.g. // current language fork. if (Sitebuilder.sb_prepare_imagecache) p = Sitebuilder.sb_prepare_imagecache(p, path, id); #endif m_delete(arg, tmp);
59de532004-08-09Henrik Grubbström (Grubba)  } else { // The magic-* attributes will be removed later. arg[tmp]=Roxen.fix_relative(arg[tmp],id); }
319dec2000-03-18Per Hedbor  }
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
a3e0ac2000-09-29Martin Nilsson  i-=({ m_delete(arg,a) });
fd79ff2000-03-21Martin Nilsson  }
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";
05776d2001-07-08Martin Nilsson #if ROXEN_COMPAT < 2.2 if(id->misc->defines->nfont && !p->nfont && !p->font && !p->afont && compat_level<"2.2") p->font=id->misc->gtext_nfont; #endif if(id->misc->defines->afont && !p->nfont && !p->font && !p->afont) p->afont=id->misc->gtext_afont;
d7e7f82000-03-18Per Hedbor  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 
05776d2001-07-08Martin Nilsson  if(p->afont) { p->font = roxen->fonts->verify_font( p->afont+" "+p->fontsize ); if(!p->font) RXML.parse_error("Font "+p->afont+" could not be loaded.\n"); } else { string font = p->font; p->font = roxen->fonts->verify_font(p->font, p->fontsize||32);
f2b2062001-11-15Henrik Grubbström (Grubba)  if(!p->font) { RXML.parse_error("Font " + (font || roxen->query("default_font")) + " could not be loaded.\n"); }
05776d2001-07-08Martin Nilsson  }
a3dfd41999-11-28Martin Nilsson  return p;
d47cbf1996-12-02Per Hedbor }
783e1b2001-07-10Martin Nilsson private 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 
4105402002-01-11Chris Burgess  c=replace(c, Roxen.replace_entities + ({ " ", " ", "\n\n\n", "\n\n", "\r\n\r\n\r\n", "\r\n\r\n", "\r\n", "\r\r\r", "\r\r", "\r" }), Roxen.replace_values + ({ " ", " ", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", }));
04cd2a2000-02-19Martin Nilsson 
a3e0ac2000-09-29Martin Nilsson  if(m->maxlen)
ed540b2001-01-13Martin Nilsson  c = c[..(( (int)m_delete(m,"maxlen") || query("deflen"))-1)];
a3dfd41999-11-28Martin Nilsson  return c;
b91fd51996-12-10Per Hedbor }
a3dfd41999-11-28Martin Nilsson  // ----------------- gtext tags and containers -------------------
a50b592000-09-03Martin Nilsson class TagGTextURL { inherit RXML.Tag; constant name = "gtext-url";
1b2d742001-10-08Anders Johansson  constant flags = RXML.FLAG_DONT_REPORT_ERRORS;
a50b592000-09-03Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) {
ce4deb2009-11-26Henrik Grubbström (Grubba)  int timeout = Roxen.timeout_dequantifier(args);
abe36f2001-11-27Martin Stjernholm  content=fix_text(content||"",args,id);
a50b592000-09-03Martin Nilsson  mapping p=mk_gtext_arg(args,id); if(args->href && !p->fgcolor) p->fgcolor=id->misc->gtext_link||"#0000ff"; string ext=""; if(query("ext")) ext="."+(p->format || "gif"); if(!args->short)
db053e2000-12-05Martin Nilsson  return ({ query_absolute_internal_location(id) +
9363fa2009-11-24Henrik Grubbström (Grubba)  image_cache->store( ({p,content}), id, timeout )+ext }); return ({ "+"+image_cache->store( ({p,content}), id, timeout )+ext });
a50b592000-09-03Martin Nilsson  } }
8b6ee51999-07-10Peter Bortas }
750d632005-05-19Stefan Wallström class TagGTextJS { inherit RXML.Tag; constant name = "gtext-js"; constant flags = RXML.FLAG_EMPTY_ELEMENT; class Frame { inherit RXML.Frame; array do_return(RequestID id) { return ({ gtext_javascript(id) }); } } }
a50b592000-09-03Martin Nilsson class TagGTextID { inherit RXML.Tag; constant name = "gtext-id";
1b2d742001-10-08Anders Johansson  constant flags = RXML.FLAG_EMPTY_ELEMENT;
a50b592000-09-03Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) {
866e2a2009-11-26Henrik Grubbström (Grubba)  int timeout = Roxen.timeout_dequantifier(args);
a50b592000-09-03Martin Nilsson  mapping p=mk_gtext_arg(args,id); if(args->href && !p->fgcolor) p->fgcolor=id->misc->gtext_link||"#0000ff"; if(!args->short)
db053e2000-12-05Martin Nilsson  return ({ query_absolute_internal_location(id) +
9363fa2009-11-24Henrik Grubbström (Grubba)  "$"+image_cache->store(p, id, timeout)+"/" }); return ({ "+"+image_cache->store(p, id, timeout)+"/foo" });
a50b592000-09-03Martin Nilsson  } }
07969c1997-02-25Per Hedbor }
a50b592000-09-03Martin Nilsson class TagGText { inherit RXML.Tag; constant name = "gtext";
1b2d742001-10-08Anders Johansson  constant flags = RXML.FLAG_DONT_REPORT_ERRORS;
a50b592000-09-03Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) {
871e632001-06-29Jonas Wallden  return ({ do_gtext(args, (string) content, id) });
a50b592000-09-03Martin Nilsson  } } }
c320d02006-09-13Stefan Wallström #ifdef GTEXT_RANDOM_PREFIX constant random_chars = "abcdefghijklmnopqrstuvwxyz" / ""; string random_pfx() { string s = ""; for(int i=0; i < 4; i++) s += random_chars[random(sizeof(random_chars))]; return s; } string get_gtext_pfx(RequestID id) { if(!id->root_id->misc->gtext_pfx) { id->root_id->misc->gtext_pfx = random_pfx(); RXML_CONTEXT->set_root_id_misc("gtext_pfx", id->root_id->misc->gtext_pfx); } return id->root_id->misc->gtext_pfx; } #endif
783e1b2001-07-10Martin Nilsson private string do_gtext(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 
21171e2000-08-25Martin 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;
a54b4d2000-06-03Martin Nilsson  lp = replace(Roxen.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  }
21171e2000-08-25Martin Nilsson  foreach( ({ "class", "onClick", "onclick", "onMouseover", "onmouseover",
0493462001-01-03Martin Nilsson  "onMouseout", "onmouseout", "target", "accesskey", "charset", "hreflang", "suppress", "tabindex" }), string name)
21171e2000-08-25Martin Nilsson  if(arg[name]) { ea+=name+"="; if(!has_value(arg[name], "\"")) ea+="\""+arg[name]+"\" "; else if(!has_value(arg[name], "'")) ea+="'"+arg[name]+"' "; else ea+="\""+replace(arg[name], "'", "&#39;")+"\" "; m_delete(arg, name); }
a3e0ac2000-09-29Martin Nilsson  int xml=!m_delete(arg, "noxml");
21171e2000-08-25Martin Nilsson 
eab6f82007-09-05Mathias Södermark  // No border should be used for <img>. Force CSS declaration to avoid // borders when gtext is clickable. m_delete(arg, "border"); arg->style = "border: none;" + (arg->style || "");
22cbbd2000-02-29Martin Nilsson 
ce4deb2009-11-26Henrik Grubbström (Grubba)  int timeout = Roxen.timeout_dequantifier(arg);
cf5b112003-10-16Anders Johansson  int no_draw = !id->misc->generate_images;
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  {
9363fa2009-11-24Henrik Grubbström (Grubba)  string fn = image_cache->store( ({ p, word }), id, timeout );
91d0172009-12-01Henrik Grubbström (Grubba)  mapping size = image_cache->metadata( fn, id, no_draw, timeout);
a3dfd41999-11-28Martin Nilsson  if(setalt) arg->alt=word;
db053e2000-12-05Martin Nilsson  arg->src=query_absolute_internal_location(id)+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)  }
113ea42002-01-21Martin Stjernholm  else { m_delete (arg, "width"); m_delete (arg, "height"); }
dd4e592000-08-21Martin Nilsson  res+=Roxen.make_tag( "img", arg, xml )+" ";
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson  return sprintf(lp,res);
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson 
9363fa2009-11-24Henrik Grubbström (Grubba)  string num = image_cache->store( ({ p, c }), id, timeout );
91d0172009-12-01Henrik Grubbström (Grubba)  mapping size = image_cache->metadata( num, id, no_draw, timeout );
a3dfd41999-11-28Martin Nilsson  if(!arg->alt) arg->alt=replace(c,"\"","'");
f1be801998-02-22Per Hedbor 
db053e2000-12-05Martin Nilsson  arg->src=query_absolute_internal_location(id)+num+ext;
a3dfd41999-11-28Martin Nilsson  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  {
a3e0ac2000-09-29Martin Nilsson  string magic=replace(m_delete(arg,"magic"), "'", "`");
a3dfd41999-11-28Martin Nilsson  if(p->bevel) p->pressed=1;
7519ad2000-03-16Martin Nilsson  m_delete(p, "fgcolor");
0786ff2000-10-19Per Hedbor  foreach(glob("magic-*", indices(arg)), string q)
c2fdf32002-02-06Martin Nilsson  p[q[6..]]=m_delete(arg, q);
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";
9363fa2009-11-24Henrik Grubbström (Grubba)  string num2 = image_cache->store( ({ p, c }), id, timeout );
91d0172009-12-01Henrik Grubbström (Grubba)  size = image_cache->metadata( num2, id, UNDEFINED, timeout );
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  }
c320d02006-09-13Stefan Wallström #ifdef GTEXT_RANDOM_PREFIX string sn = "gtext" + get_gtext_pfx(id) + id->root_id->misc->gtext_mi++; #else
8fc4242001-11-30Martin Stjernholm  string sn = "gtext" + id->root_id->misc->gtext_mi++;
c320d02006-09-13Stefan Wallström #endif
a23e502003-10-03Marcus Wellhardh  RXML_CONTEXT->set_root_id_misc("gtext_mi", id->root_id->misc->gtext_mi);
339e542003-04-22Anders Johansson  if(honor_supports && !id->supports->js_image_object) {
a3dfd41999-11-28Martin Nilsson  return (!input)?
21171e2000-08-25Martin Nilsson  ("<a"+ea+"href=\""+url+"\">"+Roxen.make_tag("img",arg+(["name":sn]),xml)+"</a>"):
dd4e592000-08-21Martin Nilsson  Roxen.make_tag("input",arg+(["type":"image"]),xml);
a3dfd41999-11-28Martin Nilsson  } arg->name=sn;
b62de02002-02-05Anders Johansson  string res="<script type='text/javascript'>\n";
750d632005-05-19Stefan Wallström  res += gtext_javascript(id);
a3dfd41999-11-28Martin Nilsson  return res+ " "+sn+"l = new Image("+arg->width+", "+arg->height+");"+sn+"l.src = \""+arg->src+"\";\n"
db053e2000-12-05Martin Nilsson  " "+sn+"h = new Image("+arg->width+", "+arg->height+");"+sn+"h.src = \"" + query_absolute_internal_location(id)+num2+ext+"\";\n"
e954162000-01-02Martin Nilsson  "</script>\n"+
21171e2000-08-25Martin Nilsson  "<a"+ea+"href=\""+url+"\" "+
a3dfd41999-11-28Martin Nilsson  (input?"onClick='document.forms[0].submit();' ":"")
839eb02001-04-25Martin Nilsson  +"onMouseover=\"gtext_mo('"+sn+"',"+sn+"h,"+((strlen(magic) && magic != "magic")? "'"+replace(magic,"'","`")+"'": "0")+"); return true;\" "
3dff862000-03-20Per Hedbor  "onMouseout=\"document.images['"+sn+"'].src = "+sn+"l.src;\">"
dd4e592000-08-21Martin Nilsson  +Roxen.make_tag("img",arg,xml)+"</a>";
d47cbf1996-12-02Per Hedbor  }
a3dfd41999-11-28Martin Nilsson 
ca0f081997-02-22Per Hedbor  if(input)
dd4e592000-08-21Martin Nilsson  return Roxen.make_tag("input",arg+(["type":"image"]),xml);
a3dfd41999-11-28Martin Nilsson 
dd4e592000-08-21Martin Nilsson  return sprintf(lp,Roxen.make_tag("img",arg,xml));
d47cbf1996-12-02Per Hedbor }
783e1b2001-07-10Martin Nilsson private 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";
a50b592000-09-03Martin Nilsson  return ({ "<p>"+do_gtext(m,c,id)+"</p><br />" });
a3dfd41999-11-28Martin Nilsson }
a50b592000-09-03Martin Nilsson class TagAnfang { inherit RXML.Tag; constant name = "anfang";
1b2d742001-10-08Anders Johansson  constant flags = RXML.FLAG_DONT_REPORT_ERRORS;
a50b592000-09-03Martin Nilsson  class Frame { inherit RXML.Frame; array do_return(RequestID id) { if(!args->align) args->align="left"; return ({ "<br clear=\"left\" />"+do_gtext(args,content[0..0],id)+content[1..] }); } }
a3dfd41999-11-28Martin Nilsson } // --------------- tag and container registration ----------------------
7519ad2000-03-16Martin Nilsson mapping query_simpletag_callers() {
a50b592000-09-03Martin Nilsson  return ([ "gh1" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }),
cf18f92000-08-15Martin Stjernholm  "gh2" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }), "gh3" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }), "gh4" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }), "gh5" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }), "gh6" : ({ RXML.FLAG_DONT_REPORT_ERRORS, simpletag_gh }),
7519ad2000-03-16Martin Nilsson  ]);
d47cbf1996-12-02Per Hedbor }