39 SHtmlStyle_t TGHtml::GetCurrentStyle()
44 style = fStyleStack->fStyle;
46 style.fFont = NormalFont(2);
47 style.fColor = COLOR_Normal;
48 style.fBgcolor = COLOR_Background;
50 style.fAlign = ALIGN_Left;
64 void TGHtml::PushStyleStack(
int tag, SHtmlStyle_t style)
68 p =
new SHtmlStyleStack_t;
69 p->fPNext = fStyleStack;
85 SHtmlStyle_t TGHtml::PopStyleStack(
int tag)
89 static Html_u8_t priority[Html_TypeCount+1];
91 if (priority[Html_TABLE] == 0) {
92 for (i = 0; i <= Html_TypeCount; i++) priority[i] = 1;
93 priority[Html_TD] = 2;
94 priority[Html_EndTD] = 2;
95 priority[Html_TH] = 2;
96 priority[Html_EndTH] = 2;
97 priority[Html_TR] = 3;
98 priority[Html_EndTR] = 3;
99 priority[Html_TABLE] = 4;
100 priority[Html_EndTABLE] = 4;
102 if (tag <= 0 || tag > Html_TypeCount) {
104 return GetCurrentStyle();
106 while ((p = fStyleStack) != 0) {
108 if (type <= 0 || type > Html_TypeCount) {
110 return GetCurrentStyle();
112 if (type != tag && priority[type] > priority[tag]) {
113 return GetCurrentStyle();
115 fStyleStack = p->fPNext;
117 if (type == tag)
break;
120 return GetCurrentStyle();
126 static void ScaleFont(SHtmlStyle_t *pStyle,
int delta)
128 int size = FontSize(pStyle->fFont) + delta;
132 }
else if (size > 6) {
136 pStyle->fFont += delta;
142 void TGHtml::MakeInvisible(TGHtmlElement *p_first, TGHtmlElement *p_last)
144 if (p_first == 0)
return;
145 p_first = p_first->fPNext;
146 while (p_first && p_first != p_last) {
147 p_first->fStyle.fFlags |= STY_Invisible;
148 p_first = p_first->fPNext;
157 int TGHtml::GetLinkColor(
const char *zURL)
159 return IsVisited(zURL) ? COLOR_Visited : COLOR_Unvisited;
165 static int *GetCoords(
const char *str,
int *nptr)
167 const char *cp = str;
169 int *cr, i, n = 0, sz = 4;
173 while (*cp && (!isdigit(*cp))) cp++;
174 if ((!*cp) || (!isdigit(*cp)))
break;
175 cr[n] = (int) strtol(cp, &ncp, 10);
176 if (cp == ncp)
break;
180 int *tmp =
new int[sz+4];
181 for (i = 0; i < sz; ++i) tmp[i] = cr[i];
214 void TGHtml::AddStyle(TGHtmlElement *p)
221 SHtmlStyle_t nextStyle;
222 int useNextStyle = 0;
226 static int header_sizes[] = { +2, +1, 1, 1, -1, -1 };
229 if (fFlags & STYLER_RUNNING)
return;
230 fFlags |= STYLER_RUNNING;
235 style = GetCurrentStyle();
237 paraAlign = fParaAlignment;
238 rowAlign = fRowAlignment;
241 while (fPFirst && p) {
245 style = PopStyleStack(Html_EndA);
249 z = p->MarkupArg(
"href", 0);
251 style.fColor = GetLinkColor(z);
252 if (fUnderlineLinks) style.fFlags |= STY_Underline;
253 fAnchorFlags |= STY_Anchor;
254 PushStyleStack(Html_EndA, style);
255 fAnchorStart = (TGHtmlAnchor *) p;
261 ((TGHtmlRef *)p)->fPOther = fAnchorStart;
262 style = PopStyleStack(Html_EndA);
275 TGHtmlMapArea *area = (TGHtmlMapArea *) p;
276 z = p->MarkupArg(
"shape", 0);
277 area->fMType = HTML_MAP_RECT;
279 if (strcasecmp(z,
"circle") == 0) {
280 area->fMType = HTML_MAP_CIRCLE;
281 }
else if (strcasecmp(z,
"poly") == 0) {
282 area->fMType = HTML_MAP_POLY;
285 z = p->MarkupArg(
"coords", 0);
287 area->fCoords = GetCoords(z, &area->fNum);
293 case Html_EndADDRESS:
294 case Html_BLOCKQUOTE:
295 case Html_EndBLOCKQUOTE:
296 paraAlign = ALIGN_None;
302 nextStyle.fFlags |= STY_Invisible;
303 PushStyleStack(Html_EndAPPLET, nextStyle);
306 PushStyleStack(Html_EndAPPLET, style);
311 style.fFont = BoldFont(style.fFont);
312 PushStyleStack(Html_EndB, style);
316 z = p->MarkupArg(
"text", 0);
319 fApColor[COLOR_Normal] = AllocColor(z);
321 z = p->MarkupArg(
"bgcolor", 0);
324 fApColor[COLOR_Background] = AllocColor(z);
325 SetBackgroundColor(fApColor[COLOR_Background]->fPixel);
326 SetBackgroundPixmap(0);
328 z = p->MarkupArg(
"link", 0);
331 fApColor[COLOR_Unvisited] = AllocColor(z);
333 z = p->MarkupArg(
"vlink", 0);
336 fApColor[COLOR_Visited] = AllocColor(z);
338 z = p->MarkupArg(
"alink", 0);
341 z = p->MarkupArg(
"background", 0);
345 TImage *img = LoadImage(z, 0, 0);
348 SetupBackgroundPic(img->GetPicture());
354 gcv.fTile = img->GetPixmap();
355 gcv.fFillStyle = kFillTiled;
356 gcv.fGraphicsExposures = kTRUE;
357 fCanvas->SetBackgroundPixmap(img->GetPixmap());
359 gVirtualX->ChangeGC(fWhiteGC.GetGC(), &gcv);
379 case Html_EndCOMMENT:
385 case Html_EndMARQUEE:
387 case Html_EndNOFRAMES:
388 case Html_EndNOSCRIPT:
389 case Html_EndNOEMBED:
401 style = PopStyleStack(p->fType);
405 z = p->MarkupArg(
"href", 0);
407 char *z1 = ResolveUri(z);
409 if (fZBaseHref)
delete[] fZBaseHref;
416 paraAlign = ALIGN_None;
417 style = PopStyleStack(p->fType);
420 case Html_EndBASEFONT:
421 style = PopStyleStack(Html_EndBASEFONT);
422 style.fFont = FontFamily(style.fFont) + 2;
426 ScaleFont(&style, 1);
427 PushStyleStack(Html_EndBIG, style);
431 paraAlign = p->GetAlignment(paraAlign);
434 case Html_EndCAPTION:
435 paraAlign = ALIGN_None;
439 paraAlign = ALIGN_None;
440 style.fAlign = ALIGN_Center;
441 PushStyleStack(Html_EndCENTER, style);
445 style.fFont = ItalicFont(style.fFont);
446 PushStyleStack(Html_EndCITE, style);
450 style.fFont = CWFont(style.fFont);
451 PushStyleStack(Html_EndCODE, style);
455 style.fFlags |= STY_Invisible;
456 PushStyleStack(Html_EndCOMMENT, style);
460 if (fInnerList && fInnerList->fType == Html_DL) {
461 ((TGHtmlRef *)p)->fPOther = fInnerList;
463 ((TGHtmlRef *)p)->fPOther = 0;
469 style.fFont = ItalicFont(style.fFont);
470 PushStyleStack(Html_EndDFN, style);
476 TGHtmlListStart *list = (TGHtmlListStart *) p;
477 list->fLPrev = fInnerList;
480 if (list->fLPrev == 0) {
481 list->fLtype = LI_TYPE_Bullet1;
482 list->fCompact = (list->MarkupArg(
"compact", 0) != 0);
483 }
else if (list->fLPrev->fLPrev == 0) {
484 list->fLtype = LI_TYPE_Bullet2;
487 list->fLtype = LI_TYPE_Bullet3;
490 list->fLtype = list->GetUnorderedListType(list->fLtype);
501 ((TGHtmlRef *)p)->fPOther = fInnerList;
502 if (fInnerList) fInnerList = fInnerList->fLPrev;
506 paraAlign = ALIGN_None;
507 style.fAlign = p->GetAlignment(style.fAlign);
508 PushStyleStack(Html_EndDIV, style);
512 if (fInnerList && fInnerList->fType == Html_DL) {
513 ((TGHtmlRef *)p)->fPOther = fInnerList;
515 ((TGHtmlRef *)p)->fPOther = 0;
526 TGHtmlListStart *list = (TGHtmlListStart *) p;
527 list->fLPrev = fInnerList;
530 list->fCompact = (list->MarkupArg(
"compact", 0) != 0);
536 style.fFont = ItalicFont(style.fFont);
537 PushStyleStack(Html_EndEM, style);
545 z = p->MarkupArg(
"size", 0);
546 if (z && !fOverrideFonts) {
548 size = FontSize(style.fFont) - atoi(&z[1]) +1;
549 }
else if (*z ==
'+') {
550 size = FontSize(style.fFont) + atoi(&z[1]) +1;
554 if (size <= 0) size = 1;
555 if (size >= N_FONT_SIZE) size = N_FONT_SIZE - 1;
556 style.fFont = FontFamily(style.fFont) + size - 1;
558 z = p->MarkupArg(
"color", 0);
559 if (z && *z && !fOverrideColors) style.fColor = GetColorByName(z);
560 PushStyleStack(p->fType == Html_FONT ?
561 Html_EndFONT : Html_EndBASEFONT, style);
565 TGHtmlForm *form = (TGHtmlForm *) p;
576 zUrl = p->MarkupArg(
"action", 0);
577 if (zUrl == 0) zUrl = fZBase;
578 zUrl = ResolveUri(zUrl);
579 if (zUrl == 0) zUrl = StrDup(
"");
580 zMethod = p->MarkupArg(
"method",
"GET");
581 snprintf(zToken, 50,
" %d form ", form->fFormId);
588 AppendArglist(&cmd, (TGHtmlMarkupElement *) p);
590 FormCreate(form, zUrl, cmd.GetString());
599 ((TGHtmlRef *)p)->fPOther = fFormStart;
600 if (fFormStart) fFormStart->fPEnd = p;
610 if (!fInTr) paraAlign = ALIGN_None;
611 i = (p->fType - Html_H1) / 2 + 1;
612 if (i >= 1 && i <= 6) {
613 ScaleFont(&style, header_sizes[i-1]);
615 style.fFont = BoldFont(style.fFont);
616 style.fAlign = p->GetAlignment(style.fAlign);
617 PushStyleStack(Html_EndH1, style);
626 paraAlign = ALIGN_None;
627 style = PopStyleStack(Html_EndH1);
632 style.fAlign = p->GetAlignment(ALIGN_None);
637 style.fFont = ItalicFont(style.fFont);
638 PushStyleStack(Html_EndI, style);
642 if (style.fFlags & STY_Invisible)
break;
643 ((TGHtmlImageMarkup *)p)->fPImage = GetImage((TGHtmlImageMarkup *) p);
650 ((TGHtmlInput *)p)->fPForm = fFormStart;
655 style.fFont = CWFont(style.fFont);
656 PushStyleStack(Html_EndKBD, style);
661 TGHtmlLi *li = (TGHtmlLi *) p;
662 li->fLtype = fInnerList->fLtype;
663 if (fInnerList->fType == Html_OL) {
664 z = li->MarkupArg(
"value", 0);
669 fInnerList->fCnt = n+1;
672 li->fCnt = fInnerList->fCnt++;
674 li->fLtype = li->GetOrderedListType(li->fLtype);
676 li->fLtype = li->GetUnorderedListType(li->fLtype);
679 p->fFlags &= ~HTML_Visible;
684 style.fFlags |= STY_Invisible;
685 PushStyleStack(Html_EndMARQUEE, style);
689 style.fFlags |= STY_NoBreak;
690 PushStyleStack(Html_EndNOBR, style);
696 nextStyle.fFlags |= STY_Invisible;
697 PushStyleStack(Html_EndNOFRAMES, nextStyle);
700 PushStyleStack(Html_EndNOFRAMES, style);
707 nextStyle.fFlags |= STY_Invisible;
708 PushStyleStack(Html_EndNOEMBED, nextStyle);
711 PushStyleStack(Html_EndNOEMBED, style);
718 nextStyle.fFlags |= STY_Invisible;
719 PushStyleStack(Html_EndNOSCRIPT, nextStyle);
722 PushStyleStack(Html_EndNOSCRIPT, style);
727 TGHtmlListStart *list = (TGHtmlListStart *) p;
728 list->fLPrev = fInnerList;
729 list->fLtype = list->GetOrderedListType(LI_TYPE_Enum_1);
731 z = list->MarkupArg(
"start", 0);
734 if (n > 0) list->fCnt = n;
736 list->fCompact = (fInnerList != 0 || list->MarkupArg(
"compact", 0) != 0);
742 paraAlign = p->GetAlignment(ALIGN_None);
746 paraAlign = ALIGN_None;
753 paraAlign = ALIGN_None;
754 style.fFont = CWFont(style.fFont);
755 style.fFlags |= STY_Preformatted;
756 PushStyleStack(Html_EndPRE, style);
760 case Html_EndLISTING:
762 style = PopStyleStack(Html_EndPRE);
766 style.fFlags |= STY_StrikeThru;
767 PushStyleStack(Html_EndS, style);
772 result = ProcessScript((TGHtmlScript *) p);
774 TGHtmlElement *b2 = p->fPNext, *b3, *e1 = p, *e2 = b2, *e3;
775 if (e2)
while (e2->fPNext) e2 = e2->fPNext;
776 TokenizerAppend(result);
777 if (e2 && e2 != p && ((e3 = b3 = e2->fPNext))) {
778 while (e3->fPNext) e3 = e3->fPNext;
780 e2->fPNext = 0; b2->fPPrev = e3;
781 e3->fPNext = b2; b3->fPPrev = e1;
786 style.fFlags |= STY_Invisible;
792 ((TGHtmlInput *)p)->fPForm = fFormStart;
793 nextStyle.fFlags |= STY_Invisible;
795 PushStyleStack(Html_EndSELECT, style);
796 fFormElemStart = (TGHtmlInput *) p;
800 style = PopStyleStack(Html_EndSELECT);
801 if (fFormElemStart && fFormElemStart->fType == Html_SELECT) {
802 ((TGHtmlRef *)p)->fPOther = fFormElemStart;
803 MakeInvisible(((TGHtmlRef *)p)->fPOther, p);
805 ((TGHtmlRef *)p)->fPOther = 0;
811 style.fFlags |= STY_StrikeThru;
812 PushStyleStack(Html_EndSTRIKE, style);
820 style.fFont = CWFont(style.fFont);
821 PushStyleStack(Html_EndSAMP, style);
825 ScaleFont(&style, -1);
826 PushStyleStack(Html_EndSMALL, style);
830 style.fFont = BoldFont(style.fFont);
831 PushStyleStack(Html_EndSTRONG, style);
835 ScaleFont(&style, -1);
836 if (style.fSubscript > -6 ) style.fSubscript--;
837 PushStyleStack(Html_EndSUB, style);
841 ScaleFont(&style, -1);
842 if (style.fSubscript < 6) style.fSubscript++;
843 PushStyleStack(Html_EndSUP, style);
847 paraAlign = ALIGN_None;
849 if (style.fFlags & STY_Preformatted) {
850 nextStyle.fFlags &= ~STY_Preformatted;
851 style.fFlags |= STY_Preformatted;
853 nextStyle.fAlign = ALIGN_Left;
854 z = p->MarkupArg(
"bgcolor", 0);
855 if (z && *z && !fOverrideColors) {
856 style.fBgcolor = nextStyle.fBgcolor = GetColorByName(z);
862 PushStyleStack(Html_EndTABLE, nextStyle);
869 paraAlign = ALIGN_None;
871 style = PopStyleStack(Html_EndTD);
875 style = PopStyleStack(Html_EndTR);
878 style = PopStyleStack(p->fType);
882 if (fInTd) style = PopStyleStack(Html_EndTD);
884 paraAlign = p->GetAlignment(rowAlign);
885 z = p->MarkupArg(
"bgcolor", 0);
886 if (z && *z && !fOverrideColors) {
887 style.fBgcolor = GetColorByName(z);
891 PushStyleStack(Html_EndTD, style);
895 ((TGHtmlInput *)p)->fPForm = fFormStart;
897 nextStyle.fFlags |= STY_Invisible;
898 PushStyleStack(Html_EndTEXTAREA, nextStyle);
899 fFormElemStart = (TGHtmlInput *) p;
903 case Html_EndTEXTAREA:
904 style = PopStyleStack(Html_EndTEXTAREA);
905 if (fFormElemStart && fFormElemStart->fType == Html_TEXTAREA) {
906 ((TGHtmlRef *)p)->fPOther = fFormElemStart;
908 ((TGHtmlRef *)p)->fPOther = 0;
915 if (fInTd) style = PopStyleStack(Html_EndTD);
916 paraAlign = p->GetAlignment(ALIGN_Center);
917 style.fFont = BoldFont(style.fFont);
918 z = p->MarkupArg(
"bgcolor", 0);
919 if (z && *z && !fOverrideColors) {
920 style.fBgcolor = GetColorByName(z);
923 PushStyleStack(Html_EndTD, style);
929 style = PopStyleStack(Html_EndTD);
933 style = PopStyleStack(Html_EndTR);
935 rowAlign = p->GetAlignment(ALIGN_None);
936 z = p->MarkupArg(
"bgcolor", 0);
937 if (z && *z && !fOverrideColors) {
938 style.fBgcolor = GetColorByName(z);
942 PushStyleStack(Html_EndTR, style);
948 style = PopStyleStack(Html_EndTD);
951 style = PopStyleStack(Html_EndTR);
953 paraAlign = ALIGN_None;
954 rowAlign = ALIGN_None;
959 style = PopStyleStack(Html_EndTD);
961 paraAlign = ALIGN_None;
966 style.fFlags |= STY_Invisible;
967 PushStyleStack(Html_EndTITLE, style);
971 style.fFont = CWFont(style.fFont);
972 PushStyleStack(Html_EndTT, style);
976 style.fFlags |= STY_Underline;
977 PushStyleStack(Html_EndU, style);
981 style.fFont = ItalicFont(style.fFont);
982 PushStyleStack(Html_EndVAR, style);
990 p->fStyle.fFlags |= fAnchorFlags | fInDt;
991 if (paraAlign != ALIGN_None) {
992 p->fStyle.fAlign = paraAlign;
1000 TRACE(HtmlTrace_Style,
1001 (
"Style font=%02d color=%02d bg=%02d "
1002 "align=%d flags=0x%04x token=%s\n",
1003 p->fStyle.fFont, p->fStyle.fColor, p->fStyle.fBgcolor,
1004 p->fStyle.fAlign, p->fStyle.fFlags, DumpToken(p)));
1011 fParaAlignment = paraAlign;
1012 fRowAlignment = rowAlign;
1014 fFlags &= ~STYLER_RUNNING;
1020 void TGHtml::TableBgndImage(TGHtmlElement *p)
1024 z = p->MarkupArg(
"background", 0);
1027 char *z1 = ResolveUri(z);
1028 TImage *img = LoadImage(z1, 0, 0);
1033 TGHtmlTable *table = (TGHtmlTable *) p;
1034 if (table->fBgImage)
delete table->fBgImage;
1035 table->fBgImage = img;
1039 TGHtmlRef *ref = (TGHtmlRef *) p;
1040 if (ref->fBgImage)
delete ref->fBgImage;
1041 ref->fBgImage = img;
1046 TGHtmlCell *cell = (TGHtmlCell *) p;
1047 if (cell->fBgImage)
delete cell->fBgImage;
1048 cell->fBgImage = img;
1052 if (img)
delete img;
1074 void TGHtml::Sizer()
1080 FontMetrics_t fontMetrics;
1084 if (fPFirst == 0)
return;
1086 if (fLastSized == 0) {
1089 p = fLastSized->fPNext;
1093 for (; !stop && p; p = p ? p->fPNext : 0) {
1094 if (p->fStyle.fFlags & STY_Invisible) {
1095 p->fFlags &= ~HTML_Visible;
1098 if (iFont != (
int)p->fStyle.fFont) {
1099 iFont = p->fStyle.fFont;
1100 font = GetFont(iFont);
1101 font->GetFontMetrics(&fontMetrics);
1106 TGHtmlTextElement *text = (TGHtmlTextElement *) p;
1107 text->fW = font->TextWidth(text->fZText, p->fCount);
1108 p->fFlags |= HTML_Visible;
1109 text->fDescent = fontMetrics.fDescent;
1110 text->fAscent = fontMetrics.fAscent;
1111 if (spaceWidth == 0) spaceWidth = font->TextWidth(
" ", 1);
1112 text->fSpaceWidth = spaceWidth;
1117 TGHtmlSpaceElement *space = (TGHtmlSpaceElement *) p;
1118 if (spaceWidth == 0) spaceWidth = font->TextWidth(
" ", 1);
1119 space->fW = spaceWidth;
1120 space->fDescent = fontMetrics.fDescent;
1121 space->fAscent = fontMetrics.fAscent;
1122 p->fFlags &= ~HTML_Visible;
1128 TGHtmlCell *cell = (TGHtmlCell *) p;
1129 z = p->MarkupArg(
"rowspan",
"1");
1130 cell->fRowspan = z ? atoi(z) : 1;
1131 z = p->MarkupArg(
"colspan",
"1");
1132 cell->fColspan = z ? atoi(z) : 1;
1133 p->fFlags |= HTML_Visible;
1138 TGHtmlLi *li = (TGHtmlLi *) p;
1139 li->fDescent = fontMetrics.fDescent;
1140 li->fAscent = fontMetrics.fAscent;
1141 p->fFlags |= HTML_Visible;
1146 TGHtmlImageMarkup *image = (TGHtmlImageMarkup *) p;
1147 z = p->MarkupArg(
"usemap", 0);
1148 if (z && *z ==
'#') {
1149 image->fPMap = GetMap(z+1);
1153 p->fFlags |= HTML_Visible;
1154 image->fRedrawNeeded = 0;
1155 image->fTextAscent = fontMetrics.fAscent;
1156 image->fTextDescent = fontMetrics.fDescent;
1157 image->fAlign = GetImageAlignment(p);
1158 if (image->fPImage == 0) {
1159 image->fAscent = fontMetrics.fAscent;
1160 image->fDescent = fontMetrics.fDescent;
1161 image->fZAlt = p->MarkupArg(
"alt",
"<image>");
1162 if (image->fZAlt == 0) image->fZAlt =
"<image>";
1163 image->fW = font->TextWidth(image->fZAlt, strlen(image->fZAlt));
1166 image->fINext = image->fPImage->fPList;
1167 image->fPImage->fPList = image;
1168 w = image->fPImage->fImage->GetWidth();
1169 h = image->fPImage->fImage->GetHeight();
1172 image->fAscent = h / 2;
1173 image->fDescent = h - image->fAscent;
1175 if ((z = p->MarkupArg(
"width", 0)) != 0) {
1177 if (z[strlen(z)-1] ==
'%') w = 0;
1178 if (w > 0) image->fW = w;
1180 if ((z = p->MarkupArg(
"height", 0)) != 0) {
1182 if (h > 0) image->fH = h;
1186 if (image->fPImage == 0 && !*image->fZAlt) {
1187 image->fAscent = image->fH / 2;
1188 image->fDescent = image->fH - image->fAscent;
1195 p->fFlags |= HTML_Visible;
1199 p->fFlags |= HTML_Visible;
1205 TGHtmlInput *input = (TGHtmlInput *) p;
1206 input->fTextAscent = fontMetrics.fAscent;
1207 input->fTextDescent = fontMetrics.fDescent;
1208 stop = ControlSize(input);
1213 case Html_TEXTAREA: {
1214 TGHtmlInput *input = (TGHtmlInput *) p;
1215 input->fTextAscent = fontMetrics.fAscent;
1216 input->fTextDescent = fontMetrics.fDescent;
1220 case Html_EndSELECT:
1221 case Html_EndTEXTAREA: {
1222 TGHtmlRef *ref = (TGHtmlRef *) p;
1224 ((TGHtmlInput *)ref->fPOther)->fPEnd = p;
1225 stop = ControlSize((TGHtmlInput *) ref->fPOther);
1231 p->fFlags &= ~HTML_Visible;
1239 fLastSized = fPLast;