/* ** Routines used for processing markup ** ** 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 #include #include #include "htmlimage.h" /* ** Find the alignment for an image */ int HtmlGetImageAlignment(HtmlElement *p){ char *z; int i; int result; static struct { char *zName; int iValue; } aligns[] = { { "bottom", IMAGE_ALIGN_Bottom }, { "baseline", IMAGE_ALIGN_Bottom }, { "middle", IMAGE_ALIGN_Middle }, { "top", IMAGE_ALIGN_Top }, { "absbottom", IMAGE_ALIGN_AbsBottom }, { "absmiddle", IMAGE_ALIGN_AbsMiddle }, { "texttop", IMAGE_ALIGN_TextTop }, { "left", IMAGE_ALIGN_Left }, { "right", IMAGE_ALIGN_Right }, }; z = HtmlMarkupArg(p, "align", 0); result = IMAGE_ALIGN_Bottom; if( z ){ for(i=0; ihtmlPtr; if( pImage->w!=newWidth || pImage->h!=newHeight ){ /* We have to completely redo the layout after adjusting the size ** of the images */ for(pElem = pImage->pList; pElem; pElem = pElem->image.pNext){ pElem->image.w = newWidth; pElem->image.h = newHeight; TestPoint(0); } htmlPtr->flags |= RELAYOUT; pImage->w = newWidth; pImage->h = newHeight; HtmlRedrawEverything(htmlPtr); }else{ for(pElem = pImage->pList; pElem; pElem = pElem->image.pNext){ pElem->image.redrawNeeded = 1; } htmlPtr->flags |= REDRAW_IMAGES; HtmlScheduleRedraw(htmlPtr); } } /* ** Append all the arguments of the given markup to the given ** DString. ** ** Example: If the markup is hello! ** then the following text is appended to the DString: ** ** "src image.gif alt hello!" ** ** Notice how all attribute names are converted to lower case. ** This conversion happens in the parser. */ void HtmlAppendArglist(Tcl_DString *str, HtmlElement *pElem){ int i; for(i=0; i+1base.count; i+=2){ char *z = pElem->markup.argv[i+1]; Tcl_DStringAppendElement(str, pElem->markup.argv[i]); Tcl_DStringAppendElement(str, z); } } /* ** Given an markup, find or create an appropriate HtmlImage ** structure and return a pointer to that structure. NULL might ** be returned. ** ** This routine may invoke a callback procedure which could delete ** the HTML widget. Use HtmlLock() if necessary to preserve the ** widget structure. */ HtmlImage *HtmlGetImage(HtmlWidget *htmlPtr, HtmlElement *p){ char *zWidth; char *zHeight; char *zSrc; char *zImageName; HtmlImage *pImage; int result; Tcl_DString cmd; int lenSrc, lenW, lenH; /* Lengths of various strings */ if( p->base.type!=Html_IMG ){ CANT_HAPPEN; return 0; } if( htmlPtr->zGetImage==0 || htmlPtr->zGetImage[0]==0 ){ TestPoint(0); return 0; } zSrc = HtmlMarkupArg(p, "src", 0); if( zSrc==0 ){ return 0; } HtmlLock(htmlPtr); zSrc = HtmlResolveUri(htmlPtr, zSrc); if( HtmlUnlock(htmlPtr) || zSrc==0 ) return 0; zWidth = HtmlMarkupArg(p, "width", ""); zHeight = HtmlMarkupArg(p, "height", ""); for(pImage=htmlPtr->imageList; pImage; pImage=pImage->pNext){ if( strcmp(pImage->zUrl,zSrc)==0 && strcmp(pImage->zWidth, zWidth)==0 && strcmp(pImage->zHeight, zHeight)==0 ){ HtmlFree(zSrc); return pImage; } } Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, htmlPtr->zGetImage, -1); Tcl_DStringAppendElement(&cmd,zSrc); Tcl_DStringAppendElement(&cmd,zWidth); Tcl_DStringAppendElement(&cmd,zHeight); Tcl_DStringStartSublist(&cmd); HtmlAppendArglist(&cmd, p); Tcl_DStringEndSublist(&cmd); HtmlLock(htmlPtr); result = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd)); Tcl_DStringFree(&cmd); if( HtmlUnlock(htmlPtr) ){ HtmlFree(zSrc); } zImageName = (char*)Tcl_GetStringResult(htmlPtr->interp); lenSrc = strlen(zSrc); lenW = strlen(zWidth); lenH = strlen(zHeight); pImage = HtmlAlloc( sizeof(HtmlImage) + lenSrc + lenW + lenH + 3 ); memset(pImage,0,sizeof(HtmlImage)); pImage->htmlPtr = htmlPtr; pImage->zUrl = (char*)&pImage[1]; strcpy(pImage->zUrl,zSrc); HtmlFree(zSrc); pImage->zWidth = &pImage->zUrl[lenSrc+1]; strcpy(pImage->zWidth, zWidth); pImage->zHeight = &pImage->zWidth[lenW+1]; strcpy(pImage->zHeight, zHeight); pImage->w = 0; pImage->h = 0; if( result==TCL_OK ){ pImage->image = Tk_GetImage(htmlPtr->interp, htmlPtr->clipwin, zImageName, ImageChangeProc, pImage); TestPoint(0); }else{ Tcl_AddErrorInfo(htmlPtr->interp, "\n (\"-imagecommand\" command executed by html widget)"); Tcl_BackgroundError(htmlPtr->interp); pImage->image = 0; TestPoint(0); } if( pImage->image==0 ){ HtmlFree((char*)pImage); TestPoint(0); return 0; } pImage->pNext = htmlPtr->imageList; htmlPtr->imageList = pImage; TestPoint(0); Tcl_ResetResult(htmlPtr->interp); return pImage; }