gwenhywfar 4.0.3
|
00001 /*************************************************************************** 00002 begin : Mon Feb 22 2010 00003 copyright : (C) 2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * Please see toplevel file COPYING for license details * 00008 ***************************************************************************/ 00009 00010 #ifdef HAVE_CONFIG_H 00011 # include <config.h> 00012 #endif 00013 00014 #include "fox16_htmlctx_p.hpp" 00015 #include "fox16_gui.hpp" 00016 00017 #include <assert.h> 00018 00019 #include <gwenhywfar/inherit.h> 00020 #include <gwenhywfar/debug.h> 00021 #include <gwenhywfar/gui_be.h> 00022 #include <gwenhywfar/i18n.h> 00023 #include <gwenhywfar/htmlctx_be.h> 00024 #include <gwenhywfar/o_image_be.h> 00025 #include <gwenhywfar/text.h> 00026 #include <gwenhywfar/debug.h> 00027 #include <gwenhywfar/syncio_memory.h> 00028 #include <gwenhywfar/directory.h> 00029 00030 00031 00032 GWEN_INHERIT(GWEN_XML_CONTEXT, FOX16_HtmlCtx) 00033 GWEN_INHERIT(HTML_FONT, FXFont) 00034 GWEN_INHERIT(HTML_IMAGE, FXImage) 00035 00036 00037 00038 int FOX16_HtmlCtxLinker::GetTextWidth(GWEN_XML_CONTEXT *ctx, 00039 HTML_FONT *fnt, 00040 const char *s) { 00041 FOX16_HtmlCtx *xctx; 00042 00043 assert(ctx); 00044 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx); 00045 assert(xctx); 00046 00047 return xctx->getTextWidth(fnt, s); 00048 } 00049 00050 00051 00052 int FOX16_HtmlCtxLinker::GetTextHeight(GWEN_XML_CONTEXT *ctx, 00053 HTML_FONT *fnt, 00054 const char *s) { 00055 FOX16_HtmlCtx *xctx; 00056 00057 assert(ctx); 00058 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx); 00059 assert(xctx); 00060 00061 return xctx->getTextHeight(fnt, s); 00062 } 00063 00064 00065 00066 uint32_t FOX16_HtmlCtxLinker::GetColorFromName(const GWEN_XML_CONTEXT *ctx, 00067 const char *name) { 00068 FOX16_HtmlCtx *xctx; 00069 00070 assert(ctx); 00071 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx); 00072 assert(xctx); 00073 00074 return xctx->getColorFromName(name); 00075 } 00076 00077 00078 00079 HTML_FONT *FOX16_HtmlCtxLinker::GetFont(GWEN_XML_CONTEXT *ctx, 00080 const char *fontName, 00081 int fontSize, 00082 uint32_t fontFlags) { 00083 FOX16_HtmlCtx *xctx; 00084 00085 assert(ctx); 00086 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx); 00087 assert(xctx); 00088 00089 return xctx->getFont(fontName, fontSize, fontFlags); 00090 } 00091 00092 00093 00094 HTML_IMAGE *FOX16_HtmlCtxLinker::GetImage(GWEN_XML_CONTEXT *ctx, 00095 const char *imageName) { 00096 FOX16_HtmlCtx *xctx; 00097 00098 assert(ctx); 00099 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, ctx); 00100 assert(xctx); 00101 00102 return xctx->getImage(imageName); 00103 00104 } 00105 00106 00107 00108 void FOX16_HtmlCtxLinker::freeData(void *bp, void *p) { 00109 FOX16_HtmlCtx *xctx; 00110 00111 xctx=(FOX16_HtmlCtx*) p; 00112 if (xctx->_context) 00113 xctx->_context=NULL; 00114 delete xctx; 00115 } 00116 00117 00118 00119 void FOX16_HtmlCtxLinker::freeFontData(void *bp, void *p) { 00120 FXFont *xfnt; 00121 00122 xfnt=(FXFont*) p; 00123 delete xfnt; 00124 } 00125 00126 00127 00128 00129 void FOX16_HtmlCtxLinker::freeImageData(void *bp, void *p) { 00130 FXImage *ximg; 00131 00132 ximg=(FXImage*) p; 00133 delete ximg; 00134 } 00135 00136 00137 00138 00139 00140 FOX16_HtmlCtx::FOX16_HtmlCtx(uint32_t flags) 00141 :_context(NULL) 00142 ,_font(NULL) 00143 ,_fgColor(0) 00144 ,_bgColor(0) 00145 ,m_iconSource(NULL) 00146 { 00147 HTML_PROPS *pr; 00148 HTML_FONT *fnt; 00149 00150 _context=HtmlCtx_new(flags); 00151 GWEN_INHERIT_SETDATA(GWEN_XML_CONTEXT, FOX16_HtmlCtx, _context, this, 00152 FOX16_HtmlCtxLinker::freeData); 00153 _font=FXApp::instance()->getNormalFont(); 00154 HtmlCtx_SetGetTextWidthFn(_context, FOX16_HtmlCtxLinker::GetTextWidth); 00155 HtmlCtx_SetGetTextHeightFn(_context, FOX16_HtmlCtxLinker::GetTextHeight); 00156 HtmlCtx_SetGetColorFromNameFn(_context, FOX16_HtmlCtxLinker::GetColorFromName); 00157 HtmlCtx_SetGetFontFn(_context, FOX16_HtmlCtxLinker::GetFont); 00158 HtmlCtx_SetGetImageFn(_context, FOX16_HtmlCtxLinker::GetImage); 00159 00160 pr=HtmlProps_new(); 00161 fnt=HtmlCtx_GetFont(_context, _font->getName().text(), _font->getSize()/10, 0); 00162 HtmlProps_SetFont(pr, fnt); 00163 HtmlCtx_SetStandardProps(_context, pr); 00164 HtmlProps_free(pr); 00165 00166 } 00167 00168 00169 00170 FOX16_HtmlCtx::~FOX16_HtmlCtx() { 00171 if (_context) { 00172 GWEN_INHERIT_UNLINK(GWEN_XML_CONTEXT, FOX16_HtmlCtx, _context); 00173 GWEN_XmlCtx_free(_context); 00174 } 00175 } 00176 00177 00178 00179 FXFont *FOX16_HtmlCtx::_getFoxFont(HTML_FONT *fnt) { 00180 FXFont *xfnt; 00181 00182 if (GWEN_INHERIT_ISOFTYPE(HTML_FONT, FXFont, fnt)) { 00183 xfnt=GWEN_INHERIT_GETDATA(HTML_FONT, FXFont, fnt); 00184 return xfnt; 00185 } 00186 else { 00187 FXuint size; 00188 FXuint weight; 00189 FXuint slant; 00190 FXuint encoding; 00191 FXString face; 00192 uint32_t flags; 00193 00194 if (HtmlFont_GetFontName(fnt)) 00195 face=HtmlFont_GetFontName(fnt); 00196 else 00197 face=_font->getName(); 00198 size=HtmlFont_GetFontSize(fnt); 00199 weight=FXFont::Normal; 00200 slant=_font->getSlant(); 00201 encoding=_font->getEncoding(); 00202 00203 flags=HtmlFont_GetFontFlags(fnt); 00204 if (flags & HTML_FONT_FLAGS_STRONG) 00205 weight=FXFont::Bold; 00206 if (flags & HTML_FONT_FLAGS_ITALIC) 00207 slant=FXFont::Italic; 00208 00209 DBG_DEBUG(GWEN_LOGDOMAIN, 00210 "Creating font [%s], size=%d, weight=%d, slant=%d, encoding=%d", 00211 face.text(), size, weight, slant, encoding); 00212 00213 xfnt=new FXFont(FXApp::instance(), face, size, weight, slant, encoding); 00214 if (xfnt==NULL) { 00215 DBG_ERROR(GWEN_LOGDOMAIN, 00216 "Could not create font [%s], size=%d, weight=%d, slant=%d, encoding=%d", 00217 face.text(), size, weight, slant, encoding); 00218 return NULL; 00219 } 00220 xfnt->create(); 00221 GWEN_INHERIT_SETDATA(HTML_FONT, FXFont, fnt, xfnt, 00222 FOX16_HtmlCtxLinker::freeFontData); 00223 return xfnt; 00224 } 00225 } 00226 00227 00228 00229 int FOX16_HtmlCtx::getTextWidth(HTML_FONT *fnt, const char *s) { 00230 if (s==NULL) { 00231 DBG_ERROR(GWEN_LOGDOMAIN, "NULLPOINTER, returning size 0"); 00232 return 0; 00233 } 00234 else { 00235 FXFont *xfnt; 00236 FXString str; 00237 00238 str=FXString(s); 00239 xfnt=_getFoxFont(fnt); 00240 if (xfnt==NULL) 00241 return _font->getTextWidth(str); 00242 else 00243 return xfnt->getTextWidth(str); 00244 } 00245 } 00246 00247 00248 00249 int FOX16_HtmlCtx::getTextHeight(HTML_FONT *fnt, const char *s) { 00250 if (s==NULL) { 00251 DBG_ERROR(GWEN_LOGDOMAIN, "NULLPOINTER, returning size 0"); 00252 return 0; 00253 } 00254 else { 00255 FXFont *xfnt; 00256 FXString str; 00257 00258 str=FXString(s); 00259 xfnt=_getFoxFont(fnt); 00260 if (xfnt==NULL) 00261 return _font->getTextHeight(str); 00262 else 00263 return xfnt->getTextHeight(str); 00264 } 00265 } 00266 00267 00268 00269 uint32_t FOX16_HtmlCtx::getColorFromName(const char *name) { 00270 return fxcolorfromname(name); 00271 } 00272 00273 00274 00275 int FOX16_HtmlCtx::layout(int width, int height) { 00276 return HtmlCtx_Layout(_context, width, height); 00277 } 00278 00279 00280 00281 void FOX16_HtmlCtx::setText(const char *s) { 00282 int rv; 00283 00284 rv=GWEN_XMLContext_ReadFromString(_context, s); 00285 if (rv<0) { 00286 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00287 } 00288 } 00289 00290 00291 00292 void FOX16_HtmlCtx::addMediaPath(const char *s) { 00293 HtmlCtx_AddMediaPath(_context, s); 00294 } 00295 00296 00297 00298 static void dumpObject(HTML_OBJECT *o, FILE *f, int indent) { 00299 HTML_OBJECT *c; 00300 int i; 00301 const char *s; 00302 HTML_PROPS *pr; 00303 HTML_FONT *fnt; 00304 00305 s=HtmlObject_GetText(o); 00306 for (i=0; i<indent; i++) fprintf(f, " "); 00307 fprintf(stderr, "Object type: %d [%s] flags: %08x, x=%d, y=%d, w=%d, h=%d\n", 00308 HtmlObject_GetObjectType(o), 00309 s?s:"(empty)", 00310 HtmlObject_GetFlags(o), 00311 HtmlObject_GetX(o), 00312 HtmlObject_GetY(o), 00313 HtmlObject_GetWidth(o), 00314 HtmlObject_GetHeight(o)); 00315 00316 pr=HtmlObject_GetProperties(o); 00317 fnt=HtmlProps_GetFont(pr); 00318 00319 for (i=0; i<indent+2; i++) fprintf(f, " "); 00320 fprintf(stderr, "fgcol=%06x, bgcol=%06x, fontsize=%d, fontflags=%08x, fontname=[%s]\n", 00321 HtmlProps_GetForegroundColor(pr), 00322 HtmlProps_GetBackgroundColor(pr), 00323 HtmlFont_GetFontSize(fnt), 00324 HtmlFont_GetFontFlags(fnt), 00325 HtmlFont_GetFontName(fnt)); 00326 00327 c=HtmlObject_Tree_GetFirstChild(o); 00328 while(c) { 00329 dumpObject(c, f, indent+2); 00330 c=HtmlObject_Tree_GetNext(c); 00331 } 00332 } 00333 00334 00335 00336 void FOX16_HtmlCtx::dump() { 00337 HTML_OBJECT *o; 00338 00339 o=HtmlCtx_GetRootObject(_context); 00340 if (o) 00341 dumpObject(o, stderr, 2); 00342 } 00343 00344 00345 00346 void FOX16_HtmlCtx::_paint(FXDC *dc, HTML_OBJECT *o, int xOffset, int yOffset) { 00347 HTML_OBJECT *c; 00348 00349 xOffset+=HtmlObject_GetX(o); 00350 yOffset+=HtmlObject_GetY(o); 00351 00352 switch(HtmlObject_GetObjectType(o)) { 00353 case HtmlObjectType_Word: { 00354 HTML_PROPS *pr; 00355 HTML_FONT *fnt; 00356 FXFont *xfnt; 00357 int ascent=0; 00358 uint32_t col; 00359 00360 pr=HtmlObject_GetProperties(o); 00361 00362 /* select font */ 00363 fnt=HtmlProps_GetFont(pr); 00364 xfnt=_getFoxFont(fnt); 00365 if (xfnt) { 00366 dc->setFont(xfnt); 00367 ascent=xfnt->getFontAscent(); 00368 } 00369 00370 /* select foreground color */ 00371 col=HtmlProps_GetForegroundColor(pr); 00372 if (col==HTML_PROPS_NOCOLOR) 00373 dc->setForeground(_fgColor); 00374 else 00375 dc->setForeground(col); 00376 00377 /* select background color */ 00378 col=HtmlProps_GetBackgroundColor(pr); 00379 if (col==HTML_PROPS_NOCOLOR) 00380 dc->setBackground(_bgColor); 00381 else 00382 dc->setBackground(col); 00383 00384 dc->drawText(xOffset, yOffset+ascent, HtmlObject_GetText(o)); 00385 break; 00386 } 00387 00388 case HtmlObjectType_Image: { 00389 HTML_IMAGE *img; 00390 00391 img=HtmlObject_Image_GetImage(o); 00392 if (img) { 00393 FXImage *ximg; 00394 00395 ximg=GWEN_INHERIT_GETDATA(HTML_IMAGE, FXImage, img); 00396 if (ximg) { 00397 HTML_PROPS *pr; 00398 uint32_t col; 00399 00400 pr=HtmlObject_GetProperties(o); 00401 00402 /* select background color */ 00403 col=HtmlProps_GetBackgroundColor(pr); 00404 if (col==HTML_PROPS_NOCOLOR) { 00405 dc->setBackground(_bgColor); 00406 dc->setForeground(_bgColor); 00407 } 00408 else { 00409 dc->setBackground(col); 00410 dc->setForeground(col); 00411 } 00412 00413 dc->fillRectangle(xOffset, yOffset, ximg->getWidth(), ximg->getHeight()); 00414 00415 dc->drawImage(ximg, xOffset, yOffset); 00416 } 00417 } 00418 break; 00419 } 00420 default: 00421 break; 00422 } 00423 00424 c=HtmlObject_Tree_GetFirstChild(o); 00425 while(c) { 00426 _paint(dc, c, xOffset, yOffset); 00427 c=HtmlObject_Tree_GetNext(c); 00428 } 00429 } 00430 00431 00432 00433 void FOX16_HtmlCtx::_paintAt(FXDC *dc, HTML_OBJECT *o, 00434 int xOffset, int yOffset, 00435 int xText, int yText, 00436 int w, int h) { 00437 HTML_OBJECT *c; 00438 int x; 00439 int y; 00440 int printX; 00441 int printY; 00442 int objectW; 00443 int objectH; 00444 00445 x=xText+HtmlObject_GetX(o); 00446 y=yText+HtmlObject_GetY(o); 00447 objectW=HtmlObject_GetWidth(o); 00448 objectH=HtmlObject_GetHeight(o); 00449 00450 printX=x-xOffset; 00451 printY=y-yOffset; 00452 00453 if (printX<w && printX+objectW>=0 && 00454 printY<h && printY+objectH>=0) { 00455 switch(HtmlObject_GetObjectType(o)) { 00456 #if 0 00457 case HtmlObjectType_Grid: 00458 dc->setForeground(FXRGB(255,0,0)); 00459 dc->fillRectangle(printX, printY, 00460 HtmlObject_GetWidth(o), 00461 HtmlObject_GetHeight(o)); 00462 #endif 00463 case HtmlObjectType_Word: { 00464 HTML_PROPS *pr; 00465 HTML_FONT *fnt; 00466 FXFont *xfnt; 00467 int ascent=0; 00468 uint32_t col; 00469 00470 pr=HtmlObject_GetProperties(o); 00471 00472 /* select font */ 00473 fnt=HtmlProps_GetFont(pr); 00474 xfnt=_getFoxFont(fnt); 00475 if (xfnt) { 00476 dc->setFont(xfnt); 00477 ascent=xfnt->getFontAscent(); 00478 } 00479 00480 /* select foreground color */ 00481 col=HtmlProps_GetForegroundColor(pr); 00482 if (col==HTML_PROPS_NOCOLOR) 00483 dc->setForeground(_fgColor); 00484 else 00485 dc->setForeground(col); 00486 00487 /* select background color */ 00488 col=HtmlProps_GetBackgroundColor(pr); 00489 if (col==HTML_PROPS_NOCOLOR) 00490 dc->setBackground(_bgColor); 00491 else 00492 dc->setBackground(col); 00493 00494 dc->drawText(printX, printY+ascent, HtmlObject_GetText(o)); 00495 break; 00496 } 00497 00498 case HtmlObjectType_Image: { 00499 HTML_IMAGE *img; 00500 00501 img=HtmlObject_Image_GetImage(o); 00502 if (img) { 00503 FXImage *ximg; 00504 00505 ximg=GWEN_INHERIT_GETDATA(HTML_IMAGE, FXImage, img); 00506 if (ximg) { 00507 HTML_PROPS *pr; 00508 uint32_t col; 00509 00510 pr=HtmlObject_GetProperties(o); 00511 00512 /* select background color */ 00513 col=HtmlProps_GetBackgroundColor(pr); 00514 if (col==HTML_PROPS_NOCOLOR) { 00515 dc->setBackground(_bgColor); 00516 dc->setForeground(_bgColor); 00517 } 00518 else { 00519 dc->setBackground(col); 00520 dc->setForeground(col); 00521 } 00522 dc->fillRectangle(printX, printY, ximg->getWidth(), ximg->getHeight()); 00523 00524 dc->drawImage(ximg, printX, printY); 00525 } 00526 } 00527 break; 00528 } 00529 default: 00530 break; 00531 } 00532 00533 00534 c=HtmlObject_Tree_GetFirstChild(o); 00535 while(c) { 00536 _paintAt(dc, c, xOffset, yOffset, x, y, w, h); 00537 c=HtmlObject_Tree_GetNext(c); 00538 } 00539 } 00540 } 00541 00542 00543 00544 void FOX16_HtmlCtx::paint(FXDC *dc, int xOffset, int yOffset) { 00545 HTML_OBJECT *o; 00546 00547 o=HtmlCtx_GetRootObject(_context); 00548 if (o) 00549 _paint(dc, o, xOffset, yOffset); 00550 } 00551 00552 00553 00554 void FOX16_HtmlCtx::paintAt(FXDC *dc, 00555 int xOffset, int yOffset, 00556 int xText, int yText, 00557 int w, int h) { 00558 HTML_OBJECT *o; 00559 00560 o=HtmlCtx_GetRootObject(_context); 00561 if (o) 00562 _paintAt(dc, o, xOffset, yOffset, xText, yText, w, h); 00563 } 00564 00565 00566 00567 int FOX16_HtmlCtx::getWidth() { 00568 HTML_OBJECT *o; 00569 00570 o=HtmlCtx_GetRootObject(_context); 00571 if (o) 00572 return HtmlObject_GetWidth(o); 00573 else 00574 return -1; 00575 } 00576 00577 00578 00579 int FOX16_HtmlCtx::getHeight() { 00580 HTML_OBJECT *o; 00581 00582 o=HtmlCtx_GetRootObject(_context); 00583 if (o) 00584 return HtmlObject_GetHeight(o); 00585 else 00586 return -1; 00587 } 00588 00589 00590 00591 HTML_FONT *FOX16_HtmlCtx::getFont(const char *fontName, 00592 int fontSize, 00593 uint32_t fontFlags) { 00594 FOX16_Gui *gui; 00595 00596 gui=FOX16_Gui::getFgGui(); 00597 assert(gui); 00598 00599 return gui->getFont(fontName, fontSize, fontFlags); 00600 } 00601 00602 00603 00604 HTML_IMAGE *FOX16_HtmlCtx::getImage(const char *fileName) { 00605 GWEN_STRINGLIST *sl; 00606 00607 sl=HtmlCtx_GetMediaPaths(_context); 00608 if (sl) { 00609 GWEN_BUFFER *tbuf; 00610 int rv; 00611 FXImage *ximg; 00612 HTML_IMAGE *img; 00613 00614 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00615 rv=GWEN_Directory_FindFileInPaths(sl, fileName, tbuf); 00616 if (rv<0) { 00617 DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv); 00618 GWEN_Buffer_free(tbuf); 00619 return NULL; 00620 } 00621 00622 if (m_iconSource==NULL) 00623 m_iconSource=new FXIconSource(FXApp::instance()); 00624 00625 ximg=m_iconSource->loadIconFile(GWEN_Buffer_GetStart(tbuf)); 00626 if (ximg==NULL) { 00627 DBG_ERROR(GWEN_LOGDOMAIN, "Could not load icon [%s]", GWEN_Buffer_GetStart(tbuf)); 00628 GWEN_Buffer_free(tbuf); 00629 return NULL; 00630 } 00631 00632 ximg->create(); 00633 img=HtmlImage_new(); 00634 HtmlImage_SetImageName(img, GWEN_Buffer_GetStart(tbuf)); 00635 HtmlImage_SetWidth(img, ximg->getWidth()); 00636 HtmlImage_SetHeight(img, ximg->getHeight()); 00637 00638 GWEN_INHERIT_SETDATA(HTML_IMAGE, FXImage, img, ximg, 00639 FOX16_HtmlCtxLinker::freeImageData); 00640 GWEN_Buffer_free(tbuf); 00641 return img; 00642 } 00643 else { 00644 DBG_ERROR(GWEN_LOGDOMAIN, "No media paths in dialog"); 00645 return NULL; 00646 } 00647 } 00648 00649 00650 00651 00652 void FOX16_HtmlCtx::setBackgroundColor(FXColor c) { 00653 _bgColor=c; 00654 } 00655 00656 00657 00658 void FOX16_HtmlCtx::setForegroundColor(FXColor c) { 00659 _fgColor=c; 00660 } 00661 00662 00663 00664 00665 00666 00667 00668