diff options
Diffstat (limited to 'tkhtml1/src/htmldraw.c')
-rw-r--r-- | tkhtml1/src/htmldraw.c | 877 |
1 files changed, 0 insertions, 877 deletions
diff --git a/tkhtml1/src/htmldraw.c b/tkhtml1/src/htmldraw.c deleted file mode 100644 index 42f2f80..0000000 --- a/tkhtml1/src/htmldraw.c +++ /dev/null @@ -1,877 +0,0 @@ -/* -** Routines used to render HTML onto the screen for the Tk HTML widget. -** -** Copyright (C) 1997-2000 D. Richard Hipp -** -** This library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Library General Public -** License as published by the Free Software Foundation; either -** version 2 of the License, or (at your option) any later version. -** -** This library is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Library General Public License for more details. -** -** You should have received a copy of the GNU Library General Public -** License along with this library; if not, write to the -** Free Software Foundation, Inc., 59 Temple Place - Suite 330, -** Boston, MA 02111-1307, USA. -** -** Author contact information: -** drh@acm.org -** http://www.hwaci.com/drh/ -*/ -#include <tk.h> -#include <string.h> -#include <stdlib.h> -#include "htmldraw.h" -/* -#ifdef USE_TK_STUBS -# include <tkIntXlibDecls.h> -#endif -*/ -#define USE_TK_DRAWCHARS 1 - -/* -** Allocate a new HtmlBlock structure. -*/ -static HtmlBlock *AllocBlock(void){ - HtmlBlock *pNew; - - pNew = HtmlAlloc( sizeof(HtmlBlock) ); - if( pNew ){ - memset(pNew, 0, sizeof(*pNew)); - pNew->base.type = Html_Block; - } - return pNew; -} - -/* -** Free an HtmlBlock structure. Assume that it is already unlinked -** from the element list and the block list. -*/ -static void FreeBlock(HtmlBlock *pBlock){ - if( pBlock ){ - if( pBlock->z ){ - HtmlFree(pBlock->z); - } - HtmlFree(pBlock); - } -} - -/* -** Destroy the given Block after first unlinking it from the -** element list. Note that this unlinks the block from the -** element list only -- not from the block list. -*/ -static void UnlinkAndFreeBlock(HtmlWidget *htmlPtr, HtmlBlock *pBlock){ - if( pBlock->base.pNext ){ - pBlock->base.pNext->base.pPrev = pBlock->base.pPrev; - TestPoint(0); - }else{ - htmlPtr->pLast = pBlock->base.pPrev; - TestPoint(0); - } - if( pBlock->base.pPrev ){ - pBlock->base.pPrev->base.pNext = pBlock->base.pNext; - TestPoint(0); - }else{ - htmlPtr->pFirst = pBlock->base.pNext; - TestPoint(0); - } - pBlock->base.pPrev = pBlock->base.pNext = 0; - FreeBlock(pBlock); -} - -/* -** Append a block to the block list and insert the block into the -** element list immediately prior to the element given. -*/ -static void AppendBlock( - HtmlWidget *htmlPtr, /* The HTML widget */ - HtmlElement *pToken, /* The token that comes after pBlock */ - HtmlBlock *pBlock /* The block to be appended */ -){ - pBlock->base.pPrev = pToken->base.pPrev; - pBlock->base.pNext = pToken; - pBlock->pPrev = htmlPtr->lastBlock; - pBlock->pNext = 0; - if( htmlPtr->lastBlock ){ - htmlPtr->lastBlock->pNext = pBlock; - TestPoint(0); - }else{ - htmlPtr->firstBlock = pBlock; - TestPoint(0); - } - htmlPtr->lastBlock = pBlock; - if( pToken->base.pPrev ){ - pToken->base.pPrev->base.pNext = (HtmlElement*)pBlock; - TestPoint(0); - }else{ - htmlPtr->pFirst = (HtmlElement*)pBlock; - TestPoint(0); - } - pToken->base.pPrev = (HtmlElement*)pBlock; -} - -/* -** Print an ordered list index into the given buffer. Use numbering -** like this: -** -** A B C ... Y Z AA BB CC ... ZZ -** -** Revert to decimal for indices greater than 52. -*/ -static void GetLetterIndex(char *zBuf, int index, int isUpper){ - int seed; - if( index<1 || index>52 ){ - sprintf(zBuf,"%d",index); - TestPoint(0); - return; - } - if( isUpper ){ - seed = 'A'; - TestPoint(0); - }else{ - seed = 'a'; - TestPoint(0); - } - index--; - if( index<26 ){ - zBuf[0] = seed + index; - zBuf[1] = 0; - TestPoint(0); - }else{ - index -= 26; - zBuf[0] = seed + index; - zBuf[1] = seed + index; - zBuf[2] = 0; - TestPoint(0); - } - strcat(zBuf,"."); -} - -/* -** Print an ordered list index into the given buffer. Use roman -** numerals. For indices greater than a few thousand, revert to -** decimal. -*/ -static void GetRomanIndex(char *zBuf, int index, int isUpper){ - int i = 0; - int j; - static struct { - int value; - char *name; - } values[] = { - { 1000, "m" }, - { 999, "im" }, - { 990, "xm" }, - { 900, "cm" }, - { 500, "d" }, - { 499, "id" }, - { 490, "xd" }, - { 400, "cd" }, - { 100, "c" }, - { 99, "ic" }, - { 90, "xc" }, - { 50, "l" }, - { 49, "il" }, - { 40, "xl" }, - { 10, "x" }, - { 9, "ix" }, - { 5, "v" }, - { 4, "iv" }, - { 1, "i" }, - }; - if( index<1 || index>=5000 ){ - sprintf(zBuf,"%d",index); - TestPoint(0); - return; - } - for(j=0; index>0 && j<sizeof(values)/sizeof(values[0]); j++){ - int k; - while( index >= values[j].value ){ - for(k=0; values[j].name[k]; k++){ - zBuf[i++] = values[j].name[k]; - TestPoint(0); - } - index -= values[j].value; - TestPoint(0); - } - } - zBuf[i] = 0; - if( isUpper ){ - for(i=0; zBuf[i]; i++){ - zBuf[i] += 'A' - 'a'; - TestPoint(0); - } - }else{ - TestPoint(0); - } - strcat(zBuf,"."); -} - -/* Draw the selection background for the given block -*/ -static void DrawSelectionBackground( - HtmlWidget *htmlPtr, /* The HTML widget */ - HtmlBlock *pBlock, /* The block whose background is drawn */ - Drawable drawable, /* Draw the background on this drawable */ - int x, int y /* Virtual coords of top-left of drawable */ -){ - int xLeft, xRight; /* Left and right bounds of box to draw */ - int yTop, yBottom; /* Top and bottom of box */ - HtmlElement *p = 0; /* First element of the block */ - Tk_Font font; /* Font */ - GC gc; /* GC for drawing */ - XRectangle xrec; /* Size of a filled rectangle to be drawn */ - - if( pBlock==0 || (pBlock->base.flags & HTML_Selected)==0 ){ - TestPoint(0); - return; - } - xLeft = pBlock->left - x; - if( pBlock==htmlPtr->pSelStartBlock && htmlPtr->selStartIndex>0 ){ - if( htmlPtr->selStartIndex >= pBlock->n ){ TestPoint(0); return; } - p = pBlock->base.pNext; - font = HtmlGetFont(htmlPtr, p->base.style.font); - if( font==0 ) return; - if( p->base.type==Html_Text ){ - xLeft = p->text.x - x + Tk_TextWidth(font, pBlock->z, - htmlPtr->selStartIndex); - } - } - xRight = pBlock->right - x; - if( pBlock==htmlPtr->pSelEndBlock && htmlPtr->selEndIndex<pBlock->n ){ - if( p==0 ){ - p = pBlock->base.pNext; - font = HtmlGetFont(htmlPtr, p->base.style.font); - if( font==0 ) return; - } - if( p->base.type==Html_Text ){ - xRight = p->text.x - x + Tk_TextWidth(font, pBlock->z, - htmlPtr->selEndIndex); - } - } - yTop = pBlock->top - y; - yBottom = pBlock->bottom - y; - gc = HtmlGetGC(htmlPtr, COLOR_Selection, FONT_Any); - xrec.x = xLeft; - xrec.y = yTop; - xrec.width = xRight - xLeft; - xrec.height = yBottom - yTop; - XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); -} - -/* -** Draw a rectangle. The rectangle will have a 3-D appearance if -** flat==0 and a flat appearance if flat==1. -** -** We don't use Tk_Draw3DRectangle() because it doesn't work well -** when the background color is close to pure white or pure black. -*/ -static void HtmlDrawRect( - HtmlWidget *htmlPtr, /* The HTML widget */ - Drawable drawable, /* Draw it here */ - HtmlElement *src, /* Element associated with drawing */ - int x, int y, int w, int h, /* Coordinates of the rectangle */ - int depth, /* Width of the relief, or the flat line */ - int relief /* The relief. TK_RELIEF_FLAT omits 3d */ -){ - if( depth>0 ){ - int i; - GC gcLight, gcDark; - XRectangle xrec[1]; - if( relief!=TK_RELIEF_FLAT ){ - int iLight, iDark; - iLight = HtmlGetLightShadowColor(htmlPtr, src->base.style.bgcolor); - gcLight = HtmlGetGC(htmlPtr, iLight, FONT_Any); - iDark = HtmlGetDarkShadowColor(htmlPtr, src->base.style.bgcolor); - gcDark = HtmlGetGC(htmlPtr, iDark, FONT_Any); - if( relief==TK_RELIEF_SUNKEN ){ - GC gcTemp = gcLight; - gcLight = gcDark; - gcDark = gcTemp; - } - }else{ - gcLight = HtmlGetGC(htmlPtr, src->base.style.color, FONT_Any); - gcDark = gcLight; - } - xrec[0].x = x; - xrec[0].y = y; - xrec[0].width = depth; - xrec[0].height = h; - XFillRectangles(htmlPtr->display, drawable, gcLight, xrec, 1); - xrec[0].x = x+w-depth; - XFillRectangles(htmlPtr->display, drawable, gcDark, xrec, 1); - for(i=0; i<depth && i<h/2; i++){ - XDrawLine(htmlPtr->display, drawable, gcLight, x+i, y+i, x+w-i-1, y+i); - XDrawLine(htmlPtr->display, drawable, gcDark, x+i, y+h-i-1, - x+w-i-1, y+h-i-1); - } - } - if( h>depth*2 && w>depth*2 ){ - GC gcBg; - XRectangle xrec[1]; - gcBg = HtmlGetGC(htmlPtr, src->base.style.bgcolor, FONT_Any); - xrec[0].x = x + depth; - xrec[0].y = y + depth; - xrec[0].width = w - depth*2; - xrec[0].height = h - depth*2; - XFillRectangles(htmlPtr->display, drawable, gcBg, xrec, 1); - } -} - -/* -** Display a single HtmlBlock. This is where all the drawing -** happens. -*/ -void HtmlBlockDraw( - HtmlWidget *htmlPtr, /* The main HTML widget */ - HtmlBlock *pBlock, /* Block which needs to be drawn */ - Drawable drawable, /* Draw the line on this */ - int drawableLeft, /* Virtual coordinate of left edge of drawable */ - int drawableTop, /* Virtual coordinate of top edge of drawable */ - int drawableWidth, /* Width of the drawable */ - int drawableHeight /* Height of the drawable */ -){ - Tk_Font font; /* Font to use to render text */ - GC gc; /* A graphics context */ - HtmlElement *src; /* HtmlElement holding style information */ - HtmlElement *pTable; /* The table (when drawing part of a table) */ - int x, y; /* Where to draw */ - - if( pBlock==0 ){ TestPoint(0); return; } - src = pBlock->base.pNext; - while( src && (src->base.flags & HTML_Visible)==0 ){ - src = src->base.pNext; - TestPoint(0); - } - if( src==0 ){ TestPoint(0); return; } - if( pBlock->n>0 ){ - /* We must be dealing with plain old text */ - if( src->base.type==Html_Text ){ - x = src->text.x; - y = src->text.y; - TestPoint(0); - }else{ - CANT_HAPPEN; - return; - } - if( pBlock->base.flags & HTML_Selected ){ - HtmlLock(htmlPtr); - DrawSelectionBackground(htmlPtr, pBlock, drawable, - drawableLeft, drawableTop); - if( HtmlUnlock(htmlPtr) ) return; - } - gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); - font = HtmlGetFont(htmlPtr, src->base.style.font); - if( font==0 ) return; - Tk_DrawChars(htmlPtr->display, - drawable, - gc, font, - pBlock->z, pBlock->n, - x - drawableLeft, y - drawableTop); - if( src->base.style.flags & STY_Underline ){ - Tk_UnderlineChars(htmlPtr->display, drawable, gc, font, pBlock->z, - x - drawableLeft, y-drawableTop, 0, pBlock->n); - } - if( src->base.style.flags & STY_StrikeThru ){ - XRectangle xrec; - xrec.x = pBlock->left - drawableLeft; - xrec.y = (pBlock->top + pBlock->bottom)/2 - drawableTop; - xrec.width = pBlock->right - pBlock->left; - xrec.height = 1 + (pBlock->bottom - pBlock->top > 15); - XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); - } - if( pBlock==htmlPtr->pInsBlock && htmlPtr->insStatus>0 ){ - int x; - XRectangle xrec; - if( htmlPtr->insIndex < pBlock->n ){ - x = src->text.x - drawableLeft; - x += Tk_TextWidth(font, pBlock->z, htmlPtr->insIndex); - }else{ - x = pBlock->right - drawableLeft; - } - if( x>0 ){ TestPoint(0); x--; } - xrec.x = x; - xrec.y = pBlock->top - drawableTop; - xrec.width = 2; - xrec.height = pBlock->bottom - pBlock->top; - XFillRectangles(htmlPtr->display, drawable, gc, &xrec, 1); - } - }else{ - /* We are dealing with a single HtmlElement which contains something - ** other than plain text. */ - int top=0; - int btm=0; - int cntr; - int cnt, w; - char zBuf[30]; - switch( src->base.type ){ - case Html_LI: - x = src->li.x; - y = src->li.y; - cntr = (top+btm)/2; - switch( src->li.type ){ - case LI_TYPE_Enum_1: - sprintf(zBuf,"%d.",src->li.cnt); - TestPoint(0); - break; - case LI_TYPE_Enum_A: - GetLetterIndex(zBuf,src->li.cnt,1); - TestPoint(0); - break; - case LI_TYPE_Enum_a: - GetLetterIndex(zBuf,src->li.cnt,0); - TestPoint(0); - break; - case LI_TYPE_Enum_I: - GetRomanIndex(zBuf,src->li.cnt,1); - TestPoint(0); - break; - case LI_TYPE_Enum_i: - GetRomanIndex(zBuf,src->li.cnt,0); - TestPoint(0); - break; - default: - zBuf[0] = 0; - TestPoint(0); - break; - } - gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); - switch( src->li.type ){ - case LI_TYPE_Undefined: - case LI_TYPE_Bullet1: - XFillArc(htmlPtr->display, - drawable, - gc, - x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7, - 0, 360*64); - TestPoint(0); - break; - - case LI_TYPE_Bullet2: - XDrawArc(htmlPtr->display, - drawable, - gc, - x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7, - 0, 360*64); - TestPoint(0); - break; - - case LI_TYPE_Bullet3: - XDrawRectangle(htmlPtr->display, - drawable, - gc, - x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7); - TestPoint(0); - break; - - case LI_TYPE_Enum_1: - case LI_TYPE_Enum_A: - case LI_TYPE_Enum_a: - case LI_TYPE_Enum_I: - case LI_TYPE_Enum_i: - cnt = strlen(zBuf); - font = HtmlGetFont(htmlPtr, src->base.style.font); - if( font==0 ) return; - w = Tk_TextWidth(font, zBuf, cnt); - Tk_DrawChars(htmlPtr->display, - drawable, - gc, font, - zBuf, cnt, - x - w - drawableLeft, y - drawableTop); - TestPoint(0); - break; - } - break; - case Html_HR: { - int relief = htmlPtr->ruleRelief; - switch( relief ){ - case TK_RELIEF_RAISED: - case TK_RELIEF_SUNKEN: - break; - default: - relief = TK_RELIEF_FLAT; - break; - } - HtmlDrawRect(htmlPtr, drawable, src, - src->hr.x - drawableLeft, - src->hr.y - drawableTop, - src->hr.w, - src->hr.h, - 1, relief); - break; - } - case Html_TABLE: { - int relief = htmlPtr->tableRelief; - switch( relief ){ - case TK_RELIEF_RAISED: - case TK_RELIEF_SUNKEN: - break; - default: - relief = TK_RELIEF_FLAT; - break; - } - HtmlDrawRect(htmlPtr, drawable, src, - src->table.x - drawableLeft, - src->table.y - drawableTop, - src->table.w, - src->table.h, - src->table.borderWidth, - relief); - break; - } - case Html_TH: - case Html_TD: { - int depth, relief; - pTable = src->cell.pTable; - depth = pTable && pTable->table.borderWidth>0; - switch( htmlPtr->tableRelief ){ - case TK_RELIEF_RAISED: relief = TK_RELIEF_SUNKEN; break; - case TK_RELIEF_SUNKEN: relief = TK_RELIEF_RAISED; break; - default: relief = TK_RELIEF_FLAT; break; - } - HtmlDrawRect(htmlPtr, drawable, src, - src->cell.x - drawableLeft, - src->cell.y - drawableTop, - src->cell.w, - src->cell.h, - depth, - relief); - break; - } - case Html_IMG: - if( src->image.pImage ){ - HtmlDrawImage(src, drawable, drawableLeft, drawableTop, - drawableLeft + drawableWidth, - drawableTop + drawableHeight); - }else if( src->image.zAlt ){ - gc = HtmlGetGC(htmlPtr, src->base.style.color, src->base.style.font); - font = HtmlGetFont(htmlPtr, src->base.style.font); - if( font==0 ) return; - Tk_DrawChars(htmlPtr->display, - drawable, - gc, font, - src->image.zAlt, strlen(src->image.zAlt), - src->image.x - drawableLeft, - src->image.y - drawableTop); - TestPoint(0); - } - break; - default: - TestPoint(0); - break; - } - } -} - -/* -** Draw all or part of an image. -*/ -void HtmlDrawImage( - HtmlElement *pElem, /* The <IMG> to be drawn */ - Drawable drawable, /* Draw it here */ - int drawableLeft, /* left edge of the drawable */ - int drawableTop, /* Virtual canvas coordinate for top of drawable */ - int drawableRight, /* right edge of the drawable */ - int drawableBottom /* bottom edge of the drawable */ -){ - int imageTop; /* virtual canvas coordinate for top of image */ - int x, y; /* where to place image on the drawable */ - int imageX, imageY; /* \__ Subset of image that fits */ - int imageW, imageH; /* / on the drawable */ - - imageTop = pElem->image.y - pElem->image.ascent; - y = imageTop - drawableTop; - if( imageTop + pElem->image.h > drawableBottom ){ - imageH = drawableBottom - imageTop; - TestPoint(0); - }else{ - imageH = pElem->image.h; - TestPoint(0); - } - if( y<0 ){ - imageY = -y; - imageH += y; - y = 0; - TestPoint(0); - }else{ - imageY = 0; - TestPoint(0); - } - x = pElem->image.x - drawableLeft; - if( pElem->image.x + pElem->image.w > drawableRight ){ - imageW = drawableRight - pElem->image.x; - TestPoint(0); - }else{ - imageW = pElem->image.w; - TestPoint(0); - } - if( x<0 ){ - imageX = -x; - imageW += x; - x = 0; - TestPoint(0); - }else{ - imageX = 0; - TestPoint(0); - } - Tk_RedrawImage(pElem->image.pImage->image, imageX, imageY, imageW, imageH, - drawable, x, y); - pElem->image.redrawNeeded = 0; -} - -/* -** Recompute the following fields of the given block structure: -** -** base.count The number of elements described by this -** block structure. -** -** n The number of characters of text output -** associated with this block. If the block -** renders something other than text (ex: <IMG>) -** then set n to 0. -** -** z Pointer to malloced memory containing the -** text associated with this block. NULL if -** n is 0. -** -** Return a pointer to the first HtmlElement not covered by the -** block. -*/ -static HtmlElement *FillOutBlock(HtmlWidget *htmlPtr, HtmlBlock *p){ - HtmlElement *pElem; - int go; - int n; - int x, y; - int i; - HtmlStyle style; - int firstSelected; /* First selected character in this block */ - int lastSelected; /* Last selected character in this block */ - char zBuf[400]; - - /* - ** Reset n and z - */ - if( p->n ){ - p->n = 0; - } - if( p->z ){ - HtmlFree(p->z); - } - firstSelected = 1000000; - lastSelected = -1; - - /* - ** Skip over HtmlElements that aren't directly displayed. - */ - pElem = p->base.pNext; - p->base.count = 0; - while( pElem && (pElem->base.flags & HTML_Visible)==0 ){ - HtmlElement *pNext = pElem->pNext; - if( pElem->base.type==Html_Block ){ - UnlinkAndFreeBlock(htmlPtr, &pElem->block); - TestPoint(0); - }else{ - p->base.count++; - TestPoint(0); - } - pElem = pNext; - } - if( pElem==0 ){ TestPoint(0); return 0; } - - /* - ** Handle "special" elements. - */ - if( pElem->base.type!=Html_Text ){ - switch( pElem->base.type ){ - case Html_HR: - p->top = pElem->hr.y - pElem->hr.h; - p->bottom = pElem->hr.y; - p->left = pElem->hr.x; - p->right = pElem->hr.x + pElem->hr.w; - TestPoint(0); - break; - case Html_LI: - p->top = pElem->li.y - pElem->li.ascent; - p->bottom = pElem->li.y + pElem->li.descent; - p->left = pElem->li.x - 10; - p->right = pElem->li.x + 10; - TestPoint(0); - break; - case Html_TD: - case Html_TH: - p->top = pElem->cell.y; - p->bottom = pElem->cell.y + pElem->cell.h; - p->left = pElem->cell.x; - p->right = pElem->cell.x + pElem->cell.w; - TestPoint(0); - break; - case Html_TABLE: - p->top = pElem->table.y; - p->bottom = pElem->table.y + pElem->table.h; - p->left = pElem->table.x; - p->right = pElem->table.x + pElem->table.w; - TestPoint(0); - break; - case Html_IMG: - p->top = pElem->image.y - pElem->image.ascent; - p->bottom = pElem->image.y + pElem->image.descent; - p->left = pElem->image.x; - p->right = pElem->image.x + pElem->image.w; - TestPoint(0); - break; - } - p->base.count++; - TestPoint(0); - return pElem->pNext; - } - - /* - ** If we get this far, we must be dealing with text. - */ - n = 0; - x = pElem->text.x; - y = pElem->text.y; - p->top = y - pElem->text.ascent; - p->bottom = y + pElem->text.descent; - p->left = x; - style = pElem->base.style; - go = 1; - while( pElem ){ - HtmlElement *pNext = pElem->pNext; - switch( pElem->base.type ){ - case Html_Text: - if( pElem->base.style.flags & STY_Invisible ){ - TestPoint(0); - break; - } - if( pElem->text.spaceWidth <=0 ){ - CANT_HAPPEN; - break; - } - if( y != pElem->text.y - || style.font != pElem->base.style.font - || style.color != pElem->base.style.color - || (style.flags & STY_FontMask) - != (pElem->base.style.flags & STY_FontMask) - ){ - go = 0; - TestPoint(0); - }else{ - int sw = pElem->text.spaceWidth; - int nSpace = (pElem->text.x - x) / sw; - if( nSpace * sw + x != pElem->text.x ){ - go = 0; - TestPoint(0); - }else if( n + nSpace + pElem->base.count >= sizeof(zBuf) ){ - go = 0; - TestPoint(0); - }else{ - for(i=0; i<nSpace; i++){ - zBuf[n++] = ' '; - TestPoint(0); - } - strcpy(&zBuf[n], pElem->text.zText); - n += pElem->base.count; - x = pElem->text.x + pElem->text.w; - } - } - break; - - case Html_Space: - if( pElem->base.style.font != style.font ){ - pElem = pElem->pNext; - go = 0; - }else if( (style.flags & STY_Preformatted)!=0 - && (pElem->base.flags & HTML_NewLine)!=0 ){ - pElem = pElem->pNext; - go = 0; - } - break; - - case Html_Block: - UnlinkAndFreeBlock(htmlPtr,&pElem->block); - break; - - case Html_A: - case Html_EndA: - go = 0; - break; - - default: - if( pElem->base.flags & HTML_Visible ) go = 0; - TestPoint(0); - break; - } - if( go==0 ) break; - p->base.count++; - pElem = pNext; - } - p->right = x; - - while( n>0 && zBuf[n-1]==' ' ){ TestPoint(0); n--; } - p->z = HtmlAlloc( n ); - strncpy(p->z, zBuf, n); - p->n = n; - return pElem; -} - -/* -** Scan ahead looking for a place to put a block. Return a pointer -** to the element which should come immediately after the block. -** -** if pCnt!=0, then put the number of elements skipped in *pCnt. -*/ -static HtmlElement *FindStartOfNextBlock( - HtmlWidget *htmlPtr, /* The HTML widget */ - HtmlElement *p, /* First candid for the start of a block */ - int *pCnt /* Write number of elements skipped here */ -){ - int cnt = 0; - - while( p && (p->base.flags & HTML_Visible)==0 ){ - HtmlElement *pNext = p->pNext; - if( p->base.type==Html_Block ){ - UnlinkAndFreeBlock(htmlPtr, &p->block); - }else{ - cnt++; - } - p = pNext; - } - if( pCnt ){ *pCnt = cnt; } - return p; -} - - -/* -** Add additional blocks to the block list in order to cover -** all elements on the element list. -** -** If any old blocks are found on the element list, they must -** be left over from a prior rendering. Unlink and delete them. -*/ -void HtmlFormBlocks(HtmlWidget *htmlPtr){ - HtmlElement *pElem; - - if( htmlPtr->lastBlock ){ - pElem = FillOutBlock(htmlPtr, htmlPtr->lastBlock); - }else{ - pElem = htmlPtr->pFirst; - } - while( pElem ){ - int cnt; - pElem = FindStartOfNextBlock(htmlPtr, pElem, &cnt); - if( pElem ){ - HtmlBlock *pNew = AllocBlock(); - if( htmlPtr->lastBlock ){ - htmlPtr->lastBlock->base.count += cnt; - } - AppendBlock(htmlPtr, pElem, pNew); - pElem = FillOutBlock(htmlPtr, pNew); - } - } -} |