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

version» Context lines:

Roxen.git/server/modules/graphics/graphic_text.pike:1: - constant cvs_version="$Id: graphic_text.pike,v 1.100 1998/02/05 00:59:25 js Exp $"; + constant cvs_version="$Id: graphic_text.pike,v 1.101 1998/02/10 18:36:17 per Exp $";   constant thread_safe=1;      #include <module.h> -  + #include <stat.h>   inherit "module";   inherit "roxenlib";    - #if efun(_static_modules) - # define map_array Array.map - import Image; - # define Image image - # define Font font - #endif -  +    #ifndef VAR_MORE   #define VAR_MORE 0   #endif /* VAR_MORE */      array register_module()   {    return ({ MODULE_LOCATION | MODULE_PARSER,    "Graphics text",    "Defines a few new containers, which all render text to gifs "    "using the image module in pike.\n<p>"
Roxen.git/server/modules/graphics/graphic_text.pike:124:    return fnts;   }      void create()   {    defvar("cache_dir", "../gtext_cache", "Cache directory for gtext images",    TYPE_DIR,    "The gtext tag saves images when they are calculated in this "    "directory. We currently do not clean this directory.");    +  defvar("cache_age", 48, "Cache max age", +  +  TYPE_INT, +  +  "If the images in the cache have not been accessed for this " +  "number of hours they are removed."); +     defvar("speedy", 0, "Avoid automatic detection of document colors",    TYPE_FLAG|VAR_MORE,    "If this flag is set, the tags 'body', 'tr', 'td', 'font' and 'th' "    " will <b>not</b> be parsed to automatically detect the colors of "    " a document. You will then have to specify all colors in all calls "    " to &lt;gtext&gt;");       defvar("deflen", 300, "Default maximum text-length", TYPE_INT|VAR_MORE,    "The module will, per default, not try to render texts "    "longer than this. This is a safeguard for things like "
Roxen.git/server/modules/graphics/graphic_text.pike:169:       defvar("default_font", "urw_itc_avant_garde-demi-r", "Default font",    TYPE_STRING_LIST,    "The default font. The 'font dir' will be prepended to the path",    list_fonts());   #endif   }      string query_location() { return query("location"); }    - object(Font) load_font(string name, string justification, int xs, int ys) + object load_font(string name, string justification, int xs, int ys)   { -  object fnt = Font(); +  object fnt = Image.font();       if ((!name)||(name == ""))    {    return get_font("default",32,0,0,lower_case(justification||"left"),    (float)xs, (float)ys);    } else if(sscanf(name, "%*s/%*s") != 2) {    name=QUERY(default_size)+"/"+name;    }       name = "fonts/" + name;
Roxen.git/server/modules/graphics/graphic_text.pike:212:   #define MAX(a,b) ((a)<(b)?(b):(a))      #if !efun(make_matrix)   static private mapping (int:array(array(int))) matrixes = ([]);   array (array(int)) make_matrix(int size)   {    if(matrixes[size]) return matrixes[size];    array res;    int i;    int j; -  res = map_array(allocate(size), lambda(int s, int size){ +  res = Array.map(allocate(size), lambda(int s, int size){    return allocate(size); }, size);       for(i=0; i<size; i++)    for(j=0; j<size; j++)    res[i][j] = (int)MAX((float)size/2.0-sqrt((size/2-i)*(size/2-i) + (size/2-j)*(size/2-j)),0);    return matrixes[size] = res;   }   #endif      string fix_relative(string file, object id)
Roxen.git/server/modules/graphics/graphic_text.pike:236:    return file;   }      object last_image; // Cache the last image for a while.   string last_image_name;   object load_image(string f,object id)   {    if(last_image_name == f && last_image) return last_image->copy();    string data;    object file; -  object img = Image(); +  object img = Image.image();       if(!(data=roxen->try_get_file(fix_relative(f, id),id)))    if(!(file=open(f,"r")) || (!(data=file->read())))    return 0;   //werror("Read "+strlen(data)+" bytes.\n");    if (catch { if(!img->frompnm(data)) return 0;}) return 0;    last_image = img; last_image_name = f;    return img->copy();   }    - object (Image) blur(object img, int amnt) + object blur(object img, int amnt)   {    img->setcolor(0,0,0);    img = img->autocrop(amnt, 0,0,0,0, 0,0,0);       for(int i=0; i<amnt; i++)    img = img->apply_matrix( make_matrix((int)sqrt(img->ysize()+20)));    return img;   }    - object (Image) outline(object (Image) on, object (Image) with, + object outline(object on, object with,    array (int) color, int radie, int x, int y)   {    int steps=10;    for(int j=0; j<=steps; j++)    on->paste_alpha_color(with, @color,    (int)(0.5+x-(sin((float)j/steps*3.145*2)*radie)),    (int)(0.5+y-(cos((float)j/steps*3.145*2)*radie)));    return on;   }      array white = ({ 255,255,255 });   array lgrey = ({ 200,200,200 });   array grey = ({ 128,128,128 });   array black = ({ 0,0,0 });      array wwwb = ({ lgrey,lgrey,grey,black }); - object (Image) bevel(object (Image) in, int width, int|void invert) + object bevel(object in, int width, int|void invert)   {    int h=in->ysize();    int w=in->xsize();    -  object corner = Image(width+1,width+1); -  object corner2 = Image(width+1,width+1); -  object pix = Image(1,1); +  object corner = Image.image(width+1,width+1); +  object corner2 = Image.image(width+1,width+1); +  object pix = Image.image(1,1);       for(int i=-1; i<=width; i++) {    corner->line(i,width-i,i,-1, @white);    corner2->setpixel(width-i, width-i, @white);    in->paste_alpha(pix, 185, w - width + i+1, h - width + i+1);    }       if(!invert)    { -  in->paste_alpha(Image(width,h-width*2,@white), 160, 0, width); -  in->paste_alpha(Image(width,h-width*2,@black), 128, in->xsize()-width, width); -  in->paste_alpha(Image(w-width,width,@white), 160, 0, 0); -  in->paste_alpha(Image(w-width,width,@black), 128, width, in->ysize()-width); +  in->paste_alpha(Image.image(width,h-width*2,@white), 160, 0, width); +  in->paste_alpha(Image.image(width,h-width*2,@black), 128, in->xsize()-width, width); +  in->paste_alpha(Image.image(w-width,width,@white), 160, 0, 0); +  in->paste_alpha(Image.image(w-width,width,@black), 128, width, in->ysize()-width);    } else {    corner=corner->invert();    corner2=corner2->invert(); -  in->paste_alpha(Image(width,h-width*2,@black), 160, 0, width); -  in->paste_alpha(Image(width,h-width*2,@white), 128, in->xsize()-width, width); -  in->paste_alpha(Image(w-width,width,@black), 160, 0, 0); -  in->paste_alpha(Image(w-width,width,@white), 128, width, in->ysize()-width); +  in->paste_alpha(Image.image(width,h-width*2,@black), 160, 0, width); +  in->paste_alpha(Image.image(width,h-width*2,@white), 128, in->xsize()-width, width); +  in->paste_alpha(Image.image(w-width,width,@black), 160, 0, 0); +  in->paste_alpha(Image.image(w-width,width,@white), 128, width, in->ysize()-width);    }       in->paste_mask(corner, corner->color(95,95,95), in->xsize()-width,-1);    in->paste_mask(corner, corner->invert()->color(128,128,128),    in->xsize()-width,-1);    in->paste_mask(corner, corner->color(95,95,95), -1, in->ysize()-width);    in->paste_mask(corner, corner->invert()->color(128,128,128),    -1, in->ysize()-width);    corner=0;    in->paste_mask(corner2, corner2->color(70,70,70), -1, -1);       corner2 = pix = 0;    return in;   }       - object (Image) make_text_image(mapping args, object font, string text,object id) + object make_text_image(mapping args, object font, string text,object id)   {    object text_alpha=font->write(@(text/"\n"));    int xoffset=0, yoffset=0;       if(!text_alpha->xsize() || !text_alpha->ysize()) -  text_alpha = Image(10,10, 0,0,0); +  text_alpha = Image.image(10,10, 0,0,0);      // perror("Making image of '%s', args=%O\n", text, args);       if(int op=((((int)args->opaque)*255)/100)) // Transparent text...    text_alpha=text_alpha->color(op,op,op);       int txsize=text_alpha->xsize();    int tysize=text_alpha->ysize(); // Size of the text, in pixels.       int xsize=txsize; // image size, in pixels
Roxen.git/server/modules/graphics/graphic_text.pike:439:    case "center":    xoffset = (xsize/2 - txsize/2);    yoffset = (ysize/2 - tysize/2);    break;    case "right":    xoffset = (xsize - txsize);    break;    case "left":    }    } else -  background = Image(xsize, ysize, @bgcolor); +  background = Image.image(xsize, ysize, @bgcolor);       if(args->border)    {    int b = (int)args->border;    background->setcolor(@parse_color((args->border/",")[-1]));       for(--b;b>=0;b--)    {    // upper left -- upper right    background->line(b,b, xsize-b-1, b);
Roxen.git/server/modules/graphics/graphic_text.pike:495:       if(args->bevel)    background = bevel(background,(int)args->bevel,!!args->pressed);       if(args->textbox) // Draw a text-box on the background.    {    int alpha,border;    string bg;    sscanf(args->textbox, "%d,%s", alpha, bg);    sscanf(bg,"%s,%d", bg,border); -  background->paste_alpha(Image(txsize+border*2,tysize+border*2, +  background->paste_alpha(Image.image(txsize+border*2,tysize+border*2,    @parse_color(bg)),    255-(alpha*255/100),xoffset-border,yoffset-border);    }       if(args->ghost)    { // Francesco..    int sdist = (int)args->ghost;    int bl=(int)(args->ghost/",")[1];    array(int)clr=parse_color((args->ghost/",")[-1]);    int j;
Roxen.git/server/modules/graphics/graphic_text.pike:535:    }      #define MIN(x,y) ((x)<(y)?(x):(y))       if(args->bshadow)    {    int sdist = (int)(args->bshadow)+1;    int xs,ys;    xs = text_alpha->xsize()+sdist*2+4;    ys = text_alpha->ysize()+sdist*2+4; -  object ta = Image(xs+sdist*2,ys+sdist*2); +  object ta = Image.image(xs+sdist*2,ys+sdist*2);    array sc = parse_color(args->scolor||"black");       ta->paste_alpha_color(text_alpha,255,255,255,sdist,sdist);    ta = blur(ta, MIN((sdist/2),1))->color(256,256,256);       background->paste_alpha_color(ta,sc[0],sc[1],sc[2],    xoffset+sdist,yoffset+sdist);    }       if(args->glow)
Roxen.git/server/modules/graphics/graphic_text.pike:561:    }       if(args->chisel)    foreground=text_alpha->apply_matrix(({ ({8,1,0}),    ({1,0,-1}),    ({0,-1,-8}) }),    128,128,128, 15 )    ->color(@fgcolor);       -  if(!foreground) foreground=Image(txsize, tysize, @fgcolor); +  if(!foreground) foreground=Image.image(txsize, tysize, @fgcolor);    if(args->textscale)    {    string c1="black",c2="black",c3="black",c4="black";    sscanf(args->textscale, "%s,%s,%s,%s", c1, c2, c3, c4);    foreground->tuned_box(0,0, txsize,tysize,    ({parse_color(c1),parse_color(c2),parse_color(c3),    parse_color(c4)}));    }    if(args->outline)    outline(background, text_alpha, parse_color((args->outline/",")[0]),
Roxen.git/server/modules/graphics/graphic_text.pike:602:    }       if(args->crop) background = background->autocrop();       return background;   }      string base_key;   object mc;    +  + array to_clean = ({}); + void clean_cache_dir() + { +  if(!sizeof(to_clean)) +  to_clean = get_dir(query("cache_dir")); +  if(!sizeof(to_clean)) return; +  int md = file_stat(query("cache_dir")+to_clean[0])[ST_ATIME]; +  +  if((time() - md) > (query("cache_age")*3600)) +  rm(query("cache_dir")+to_clean[0]); +  +  to_clean = to_clean[1..]; +  if(sizeof(to_clean)) +  call_out(clean_cache_dir, 0.1); +  else +  call_out(clean_cache_dir, 3600); + } +    void start(int|void val, object|void conf)   {    if(conf)    {    mkdirhier( query( "cache_dir" )+".foo" );   #ifndef __NT__   #if efun(chmod)    chmod( query( "cache_dir" ), 0777 );   #endif   #endif -  +  remove_call_out(clean_cache_dir); +  call_out(clean_cache_dir, 10);    mc = conf;    base_key = "gtext:"+(conf?conf->name:roxen->current_configuration->name);    }   }      #ifdef QUANT_DEBUG   void print_colors(array from)   {   #if efun(color_name)    for(int i=0; i<sizeof(from); i++)
Roxen.git/server/modules/graphics/graphic_text.pike:847:   // place in cache, as a gif image.       if(!args->scroll)    if(args->fadein)    {    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)    { -  object foo=image(img->xsize(),img->ysize(),@parse_color(args->bg)); +  object foo=Image.image(img->xsize(),img->ysize(),@parse_color(args->bg));    res += foo->gif_add(0,0,initialdelay);    }    for(int i = 0; i<(steps-1); i++)    {    object foo=img->clone();    foo = foo->apply_matrix(make_matrix(( (int)((steps-i)*amount))));    res += foo->gif_add(0,0,delay);    }    res+= img->gif_add(0,0,delay);    res += img->gif_end();
Roxen.git/server/modules/graphics/graphic_text.pike:1054:   {    if(!id->supports->images) return alt;    if(!id->supports->netscape_javascript)    return (!input)?    ("<a "+extra_args+"href=\""+url+"\"><img _parsed=1 src=\""+image_1+"\" name="+sn+" border=0 "+    "alt=\""+alt+"\"></a>\n"):    ("<input type=image "+extra_args+" src=\""+image_1+"\" name="+input+">");       return    ("<script>\n" -  " "+sn+"l = new Image("+xs+", "+ys+");"+sn+"l.src = \""+image_1+"\";\n" -  " "+sn+"h = new Image("+xs+", "+ys+");"+sn+"h.src = \""+image_2+"\";\n" +  " "+sn+"l = new Image.image("+xs+", "+ys+");"+sn+"l.src = \""+image_1+"\";\n" +  " "+sn+"h = new Image.image("+xs+", "+ys+");"+sn+"h.src = \""+image_2+"\";\n"    "</script>\n"+    ("<a "+extra_args+"href=\""+url+"\" "+    (input?"onClick='document.forms[0].submit();' ":"")    +"onMouseover=\"img_act('"+sn+"',"+sn+"h,'"+(mess||url)+"'); return true;\"\n"    "onMouseout='document.images[\""+sn+"\"].src = "+sn+"l.src;'><img "    "_parsed=1 width="+xs+" height="+ys+" src=\""+image_1+"\" name="+sn+    " border=0 alt=\""+alt+"\" ></a>\n"));   }