summaryrefslogtreecommitdiffstats
path: root/tkhtml1/src/htmlimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'tkhtml1/src/htmlimage.c')
-rw-r--r--tkhtml1/src/htmlimage.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/tkhtml1/src/htmlimage.c b/tkhtml1/src/htmlimage.c
new file mode 100644
index 0000000..962ac5c
--- /dev/null
+++ b/tkhtml1/src/htmlimage.c
@@ -0,0 +1,225 @@
+/*
+** Routines used for processing <IMG> 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 <tk.h>
+#include <string.h>
+#include <stdlib.h>
+#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; i<sizeof(aligns)/sizeof(aligns[0]); i++){
+ if( stricmp(aligns[i].zName,z)==0 ){
+ result = aligns[i].iValue;
+ TestPoint(0);
+ break;
+ }else{
+ TestPoint(0);
+ }
+ }
+ }else{
+ TestPoint(0);
+ }
+ return result;
+}
+
+/*
+** This routine is called when an image changes. If the size of the
+** images changes, then we need to completely redo the layout. If
+** only the appearance changes, then this works like an expose event.
+*/
+static void ImageChangeProc(
+ ClientData clientData, /* Pointer to an HtmlImage structure */
+ int x, /* Left edge of region that changed */
+ int y, /* Top edge of region that changed */
+ int w, /* Width of region that changes. Maybe 0 */
+ int h, /* Height of region that changed. Maybe 0 */
+ int newWidth, /* New width of the image */
+ int newHeight /* New height of the image */
+){
+ HtmlImage *pImage;
+ HtmlWidget *htmlPtr;
+ HtmlElement *pElem;
+
+ pImage = (HtmlImage*)clientData;
+ htmlPtr = pImage->htmlPtr;
+ 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 <IMG SRC=image.gif ALT="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+1<pElem->base.count; i+=2){
+ char *z = pElem->markup.argv[i+1];
+ Tcl_DStringAppendElement(str, pElem->markup.argv[i]);
+ Tcl_DStringAppendElement(str, z);
+ }
+}
+
+/*
+** Given an <IMG> 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;
+}