Logo ROOT   master
Reference Guide
TGHtmlImage.cxx
Go to the documentation of this file.
1 // $Id: TGHtmlImage.cxx,v 1.2 2007/05/07 15:28:48 brun Exp $
2 // Author: Valeriy Onuchin 03/05/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**************************************************************************
13 
14  HTML widget for xclass. Based on tkhtml 1.28
15  Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
16  Copyright (C) 2002-2003 Hector Peraza.
17 
18  This library is free software; you can redistribute it and/or
19  modify it under the terms of the GNU Library General Public
20  License as published by the Free Software Foundation; either
21  version 2 of the License, or (at your option) any later version.
22 
23  This library is distributed in the hope that it will be useful,
24  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26  Library General Public License for more details.
27 
28  You should have received a copy of the GNU Library General Public
29  License along with this library; if not, write to the Free
30  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 
32 **************************************************************************/
33 
34 // Routines used for processing <IMG> markup
35 
36 #include <string.h>
37 #include <stdlib.h>
38 
39 #include "TGHtml.h"
40 //#include <TGHtmlUri.h>
41 #include "TImage.h"
42 #include "TUrl.h"
43 #include "TSocket.h"
44 #include "TSystem.h"
45 #include "TError.h"
46 #ifdef R__SSL
47 #include "TSSLSocket.h"
48 #endif
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// ctor.
52 
53 TGHtmlImage::TGHtmlImage(TGHtml *htm, const char *url, const char *width,
54  const char *height)
55 {
56  fHtml = htm;
57  fZUrl = StrDup(url);
58  fZWidth = StrDup(width);
59  fZHeight = StrDup(height);
60  fImage = NULL;
61  fPNext = NULL;
62  fPList = NULL;
63  fW = 0;
64  fH = 0;
65  fTimer = NULL;
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// dtor.
70 
72 {
73  delete [] fZUrl;
74  delete [] fZWidth;
75  delete [] fZHeight;
76 
77  if (fImage) delete fImage;
78  if (fTimer) delete fTimer;
79 }
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// Find the alignment for an image
83 
85 {
86  const char *z;
87  int i;
88  int result;
89 
90  static struct {
91  const char *zName;
92  int iValue;
93  } aligns[] = {
94  { "bottom", IMAGE_ALIGN_Bottom },
95  { "baseline", IMAGE_ALIGN_Bottom },
96  { "middle", IMAGE_ALIGN_Middle },
97  { "top", IMAGE_ALIGN_Top },
98  { "absbottom", IMAGE_ALIGN_AbsBottom },
99  { "absmiddle", IMAGE_ALIGN_AbsMiddle },
100  { "texttop", IMAGE_ALIGN_TextTop },
101  { "left", IMAGE_ALIGN_Left },
102  { "right", IMAGE_ALIGN_Right },
103  };
104 
105  z = p->MarkupArg("align", 0);
106  result = IMAGE_ALIGN_Bottom;
107  if (z) {
108  for (i = 0; i < int(sizeof(aligns) / sizeof(aligns[0])); i++) {
109  if (strcasecmp(aligns[i].zName, z) == 0) {
110  result = aligns[i].iValue;
111  break;
112  }
113  }
114  }
115  return result;
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// This routine is called when an image changes. If the size of the
120 /// images changes, then we need to completely redo the layout. If
121 /// only the appearance changes, then this works like an expose event.
122 ///
123 /// pImage - Pointer to an TGHtmlImage object
124 /// newWidth - New width of the image
125 /// newHeight - New height of the image
126 
127 void TGHtml::ImageChanged(TGHtmlImage *pImage, int newWidth, int newHeight)
128 {
129  TGHtmlImageMarkup *pElem;
130 
131  if (pImage->fW != newWidth || pImage->fH != newHeight) {
132  // We have to completely redo the layout after adjusting the size
133  // of the images
134  for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
135  pElem->fW = newWidth;
136  pElem->fH = newHeight;
137  }
138  fFlags |= RELAYOUT;
139  pImage->fW = newWidth;
140  pImage->fH = newHeight;
142  } else {
143 #if 0
144  for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
145  pElem->fRedrawNeeded = 1;
146  }
148  ScheduleRedraw();
149 #else
150  for (pElem = pImage->fPList; pElem; pElem = pElem->fINext) {
151  pElem->fRedrawNeeded = 1;
152  DrawRegion(pElem->fX, pElem->fY - pElem->fAscent, pElem->fW, pElem->fH);
153  }
154 #endif
155  }
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 /// Given an <IMG> markup, find or create an appropriate TGHtmlImage
160 /// object and return a pointer to that object. NULL might be returned.
161 
163 {
164  const char *zWidth;
165  const char *zHeight;
166  const char *zSrc;
167  TGHtmlImage *pImage;
168 
169  if (p->fType != Html_IMG) { CANT_HAPPEN; return 0; }
170 
171  zSrc = p->MarkupArg("src", 0);
172  if (zSrc == 0) return 0;
173 
174  zSrc = ResolveUri(zSrc);
175  if (zSrc == 0) return 0;
176 
177  zWidth = p->MarkupArg("width", "");
178  zHeight = p->MarkupArg("height", "");
179 
180  //p->w = atoi(fZWidth);
181  //p->h = atoi(zHeight);
182 
183  for (pImage = fImageList; pImage; pImage = pImage->fPNext) {
184  if (strcmp(pImage->fZUrl, zSrc) == 0
185  && strcmp(pImage->fZWidth, zWidth) == 0
186  && strcmp(pImage->fZHeight, zHeight) == 0) {
187  delete [] zSrc;
188  return pImage;
189  }
190  }
191 
192  TImage *img = LoadImage(zSrc, atoi(zWidth), atoi(zHeight));
193 
194  if (img) {
195  pImage = new TGHtmlImage(this, zSrc, zWidth, zHeight);
196  pImage->fImage = img;
197  //if (img->IsAnimated()) {
198  // pImage->timer = new TTimer(this, img->GetAnimDelay());
199  //}
200  ImageChanged(pImage, img->GetWidth(), img->GetHeight());
201  pImage->fPNext = fImageList;
202  fImageList = pImage;
203  } else {
204  pImage = 0;
205  }
206 
207  delete [] zSrc;
208 
209  return pImage;
210 }
211 
212 ////////////////////////////////////////////////////////////////////////////////
213 /// Temporary function to read remote pictures
214 
215 static TImage *ReadRemoteImage(const char *url)
216 {
217  TImage *image = 0;
218  FILE *tmp;
219  char *buf;
220  TUrl fUrl(url);
221 
222  TString msg = "GET ";
223  msg += fUrl.GetProtocol();
224  msg += "://";
225  msg += fUrl.GetHost();
226  msg += ":";
227  msg += fUrl.GetPort();
228  msg += "/";
229  msg += fUrl.GetFile();
230  msg += "\r\n";
231 
232  TString uri(url);
233  if ((!uri.BeginsWith("http://") && !uri.BeginsWith("https://")) ||
234  uri.EndsWith(".html"))
235  return 0;
236  TSocket *s;
237  if (uri.BeginsWith("https://")) {
238 #ifdef R__SSL
239  s = new TSSLSocket(fUrl.GetHost(), fUrl.GetPort());
240 #else
241  ::Error("ReadRemoteImage", "library compiled without SSL, https not supported");
242  return 0;
243 #endif
244  }
245  else {
246  s = new TSocket(fUrl.GetHost(), fUrl.GetPort());
247  }
248  if (!s->IsValid()) {
249  delete s;
250  return 0;
251  }
252  if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
253  delete s;
254  return 0;
255  }
256  Int_t size = 1024*1024;
257  buf = (char *)calloc(size, sizeof(char));
258  if (!buf) {
259  delete s;
260  return 0;
261  }
262  if (s->RecvRaw(buf, size) == -1) {
263  free(buf);
264  delete s;
265  return 0;
266  }
267  TString pathtmp = TString::Format("%s/%s", gSystem->TempDirectory(),
268  gSystem->BaseName(url));
269  tmp = fopen(pathtmp.Data(), "wb");
270  if (!tmp) {
271  free(buf);
272  delete s;
273  return 0;
274  }
275  fwrite(buf, sizeof(char), size, tmp);
276  fclose(tmp);
277  free(buf);
278  image = TImage::Open(pathtmp.Data());
279  if (image && !image->IsValid()) {
280  delete image;
281  image = 0;
282  }
283  gSystem->Unlink(pathtmp.Data());
284  delete s;
285  return image;
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// This is the default LoadImage() procedure. It just tries to load the
290 /// image from a file in the local filesystem.
291 
292 TImage *TGHtml::LoadImage(const char *url, int w, int h)
293 {
294  TImage *image = 0;
295 
296  //TGHtmlUri uri(url);
297 
298  TString uri(url);
299  if ((uri.BeginsWith("http://") || uri.BeginsWith("https://")) &&
300  !uri.EndsWith(".html"))
301  image = ReadRemoteImage(url);
302  else
303  image = TImage::Open(url);
304  if (image) {
305  if (!image->IsValid()) {
306  delete image;
307  image = 0;
308  return 0;
309  }
310  if ((w > 0 && h > 0) && ((w != (int)image->GetWidth()) ||
311  (h != (int)image->GetHeight()))) {
312  image->Scale(w, h);
313  }
314  }
315  return image;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Return the height and width, converting to percent if required
320 /// ret must be at least 16 characters long
321 
322 const char *TGHtml::GetPctWidth(TGHtmlElement *p, char *opt, char *ret)
323 {
324  int n, m, val;
325  const char *tz, *z;
326  TGHtmlElement *pElem = p;
327 
328  z = pElem->MarkupArg(opt, "");
329  if (!z) return z;
330  if (!strchr(z, '%')) return z;
331  // coverity[secure_coding]
332  if (!sscanf(z, "%d", &n)) return z;
333  if (n <= 0 || n > 100) return z;
334  if (opt[0] == 'h') {
335  val = fCanvas->GetHeight() * 100;
336  } else {
337  val = fCanvas->GetWidth() * 100;
338  }
339  if (!fInTd) {
340  snprintf(ret, 15, "%d", val / n);
341  } else {
342  while (pElem && pElem->fType != Html_TD) pElem = pElem->fPPrev;
343  if (!pElem) return z;
344  tz = pElem->MarkupArg(opt, 0);
345  // coverity[secure_coding]
346  if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
347  snprintf(ret, 15, "%d", m * 100 / n);
348  return ret;
349  }
350  pElem = ((TGHtmlCell *)pElem)->fPTable;
351  if (!pElem) return z;
352  tz = pElem->MarkupArg(opt, 0);
353  // coverity[secure_coding]
354  if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
355  snprintf(ret, 15, "%d", m * 100 / n);
356  return ret;
357  }
358  return z;
359  }
360  return ret;
361 }
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /// This routine searchs for an image beneath the coordinates x,y
365 /// and returns the token number of the the image, or -1 if no
366 /// image found.
367 
368 int TGHtml::GetImageAt(int x, int y)
369 {
370  TGHtmlBlock *pBlock;
371  TGHtmlElement *pElem;
372  //int n;
373 
374  for (pBlock = fFirstBlock; pBlock; pBlock = pBlock->fBNext) {
375  if (pBlock->fTop > y || pBlock->fBottom < y ||
376  pBlock->fLeft > x || pBlock->fRight < x) {
377  continue;
378  }
379  for (pElem = pBlock->fPNext; pElem; pElem = pElem->fPNext) {
380  if (pBlock->fBNext && pElem == pBlock->fBNext->fPNext) break;
381  if (pElem->fType == Html_IMG) {
382  return TokenNumber(pElem);
383  }
384  }
385  }
386 
387  return -1;
388 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:930
char * fZHeight
Definition: TGHtml.h:522
#define IMAGE_ALIGN_Left
Definition: TGHtml.h:566
#define IMAGE_ALIGN_TextTop
Definition: TGHtml.h:563
auto * m
Definition: textangle.C:8
int fTop
Definition: TGHtml.h:717
virtual UInt_t GetHeight() const
Definition: TImage.h:229
TGHtmlImageMarkup * fINext
Definition: TGHtml.h:553
Html_16_t fAscent
Definition: TGHtml.h:546
virtual void DrawRegion(Int_t x, Int_t y, UInt_t w, UInt_t h)
Draw region defined by [x,y] [w,h].
Definition: TGHtml.cxx:794
char * fZUrl
Definition: TGHtml.h:521
#define REDRAW_IMAGES
Definition: TGHtml.h:1331
Html_u16_t fRight
Definition: TGHtml.h:718
virtual UInt_t GetWidth() const
Definition: TImage.h:228
virtual Bool_t IsValid() const
Definition: TImage.h:230
Html_16_t fX
Definition: TGHtml.h:548
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetProtocol() const
Definition: TUrl.h:66
UInt_t GetHeight() const
Definition: TGFrame.h:250
TGHtmlBlock * fFirstBlock
Definition: TGHtml.h:1135
TGHtmlImage * fImageList
Definition: TGHtml.h:1236
Basic string class.
Definition: TString.h:131
int Int_t
Definition: RtypesCore.h:43
void ScheduleRedraw()
Make sure that a call to the Redraw() routine has been queued.
Definition: TGHtml.cxx:751
An abstract interface to image processing library.
Definition: TImage.h:29
void RedrawEverything()
Call this routine to force the entire widget to be redrawn.
Definition: TGHtml.cxx:866
UInt_t GetWidth() const
Definition: TGFrame.h:249
Html_16_t fW
Definition: TGHtml.h:545
Definition: TGHtml.h:872
TGHtmlElement * fPNext
Definition: TGHtml.h:261
const char * GetPctWidth(TGHtmlElement *p, char *opt, char *ret)
Return the height and width, converting to percent if required ret must be at least 16 characters lon...
virtual void Scale(UInt_t, UInt_t)
Definition: TImage.h:141
const char * GetFile() const
Definition: TUrl.h:71
TTimer * fTimer
Definition: TGHtml.h:526
const char * GetHost() const
Definition: TUrl.h:69
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1376
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2311
virtual const char * MarkupArg(const char *, const char *)
Definition: TGHtml.h:254
char * fZWidth
Definition: TGHtml.h:522
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
TGHtmlElement * fPPrev
Definition: TGHtml.h:262
static constexpr double s
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1477
TGHtmlBlock * fBNext
Definition: TGHtml.h:720
void Error(const char *location, const char *msgfmt,...)
Html_u8_t fRedrawNeeded
Definition: TGHtml.h:542
virtual char * ResolveUri(const char *uri)
This function resolves the specified URI and returns the result in a newly allocated string...
Definition: TGHtmlUri.cxx:307
Html_32_t fY
Definition: TGHtml.h:549
void ImageChanged(TGHtmlImage *image, int newWidth, int newHeight)
This routine is called when an image changes.
#define IMAGE_ALIGN_AbsBottom
Definition: TGHtml.h:565
#define IMAGE_ALIGN_Top
Definition: TGHtml.h:562
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
TGViewFrame * fCanvas
Definition: TGView.h:62
TImage * fImage
Definition: TGHtml.h:518
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
int GetImageAt(int x, int y)
This routine searchs for an image beneath the coordinates x,y and returns the token number of the the...
TGHtmlImage * fPNext
Definition: TGHtml.h:523
Ssiz_t Length() const
Definition: TString.h:405
#define calloc
Definition: civetweb.c:1537
Html_u8_t fType
Definition: TGHtml.h:264
#define h(i)
Definition: RSha256.hxx:106
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
virtual ~TGHtmlImage()
dtor.
Definition: TGHtmlImage.cxx:71
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
static TImage * ReadRemoteImage(const char *url)
Temporary function to read remote pictures.
TGHtmlImage * GetImage(TGHtmlImageMarkup *p)
Given an.
Html_32_t fH
Definition: TGHtml.h:520
TGHtmlImage(const TGHtmlImage &)
#define IMAGE_ALIGN_Middle
Definition: TGHtml.h:561
Html_16_t fH
Definition: TGHtml.h:544
#define free
Definition: civetweb.c:1539
Double_t y[n]
Definition: legend1.C:17
Int_t GetPort() const
Definition: TUrl.h:80
#define IMAGE_ALIGN_AbsMiddle
Definition: TGHtml.h:564
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
int TokenNumber(TGHtmlElement *p)
Return the token number for the given TGHtmlElement.
Definition: TGHtmlIndex.cxx:79
Html_u16_t fLeft
Definition: TGHtml.h:718
int fFlags
Definition: TGHtml.h:1269
#define CANT_HAPPEN
Definition: TGHtml.h:59
#define IMAGE_ALIGN_Bottom
Definition: TGHtml.h:560
TGHtml * fHtml
Definition: TGHtml.h:517
#define snprintf
Definition: civetweb.c:1540
int fBottom
Definition: TGHtml.h:717
Html_32_t fW
Definition: TGHtml.h:519
static TImage * Open(const char *file, EImageFileTypes type=kUnknown)
Open a specified image file.
Definition: TImage.cxx:119
int GetImageAlignment(TGHtmlElement *p)
Find the alignment for an image.
Definition: TGHtmlImage.cxx:84
#define IMAGE_ALIGN_Right
Definition: TGHtml.h:567
virtual TImage * LoadImage(const char *uri, int w=0, int h=0)
This is the default LoadImage() procedure.
int fInTd
Definition: TGHtml.h:1194
virtual const char * MarkupArg(const char *tag, const char *zDefault)
Lookup an argument in the given markup with the name given.
TGHtmlImageMarkup * fPList
Definition: TGHtml.h:524
const Int_t n
Definition: legend1.C:16
#define RELAYOUT
Definition: TGHtml.h:1324
const char * Data() const
Definition: TString.h:364