1 /* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: image_converter.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
19 inherit "/kernel/module";
21 #include <attributes.h>
23 //! Converts images from one format to another. The most
24 //! important function is the get_image() function of this module.
26 class image_converter : public module{
35 #define _FILEPATH _Server->get_module("filepath:tree")
36 #define MODULE_FONT_CACHE _Server->get_module("fonts:TTF")
41 * Get a font according to font-description
42 * substitutes the default font, if no matching font can be found.
43 * @param type - the fonts name
44 * @param style - 0 plain, 1 bold, 2 italic (bitwise or to use combinations)
45 * @param size - fontsize
48 private Image.Font get_font(string type, int style, int size)
51 if ( objectp(MODULE_FONT_CACHE) )
53 oTTF=MODULE_FONT_CACHE->get_font_object(type, style);
58 oTTF->set_height(size);
68 private array __text_extends(array list, object font)
70 mapping(int:int) width_cache=([]);
73 foreach(list, string s)
76 foreach(s/"", string c)
78 if (w=width_cache[c[0]])
82 width_cache[c[0]]=w=font->write(c)->xsize();
86 result += ({ width });
94 private array wrap_with_font(string from, int width, object font)
96 // array charlens = font->text_extends(from/"");
97 // doesn't work inspite of the Pike Dokumentation
98 array charlens = __text_extends(from/"", font);
104 for (i=0,sz=sizeof(charlens);i<sz;i++)
108 result += ({ from[last_pos..i-1] });
115 if ((curr_len < width) ||
116 (font->write(from[last_pos..i-1])->xsize()) < width)
117 curr_len += charlens[i];
121 while (from[i]==' ') i++;
124 while (from[i]!=' ' && i>last_pos) i--;
126 if (i==last_pos) i=oldi;
128 result += ({ from[last_pos..i-1] });
134 result += ({ from[last_pos..sz] });
135 LOG("number of lines wrapped is"+sizeof(result));
142 private object hard_default_icon(int iOclass)
146 if (iOclass & CLASS_CONTAINER)
147 if (iOclass & CLASS_ROOM)
148 sImagePath = "/images/doctypes/type_room.gif";
150 sImagePath = "/images/doctypes/type_folder.gif";
152 if (iOclass & CLASS_DOCLPC)
153 sImagePath = "/images/doctypes/type_object.gif";
155 object oIcon=_FILEPATH->path_to_object(sImagePath);
161 private Image.Layer image_from_object(object oIcon)
163 string sMime = oIcon->query_attribute(DOC_MIME_TYPE);
167 sscanf(sMime, "image/%s", sMime);
168 sMime = upper_case(sMime);
170 LOG("sMime in image_from_object is "+sMime);
171 string content = oIcon->get_content();
174 object oInputImageCoder = Image[sMime];
175 if (objectp(oInputImageCoder))
177 return oInputImageCoder->decode_layer(content)->image();
179 return oInputImageCoder->decode(content);
187 * Get an image representation of given (container) object (if any)
189 * @param obj - the object to represent
190 * @param x - x-size of image
191 * @param y - y-size of image
192 * @param encoding - an image/encoding (e.g. image/jpeg)
193 * @return a string containing the image of given encoding
195 string get_image(object obj, int x, int y, string encoding)
202 string sImagePath = "/images/doctypes/type_generic.gif";
204 if (!(obj->get_object_class() & CLASS_CONTAINER))
207 aoInv = obj->get_inventory();
211 mapping mLayer = obj->query_attribute("WHITEBOARD_ATTR_LAYER_INFO");
214 foreach(aoInv, object o)
215 LOG("["+o->get_object_id()+"]");
216 mLayer -= ({"size"});
217 mapping(int:int) LayTable = ([]);
218 foreach(indices(mLayer), int layer)
219 LayTable[mLayer[layer]]=layer;
220 array ordered = allocate(sizeof(mLayer));
223 for (int i=0; i<sizeof(aoInv); i++)
225 p=LayTable[aoInv[i]->get_object_id()];
228 LOG("p for "+aoInv[i]->get_object_id()+" is "+p+"("+
229 aoInv[i]->get_identifier()+")");
234 aoInv += reverse(ordered);
236 foreach(aoInv, object o)
237 LOG("["+o->get_object_id()+"]");
241 x = (int) obj->query_attribute(CONT_SIZE_X);
246 y = (int) obj->query_attribute(CONT_SIZE_Y);
250 object oImage = Image.Image(x, y);
251 // object oColor = Image.Color()
252 oImage->box(0,0,x,y,255,255,255);
253 oImage->box(0,0,0,0,0,0,0);
254 // to do ... sort by WHITEBOARD_ATTR_LAYER_INFO
256 foreach(aoInv, object graphics)
258 LOG("I:"+sprintf("%O", graphics));
259 int x1 = (int) graphics->query_attribute(OBJ_POSITION_X);
260 int w = (int) graphics->query_attribute(DRAWING_WIDTH);
261 int x2 = (int) x1+ w;
262 int y1 = (int) graphics->query_attribute(OBJ_POSITION_Y);
263 int h = (int) graphics->query_attribute(DRAWING_HEIGHT);
265 int iColor = graphics->query_attribute(DRAWING_COLOR);
270 iColor = iColor >> 8;
272 iColor = iColor >> 8;
277 if (!((iOclass = graphics->get_object_class()) &
278 (CLASS_DRAWING|CLASS_USER )))
280 oIcon=graphics->query_attribute(OBJ_ICON);
282 oIcon= hard_default_icon(iOclass);
286 catch {oTempImage = image_from_object(oIcon);};
289 oLine = Image.Font()->write(graphics->get_identifier());
290 oImage->paste_alpha_color(
293 (y1+oTempImage->ysize())
295 oImage->paste(oTempImage, x1-(oTempImage->xsize()/2)+(oLine->xsize()/2), y1);
300 switch (graphics->query_attribute(DRAWING_TYPE))
303 if (graphics->query_attribute("LINE_ATTR_DIRECTION") == 1)
304 oImage->line(x1, y1, x2, y2, r, g, b);
306 oImage->line(x1, y2, x2, y1, r, g, b);
308 case DRAWING_RECTANGLE:
309 oImage->line(x1, y1, x2, y1, r, g, b);
310 oImage->line(x1, y1, x1, y2, r, g, b);
311 oImage->line(x2, y1, x2, y2, r, g, b);
312 oImage->line(x1, y2, x2, y2, r, g, b);
314 //case DRAWING_TRIANGLE:
315 //case DRAWING_POLYGON:
317 case DRAWING_CIRCLE :
318 oImage->circle((x1+x2)/2,(y1+y2)/2,
319 (int)(w/2), (int) (h/2), r, g, b);//, 0, 255, 0);
322 case 9: // embedded image
323 oIcon = graphics->query_attribute("IMAGE_ATTR_IMAGEOBJECT");
326 catch {oTempImage = image_from_object(oIcon);};
329 float xf = (float)w /(float)oTempImage->xsize();
330 float yf = (float)h /(float)oTempImage->ysize();
331 oImage->paste(oTempImage->scale(xf,yf), x1, y1);
335 case 10: // filled rectangle
336 oImage->box(x1,y1,x2,y2, r,g,b);
338 case 11: // filled circle
339 oTempImage = Image.Image(w,h);
340 oTempImage->circle(w/2, h/2, w/2, h/2, 255, 255, 255);
341 oImage->paste_alpha_color(
342 oTempImage->select_from(w/2,h/2), r,g,b,x1,y1);
344 case DRAWING_TEXT : // obsolete, but for compatibility reasons.
345 case 16 : // multiline text
346 string fontfile = graphics->query_attribute("TEXT_ATTR_TYPE");
347 int fontstyle = graphics->query_attribute("TEXT_ATTR_STYLE");
348 string textlabel = graphics->query_attribute("TEXT_ATTR_TEXT");
349 int fontsize = graphics->query_attribute("TEXT_ATTR_SIZE");
351 object oFont = get_font(fontfile, fontstyle, fontsize);
353 /*if ( stringp(textlabel) )
355 oLine = oFont->write(textlabel);
356 oImage->paste_alpha_color(oLine, r,g,b, x1, y1);
358 if (stringp(textlabel))
361 wrap_with_font(textlabel, w, oFont);
362 for (int i=0;i<sizeof(splitted);i++)
364 LOG("Line"+i+":"+splitted[i]);
365 oLine = oFont->write(splitted[i]);
366 oImage->paste_alpha_color(oLine, r,g,b, x1, y1);
367 y1 += (int)(oLine->ysize()*1.2);
372 LOG("unknown graphixtype:"+
373 graphics->query_attribute(DRAWING_TYPE));
376 if (!encoding) // use a free one by default!
377 encoding = "image/jpeg";
380 sscanf(encoding, "image/%s", sImageCoder);
381 sImageCoder = upper_case(sImageCoder);
382 object oImageCoder = Image[sImageCoder];
387 return oImageCoder->encode(oImage);
390 string get_image_map(object obj, void|mapping vars)
395 string sImagePath = "/images/doctypes/type_generic.gif";
397 if (!(obj->get_object_class() & CLASS_CONTAINER))
400 aoInv = obj->get_inventory();
404 sImageMap = "<map name=\""+obj->get_object_id()+"\">\n";
405 foreach(aoInv, object graphics)
409 if (!((iOclass = graphics->get_object_class())
410 & (CLASS_DRAWING|CLASS_USER)))
412 int x1 = (int) graphics->query_attribute(OBJ_POSITION_X);
413 int w = (int) graphics->query_attribute(DRAWING_WIDTH);
414 int y1 = (int) graphics->query_attribute(OBJ_POSITION_Y);
415 int h = (int) graphics->query_attribute(DRAWING_HEIGHT);
419 object oIcon = graphics->query_attribute(OBJ_ICON);
420 if ( !objectp(oIcon) )
422 string sMime = oIcon->query_attribute(DOC_MIME_TYPE);
426 sscanf(sMime, "image/%s", sMime);
427 sMime = upper_case(sMime);
429 MESSAGE("Module"+sMime);
430 object oInputImageCoder = Image[sMime];
431 if (objectp(oInputImageCoder))
433 MESSAGE("ImageCoder:"+master()->describe_object(oInputImageCoder));
437 oInputImageCoder->decode_map(oIcon->get_content());
440 oInputImageCoder->_decode(oIcon->get_content());
441 w = mIconData["xsize"];
442 h = mIconData["ysize"];
446 sImageMap +=" <area shape=\"rect\" coords=\""+
447 x1+ ", " + y1 + ", " + (x1+w) + ", " + (y1+h) +"\" "+
448 href_link_navigate_postfix(graphics, vars->prefix, vars->postfix)+"/>\n";
450 oLine = Image.Font()->write(graphics->get_identifier());
451 sImageMap +=" <area shape=\"rect\" coords=\""+
452 (x1+(w/2)-(oLine->xsize()/2))+", "+
454 (x1+(w/2)+(oLine->xsize()/2))+", "+
455 (y1+h+5+oLine->ysize())+"\" "+
456 href_link_navigate_postfix(graphics, vars->prefix, vars->postfix)+"/>\n";
461 if (stringp(vars["x"])) x = (int)vars["x"];
462 if (intp(vars["x"])) x = vars["x"];
463 if (stringp(vars["y"])) y = (int)vars["y"];
464 if (intp(vars["x"])) y = vars["y"];
465 sImageMap += "</map> <img src=\"/scripts/svg.svg?object="+obj->get_object_id()+
466 "&enc=image/jpeg&x="+x+"&y="+y+"\" usemap=\"#"+obj->get_object_id()+"\"/>\n";
471 string get_identifier() { return "Converter:IMAGE"; }