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