g_box.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 #ifdef HAVE_CONFIG_H
00012 # include <config.h>
00013 #endif
00014 
00015 #define DISABLE_DEBUGLOG
00016 
00017 
00018 #include "g_box_p.h"
00019 #include "g_generic_l.h"
00020 #include "g_table_l.h"
00021 #include "g_unorderedlist_l.h"
00022 #include "htmlctx_l.h"
00023 #include "o_box_l.h"
00024 #include "o_word_l.h"
00025 #include "o_grid_l.h"
00026 #include "o_image_be.h"
00027 
00028 #include <gwenhywfar/misc.h>
00029 #include <gwenhywfar/debug.h>
00030 
00031 #include <ctype.h>
00032 
00033 
00034 
00035 
00036 HTML_GROUP *HtmlGroup_Box_new(const char *groupName,
00037                               HTML_GROUP *parent,
00038                               GWEN_XML_CONTEXT *ctx) {
00039   HTML_GROUP *g;
00040 
00041   /* create base group */
00042   g=HtmlGroup_Generic_new(groupName, parent, ctx);
00043   assert(g);
00044 
00045   /* set virtual functions */
00046   HtmlGroup_SetStartTagFn(g, HtmlGroup_Box_StartTag);
00047   HtmlGroup_SetAddDataFn(g, HtmlGroup_Box_AddData);
00048 
00049   return g;
00050 }
00051 
00052 
00053 
00054 int HtmlGroup_Box_StartTag(HTML_GROUP *g, const char *tagName) {
00055   HTML_GROUP *gNew=NULL;
00056   GWEN_XML_CONTEXT *ctx;
00057   GWEN_DB_NODE *dbAttribs;
00058 
00059   assert(g);
00060 
00061   ctx=HtmlGroup_GetXmlContext(g);
00062   dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
00063 
00064   if (strcasecmp(tagName, "b")==0) {
00065     /* Create new parser group with new properties but use the same object */
00066     HTML_PROPS *pr;
00067     HTML_FONT *fnt;
00068 
00069     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00070     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00071     fnt=HtmlProps_GetFont(pr);
00072     fnt=HtmlCtx_GetFont(ctx,
00073                         HtmlFont_GetFontName(fnt),
00074                         HtmlFont_GetFontSize(fnt),
00075                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_STRONG);
00076     if (fnt) {
00077       HtmlProps_SetFont(pr, fnt);
00078       //HtmlFont_free(fnt);
00079     }
00080     HtmlGroup_SetProperties(gNew, pr);
00081     HtmlProps_free(pr);
00082     HtmlGroup_SetObject(gNew, HtmlGroup_GetObject(g));
00083   }
00084   else if (strcasecmp(tagName, "i")==0) {
00085     /* Create new parser group with new properties but use the same object */
00086     HTML_PROPS *pr;
00087     HTML_FONT *fnt;
00088 
00089     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00090     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00091     fnt=HtmlProps_GetFont(pr);
00092     fnt=HtmlCtx_GetFont(ctx,
00093                         HtmlFont_GetFontName(fnt),
00094                         HtmlFont_GetFontSize(fnt),
00095                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_ITALIC);
00096     if (fnt) {
00097       HtmlProps_SetFont(pr, fnt);
00098       //HtmlFont_free(fnt);
00099     }
00100     HtmlGroup_SetProperties(gNew, pr);
00101     HtmlProps_free(pr);
00102     HtmlGroup_SetObject(gNew, HtmlGroup_GetObject(g));
00103   }
00104   else if (strcasecmp(tagName, "u")==0) {
00105     /* Create new parser group with new properties but use the same object */
00106     HTML_PROPS *pr;
00107     HTML_FONT *fnt;
00108 
00109     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00110     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00111     fnt=HtmlProps_GetFont(pr);
00112     fnt=HtmlCtx_GetFont(ctx,
00113                         HtmlFont_GetFontName(fnt),
00114                         HtmlFont_GetFontSize(fnt),
00115                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_UNDERLINE);
00116     if (fnt) {
00117       HtmlProps_SetFont(pr, fnt);
00118       //HtmlFont_free(fnt);
00119     }
00120     HtmlGroup_SetProperties(gNew, pr);
00121     HtmlProps_free(pr);
00122     HtmlGroup_SetObject(gNew, HtmlGroup_GetObject(g));
00123   }
00124   else if (strcasecmp(tagName, "p")==0) {
00125     HTML_OBJECT *o;
00126 
00127     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00128     HtmlGroup_SetProperties(gNew, HtmlGroup_GetProperties(g));
00129     o=HtmlObject_Box_new(ctx);
00130     HtmlObject_AddFlags(o,
00131                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00132                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00133     if (dbAttribs) {
00134       const char *s;
00135 
00136       s=GWEN_DB_GetCharValue(dbAttribs, "align", 0, "left");
00137       if (s) {
00138         if (strcasecmp(s, "right")==0)
00139           HtmlObject_AddFlags(o, HTML_OBJECT_FLAGS_JUSTIFY_RIGHT);
00140         else if (strcasecmp(s, "center")==0)
00141           HtmlObject_AddFlags(o, HTML_OBJECT_FLAGS_JUSTIFY_HCENTER);
00142       }
00143     }
00144     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00145     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00146     HtmlGroup_SetObject(gNew, o);
00147   }
00148   else if (strcasecmp(tagName, "right")==0) {
00149     HTML_OBJECT *o;
00150 
00151     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00152     HtmlGroup_SetProperties(gNew, HtmlGroup_GetProperties(g));
00153     o=HtmlObject_Box_new(ctx);
00154     HtmlObject_AddFlags(o,
00155                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00156                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE |
00157                         HTML_OBJECT_FLAGS_JUSTIFY_RIGHT);
00158     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00159     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00160     HtmlGroup_SetObject(gNew, o);
00161   }
00162   else if (strcasecmp(tagName, "br")==0) {
00163     HTML_OBJECT *o;
00164 
00165     /* just create and add a control object */
00166     o=HtmlObject_new(ctx, HtmlObjectType_Control);
00167     HtmlObject_AddFlags(o, HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00168     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00169     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00170   }
00171   else if (strcasecmp(tagName, "img")==0) {
00172     HTML_OBJECT *o;
00173     GWEN_DB_NODE *dbAttribs;
00174 
00175     o=HtmlObject_Image_new(ctx);
00176     HtmlObject_AddFlags(o,
00177                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00178                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00179     dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
00180     if (dbAttribs) {
00181       const char *s;
00182       int w;
00183       int h;
00184 
00185       w=GWEN_DB_GetIntValue(dbAttribs, "width", 0, -1);
00186       h=GWEN_DB_GetIntValue(dbAttribs, "height", 0, -1);
00187 
00188       /* preset */
00189       if (w!=-1)
00190         HtmlObject_Image_SetScaledWidth(o, w);
00191       if (h!=-1)
00192         HtmlObject_Image_SetScaledHeight(o, w);
00193 
00194       s=GWEN_DB_GetCharValue(dbAttribs, "src", 0, NULL);
00195       if (s && *s) {
00196         HTML_IMAGE *img;
00197 
00198         img=HtmlCtx_GetImage(ctx, s);
00199         if (img) {
00200           HtmlObject_Image_SetImage(o, img);
00201           /* adjust scaled width and height if not set by attributes */
00202           if (w==-1)
00203             HtmlObject_Image_SetScaledWidth(o, HtmlImage_GetWidth(img));
00204           if (h==-1)
00205             HtmlObject_Image_SetScaledHeight(o, HtmlImage_GetHeight(img));
00206         }
00207         else {
00208           DBG_ERROR(GWEN_LOGDOMAIN, "Image [%s] not found", s);
00209         }
00210       }
00211       else {
00212         DBG_ERROR(GWEN_LOGDOMAIN, "Missing image name in IMG element");
00213       }
00214     }
00215 
00216     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00217     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00218   }
00219   else if (strcasecmp(tagName, "table")==0) {
00220     HTML_OBJECT *o;
00221 
00222     gNew=HtmlGroup_Table_new(tagName, g, ctx);
00223     HtmlGroup_SetProperties(gNew, HtmlGroup_GetProperties(g));
00224     o=HtmlObject_Grid_new(ctx);
00225     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00226     HtmlGroup_SetObject(gNew, o);
00227     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00228   }
00229   else if (strcasecmp(tagName, "ul")==0) {
00230     HTML_OBJECT *o;
00231 
00232     gNew=HtmlGroup_UnorderedList_new(tagName, g, ctx);
00233     HtmlGroup_SetProperties(gNew, HtmlGroup_GetProperties(g));
00234     o=HtmlObject_Grid_new(ctx);
00235     HtmlObject_Grid_SetColumns(o, 2);
00236     HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00237     HtmlGroup_SetObject(gNew, o);
00238     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00239   }
00240   else if (strcasecmp(tagName, "font")==0) {
00241     /* Create new parser group with new properties but use the same object */
00242     HTML_PROPS *pr;
00243     GWEN_DB_NODE *dbAttribs;
00244 
00245     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00246     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00247 
00248     dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
00249     if (dbAttribs) {
00250       HTML_FONT *fnt;
00251       const char *s;
00252       const char *fontName;
00253       int fontSize;
00254       uint32_t fontFlags;
00255 
00256       fnt=HtmlProps_GetFont(pr);
00257       fontName=GWEN_DB_GetCharValue(dbAttribs, "face", 0, NULL);
00258       if (fontName==NULL)
00259         fontName=HtmlFont_GetFontName(fnt);
00260       fontFlags=HtmlFont_GetFontFlags(fnt);
00261       fontSize=HtmlFont_GetFontSize(fnt);
00262       s=GWEN_DB_GetCharValue(dbAttribs, "size", 0, NULL);
00263       if (s && *s) {
00264         if (*s=='+') {
00265           int i;
00266 
00267           sscanf(s, "%d", &i);
00268           fontSize+=i*4;
00269         }
00270         else if (*s=='-') {
00271           int i;
00272 
00273           sscanf(s, "%d", &i);
00274           fontSize+=i*4;
00275         }
00276         else
00277           sscanf(s, "%d", &fontSize);
00278       }
00279 
00280       s=GWEN_DB_GetCharValue(dbAttribs, "color", 0, NULL);
00281       if (s && *s) {
00282         uint32_t color;
00283 
00284         color=HtmlCtx_GetColorFromName(ctx, s);
00285         HtmlProps_SetForegroundColor(pr, color);
00286       }
00287 
00288       fnt=HtmlCtx_GetFont(ctx, fontName, fontSize, fontFlags);
00289       if (fnt) {
00290         HtmlProps_SetFont(pr, fnt);
00291         //HtmlFont_free(fnt);
00292       }
00293     }
00294 
00295     HtmlGroup_SetProperties(gNew, pr);
00296     HtmlProps_free(pr);
00297     HtmlGroup_SetObject(gNew, HtmlGroup_GetObject(g));
00298   }
00299   else if (strcasecmp(tagName, "h1")==0) {
00300     /* Create new parser group with new properties but use the same object */
00301     HTML_PROPS *pr;
00302     HTML_FONT *fnt;
00303     HTML_OBJECT *o;
00304 
00305     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00306     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00307     fnt=HtmlProps_GetFont(pr);
00308     fnt=HtmlCtx_GetFont(ctx,
00309                         HtmlFont_GetFontName(fnt),
00310                         HtmlFont_GetFontSize(fnt)*1.8,
00311                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_STRONG);
00312     if (fnt) {
00313       HtmlProps_SetFont(pr, fnt);
00314       //HtmlFont_free(fnt);
00315     }
00316     HtmlGroup_SetProperties(gNew, pr);
00317 
00318     o=HtmlObject_Box_new(ctx);
00319     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00320     HtmlObject_AddFlags(o,
00321                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00322                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00323     HtmlObject_SetProperties(o, pr);
00324     HtmlGroup_SetObject(gNew, o);
00325     HtmlProps_free(pr);
00326   }
00327   else if (strcasecmp(tagName, "h2")==0) {
00328     /* Create new parser group with new properties but use the same object */
00329     HTML_PROPS *pr;
00330     HTML_FONT *fnt;
00331     HTML_OBJECT *o;
00332 
00333     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00334     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00335     fnt=HtmlProps_GetFont(pr);
00336     fnt=HtmlCtx_GetFont(ctx,
00337                         HtmlFont_GetFontName(fnt),
00338                         HtmlFont_GetFontSize(fnt)*1.5,
00339                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_STRONG);
00340     if (fnt) {
00341       HtmlProps_SetFont(pr, fnt);
00342       //HtmlFont_free(fnt);
00343     }
00344     HtmlGroup_SetProperties(gNew, pr);
00345 
00346     o=HtmlObject_Box_new(ctx);
00347     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00348     HtmlObject_AddFlags(o,
00349                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00350                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00351     HtmlObject_SetProperties(o, pr);
00352     HtmlGroup_SetObject(gNew, o);
00353     HtmlProps_free(pr);
00354   }
00355   else if (strcasecmp(tagName, "h3")==0) {
00356     /* Create new parser group with new properties but use the same object */
00357     HTML_PROPS *pr;
00358     HTML_FONT *fnt;
00359     HTML_OBJECT *o;
00360 
00361     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00362     pr=HtmlProps_dup(HtmlGroup_GetProperties(g));
00363     fnt=HtmlProps_GetFont(pr);
00364     fnt=HtmlCtx_GetFont(ctx,
00365                         HtmlFont_GetFontName(fnt),
00366                         HtmlFont_GetFontSize(fnt),
00367                         HtmlFont_GetFontFlags(fnt) | HTML_FONT_FLAGS_STRONG);
00368     if (fnt) {
00369       HtmlProps_SetFont(pr, fnt);
00370       //HtmlFont_free(fnt);
00371     }
00372     HtmlGroup_SetProperties(gNew, pr);
00373 
00374     o=HtmlObject_Box_new(ctx);
00375     HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00376     HtmlObject_AddFlags(o,
00377                         HTML_OBJECT_FLAGS_START_ON_NEWLINE |
00378                         HTML_OBJECT_FLAGS_END_WITH_NEWLINE);
00379     HtmlObject_SetProperties(o, pr);
00380     HtmlGroup_SetObject(gNew, o);
00381     HtmlProps_free(pr);
00382   }
00383   else if (strcasecmp(tagName, "html")==0 ||
00384            strcasecmp(tagName, "body")==0) {
00385   }
00386   else {
00387     DBG_WARN(GWEN_LOGDOMAIN,
00388              "Unknown group [%s], handling as normal box", tagName);
00389     gNew=HtmlGroup_Box_new(tagName, g, ctx);
00390     HtmlGroup_SetProperties(gNew, HtmlGroup_GetProperties(g));
00391     HtmlGroup_SetObject(gNew, HtmlGroup_GetObject(g));
00392   }
00393 
00394   if (gNew) {
00395     HtmlCtx_SetCurrentGroup(ctx, gNew);
00396     GWEN_XmlCtx_IncDepth(ctx);
00397   }
00398 
00399   return 0;
00400 }
00401 
00402 
00403 
00404 int HtmlGroup_Box_AddData(HTML_GROUP *g, const char *data) {
00405   GWEN_XML_CONTEXT *ctx;
00406   GWEN_BUFFER *buf;
00407   int rv;
00408   uint8_t *s;
00409   HTML_OBJECT *o;
00410 
00411   assert(g);
00412 
00413   ctx=HtmlGroup_GetXmlContext(g);
00414   if (data && *data) {
00415     buf=GWEN_Buffer_new(0, strlen(data), 0, 1);
00416     rv=HtmlCtx_SanitizeData(ctx, data, buf);
00417     if (rv<0) {
00418       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00419       GWEN_Buffer_free(buf);
00420       return rv;
00421     }
00422     if (GWEN_Buffer_GetUsedBytes(buf)) {
00423       s=(uint8_t*)GWEN_Buffer_GetStart(buf);
00424 
00425       while(*s) {
00426         uint8_t *t;
00427         uint8_t c;
00428     
00429         /* find begin of word */
00430         while(*s && isspace(*s))
00431           s++;
00432     
00433         /* find end of word */
00434         t=s;
00435         while(*t && !isspace(*t))
00436           t++;
00437         c=*t;
00438         *t=0;
00439         o=HtmlObject_Word_new(ctx, (const char*) s);
00440         HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
00441         HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
00442         *t=c;
00443         s=t;
00444       }
00445     }
00446     GWEN_Buffer_free(buf);
00447   }
00448 
00449   return 0;
00450 }
00451 
00452 
00453