htmlctx.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  begin       : Sat Feb 20 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 
00011 
00012 #ifdef HAVE_CONFIG_H
00013 # include <config.h>
00014 #endif
00015 
00016 #define DISABLE_DEBUGLOG
00017 
00018 
00019 #include "htmlctx_p.h"
00020 #include "o_box_l.h"
00021 #include "g_box_l.h"
00022 
00023 #include <gwenhywfar/misc.h>
00024 #include <gwenhywfar/debug.h>
00025 #include <gwenhywfar/text.h>
00026 
00027 
00028 
00029 GWEN_INHERIT(GWEN_XML_CONTEXT, HTML_XMLCTX)
00030 
00031 
00032 
00033 
00034 GWEN_XML_CONTEXT *HtmlCtx_new(uint32_t flags) {
00035   GWEN_XML_CONTEXT *ctx;
00036   HTML_XMLCTX *xctx;
00037   HTML_GROUP *g;
00038   HTML_OBJECT *o;
00039 
00040   /* create base object */
00041   ctx=GWEN_XmlCtx_new(flags);
00042   assert(ctx);
00043 
00044   /* create and assign extension */
00045   GWEN_NEW_OBJECT(HTML_XMLCTX, xctx);
00046   assert(xctx);
00047   GWEN_INHERIT_SETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx, xctx,
00048                        HtmlCtx_FreeData);
00049 
00050   /* set virtual functions */
00051   GWEN_XmlCtx_SetStartTagFn(ctx, HtmlCtx_StartTag);
00052   GWEN_XmlCtx_SetEndTagFn(ctx, HtmlCtx_EndTag);
00053   GWEN_XmlCtx_SetAddDataFn(ctx, HtmlCtx_AddData);
00054   GWEN_XmlCtx_SetAddCommentFn(ctx, HtmlCtx_AddComment);
00055   GWEN_XmlCtx_SetAddAttrFn(ctx, HtmlCtx_AddAttr);
00056 
00057   xctx->objects=HtmlObject_Tree_new();
00058   xctx->mediaPaths=GWEN_StringList_new();
00059 
00060   xctx->resolutionX=75;
00061   xctx->resolutionY=75;
00062 
00063   /* create initial group */
00064   g=HtmlGroup_Box_new("HTML_ROOT", NULL, ctx);
00065   assert(g);
00066   o=HtmlObject_Box_new(ctx);
00067   HtmlGroup_SetObject(g, o);
00068   HtmlObject_Tree_Add(xctx->objects, o);
00069   HtmlCtx_SetCurrentGroup(ctx, g);
00070 
00071   /* return base object */
00072   return ctx;
00073 }
00074 
00075 
00076 
00077 GWENHYWFAR_CB
00078 void HtmlCtx_FreeData(void *bp, void *p) {
00079   HTML_XMLCTX *xctx;
00080   HTML_GROUP *g;
00081 
00082   xctx=(HTML_XMLCTX*)p;
00083 
00084   g=xctx->currentGroup;
00085   while (g) {
00086     HTML_GROUP *gParent;
00087 
00088     gParent=HtmlGroup_GetParent(g);
00089     HtmlGroup_free(g);
00090     g=gParent;
00091   }
00092 
00093   GWEN_DB_Group_free(xctx->dbCurrentAttribs);
00094   free(xctx->currentTagName);
00095   HtmlObject_Tree_free(xctx->objects);
00096 
00097   GWEN_StringList_free(xctx->mediaPaths);
00098 
00099   HtmlProps_free(xctx->standardProps);
00100 
00101   GWEN_FREE_OBJECT(xctx);
00102 }
00103 
00104 
00105 
00106 int HtmlCtx_GetResolutionX(const GWEN_XML_CONTEXT *ctx) {
00107   HTML_XMLCTX *xctx;
00108 
00109   assert(ctx);
00110   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00111   assert(xctx);
00112 
00113   return xctx->resolutionX;
00114 }
00115 
00116 
00117 
00118 void HtmlCtx_SetResolutionX(GWEN_XML_CONTEXT *ctx, int i) {
00119   HTML_XMLCTX *xctx;
00120 
00121   assert(ctx);
00122   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00123   assert(xctx);
00124 
00125   xctx->resolutionX=i;
00126 }
00127 
00128 
00129 
00130 int HtmlCtx_GetResolutionY(const GWEN_XML_CONTEXT *ctx) {
00131   HTML_XMLCTX *xctx;
00132 
00133   assert(ctx);
00134   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00135   assert(xctx);
00136 
00137   return xctx->resolutionY;
00138 }
00139 
00140 
00141 
00142 void HtmlCtx_SetResolutionY(GWEN_XML_CONTEXT *ctx, int i) {
00143   HTML_XMLCTX *xctx;
00144 
00145   assert(ctx);
00146   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00147   assert(xctx);
00148 
00149   xctx->resolutionY=i;
00150 }
00151 
00152 
00153 
00154 GWEN_STRINGLIST *HtmlCtx_GetMediaPaths(const GWEN_XML_CONTEXT *ctx) {
00155   HTML_XMLCTX *xctx;
00156 
00157   assert(ctx);
00158   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00159   assert(xctx);
00160 
00161   return xctx->mediaPaths;
00162 }
00163 
00164 
00165 
00166 void HtmlCtx_AddMediaPath(GWEN_XML_CONTEXT *ctx, const char *s) {
00167   HTML_XMLCTX *xctx;
00168 
00169   assert(ctx);
00170   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00171   assert(xctx);
00172 
00173   assert(s && *s);
00174   GWEN_StringList_AppendString(xctx->mediaPaths, s, 0, 1);
00175 }
00176 
00177 
00178 
00179 
00180 HTML_GROUP *HtmlCtx_GetCurrentGroup(const GWEN_XML_CONTEXT *ctx) {
00181   HTML_XMLCTX *xctx;
00182 
00183   assert(ctx);
00184   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00185   assert(xctx);
00186 
00187   return xctx->currentGroup;
00188 }
00189 
00190 
00191 
00192 void HtmlCtx_SetCurrentGroup(GWEN_XML_CONTEXT *ctx, HTML_GROUP *g){
00193   HTML_XMLCTX *xctx;
00194 
00195   assert(ctx);
00196   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00197   assert(xctx);
00198 
00199   xctx->currentGroup=g;
00200 }
00201 
00202 
00203 
00204 const char *HtmlCtx_GetCurrentTagName(const GWEN_XML_CONTEXT *ctx) {
00205   HTML_XMLCTX *xctx;
00206 
00207   assert(ctx);
00208   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00209   assert(xctx);
00210 
00211   return xctx->currentTagName;
00212 }
00213 
00214 
00215 
00216 void HtmlCtx_SetCurrentTagName(GWEN_XML_CONTEXT *ctx, const char *s) {
00217   HTML_XMLCTX *xctx;
00218 
00219   assert(ctx);
00220   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00221   assert(xctx);
00222 
00223   free(xctx->currentTagName);
00224   if (s) xctx->currentTagName=strdup(s);
00225   else xctx->currentTagName=NULL;
00226 }
00227 
00228 
00229 
00230 GWEN_DB_NODE *HtmlCtx_GetCurrentAttributes(const GWEN_XML_CONTEXT *ctx) {
00231   HTML_XMLCTX *xctx;
00232 
00233   assert(ctx);
00234   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00235   assert(xctx);
00236 
00237   return xctx->dbCurrentAttribs;
00238 }
00239 
00240 
00241 
00242 HTML_OBJECT_TREE *HtmlCtx_GetObjects(const GWEN_XML_CONTEXT *ctx) {
00243   HTML_XMLCTX *xctx;
00244 
00245   assert(ctx);
00246   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00247   assert(xctx);
00248 
00249   return xctx->objects;
00250 }
00251 
00252 
00253 
00254 HTML_OBJECT_TREE *HtmlCtx_TakeObjects(const GWEN_XML_CONTEXT *ctx) {
00255   HTML_XMLCTX *xctx;
00256   HTML_OBJECT_TREE *t;
00257 
00258   assert(ctx);
00259   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00260   assert(xctx);
00261 
00262   t=xctx->objects;
00263   xctx->objects=NULL;
00264 
00265   return t;
00266 }
00267 
00268 
00269 
00270 HTML_OBJECT *HtmlCtx_GetRootObject(const GWEN_XML_CONTEXT *ctx) {
00271   HTML_XMLCTX *xctx;
00272 
00273   assert(ctx);
00274   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00275   assert(xctx);
00276 
00277   return HtmlObject_Tree_GetFirst(xctx->objects);
00278 }
00279 
00280 
00281 
00282 int HtmlCtx_SanitizeData(GWEN_XML_CONTEXT *ctx,
00283                          const char *data,
00284                          GWEN_BUFFER *buf) {
00285   if (data && *data) {
00286     const uint8_t *p;
00287     uint8_t *dst;
00288     uint8_t *src;
00289     unsigned int size;
00290     unsigned int i;
00291     int lastWasBlank;
00292     uint8_t *lastBlankPos;
00293     uint32_t bStart=0;
00294   
00295     if (GWEN_Text_UnescapeXmlToBuffer(data, buf)) {
00296       DBG_INFO(GWEN_LOGDOMAIN, "here");
00297       return GWEN_ERROR_BAD_DATA;
00298     }
00299     if (GWEN_Buffer_GetUsedBytes(buf)==0) {
00300       DBG_INFO(GWEN_LOGDOMAIN, "Empty data.");
00301       return 0;
00302     }
00303   
00304     dst=(uint8_t*)GWEN_Buffer_GetStart(buf);
00305     src=dst;
00306   
00307     /* skip leading blanks */
00308     while(*src && (*src<33 || *src==127))
00309       src++;
00310   
00311     p=src;
00312     bStart=src-((uint8_t*)GWEN_Buffer_GetStart(buf));
00313     size=GWEN_Buffer_GetUsedBytes(buf)-bStart;
00314     lastWasBlank=0;
00315     lastBlankPos=0;
00316   
00317     for (i=0; i<size; i++) {
00318       uint8_t c;
00319   
00320       c=*p;
00321       if (c<32 || c==127)
00322         c=32;
00323   
00324       /* remember next loop whether this char was a blank */
00325       if (c==32) {
00326         if (!lastWasBlank) {
00327           /* store only one blank */
00328           lastWasBlank=1;
00329           lastBlankPos=dst;
00330           *(dst++)=c;
00331         }
00332       }
00333       else {
00334         lastWasBlank=0;
00335         lastBlankPos=0;
00336         *(dst++)=c;
00337       }
00338       p++;
00339     }
00340   
00341     /* remove trailing blanks */
00342     if (lastBlankPos!=0)
00343       dst=lastBlankPos;
00344   
00345     size=dst-(uint8_t*)GWEN_Buffer_GetStart(buf);
00346     GWEN_Buffer_Crop(buf, 0, size);
00347   }
00348 
00349   return 0;
00350 }
00351 
00352 
00353 
00354 HTML_PROPS *HtmlCtx_GetStandardProps(const GWEN_XML_CONTEXT *ctx) {
00355   HTML_XMLCTX *xctx;
00356 
00357   assert(ctx);
00358   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00359   assert(xctx);
00360 
00361   return xctx->standardProps;
00362 }
00363 
00364 
00365 
00366 void HtmlCtx_SetStandardProps(GWEN_XML_CONTEXT *ctx, HTML_PROPS *pr) {
00367   HTML_XMLCTX *xctx;
00368   HTML_OBJECT *o;
00369 
00370   assert(ctx);
00371   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00372   assert(xctx);
00373 
00374   HtmlProps_Attach(pr);
00375   HtmlProps_free(xctx->standardProps);
00376   xctx->standardProps=pr;
00377 
00378   if (pr) {
00379     if (xctx->currentGroup && HtmlGroup_GetParent(xctx->currentGroup)==NULL)
00380       HtmlGroup_SetProperties(xctx->currentGroup, pr);
00381     o=HtmlObject_Tree_GetFirst(xctx->objects);
00382     if (o && HtmlObject_GetProperties(o)==NULL)
00383       HtmlObject_SetProperties(o, pr);
00384   }
00385 }
00386 
00387 
00388 
00389 int HtmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName) {
00390   HTML_XMLCTX *xctx;
00391 
00392   assert(ctx);
00393   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00394   assert(xctx);
00395 
00396   DBG_DEBUG(GWEN_LOGDOMAIN, "Starting tag [%s]", tagName);
00397 
00398   /* store for later, do nothing more here */
00399   HtmlCtx_SetCurrentTagName(ctx, tagName);
00400   GWEN_DB_Group_free(xctx->dbCurrentAttribs);
00401   xctx->dbCurrentAttribs=GWEN_DB_Group_new("attribs");
00402 
00403   return 0;
00404 }
00405 
00406 
00407 
00408 int HtmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing) {
00409   HTML_XMLCTX *xctx;
00410 
00411   assert(ctx);
00412   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00413   assert(xctx);
00414 
00415   if (closing) {
00416     /* just ignore empty tags which are closed immediately */
00417     DBG_DEBUG(GWEN_LOGDOMAIN, "Closing empty tag [%s]",
00418              (xctx->currentTagName)?xctx->currentTagName:"<noname>");
00419     return 0;
00420   }
00421 
00422   if (xctx->currentTagName==NULL) {
00423     DBG_INFO(GWEN_LOGDOMAIN, "No tag name, malformed HTML data");
00424     return GWEN_ERROR_BAD_DATA;
00425   }
00426 
00427   DBG_DEBUG(GWEN_LOGDOMAIN, "Completed tag [%s]", xctx->currentTagName);
00428 
00429   if (xctx->currentGroup) {
00430     if (*(xctx->currentTagName)=='/') {
00431       int rv;
00432 
00433       /* it is a closing tag, call EndTagFn */
00434       DBG_DEBUG(GWEN_LOGDOMAIN,
00435                "Calling %s->EndTag(%s)",
00436                HtmlGroup_GetGroupName(xctx->currentGroup),
00437                xctx->currentTagName);
00438       rv=HtmlGroup_EndTag(xctx->currentGroup, xctx->currentTagName+1);
00439       if (rv<0) {
00440         if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
00441           DBG_INFO(GWEN_LOGDOMAIN,
00442                    "Error in EndTag(%s) for [%s]",
00443                    HtmlGroup_GetGroupName(xctx->currentGroup),
00444                    xctx->currentTagName);
00445           return rv;
00446         }
00447       }
00448       else if (rv==1) {
00449         HTML_GROUP *g;
00450         HTML_GROUP *gParent;
00451 
00452         /* pop current group from stack */
00453         g=xctx->currentGroup;
00454         gParent=HtmlGroup_GetParent(g);
00455         xctx->currentGroup=gParent;
00456         if (gParent) {
00457           DBG_DEBUG(GWEN_LOGDOMAIN,
00458                    "Calling %s->EndSubGroup(%s)",
00459                    HtmlGroup_GetGroupName(gParent),
00460                    HtmlGroup_GetGroupName(g));
00461           HtmlGroup_EndSubGroup(gParent, g);
00462         }
00463         HtmlGroup_free(g);
00464         GWEN_XmlCtx_DecDepth(ctx);
00465       }
00466     }
00467     else {
00468       int rv;
00469 
00470       /* it is an opening tag, call StartTagFn */
00471       DBG_DEBUG(GWEN_LOGDOMAIN,
00472                "Calling %s->StartTag(%s)",
00473                HtmlGroup_GetGroupName(xctx->currentGroup),
00474                xctx->currentTagName);
00475       rv=HtmlGroup_StartTag(xctx->currentGroup, xctx->currentTagName);
00476       if (rv<0) {
00477         if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
00478           DBG_INFO(GWEN_LOGDOMAIN,
00479                    "Error in StartTag(%s) for [%s]",
00480                    HtmlGroup_GetGroupName(xctx->currentGroup),
00481                    xctx->currentTagName);
00482           return rv;
00483         }
00484       }
00485     }
00486   }
00487 
00488   return 0;
00489 }
00490 
00491 
00492 
00493 
00494 
00495 
00496 int HtmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data) {
00497   HTML_XMLCTX *xctx;
00498 
00499   assert(ctx);
00500   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00501   assert(xctx);
00502 
00503   if (xctx->currentGroup) {
00504     int rv;
00505 
00506     DBG_DEBUG(GWEN_LOGDOMAIN,
00507               "Calling %s->AddData()",
00508               HtmlGroup_GetGroupName(xctx->currentGroup));
00509     rv=HtmlGroup_AddData(xctx->currentGroup, data);
00510     if (rv<0) {
00511       if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
00512         DBG_INFO(GWEN_LOGDOMAIN,
00513                  "Error in AddData(%s)",
00514                  HtmlGroup_GetGroupName(xctx->currentGroup));
00515         return rv;
00516       }
00517     }
00518   }
00519 
00520   return 0;
00521 }
00522 
00523 
00524 
00525 int HtmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data) {
00526   HTML_XMLCTX *xctx;
00527 
00528   assert(ctx);
00529   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00530   assert(xctx);
00531 
00532   /* ignore comments */
00533   return 0;
00534 }
00535 
00536 
00537 
00538 int HtmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx,
00539                     const char *attrName,
00540                     const char *attrData) {
00541   HTML_XMLCTX *xctx;
00542 
00543   assert(ctx);
00544   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00545   assert(xctx);
00546 
00547   if (xctx->currentGroup) {
00548     assert(xctx->dbCurrentAttribs);
00549     GWEN_DB_SetCharValue(xctx->dbCurrentAttribs,
00550                          GWEN_DB_FLAGS_DEFAULT,
00551                          attrName, attrData);
00552   }
00553 
00554   return 0;
00555 }
00556 
00557 
00558 
00559 int HtmlCtx_GetTextWidth(GWEN_XML_CONTEXT *ctx,
00560                          HTML_FONT *fnt,
00561                          const char *s) {
00562   HTML_XMLCTX *xctx;
00563 
00564   assert(ctx);
00565   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00566   assert(xctx);
00567 
00568   if (xctx->getTextWidthFn)
00569     return xctx->getTextWidthFn(ctx, fnt, s);
00570   else
00571     return -1;
00572 }
00573 
00574 
00575 
00576 int HtmlCtx_GetTextHeight(GWEN_XML_CONTEXT *ctx,
00577                           HTML_FONT *fnt,
00578                           const char *s) {
00579   HTML_XMLCTX *xctx;
00580 
00581   assert(ctx);
00582   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00583   assert(xctx);
00584 
00585   if (xctx->getTextHeightFn)
00586     return xctx->getTextHeightFn(ctx, fnt, s);
00587   else
00588     return -1;
00589 }
00590 
00591 
00592 
00593 uint32_t HtmlCtx_GetColorFromName(const GWEN_XML_CONTEXT *ctx,
00594                                   const char *name) {
00595   HTML_XMLCTX *xctx;
00596 
00597   assert(ctx);
00598   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00599   assert(xctx);
00600 
00601   if (xctx->getColorFromNameFn)
00602     return xctx->getColorFromNameFn(ctx, name);
00603   else
00604     return 0xffffffff;
00605 }
00606 
00607 
00608 
00609 HTML_FONT *HtmlCtx_GetFont(GWEN_XML_CONTEXT *ctx,
00610                            const char *fontName,
00611                            int fontSize,
00612                            uint32_t fontFlags) {
00613   HTML_XMLCTX *xctx;
00614 
00615   assert(ctx);
00616   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00617   assert(xctx);
00618 
00619   if (xctx->getFontFn)
00620     return xctx->getFontFn(ctx, fontName, fontSize, fontFlags);
00621   else
00622     return NULL;
00623 }
00624 
00625 
00626 
00627 HTML_IMAGE *HtmlCtx_GetImage(GWEN_XML_CONTEXT *ctx, const char *imageName) {
00628   HTML_XMLCTX *xctx;
00629 
00630   assert(ctx);
00631   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00632   assert(xctx);
00633 
00634   if (xctx->getImageFn)
00635     return xctx->getImageFn(ctx, imageName);
00636   else
00637     return NULL;
00638 }
00639 
00640 
00641 
00642 HTMLCTX_GET_TEXT_WIDTH_FN HtmlCtx_SetGetTextWidthFn(GWEN_XML_CONTEXT *ctx,
00643                                                     HTMLCTX_GET_TEXT_WIDTH_FN fn) {
00644   HTML_XMLCTX *xctx;
00645   HTMLCTX_GET_TEXT_WIDTH_FN of;
00646 
00647   assert(ctx);
00648   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00649   assert(xctx);
00650 
00651   of=xctx->getTextWidthFn;
00652   xctx->getTextWidthFn=fn;
00653 
00654   return of;
00655 }
00656 
00657 
00658 
00659 HTMLCTX_GET_TEXT_HEIGHT_FN HtmlCtx_SetGetTextHeightFn(GWEN_XML_CONTEXT *ctx,
00660                                                       HTMLCTX_GET_TEXT_HEIGHT_FN fn) {
00661   HTML_XMLCTX *xctx;
00662   HTMLCTX_GET_TEXT_HEIGHT_FN of;
00663 
00664   assert(ctx);
00665   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00666   assert(xctx);
00667 
00668   of=xctx->getTextHeightFn;
00669   xctx->getTextHeightFn=fn;
00670 
00671   return of;
00672 }
00673 
00674 
00675 
00676 HTMLCTX_GET_COLOR_FROM_NAME_FN HtmlCtx_SetGetColorFromNameFn(GWEN_XML_CONTEXT *ctx,
00677                                                              HTMLCTX_GET_COLOR_FROM_NAME_FN fn) {
00678   HTML_XMLCTX *xctx;
00679   HTMLCTX_GET_COLOR_FROM_NAME_FN of;
00680 
00681   assert(ctx);
00682   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00683   assert(xctx);
00684 
00685   of=xctx->getColorFromNameFn;
00686   xctx->getColorFromNameFn=fn;
00687 
00688   return of;
00689 }
00690 
00691 
00692 
00693 HTMLCTX_GET_FONT_FN HtmlCtx_SetGetFontFn(GWEN_XML_CONTEXT *ctx, HTMLCTX_GET_FONT_FN fn) {
00694   HTML_XMLCTX *xctx;
00695   HTMLCTX_GET_FONT_FN of;
00696 
00697   assert(ctx);
00698   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00699   assert(xctx);
00700 
00701   of=xctx->getFontFn;
00702   xctx->getFontFn=fn;
00703 
00704   return of;
00705 }
00706 
00707 
00708 
00709 HTMLCTX_GET_IMAGE_FN HtmlCtx_SetGetImageFn(GWEN_XML_CONTEXT *ctx, HTMLCTX_GET_IMAGE_FN fn) {
00710   HTML_XMLCTX *xctx;
00711   HTMLCTX_GET_IMAGE_FN of;
00712 
00713   assert(ctx);
00714   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00715   assert(xctx);
00716 
00717   of=xctx->getImageFn;
00718   xctx->getImageFn=fn;
00719 
00720   return of;
00721 }
00722 
00723 
00724 
00725 int HtmlCtx_Layout(GWEN_XML_CONTEXT *ctx, int width, int height) {
00726   HTML_XMLCTX *xctx;
00727   HTML_OBJECT *o;
00728   int rv;
00729 
00730   assert(ctx);
00731   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00732   assert(xctx);
00733 
00734   o=HtmlObject_Tree_GetFirst(xctx->objects);
00735   if (o==NULL) {
00736     DBG_ERROR(GWEN_LOGDOMAIN, "No objects");
00737     return 0;
00738   }
00739 
00740   HtmlObject_SetWidth(o, width);
00741   HtmlObject_SetHeight(o, height);
00742   rv=HtmlObject_Layout(o);
00743   if (rv<0) {
00744     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00745     return rv;
00746   }
00747 
00748   return 0;
00749 }
00750 
00751 
00752 
00753 void HtmlCtx_SetText(GWEN_XML_CONTEXT *ctx, const char *s) {
00754   HTML_XMLCTX *xctx;
00755   int rv;
00756   HTML_GROUP *g;
00757   HTML_OBJECT *o;
00758 
00759   assert(ctx);
00760   xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
00761   assert(xctx);
00762 
00763   /* reset */
00764   HtmlObject_Tree_Clear(xctx->objects);
00765 
00766   /* create initial group */
00767   g=HtmlGroup_Box_new("HTML_ROOT", NULL, ctx);
00768   assert(g);
00769 
00770   HtmlGroup_SetProperties(g, xctx->standardProps);
00771   o=HtmlObject_Box_new(ctx);
00772   HtmlObject_SetProperties(o, xctx->standardProps);
00773   HtmlGroup_SetObject(g, o);
00774   HtmlObject_Tree_Add(xctx->objects, o);
00775   HtmlCtx_SetCurrentGroup(ctx, g);
00776 
00777   if (s && *s) {
00778     rv=GWEN_XMLContext_ReadFromString(ctx, s);
00779     if (rv<0) {
00780       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00781     }
00782   }
00783 
00784 #if 0
00785   fprintf(stderr, "============ Objects:\n");
00786   fprintf(stderr, "String: [%s]\n", s);
00787   o=HtmlObject_Tree_GetFirst(xctx->objects);
00788   while(o) {
00789     const char *xx;
00790 
00791     xx=HtmlObject_GetText(o);
00792     fprintf(stderr, "Object(%d): [%s]\n",
00793             HtmlObject_GetObjectType(o),
00794             xx?xx:"(NULL)");
00795     o=HtmlObject_Tree_GetBelow(o);
00796   }
00797 #endif
00798 }
00799 
00800 
00801 
00802 int HtmlCtx_GetWidth(const GWEN_XML_CONTEXT *ctx) {
00803   HTML_OBJECT *o;
00804 
00805   o=HtmlCtx_GetRootObject(ctx);
00806   if (o)
00807     return HtmlObject_GetWidth(o);
00808   else
00809     return -1;
00810 }
00811 
00812 
00813 
00814 int HtmlCtx_GetHeight(const GWEN_XML_CONTEXT *ctx) {
00815   HTML_OBJECT *o;
00816 
00817   o=HtmlCtx_GetRootObject(ctx);
00818   if (o)
00819     return HtmlObject_GetHeight(o);
00820   else
00821     return -1;
00822 }
00823 
00824