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
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
15
16 #define DISABLE_DEBUGLOG
17
18
19 #include "htmlctx_p.h"
20 #include "o_box_l.h"
21 #include "g_box_l.h"
22
23 #include <gwenhywfar/misc.h>
24 #include <gwenhywfar/debug.h>
25 #include <gwenhywfar/text.h>
26
27
28
GWEN_INHERIT(GWEN_XML_CONTEXT,HTML_XMLCTX)29 GWEN_INHERIT(GWEN_XML_CONTEXT, HTML_XMLCTX)
30
31
32
33
34 GWEN_XML_CONTEXT *HtmlCtx_new(uint32_t flags)
35 {
36 GWEN_XML_CONTEXT *ctx;
37 HTML_XMLCTX *xctx;
38 HTML_GROUP *g;
39 HTML_OBJECT *o;
40
41 /* create base object */
42 ctx=GWEN_XmlCtx_new(flags);
43 assert(ctx);
44
45 /* create and assign extension */
46 GWEN_NEW_OBJECT(HTML_XMLCTX, xctx);
47 assert(xctx);
48 GWEN_INHERIT_SETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx, xctx,
49 HtmlCtx_FreeData);
50
51 /* set virtual functions */
52 GWEN_XmlCtx_SetStartTagFn(ctx, HtmlCtx_StartTag);
53 GWEN_XmlCtx_SetEndTagFn(ctx, HtmlCtx_EndTag);
54 GWEN_XmlCtx_SetAddDataFn(ctx, HtmlCtx_AddData);
55 GWEN_XmlCtx_SetAddCommentFn(ctx, HtmlCtx_AddComment);
56 GWEN_XmlCtx_SetAddAttrFn(ctx, HtmlCtx_AddAttr);
57
58 xctx->objects=HtmlObject_Tree_new();
59 xctx->mediaPaths=GWEN_StringList_new();
60
61 xctx->resolutionX=75;
62 xctx->resolutionY=75;
63
64 /* create initial group */
65 g=HtmlGroup_Box_new("HTML_ROOT", NULL, ctx);
66 assert(g);
67 o=HtmlObject_Box_new(ctx);
68 HtmlGroup_SetObject(g, o);
69 HtmlObject_Tree_Add(xctx->objects, o);
70 HtmlCtx_SetCurrentGroup(ctx, g);
71
72 /* return base object */
73 return ctx;
74 }
75
76
77
78 GWENHYWFAR_CB
HtmlCtx_FreeData(GWEN_UNUSED void * bp,void * p)79 void HtmlCtx_FreeData(GWEN_UNUSED void *bp, void *p)
80 {
81 HTML_XMLCTX *xctx;
82 HTML_GROUP *g;
83
84 xctx=(HTML_XMLCTX *)p;
85
86 g=xctx->currentGroup;
87 while (g) {
88 HTML_GROUP *gParent;
89
90 gParent=HtmlGroup_GetParent(g);
91 HtmlGroup_free(g);
92 g=gParent;
93 }
94
95 GWEN_DB_Group_free(xctx->dbCurrentAttribs);
96 free(xctx->currentTagName);
97 HtmlObject_Tree_free(xctx->objects);
98
99 GWEN_StringList_free(xctx->mediaPaths);
100
101 HtmlProps_free(xctx->standardProps);
102
103 GWEN_FREE_OBJECT(xctx);
104 }
105
106
107
HtmlCtx_GetResolutionX(const GWEN_XML_CONTEXT * ctx)108 int HtmlCtx_GetResolutionX(const GWEN_XML_CONTEXT *ctx)
109 {
110 HTML_XMLCTX *xctx;
111
112 assert(ctx);
113 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
114 assert(xctx);
115
116 return xctx->resolutionX;
117 }
118
119
120
HtmlCtx_SetResolutionX(GWEN_XML_CONTEXT * ctx,int i)121 void HtmlCtx_SetResolutionX(GWEN_XML_CONTEXT *ctx, int i)
122 {
123 HTML_XMLCTX *xctx;
124
125 assert(ctx);
126 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
127 assert(xctx);
128
129 xctx->resolutionX=i;
130 }
131
132
133
HtmlCtx_GetResolutionY(const GWEN_XML_CONTEXT * ctx)134 int HtmlCtx_GetResolutionY(const GWEN_XML_CONTEXT *ctx)
135 {
136 HTML_XMLCTX *xctx;
137
138 assert(ctx);
139 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
140 assert(xctx);
141
142 return xctx->resolutionY;
143 }
144
145
146
HtmlCtx_SetResolutionY(GWEN_XML_CONTEXT * ctx,int i)147 void HtmlCtx_SetResolutionY(GWEN_XML_CONTEXT *ctx, int i)
148 {
149 HTML_XMLCTX *xctx;
150
151 assert(ctx);
152 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
153 assert(xctx);
154
155 xctx->resolutionY=i;
156 }
157
158
159
HtmlCtx_GetMediaPaths(const GWEN_XML_CONTEXT * ctx)160 GWEN_STRINGLIST *HtmlCtx_GetMediaPaths(const GWEN_XML_CONTEXT *ctx)
161 {
162 HTML_XMLCTX *xctx;
163
164 assert(ctx);
165 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
166 assert(xctx);
167
168 return xctx->mediaPaths;
169 }
170
171
172
HtmlCtx_AddMediaPath(GWEN_XML_CONTEXT * ctx,const char * s)173 void HtmlCtx_AddMediaPath(GWEN_XML_CONTEXT *ctx, const char *s)
174 {
175 HTML_XMLCTX *xctx;
176
177 assert(ctx);
178 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
179 assert(xctx);
180
181 assert(s && *s);
182 GWEN_StringList_AppendString(xctx->mediaPaths, s, 0, 1);
183 }
184
185
186
187
HtmlCtx_GetCurrentGroup(const GWEN_XML_CONTEXT * ctx)188 HTML_GROUP *HtmlCtx_GetCurrentGroup(const GWEN_XML_CONTEXT *ctx)
189 {
190 HTML_XMLCTX *xctx;
191
192 assert(ctx);
193 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
194 assert(xctx);
195
196 return xctx->currentGroup;
197 }
198
199
200
HtmlCtx_SetCurrentGroup(GWEN_XML_CONTEXT * ctx,HTML_GROUP * g)201 void HtmlCtx_SetCurrentGroup(GWEN_XML_CONTEXT *ctx, HTML_GROUP *g)
202 {
203 HTML_XMLCTX *xctx;
204
205 assert(ctx);
206 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
207 assert(xctx);
208
209 xctx->currentGroup=g;
210 }
211
212
213
HtmlCtx_GetCurrentTagName(const GWEN_XML_CONTEXT * ctx)214 const char *HtmlCtx_GetCurrentTagName(const GWEN_XML_CONTEXT *ctx)
215 {
216 HTML_XMLCTX *xctx;
217
218 assert(ctx);
219 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
220 assert(xctx);
221
222 return xctx->currentTagName;
223 }
224
225
226
HtmlCtx_SetCurrentTagName(GWEN_XML_CONTEXT * ctx,const char * s)227 void HtmlCtx_SetCurrentTagName(GWEN_XML_CONTEXT *ctx, const char *s)
228 {
229 HTML_XMLCTX *xctx;
230
231 assert(ctx);
232 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
233 assert(xctx);
234
235 free(xctx->currentTagName);
236 if (s)
237 xctx->currentTagName=strdup(s);
238 else
239 xctx->currentTagName=NULL;
240 }
241
242
243
HtmlCtx_GetCurrentAttributes(const GWEN_XML_CONTEXT * ctx)244 GWEN_DB_NODE *HtmlCtx_GetCurrentAttributes(const GWEN_XML_CONTEXT *ctx)
245 {
246 HTML_XMLCTX *xctx;
247
248 assert(ctx);
249 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
250 assert(xctx);
251
252 return xctx->dbCurrentAttribs;
253 }
254
255
256
HtmlCtx_GetObjects(const GWEN_XML_CONTEXT * ctx)257 HTML_OBJECT_TREE *HtmlCtx_GetObjects(const GWEN_XML_CONTEXT *ctx)
258 {
259 HTML_XMLCTX *xctx;
260
261 assert(ctx);
262 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
263 assert(xctx);
264
265 return xctx->objects;
266 }
267
268
269
HtmlCtx_TakeObjects(const GWEN_XML_CONTEXT * ctx)270 HTML_OBJECT_TREE *HtmlCtx_TakeObjects(const GWEN_XML_CONTEXT *ctx)
271 {
272 HTML_XMLCTX *xctx;
273 HTML_OBJECT_TREE *t;
274
275 assert(ctx);
276 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
277 assert(xctx);
278
279 t=xctx->objects;
280 xctx->objects=NULL;
281
282 return t;
283 }
284
285
286
HtmlCtx_GetRootObject(const GWEN_XML_CONTEXT * ctx)287 HTML_OBJECT *HtmlCtx_GetRootObject(const GWEN_XML_CONTEXT *ctx)
288 {
289 HTML_XMLCTX *xctx;
290
291 assert(ctx);
292 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
293 assert(xctx);
294
295 return HtmlObject_Tree_GetFirst(xctx->objects);
296 }
297
298
299
HtmlCtx_SanitizeData(GWEN_UNUSED GWEN_XML_CONTEXT * ctx,const char * data,GWEN_BUFFER * buf)300 int HtmlCtx_SanitizeData(GWEN_UNUSED GWEN_XML_CONTEXT *ctx,
301 const char *data,
302 GWEN_BUFFER *buf)
303 {
304 if (data && *data) {
305 const uint8_t *p;
306 uint8_t *dst;
307 uint8_t *src;
308 unsigned int size;
309 unsigned int i;
310 int lastWasBlank;
311 uint8_t *lastBlankPos;
312 uint32_t bStart=0;
313
314 if (GWEN_Text_UnescapeXmlToBuffer(data, buf)) {
315 DBG_INFO(GWEN_LOGDOMAIN, "here");
316 return GWEN_ERROR_BAD_DATA;
317 }
318 if (GWEN_Buffer_GetUsedBytes(buf)==0) {
319 DBG_INFO(GWEN_LOGDOMAIN, "Empty data.");
320 return 0;
321 }
322
323 dst=(uint8_t *)GWEN_Buffer_GetStart(buf);
324 src=dst;
325
326 /* skip leading blanks */
327 while (*src && (*src<33 || *src==127))
328 src++;
329
330 p=src;
331 bStart=src-((uint8_t *)GWEN_Buffer_GetStart(buf));
332 size=GWEN_Buffer_GetUsedBytes(buf)-bStart;
333 lastWasBlank=0;
334 lastBlankPos=0;
335
336 for (i=0; i<size; i++) {
337 uint8_t c;
338
339 c=*p;
340 if (c<32 || c==127)
341 c=32;
342
343 /* remember next loop whether this char was a blank */
344 if (c==32) {
345 if (!lastWasBlank) {
346 /* store only one blank */
347 lastWasBlank=1;
348 lastBlankPos=dst;
349 *(dst++)=c;
350 }
351 }
352 else {
353 lastWasBlank=0;
354 lastBlankPos=0;
355 *(dst++)=c;
356 }
357 p++;
358 }
359
360 /* remove trailing blanks */
361 if (lastBlankPos!=0)
362 dst=lastBlankPos;
363
364 size=dst-(uint8_t *)GWEN_Buffer_GetStart(buf);
365 GWEN_Buffer_Crop(buf, 0, size);
366 }
367
368 return 0;
369 }
370
371
372
HtmlCtx_GetStandardProps(const GWEN_XML_CONTEXT * ctx)373 HTML_PROPS *HtmlCtx_GetStandardProps(const GWEN_XML_CONTEXT *ctx)
374 {
375 HTML_XMLCTX *xctx;
376
377 assert(ctx);
378 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
379 assert(xctx);
380
381 return xctx->standardProps;
382 }
383
384
385
HtmlCtx_SetStandardProps(GWEN_XML_CONTEXT * ctx,HTML_PROPS * pr)386 void HtmlCtx_SetStandardProps(GWEN_XML_CONTEXT *ctx, HTML_PROPS *pr)
387 {
388 HTML_XMLCTX *xctx;
389 HTML_OBJECT *o;
390
391 assert(ctx);
392 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
393 assert(xctx);
394
395 HtmlProps_Attach(pr);
396 HtmlProps_free(xctx->standardProps);
397 xctx->standardProps=pr;
398
399 if (pr) {
400 if (xctx->currentGroup && HtmlGroup_GetParent(xctx->currentGroup)==NULL)
401 HtmlGroup_SetProperties(xctx->currentGroup, pr);
402 o=HtmlObject_Tree_GetFirst(xctx->objects);
403 if (o && HtmlObject_GetProperties(o)==NULL)
404 HtmlObject_SetProperties(o, pr);
405 }
406 }
407
408
409
HtmlCtx_StartTag(GWEN_XML_CONTEXT * ctx,const char * tagName)410 int HtmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
411 {
412 HTML_XMLCTX *xctx;
413
414 assert(ctx);
415 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
416 assert(xctx);
417
418 DBG_DEBUG(GWEN_LOGDOMAIN, "Starting tag [%s]", tagName);
419
420 /* store for later, do nothing more here */
421 HtmlCtx_SetCurrentTagName(ctx, tagName);
422 GWEN_DB_Group_free(xctx->dbCurrentAttribs);
423 xctx->dbCurrentAttribs=GWEN_DB_Group_new("attribs");
424
425 return 0;
426 }
427
428
429
HtmlCtx_EndTag(GWEN_XML_CONTEXT * ctx,int closing)430 int HtmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
431 {
432 HTML_XMLCTX *xctx;
433
434 assert(ctx);
435 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
436 assert(xctx);
437
438 if (closing) {
439 /* just ignore empty tags which are closed immediately */
440 DBG_DEBUG(GWEN_LOGDOMAIN, "Closing empty tag [%s]",
441 (xctx->currentTagName)?xctx->currentTagName:"<noname>");
442 return 0;
443 }
444
445 if (xctx->currentTagName==NULL) {
446 DBG_INFO(GWEN_LOGDOMAIN, "No tag name, malformed HTML data");
447 return GWEN_ERROR_BAD_DATA;
448 }
449
450 DBG_DEBUG(GWEN_LOGDOMAIN, "Completed tag [%s]", xctx->currentTagName);
451
452 if (xctx->currentGroup) {
453 if (*(xctx->currentTagName)=='/') {
454 int rv;
455
456 /* it is a closing tag, call EndTagFn */
457 DBG_DEBUG(GWEN_LOGDOMAIN,
458 "Calling %s->EndTag(%s)",
459 HtmlGroup_GetGroupName(xctx->currentGroup),
460 xctx->currentTagName);
461 rv=HtmlGroup_EndTag(xctx->currentGroup, xctx->currentTagName+1);
462 if (rv<0) {
463 if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
464 DBG_INFO(GWEN_LOGDOMAIN,
465 "Error in EndTag(%s) for [%s]",
466 HtmlGroup_GetGroupName(xctx->currentGroup),
467 xctx->currentTagName);
468 return rv;
469 }
470 }
471 else if (rv==1) {
472 HTML_GROUP *g;
473 HTML_GROUP *gParent;
474
475 /* pop current group from stack */
476 g=xctx->currentGroup;
477 gParent=HtmlGroup_GetParent(g);
478 xctx->currentGroup=gParent;
479 if (gParent) {
480 DBG_DEBUG(GWEN_LOGDOMAIN,
481 "Calling %s->EndSubGroup(%s)",
482 HtmlGroup_GetGroupName(gParent),
483 HtmlGroup_GetGroupName(g));
484 HtmlGroup_EndSubGroup(gParent, g);
485 }
486 HtmlGroup_free(g);
487 GWEN_XmlCtx_DecDepth(ctx);
488 }
489 }
490 else {
491 int rv;
492
493 /* it is an opening tag, call StartTagFn */
494 DBG_DEBUG(GWEN_LOGDOMAIN,
495 "Calling %s->StartTag(%s)",
496 HtmlGroup_GetGroupName(xctx->currentGroup),
497 xctx->currentTagName);
498 rv=HtmlGroup_StartTag(xctx->currentGroup, xctx->currentTagName);
499 if (rv<0) {
500 if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
501 DBG_INFO(GWEN_LOGDOMAIN,
502 "Error in StartTag(%s) for [%s]",
503 HtmlGroup_GetGroupName(xctx->currentGroup),
504 xctx->currentTagName);
505 return rv;
506 }
507 }
508 }
509 }
510
511 return 0;
512 }
513
514
515
516
517
518
HtmlCtx_AddData(GWEN_XML_CONTEXT * ctx,const char * data)519 int HtmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
520 {
521 HTML_XMLCTX *xctx;
522
523 assert(ctx);
524 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
525 assert(xctx);
526
527 if (xctx->currentGroup) {
528 int rv;
529
530 DBG_DEBUG(GWEN_LOGDOMAIN,
531 "Calling %s->AddData()",
532 HtmlGroup_GetGroupName(xctx->currentGroup));
533 rv=HtmlGroup_AddData(xctx->currentGroup, data);
534 if (rv<0) {
535 if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
536 DBG_INFO(GWEN_LOGDOMAIN,
537 "Error in AddData(%s)",
538 HtmlGroup_GetGroupName(xctx->currentGroup));
539 return rv;
540 }
541 }
542 }
543
544 return 0;
545 }
546
547
548
HtmlCtx_AddComment(GWEN_XML_CONTEXT * ctx,GWEN_UNUSED const char * data)549 int HtmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, GWEN_UNUSED const char *data)
550 {
551 HTML_XMLCTX *xctx;
552
553 assert(ctx);
554 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
555 assert(xctx);
556
557 /* ignore comments */
558 return 0;
559 }
560
561
562
HtmlCtx_AddAttr(GWEN_XML_CONTEXT * ctx,const char * attrName,const char * attrData)563 int HtmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx,
564 const char *attrName,
565 const char *attrData)
566 {
567 HTML_XMLCTX *xctx;
568
569 assert(ctx);
570 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
571 assert(xctx);
572
573 if (xctx->currentGroup) {
574 assert(xctx->dbCurrentAttribs);
575 GWEN_DB_SetCharValue(xctx->dbCurrentAttribs,
576 GWEN_DB_FLAGS_DEFAULT,
577 attrName, attrData);
578 }
579
580 return 0;
581 }
582
583
584
HtmlCtx_GetTextWidth(GWEN_XML_CONTEXT * ctx,HTML_FONT * fnt,const char * s)585 int HtmlCtx_GetTextWidth(GWEN_XML_CONTEXT *ctx,
586 HTML_FONT *fnt,
587 const char *s)
588 {
589 HTML_XMLCTX *xctx;
590
591 assert(ctx);
592 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
593 assert(xctx);
594
595 if (xctx->getTextWidthFn)
596 return xctx->getTextWidthFn(ctx, fnt, s);
597 else
598 return -1;
599 }
600
601
602
HtmlCtx_GetTextHeight(GWEN_XML_CONTEXT * ctx,HTML_FONT * fnt,const char * s)603 int HtmlCtx_GetTextHeight(GWEN_XML_CONTEXT *ctx,
604 HTML_FONT *fnt,
605 const char *s)
606 {
607 HTML_XMLCTX *xctx;
608
609 assert(ctx);
610 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
611 assert(xctx);
612
613 if (xctx->getTextHeightFn)
614 return xctx->getTextHeightFn(ctx, fnt, s);
615 else
616 return -1;
617 }
618
619
620
HtmlCtx_GetColorFromName(const GWEN_XML_CONTEXT * ctx,const char * name)621 uint32_t HtmlCtx_GetColorFromName(const GWEN_XML_CONTEXT *ctx,
622 const char *name)
623 {
624 HTML_XMLCTX *xctx;
625
626 assert(ctx);
627 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
628 assert(xctx);
629
630 if (xctx->getColorFromNameFn)
631 return xctx->getColorFromNameFn(ctx, name);
632 else
633 return 0xffffffff;
634 }
635
636
637
HtmlCtx_GetFont(GWEN_XML_CONTEXT * ctx,const char * fontName,int fontSize,uint32_t fontFlags)638 HTML_FONT *HtmlCtx_GetFont(GWEN_XML_CONTEXT *ctx,
639 const char *fontName,
640 int fontSize,
641 uint32_t fontFlags)
642 {
643 HTML_XMLCTX *xctx;
644
645 assert(ctx);
646 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
647 assert(xctx);
648
649 if (xctx->getFontFn)
650 return xctx->getFontFn(ctx, fontName, fontSize, fontFlags);
651 else
652 return NULL;
653 }
654
655
656
HtmlCtx_GetImage(GWEN_XML_CONTEXT * ctx,const char * imageName)657 HTML_IMAGE *HtmlCtx_GetImage(GWEN_XML_CONTEXT *ctx, const char *imageName)
658 {
659 HTML_XMLCTX *xctx;
660
661 assert(ctx);
662 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
663 assert(xctx);
664
665 if (xctx->getImageFn)
666 return xctx->getImageFn(ctx, imageName);
667 else
668 return NULL;
669 }
670
671
672
HtmlCtx_SetGetTextWidthFn(GWEN_XML_CONTEXT * ctx,HTMLCTX_GET_TEXT_WIDTH_FN fn)673 HTMLCTX_GET_TEXT_WIDTH_FN HtmlCtx_SetGetTextWidthFn(GWEN_XML_CONTEXT *ctx,
674 HTMLCTX_GET_TEXT_WIDTH_FN fn)
675 {
676 HTML_XMLCTX *xctx;
677 HTMLCTX_GET_TEXT_WIDTH_FN of;
678
679 assert(ctx);
680 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
681 assert(xctx);
682
683 of=xctx->getTextWidthFn;
684 xctx->getTextWidthFn=fn;
685
686 return of;
687 }
688
689
690
HtmlCtx_SetGetTextHeightFn(GWEN_XML_CONTEXT * ctx,HTMLCTX_GET_TEXT_HEIGHT_FN fn)691 HTMLCTX_GET_TEXT_HEIGHT_FN HtmlCtx_SetGetTextHeightFn(GWEN_XML_CONTEXT *ctx,
692 HTMLCTX_GET_TEXT_HEIGHT_FN fn)
693 {
694 HTML_XMLCTX *xctx;
695 HTMLCTX_GET_TEXT_HEIGHT_FN of;
696
697 assert(ctx);
698 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
699 assert(xctx);
700
701 of=xctx->getTextHeightFn;
702 xctx->getTextHeightFn=fn;
703
704 return of;
705 }
706
707
708
HtmlCtx_SetGetColorFromNameFn(GWEN_XML_CONTEXT * ctx,HTMLCTX_GET_COLOR_FROM_NAME_FN fn)709 HTMLCTX_GET_COLOR_FROM_NAME_FN HtmlCtx_SetGetColorFromNameFn(GWEN_XML_CONTEXT *ctx,
710 HTMLCTX_GET_COLOR_FROM_NAME_FN fn)
711 {
712 HTML_XMLCTX *xctx;
713 HTMLCTX_GET_COLOR_FROM_NAME_FN of;
714
715 assert(ctx);
716 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
717 assert(xctx);
718
719 of=xctx->getColorFromNameFn;
720 xctx->getColorFromNameFn=fn;
721
722 return of;
723 }
724
725
726
HtmlCtx_SetGetFontFn(GWEN_XML_CONTEXT * ctx,HTMLCTX_GET_FONT_FN fn)727 HTMLCTX_GET_FONT_FN HtmlCtx_SetGetFontFn(GWEN_XML_CONTEXT *ctx, HTMLCTX_GET_FONT_FN fn)
728 {
729 HTML_XMLCTX *xctx;
730 HTMLCTX_GET_FONT_FN of;
731
732 assert(ctx);
733 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
734 assert(xctx);
735
736 of=xctx->getFontFn;
737 xctx->getFontFn=fn;
738
739 return of;
740 }
741
742
743
HtmlCtx_SetGetImageFn(GWEN_XML_CONTEXT * ctx,HTMLCTX_GET_IMAGE_FN fn)744 HTMLCTX_GET_IMAGE_FN HtmlCtx_SetGetImageFn(GWEN_XML_CONTEXT *ctx, HTMLCTX_GET_IMAGE_FN fn)
745 {
746 HTML_XMLCTX *xctx;
747 HTMLCTX_GET_IMAGE_FN of;
748
749 assert(ctx);
750 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
751 assert(xctx);
752
753 of=xctx->getImageFn;
754 xctx->getImageFn=fn;
755
756 return of;
757 }
758
759
760
HtmlCtx_Layout(GWEN_XML_CONTEXT * ctx,int width,int height)761 int HtmlCtx_Layout(GWEN_XML_CONTEXT *ctx, int width, int height)
762 {
763 HTML_XMLCTX *xctx;
764 HTML_OBJECT *o;
765 int rv;
766
767 assert(ctx);
768 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
769 assert(xctx);
770
771 o=HtmlObject_Tree_GetFirst(xctx->objects);
772 if (o==NULL) {
773 DBG_ERROR(GWEN_LOGDOMAIN, "No objects");
774 return 0;
775 }
776
777 HtmlObject_SetWidth(o, width);
778 HtmlObject_SetHeight(o, height);
779 rv=HtmlObject_Layout(o);
780 if (rv<0) {
781 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
782 return rv;
783 }
784
785 return 0;
786 }
787
788
789
HtmlCtx_SetText(GWEN_XML_CONTEXT * ctx,const char * s)790 void HtmlCtx_SetText(GWEN_XML_CONTEXT *ctx, const char *s)
791 {
792 HTML_XMLCTX *xctx;
793 int rv;
794 HTML_GROUP *g;
795 HTML_OBJECT *o;
796
797 assert(ctx);
798 xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, HTML_XMLCTX, ctx);
799 assert(xctx);
800
801 /* reset */
802 HtmlObject_Tree_Clear(xctx->objects);
803
804 /* create initial group */
805 g=HtmlGroup_Box_new("HTML_ROOT", NULL, ctx);
806 assert(g);
807
808 HtmlGroup_SetProperties(g, xctx->standardProps);
809 o=HtmlObject_Box_new(ctx);
810 HtmlObject_SetProperties(o, xctx->standardProps);
811 HtmlGroup_SetObject(g, o);
812 HtmlObject_Tree_Add(xctx->objects, o);
813 HtmlCtx_SetCurrentGroup(ctx, g);
814
815 if (s && *s) {
816 rv=GWEN_XMLContext_ReadFromString(ctx, s);
817 if (rv<0) {
818 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
819 }
820 }
821
822 #if 0
823 fprintf(stderr, "============ Objects:\n");
824 fprintf(stderr, "String: [%s]\n", s);
825 o=HtmlObject_Tree_GetFirst(xctx->objects);
826 while (o) {
827 const char *xx;
828
829 xx=HtmlObject_GetText(o);
830 fprintf(stderr, "Object(%d): [%s]\n",
831 HtmlObject_GetObjectType(o),
832 xx?xx:"(NULL)");
833 o=HtmlObject_Tree_GetBelow(o);
834 }
835 #endif
836 }
837
838
839
HtmlCtx_GetWidth(const GWEN_XML_CONTEXT * ctx)840 int HtmlCtx_GetWidth(const GWEN_XML_CONTEXT *ctx)
841 {
842 HTML_OBJECT *o;
843
844 o=HtmlCtx_GetRootObject(ctx);
845 if (o)
846 return HtmlObject_GetWidth(o);
847 else
848 return -1;
849 }
850
851
852
HtmlCtx_GetHeight(const GWEN_XML_CONTEXT * ctx)853 int HtmlCtx_GetHeight(const GWEN_XML_CONTEXT *ctx)
854 {
855 HTML_OBJECT *o;
856
857 o=HtmlCtx_GetRootObject(ctx);
858 if (o)
859 return HtmlObject_GetHeight(o);
860 else
861 return -1;
862 }
863
864
865