TGHtmlImage.cxx

Go to the documentation of this file.
00001 // $Id: TGHtmlImage.cxx,v 1.2 2007/05/07 15:28:48 brun Exp $
00002 // Author:  Valeriy Onuchin   03/05/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 /**************************************************************************
00013 
00014     HTML widget for xclass. Based on tkhtml 1.28
00015     Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
00016     Copyright (C) 2002-2003 Hector Peraza.
00017 
00018     This library is free software; you can redistribute it and/or
00019     modify it under the terms of the GNU Library General Public
00020     License as published by the Free Software Foundation; either
00021     version 2 of the License, or (at your option) any later version.
00022 
00023     This library is distributed in the hope that it will be useful,
00024     but WITHOUT ANY WARRANTY; without even the implied warranty of
00025     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026     Library General Public License for more details.
00027 
00028     You should have received a copy of the GNU Library General Public
00029     License along with this library; if not, write to the Free
00030     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00031 
00032 **************************************************************************/
00033 
00034 // Routines used for processing <IMG> markup
00035 
00036 #include <string.h>
00037 #include <stdlib.h>
00038 
00039 #include "TGHtml.h"
00040 //#include <TGHtmlUri.h>
00041 #include "TImage.h"
00042 #include "TUrl.h"
00043 #include "TSocket.h"
00044 #include "TSystem.h"
00045 
00046 //______________________________________________________________________________
00047 TGHtmlImage::TGHtmlImage(TGHtml *htm, const char *url, const char *width,
00048                        const char *height)
00049 {
00050    // ctor.
00051 
00052    fHtml = htm;
00053    fZUrl = StrDup(url);
00054    fZWidth = StrDup(width);
00055    fZHeight = StrDup(height);
00056    fImage = NULL;
00057    fPNext = NULL;
00058    fPList = NULL;
00059    fW = 0;
00060    fH = 0;
00061    fTimer = NULL;
00062 }
00063 
00064 //______________________________________________________________________________
00065 TGHtmlImage::~TGHtmlImage()
00066 {
00067    //  dtor.
00068 
00069    delete [] fZUrl;
00070    delete [] fZWidth;
00071    delete [] fZHeight;
00072 
00073    if (fImage) delete fImage;
00074    if (fTimer) delete fTimer;
00075 }
00076 
00077 //______________________________________________________________________________
00078 int TGHtml::GetImageAlignment(TGHtmlElement *p)
00079 {
00080    // Find the alignment for an image
00081 
00082    const char *z;
00083    int i;
00084    int result;
00085 
00086    static struct {
00087       const char *zName;
00088       int iValue;
00089    } aligns[] = {
00090       { "bottom",    IMAGE_ALIGN_Bottom    },
00091       { "baseline",  IMAGE_ALIGN_Bottom    },
00092       { "middle",    IMAGE_ALIGN_Middle    },
00093       { "top",       IMAGE_ALIGN_Top       },
00094       { "absbottom", IMAGE_ALIGN_AbsBottom },
00095       { "absmiddle", IMAGE_ALIGN_AbsMiddle },
00096       { "texttop",   IMAGE_ALIGN_TextTop   },
00097       { "left",      IMAGE_ALIGN_Left      },
00098       { "right",     IMAGE_ALIGN_Right     },
00099    };
00100 
00101    z = p->MarkupArg("align", 0);
00102    result = IMAGE_ALIGN_Bottom;
00103    if (z) {
00104       for (i = 0; i < int(sizeof(aligns) / sizeof(aligns[0])); i++) {
00105          if (strcasecmp(aligns[i].zName, z) == 0) {
00106             result = aligns[i].iValue;
00107             break;
00108          }
00109       }
00110    }
00111    return result;
00112 }
00113 
00114 //______________________________________________________________________________
00115 void TGHtml::ImageChanged(TGHtmlImage *pImage, int newWidth, int newHeight)
00116 {
00117    // This routine is called when an image changes. If the size of the
00118    // images changes, then we need to completely redo the layout. If
00119    // only the appearance changes, then this works like an expose event.
00120    //
00121    // pImage    - Pointer to an TGHtmlImage object
00122    // newWidth  - New width of the image
00123    // newHeight - New height of the image
00124 
00125    TGHtmlImageMarkup *pElem;
00126 
00127    if (pImage->fW != newWidth || pImage->fH != newHeight) {
00128       // We have to completely redo the layout after adjusting the size
00129       // of the images
00130       for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
00131          pElem->fW = newWidth;
00132          pElem->fH = newHeight;
00133       }
00134       fFlags |= RELAYOUT;
00135       pImage->fW = newWidth;
00136       pImage->fH = newHeight;
00137       RedrawEverything();
00138    } else {
00139 #if 0
00140       for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
00141          pElem->fRedrawNeeded = 1;
00142       }
00143       fFlags |= REDRAW_IMAGES;
00144       ScheduleRedraw();
00145 #else
00146       for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
00147          pElem->fRedrawNeeded = 1;
00148          DrawRegion(pElem->fX, pElem->fY - pElem->fAscent, pElem->fW, pElem->fH);
00149       }
00150 #endif
00151    }
00152 }
00153 
00154 //______________________________________________________________________________
00155 TGHtmlImage *TGHtml::GetImage(TGHtmlImageMarkup *p)
00156 {
00157    // Given an <IMG> markup, find or create an appropriate TGHtmlImage
00158    // object and return a pointer to that object. NULL might be returned.
00159 
00160    const char *zWidth;
00161    const char *zHeight;
00162    const char *zSrc;
00163    TGHtmlImage *pImage;
00164 
00165    if (p->fType != Html_IMG) { CANT_HAPPEN; return 0; }
00166 
00167    zSrc = p->MarkupArg("src", 0);
00168    if (zSrc == 0) return 0;
00169 
00170    zSrc = ResolveUri(zSrc);
00171    if (zSrc == 0) return 0;
00172 
00173    zWidth = p->MarkupArg("width", "");
00174    zHeight = p->MarkupArg("height", "");
00175 
00176    //p->w = atoi(fZWidth);
00177    //p->h = atoi(zHeight);
00178 
00179    for (pImage = fImageList; pImage; pImage = pImage->fPNext) {
00180       if (strcmp(pImage->fZUrl, zSrc) == 0
00181           &&  strcmp(pImage->fZWidth, zWidth) == 0
00182           &&  strcmp(pImage->fZHeight, zHeight) == 0) {
00183          delete [] zSrc;
00184          return pImage;
00185       }
00186    }
00187 
00188    TImage *img = LoadImage(zSrc, atoi(zWidth), atoi(zHeight));
00189 
00190    if (img) {
00191       pImage = new TGHtmlImage(this, zSrc, zWidth, zHeight);
00192       pImage->fImage = img;
00193     //if (img->IsAnimated()) {
00194     //  pImage->timer = new TTimer(this, img->GetAnimDelay());
00195     //}
00196       ImageChanged(pImage, img->GetWidth(), img->GetHeight());
00197       pImage->fPNext = fImageList;
00198       fImageList = pImage;
00199    } else {
00200       pImage = 0;
00201    }
00202 
00203    delete [] zSrc;
00204 
00205    return pImage;
00206 }
00207 
00208 //______________________________________________________________________________
00209 static TImage *ReadRemoteImage(const char *url)
00210 {
00211    // Temporary function to read remote pictures
00212 
00213    TImage *image = 0;
00214    FILE *tmp;
00215    char *buf;
00216    TUrl fUrl(url);
00217 
00218    TString msg = "GET ";
00219    msg += fUrl.GetProtocol();
00220    msg += "://";
00221    msg += fUrl.GetHost();
00222    msg += ":";
00223    msg += fUrl.GetPort();
00224    msg += "/";
00225    msg += fUrl.GetFile();
00226    msg += "\r\n";
00227 
00228    TString uri(url);
00229    if (!uri.BeginsWith("http://") || uri.EndsWith(".html"))
00230       return 0;
00231    TSocket s(fUrl.GetHost(), fUrl.GetPort());
00232    if (!s.IsValid())
00233       return 0;
00234    if (s.SendRaw(msg.Data(), msg.Length()) == -1)
00235       return 0;
00236    Int_t size = 1024*1024;
00237    buf = (char *)calloc(size, sizeof(char));
00238    if (s.RecvRaw(buf, size) == -1) {
00239       free(buf);
00240       return 0;
00241    }
00242    TString pathtmp = TString::Format("%s/%s", gSystem->TempDirectory(), 
00243                                      gSystem->BaseName(url));
00244    tmp = fopen(pathtmp.Data(), "wb");
00245    if (!tmp) {
00246       free(buf);
00247       return 0;
00248    }
00249    fwrite(buf, sizeof(char), size, tmp);
00250    fclose(tmp);
00251    free(buf);
00252    image = TImage::Open(pathtmp.Data());
00253    if (!image->IsValid()) {
00254       delete image;
00255       image = 0;
00256    }
00257    gSystem->Unlink(pathtmp.Data());
00258    return image;
00259 }
00260 
00261 //______________________________________________________________________________
00262 TImage *TGHtml::LoadImage(const char *url, int w, int h)
00263 {
00264    // This is the default LoadImage() procedure. It just tries to load the
00265    // image from a file in the local filesystem.
00266 
00267    TImage *image = 0;
00268 
00269    //TGHtmlUri uri(url);
00270 
00271    TString uri(url);
00272    if (uri.BeginsWith("http://") && !uri.EndsWith(".html"))
00273       image = ReadRemoteImage(url);
00274    else
00275       image = TImage::Open(url);
00276    if (image) {
00277       if (!image->IsValid()) {
00278          delete image;
00279          image = 0;
00280          return 0;
00281       }
00282       if ((w > 0 && h > 0) && ((w != (int)image->GetWidth()) ||
00283           (h != (int)image->GetHeight()))) {
00284          image->Scale(w, h);
00285       }
00286    }
00287    return image;
00288 }
00289 
00290 //______________________________________________________________________________
00291 const char *TGHtml::GetPctWidth(TGHtmlElement *p, char *opt, char *ret)
00292 {
00293    // Return the height and width, converting to percent if required
00294    // ret must be at least 16 characters long
00295 
00296    int n, m, val;
00297    const char *tz, *z;
00298    TGHtmlElement *pElem = p;
00299 
00300    z = pElem->MarkupArg(opt, "");
00301    if (!strchr(z, '%')) return z;
00302    if (!sscanf(z, "%d", &n)) return z;
00303    if (n < 0 || n > 100) return z;
00304    if (opt[0] == 'h') {
00305       val = fCanvas->GetHeight() * 100;
00306    } else {
00307       val = fCanvas->GetWidth() * 100;
00308    }
00309    if (!fInTd) {
00310       snprintf(ret, 15, "%d", val / n);
00311    } else {
00312       while (pElem && pElem->fType != Html_TD) pElem = pElem->fPPrev;
00313       if (!pElem) return z;
00314       tz = pElem->MarkupArg(opt, 0);
00315       if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
00316          snprintf(ret, 15, "%d", m * 100 / n);
00317          return ret;
00318       }
00319       pElem = ((TGHtmlCell *)pElem)->fPTable;
00320       if (!pElem) return z;
00321       tz = pElem->MarkupArg(opt, 0);
00322       if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
00323          snprintf(ret, 15, "%d", m * 100 / n);
00324          return ret;
00325       }
00326       return z;
00327    }
00328    return ret;
00329 }
00330 
00331 //______________________________________________________________________________
00332 int TGHtml::GetImageAt(int x, int y)
00333 {
00334    // This routine searchs for an image beneath the coordinates x,y
00335    // and returns the token number of the the image, or -1 if no
00336    // image found.
00337 
00338    TGHtmlBlock *pBlock;
00339    TGHtmlElement *pElem;
00340    //int n;
00341 
00342    for (pBlock = fFirstBlock; pBlock; pBlock = pBlock->fBNext) {
00343       if (pBlock->fTop > y || pBlock->fBottom < y ||
00344           pBlock->fLeft > x || pBlock->fRight < x) {
00345          continue;
00346       }
00347       for (pElem = pBlock->fPNext; pElem; pElem = pElem->fPNext) {
00348          if (pBlock->fBNext && pElem == pBlock->fBNext->fPNext) break;
00349          if (pElem->fType == Html_IMG) {
00350             return TokenNumber(pElem);
00351          }
00352       }
00353    }
00354 
00355    return -1;
00356 }

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