Logo ROOT   6.10/09
Reference Guide
TGHtmlDraw.cxx
Go to the documentation of this file.
1 // $Id: TGHtmlDraw.cxx,v 1.1 2007/05/04 17:07:01 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 to render HTML onto the screen for the TGHtml widget.
35 
36 #include <string.h>
37 #include <stdlib.h>
38 
39 #include "TGHtml.h"
40 #include "TImage.h"
41 
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// ctor.
45 
47 {
48  fZ = NULL;
49  fTop = fBottom = 0;
50  fLeft = fRight = 0;
51  fN = 0;
52  fPPrev = fPNext = 0;
53  fBPrev = fBNext = 0;
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// dtor.
58 
60 {
61  if (fZ) delete[] fZ;
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Destroy the given Block after first unlinking it from the element list.
66 /// Note that this unlinks the block from the element list only -- not from
67 /// the block list.
68 
70 {
71  if (pBlock->fPNext) {
72  pBlock->fPNext->fPPrev = pBlock->fPPrev;
73  } else {
74  fPLast = pBlock->fPPrev;
75  }
76  if (pBlock->fPPrev) {
77  pBlock->fPPrev->fPNext = pBlock->fPNext;
78  } else {
79  fPFirst = pBlock->fPNext;
80  }
81  pBlock->fPPrev = pBlock->fPNext = 0;
82  delete pBlock;
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// Append a block to the block list and insert the block into the
87 /// element list immediately prior to the element given.
88 ///
89 /// pToken - The token that comes after pBlock
90 /// pBlock - The block to be appended
91 
93 {
94  pBlock->fPPrev = pToken->fPPrev;
95  pBlock->fPNext = pToken;
96  pBlock->fBPrev = fLastBlock;
97  pBlock->fBNext = 0;
98  if (fLastBlock) {
99  fLastBlock->fBNext = pBlock;
100  } else {
101  fFirstBlock = pBlock;
102  }
103  fLastBlock = pBlock;
104  if (pToken->fPPrev) {
105  pToken->fPPrev->fPNext = (TGHtmlElement *) pBlock;
106  } else {
107  fPFirst = (TGHtmlElement *) pBlock;
108  }
109  pToken->fPPrev = (TGHtmlElement *) pBlock;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Print an ordered list index into the given buffer. Use numbering
114 /// like this:
115 ///
116 /// A B C ... Y Z AA BB CC ... ZZ
117 ///
118 /// Revert to decimal for indices greater than 52.
119 
120 static void GetLetterIndex(char *zBuf, int index, int isUpper)
121 {
122  int seed;
123 
124  if (index < 1 || index > 52) {
125  // coverity[secure_coding]: zBuf is large enough for an integer
126  sprintf(zBuf, "%d", index);
127  return;
128  }
129 
130  if (isUpper) {
131  seed = 'A';
132  } else {
133  seed = 'a';
134  }
135 
136  index--;
137 
138  if (index < 26) {
139  zBuf[0] = seed + index;
140  zBuf[1] = 0;
141  } else {
142  index -= 26;
143  zBuf[0] = seed + index;
144  zBuf[1] = seed + index;
145  zBuf[2] = 0;
146  }
147 
148  strcat(zBuf, ".");
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Print an ordered list index into the given buffer. Use roman
153 /// numerals. For indices greater than a few thousand, revert to
154 /// decimal.
155 
156 static void GetRomanIndex(char *zBuf, int index, int isUpper)
157 {
158  int i = 0;
159  UInt_t j;
160 
161  static struct {
162  int value;
163  const char *name;
164  } values[] = {
165  { 1000, "m" },
166  { 999, "im" },
167  { 990, "xm" },
168  { 900, "cm" },
169  { 500, "d" },
170  { 499, "id" },
171  { 490, "xd" },
172  { 400, "cd" },
173  { 100, "c" },
174  { 99, "ic" },
175  { 90, "xc" },
176  { 50, "l" },
177  { 49, "il" },
178  { 40, "xl" },
179  { 10, "x" },
180  { 9, "ix" },
181  { 5, "v" },
182  { 4, "iv" },
183  { 1, "i" },
184  };
185 
186  if (index < 1 || index >= 5000) {
187  // coverity[secure_coding]: zBuf is large enough for an integer
188  sprintf(zBuf, "%d", index);
189  return;
190  }
191  for (j = 0; index > 0 && j < sizeof(values)/sizeof(values[0]); j++) {
192  int k;
193  while (index >= values[j].value) {
194  for (k = 0; values[j].name[k]; k++) {
195  zBuf[i++] = values[j].name[k];
196  }
197  index -= values[j].value;
198  }
199  }
200  zBuf[i] = 0;
201  if (isUpper) {
202  for (i = 0; zBuf[i]; i++) {
203  zBuf[i] += 'A' - 'a';
204  }
205  }
206 
207  strcat(zBuf, ".");
208 }
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// Draw the selection background for the given block
212 ///
213 /// x, y - Virtual coords of top-left of drawable
214 
216  int x, int y)
217 {
218  int xLeft, xRight; // Left and right bounds of box to draw
219  int yTop, yBottom; // Top and bottom of box
220  TGHtmlElement *p = 0; // First element of the block
221  TGFont *font=0; // Font
222  GContext_t gc; // GC for drawing
223 
224  if (pBlock == 0 || (pBlock->fFlags & HTML_Selected) == 0) return;
225 
226  xLeft = pBlock->fLeft - x;
227  if (pBlock == fPSelStartBlock && fSelStartIndex > 0) {
228  if (fSelStartIndex >= pBlock->fN) return;
229  p = pBlock->fPNext;
230  font = GetFont(p->fStyle.fFont);
231  if (font == 0) return;
232  if (p->fType == Html_Text) {
234  xLeft = tp->fX - x + font->TextWidth(pBlock->fZ, fSelStartIndex);
235  }
236  }
237  xRight = pBlock->fRight - x;
238  if (pBlock == fPSelEndBlock && fSelEndIndex < pBlock->fN) {
239  if (p == 0) {
240  p = pBlock->fPNext;
241  font = GetFont(p->fStyle.fFont);
242  if (font == 0) return;
243  }
244  if (p->fType == Html_Text) {
246  xRight = tp->fX - x + font->TextWidth(pBlock->fZ, fSelEndIndex);
247  }
248  }
249  yTop = pBlock->fTop - y;
250  yBottom = pBlock->fBottom - y;
251  gc = GetGC(COLOR_Selection, FONT_Any);
252  Int_t xx = xLeft;
253  Int_t yy = yTop;
254  UInt_t width = xRight - xLeft;
255  UInt_t height = yBottom - yTop;
256  gVirtualX->FillRectangle(drawable, gc, xx, yy, width, height);
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Draw a rectangle. The rectangle will have a 3-D appearance if
261 /// flat is 0 and a flat appearance if flat is 1.
262 ///
263 /// depth - width of the relief or the flat line
264 
266  int x, int y, int w, int h, int depth, int relief)
267 {
268  Int_t xx, yy;
269  UInt_t width, height;
270 
271  if (depth > 0) {
272  int i;
273  GContext_t gcLight, gcDark;
274 
275  if (relief != HTML_RELIEF_FLAT) {
276  int iLight1, iDark1;
277  iLight1 = GetLightShadowColor(src->fStyle.fBgcolor);
278  gcLight = GetGC(iLight1, FONT_Any);
279  iDark1 = GetDarkShadowColor(src->fStyle.fBgcolor);
280  gcDark = GetGC(iDark1, FONT_Any);
281  if (relief == HTML_RELIEF_SUNKEN) {
282  GContext_t gcTemp = gcLight;
283  gcLight = gcDark;
284  gcDark = gcTemp;
285  }
286  } else {
287  gcLight = GetGC(src->fStyle.fColor, FONT_Any);
288  gcDark = gcLight;
289  }
290  xx = x;
291  yy = y;
292  width = depth;
293  height = h;
294  gVirtualX->FillRectangle(drawable, gcLight, xx, yy, width, height);
295  xx = x + w - depth;
296  gVirtualX->FillRectangle(drawable, gcLight, xx, yy, width, height);
297  for (i = 0; i < depth && i < h/2; i++) {
298  gVirtualX->DrawLine(drawable, gcLight, x+i, y+i, x+w-i-1, y+i);
299  gVirtualX->DrawLine(drawable, gcDark, x+i, y+h-i-1, x+w-i-1, y+h-i-1);
300  }
301  }
302  if (h > depth*2 && w > depth*2) {
303  GContext_t gcBg;
304  gcBg = GetGC(src->fStyle.fBgcolor, FONT_Any);
305  xx = x + depth;
306  yy = y + depth;
307  width = w - depth*2;
308  height = h - depth*2;
309  gVirtualX->FillRectangle(drawable, gcBg, xx, yy, width, height);
310  }
311 }
312 
313 ////////////////////////////////////////////////////////////////////////////////
314 /// Display a single HtmlBlock. This is where all the drawing happens.
315 
316 void TGHtml::BlockDraw(TGHtmlBlock *pBlock, Drawable_t drawable,
317  int drawableLeft, int drawableTop,
318  int drawableWidth, int drawableHeight,
319  Pixmap_t pixmap)
320 {
321  TGFont *font; // Font to use to render text
322  GContext_t gc; // A graphics context
323  TGHtmlElement *src; // TGHtmlElement holding style information
324  TGHtmlTable *pTable; // The table (when drawing part of a table)
325  Int_t x, y; // Where to draw
326  UInt_t width, height;
327 
328  if (pBlock == 0) return;
329 
330  src = pBlock->fPNext;
331  while (src && (src->fFlags & HTML_Visible) == 0) src = src->fPNext;
332 
333  if (src == 0) return;
334 
335  if (pBlock->fN > 0) {
336  // We must be dealing with plain old text
337  if (src->fType == Html_Text) {
338  TGHtmlTextElement *tsrc = (TGHtmlTextElement *) src;
339  x = tsrc->fX;
340  y = tsrc->fY;
341  } else {
342  CANT_HAPPEN;
343  return;
344  }
345  if (pBlock->fFlags & HTML_Selected) {
346  DrawSelectionBackground(pBlock, drawable, drawableLeft, drawableTop);
347  }
348  gc = GetGC(src->fStyle.fColor, src->fStyle.fFont);
349  font = GetFont(src->fStyle.fFont);
350  if (font == 0) return;
351  font->DrawChars(drawable, gc, pBlock->fZ, pBlock->fN,
352  x - drawableLeft, y - drawableTop);
353  if (src->fStyle.fFlags & STY_Underline) {
354  font->UnderlineChars(drawable, gc, pBlock->fZ,
355  x - drawableLeft, y-drawableTop, 0, pBlock->fN);
356  }
357  if (src->fStyle.fFlags & STY_StrikeThru) {
358  x = pBlock->fLeft - drawableLeft;
359  y = (pBlock->fTop + pBlock->fBottom) / 2 - drawableTop;
360  width = pBlock->fRight - pBlock->fLeft;
361  height = 1 + (pBlock->fBottom - pBlock->fTop > 15);
362  gVirtualX->FillRectangle(drawable, gc, x, y, width, height);
363  }
364  if (pBlock == fPInsBlock && fInsStatus > 0) {
365  if (fInsIndex < pBlock->fN) {
366  TGHtmlTextElement *tsrc = (TGHtmlTextElement *) src;
367  x = tsrc->fX - drawableLeft;
368  x += font->TextWidth(pBlock->fZ, fInsIndex);
369  } else {
370  x = pBlock->fRight - drawableLeft;
371  }
372  if (x > 0) --x;
373  gVirtualX->FillRectangle(drawable, gc, x, pBlock->fTop - drawableTop,
374  2, pBlock->fBottom - pBlock->fTop);
375  }
376  } else {
377  // We are dealing with a single TGHtmlElement which contains something
378  // other than plain text.
379  int cnt, w;
380  char zBuf[30];
381  TGHtmlLi *li;
382  TGHtmlImageMarkup *image;
383  switch (src->fType) {
384  case Html_LI:
385  li = (TGHtmlLi *) src;
386  x = li->fX;
387  y = li->fY;
388  switch (li->fLtype) {
389  case LI_TYPE_Enum_1:
390  // coverity[secure_coding]: zBuf is large enough for an int
391  sprintf(zBuf, "%d.", li->fCnt);
392  break;
393  case LI_TYPE_Enum_A:
394  GetLetterIndex(zBuf, li->fCnt, 1);
395  break;
396  case LI_TYPE_Enum_a:
397  GetLetterIndex(zBuf, li->fCnt, 0);
398  break;
399  case LI_TYPE_Enum_I:
400  GetRomanIndex(zBuf, li->fCnt, 1);
401  break;
402  case LI_TYPE_Enum_i:
403  GetRomanIndex(zBuf, li->fCnt, 0);
404  break;
405  default:
406  zBuf[0] = 0;
407  break;
408  }
409  gc = GetGC(src->fStyle.fColor, src->fStyle.fFont);
410  switch (li->fLtype) {
411  case LI_TYPE_Undefined:
412  case LI_TYPE_Bullet1:
413  //gVirtualX->FillArc(drawable, gc,
414  // x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7,
415  // 0, 360*64);
416  break;
417 
418  case LI_TYPE_Bullet2:
419  //gVirtualX->DrawArc(drawable, gc,
420  // x - 7 - drawableLeft, y - 8 - drawableTop, 7, 7,
421  // 0, 360*64);
422  break;
423 
424  case LI_TYPE_Bullet3:
425  gVirtualX->DrawRectangle(drawable, gc, x - 7 - drawableLeft,
426  y - 8 - drawableTop, 7, 7);
427  break;
428 
429  case LI_TYPE_Enum_1:
430  case LI_TYPE_Enum_A:
431  case LI_TYPE_Enum_a:
432  case LI_TYPE_Enum_I:
433  case LI_TYPE_Enum_i:
434  cnt = strlen(zBuf);
435  font = GetFont(src->fStyle.fFont);
436  if (font == 0) return;
437  w = font->TextWidth(zBuf, cnt);
438  font->DrawChars(drawable, gc, zBuf, cnt,
439  x - w - drawableLeft, y - drawableTop);
440  break;
441  }
442  break;
443 
444  case Html_HR: {
445  TGHtmlHr *hr = (TGHtmlHr *) src;
446  int relief = fRuleRelief;
447  switch (relief) {
448  case HTML_RELIEF_RAISED:
449  case HTML_RELIEF_SUNKEN:
450  break;
451  default:
452  relief = HTML_RELIEF_FLAT;
453  break;
454  }
455  DrawRect(drawable, src, hr->fX - drawableLeft, hr->fY - drawableTop,
456  hr->fW, hr->fH, 1, relief);
457  break;
458  }
459 
460  case Html_TABLE: {
461  TGHtmlTable *table = (TGHtmlTable *) src;
462  int relief = fTableRelief;
463  if ((!fBgImage || src->fStyle.fExpbg) && !table->fHasbg) {
464  switch (relief) {
465  case HTML_RELIEF_RAISED:
466  case HTML_RELIEF_SUNKEN:
467  break;
468  default:
469  relief = HTML_RELIEF_FLAT;
470  break;
471  }
472 
473  DrawRect(drawable, src, table->fX - drawableLeft,
474  table->fY - drawableTop, table->fW, table->fH,
475  table->fBorderWidth, relief);
476  }
477 
478  if (table->fBgImage) {
479  DrawTableBgnd(table->fX, table->fY, table->fW, table->fH, pixmap,
480  table->fBgImage);
481  }
482  break;
483  }
484 
485  case Html_TH:
486  case Html_TD: {
487  TGHtmlCell *cell = (TGHtmlCell *) src;
488  int depth, relief;
489  TImage *bgImg;
490  pTable = cell->fPTable;
491  if ((!fBgImage || src->fStyle.fExpbg) && !(pTable && pTable->fHasbg)) {
492  depth = pTable && (pTable->fBorderWidth > 0);
493  switch (fTableRelief) {
494  case HTML_RELIEF_RAISED: relief = HTML_RELIEF_SUNKEN; break;
495  case HTML_RELIEF_SUNKEN: relief = HTML_RELIEF_RAISED; break;
496  default: relief = HTML_RELIEF_FLAT; break;
497  }
498  DrawRect(drawable, src,
499  cell->fX - drawableLeft, cell->fY - drawableTop,
500  cell->fW, cell->fH, depth, relief);
501  }
502  // See if row has an image
503  if (cell->fBgImage) {
504  DrawTableBgnd(cell->fX, cell->fY, cell->fW, cell->fH, pixmap,
505  cell->fBgImage);
506  } else if (cell->fPRow && (bgImg = ((TGHtmlRef *)cell->fPRow)->fBgImage)) {
507  DrawTableBgnd(cell->fX, cell->fY, cell->fW, cell->fH, pixmap, bgImg);
508  }
509  break;
510  }
511 
512  case Html_IMG:
513  image = (TGHtmlImageMarkup *) src;
514  if (image->fPImage) {
515  DrawImage(image, drawable, drawableLeft, drawableTop,
516  drawableLeft + drawableWidth,
517  drawableTop + drawableHeight);
518  } else if (image->fZAlt) {
519  gc = GetGC(src->fStyle.fColor, src->fStyle.fFont);
520  font = GetFont(src->fStyle.fFont);
521  if (font == 0) return;
522  font->DrawChars(drawable, gc,
523  image->fZAlt, strlen(image->fZAlt),
524  image->fX - drawableLeft,
525  image->fY - drawableTop);
526  }
527  break;
528 
529  default:
530  break;
531  }
532  }
533 }
534 
535 ////////////////////////////////////////////////////////////////////////////////
536 /// Draw all or part of an image.
537 
539  int drawableLeft, int drawableTop,
540  int drawableRight, int drawableBottom)
541 {
542  int imageTop; // virtual canvas coordinate for top of image
543  int x, y; // where to place image on the drawable
544  int imageX, imageY; // \__ Subset of image that fits
545  int imageW, imageH; // / on the drawable
546 
547  imageTop = image->fY - image->fAscent;
548  y = imageTop - drawableTop;
549  if (imageTop + image->fH > drawableBottom) {
550  imageH = drawableBottom - imageTop;
551  } else {
552  imageH = image->fH;
553  }
554  if (y < 0) {
555  imageY = -y;
556  imageH += y;
557  y = 0;
558  } else {
559  imageY = 0;
560  }
561  x = image->fX - drawableLeft;
562  if (image->fX + image->fW > drawableRight) {
563  imageW = drawableRight - image->fX;
564  } else {
565  imageW = image->fW;
566  }
567  if (x < 0) {
568  imageX = -x;
569  imageW += x;
570  x = 0;
571  } else {
572  imageX = 0;
573  }
574 
575  TImage *img = image->fPImage->fImage;
576 
577  imageH = imageH < 0 ? -imageH : imageH;
578  imageW = imageW < 0 ? -imageW : imageW;
579 
580  img->PaintImage(drawable, x, y, imageX, imageY, imageW, imageH);
581  //gVirtualX->Update(kFALSE);
582 
583  image->fRedrawNeeded = 0;
584 }
585 
586 ////////////////////////////////////////////////////////////////////////////////
587 ///
588 ///TGImage *img = image->image;
589 
591 {
592  //if (!img->IsAnimated()) return;
593  //img->NextFrame();
594  //delete image->timer;
595  //image->timer = new TTimer(this, img->GetAnimDelay());
596  //ImageChanged(image, image->fW, image->fH);
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// Recompute the following fields of the given block structure:
601 ///
602 /// base.count The number of elements described by this
603 /// block structure.
604 ///
605 /// n The number of characters of text output
606 /// associated with this block. If the block
607 /// renders something other than text (ex: <IMG>)
608 /// then set n to 0.
609 ///
610 /// z Pointer to malloced memory containing the
611 /// text associated with this block. NULL if
612 /// n is 0.
613 ///
614 /// Return a pointer to the first TGHtmlElement not covered by the block.
615 
617 {
618 
619  TGHtmlElement *pElem;
620  int go, i, n, x, y;
622  char zBuf[2000];
623 
624  // Reset n and z
625 
626  if (p->fN) p->fN = 0;
627 
628  if (p->fZ) delete[] p->fZ;
629  p->fZ = 0;
630 
631  // Skip over TGHtmlElements that aren't directly displayed.
632 
633  pElem = p->fPNext;
634  p->fCount = 0;
635  while (pElem && (pElem->fFlags & HTML_Visible) == 0) {
636  TGHtmlElement *fPNext = pElem->fPNext;
637  if (pElem->fType == Html_Block) {
638  UnlinkAndFreeBlock((TGHtmlBlock *) pElem);
639  } else {
640  p->fCount++;
641  }
642  pElem = fPNext;
643  }
644  if (pElem == 0) return 0;
645 
646  // Handle "special" elements.
647 
648  if (pElem->fType != Html_Text) {
649  switch (pElem->fType) {
650  case Html_HR: {
651  TGHtmlHr *hr = (TGHtmlHr *) pElem;
652  p->fTop = hr->fY - hr->fH;
653  p->fBottom = hr->fY;
654  p->fLeft = hr->fX;
655  p->fRight = hr->fX + hr->fW;
656  break;
657  }
658 
659  case Html_LI: {
660  TGHtmlLi *li = (TGHtmlLi *) pElem;
661  p->fTop = li->fY - li->fAscent;
662  p->fBottom = li->fY + li->fDescent;
663  p->fLeft = li->fX - 10;
664  p->fRight = li->fX + 10;
665  break;
666  }
667 
668  case Html_TD:
669  case Html_TH: {
670  TGHtmlCell *cell = (TGHtmlCell *) pElem;
671  p->fTop = cell->fY;
672  p->fBottom = cell->fY + cell->fH;
673  p->fLeft = cell->fX;
674  p->fRight = cell->fX + cell->fW;
675  break;
676  }
677 
678  case Html_TABLE: {
679  TGHtmlTable *table = (TGHtmlTable *) pElem;
680  p->fTop = table->fY;
681  p->fBottom = table->fY + table->fH;
682  p->fLeft = table->fX;
683  p->fRight = table->fX + table->fW;
684  break;
685  }
686 
687  case Html_IMG: {
688  TGHtmlImageMarkup *image = (TGHtmlImageMarkup *) pElem;
689  p->fTop = image->fY - image->fAscent;
690  p->fBottom = image->fY + image->fDescent;
691  p->fLeft = image->fX;
692  p->fRight = image->fX + image->fW;
693  break;
694  }
695  }
696  p->fCount++;
697 
698  return pElem->fPNext;
699  }
700 
701  // If we get this far, we must be dealing with text.
702 
704  n = 0;
705  x = text->fX;
706  y = text->fY;
707  p->fTop = y - text->fAscent;
708  p->fBottom = y + text->fDescent;
709  p->fLeft = x;
710  style = pElem->fStyle;
711  go = 1;
712  while (pElem) {
713  TGHtmlElement *fPNext = pElem->fPNext;
714  switch (pElem->fType) {
715  case Html_Text: {
716  TGHtmlTextElement *txt = (TGHtmlTextElement *) pElem;
717  if (pElem->fFlags & STY_Invisible) {
718  break;
719  }
720  if (txt->fSpaceWidth <= 0) {
721  //CANT_HAPPEN;
722  break;
723  }
724  if (y != txt->fY
725  || style.fFont != pElem->fStyle.fFont
726  || style.fColor != pElem->fStyle.fColor
727  || (style.fFlags & STY_FontMask)
728  != (pElem->fStyle.fFlags & STY_FontMask)) {
729  go = 0;
730  } else {
731  int sw = txt->fSpaceWidth;
732  int nSpace = (txt->fX - x) / sw;
733  if (nSpace * sw + x != txt->fX) {
734  go = 0;
735  } else if ((n + nSpace + pElem->fCount) >= (int)sizeof(zBuf)) {
736  // go = 0; - this caused a hang, instead lets do what we can
737  for (i = 0; i < nSpace && (n+1) < (int)sizeof(zBuf); ++i) {
738  zBuf[n++] = ' ';
739  }
740  strncpy(&zBuf[n], txt->fZText, sizeof(zBuf) - n - 1);
741  zBuf[sizeof(zBuf)-1] = 0;
742  n += i;
743  x = txt->fX + txt->fW;
744  } else {
745  for (i = 0; i < nSpace && (n+1) < (int)sizeof(zBuf); ++i) {
746  zBuf[n++] = ' ';
747  }
748  strncpy(&zBuf[n], txt->fZText, sizeof(zBuf) - n - 1);
749  zBuf[sizeof(zBuf)-1] = 0;
750  n += pElem->fCount;
751  x = txt->fX + txt->fW;
752  }
753  }
754  break;
755  }
756 
757  case Html_Space:
758  if (pElem->fStyle.fFont != style.fFont) {
759  pElem = pElem->fPNext;
760  go = 0;
761  } else if ((style.fFlags & STY_Preformatted) != 0 &&
762  (pElem->fFlags & HTML_NewLine) != 0) {
763  pElem = pElem->fPNext;
764  go = 0;
765  }
766  break;
767 
768  case Html_Block:
769  UnlinkAndFreeBlock((TGHtmlBlock *) pElem);
770  break;
771 
772  case Html_A:
773  case Html_EndA:
774  go = 0;
775  break;
776 
777  default:
778  if (pElem->fFlags & HTML_Visible) go = 0;
779  break;
780  }
781  if (go == 0) break;
782  p->fCount++;
783  pElem = fPNext;
784  }
785  p->fRight = x;
786 
787  while (n > 0 && zBuf[n-1] == ' ') n--;
788  p->fZ = new char[n+1];
789  strlcpy(p->fZ, zBuf, n+1);
790  p->fZ[n] = 0;
791  p->fN = n;
792 
793  return pElem;
794 }
795 
796 ////////////////////////////////////////////////////////////////////////////////
797 /// Scan ahead looking for a place to put a block. Return a pointer
798 /// to the element which should come immediately after the block.
799 ///
800 /// if pCnt != 0, then put the number of elements skipped in *pCnt.
801 ///
802 /// p - First candidate for the start of a block
803 /// pCnt - Write number of elements skipped here
804 
806 {
807  int cnt = 0;
808 
809  while (p && (p->fFlags & HTML_Visible) == 0) {
811  if (p->fType == Html_Block) {
812  UnlinkAndFreeBlock((TGHtmlBlock *) p);
813  } else {
814  cnt++;
815  }
816  p = fPNext;
817  }
818  if (pCnt) *pCnt = cnt;
819 
820  return p;
821 }
822 
823 ////////////////////////////////////////////////////////////////////////////////
824 /// Add additional blocks to the block list in order to cover
825 /// all elements on the element list.
826 ///
827 /// If any old blocks are found on the element list, they must
828 /// be left over from a prior rendering. Unlink and delete them.
829 
831 {
832  TGHtmlElement *pElem;
833 
834  if (fLastBlock) {
835  pElem = FillOutBlock(fLastBlock);
836  } else {
837  pElem = fPFirst;
838  }
839  while (pElem) {
840  int cnt;
841  pElem = FindStartOfNextBlock(pElem, &cnt);
842  if (pElem) {
843  TGHtmlBlock *pNew = new TGHtmlBlock();
844  if (fLastBlock) {
845  fLastBlock->fCount += cnt;
846  }
847  AppendBlock(pElem, pNew);
848  pElem = FillOutBlock(pNew);
849  }
850  }
851 }
852 
853 ////////////////////////////////////////////////////////////////////////////////
854 /// Draw table background
855 
856 void TGHtml::DrawTableBgnd(int l, int t, int w, int h,
857  Drawable_t pixmap, TImage *image)
858 {
859  //int mx, my, sh, sw, sx, sy, hd;
860  int dl, dt, dr, db, left, top, right, bottom;
861 
862  left = l - fVisible.fX;
863  top = t - fVisible.fY;
864 
865  dl = fDirtyLeft;
866  dt = fDirtyTop;
867  dr = fDirtyRight;
868  db = fDirtyBottom;
869 
870  right = left + w - 1;
871  bottom = top + h - 1;
872  if (dr == 0 && db == 0) { dr = right; db = bottom; }
873  if (left > dr || right < dl || top > db || bottom < dt) return;
874 
875 #if 0
876  int iw = image->GetWidth();
877  int ih = image->GetHeight();
878  if (iw < 4 && ih < 4) return; // CPU burners we ignore.
879  sx = (left + _visibleStart.x) % iw; // X offset within image to start from
880  sw = iw - sx; // Width of section of image to draw.
881  for (mx = left - dl; w > 0; mx += sw, sw = iw, sx = 0) {
882  if (sw > w) sw = w;
883  sy = (top + _visibleStart.y) % ih; // Y offset within image to start from
884  sh = ih - sy; // Height of section of image to draw.
885  for (my = top - dt, hd = h; hd > 0; my += sh, sh = ih, sy = 0) {
886  if (sh > hd) sh = hd;
887  // printf("image: %d %d %d %d %d %d\n", sx, sy, sw, sh, mx,my);
888  image->Draw(pixmap, GetAnyGC(), sx, sy, sw, sh, mx, my);
889  hd -= sh;
890  }
891  w -= sw;
892  }
893 #else
894  if (!image->GetPixmap()) return;
895  GContext_t gc = GetAnyGC();
896  GCValues_t gcv;
897  // unsigned int mask = kGCTile | kGCFillStyle |
898  // kGCTileStipXOrigin | kGCTileStipYOrigin;
899  gcv.fTile = image->GetPixmap();
900  gcv.fFillStyle = kFillTiled;
901  gcv.fTsXOrigin = -fVisible.fX - fDirtyLeft;
902  gcv.fTsYOrigin = -fVisible.fY - fDirtyTop;
903  gVirtualX->ChangeGC(gc, &gcv);
904 
905  gVirtualX->FillRectangle(pixmap, gc, left - dl, top - dt, w, h);
906 
907  // mask = kGCFillStyle;
908  gcv.fFillStyle = kFillSolid;
909  gVirtualX->ChangeGC(gc, &gcv);
910 #endif
911 }
Html_32_t fY
Definition: TGHtml.h:362
TImage * fBgImage
Definition: TGHtml.h:395
void DrawChars(Drawable_t dst, GContext_t gc, const char *source, Int_t numChars, Int_t x, Int_t y) const
Perform a quick sanity check to ensure we won&#39;t overflow the X coordinate space.
Definition: TGFont.cxx:1478
#define HTML_RELIEF_FLAT
Definition: TGHtml.h:50
Html_16_t fX
Definition: TGHtml.h:427
char * fZ
Definition: TGHtml.h:716
Pixmap_t fTile
Definition: GuiTypes.h:237
unsigned int fColor
Definition: TGHtml.h:145
int fTop
Definition: TGHtml.h:717
virtual UInt_t GetHeight() const
Definition: TImage.h:229
Html_16_t fAscent
Definition: TGHtml.h:546
int fHasbg
Definition: TGHtml.h:370
#define LI_TYPE_Enum_i
Definition: TGHtml.h:445
#define STY_Invisible
Definition: TGHtml.h:239
#define STY_FontMask
Definition: TGHtml.h:240
Html_u16_t fRight
Definition: TGHtml.h:718
virtual UInt_t GetWidth() const
Definition: TImage.h:228
Html_16_t fX
Definition: TGHtml.h:548
Html_32_t fY
Definition: TGHtml.h:390
static void GetRomanIndex(char *zBuf, int index, int isUpper)
Print an ordered list index into the given buffer.
Definition: TGHtmlDraw.cxx:156
TH1 * h
Definition: legend2.C:5
TGHtmlBlock * fBPrev
Definition: TGHtml.h:720
#define LI_TYPE_Enum_A
Definition: TGHtml.h:442
TGHtmlBlock()
ctor.
Definition: TGHtmlDraw.cxx:46
Int_t fTsYOrigin
Definition: GuiTypes.h:240
void DrawTableBgnd(int x, int y, int w, int h, Drawable_t d, TImage *image)
Draw table background.
Definition: TGHtmlDraw.cxx:856
#define COLOR_Selection
Definition: TGHtml.h:199
#define HTML_Visible
Definition: TGHtml.h:274
Handle_t GContext_t
Definition: GuiTypes.h:37
Html_16_t fX
Definition: TGHtml.h:388
int Int_t
Definition: RtypesCore.h:41
TImage * fBgImage
Definition: TGHtml.h:369
unsigned int fExpbg
Definition: TGHtml.h:149
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:202
Handle_t Drawable_t
Definition: GuiTypes.h:30
An abstract interface to image processing library.
Definition: TImage.h:29
Int_t fFillStyle
Definition: GuiTypes.h:233
#define NULL
Definition: RtypesCore.h:88
Html_u8_t fLtype
Definition: TGHtml.h:423
#define STY_Preformatted
Definition: TGHtml.h:233
virtual Pixmap_t GetPixmap()
Definition: TImage.h:235
Html_16_t fW
Definition: TGHtml.h:545
void DrawSelectionBackground(TGHtmlBlock *pBlock, Drawable_t Drawable_t, int x, int y)
Draw the selection background for the given block.
Definition: TGHtmlDraw.cxx:215
TGHtmlElement * fPNext
Definition: TGHtml.h:261
#define FONT_Any
Definition: TGHtml.h:172
Html_32_t fH
Definition: TGHtml.h:363
Html_u8_t fBorderWidth
Definition: TGHtml.h:359
void DrawRect(Drawable_t drawable, TGHtmlElement *src, int x, int y, int w, int h, int depth, int relief)
Draw a rectangle.
Definition: TGHtmlDraw.cxx:265
Html_32_t fY
Definition: TGHtml.h:653
Double_t x[n]
Definition: legend1.C:17
TGHtmlElement * FillOutBlock(TGHtmlBlock *p)
Recompute the following fields of the given block structure:
Definition: TGHtmlDraw.cxx:616
static void GetLetterIndex(char *zBuf, int index, int isUpper)
Print an ordered list index into the given buffer.
Definition: TGHtmlDraw.cxx:120
Int_t TextWidth(const char *string, Int_t numChars=-1) const
A wrapper function for the more complicated interface of MeasureChars.
Definition: TGFont.cxx:563
unsigned int fBgcolor
Definition: TGHtml.h:148
unsigned int fFont
Definition: TGHtml.h:144
Html_u16_t fW
Definition: TGHtml.h:655
void UnlinkAndFreeBlock(TGHtmlBlock *pBlock)
Destroy the given Block after first unlinking it from the element list.
Definition: TGHtmlDraw.cxx:69
TGHtmlElement * fPPrev
Definition: TGHtml.h:262
TGHtmlBlock * fBNext
Definition: TGHtml.h:720
#define LI_TYPE_Bullet3
Definition: TGHtml.h:440
Int_t fTsXOrigin
Definition: GuiTypes.h:239
void DrawImage(TGHtmlImageMarkup *image, Drawable_t wid, int left, int top, int right, int bottom)
Draw all or part of an image.
Definition: TGHtmlDraw.cxx:538
Html_u8_t fRedrawNeeded
Definition: TGHtml.h:542
TGHtmlImage * fPImage
Definition: TGHtml.h:551
Html_16_t fX
Definition: TGHtml.h:295
Html_32_t fY
Definition: TGHtml.h:549
void BlockDraw(TGHtmlBlock *pBlock, Drawable_t wid, int left, int top, int width, int height, Pixmap_t pixmap)
Display a single HtmlBlock. This is where all the drawing happens.
Definition: TGHtmlDraw.cxx:316
virtual void PaintImage(Drawable_t, Int_t, Int_t, Int_t=0, Int_t=0, UInt_t=0, UInt_t=0, Option_t *="")
Definition: TImage.h:243
Html_u8_t fAscent
Definition: TGHtml.h:297
#define HTML_RELIEF_SUNKEN
Definition: TGHtml.h:51
SHtmlStyle_t fStyle
Definition: TGHtml.h:263
Html_32_t fH
Definition: TGHtml.h:391
#define LI_TYPE_Bullet1
Definition: TGHtml.h:438
void AppendBlock(TGHtmlElement *pToken, TGHtmlBlock *pBlock)
Append a block to the block list and insert the block into the element list immediately prior to the ...
Definition: TGHtmlDraw.cxx:92
TImage * fImage
Definition: TGHtml.h:518
#define LI_TYPE_Enum_a
Definition: TGHtml.h:443
#define LI_TYPE_Bullet2
Definition: TGHtml.h:439
#define STY_Underline
Definition: TGHtml.h:235
unsigned int UInt_t
Definition: RtypesCore.h:42
void AnimateImage(TGHtmlImage *image)
TGImage *img = image->image;.
Definition: TGHtmlDraw.cxx:590
TGHtmlTable * fPTable
Definition: TGHtml.h:392
Html_u16_t fN
Definition: TGHtml.h:719
TLine * l
Definition: textangle.C:4
char * fZText
Definition: TGHtml.h:300
Html_16_t fX
Definition: TGHtml.h:364
Html_u8_t fAscent
Definition: TGHtml.h:424
Html_u8_t fType
Definition: TGHtml.h:264
#define gVirtualX
Definition: TVirtualX.h:350
Html_u8_t fSpaceWidth
Definition: TGHtml.h:299
#define HTML_NewLine
Definition: TGHtml.h:275
Html_u16_t fH
Definition: TGHtml.h:655
TGHtmlElement * FindStartOfNextBlock(TGHtmlElement *p, int *pCnt)
Scan ahead looking for a place to put a block.
Definition: TGHtmlDraw.cxx:805
unsigned int fFlags
Definition: TGHtml.h:150
Html_u16_t fX
Definition: TGHtml.h:654
Html_16_t fCnt
Definition: TGHtml.h:426
#define LI_TYPE_Enum_1
Definition: TGHtml.h:441
TText * text
Html_16_t fH
Definition: TGHtml.h:544
#define LI_TYPE_Enum_I
Definition: TGHtml.h:444
Definition: TGFont.h:149
TCanvas * style()
Definition: style.C:1
Html_16_t fW
Definition: TGHtml.h:296
Double_t y[n]
Definition: legend1.C:17
Html_16_t fW
Definition: TGHtml.h:389
#define HTML_Selected
Definition: TGHtml.h:276
Html_32_t fY
Definition: TGHtml.h:428
#define HTML_RELIEF_RAISED
Definition: TGHtml.h:52
Html_u8_t fDescent
Definition: TGHtml.h:425
#define STY_StrikeThru
Definition: TGHtml.h:234
virtual ~TGHtmlBlock()
dtor.
Definition: TGHtmlDraw.cxx:59
Html_u16_t fLeft
Definition: TGHtml.h:718
#define CANT_HAPPEN
Definition: TGHtml.h:59
Html_16_t fW
Definition: TGHtml.h:365
Html_16_t fCount
Definition: TGHtml.h:266
const char * fZAlt
Definition: TGHtml.h:550
Handle_t Pixmap_t
Definition: GuiTypes.h:29
int fBottom
Definition: TGHtml.h:717
void FormBlocks()
Add additional blocks to the block list in order to cover all elements on the element list...
Definition: TGHtmlDraw.cxx:830
void UnderlineChars(Drawable_t dst, GContext_t gc, const char *string, Int_t x, Int_t y, Int_t firstChar, Int_t lastChar) const
This procedure draws an underline for a given range of characters in a given string.
Definition: TGFont.cxx:605
#define LI_TYPE_Undefined
Definition: TGHtml.h:437
Html_32_t fY
Definition: TGHtml.h:294
const Int_t n
Definition: legend1.C:16
TGHtmlElement * fPRow
Definition: TGHtml.h:393
Html_16_t fDescent
Definition: TGHtml.h:547
const char * cnt
Definition: TXMLSetup.cxx:75
Html_u8_t fFlags
Definition: TGHtml.h:265
Html_u8_t fDescent
Definition: TGHtml.h:298