1 /***************************************************************************
2  begin       : Mon Feb 22 2010
3  copyright   : (C) 2010 by Martin Preuss
4  email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #include "fox16_htmlctx_p.hpp"
15 #include "fox16_gui.hpp"
16 
17 #include <assert.h>
18 
19 #include <gwenhywfar/inherit.h>
20 #include <gwenhywfar/debug.h>
21 #include <gwenhywfar/gui_be.h>
22 #include <gwenhywfar/i18n.h>
23 #include <gwenhywfar/htmlctx_be.h>
24 #include <gwenhywfar/o_image_be.h>
25 #include <gwenhywfar/text.h>
26 #include <gwenhywfar/debug.h>
27 #include <gwenhywfar/syncio_memory.h>
28 #include <gwenhywfar/directory.h>
29 
30 
31 
GWEN_INHERIT(GWEN_XML_CONTEXT,FOX16_HtmlCtx)32 GWEN_INHERIT(GWEN_XML_CONTEXT, FOX16_HtmlCtx)
33 GWEN_INHERIT(HTML_FONT, FXFont)
34 GWEN_INHERIT(HTML_IMAGE, FXImage)
35 
36 
37 
38 int FOX16_HtmlCtxLinker::GetTextWidth(GWEN_XML_CONTEXT *ctx,
39                                       HTML_FONT *fnt,
40                                       const char *s) {
41   FOX16_HtmlCtx *xctx;
42 
43   assert(ctx);
44   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx);
45   assert(xctx);
46 
47   return xctx->getTextWidth(fnt, s);
48 }
49 
50 
51 
GetTextHeight(GWEN_XML_CONTEXT * ctx,HTML_FONT * fnt,const char * s)52 int FOX16_HtmlCtxLinker::GetTextHeight(GWEN_XML_CONTEXT *ctx,
53                                        HTML_FONT *fnt,
54                                        const char *s) {
55   FOX16_HtmlCtx *xctx;
56 
57   assert(ctx);
58   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx);
59   assert(xctx);
60 
61   return xctx->getTextHeight(fnt, s);
62 }
63 
64 
65 
GetColorFromName(const GWEN_XML_CONTEXT * ctx,const char * name)66 uint32_t FOX16_HtmlCtxLinker::GetColorFromName(const GWEN_XML_CONTEXT *ctx,
67     const char *name) {
68   FOX16_HtmlCtx *xctx;
69 
70   assert(ctx);
71   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx);
72   assert(xctx);
73 
74   return xctx->getColorFromName(name);
75 }
76 
77 
78 
GetFont(GWEN_XML_CONTEXT * ctx,const char * fontName,int fontSize,uint32_t fontFlags)79 HTML_FONT *FOX16_HtmlCtxLinker::GetFont(GWEN_XML_CONTEXT *ctx,
80                                         const char *fontName,
81                                         int fontSize,
82                                         uint32_t fontFlags) {
83   FOX16_HtmlCtx *xctx;
84 
85   assert(ctx);
86   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx);
87   assert(xctx);
88 
89   return xctx->getFont(fontName, fontSize, fontFlags);
90 }
91 
92 
93 
GetImage(GWEN_XML_CONTEXT * ctx,const char * imageName)94 HTML_IMAGE *FOX16_HtmlCtxLinker::GetImage(GWEN_XML_CONTEXT *ctx,
95     const char *imageName) {
96   FOX16_HtmlCtx *xctx;
97 
98   assert(ctx);
99   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx);
100   assert(xctx);
101 
102   return xctx->getImage(imageName);
103 
104 }
105 
106 
107 
freeData(void * bp,void * p)108 void FOX16_HtmlCtxLinker::freeData(void *bp, void *p) {
109   FOX16_HtmlCtx *xctx;
110 
111   xctx=(FOX16_HtmlCtx*) p;
112   if (xctx->_context)
113     xctx->_context=NULL;
114   delete xctx;
115 }
116 
117 
118 
freeFontData(void * bp,void * p)119 void FOX16_HtmlCtxLinker::freeFontData(void *bp, void *p) {
120   FXFont *xfnt;
121 
122   xfnt=(FXFont*) p;
123   delete xfnt;
124 }
125 
126 
127 
128 
freeImageData(void * bp,void * p)129 void FOX16_HtmlCtxLinker::freeImageData(void *bp, void *p) {
130   FXImage *ximg;
131 
132   ximg=(FXImage*) p;
133   delete ximg;
134 }
135 
136 
137 
138 
139 
FOX16_HtmlCtx(uint32_t flags)140 FOX16_HtmlCtx::FOX16_HtmlCtx(uint32_t flags)
141   :_context(NULL)
142   ,_font(NULL)
143   ,_fgColor(0)
144   ,_bgColor(0)
145   ,m_iconSource(NULL) {
146   HTML_PROPS *pr;
147   HTML_FONT *fnt;
148 
149   _context=HtmlCtx_new(flags);
150   GWEN_INHERIT_SETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, _context, this,
151                        FOX16_HtmlCtxLinker::freeData);
152   _font=FXApp::instance()->getNormalFont();
153   HtmlCtx_SetGetTextWidthFn(_context, FOX16_HtmlCtxLinker::GetTextWidth);
154   HtmlCtx_SetGetTextHeightFn(_context, FOX16_HtmlCtxLinker::GetTextHeight);
155   HtmlCtx_SetGetColorFromNameFn(_context, FOX16_HtmlCtxLinker::GetColorFromName);
156   HtmlCtx_SetGetFontFn(_context, FOX16_HtmlCtxLinker::GetFont);
157   HtmlCtx_SetGetImageFn(_context, FOX16_HtmlCtxLinker::GetImage);
158 
159   pr=HtmlProps_new();
160   fnt=HtmlCtx_GetFont(_context, _font->getName().text(), _font->getSize()/10, 0);
161   HtmlProps_SetFont(pr, fnt);
162   HtmlCtx_SetStandardProps(_context, pr);
163   HtmlProps_free(pr);
164 
165 }
166 
167 
168 
~FOX16_HtmlCtx()169 FOX16_HtmlCtx::~FOX16_HtmlCtx() {
170   if (_context) {
171     GWEN_INHERIT_UNLINK(GWEN_XML_CONTEXT, FOX16_HtmlCtx, _context);
172     GWEN_XmlCtx_free(_context);
173   }
174 }
175 
176 
177 
_getFoxFont(HTML_FONT * fnt)178 FXFont *FOX16_HtmlCtx::_getFoxFont(HTML_FONT *fnt) {
179   FXFont *xfnt;
180 
181   if (GWEN_INHERIT_ISOFTYPE(HTML_FONT, FXFont, fnt)) {
182     xfnt=GWEN_INHERIT_GETDATA(HTML_FONT, FXFont, fnt);
183     return xfnt;
184   }
185   else {
186     FXuint size;
187     FXuint weight;
188     FXuint slant;
189     FXuint encoding;
190     FXString face;
191     uint32_t flags;
192 
193     if (HtmlFont_GetFontName(fnt))
194       face=HtmlFont_GetFontName(fnt);
195     else
196       face=_font->getName();
197     size=HtmlFont_GetFontSize(fnt);
198     weight=FXFont::Normal;
199     slant=_font->getSlant();
200     encoding=_font->getEncoding();
201 
202     flags=HtmlFont_GetFontFlags(fnt);
203     if (flags & HTML_FONT_FLAGS_STRONG)
204       weight=FXFont::Bold;
205     if (flags & HTML_FONT_FLAGS_ITALIC)
206       slant=FXFont::Italic;
207 
208     DBG_DEBUG(GWEN_LOGDOMAIN,
209               "Creating font [%s], size=%d, weight=%d, slant=%d, encoding=%d",
210               face.text(), size, weight, slant, encoding);
211 
212     xfnt=new FXFont(FXApp::instance(), face, size, weight, slant, encoding);
213     if (xfnt==NULL) {
214       DBG_ERROR(GWEN_LOGDOMAIN,
215                 "Could not create font [%s], size=%d, weight=%d, slant=%d, encoding=%d",
216                 face.text(), size, weight, slant, encoding);
217       return NULL;
218     }
219     xfnt->create();
220     GWEN_INHERIT_SETDATA(HTML_FONT, FXFont, fnt, xfnt,
221                          FOX16_HtmlCtxLinker::freeFontData);
222     return xfnt;
223   }
224 }
225 
226 
227 
getTextWidth(HTML_FONT * fnt,const char * s)228 int FOX16_HtmlCtx::getTextWidth(HTML_FONT *fnt, const char *s) {
229   if (s==NULL) {
230     DBG_ERROR(GWEN_LOGDOMAIN, "NULLPOINTER, returning size 0");
231     return 0;
232   }
233   else {
234     FXFont *xfnt;
235     FXString str;
236 
237     str=FXString(s);
238     xfnt=_getFoxFont(fnt);
239     if (xfnt==NULL)
240       return _font->getTextWidth(str);
241     else
242       return xfnt->getTextWidth(str);
243   }
244 }
245 
246 
247 
getTextHeight(HTML_FONT * fnt,const char * s)248 int FOX16_HtmlCtx::getTextHeight(HTML_FONT *fnt, const char *s) {
249   if (s==NULL) {
250     DBG_ERROR(GWEN_LOGDOMAIN, "NULLPOINTER, returning size 0");
251     return 0;
252   }
253   else {
254     FXFont *xfnt;
255     FXString str;
256 
257     str=FXString(s);
258     xfnt=_getFoxFont(fnt);
259     if (xfnt==NULL)
260       return _font->getTextHeight(str);
261     else
262       return xfnt->getTextHeight(str);
263   }
264 }
265 
266 
267 
getColorFromName(const char * name)268 uint32_t FOX16_HtmlCtx::getColorFromName(const char *name) {
269   return fxcolorfromname(name);
270 }
271 
272 
273 
layout(int width,int height)274 int FOX16_HtmlCtx::layout(int width, int height) {
275   return HtmlCtx_Layout(_context, width, height);
276 }
277 
278 
279 
setText(const char * s)280 void FOX16_HtmlCtx::setText(const char *s) {
281   int rv;
282 
283   rv=GWEN_XMLContext_ReadFromString(_context, s);
284   if (rv<0) {
285     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
286   }
287 }
288 
289 
290 
addMediaPath(const char * s)291 void FOX16_HtmlCtx::addMediaPath(const char *s) {
292   HtmlCtx_AddMediaPath(_context, s);
293 }
294 
295 
296 
dumpObject(HTML_OBJECT * o,FILE * f,int indent)297 static void dumpObject(HTML_OBJECT *o, FILE *f, int indent) {
298   HTML_OBJECT *c;
299   int i;
300   const char *s;
301   HTML_PROPS *pr;
302   HTML_FONT *fnt;
303 
304   s=HtmlObject_GetText(o);
305   for (i=0; i<indent; i++) fprintf(f, " ");
306   fprintf(stderr, "Object type: %d [%s] flags: %08x, x=%d, y=%d, w=%d, h=%d\n",
307           HtmlObject_GetObjectType(o),
308           s?s:"(empty)",
309           HtmlObject_GetFlags(o),
310           HtmlObject_GetX(o),
311           HtmlObject_GetY(o),
312           HtmlObject_GetWidth(o),
313           HtmlObject_GetHeight(o));
314 
315   pr=HtmlObject_GetProperties(o);
316   fnt=HtmlProps_GetFont(pr);
317 
318   for (i=0; i<indent+2; i++) fprintf(f, " ");
319   fprintf(stderr, "fgcol=%06x, bgcol=%06x, fontsize=%d, fontflags=%08x, fontname=[%s]\n",
320           HtmlProps_GetForegroundColor(pr),
321           HtmlProps_GetBackgroundColor(pr),
322           HtmlFont_GetFontSize(fnt),
323           HtmlFont_GetFontFlags(fnt),
324           HtmlFont_GetFontName(fnt));
325 
326   c=HtmlObject_Tree_GetFirstChild(o);
327   while(c) {
328     dumpObject(c, f, indent+2);
329     c=HtmlObject_Tree_GetNext(c);
330   }
331 }
332 
333 
334 
dump()335 void FOX16_HtmlCtx::dump() {
336   HTML_OBJECT *o;
337 
338   o=HtmlCtx_GetRootObject(_context);
339   if (o)
340     dumpObject(o, stderr, 2);
341 }
342 
343 
344 
_paint(FXDC * dc,HTML_OBJECT * o,int xOffset,int yOffset)345 void FOX16_HtmlCtx::_paint(FXDC *dc, HTML_OBJECT *o, int xOffset, int yOffset) {
346   HTML_OBJECT *c;
347 
348   xOffset+=HtmlObject_GetX(o);
349   yOffset+=HtmlObject_GetY(o);
350 
351   switch(HtmlObject_GetObjectType(o)) {
352   case HtmlObjectType_Word: {
353     HTML_PROPS *pr;
354     HTML_FONT *fnt;
355     FXFont *xfnt;
356     int ascent=0;
357     uint32_t col;
358 
359     pr=HtmlObject_GetProperties(o);
360 
361     /* select font */
362     fnt=HtmlProps_GetFont(pr);
363     xfnt=_getFoxFont(fnt);
364     if (xfnt) {
365       dc->setFont(xfnt);
366       ascent=xfnt->getFontAscent();
367     }
368 
369     /* select foreground color */
370     col=HtmlProps_GetForegroundColor(pr);
371     if (col==HTML_PROPS_NOCOLOR)
372       dc->setForeground(_fgColor);
373     else
374       dc->setForeground(col);
375 
376     /* select background color */
377     col=HtmlProps_GetBackgroundColor(pr);
378     if (col==HTML_PROPS_NOCOLOR)
379       dc->setBackground(_bgColor);
380     else
381       dc->setBackground(col);
382 
383     dc->drawText(xOffset, yOffset+ascent, HtmlObject_GetText(o));
384     break;
385   }
386 
387   case HtmlObjectType_Image: {
388     HTML_IMAGE *img;
389 
390     img=HtmlObject_Image_GetImage(o);
391     if (img) {
392       FXImage *ximg;
393 
394       ximg=GWEN_INHERIT_GETDATA(HTML_IMAGE, FXImage, img);
395       if (ximg) {
396         HTML_PROPS *pr;
397         uint32_t col;
398 
399         pr=HtmlObject_GetProperties(o);
400 
401         /* select background color */
402         col=HtmlProps_GetBackgroundColor(pr);
403         if (col==HTML_PROPS_NOCOLOR) {
404           dc->setBackground(_bgColor);
405           dc->setForeground(_bgColor);
406         }
407         else {
408           dc->setBackground(col);
409           dc->setForeground(col);
410         }
411 
412         dc->fillRectangle(xOffset, yOffset, ximg->getWidth(), ximg->getHeight());
413 
414         dc->drawImage(ximg, xOffset, yOffset);
415       }
416     }
417     break;
418   }
419   default:
420     break;
421   }
422 
423   c=HtmlObject_Tree_GetFirstChild(o);
424   while(c) {
425     _paint(dc, c, xOffset, yOffset);
426     c=HtmlObject_Tree_GetNext(c);
427   }
428 }
429 
430 
431 
_paintAt(FXDC * dc,HTML_OBJECT * o,int xOffset,int yOffset,int xText,int yText,int w,int h)432 void FOX16_HtmlCtx::_paintAt(FXDC *dc, HTML_OBJECT *o,
433                              int xOffset, int yOffset,
434                              int xText, int yText,
435                              int w, int h) {
436   HTML_OBJECT *c;
437   int x;
438   int y;
439   int printX;
440   int printY;
441   int objectW;
442   int objectH;
443 
444   x=xText+HtmlObject_GetX(o);
445   y=yText+HtmlObject_GetY(o);
446   objectW=HtmlObject_GetWidth(o);
447   objectH=HtmlObject_GetHeight(o);
448 
449   printX=x-xOffset;
450   printY=y-yOffset;
451 
452   if (printX<w && printX+objectW>=0 &&
453       printY<h && printY+objectH>=0) {
454     switch(HtmlObject_GetObjectType(o)) {
455 #if 0
456     case HtmlObjectType_Grid:
457       dc->setForeground(FXRGB(255,0,0));
458       dc->fillRectangle(printX, printY,
459                         HtmlObject_GetWidth(o),
460                         HtmlObject_GetHeight(o));
461 #endif
462     case HtmlObjectType_Word: {
463       HTML_PROPS *pr;
464       HTML_FONT *fnt;
465       FXFont *xfnt;
466       int ascent=0;
467       uint32_t col;
468 
469       pr=HtmlObject_GetProperties(o);
470 
471       /* select font */
472       fnt=HtmlProps_GetFont(pr);
473       xfnt=_getFoxFont(fnt);
474       if (xfnt) {
475         dc->setFont(xfnt);
476         ascent=xfnt->getFontAscent();
477       }
478 
479       /* select foreground color */
480       col=HtmlProps_GetForegroundColor(pr);
481       if (col==HTML_PROPS_NOCOLOR)
482         dc->setForeground(_fgColor);
483       else
484         dc->setForeground(col);
485 
486       /* select background color */
487       col=HtmlProps_GetBackgroundColor(pr);
488       if (col==HTML_PROPS_NOCOLOR)
489         dc->setBackground(_bgColor);
490       else
491         dc->setBackground(col);
492 
493       dc->drawText(printX, printY+ascent, HtmlObject_GetText(o));
494       break;
495     }
496 
497     case HtmlObjectType_Image: {
498       HTML_IMAGE *img;
499 
500       img=HtmlObject_Image_GetImage(o);
501       if (img) {
502         FXImage *ximg;
503 
504         ximg=GWEN_INHERIT_GETDATA(HTML_IMAGE, FXImage, img);
505         if (ximg) {
506           HTML_PROPS *pr;
507           uint32_t col;
508 
509           pr=HtmlObject_GetProperties(o);
510 
511           /* select background color */
512           col=HtmlProps_GetBackgroundColor(pr);
513           if (col==HTML_PROPS_NOCOLOR) {
514             dc->setBackground(_bgColor);
515             dc->setForeground(_bgColor);
516           }
517           else {
518             dc->setBackground(col);
519             dc->setForeground(col);
520           }
521           dc->fillRectangle(printX, printY, ximg->getWidth(), ximg->getHeight());
522 
523           dc->drawImage(ximg, printX, printY);
524         }
525       }
526       break;
527     }
528     default:
529       break;
530     }
531 
532 
533     c=HtmlObject_Tree_GetFirstChild(o);
534     while(c) {
535       _paintAt(dc, c, xOffset, yOffset, x, y, w, h);
536       c=HtmlObject_Tree_GetNext(c);
537     }
538   }
539 }
540 
541 
542 
paint(FXDC * dc,int xOffset,int yOffset)543 void FOX16_HtmlCtx::paint(FXDC *dc, int xOffset, int yOffset) {
544   HTML_OBJECT *o;
545 
546   o=HtmlCtx_GetRootObject(_context);
547   if (o)
548     _paint(dc, o, xOffset, yOffset);
549 }
550 
551 
552 
paintAt(FXDC * dc,int xOffset,int yOffset,int xText,int yText,int w,int h)553 void FOX16_HtmlCtx::paintAt(FXDC *dc,
554                             int xOffset, int yOffset,
555                             int xText, int yText,
556                             int w, int h) {
557   HTML_OBJECT *o;
558 
559   o=HtmlCtx_GetRootObject(_context);
560   if (o)
561     _paintAt(dc, o, xOffset, yOffset, xText, yText, w, h);
562 }
563 
564 
565 
getWidth()566 int FOX16_HtmlCtx::getWidth() {
567   HTML_OBJECT *o;
568 
569   o=HtmlCtx_GetRootObject(_context);
570   if (o)
571     return HtmlObject_GetWidth(o);
572   else
573     return -1;
574 }
575 
576 
577 
getHeight()578 int FOX16_HtmlCtx::getHeight() {
579   HTML_OBJECT *o;
580 
581   o=HtmlCtx_GetRootObject(_context);
582   if (o)
583     return HtmlObject_GetHeight(o);
584   else
585     return -1;
586 }
587 
588 
589 
getFont(const char * fontName,int fontSize,uint32_t fontFlags)590 HTML_FONT *FOX16_HtmlCtx::getFont(const char *fontName,
591                                   int fontSize,
592                                   uint32_t fontFlags) {
593   FOX16_Gui *gui;
594 
595   gui=FOX16_Gui::getFgGui();
596   assert(gui);
597 
598   return gui->getFont(fontName, fontSize, fontFlags);
599 }
600 
601 
602 
getImage(const char * fileName)603 HTML_IMAGE *FOX16_HtmlCtx::getImage(const char *fileName) {
604   GWEN_STRINGLIST *sl;
605 
606   sl=HtmlCtx_GetMediaPaths(_context);
607   if (sl) {
608     GWEN_BUFFER *tbuf;
609     int rv;
610     FXImage *ximg;
611     HTML_IMAGE *img;
612 
613     tbuf=GWEN_Buffer_new(0, 256, 0, 1);
614     rv=GWEN_Directory_FindFileInPaths(sl, fileName, tbuf);
615     if (rv<0) {
616       DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
617       GWEN_Buffer_free(tbuf);
618       return NULL;
619     }
620 
621     if (m_iconSource==NULL)
622       m_iconSource=new FXIconSource(FXApp::instance());
623 
624     ximg=m_iconSource->loadIconFile(GWEN_Buffer_GetStart(tbuf));
625     if (ximg==NULL) {
626       DBG_ERROR(GWEN_LOGDOMAIN, "Could not load icon [%s]", GWEN_Buffer_GetStart(tbuf));
627       GWEN_Buffer_free(tbuf);
628       return NULL;
629     }
630 
631     ximg->create();
632     img=HtmlImage_new();
633     HtmlImage_SetImageName(img, GWEN_Buffer_GetStart(tbuf));
634     HtmlImage_SetWidth(img, ximg->getWidth());
635     HtmlImage_SetHeight(img, ximg->getHeight());
636 
637     GWEN_INHERIT_SETDATA(HTML_IMAGE, FXImage, img, ximg,
638                          FOX16_HtmlCtxLinker::freeImageData);
639     GWEN_Buffer_free(tbuf);
640     return img;
641   }
642   else {
643     DBG_ERROR(GWEN_LOGDOMAIN, "No media paths in dialog");
644     return NULL;
645   }
646 }
647 
648 
649 
650 
setBackgroundColor(FXColor c)651 void FOX16_HtmlCtx::setBackgroundColor(FXColor c) {
652   _bgColor=c;
653 }
654 
655 
656 
setForegroundColor(FXColor c)657 void FOX16_HtmlCtx::setForegroundColor(FXColor c) {
658   _fgColor=c;
659 }
660 
661 
662 
663 
664 
665 
666 
667 
668