gwenhywfar  5.10.1
g_box.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sat Feb 20 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 
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14 
15 #define DISABLE_DEBUGLOG
16 
17 
18 #include "g_box_p.h"
19 #include "g_generic_l.h"
20 #include "g_table_l.h"
21 #include "g_unorderedlist_l.h"
22 #include "htmlctx_l.h"
23 #include "o_box_l.h"
24 #include "o_word_l.h"
25 #include "o_grid_l.h"
26 #include "o_image_be.h"
27 
28 #include <gwenhywfar/misc.h>
29 #include <gwenhywfar/debug.h>
30 
31 #include <ctype.h>
32 
33 
34 
35 
36 HTML_GROUP *HtmlGroup_Box_new(const char *groupName,
37  HTML_GROUP *parent,
38  GWEN_XML_CONTEXT *ctx)
39 {
40  HTML_GROUP *g;
41 
42  /* create base group */
43  g=HtmlGroup_Generic_new(groupName, parent, ctx);
44  assert(g);
45 
46  /* set virtual functions */
49 
50  return g;
51 }
52 
53 
54 
55 int HtmlGroup_Box_StartTag(HTML_GROUP *g, const char *tagName)
56 {
57  HTML_GROUP *gNew=NULL;
58  GWEN_XML_CONTEXT *ctx;
59  GWEN_DB_NODE *dbAttribs;
60 
61  assert(g);
62 
64  dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
65 
66  if (strcasecmp(tagName, "b")==0) {
67  /* Create new parser group with new properties but use the same object */
68  HTML_PROPS *pr;
69  HTML_FONT *fnt;
70 
71  gNew=HtmlGroup_Box_new(tagName, g, ctx);
73  fnt=HtmlProps_GetFont(pr);
74  fnt=HtmlCtx_GetFont(ctx,
78  if (fnt) {
79  HtmlProps_SetFont(pr, fnt);
80  //HtmlFont_free(fnt);
81  }
82  HtmlGroup_SetProperties(gNew, pr);
83  HtmlProps_free(pr);
85  }
86  else if (strcasecmp(tagName, "i")==0) {
87  /* Create new parser group with new properties but use the same object */
88  HTML_PROPS *pr;
89  HTML_FONT *fnt;
90 
91  gNew=HtmlGroup_Box_new(tagName, g, ctx);
93  fnt=HtmlProps_GetFont(pr);
94  fnt=HtmlCtx_GetFont(ctx,
98  if (fnt) {
99  HtmlProps_SetFont(pr, fnt);
100  //HtmlFont_free(fnt);
101  }
102  HtmlGroup_SetProperties(gNew, pr);
103  HtmlProps_free(pr);
105  }
106  else if (strcasecmp(tagName, "u")==0) {
107  /* Create new parser group with new properties but use the same object */
108  HTML_PROPS *pr;
109  HTML_FONT *fnt;
110 
111  gNew=HtmlGroup_Box_new(tagName, g, ctx);
113  fnt=HtmlProps_GetFont(pr);
114  fnt=HtmlCtx_GetFont(ctx,
118  if (fnt) {
119  HtmlProps_SetFont(pr, fnt);
120  //HtmlFont_free(fnt);
121  }
122  HtmlGroup_SetProperties(gNew, pr);
123  HtmlProps_free(pr);
125  }
126  else if (strcasecmp(tagName, "p")==0) {
127  HTML_OBJECT *o;
128 
129  gNew=HtmlGroup_Box_new(tagName, g, ctx);
131  o=HtmlObject_Box_new(ctx);
135  if (dbAttribs) {
136  const char *s;
137 
138  s=GWEN_DB_GetCharValue(dbAttribs, "align", 0, "left");
139  if (s) {
140  if (strcasecmp(s, "right")==0)
142  else if (strcasecmp(s, "center")==0)
144  }
145  }
146  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
148  HtmlGroup_SetObject(gNew, o);
149  }
150  else if (strcasecmp(tagName, "right")==0) {
151  HTML_OBJECT *o;
152 
153  gNew=HtmlGroup_Box_new(tagName, g, ctx);
155  o=HtmlObject_Box_new(ctx);
160  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
162  HtmlGroup_SetObject(gNew, o);
163  }
164  else if (strcasecmp(tagName, "br")==0) {
165  HTML_OBJECT *o;
166 
167  /* just create and add a control object */
170  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
172  }
173  else if (strcasecmp(tagName, "img")==0) {
174  HTML_OBJECT *o;
175  GWEN_DB_NODE *dbAttribs;
176 
177  o=HtmlObject_Image_new(ctx);
181  dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
182  if (dbAttribs) {
183  const char *s;
184  int w;
185  int h;
186 
187  w=GWEN_DB_GetIntValue(dbAttribs, "width", 0, -1);
188  h=GWEN_DB_GetIntValue(dbAttribs, "height", 0, -1);
189 
190  /* preset */
191  if (w!=-1)
193  if (h!=-1)
195 
196  s=GWEN_DB_GetCharValue(dbAttribs, "src", 0, NULL);
197  if (s && *s) {
198  HTML_IMAGE *img;
199 
200  img=HtmlCtx_GetImage(ctx, s);
201  if (img) {
203  /* adjust scaled width and height if not set by attributes */
204  if (w==-1)
206  if (h==-1)
208  }
209  else {
210  DBG_ERROR(GWEN_LOGDOMAIN, "Image [%s] not found", s);
211  }
212  }
213  else {
214  DBG_ERROR(GWEN_LOGDOMAIN, "Missing image name in IMG element");
215  }
216  }
217 
218  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
220  }
221  else if (strcasecmp(tagName, "table")==0) {
222  HTML_OBJECT *o;
223 
224  gNew=HtmlGroup_Table_new(tagName, g, ctx);
226  o=HtmlObject_Grid_new(ctx);
228  HtmlGroup_SetObject(gNew, o);
229  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
230  }
231  else if (strcasecmp(tagName, "ul")==0) {
232  HTML_OBJECT *o;
233 
234  gNew=HtmlGroup_UnorderedList_new(tagName, g, ctx);
236  o=HtmlObject_Grid_new(ctx);
239  HtmlGroup_SetObject(gNew, o);
240  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
241  }
242  else if (strcasecmp(tagName, "font")==0) {
243  /* Create new parser group with new properties but use the same object */
244  HTML_PROPS *pr;
245  GWEN_DB_NODE *dbAttribs;
246 
247  gNew=HtmlGroup_Box_new(tagName, g, ctx);
249 
250  dbAttribs=HtmlCtx_GetCurrentAttributes(ctx);
251  if (dbAttribs) {
252  HTML_FONT *fnt;
253  const char *s;
254  const char *fontName;
255  int fontSize;
256  uint32_t fontFlags;
257 
258  fnt=HtmlProps_GetFont(pr);
259  fontName=GWEN_DB_GetCharValue(dbAttribs, "face", 0, NULL);
260  if (fontName==NULL)
261  fontName=HtmlFont_GetFontName(fnt);
262  fontFlags=HtmlFont_GetFontFlags(fnt);
263  fontSize=HtmlFont_GetFontSize(fnt);
264  s=GWEN_DB_GetCharValue(dbAttribs, "size", 0, NULL);
265  if (s && *s) {
266  if (*s=='+') {
267  int i;
268 
269  sscanf(s, "%d", &i);
270  fontSize+=i*4;
271  }
272  else if (*s=='-') {
273  int i;
274 
275  sscanf(s, "%d", &i);
276  fontSize+=i*4;
277  }
278  else
279  sscanf(s, "%d", &fontSize);
280  }
281 
282  s=GWEN_DB_GetCharValue(dbAttribs, "color", 0, NULL);
283  if (s && *s) {
284  uint32_t color;
285 
286  color=HtmlCtx_GetColorFromName(ctx, s);
287  HtmlProps_SetForegroundColor(pr, color);
288  }
289 
290  fnt=HtmlCtx_GetFont(ctx, fontName, fontSize, fontFlags);
291  if (fnt) {
292  HtmlProps_SetFont(pr, fnt);
293  //HtmlFont_free(fnt);
294  }
295  }
296 
297  HtmlGroup_SetProperties(gNew, pr);
298  HtmlProps_free(pr);
300  }
301  else if (strcasecmp(tagName, "h1")==0) {
302  /* Create new parser group with new properties but use the same object */
303  HTML_PROPS *pr;
304  HTML_FONT *fnt;
305  HTML_OBJECT *o;
306 
307  gNew=HtmlGroup_Box_new(tagName, g, ctx);
309  fnt=HtmlProps_GetFont(pr);
310  fnt=HtmlCtx_GetFont(ctx,
312  HtmlFont_GetFontSize(fnt)*1.8,
314  if (fnt) {
315  HtmlProps_SetFont(pr, fnt);
316  //HtmlFont_free(fnt);
317  }
318  HtmlGroup_SetProperties(gNew, pr);
319 
320  o=HtmlObject_Box_new(ctx);
321  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
326  HtmlGroup_SetObject(gNew, o);
327  HtmlProps_free(pr);
328  }
329  else if (strcasecmp(tagName, "h2")==0) {
330  /* Create new parser group with new properties but use the same object */
331  HTML_PROPS *pr;
332  HTML_FONT *fnt;
333  HTML_OBJECT *o;
334 
335  gNew=HtmlGroup_Box_new(tagName, g, ctx);
337  fnt=HtmlProps_GetFont(pr);
338  fnt=HtmlCtx_GetFont(ctx,
340  HtmlFont_GetFontSize(fnt)*1.5,
342  if (fnt) {
343  HtmlProps_SetFont(pr, fnt);
344  //HtmlFont_free(fnt);
345  }
346  HtmlGroup_SetProperties(gNew, pr);
347 
348  o=HtmlObject_Box_new(ctx);
349  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
354  HtmlGroup_SetObject(gNew, o);
355  HtmlProps_free(pr);
356  }
357  else if (strcasecmp(tagName, "h3")==0) {
358  /* Create new parser group with new properties but use the same object */
359  HTML_PROPS *pr;
360  HTML_FONT *fnt;
361  HTML_OBJECT *o;
362 
363  gNew=HtmlGroup_Box_new(tagName, g, ctx);
365  fnt=HtmlProps_GetFont(pr);
366  fnt=HtmlCtx_GetFont(ctx,
370  if (fnt) {
371  HtmlProps_SetFont(pr, fnt);
372  //HtmlFont_free(fnt);
373  }
374  HtmlGroup_SetProperties(gNew, pr);
375 
376  o=HtmlObject_Box_new(ctx);
377  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
382  HtmlGroup_SetObject(gNew, o);
383  HtmlProps_free(pr);
384  }
385  else if (strcasecmp(tagName, "h4")==0) {
386  /* Create new parser group with new properties but use the same object */
387  HTML_PROPS *pr;
388  HTML_FONT *fnt;
389  HTML_OBJECT *o;
390 
391  gNew=HtmlGroup_Box_new(tagName, g, ctx);
393  fnt=HtmlProps_GetFont(pr);
394  fnt=HtmlCtx_GetFont(ctx,
398  if (fnt) {
399  HtmlProps_SetFont(pr, fnt);
400  //HtmlFont_free(fnt);
401  }
402  HtmlGroup_SetProperties(gNew, pr);
403 
404  o=HtmlObject_Box_new(ctx);
405  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
410  HtmlGroup_SetObject(gNew, o);
411  HtmlProps_free(pr);
412  }
413  else if (strcasecmp(tagName, "html")==0 ||
414  strcasecmp(tagName, "body")==0) {
415  }
416  else {
418  "Unknown group [%s], handling as normal box", tagName);
419  gNew=HtmlGroup_Box_new(tagName, g, ctx);
422  }
423 
424  if (gNew) {
425  HtmlCtx_SetCurrentGroup(ctx, gNew);
427  }
428 
429  return 0;
430 }
431 
432 
433 
434 int HtmlGroup_Box_AddData(HTML_GROUP *g, const char *data)
435 {
436  GWEN_XML_CONTEXT *ctx;
437  GWEN_BUFFER *buf;
438  int rv;
439  uint8_t *s;
440  HTML_OBJECT *o;
441 
442  assert(g);
443 
445  if (data && *data) {
446  buf=GWEN_Buffer_new(0, strlen(data), 0, 1);
447  rv=HtmlCtx_SanitizeData(ctx, data, buf);
448  if (rv<0) {
449  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
450  GWEN_Buffer_free(buf);
451  return rv;
452  }
453  if (GWEN_Buffer_GetUsedBytes(buf)) {
454  s=(uint8_t *)GWEN_Buffer_GetStart(buf);
455 
456  while (*s) {
457  uint8_t *t;
458  uint8_t c;
459 
460  /* find begin of word */
461  while (*s && isspace(*s))
462  s++;
463 
464  /* find end of word */
465  t=s;
466  while (*t && !isspace(*t))
467  t++;
468  c=*t;
469  *t=0;
470  o=HtmlObject_Word_new(ctx, (const char *) s);
472  HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
473  *t=c;
474  s=t;
475  }
476  }
477  GWEN_Buffer_free(buf);
478  }
479 
480  return 0;
481 }
482 
483 
484 
const char * HtmlFont_GetFontName(const HTML_FONT *fnt)
Definition: htmlfont.c:67
struct HTML_GROUP HTML_GROUP
Definition: htmlgroup_l.h:19
HTML_OBJECT * HtmlGroup_GetObject(const HTML_GROUP *g)
Definition: htmlgroup.c:88
HTML_OBJECT * HtmlObject_Grid_new(GWEN_XML_CONTEXT *ctx)
Definition: o_grid.c:207
int HtmlFont_GetFontSize(const HTML_FONT *fnt)
Definition: htmlfont.c:89
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
HTML_OBJECT * HtmlObject_Box_new(GWEN_XML_CONTEXT *ctx)
Definition: o_box.c:237
void HtmlGroup_SetObject(HTML_GROUP *g, HTML_OBJECT *o)
Definition: htmlgroup.c:96
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
void HtmlObject_Image_SetImage(HTML_OBJECT *o, HTML_IMAGE *img)
Definition: o_image.c:132
void HtmlProps_free(HTML_PROPS *pr)
Definition: htmlprops.c:40
void HtmlObject_Grid_SetColumns(HTML_OBJECT *o, int i)
Definition: o_grid.c:276
int HtmlImage_GetWidth(const HTML_IMAGE *img)
Definition: htmlimage.c:89
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
#define HTML_OBJECT_FLAGS_JUSTIFY_HCENTER
Definition: htmlobject_be.h:35
HTML_GROUP_STARTTAG_FN HtmlGroup_SetStartTagFn(HTML_GROUP *g, HTML_GROUP_STARTTAG_FN f)
Definition: htmlgroup.c:128
#define HTML_FONT_FLAGS_ITALIC
Definition: htmlfont_be.h:30
void HtmlProps_SetFont(HTML_PROPS *pr, HTML_FONT *fnt)
Definition: htmlprops.c:91
#define NULL
Definition: binreloc.c:300
#define HTML_OBJECT_FLAGS_START_ON_NEWLINE
Definition: htmlobject_be.h:30
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
HTML_OBJECT * HtmlObject_Image_new(GWEN_XML_CONTEXT *ctx)
Definition: o_image.c:40
uint32_t HtmlCtx_GetColorFromName(const GWEN_XML_CONTEXT *ctx, const char *name)
Definition: htmlctx.c:621
#define HTML_FONT_FLAGS_UNDERLINE
Definition: htmlfont_be.h:31
void HtmlObject_Image_SetScaledHeight(HTML_OBJECT *o, int i)
Definition: o_image.c:106
HTML_PROPS * HtmlProps_dup(const HTML_PROPS *pro)
Definition: htmlprops.c:57
struct HTML_IMAGE HTML_IMAGE
Definition: htmlimage_be.h:23
#define HTML_OBJECT_FLAGS_JUSTIFY_RIGHT
Definition: htmlobject_be.h:34
int HtmlGroup_Box_StartTag(HTML_GROUP *g, const char *tagName)
Definition: g_box.c:55
void HtmlObject_AddFlags(HTML_OBJECT *o, uint32_t fl)
Definition: htmlobject.c:275
void GWEN_XmlCtx_IncDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:166
struct HTML_FONT HTML_FONT
Definition: htmlfont_be.h:23
void HtmlProps_SetForegroundColor(HTML_PROPS *pr, uint32_t c)
Definition: htmlprops.c:111
HTML_GROUP * HtmlGroup_Box_new(const char *groupName, HTML_GROUP *parent, GWEN_XML_CONTEXT *ctx)
Definition: g_box.c:36
HTML_OBJECT * HtmlObject_new(GWEN_XML_CONTEXT *ctx, HTML_OBJECT_TYPE t)
Definition: htmlobject.c:31
void HtmlObject_SetProperties(HTML_OBJECT *o, HTML_PROPS *pr)
Definition: htmlobject.c:113
struct HTML_PROPS HTML_PROPS
Definition: htmlprops_be.h:15
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
int HtmlImage_GetHeight(const HTML_IMAGE *img)
Definition: htmlimage.c:107
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWEN_DB_NODE * HtmlCtx_GetCurrentAttributes(const GWEN_XML_CONTEXT *ctx)
Definition: htmlctx.c:244
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
HTML_GROUP_ADDDATA_FN HtmlGroup_SetAddDataFn(HTML_GROUP *g, HTML_GROUP_ADDDATA_FN f)
Definition: htmlgroup.c:154
HTML_PROPS * HtmlGroup_GetProperties(const HTML_GROUP *g)
Definition: htmlgroup.c:104
GWEN_XML_CONTEXT * HtmlGroup_GetXmlContext(const HTML_GROUP *g)
Definition: htmlgroup.c:72
HTML_FONT * HtmlProps_GetFont(const HTML_PROPS *pr)
Definition: htmlprops.c:82
#define HTML_FONT_FLAGS_STRONG
Definition: htmlfont_be.h:29
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
HTML_FONT * HtmlCtx_GetFont(GWEN_XML_CONTEXT *ctx, const char *fontName, int fontSize, uint32_t fontFlags)
Definition: htmlctx.c:638
HTML_IMAGE * HtmlCtx_GetImage(GWEN_XML_CONTEXT *ctx, const char *imageName)
Definition: htmlctx.c:657
int HtmlGroup_Box_AddData(HTML_GROUP *g, const char *data)
Definition: g_box.c:434
void HtmlCtx_SetCurrentGroup(GWEN_XML_CONTEXT *ctx, HTML_GROUP *g)
Definition: htmlctx.c:201
void HtmlObject_Image_SetScaledWidth(HTML_OBJECT *o, int i)
Definition: o_image.c:80
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
#define HTML_OBJECT_FLAGS_END_WITH_NEWLINE
Definition: htmlobject_be.h:31
HTML_GROUP * HtmlGroup_Table_new(const char *groupName, HTML_GROUP *parent, GWEN_XML_CONTEXT *ctx)
Definition: g_table.c:27
HTML_OBJECT * HtmlObject_Word_new(GWEN_XML_CONTEXT *ctx, const char *s)
Definition: o_word.c:49
HTML_GROUP * HtmlGroup_UnorderedList_new(const char *groupName, HTML_GROUP *parent, GWEN_XML_CONTEXT *ctx)
int HtmlCtx_SanitizeData(GWEN_UNUSED GWEN_XML_CONTEXT *ctx, const char *data, GWEN_BUFFER *buf)
Definition: htmlctx.c:300
void HtmlGroup_SetProperties(HTML_GROUP *g, HTML_PROPS *pr)
Definition: htmlgroup.c:112
HTML_GROUP * HtmlGroup_Generic_new(const char *groupName, HTML_GROUP *parent, GWEN_XML_CONTEXT *ctx)
Definition: g_generic.c:26
uint32_t HtmlFont_GetFontFlags(const HTML_FONT *fnt)
Definition: htmlfont.c:107
struct GWEN_XML_CONTEXT GWEN_XML_CONTEXT
Definition: xmlctx.h:39
struct HTML_OBJECT HTML_OBJECT
Definition: htmlobject_be.h:25