TGHtmlSizer.cxx

Go to the documentation of this file.
00001 // $Id: TGHtmlSizer.cxx,v 1.2 2007/05/04 20:33:16 rdm Exp $
00002 // Author:  Valeriy Onuchin   03/05/2007
00003 
00004 /**************************************************************************
00005 
00006     HTML widget for xclass. Based on tkhtml 1.28
00007     Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
00008     Copyright (C) 2002-2003 Hector Peraza.
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Library General Public
00012     License as published by the Free Software Foundation; either
00013     version 2 of the License, or (at your option) any later version.
00014 
00015     This library is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018     Library General Public License for more details.
00019 
00020     You should have received a copy of the GNU Library General Public
00021     License along with this library; if not, write to the Free
00022     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023 
00024 **************************************************************************/
00025 
00026 // Routines used to compute the style and size of individual elements.
00027 
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <ctype.h>
00031 
00032 #include "TGHtml.h"
00033 #include "TImage.h"
00034 
00035 //______________________________________________________________________________
00036 SHtmlStyle_t TGHtml::GetCurrentStyle()
00037 {
00038    // Get the current rendering style. In other words, get the style
00039    // that is currently on the top of the style stack.
00040 
00041    SHtmlStyle_t style;
00042 
00043    if (fStyleStack) {
00044       style = fStyleStack->fStyle;
00045    } else {
00046       style.fFont = NormalFont(2);
00047       style.fColor = COLOR_Normal;
00048       style.fBgcolor = COLOR_Background;
00049       style.fSubscript = 0;
00050       style.fAlign = ALIGN_Left;
00051       style.fFlags = 0;
00052       style.fExpbg = 0;
00053    }
00054 
00055    return style;
00056 }
00057 
00058 //______________________________________________________________________________
00059 void TGHtml::PushStyleStack(int tag, SHtmlStyle_t style)
00060 {
00061    // Push a new rendering style onto the stack.
00062    //
00063    //  tag   - Tag for this style. Normally the end-tag such as </h3> or </em>.
00064    //  style - The style to push
00065 
00066    SHtmlStyleStack_t *p;
00067 
00068    p = new SHtmlStyleStack_t;
00069    p->fPNext = fStyleStack;
00070    p->fType = tag;
00071    p->fStyle = style;
00072    fStyleStack = p;
00073 }
00074 
00075 //______________________________________________________________________________
00076 SHtmlStyle_t TGHtml::PopStyleStack(int tag)
00077 {
00078    // Pop a rendering style off of the stack.
00079    //
00080    // The top-most style on the stack should have a tag equal to "tag".
00081    // If not, then we have an HTML coding error.  Perhaps something
00082    // like this:  "Some text <em>Enphasized</i> more text".  It is an
00083    // interesting problem to figure out how to respond sanely to this
00084    // kind of error.  Our solution is to keep popping the stack until
00085    // we find the correct tag, or until the stack is empty.
00086 
00087    int i, type;
00088    SHtmlStyleStack_t *p;
00089    static Html_u8_t priority[Html_TypeCount+1];
00090 
00091    if (priority[Html_TABLE] == 0) {
00092       for (i = 0; i <= Html_TypeCount; i++) priority[i] = 1;
00093       priority[Html_TD] = 2;
00094       priority[Html_EndTD] = 2;
00095       priority[Html_TH] = 2;
00096       priority[Html_EndTH] = 2;
00097       priority[Html_TR] = 3;
00098       priority[Html_EndTR] = 3;
00099       priority[Html_TABLE] = 4;
00100       priority[Html_EndTABLE] = 4;
00101    }
00102    if (tag <= 0 || tag > Html_TypeCount) {
00103       CANT_HAPPEN;
00104       return GetCurrentStyle();
00105    }
00106    while ((p = fStyleStack) != 0) {
00107       type = p->fType;
00108       if (type <= 0 || type > Html_TypeCount) {
00109          CANT_HAPPEN;
00110          return GetCurrentStyle();
00111       }
00112       if (type != tag && priority[type] > priority[tag]) {
00113          return GetCurrentStyle();
00114       }
00115       fStyleStack = p->fPNext;
00116       delete p;
00117       if (type == tag) break;
00118    }
00119 
00120    return GetCurrentStyle();
00121 }
00122 
00123 //______________________________________________________________________________
00124 static void ScaleFont(SHtmlStyle_t *pStyle, int delta)
00125 {
00126    // Change the font size on the given style by the delta-amount given
00127 
00128    int size = FontSize(pStyle->fFont) + delta;
00129 
00130    if (size < 0) {
00131       delta -= size;
00132    } else if (size > 6) {
00133       delta -= size-6;
00134    }
00135 
00136    pStyle->fFont += delta;
00137 }
00138 
00139 //______________________________________________________________________________
00140 void TGHtml::MakeInvisible(TGHtmlElement *p_first, TGHtmlElement *p_last)
00141 {
00142    // Add the STY_Invisible style to every token between p_first and p_last.
00143 
00144    if (p_first == 0) return;
00145    p_first = p_first->fPNext;
00146    while (p_first && p_first != p_last) {
00147       p_first->fStyle.fFlags |= STY_Invisible;
00148       p_first = p_first->fPNext;
00149    }
00150 }
00151 
00152 //______________________________________________________________________________
00153 int TGHtml::GetLinkColor(const char *zURL)
00154 {
00155    // For the markup <a href=XXX>, find out if the URL has been visited
00156    // before or not.  Return COLOR_Visited or COLOR_Unvisited, as
00157    // appropriate.
00158 
00159    return IsVisited(zURL) ? COLOR_Visited : COLOR_Unvisited;
00160 }
00161 
00162 //______________________________________________________________________________
00163 static int *GetCoords(const char *str, int *nptr)
00164 {
00165    // Returns coordinates of string str.
00166 
00167    const char *cp = str;
00168    char *ncp;
00169    int  *cr, i, n = 0, sz = 4;
00170 
00171    cr = new int[sz];
00172    while (cp) {
00173       while (*cp && (!isdigit(*cp))) cp++;
00174       if ((!*cp) || (!isdigit(*cp))) break;
00175       cr[n] = (int) strtol(cp, &ncp, 10);
00176       if (cp == ncp) break;
00177       cp = ncp;
00178       n++;
00179       if (n >= sz) {
00180          int *tmp = new int[sz+4];
00181          for (i = 0; i < sz; ++i) tmp[i] = cr[i];
00182          delete[] cr;
00183          cr = tmp;
00184          sz += 4;
00185       }
00186    }
00187    *nptr = n;
00188 
00189    return cr;
00190 }
00191 
00192 //______________________________________________________________________________
00193 void TGHtml::AddStyle(TGHtmlElement *p)
00194 {
00195    // This routine adds information to the input texts that doesn't change
00196    // when the display is resized or when new fonts are selected, etc.
00197    // Mostly this means adding style attributes.  But other constant
00198    // information (such as numbering on <li> and images used for <IMG>)
00199    // is also obtained.  The key is that this routine is only called
00200    // once, where the sizer and layout routines can be called many times.
00201    //
00202    // This routine is called whenever the list of elements grows.  The
00203    // style stack is stored as part of the HTML widget so that we can
00204    // always continue where we left off the last time.
00205    //
00206    // In addition to adding style, this routine will invoke methods
00207    // needed to acquire information about a markup. The IsVisitied()
00208    // method is called for each <a> and the GetImage() is called
00209    // for each <IMG> or for each <LI> that has a SRC= field.
00210    //
00211    // When a markup is inserted or deleted from the token list, the
00212    // style routine must be completely rerun from the beginning.  So
00213    // what we said above, that this routine is only run once, is not
00214    // strictly true.
00215 
00216    SHtmlStyle_t style;       // Current style
00217    int size;                 // A new font size
00218    int i;                    // Loop counter
00219    int paraAlign;            // Current paragraph alignment
00220    int rowAlign;             // Current table row alignment
00221    SHtmlStyle_t nextStyle;   // Style for next token if useNextStyle==1
00222    int useNextStyle = 0;     // True if nextStyle is valid
00223    const char *z;            // A tag parameter's value
00224 
00225    // The size of header fonts relative to the current font size
00226    static int header_sizes[] = { +2, +1, 1, 1, -1, -1 };
00227 
00228    // Don't allow recursion
00229    if (fFlags & STYLER_RUNNING) return;
00230    fFlags |= STYLER_RUNNING;
00231 
00232    // Load the style state out of the TGHtml object and into local
00233    // variables. This is purely a matter of convenience...
00234 
00235    style = GetCurrentStyle();
00236    nextStyle = style;   //ia: nextStyle was not initialized
00237    paraAlign = fParaAlignment;
00238    rowAlign = fRowAlignment;
00239 
00240    // Loop over tokens
00241    while (fPFirst && p) {
00242       switch (p->fType) {
00243          case Html_A:
00244             if (fAnchorStart) {
00245                style = PopStyleStack(Html_EndA);
00246                fAnchorStart = 0;
00247                fAnchorFlags = 0;
00248             }
00249             z = p->MarkupArg("href", 0);
00250             if (z) {
00251                style.fColor = GetLinkColor(z);
00252                if (fUnderlineLinks) style.fFlags |= STY_Underline;
00253                fAnchorFlags |= STY_Anchor;
00254                PushStyleStack(Html_EndA, style);
00255                fAnchorStart = (TGHtmlAnchor *) p;
00256             }
00257             break;
00258 
00259          case Html_EndA:
00260             if (fAnchorStart) {
00261                ((TGHtmlRef *)p)->fPOther = fAnchorStart;
00262                style = PopStyleStack(Html_EndA);
00263                fAnchorStart = 0;
00264                fAnchorFlags = 0;
00265             }
00266             break;
00267 
00268          case Html_MAP:
00269          break;
00270 
00271          case Html_EndMAP:
00272          break;
00273 
00274          case Html_AREA: {
00275             TGHtmlMapArea *area = (TGHtmlMapArea *) p;
00276             z = p->MarkupArg("shape", 0);
00277             area->fMType = HTML_MAP_RECT;
00278             if (z) {
00279                if (strcasecmp(z, "circle") == 0) {
00280                   area->fMType = HTML_MAP_CIRCLE;
00281                } else if (strcasecmp(z,"poly") == 0) {
00282                   area->fMType = HTML_MAP_POLY;
00283                }
00284             }
00285             z = p->MarkupArg("coords", 0);
00286             if (z) {
00287                area->fCoords = GetCoords(z, &area->fNum);
00288             }
00289             break;
00290          }
00291 
00292          case Html_ADDRESS:
00293          case Html_EndADDRESS:
00294          case Html_BLOCKQUOTE:
00295          case Html_EndBLOCKQUOTE:
00296             paraAlign = ALIGN_None;
00297             break;
00298 
00299          case Html_APPLET:
00300             if (0 /* has ProcessApplet() */) {
00301                nextStyle = style;
00302                nextStyle.fFlags |= STY_Invisible;
00303                PushStyleStack(Html_EndAPPLET, nextStyle);
00304                useNextStyle = 1;
00305             } else {
00306                PushStyleStack(Html_EndAPPLET, style);
00307             }
00308             break;
00309 
00310          case Html_B:
00311             style.fFont = BoldFont(style.fFont);
00312             PushStyleStack(Html_EndB, style);
00313             break;
00314 
00315          case Html_BODY:
00316             z = p->MarkupArg("text", 0);
00317             if (z) {
00318                //FreeColor(fApColor[COLOR_Normal]);
00319                fApColor[COLOR_Normal] = AllocColor(z);
00320             }
00321             z = p->MarkupArg("bgcolor", 0);
00322             if (z) {
00323                //FreeColor(fApColor[COLOR_Background]);
00324                fApColor[COLOR_Background] = AllocColor(z);
00325                SetBackgroundColor(fApColor[COLOR_Background]->fPixel);
00326                SetBackgroundPixmap(0);
00327             }
00328             z = p->MarkupArg("link", 0);
00329             if (z) {
00330                //FreeColor(fApColor[COLOR_Unvisited]);
00331                fApColor[COLOR_Unvisited] = AllocColor(z);
00332             }
00333             z = p->MarkupArg("vlink", 0);
00334             if (z) {
00335                //FreeColor(fApColor[COLOR_Visited]);
00336                fApColor[COLOR_Visited] = AllocColor(z);
00337             }
00338             z = p->MarkupArg("alink", 0);
00339             if (z) {
00340             }
00341             z = p->MarkupArg("background", 0);
00342             if (z) {
00343                z = ResolveUri(z);
00344                if (z) {
00345                   TImage *img = LoadImage(z, 0, 0);
00346                   if (img) {
00347 #if 0
00348                      SetupBackgroundPic(img->GetPicture());
00349 #else
00350                      GCValues_t gcv;
00351                      unsigned int mask;
00352 
00353                      mask = kGCTile | kGCFillStyle | kGCGraphicsExposures;
00354                      gcv.fTile = img->GetPixmap();
00355                      gcv.fFillStyle = kFillTiled;
00356                      gcv.fGraphicsExposures = kTRUE;
00357                      fCanvas->SetBackgroundPixmap(img->GetPixmap());
00358 
00359                      gVirtualX->ChangeGC(fWhiteGC.GetGC(), &gcv);
00360 
00361                      //NeedRedraw(TGRectangle(fVisible, fCanvas->GetSize()));
00362 #endif
00363                      fBgImage = img;//delete img;
00364                   }
00365                   delete [] z;
00366                }
00367             }
00368             break;
00369 
00370          case Html_EndBODY:
00371             break;
00372 
00373          case Html_EndAPPLET:
00374          case Html_EndB:
00375          case Html_EndBIG:
00376          case Html_EndCENTER:
00377          case Html_EndCITE:
00378          case Html_EndCODE:
00379          case Html_EndCOMMENT:
00380          case Html_EndDFN:
00381          case Html_EndEM:
00382          case Html_EndFONT:
00383          case Html_EndI:
00384          case Html_EndKBD:
00385          case Html_EndMARQUEE:
00386          case Html_EndNOBR:
00387          case Html_EndNOFRAMES:
00388          case Html_EndNOSCRIPT:
00389          case Html_EndNOEMBED:
00390          case Html_EndS:
00391          case Html_EndSAMP:
00392          case Html_EndSMALL:
00393          case Html_EndSTRIKE:
00394          case Html_EndSTRONG:
00395          case Html_EndSUB:
00396          case Html_EndSUP:
00397          case Html_EndTITLE:
00398          case Html_EndTT:
00399          case Html_EndU:
00400          case Html_EndVAR:
00401             style = PopStyleStack(p->fType);
00402             break;
00403 
00404          case Html_BASE:
00405             z = p->MarkupArg("href", 0);
00406             if (z) {
00407                char *z1 = ResolveUri(z);
00408                if (z1 != 0) {
00409                   if (fZBaseHref) delete[] fZBaseHref;
00410                   fZBaseHref = z1;
00411                }
00412             }
00413             break;
00414 
00415          case Html_EndDIV:
00416             paraAlign = ALIGN_None;
00417             style = PopStyleStack(p->fType);
00418             break;
00419 
00420          case Html_EndBASEFONT:
00421             style = PopStyleStack(Html_EndBASEFONT);
00422             style.fFont = FontFamily(style.fFont) + 2;
00423             break;
00424 
00425          case Html_BIG:
00426             ScaleFont(&style, 1);
00427             PushStyleStack(Html_EndBIG, style);
00428             break;
00429 
00430          case Html_CAPTION:
00431             paraAlign = p->GetAlignment(paraAlign);
00432             break;
00433 
00434          case Html_EndCAPTION:
00435             paraAlign = ALIGN_None;
00436             break;
00437 
00438          case Html_CENTER:
00439             paraAlign = ALIGN_None;
00440             style.fAlign = ALIGN_Center;
00441             PushStyleStack(Html_EndCENTER, style);
00442             break;
00443 
00444          case Html_CITE:
00445             style.fFont = ItalicFont(style.fFont);
00446             PushStyleStack(Html_EndCITE, style);
00447             break;
00448 
00449          case Html_CODE:
00450             style.fFont = CWFont(style.fFont);
00451             PushStyleStack(Html_EndCODE, style);
00452             break;
00453 
00454          case Html_COMMENT:
00455             style.fFlags |= STY_Invisible;
00456             PushStyleStack(Html_EndCOMMENT, style);
00457             break;
00458 
00459          case Html_DD:
00460             if (fInnerList && fInnerList->fType == Html_DL) {
00461                ((TGHtmlRef *)p)->fPOther = fInnerList;
00462             } else {
00463                ((TGHtmlRef *)p)->fPOther = 0;
00464             }
00465             fInDt = 0;
00466             break;
00467 
00468          case Html_DFN:
00469             style.fFont = ItalicFont(style.fFont);
00470             PushStyleStack(Html_EndDFN, style);
00471             break;
00472 
00473          case Html_DIR:
00474          case Html_MENU:
00475          case Html_UL: {
00476             TGHtmlListStart *list = (TGHtmlListStart *) p;
00477             list->fLPrev = fInnerList;
00478             list->fCnt = 0;
00479             fInnerList = list;
00480             if (list->fLPrev == 0) {
00481                list->fLtype = LI_TYPE_Bullet1;
00482                list->fCompact = (list->MarkupArg("compact", 0) != 0);
00483             } else if (list->fLPrev->fLPrev == 0) {
00484                list->fLtype = LI_TYPE_Bullet2;
00485                list->fCompact = 1;
00486             } else {
00487                list->fLtype = LI_TYPE_Bullet3;
00488                list->fCompact = 1;
00489             }
00490             list->fLtype = list->GetUnorderedListType(list->fLtype);
00491             break;
00492          }
00493 
00494          case Html_EndDL:
00495             fInDt = 0;
00496             /* Fall thru into the next case */
00497          case Html_EndDIR:
00498          case Html_EndMENU:
00499          case Html_EndOL:
00500          case Html_EndUL:
00501             ((TGHtmlRef *)p)->fPOther = fInnerList;
00502             if (fInnerList) fInnerList = fInnerList->fLPrev;
00503             break;
00504 
00505          case Html_DIV:
00506             paraAlign = ALIGN_None;
00507             style.fAlign = p->GetAlignment(style.fAlign);
00508             PushStyleStack(Html_EndDIV, style);
00509             break;
00510 
00511          case Html_DT:
00512             if (fInnerList && fInnerList->fType == Html_DL) {
00513                ((TGHtmlRef *)p)->fPOther = fInnerList;
00514             } else {
00515                ((TGHtmlRef *)p)->fPOther = 0;
00516             }
00517             fInDt = STY_DT;
00518             break;
00519 
00520          case Html_EndDD:
00521          case Html_EndDT:
00522             fInDt = 0;
00523             break;
00524 
00525          case Html_DL: {
00526             TGHtmlListStart *list = (TGHtmlListStart *) p;
00527             list->fLPrev = fInnerList;
00528             list->fCnt = 0;
00529             fInnerList = list;
00530             list->fCompact = (list->MarkupArg("compact", 0) != 0);
00531             fInDt = 0;
00532             break;
00533          }
00534 
00535          case Html_EM:
00536             style.fFont = ItalicFont(style.fFont);
00537             PushStyleStack(Html_EndEM, style);
00538             break;
00539 
00540          case Html_EMBED:
00541             break;
00542 
00543          case Html_BASEFONT:
00544          case Html_FONT:
00545             z = p->MarkupArg("size", 0);
00546             if (z && !fOverrideFonts) {
00547                if (*z == '-') {
00548                   size = FontSize(style.fFont) - atoi(&z[1]) +1;
00549                } else if (*z == '+') {
00550                   size = FontSize(style.fFont) + atoi(&z[1]) +1;
00551                } else {
00552                   size = atoi(z);
00553                }
00554                if (size <= 0) size = 1;
00555                if (size >= N_FONT_SIZE) size = N_FONT_SIZE - 1;
00556                style.fFont = FontFamily(style.fFont) + size - 1;
00557             }
00558             z = p->MarkupArg("color", 0);
00559             if (z && *z && !fOverrideColors) style.fColor = GetColorByName(z);
00560             PushStyleStack(p->fType == Html_FONT ?
00561                            Html_EndFONT : Html_EndBASEFONT, style);
00562             break;
00563 
00564          case Html_FORM: {
00565             TGHtmlForm *form = (TGHtmlForm *) p;
00566 
00567             const char *zUrl;
00568             const char *zMethod;
00569             TGString cmd("");
00570             int result;
00571             char zToken[50];
00572 
00573             fFormStart = 0;
00574             //form->fFormId = 0;
00575 
00576             zUrl = p->MarkupArg("action", 0);
00577             if (zUrl == 0) zUrl = fZBase;
00578             zUrl = ResolveUri(zUrl);
00579             if (zUrl == 0) zUrl = StrDup("");
00580             zMethod = p->MarkupArg("method", "GET");
00581             sprintf(zToken, " %d form ", form->fFormId);
00582             cmd.Append("Form:");
00583             cmd.Append(zToken);
00584             cmd.Append(zUrl);
00585             cmd.Append(" ");
00586             cmd.Append(zMethod);
00587             cmd.Append(" { ");
00588             AppendArglist(&cmd, (TGHtmlMarkupElement *) p);
00589             cmd.Append("} ");
00590             result = FormCreate(form, zUrl, cmd.GetString());
00591             delete[] zUrl;
00592 
00593             /*if (result)*/ fFormStart = form;
00594 
00595             break;
00596          }
00597 
00598          case Html_EndFORM:
00599             ((TGHtmlRef *)p)->fPOther = fFormStart;
00600             if (fFormStart) fFormStart->fPEnd = p;
00601             fFormStart = 0;
00602             break;
00603 
00604          case Html_H1:
00605          case Html_H2:
00606          case Html_H3:
00607          case Html_H4:
00608          case Html_H5:
00609          case Html_H6:
00610             if (!fInTr) paraAlign = ALIGN_None;
00611             i = (p->fType - Html_H1) / 2 + 1;
00612             if (i >= 1 && i <= 6) {
00613                ScaleFont(&style, header_sizes[i-1]);
00614             }
00615             style.fFont = BoldFont(style.fFont);
00616             style.fAlign = p->GetAlignment(style.fAlign);
00617             PushStyleStack(Html_EndH1, style);
00618             break;
00619 
00620          case Html_EndH1:
00621          case Html_EndH2:
00622          case Html_EndH3:
00623          case Html_EndH4:
00624          case Html_EndH5:
00625          case Html_EndH6:
00626             paraAlign = ALIGN_None;
00627             style = PopStyleStack(Html_EndH1);
00628             break;
00629 
00630          case Html_HR:
00631             nextStyle = style;
00632             style.fAlign = p->GetAlignment(ALIGN_None);
00633             useNextStyle = 1;
00634             break;
00635 
00636          case Html_I:
00637             style.fFont = ItalicFont(style.fFont);
00638             PushStyleStack(Html_EndI, style);
00639             break;
00640 
00641          case Html_IMG:
00642             if (style.fFlags & STY_Invisible) break;
00643             ((TGHtmlImageMarkup *)p)->fPImage = GetImage((TGHtmlImageMarkup *) p);
00644             break;
00645 
00646          case Html_OPTION:
00647             break;
00648 
00649          case Html_INPUT:
00650             ((TGHtmlInput *)p)->fPForm = fFormStart;
00651             ////ControlSize((TGHtmlInput *) p);
00652             break;
00653 
00654          case Html_KBD:
00655             style.fFont = CWFont(style.fFont);
00656             PushStyleStack(Html_EndKBD, style);
00657             break;
00658 
00659          case Html_LI:
00660             if (fInnerList) {
00661                TGHtmlLi *li = (TGHtmlLi *) p;
00662                li->fLtype = fInnerList->fLtype;
00663                if (fInnerList->fType == Html_OL) {
00664                   z = li->MarkupArg("value", 0);
00665                   if (z) {
00666                      int n = atoi(z);
00667                      if (n > 0) {
00668                         li->fCnt = n;
00669                         fInnerList->fCnt = n+1;
00670                      }
00671                   } else {
00672                      li->fCnt = fInnerList->fCnt++;
00673                   }
00674                   li->fLtype = li->GetOrderedListType(li->fLtype);
00675                } else {
00676                   li->fLtype = li->GetUnorderedListType(li->fLtype);
00677                }
00678             } else {
00679                p->fFlags &= ~HTML_Visible;
00680             }
00681             break;
00682 
00683          case Html_MARQUEE:
00684             style.fFlags |= STY_Invisible;
00685             PushStyleStack(Html_EndMARQUEE, style);
00686             break;
00687 
00688          case Html_NOBR:
00689             style.fFlags |= STY_NoBreak;
00690             PushStyleStack(Html_EndNOBR, style);
00691             break;
00692 
00693          case Html_NOFRAMES:
00694             if (0 /* has ProcessFrame()*/) {
00695                nextStyle = style;
00696                nextStyle.fFlags |= STY_Invisible;
00697                PushStyleStack(Html_EndNOFRAMES, nextStyle);
00698                useNextStyle = 1;
00699             } else {
00700                PushStyleStack(Html_EndNOFRAMES, style);
00701             }
00702             break;
00703 
00704          case Html_NOEMBED:
00705             if (0 /* has ProcessScript() && HasScript */) {
00706                nextStyle = style;
00707                nextStyle.fFlags |= STY_Invisible;
00708                PushStyleStack(Html_EndNOEMBED, nextStyle);
00709                useNextStyle = 1;
00710             } else {
00711                PushStyleStack(Html_EndNOEMBED, style);
00712             }
00713             break;
00714 
00715          case Html_NOSCRIPT:
00716             if (0 /* has ProcessScript() && HasScript */) {
00717                nextStyle = style;
00718                nextStyle.fFlags |= STY_Invisible;
00719                PushStyleStack(Html_EndNOSCRIPT, nextStyle);
00720                useNextStyle = 1;
00721             } else {
00722                PushStyleStack(Html_EndNOSCRIPT, style);
00723             }
00724             break;
00725 
00726          case Html_OL: {
00727             TGHtmlListStart *list = (TGHtmlListStart *) p;
00728             list->fLPrev = fInnerList;
00729             list->fLtype = list->GetOrderedListType(LI_TYPE_Enum_1);
00730             list->fCnt = 1;
00731             z = list->MarkupArg("start", 0);
00732             if (z) {
00733                int n = atoi(z);
00734                if (n > 0) list->fCnt = n;
00735             }
00736             list->fCompact = (fInnerList != 0 || list->MarkupArg("compact", 0) != 0);
00737             fInnerList = list;
00738             break;
00739          }
00740 
00741          case Html_P:
00742             paraAlign = p->GetAlignment(ALIGN_None);
00743             break;
00744 
00745          case Html_EndP:
00746             paraAlign = ALIGN_None;
00747             break;
00748 
00749          case Html_PRE:
00750          case Html_LISTING:
00751          case Html_XMP:
00752          case Html_PLAINTEXT:
00753             paraAlign = ALIGN_None;
00754             style.fFont = CWFont(style.fFont);
00755             style.fFlags |= STY_Preformatted;
00756             PushStyleStack(Html_EndPRE, style);
00757             break;
00758 
00759          case Html_EndPRE:
00760          case Html_EndLISTING:
00761          case Html_EndXMP:
00762             style = PopStyleStack(Html_EndPRE);
00763             break;
00764 
00765          case Html_S:
00766             style.fFlags |= STY_StrikeThru;
00767             PushStyleStack(Html_EndS, style);
00768             break;
00769 
00770          case Html_SCRIPT: {
00771             char *result;
00772             result = ProcessScript((TGHtmlScript *) p);   // fZText[script->nStart .. script->nScript]
00773             if (result) {
00774                TGHtmlElement *b2 = p->fPNext, *b3, *e1 = p, *e2 = b2, *e3;
00775                if (e2) while (e2->fPNext) e2 = e2->fPNext;
00776                TokenizerAppend(result);
00777                if (e2 && e2 != p && ((e3 = b3 = e2->fPNext))) {
00778                   while (e3->fPNext) e3 = e3->fPNext;
00779                   e1->fPNext = b3;
00780                   e2->fPNext = 0;   b2->fPPrev = e3;
00781                   e3->fPNext = b2;  b3->fPPrev = e1;
00782                }
00783                delete[] result;
00784             }
00785             nextStyle = style;
00786             style.fFlags |= STY_Invisible;
00787             useNextStyle = 1;
00788             break;
00789          }
00790 
00791          case Html_SELECT:
00792             ((TGHtmlInput *)p)->fPForm = fFormStart;
00793             nextStyle.fFlags |= STY_Invisible;
00794             useNextStyle = 1;
00795             PushStyleStack(Html_EndSELECT, style);
00796             fFormElemStart = (TGHtmlInput *) p;
00797             break;
00798 
00799          case Html_EndSELECT:
00800             style = PopStyleStack(Html_EndSELECT);
00801             if (fFormElemStart && fFormElemStart->fType == Html_SELECT) {
00802                 ((TGHtmlRef *)p)->fPOther = fFormElemStart;
00803                MakeInvisible(((TGHtmlRef *)p)->fPOther, p);
00804             } else {
00805                ((TGHtmlRef *)p)->fPOther = 0;
00806             }
00807             fFormElemStart = 0;
00808             break;
00809 
00810          case Html_STRIKE:
00811             style.fFlags |= STY_StrikeThru;
00812             PushStyleStack(Html_EndSTRIKE, style);
00813             break;
00814 
00815          case Html_STYLE:
00816             // Ignore style sheets
00817             break;
00818 
00819          case Html_SAMP:
00820             style.fFont = CWFont(style.fFont);
00821             PushStyleStack(Html_EndSAMP, style);
00822             break;
00823 
00824          case Html_SMALL:
00825             ScaleFont(&style, -1);
00826             PushStyleStack(Html_EndSMALL, style);
00827             break;
00828 
00829          case Html_STRONG:
00830             style.fFont = BoldFont(style.fFont);
00831             PushStyleStack(Html_EndSTRONG, style);
00832             break;
00833 
00834          case Html_SUB:
00835             ScaleFont(&style, -1);
00836             if (style.fSubscript > -6 ) style.fSubscript--;
00837             PushStyleStack(Html_EndSUB, style);
00838             break;
00839 
00840          case Html_SUP:
00841             ScaleFont(&style, -1);
00842             if (style.fSubscript < 6) style.fSubscript++;
00843             PushStyleStack(Html_EndSUP, style);
00844             break;
00845 
00846          case Html_TABLE:
00847             paraAlign = ALIGN_None;
00848             nextStyle = style;
00849             if (style.fFlags & STY_Preformatted) {
00850                nextStyle.fFlags &= ~STY_Preformatted;
00851                style.fFlags |= STY_Preformatted;
00852             }
00853             nextStyle.fAlign = ALIGN_Left;
00854             z = p->MarkupArg("bgcolor", 0);
00855             if (z && *z && !fOverrideColors) {
00856                style.fBgcolor = nextStyle.fBgcolor = GetColorByName(z);
00857                style.fExpbg = 1;
00858 //            } else {
00859 //               nextStyle.fBgcolor = COLOR_Background;
00860             }
00861             TableBgndImage(p);
00862             PushStyleStack(Html_EndTABLE, nextStyle);
00863             useNextStyle = 1;
00864             fInTd = 0;
00865             fInTr = 0;
00866             break;
00867 
00868          case Html_EndTABLE:
00869             paraAlign = ALIGN_None;
00870             if (fInTd) {
00871                style = PopStyleStack(Html_EndTD);
00872                fInTd = 0;
00873             }
00874             if (fInTr) {
00875                style = PopStyleStack(Html_EndTR);
00876                fInTr = 0;
00877             }
00878             style = PopStyleStack(p->fType);
00879             break;
00880 
00881          case Html_TD:
00882             if (fInTd) style = PopStyleStack(Html_EndTD);
00883             fInTd = 1;
00884             paraAlign = p->GetAlignment(rowAlign);
00885             z = p->MarkupArg("bgcolor", 0);
00886             if (z && *z && !fOverrideColors) {
00887                style.fBgcolor = GetColorByName(z);
00888                style.fExpbg = 1;
00889             }
00890             TableBgndImage(p);
00891             PushStyleStack(Html_EndTD, style);
00892             break;
00893 
00894          case Html_TEXTAREA:
00895             ((TGHtmlInput *)p)->fPForm = fFormStart;
00896             nextStyle = style;
00897             nextStyle.fFlags |= STY_Invisible;
00898             PushStyleStack(Html_EndTEXTAREA, nextStyle);
00899             fFormElemStart = (TGHtmlInput *) p;
00900             useNextStyle = 1;
00901             break;
00902 
00903          case Html_EndTEXTAREA:
00904             style = PopStyleStack(Html_EndTEXTAREA);
00905             if (fFormElemStart && fFormElemStart->fType == Html_TEXTAREA) {
00906                ((TGHtmlRef *)p)->fPOther = fFormElemStart;
00907             } else {
00908                ((TGHtmlRef *)p)->fPOther = 0;
00909             }
00910             fFormElemStart = 0;
00911             break;
00912 
00913          case Html_TH:
00914             //paraAlign = p->GetAlignment(rowAlign);
00915             if (fInTd) style = PopStyleStack(Html_EndTD);
00916             paraAlign = p->GetAlignment(ALIGN_Center);
00917             style.fFont = BoldFont(style.fFont);
00918             z = p->MarkupArg("bgcolor", 0);
00919             if (z && *z && !fOverrideColors) {
00920                style.fBgcolor = GetColorByName(z);
00921                style.fExpbg = 1;
00922             }
00923             PushStyleStack(Html_EndTD, style);
00924             fInTd = 1;
00925             break;
00926 
00927          case Html_TR:
00928             if (fInTd) {
00929                style = PopStyleStack(Html_EndTD);
00930                fInTd = 0;
00931             }
00932             if (fInTr) {
00933                style = PopStyleStack(Html_EndTR);
00934             }
00935             rowAlign = p->GetAlignment(ALIGN_None);
00936             z = p->MarkupArg("bgcolor", 0);
00937             if (z && *z && !fOverrideColors) {
00938                style.fBgcolor = GetColorByName(z);
00939                style.fExpbg = 1;
00940             }
00941             TableBgndImage(p);
00942             PushStyleStack(Html_EndTR, style);
00943             fInTr = 1;
00944             break;
00945 
00946          case Html_EndTR:
00947             if (fInTd) {
00948                style = PopStyleStack(Html_EndTD);
00949                fInTd = 0;
00950             }
00951             style = PopStyleStack(Html_EndTR);
00952             fInTr = 0;
00953             paraAlign = ALIGN_None;
00954             rowAlign = ALIGN_None;
00955             break;
00956 
00957          case Html_EndTD:
00958          case Html_EndTH:
00959             style = PopStyleStack(Html_EndTD);
00960             fInTd = 0;
00961             paraAlign = ALIGN_None;
00962             //rowAlign = ALIGN_None;
00963             break;
00964 
00965          case Html_TITLE:
00966             style.fFlags |= STY_Invisible;
00967             PushStyleStack(Html_EndTITLE, style);
00968             break;
00969 
00970          case Html_TT:
00971             style.fFont = CWFont(style.fFont);
00972             PushStyleStack(Html_EndTT, style);
00973             break;
00974 
00975          case Html_U:
00976             style.fFlags |= STY_Underline;
00977             PushStyleStack(Html_EndU, style);
00978             break;
00979 
00980          case Html_VAR:
00981             style.fFont = ItalicFont(style.fFont);
00982             PushStyleStack(Html_EndVAR, style);
00983             break;
00984 
00985          default:
00986             break;
00987       }
00988 
00989       p->fStyle = style;
00990       p->fStyle.fFlags |= fAnchorFlags | fInDt;
00991       if (paraAlign != ALIGN_None) {
00992          p->fStyle.fAlign = paraAlign;
00993       }
00994       if (useNextStyle) {
00995          style = nextStyle;
00996          style.fExpbg = 0;
00997          useNextStyle = 0;
00998       }
00999 
01000       TRACE(HtmlTrace_Style,
01001           ("Style font=%02d color=%02d bg=%02d "
01002            "align=%d flags=0x%04x token=%s\n",
01003            p->fStyle.fFont, p->fStyle.fColor, p->fStyle.fBgcolor,
01004            p->fStyle.fAlign, p->fStyle.fFlags, DumpToken(p)));
01005 
01006       p = p->fPNext;
01007    }
01008 
01009    // Copy state information back into the TGHtml object for safe keeping.
01010 
01011    fParaAlignment = paraAlign;
01012    fRowAlignment = rowAlign;
01013 
01014    fFlags &= ~STYLER_RUNNING;
01015 }
01016 
01017 //______________________________________________________________________________
01018 void TGHtml::TableBgndImage(TGHtmlElement *p)
01019 {
01020    // Set background picture of a html table.
01021 
01022    const char *z;
01023 
01024    z = p->MarkupArg("background", 0);
01025    if (!z) return;
01026 
01027    char *z1 = ResolveUri(z);
01028    TImage *img = LoadImage(z1, 0, 0);
01029    delete [] z1;
01030 
01031    switch (p->fType) {
01032       case Html_TABLE: {
01033          TGHtmlTable *table = (TGHtmlTable *) p;
01034          if (table->fBgImage) delete table->fBgImage;
01035          table->fBgImage = img;
01036          break;
01037       }
01038       case Html_TR: {
01039          TGHtmlRef *ref = (TGHtmlRef *) p;
01040          if (ref->fBgImage) delete ref->fBgImage;
01041             ref->fBgImage = img;
01042             break;
01043       }
01044       case Html_TH:
01045       case Html_TD: {
01046          TGHtmlCell *cell = (TGHtmlCell *) p;
01047          if (cell->fBgImage) delete cell->fBgImage;
01048             cell->fBgImage = img;
01049             break;
01050          }
01051       default:
01052          if (img) delete img;
01053          break;
01054    }
01055 }
01056 
01057 //______________________________________________________________________________
01058 void TGHtml::Sizer()
01059 {
01060    // Compute the size of all elements in the widget. Assume that a style has
01061    // already been assigned to all elements.
01062    //
01063    // Some of the elements might have already been sized. Refer to the
01064    // fLastSized and only compute sizes for elements that follow this one. If
01065    // fLastSized is 0, then size everything.
01066    //
01067    // This routine only computes the sizes of individual elements. The size of
01068    // aggregate elements (like tables) are computed separately.
01069    //
01070    // The HTML_Visible flag is also set on every element that results in ink on
01071    // the page.
01072    //
01073    // This routine may invoke a callback procedure which could delete the HTML
01074    // widget.
01075 
01076    TGHtmlElement *p;
01077    int iFont = -1;
01078    TGFont *font=0;
01079    int spaceWidth = 0;
01080    FontMetrics_t fontMetrics;
01081    const char *z;
01082    int stop = 0;
01083 
01084    if (fPFirst == 0) return;
01085 
01086    if (fLastSized == 0) {
01087       p = fPFirst;
01088    } else {
01089       p = fLastSized->fPNext;
01090    }
01091 
01092    for (; !stop && p; p = p ? p->fPNext : 0) {
01093       if (p->fStyle.fFlags & STY_Invisible) {
01094          p->fFlags &= ~HTML_Visible;
01095          continue;
01096       }
01097       if (iFont != (int)p->fStyle.fFont) {
01098          iFont = p->fStyle.fFont;
01099          font = GetFont(iFont);
01100          font->GetFontMetrics(&fontMetrics);
01101          spaceWidth = 0;
01102       }
01103       switch (p->fType) {
01104          case Html_Text: {
01105             TGHtmlTextElement *text = (TGHtmlTextElement *) p;
01106             text->fW = font->TextWidth(text->fZText, p->fCount);
01107             p->fFlags |= HTML_Visible;
01108             text->fDescent = fontMetrics.fDescent;
01109             text->fAscent = fontMetrics.fAscent;
01110             if (spaceWidth == 0) spaceWidth = font->TextWidth(" ", 1);
01111             text->fSpaceWidth = spaceWidth;
01112             break;
01113          }
01114 
01115          case Html_Space: {
01116             TGHtmlSpaceElement *space = (TGHtmlSpaceElement *) p;
01117             if (spaceWidth == 0) spaceWidth = font->TextWidth(" ", 1);
01118             space->fW = spaceWidth;
01119             space->fDescent = fontMetrics.fDescent;
01120             space->fAscent = fontMetrics.fAscent;
01121             p->fFlags &= ~HTML_Visible;
01122             break;
01123          }
01124 
01125          case Html_TD:
01126          case Html_TH: {
01127             TGHtmlCell *cell = (TGHtmlCell *) p;
01128             z = p->MarkupArg("rowspan", "1");
01129             cell->fRowspan = atoi(z);
01130             z = p->MarkupArg("colspan", "1");
01131             cell->fColspan = atoi(z);
01132             p->fFlags |= HTML_Visible;
01133             break;
01134          }
01135 
01136          case Html_LI: {
01137             TGHtmlLi *li = (TGHtmlLi *) p;
01138             li->fDescent = fontMetrics.fDescent;
01139             li->fAscent = fontMetrics.fAscent;
01140             p->fFlags |= HTML_Visible;
01141             break;
01142          }
01143 
01144          case Html_IMG: {
01145             TGHtmlImageMarkup *image = (TGHtmlImageMarkup *) p;
01146             z = p->MarkupArg("usemap", 0);
01147             if (z && *z == '#') {
01148                image->fPMap = GetMap(z+1);
01149             } else {
01150                image->fPMap = 0;
01151             }
01152             p->fFlags |= HTML_Visible;
01153             image->fRedrawNeeded = 0;
01154             image->fTextAscent = fontMetrics.fAscent;
01155             image->fTextDescent = fontMetrics.fDescent;
01156             image->fAlign = GetImageAlignment(p);
01157             if (image->fPImage == 0) {
01158                image->fAscent = fontMetrics.fAscent;
01159                image->fDescent = fontMetrics.fDescent;
01160                image->fZAlt = p->MarkupArg("alt", "<image>");
01161                image->fW = font->TextWidth(image->fZAlt, strlen(image->fZAlt));
01162             } else {
01163                int w, h;
01164                image->fINext = image->fPImage->fPList;
01165                image->fPImage->fPList = image;
01166                w = image->fPImage->fImage->GetWidth();
01167                h = image->fPImage->fImage->GetHeight();
01168                image->fH = h;
01169                image->fW = w;
01170                image->fAscent = h / 2;
01171                image->fDescent = h - image->fAscent;
01172             }
01173             if ((z = p->MarkupArg("width", 0)) != 0) {
01174                int w = atoi(z);
01175                if (z[strlen(z)-1] == '%') w = 0; //// -- HP
01176                if (w > 0) image->fW = w;
01177             }
01178             if ((z = p->MarkupArg("height", 0)) != 0) {
01179                int h = atoi(z);
01180                if (h > 0) image->fH = h;
01181             }
01182 
01183 #if 1  // --HP
01184             if (image->fPImage == 0 && !*image->fZAlt) {
01185                image->fAscent = image->fH / 2;
01186                image->fDescent = image->fH - image->fAscent;
01187             }
01188 #endif
01189             break;
01190          }
01191 
01192          case Html_TABLE:
01193             p->fFlags |= HTML_Visible;
01194             break;
01195 
01196          case Html_HR:
01197             p->fFlags |= HTML_Visible;
01198             break;
01199 
01200          case Html_APPLET:
01201          case Html_EMBED:
01202          case Html_INPUT: {
01203             TGHtmlInput *input = (TGHtmlInput *) p;
01204             input->fTextAscent = fontMetrics.fAscent;
01205             input->fTextDescent = fontMetrics.fDescent;
01206             stop = ControlSize(input);
01207             break;
01208          }
01209 
01210          case Html_SELECT:
01211          case Html_TEXTAREA: {
01212             TGHtmlInput *input = (TGHtmlInput *) p;
01213             input->fTextAscent = fontMetrics.fAscent;
01214             input->fTextDescent = fontMetrics.fDescent;
01215             break;
01216          }
01217 
01218          case Html_EndSELECT:
01219          case Html_EndTEXTAREA: {
01220             TGHtmlRef *ref = (TGHtmlRef *) p;
01221             if (ref->fPOther) {
01222                ((TGHtmlInput *)ref->fPOther)->fPEnd = p;
01223                stop = ControlSize((TGHtmlInput *) ref->fPOther);
01224             }
01225             break;
01226          }
01227 
01228          default:
01229             p->fFlags &= ~HTML_Visible;
01230             break;
01231       }
01232    }
01233 
01234    if (p) {
01235       fLastSized = p;
01236    } else {
01237       fLastSized = fPLast;
01238    }
01239 }

Generated on Tue Jul 5 14:22:19 2011 for ROOT_528-00b_version by  doxygen 1.5.1