Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGFont.cxx
Go to the documentation of this file.
1// @(#)root/gui:$Id$
2// Author: Fons Rademakers 20/5/2003
3
4/*************************************************************************
5 * Copyright (C) 1995-2003, Rene Brun and Fons Rademakers. *
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 This source is based on Xclass95, a Win95-looking GUI toolkit.
14 Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15
16 Xclass95 is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Library General Public
18 License as published by the Free Software Foundation; either
19 version 2 of the License, or (at your option) any later version.
20
21**************************************************************************/
22
23
24/** \class TGFont
25 \ingroup guiwidgets
26
27Encapsulate fonts used in the GUI system.
28
29
30\class TGFontPool
31\ingroup guiwidgets
32
33Provides a pool of fonts.
34
35
36\class TGTextLayout
37\ingroup guiwidgets
38
39Is used to keep track of string measurement
40information when using the text layout facilities.
41It can be displayed with respect to any origin.
42
43*/
44
45
46#include "TGFont.h"
47#include "TGClient.h"
48#include "THashTable.h"
49#include "TVirtualX.h"
50#include "TObjString.h"
51#include "TGWidget.h"
52#include "TROOT.h"
53#include "TError.h"
54#include "TMath.h"
55#include "strlcpy.h"
56#include "snprintf.h"
57
58#include <cerrno>
59#include <cstdlib>
60#include <climits>
61#include <iostream>
62
63
64
65#define FONT_FAMILY 0
66#define FONT_SIZE 1
67#define FONT_WEIGHT 2
68#define FONT_SLANT 3
69#define FONT_UNDERLINE 4
70#define FONT_OVERSTRIKE 5
71#define FONT_NUMFIELDS 6
72
73// The following defines specify the meaning of the fields in a fully
74// qualified XLFD.
75
76#define XLFD_FOUNDRY 0
77#define XLFD_FAMILY 1
78#define XLFD_WEIGHT 2
79#define XLFD_SLANT 3
80#define XLFD_SETWIDTH 4
81#define XLFD_ADD_STYLE 5
82#define XLFD_PIXEL_SIZE 6
83#define XLFD_POINT_SIZE 7
84#define XLFD_RESOLUTION_X 8
85#define XLFD_RESOLUTION_Y 9
86#define XLFD_SPACING 10
87#define XLFD_AVERAGE_WIDTH 11
88#define XLFD_REGISTRY 12
89#define XLFD_ENCODING 13
90#define XLFD_NUMFIELDS 14 // Number of fields in XLFD.
91
92
93// A LayoutChunk_t represents a contiguous range of text that can be measured
94// and displayed by low-level text calls. In general, chunks will be
95// delimited by newlines and tabs. Low-level, platform-specific things
96// like kerning and non-integer character widths may occur between the
97// characters in a single chunk, but not between characters in different
98// chunks.
99
101
102 const char *fStart; // Pointer to simple string to be displayed.
103 // This is a pointer into the TGTextLayout's
104 // string.
105 Int_t fNumChars; // The number of characters in this chunk.
106 Int_t fNumDisplayChars; // The number of characters to display when
107 // this chunk is displayed. Can be less than
108 // numChars if extra space characters were
109 // absorbed by the end of the chunk. This
110 // will be < 0 if this is a chunk that is
111 // holding a tab or newline.
112 Int_t fX; // The x origin and
113 Int_t fY; // the y origin of the first character in this
114 // chunk with respect to the upper-left hand
115 // corner of the TGTextLayout.
116 Int_t fTotalWidth; // Width in pixels of this chunk. Used
117 // when hit testing the invisible spaces at
118 // the end of a chunk.
119 Int_t fDisplayWidth; // Width in pixels of the displayable
120 // characters in this chunk. Can be less than
121 // width if extra space characters were
122 // absorbed by the end of the chunk.
123};
124
125
126// The following structure is used to return attributes when parsing an
127// XLFD. The extra information is used to find the closest matching font.
128
130 FontAttributes_t fFA; // Standard set of font attributes.
131 const char *fFoundry; // The foundry of the font.
132 Int_t fSlant; // The tristate value for the slant
133 Int_t fSetwidth; // The proportionate width
134 Int_t fCharset; // The character set encoding (the glyph family).
135 Int_t fEncoding; // Variations within a charset for the glyphs above character 127.
136
137 XLFDAttributes_t() : // default constructor
138 fFA(),
139 fFoundry(0),
140 fSlant(0),
141 fSetwidth(0),
142 fCharset(0),
143 fEncoding(0) { }
144};
145
146
147// The following data structure is used to keep track of the font attributes
148// for each named font that has been defined. The named font is only deleted
149// when the last reference to it goes away.
150
151class TNamedFont : public TObjString, public TRefCnt {
152public:
153 Int_t fDeletePending; // Non-zero if font should be deleted when last reference goes away.
154 FontAttributes_t fFA; // Desired attributes for named font.
155};
156
157// enums
162
167
171
172
173// Possible values for entries in the "types" field in a TGFont structure,
174// which classifies the types of all characters in the given font. This
175// information is used when measuring and displaying characters.
176//
177// kCharNormal: Standard character.
178// kCharReplace: This character doesn't print: instead of displaying
179// character, display a replacement sequence like "\n"
180// (for those characters where ANSI C defines such a
181// sequence) or a sequence of the form "\xdd" where dd
182// is the hex equivalent of the character.
183// kCharSkip: Don't display anything for this character. This is
184// only used where the font doesn't contain all the
185// characters needed to generate replacement sequences.
187
188
189// The following structures are used as two-way maps between the values for
190// the fields in the FontAttributes_t structure and the strings used when
191// parsing both option-value format and style-list format font name strings.
192
193struct FontStateMap_t { Int_t fNumKey; const char *fStrKey; };
194
195static const FontStateMap_t gWeightMap[] = {
196 { kFontWeightNormal, "normal" },
197 { kFontWeightBold, "bold" },
198 { kFontWeightUnknown, 0 }
199};
200
201static const FontStateMap_t gSlantMap[] = {
202 { kFontSlantRoman, "roman" },
203 { kFontSlantItalic, "italic" },
204 { kFontSlantUnknown, 0 }
205};
206
208 { 1, "underline" },
209 { 0, 0 }
210};
211
213 { 1, "overstrike" },
214 { 0, 0 }
215};
216
217// The following structures are used when parsing XLFD's into a set of
218// FontAttributes_t.
219
221 { kFontWeightNormal, "normal" },
222 { kFontWeightNormal, "medium" },
223 { kFontWeightNormal, "book" },
224 { kFontWeightNormal, "light" },
225 { kFontWeightBold, "bold" },
226 { kFontWeightBold, "demi" },
227 { kFontWeightBold, "demibold" },
228 { kFontWeightNormal, 0 } // Assume anything else is "normal".
229};
230
232 { kFontSlantRoman, "r" },
233 { kFontSlantItalic, "i" },
234 { kFontSlantOblique, "o" },
235 { kFontSlantRoman, 0 } // Assume anything else is "roman".
236};
237
239 { kFontSWNormal, "normal" },
240 { kFontSWCondence, "narrow" },
241 { kFontSWCondence, "semicondensed" },
242 { kFontSWCondence, "condensed" },
243 { kFontSWUnknown, 0 }
244};
245
247 { kFontCSNormal, "iso8859" },
248 { kFontCSSymbol, "adobe" },
249 { kFontCSSymbol, "sun" },
250 { kFontCSOther, 0 }
251};
252
253
254// Characters used when displaying control sequences.
255
256static char gHexChars[] = "0123456789abcdefxtnvr\\";
257
258
259// The following table maps some control characters to sequences like '\n'
260// rather than '\x10'. A zero entry in the table means no such mapping
261// exists, and the table only maps characters less than 0x10.
262
263static char gMapChars[] = {
264 0, 0, 0, 0, 0, 0, 0, 'a', 'b', 't', 'n', 'v', 'f', 'r', 0
265};
266
267static int GetControlCharSubst(int c, char buf[4]);
268
269
270////////////////////////////////////////////////////////////////////////////////
271/// Delete font.
272
274{
275 if (fFontStruct) {
276 gVirtualX->DeleteFont(fFontStruct);
277 }
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// Get font metrics.
282
284{
285 if (!m) {
286 Error("GetFontMetrics", "argument may not be 0");
287 return;
288 }
289
290 *m = fFM;
291 m->fLinespace = fFM.fAscent + fFM.fDescent;
292}
293
294////////////////////////////////////////////////////////////////////////////////
295/// Not inline due to a bug in g++ 2.96 20000731 (Red Hat Linux 7.0)
296
298{
299 return fFontStruct;
300}
301
302////////////////////////////////////////////////////////////////////////////////
303/// Print font info.
304
306{
307 TString opt = option;
308
309 if ((opt == "full") && fNamedHash) {
310 Printf("TGFont: %s, %s, ref cnt = %u",
312 fFM.fFixed ? "fixed" : "prop", References());
313 } else {
314 Printf("TGFont: %s, %s, ref cnt = %u", fName.Data(),
315 fFM.fFixed ? "fixed" : "prop", References());
316 }
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Return the name of the corresponding Postscript font for this TGFont.
321///
322/// The return value is the pointsize of the TGFont. The name of the
323/// Postscript font is appended to ds.
324///
325/// If the font does not exist on the printer, the print job will fail at
326/// print time. Given a "reasonable" Postscript printer, the following
327/// TGFont font families should print correctly:
328///
329/// Avant Garde, Arial, Bookman, Courier, Courier New, Geneva,
330/// Helvetica, Monaco, New Century Schoolbook, New York,
331/// Palatino, Symbol, Times, Times New Roman, Zapf Chancery,
332/// and Zapf Dingbats.
333///
334/// Any other TGFont font families may not print correctly because the
335/// computed Postscript font name may be incorrect.
336///
337/// dst -- Pointer to an initialized TString object to which the name of the
338/// Postscript font that corresponds to the font will be appended.
339
341{
342 const char *family;
345 char *src, *dest;
346 Int_t upper, len;
347
348 len = dst->Length();
349
350 // Convert the case-insensitive TGFont family name to the
351 // case-sensitive Postscript family name. Take out any spaces and
352 // capitalize the first letter of each word.
353
354 family = fFA.fFamily;
355 if (strncasecmp(family, "itc ", 4) == 0) {
356 family = family + 4;
357 }
358 if ((strcasecmp(family, "Arial") == 0)
359 || (strcasecmp(family, "Geneva") == 0)) {
360 family = "Helvetica";
361 } else if ((strcasecmp(family, "Times New Roman") == 0)
362 || (strcasecmp(family, "New York") == 0)) {
363 family = "Times";
364 } else if ((strcasecmp(family, "Courier New") == 0)
365 || (strcasecmp(family, "Monaco") == 0)) {
366 family = "Courier";
367 } else if (strcasecmp(family, "AvantGarde") == 0) {
368 family = "AvantGarde";
369 } else if (strcasecmp(family, "ZapfChancery") == 0) {
370 family = "ZapfChancery";
371 } else if (strcasecmp(family, "ZapfDingbats") == 0) {
372 family = "ZapfDingbats";
373 } else {
374
375 // Inline, capitalize the first letter of each word, lowercase the
376 // rest of the letters in each word, and then take out the spaces
377 // between the words. This may make the TString shorter, which is
378 // safe to do.
379
380 dst->Append(family);
381
382 src = dest = (char*)dst->Data() + len;
383 upper = 1;
384 for (; *src != '\0'; src++, dest++) {
385 while (isspace(UChar_t(*src))) {
386 src++;
387 upper = 1;
388 }
389 *dest = *src;
390 if ((upper != 0) && (islower(UChar_t(*src)))) {
391 *dest = toupper(UChar_t(*src));
392 }
393 upper = 0;
394 }
395 *dest = '\0';
396 //dst->SetLength(dest - dst->GetString()); // dst->ResetLength(); may be better
397 family = (char *) dst->Data() + len;
398 }
399 if (family != (char *) dst->Data() + len) {
400 dst->Append(family);
401 family = (char *) dst->Data() + len;
402 }
403 if (strcasecmp(family, "NewCenturySchoolbook") == 0) {
404// dst->SetLength(len);
405 dst->Append("NewCenturySchlbk");
406 family = (char *) dst->Data() + len;
407 }
408
409 // Get the string to use for the weight.
410
411 weightString = "";
413 if (strcmp(family, "Bookman") == 0) {
414 weightString = "Light";
415 } else if (strcmp(family, "AvantGarde") == 0) {
416 weightString = "Book";
417 } else if (strcmp(family, "ZapfChancery") == 0) {
418 weightString = "Medium";
419 }
420 } else {
421 if ((strcmp(family, "Bookman") == 0)
422 || (strcmp(family, "AvantGarde") == 0)) {
423 weightString = "Demi";
424 } else {
425 weightString = "Bold";
426 }
427 }
428
429 // Get the string to use for the slant.
430
431 slantString = "";
432 if (fFA.fSlant == kFontSlantRoman) {
433 ;
434 } else {
435 if ((strcmp(family, "Helvetica") == 0)
436 || (strcmp(family, "Courier") == 0)
437 || (strcmp(family, "AvantGarde") == 0)) {
438 slantString = "Oblique";
439 } else {
440 slantString = "Italic";
441 }
442 }
443
444 // The string "Roman" needs to be added to some fonts that are not bold
445 // and not italic.
446
447 if ((slantString.IsNull()) && (weightString.IsNull())) {
448 if ((strcmp(family, "Times") == 0)
449 || (strcmp(family, "NewCenturySchlbk") == 0)
450 || (strcmp(family, "Palatino") == 0)) {
451 dst->Append("-Roman");
452 }
453 } else {
454 dst->Append("-");
455 if (!weightString.IsNull()) dst->Append(weightString);
456 if (!slantString.IsNull()) dst->Append(slantString);
457 }
458
459 return fFA.fPointsize;
460}
461
462////////////////////////////////////////////////////////////////////////////////
463/// Determine the number of characters from the string that will fit in the
464/// given horizontal span. The measurement is done under the assumption that
465/// DrawChars() will be used to actually display the characters.
466///
467/// The return value is the number of characters from source that fit into
468/// the span that extends from 0 to maxLength. *length is filled with the
469/// x-coordinate of the right edge of the last character that did fit.
470///
471/// source -- Characters to be displayed. Need not be '\0' terminated.
472/// numChars -- Maximum number of characters to consider from source string.
473/// maxLength -- If > 0, maxLength specifies the longest permissible line
474/// length; don't consider any character that would cross this
475/// x-position. If <= 0, then line length is unbounded and the
476/// flags argument is ignored.
477/// flags -- Various flag bits OR-ed together:
478/// TEXT_PARTIAL_OK means include the last char which only
479/// partially fit on this line.
480/// TEXT_WHOLE_WORDS means stop on a word boundary, if possible.
481/// TEXT_AT_LEAST_ONE means return at least one character even
482/// if no characters fit.
483/// *length -- Filled with x-location just after the terminating character.
484
486 Int_t flags, Int_t *length) const
487{
488 const char *p; // Current character.
489 const char *term; // Pointer to most recent character that may legally be a terminating character.
490 Int_t termX; // X-position just after term.
491 Int_t curX; // X-position corresponding to p.
492 Int_t newX; // X-position corresponding to p+1.
494
495 if (!numChars) {
496 *length = 0;
497 return 0;
498 }
499 if (maxLength <= 0) {
501 }
502 newX = curX = termX = 0;
503 p = term = source;
505
506 // Scan the input string one character at a time, calculating width.
507
508 for (c = UChar_t(*p);;) {
509 newX += fWidths[c];
510 if (newX > maxLength) {
511 break;
512 }
513 curX = newX;
514 numChars--;
515 p++;
516 if (!numChars) {
517 term = p;
518 termX = curX;
519 break;
520 }
521 c = UChar_t(*p);
522 if (isspace(c)) {
523 if (sawNonSpace) {
524 term = p;
525 termX = curX;
526 sawNonSpace = 0;
527 }
528 } else {
529 sawNonSpace = 1;
530 }
531 }
532
533 // P points to the first character that doesn't fit in the desired
534 // span. Use the flags to figure out what to return.
535
536 if ((flags & kTextPartialOK) && (numChars > 0) && (curX < maxLength)) {
537
538 // Include the first character that didn't quite fit in the desired
539 // span. The width returned will include the width of that extra
540 // character.
541
542 numChars--;
543 curX = newX;
544 p++;
545 }
546 if ((flags & kTextAtLeastOne) && (term == source) && (numChars > 0)) {
547 term = p;
548 termX = curX;
549 if (term == source) {
550 term++;
551 termX = newX;
552 }
553 } else if ((numChars == 0) || !(flags & kTextWholeWords)) {
554 term = p;
555 termX = curX;
556 }
557 *length = termX;
558
559 return term - source;
560}
561
562////////////////////////////////////////////////////////////////////////////////
563/// A wrapper function for the more complicated interface of MeasureChars.
564/// Computes how much space the given simple string needs.
565///
566/// The return value is the width (in pixels) of the given string.
567///
568/// string -- String whose width will be computed.
569/// numChars -- Number of characters to consider from string, or < 0 for
570/// strlen().
571
572Int_t TGFont::TextWidth(const char *string, Int_t numChars) const
573{
574 Int_t width;
575
576 if (numChars < 0) {
577 numChars = strlen(string);
578 }
579 MeasureChars(string, numChars, 0, 0, &width);
580
581 return width;
582}
583
584////////////////////////////////////////////////////////////////////////////////
585/// Return text width in pixels
586
587Int_t TGFont::XTextWidth(const char *string, Int_t numChars) const
588{
589 int width;
590
591 if (numChars < 0) {
592 numChars = strlen(string);
593 }
594 width = gVirtualX->TextWidth(fFontStruct, string, numChars);
595
596 return width;
597}
598
599////////////////////////////////////////////////////////////////////////////////
600/// This procedure draws an underline for a given range of characters in a
601/// given string. It doesn't draw the characters (which are assumed to have
602/// been displayed previously); it just draws the underline. This procedure
603/// would mainly be used to quickly underline a few characters without having
604/// to construct an underlined font. To produce properly underlined text, the
605/// appropriate underlined font should be constructed and used.
606///
607/// dst -- Window or pixmap in which to draw.
608/// gc -- Graphics context for actually drawing line.
609/// string -- String containing characters to be underlined or overstruck.
610/// x, y -- Coordinates at which first character of string is drawn.
611/// firstChar -- Index of first character.
612/// lastChar -- Index of one after the last character.
613
615 const char *string, Int_t x, Int_t y,
617{
619
620 MeasureChars(string, firstChar, 0, 0, &startX);
621 MeasureChars(string, lastChar, 0, 0, &endX);
622
623 gVirtualX->FillRectangle(dst, gc, x + startX, y + fUnderlinePos,
624 (UInt_t) (endX - startX),
626}
627
628////////////////////////////////////////////////////////////////////////////////
629/// Computes the amount of screen space needed to display a multi-line,
630/// justified string of text. Records all the measurements that were done
631/// to determine to size and positioning of the individual lines of text;
632/// this information can be used by the TGTextLayout::DrawText() procedure
633/// to display the text quickly (without remeasuring it).
634///
635/// This procedure is useful for simple widgets that want to display
636/// single-font, multi-line text and want TGFont to handle the details.
637///
638/// The return value is a TGTextLayout token that holds the measurement
639/// information for the given string. The token is only valid for the given
640/// string. If the string is freed, the token is no longer valid and must
641/// also be deleted.
642///
643/// The dimensions of the screen area needed to display the text are stored
644/// in *width and *height.
645///
646/// string -- String whose dimensions are to be computed.
647/// numChars -- Number of characters to consider from string, or < 0 for
648/// strlen().
649/// wrapLength -- Longest permissible line length, in pixels. <= 0 means no
650/// automatic wrapping: just let lines get as long as needed.
651/// justify -- How to justify lines.
652/// flags -- Flag bits OR-ed together. kTextIgnoreTabs means that tab
653/// characters should not be expanded. kTextIgnoreNewlines
654/// means that newline characters should not cause a line break.
655/// width -- Filled with width of string.
656/// height -- Filled with height of string.
657
660 UInt_t *width, UInt_t *height) const
661{
662 const char *start, *end, *special;
667
668#define MAX_LINES 50
672
675
677
678 if (numChars < 0) {
679 numChars = strlen(string);
680 }
681 maxChunks = 0;
682
683 layout = new TGTextLayout;
684 layout->fFont = this;
685 layout->fString = string;
686 layout->fNumChunks = 0;
687 layout->fChunks = 0;
688
690 maxWidth = 0;
691
692 // Divide the string up into simple strings and measure each string.
693
694 curX = 0;
695
696 end = string + numChars;
697 special = string;
698
701 curLine = 0;
702
703 for (start = string; start < end;) {
704 if (start >= special) {
705 // Find the next special character in the string.
706
707 for (special = start; special < end; special++) {
708 if (!(flags & kTextIgnoreNewlines)) {
709 if ((*special == '\n') || (*special == '\r')) {
710 break;
711 }
712 }
713 if (!(flags & kTextIgnoreTabs)) {
714 if (*special == '\t') {
715 break;
716 }
717 }
718 }
719 }
720
721 // Special points at the next special character (or the end of the
722 // string). Process characters between start and special.
723
724 chunk = 0;
725 if (start < special) {
726 charsThisChunk = MeasureChars(start, special - start,
727 wrapLength - curX, flags, &newX);
728 newX += curX;
729 flags &= ~kTextAtLeastOne;
730 if (charsThisChunk > 0) {
731 chunk = NewChunk(layout, &maxChunks, start,
733
734 start += charsThisChunk;
735 curX = newX;
736 }
737 }
738 if ((start == special) && (special < end)) {
739 // Handle the special character.
741
742 chunk = 0;
743 if (*special == '\t') {
744 newX = curX + fTabWidth;
745 newX -= newX % fTabWidth;
747 if (newchunk) newchunk->fNumDisplayChars = -1;
748 start++;
749 if ((start < end) && ((wrapLength <= 0) || (newX <= wrapLength))) {
750
751 // More chars can still fit on this line.
752
753 curX = newX;
754 flags &= ~kTextAtLeastOne;
755 continue;
756 }
757 } else {
758 newchunk = NewChunk(layout, &maxChunks, start, 1, curX, 1000000000, baseline);
759 if (newchunk) newchunk->fNumDisplayChars = -1;
760 start++;
761 goto wrapLine;
762 }
763 }
764
765 // No more characters are going to go on this line, either because
766 // no more characters can fit or there are no more characters left.
767 // Consume all extra spaces at end of line.
768
769 while ((start < end) && isspace(UChar_t(*start))) {
770 if (!(flags & kTextIgnoreNewlines)) {
771 if ((*start == '\n') || (*start == '\r')) {
772 break;
773 }
774 }
775 if (!(flags & kTextIgnoreTabs)) {
776 if (*start == '\t') {
777 break;
778 }
779 }
780 start++;
781 }
782 if (chunk) {
783 // Append all the extra spaces on this line to the end of the
784 // last text chunk.
785
786 charsThisChunk = start - (chunk->fStart + chunk->fNumChars);
787 if (charsThisChunk > 0) {
788 chunk->fNumChars += MeasureChars(chunk->fStart + chunk->fNumChars,
789 charsThisChunk, 0, 0, &chunk->fTotalWidth);
790 chunk->fTotalWidth += curX;
791 }
792 }
794 flags |= kTextAtLeastOne;
795
796 // Save current line length, then move current position to start of
797 // next line.
798
799 if (curX > maxWidth) {
800 maxWidth = curX;
801 }
802
803 // Remember width of this line, so that all chunks on this line
804 // can be centered or right justified, if necessary.
805
806 if (curLine >= maxLines) {
807 int *newLengths;
808
809 newLengths = new int[2 * maxLines];
810 memcpy((void *) newLengths, lineLengths, maxLines * sizeof (int));
811
813 delete[] lineLengths;
814 }
816 maxLines *= 2;
817 }
819 curLine++;
820
821 curX = 0;
822 baseline += h;
823 }
824
825 // If last line ends with a newline, then we need to make a 0 width
826 // chunk on the next line. Otherwise "Hello" and "Hello\n" are the
827 // same height.
828
829 if ((layout->fNumChunks > 0) && ((flags & kTextIgnoreNewlines) == 0)) {
830 if (layout->fChunks[layout->fNumChunks - 1].fStart[0] == '\n') {
831 chunk = NewChunk(layout, &maxChunks, start, 0, curX, 1000000000, baseline);
832 chunk->fNumDisplayChars = -1;
833 baseline += h;
834 }
835 }
836
837 // Using maximum line length, shift all the chunks so that the lines are
838 // all justified correctly.
839
840 curLine = 0;
841 chunk = layout->fChunks;
842 if (chunk) {
843 y = chunk->fY;
844 for (n = 0; n < layout->fNumChunks; n++) {
845 int extra = maxWidth;
846
847 if (chunk->fY != y) {
848 curLine++;
849 y = chunk->fY;
850 }
851 if (curLine < maxLines)
852 extra = maxWidth - lineLengths[curLine];
853 if (justify == kTextCenterX) {
854 chunk->fX += extra / 2;
855 } else if (justify == kTextRight) {
856 chunk->fX += extra;
857 }
858 ++chunk;
859 }
860 }
861
862 layout->fWidth = maxWidth;
864 if (layout->fNumChunks == 0) {
865 layoutHeight = h;
866
867 // This fake chunk is used by the other procedures so that they can
868 // pretend that there is a chunk with no chars in it, which makes
869 // the coding simpler.
870
871 layout->fNumChunks = 1;
872 layout->fChunks = new LayoutChunk_t[1];
873 layout->fChunks[0].fStart = string;
874 layout->fChunks[0].fNumChars = 0;
875 layout->fChunks[0].fNumDisplayChars = -1;
876 layout->fChunks[0].fX = 0;
877 layout->fChunks[0].fY = fFM.fAscent;
878 layout->fChunks[0].fTotalWidth = 0;
879 layout->fChunks[0].fDisplayWidth = 0;
880 }
881 if (width) {
882 *width = layout->fWidth;
883 }
884 if (height) {
886 }
888 delete[] lineLengths;
889 }
890
891 return layout;
892}
893
894////////////////////////////////////////////////////////////////////////////////
895/// destructor
896
898{
899 if (fChunks) {
900 delete[] fChunks;
901 }
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Use the information in the TGTextLayout object to display a multi-line,
906/// justified string of text.
907///
908/// This procedure is useful for simple widgets that need to display
909/// single-font, multi-line text and want TGFont to handle the details.
910///
911/// dst -- Window or pixmap in which to draw.
912/// gc -- Graphics context to use for drawing text.
913/// x, y -- Upper-left hand corner of rectangle in which to draw
914/// (pixels).
915/// firstChar -- The index of the first character to draw from the given
916/// text item. 0 specfies the beginning.
917/// lastChar -- The index just after the last character to draw from the
918/// given text item. A number < 0 means to draw all characters.
919
922{
925
926 if (lastChar < 0) lastChar = 100000000;
927 chunk = fChunks;
928
929 for (i = 0; i < fNumChunks; i++) {
930 numDisplayChars = chunk->fNumDisplayChars;
931 if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) {
932 if (firstChar <= 0) {
933 drawX = 0;
934 firstChar = 0;
935 } else {
936 fFont->MeasureChars(chunk->fStart, firstChar, 0, 0, &drawX);
937 }
939 fFont->DrawChars(dst, gc, chunk->fStart + firstChar, numDisplayChars - firstChar,
940 x + chunk->fX + drawX, y + chunk->fY);
941 }
942 firstChar -= chunk->fNumChars;
943 lastChar -= chunk->fNumChars;
944
945 if (lastChar <= 0) break;
946 chunk++;
947 }
948}
949
950////////////////////////////////////////////////////////////////////////////////
951/// Use the information in the TGTextLayout object to display an underline
952/// below an individual character. This procedure does not draw the text,
953/// just the underline.
954///
955/// This procedure is useful for simple widgets that need to display
956/// single-font, multi-line text with an individual character underlined
957/// and want TGFont to handle the details. To display larger amounts of
958/// underlined text, construct and use an underlined font.
959///
960/// dst -- Window or pixmap in which to draw.
961/// gc -- Graphics context to use for drawing text.
962/// x, y -- Upper-left hand corner of rectangle in which to draw
963/// (pixels).
964/// underline -- Index of the single character to underline, or -1 for
965/// no underline.
966
968 Int_t x, Int_t y, Int_t underline) const
969{
970 int xx, yy, width, height;
971
972 if ((CharBbox(underline, &xx, &yy, &width, &height) != 0)
973 && (width != 0)) {
974 gVirtualX->FillRectangle(dst, gc, x + xx,
975 y + yy + fFont->fFM.fAscent + fFont->fUnderlinePos,
976 (UInt_t) width, (UInt_t) fFont->fUnderlineHeight);
977 }
978}
979
980////////////////////////////////////////////////////////////////////////////////
981/// Use the information in the TGTextLayout token to determine the character
982/// closest to the given point. The point must be specified with respect to
983/// the upper-left hand corner of the text layout, which is considered to be
984/// located at (0, 0).
985///
986/// Any point whose y-value is less that 0 will be considered closest to the
987/// first character in the text layout; any point whose y-value is greater
988/// than the height of the text layout will be considered closest to the last
989/// character in the text layout.
990///
991/// Any point whose x-value is less than 0 will be considered closest to the
992/// first character on that line; any point whose x-value is greater than the
993/// width of the text layout will be considered closest to the last character
994/// on that line.
995///
996/// The return value is the index of the character that was closest to the
997/// point. Given a text layout with no characters, the value 0 will always
998/// be returned, referring to a hypothetical zero-width placeholder character.
999
1001{
1002 LayoutChunk_t *chunk, *last;
1003 Int_t i, n, dummy, baseline, pos;
1004
1005 if (y < 0) {
1006 // Point lies above any line in this layout. Return the index of
1007 // the first char.
1008
1009 return 0;
1010 }
1011
1012 // Find which line contains the point.
1013
1014 last = chunk = fChunks;
1015 for (i = 0; i < fNumChunks; i++) {
1016 baseline = chunk->fY;
1017 if (y < baseline + fFont->fFM.fDescent) {
1018 if (x < chunk->fX) {
1019 // Point is to the left of all chunks on this line. Return
1020 // the index of the first character on this line.
1021
1022 return (chunk->fStart - fString);
1023 }
1024 if (x >= fWidth) {
1025
1026 // If point lies off right side of the text layout, return
1027 // the last char in the last chunk on this line. Without
1028 // this, it might return the index of the first char that
1029 // was located outside of the text layout.
1030
1031 x = INT_MAX;
1032 }
1033
1034 // Examine all chunks on this line to see which one contains
1035 // the specified point.
1036
1037 last = chunk;
1038 while ((i < fNumChunks) && (chunk->fY == baseline)) {
1039 if (x < chunk->fX + chunk->fTotalWidth) {
1040
1041 // Point falls on one of the characters in this chunk.
1042
1043 if (chunk->fNumDisplayChars < 0) {
1044
1045 // This is a special chunk that encapsulates a single
1046 // tab or newline char.
1047
1048 return (chunk->fStart - fString);
1049 }
1050 n = fFont->MeasureChars(chunk->fStart, chunk->fNumChars,
1051 x + 1 - chunk->fX, kTextPartialOK, &dummy);
1052 return ((chunk->fStart + n - 1) - fString);
1053 }
1054 last = chunk;
1055 chunk++;
1056 i++;
1057 }
1058
1059 // Point is to the right of all chars in all the chunks on this
1060 // line. Return the index just past the last char in the last
1061 // chunk on this line.
1062
1063 pos = (last->fStart + last->fNumChars) - fString;
1064 if (i < fNumChunks) pos--;
1065 return pos;
1066 }
1067 last = chunk;
1068 chunk++;
1069 }
1070
1071 // Point lies below any line in this text layout. Return the index
1072 // just past the last char.
1073
1074 return ((last->fStart + last->fNumChars) - fString);
1075}
1076
1077////////////////////////////////////////////////////////////////////////////////
1078/// Use the information in the TGTextLayout token to return the bounding box
1079/// for the character specified by index.
1080///
1081/// The width of the bounding box is the advance width of the character, and
1082/// does not include and left- or right-bearing. Any character that extends
1083/// partially outside of the text layout is considered to be truncated at the
1084/// edge. Any character which is located completely outside of the text
1085/// layout is considered to be zero-width and pegged against the edge.
1086///
1087/// The height of the bounding box is the line height for this font,
1088/// extending from the top of the ascent to the bottom of the descent.
1089/// Information about the actual height of the individual letter is not
1090/// available.
1091///
1092/// A text layout that contains no characters is considered to contain a
1093/// single zero-width placeholder character.
1094///
1095/// The return value is 0 if the index did not specify a character in the
1096/// text layout, or non-zero otherwise. In that case, *bbox is filled with
1097/// the bounding box of the character.
1098///
1099/// layout -- Layout information, from a previous call to ComputeTextLayout().
1100/// index -- The index of the character whose bbox is desired.
1101/// x, y -- Filled with the upper-left hand corner, in pixels, of the
1102/// bounding box for the character specified by index, if non-NULL.
1103/// w, h -- Filled with the width and height of the bounding box for the
1104/// character specified by index, if non-NULL.
1105
1107{
1109 Int_t i, xx = 0, ww = 0;
1110
1111 if (index < 0) {
1112 return 0;
1113 }
1114
1115 chunk = fChunks;
1116
1117 for (i = 0; i < fNumChunks; i++) {
1118 if (chunk->fNumDisplayChars < 0) {
1119 if (!index) {
1120 xx = chunk->fX;
1121 ww = chunk->fTotalWidth;
1122 goto check;
1123 }
1124 } else if (index < chunk->fNumChars) {
1125 if (x) {
1126 fFont->MeasureChars(chunk->fStart, index, 0, 0, &xx);
1127 xx += chunk->fX;
1128 }
1129 if (w) {
1130 fFont->MeasureChars(chunk->fStart + index, 1, 0, 0, &ww);
1131 }
1132 goto check;
1133 }
1134 index -= chunk->fNumChars;
1135 chunk++;
1136 }
1137 if (!index) {
1138
1139 // Special case to get location just past last char in layout.
1140
1141 chunk--;
1142 xx = chunk->fX + chunk->fTotalWidth;
1143 ww = 0;
1144 } else {
1145 return 0;
1146 }
1147
1148 // Ensure that the bbox lies within the text layout. This forces all
1149 // chars that extend off the right edge of the text layout to have
1150 // truncated widths, and all chars that are completely off the right
1151 // edge of the text layout to peg to the edge and have 0 width.
1152
1153check:
1154 if (y) {
1155 *y = chunk->fY - fFont->fFM.fAscent;
1156 }
1157 if (h) {
1158 *h = fFont->fFM.fAscent + fFont->fFM.fDescent;
1159 }
1160 if (xx > fWidth) {
1161 xx = fWidth;
1162 }
1163 if (x) {
1164 *x = xx;
1165 }
1166 if (w) {
1167 if (xx + ww > fWidth) {
1168 ww = fWidth - xx;
1169 }
1170 *w = ww;
1171 }
1172 return 1;
1173}
1174
1175////////////////////////////////////////////////////////////////////////////////
1176/// Computes the distance in pixels from the given point to the given
1177/// text layout. Non-displaying space characters that occur at the end of
1178/// individual lines in the text layout are ignored for hit detection
1179/// purposes.
1180///
1181/// The return value is 0 if the point (x, y) is inside the text layout.
1182/// If the point isn't inside the text layout then the return value is the
1183/// distance in pixels from the point to the text item.
1184///
1185/// x, y -- Coordinates of point to check, with respect to the upper-left
1186/// corner of the text layout (in pixels).
1187
1189{
1190 Int_t i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent;
1192
1193 ascent = fFont->fFM.fAscent;
1194 descent = fFont->fFM.fDescent;
1195
1196 minDist = 0;
1197 chunk = fChunks;
1198 for (i = 0; i < fNumChunks; i++) {
1199 if (chunk->fStart[0] == '\n') {
1200
1201 // Newline characters are not counted when computing distance
1202 // (but tab characters would still be considered).
1203
1204 chunk++;
1205 continue;
1206 }
1207 x1 = chunk->fX;
1208 y1 = chunk->fY - ascent;
1209 x2 = chunk->fX + chunk->fDisplayWidth;
1210 y2 = chunk->fY + descent;
1211
1212 if (x < x1) {
1213 xDiff = x1 - x;
1214 } else if (x >= x2) {
1215 xDiff = x - x2 + 1;
1216 } else {
1217 xDiff = 0;
1218 }
1219
1220 if (y < y1) {
1221 yDiff = y1 - y;
1222 } else if (y >= y2) {
1223 yDiff = y - y2 + 1;
1224 } else {
1225 yDiff = 0;
1226 }
1227 if ((xDiff == 0) && (yDiff == 0)) {
1228 return 0;
1229 }
1231 if ((dist < minDist) || !minDist) {
1232 minDist = dist;
1233 }
1234 chunk++;
1235 }
1236 return minDist;
1237}
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Determines whether a text layout lies entirely inside, entirely outside,
1241/// or overlaps a given rectangle. Non-displaying space characters that occur
1242/// at the end of individual lines in the text layout are ignored for
1243/// intersection calculations.
1244///
1245/// The return value is -1 if the text layout is entirely outside of the
1246/// rectangle, 0 if it overlaps, and 1 if it is entirely inside of the
1247/// rectangle.
1248///
1249/// x, y -- Upper-left hand corner, in pixels, of rectangular area to compare
1250/// with text layout. Coordinates are with respect to the upper-left
1251/// hand corner of the text layout itself.
1252/// w, h -- The width and height of the above rectangular area, in pixels.
1253
1255{
1256 Int_t result, i, x1, y1, x2, y2;
1258 Int_t left, top, right, bottom;
1259
1260 // Scan the chunks one at a time, seeing whether each is entirely in,
1261 // entirely out, or overlapping the rectangle. If an overlap is
1262 // detected, return immediately; otherwise wait until all chunks have
1263 // been processed and see if they were all inside or all outside.
1264
1265 chunk = fChunks;
1266
1267 left = x;
1268 top = y;
1269 right = x + w;
1270 bottom = y + h;
1271
1272 result = 0;
1273 for (i = 0; i < fNumChunks; i++) {
1274 if (chunk->fStart[0] == '\n') {
1275
1276 // Newline characters are not counted when computing area
1277 // intersection (but tab characters would still be considered).
1278
1279 chunk++;
1280 continue;
1281 }
1282 x1 = chunk->fX;
1283 y1 = chunk->fY - fFont->fFM.fAscent;
1284 x2 = chunk->fX + chunk->fDisplayWidth;
1285 y2 = chunk->fY + fFont->fFM.fDescent;
1286
1287 if ((right < x1) || (left >= x2) || (bottom < y1) || (top >= y2)) {
1288 if (result == 1) {
1289 return 0;
1290 }
1291 result = -1;
1292 } else if ((x1 < left) || (x2 >= right) || (y1 < top) || (y2 >= bottom)) {
1293 return 0;
1294 } else if (result == -1) {
1295 return 0;
1296 } else {
1297 result = 1;
1298 }
1299 chunk++;
1300 }
1301 return result;
1302}
1303
1304////////////////////////////////////////////////////////////////////////////////
1305/// Outputs the contents of a text layout in Postscript format. The set of
1306/// lines in the text layout will be rendered by the user supplied Postscript
1307/// function. The function should be of the form:
1308///
1309/// justify x y string function --
1310///
1311/// Justify is -1, 0, or 1, depending on whether the following string should
1312/// be left, center, or right justified, x and y is the location for the
1313/// origin of the string, string is the sequence of characters to be printed,
1314/// and function is the name of the caller-provided function; the function
1315/// should leave nothing on the stack.
1316///
1317/// The meaning of the origin of the string (x and y) depends on the
1318/// justification. For left justification, x is where the left edge of the
1319/// string should appear. For center justification, x is where the center of
1320/// the string should appear. And for right justification, x is where the
1321/// right edge of the string should appear. This behavior is necessary
1322/// because, for example, right justified text on the screen is justified
1323/// with screen metrics. The same string needs to be justified with printer
1324/// metrics on the printer to appear in the correct place with respect to
1325/// other similarly justified strings. In all circumstances, y is the
1326/// location of the baseline for the string.
1327///
1328/// result is modified to hold the Postscript code that will render the text
1329/// layout.
1330
1332{
1333#define MAXUSE 128
1334 char buf[MAXUSE + 10];
1336 Int_t i, j, used, c, baseline;
1337
1338 chunk = fChunks;
1339 baseline = chunk->fY;
1340 used = 0;
1341 buf[used++] = '(';
1342
1343 for (i = 0; i < fNumChunks; i++) {
1344 if (baseline != chunk->fY) {
1345 buf[used++] = ')';
1346 buf[used++] = '\n';
1347 buf[used++] = '(';
1348 baseline = chunk->fY;
1349 }
1350 if (chunk->fNumDisplayChars <= 0) {
1351 if (chunk->fStart[0] == '\t') {
1352 buf[used++] = '\\';
1353 buf[used++] = 't';
1354 }
1355 } else {
1356 for (j = 0; j < chunk->fNumDisplayChars; j++) {
1357 c = UChar_t(chunk->fStart[j]);
1358 if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) || (c >= UChar_t(0x7f))) {
1359
1360 // Tricky point: the "03" is necessary in the sprintf
1361 // below, so that a full three digits of octal are
1362 // always generated. Without the "03", a number
1363 // following this sequence could be interpreted by
1364 // Postscript as part of this sequence.
1365
1366 // coverity[secure_coding]
1367 snprintf(buf + used, MAXUSE + 10 - used, "\\%03o", c);
1368 used += 4;
1369 } else {
1370 buf[used++] = c;
1371 }
1372 if (used >= MAXUSE) {
1373 buf[used] = '\0';
1374 result->Append(buf);
1375 used = 0;
1376 }
1377 }
1378 }
1379 if (used >= MAXUSE) {
1380 // If there are a whole bunch of returns or tabs in a row,
1381 // then buf[] could get filled up.
1382
1383 buf[used] = '\0';
1384 result->Append(buf);
1385 used = 0;
1386 }
1387 chunk++;
1388 }
1389 buf[used++] = ')';
1390 buf[used++] = '\n';
1391 buf[used] = '\0';
1392
1393 result->Append(buf);
1394}
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// Helper function for ComputeTextLayout(). Encapsulates a measured set of
1398/// characters in a chunk that can be quickly drawn.
1399///
1400/// Returns a pointer to the new chunk in the text layout. The text layout is
1401/// reallocated to hold more chunks as necessary.
1402///
1403/// Currently, ComputeTextLayout() stores contiguous ranges of "normal"
1404/// characters in a chunk, along with individual tab and newline chars in
1405/// their own chunks. All characters in the text layout are accounted for.
1406
1408 const char *start, Int_t numChars,
1409 Int_t curX, Int_t newX, Int_t y) const
1410{
1412 Int_t i, maxChunks;
1413
1414 maxChunks = *maxPtr;
1415 if (layout->fNumChunks == maxChunks) {
1416 if (maxChunks == 0) {
1417 maxChunks = 1;
1418 } else {
1419 maxChunks *= 2;
1420 }
1422
1423 if (layout->fNumChunks > 0) {
1424 for (i=0; i<layout->fNumChunks; ++i) chunk[i] = layout->fChunks[i];
1425 delete[] layout->fChunks;
1426 }
1427 layout->fChunks = chunk;
1428 *maxPtr = maxChunks;
1429 }
1430
1431 chunk = &layout->fChunks[layout->fNumChunks];
1432 chunk->fStart = start;
1433 chunk->fNumChars = numChars;
1434 chunk->fNumDisplayChars = numChars;
1435 chunk->fX = curX;
1436 chunk->fY = y;
1437 chunk->fTotalWidth = newX - curX;
1438 chunk->fDisplayWidth = newX - curX;
1439 layout->fNumChunks++;
1440
1441 return chunk;
1442}
1443
1444////////////////////////////////////////////////////////////////////////////////
1445/// Draw a string of characters on the screen. DrawCharsExp() expands
1446/// control characters that occur in the string to \\X or \\xXX sequences.
1447/// DrawChars() just draws the strings.
1448///
1449/// dst -- Window or pixmap in which to draw.
1450/// gc -- Graphics context for drawing characters.
1451/// source -- Characters to be displayed. Need not be'\0' terminated.
1452/// For DrawChars(), all meta-characters (tabs, control
1453/// characters, and newlines) should be stripped out of the
1454/// string that is passed to this function. If they are not
1455/// stripped out, they will be displayed as regular printing
1456/// characters.
1457/// numChars -- Number of characters in string.
1458/// x, y -- Coordinates at which to place origin of string when drawing.
1459
1461 const char *source, Int_t numChars,
1462 Int_t x, Int_t y) const
1463{
1464 const char *p;
1465 Int_t i, type;
1466 char buf[4];
1467
1468 p = source;
1469 for (i = 0; i < numChars; i++) {
1470 type = fTypes[UChar_t(*p)];
1471 if (type != kCharNormal) {
1472 DrawChars(dst, gc, source, p - source, x, y);
1473 x += gVirtualX->TextWidth(fFontStruct, source, p - source);
1474 if (type == kCharReplace) {
1475 DrawChars(dst, gc, buf, GetControlCharSubst(UChar_t(*p), buf), x, y);
1476 x += fWidths[UChar_t(*p)];
1477 }
1478 source = p + 1;
1479 }
1480 p++;
1481 }
1482
1483 DrawChars(dst, gc, source, p - source, x, y);
1484}
1485
1486////////////////////////////////////////////////////////////////////////////////
1487/// Perform a quick sanity check to ensure we won't overflow the X
1488/// coordinate space.
1489
1491 const char *source, Int_t numChars,
1492 Int_t x, Int_t y) const
1493{
1494 Int_t max_width = gVirtualX->TextWidth(fFontStruct, "@", 1);
1495
1496 if ((x + (max_width * numChars) > 0x7fff)) {
1497 int length;
1498
1499 // The string we are being asked to draw is too big and would overflow
1500 // the X coordinate space. Unfortunately X servers aren't too bright
1501 // and so they won't deal with this case cleanly. We need to truncate
1502 // the string before sending it to X.
1503
1504 numChars = MeasureChars(source, numChars, 0x7fff - x, 0, &length);
1505 }
1506
1507 gVirtualX->DrawString(dst, gc, x, y, source, numChars);
1508
1509 if (fFA.fUnderline != 0) {
1510 gVirtualX->FillRectangle(dst, gc, x, y + fUnderlinePos,
1511 (UInt_t) gVirtualX->TextWidth(fFontStruct, source, numChars),
1512 (UInt_t) fBarHeight);
1513 }
1514 if (fFA.fOverstrike != 0) {
1515 y -= fFM.fDescent + fFM.fAscent / 10;
1516 gVirtualX->FillRectangle(dst, gc, x, y,
1517 (UInt_t) gVirtualX->TextWidth(fFontStruct, source, numChars),
1518 (UInt_t) fBarHeight);
1519 }
1520}
1521
1522////////////////////////////////////////////////////////////////////////////////
1523/// Create a font pool.
1524
1526{
1527 fClient = client;
1528 fList = new THashTable(50);
1529 fList->SetOwner();
1530
1531 fNamedTable = new THashTable(50);
1533
1534 fUidTable = new THashTable(50);
1536}
1537
1538////////////////////////////////////////////////////////////////////////////////
1539/// Cleanup font pool.
1540
1542{
1543 delete fList;
1544}
1545
1546////////////////////////////////////////////////////////////////////////////////
1547/// Get the specified font.
1548/// The font can be one of the following forms:
1549/// XLFD (see X documentation)
1550/// "Family [size [style] [style ...]]"
1551/// Returns 0 if error or no font can be found.
1552/// If fixedDefault is false the "fixed" font will not be substituted
1553/// as fallback when the asked for font does not exist.
1554
1556{
1557 if (!font || !*font) {
1558 Error("GetFont", "argument may not be 0 or empty");
1559 return 0;
1560 }
1561
1562 TGFont *f = (TGFont*)fList->FindObject(font);
1563
1564 if (f) {
1565 f->AddReference();
1566 return f;
1567 }
1568
1570
1571 if (nf) {
1572 // Construct a font based on a named font.
1573 nf->AddReference();
1574 f = GetFontFromAttributes(&nf->fFA, 0);
1575
1576 } else {
1577
1578 // Native font (aka string in XLFD format)?
1581
1582 f = GetNativeFont(font, fixedDefault);
1584
1585 if (!f) {
1587
1588 if (!ParseFontName(font, &fa)) {
1589 //fontCache.DeleteHashEntry(cacheHash);
1590
1591 return 0;
1592 }
1593
1594 // String contained the attributes inline.
1595 f = GetFontFromAttributes(&fa, 0);
1596 }
1597 }
1598
1599 if (!f) return 0;
1600
1601 fList->Add(f);
1602
1603 f->SetRefCount(1);
1604 //f->cacheHash = cacheHash;
1605 f->fNamedHash = nf;
1606
1607 f->MeasureChars("0", 1, 0, 0, &f->fTabWidth);
1608
1609 if (!f->fTabWidth) {
1610 f->fTabWidth = f->fFM.fMaxWidth;
1611 }
1612 f->fTabWidth *= 8;
1613
1614 // Make sure the tab width isn't zero (some fonts may not have enough
1615 // information to set a reasonable tab width).
1616
1617 if (!f->fTabWidth) {
1618 f->fTabWidth = 1;
1619 }
1620
1621 // Get information used for drawing underlines in generic code on a
1622 // non-underlined font.
1623
1624 Int_t descent = f->fFM.fDescent;
1625 f->fUnderlinePos = descent/2; // ==!== could be set by MakeFont()
1626 f->fUnderlineHeight = f->fFA.fPointsize/10;
1627
1628 if (!f->fUnderlineHeight) {
1629 f->fUnderlineHeight = 1;
1630 }
1631 if (f->fUnderlinePos + f->fUnderlineHeight > descent) {
1632
1633 // If this set of values would cause the bottom of the underline
1634 // bar to stick below the descent of the font, jack the underline
1635 // up a bit higher.
1636
1637 f->fUnderlineHeight = descent - f->fUnderlinePos;
1638
1639 if (!f->fUnderlineHeight) {
1640 f->fUnderlinePos--;
1641 f->fUnderlineHeight = 1;
1642 }
1643 }
1644
1645 return f;
1646}
1647
1648////////////////////////////////////////////////////////////////////////////////
1649/// Use font, i.e. increases ref count of specified font. Returns 0
1650/// if font is not found.
1651
1653{
1654 TGFont *f = (TGFont*)fList->FindObject(font);
1655
1656 if (f) {
1657 f->AddReference();
1658 return f;
1659 }
1660
1661 return 0;
1662}
1663
1664////////////////////////////////////////////////////////////////////////////////
1665/// Use font, i.e. increases ref count of specified font.
1666
1668{
1669 TGFont *f = FindFont(fs);
1670
1671 if (f) {
1672 f->AddReference();
1673 return f;
1674 }
1675
1676 static int i = 0;
1677 f = MakeFont(0, fs, TString::Format("unknown-%d", i));
1678 fList->Add(f);
1679 i++;
1680
1681 return f;
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685/// Returns font specified bay family, pixel/point size, weight and slant
1686/// negative value of ptsize means size in pixels
1687/// positive value of ptsize means size in points
1688///
1689/// For example:
1690/// TGFont *font = fpool->GetFont("helvetica", -9, kFontWeightNormal, kFontSlantRoman);
1691/// font->Print();
1692
1694{
1695 const char *s;
1696 TString tmp;
1697
1698 tmp = TString::Format("%s %d", family, ptsize);
1699 s = FindStateString(gWeightMap, weight);
1700 if (s) {
1701 tmp += " ";
1702 tmp + s;
1703 }
1705 if (s) {
1706 tmp += " ";
1707 tmp += s;
1708 }
1709 return GetFont(tmp.Data());
1710}
1711
1712////////////////////////////////////////////////////////////////////////////////
1713/// Free font. If ref count is 0 delete font.
1714
1716{
1717 TGFont *f = (TGFont*) fList->FindObject(font);
1718 if (f) {
1719 if (f->RemoveReference() == 0) {
1720 if (font->fNamedHash) {
1721
1722 // The font is being deleted. Determine if the associated named
1723 // font definition should and/or can be deleted too.
1724
1725 TNamedFont *nf = (TNamedFont *) font->fNamedHash;
1726
1727 if ((nf->RemoveReference() == 0) && (nf->fDeletePending != 0)) {
1729 delete nf;
1730 }
1731 }
1732 fList->Remove(f);
1733 delete font;
1734 }
1735 }
1736}
1737
1738////////////////////////////////////////////////////////////////////////////////
1739/// Find font based on its font struct. Returns 0 if font is not found.
1740
1742{
1743 TIter next(fList);
1744 TGFont *f = 0;
1745
1746 while ((f = (TGFont*) next())) {
1747 if (f->fFontStruct == font) {
1748 return f;
1749 }
1750 }
1751
1752 return 0;
1753}
1754
1755////////////////////////////////////////////////////////////////////////////////
1756/// Find font based on its font handle. Returns 0 if font is not found.
1757
1759{
1760 TIter next(fList);
1761 TGFont *f = 0;
1762
1763 while ((f = (TGFont*) next())) {
1764 if (f->fFontH == font) {
1765 return f;
1766 }
1767 }
1768
1769 return 0;
1770}
1771
1772////////////////////////////////////////////////////////////////////////////////
1773/// Given a string, this procedure returns a unique identifier for the string.
1774///
1775/// This procedure returns a pointer to a new char string corresponding to
1776/// the "string" argument. The new string has a value identical to string
1777/// (strcmp will return 0), but it's guaranteed that any other calls to this
1778/// procedure with a string equal to "string" will return exactly the same
1779/// result (i.e. can compare pointer *values* directly, without having to
1780/// call strcmp on what they point to).
1781
1782const char *TGFontPool::GetUid(const char *string)
1783{
1784 TObjString *obj = 0;
1785 obj = (TObjString*)fUidTable->FindObject(string);
1786
1787 if (!obj) {
1788 obj = new TObjString(string);
1789 fUidTable->Add(obj);
1790 }
1791
1792 return (const char *)obj->GetName();
1793}
1794
1795////////////////////////////////////////////////////////////////////////////////
1796/// Return information about the font attributes as an array of strings.
1797///
1798/// An array of FONT_NUMFIELDS strings is returned holding the value of the
1799/// font attributes in the following order:
1800/// family size weight slant underline overstrike
1801
1803{
1804 Int_t i, num;
1805 const char *str = 0;
1806
1807 char **result = new char*[FONT_NUMFIELDS];
1808
1809 for (i = 0; i < FONT_NUMFIELDS; ++i) {
1810 str = 0;
1811 num = 0;
1812
1813 switch (i) {
1814 case FONT_FAMILY:
1815 str = fa->fFamily;
1816 if (!str) str = "";
1817 break;
1818
1819 case FONT_SIZE:
1820 num = fa->fPointsize;
1821 break;
1822
1823 case FONT_WEIGHT:
1825 break;
1826
1827 case FONT_SLANT:
1828 str = FindStateString(gSlantMap, fa->fSlant);
1829 break;
1830
1831 case FONT_UNDERLINE:
1832 num = fa->fUnderline;
1833 break;
1834
1835 case FONT_OVERSTRIKE:
1836 num = fa->fOverstrike;
1837 break;
1838 }
1839
1840 if (str) {
1841 int len = strlen(str)+1;
1842 result[i] = new char[len];
1843 strlcpy(result[i], str, len);
1844 } else {
1845 result[i] = new char[20];
1846 snprintf(result[i], 20, "%d", num);
1847 }
1848 }
1849
1850 return result;
1851}
1852
1853////////////////////////////////////////////////////////////////////////////////
1854/// Free attributes info.
1855
1857{
1858 Int_t i;
1859
1860 if (info) {
1861 for (i = 0; i < FONT_NUMFIELDS; ++i) {
1862 if (info[i]) {
1863 delete[] info[i];
1864 }
1865 }
1866 delete[] info;
1867 }
1868}
1869
1870////////////////////////////////////////////////////////////////////////////////
1871/// List all fonts in the pool.
1872
1874{
1875 fList->Print(opt);
1876}
1877
1878////////////////////////////////////////////////////////////////////////////////
1879/// Save the used font as a C++ statement(s) on output stream out.
1880
1881void TGFont::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
1882{
1883 out << " \n";
1884
1885 // declare a font object to reflect required user changes
1886 if (!gROOT->ClassSaved(TGFont::Class()))
1887 out << " TGFont *ufont; // will reflect user font changes\n";
1888 out << " ufont = gClient->GetFont(\"" << TString(GetName()).ReplaceSpecialCppChars() << "\");\n";
1889}
1890
1891////////////////////////////////////////////////////////////////////////////////
1892
1893static char *GetToken(char *str)
1894{
1895 static char *p = 0;
1896 char *retp;
1897
1898 if (str) p = str;
1899
1900 if (!p) {
1901 return 0;
1902 }
1903 if (!*p) {
1904 return 0;
1905 }
1906
1907 while (*p && ((*p == ' ') || (*p == '\t'))) { // skip spaces
1908 ++p;
1909 }
1910
1911 if (!*p) {
1912 return 0;
1913 }
1914
1915 if (*p == '"') { // quoted string
1916 retp = ++p;
1917
1918 if (!*p) {
1919 return 0;
1920 }
1921
1922 while (*p && (*p != '"')) {
1923 ++p;
1924 }
1925
1926 if (*p == '"') {
1927 *p++ = '\0';
1928 }
1929 } else {
1930 retp = p;
1931 while (*p && (*p != ' ') && (*p != '\t')) {
1932 ++p;
1933 }
1934 if (*p) {
1935 *p++ = '\0';
1936 }
1937 }
1938
1939 return retp;
1940}
1941
1942////////////////////////////////////////////////////////////////////////////////
1943/// Converts a string into a set of font attributes that can be used to
1944/// construct a font.
1945///
1946/// The string can be one of the following forms:
1947/// XLFD (see X documentation)
1948/// "Family [size [style] [style ...]]"
1949///
1950/// The return value is kFALSE if the object was syntactically
1951/// invalid. Otherwise, fills the font attribute buffer with the values
1952/// parsed from the string and returns kTRUE. The structure must already be
1953/// properly initialized.
1954
1956{
1957 char *s;
1958 int n, result;
1959
1961
1962 int len = strlen(string)+1;
1963 char *str = new char[len];
1964 strlcpy(str, string, len);
1965
1966 if (*str == '-' || *str == '*') {
1967
1968 // This appears to be an XLFD.
1969
1970 xa.fFA = *fa;
1971 result = ParseXLFD(str, &xa);
1972 if (result) {
1973 *fa = xa.fFA;
1974 delete[] str;
1975 return kTRUE; //OK
1976 }
1977 }
1978
1979 // Wasn't an XLFD or "-option value" string. Try it as a
1980 // "font size style" list.
1981
1982 s = GetToken(str);
1983 if (!s) {
1984 delete[] str;
1985 return kFALSE;
1986 }
1987 fa->fFamily = GetUid(s);
1988
1989 s = GetToken(0);
1990
1991 if (s) {
1992 char *end;
1993
1994 fa->fPointsize = strtol(s, &end, 0);
1995 if ((errno == ERANGE) || (end == s)) {
1996 delete[] str;
1997 return kFALSE;
1998 }
1999 }
2000
2001 while ((s = GetToken(0))) {
2004 fa->fWeight = n;
2005 continue;
2006 }
2007 n = FindStateNum(gSlantMap, s);
2008 // tell coverity that n is an integer value, and not an enum, even if
2009 // we compare it with an enum value (which is -1 in both case anyway)
2010 // coverity[mixed_enums]
2011 if ((EFontSlant)n != kFontSlantUnknown) {
2012 fa->fSlant = n;
2013 continue;
2014 }
2016 if (n) {
2017 fa->fUnderline = n;
2018 continue;
2019 }
2021 if (n) {
2022 fa->fOverstrike = n;
2023 continue;
2024 }
2025
2026 // Unknown style.
2027
2028 delete[] str;
2029 return kFALSE;
2030 }
2031
2032 delete[] str;
2033 return kTRUE;
2034}
2035
2036////////////////////////////////////////////////////////////////////////////////
2037/// Break up a fully specified XLFD into a set of font attributes.
2038///
2039/// Return value is kFALSE if string was not a fully specified XLFD.
2040/// Otherwise, fills font attribute buffer with the values parsed from
2041/// the XLFD and returns kTRUE.
2042///
2043/// string -- Parseable font description string.
2044/// xa -- XLFD attributes structure whose fields are to be modified.
2045/// Structure must already be properly initialized.
2046
2048{
2049 char *src;
2050 const char *str;
2051 int i, j;
2052 char *field[XLFD_NUMFIELDS + 2];
2053 TString ds("");
2054
2055 memset(field, '\0', sizeof (field));
2056
2057 str = string;
2058 if (*str == '-') str++;
2059
2060 ds.Append((char *) str);
2061 src = (char*)ds.Data();
2062
2063 field[0] = src;
2064 for (i = 0; *src != '\0'; src++) {
2065 if (isupper(UChar_t(*src))) {
2066 *src = tolower(UChar_t(*src));
2067 }
2068 if (*src == '-') {
2069 i++;
2070 if (i > XLFD_NUMFIELDS) {
2071 break;
2072 }
2073 *src = '\0';
2074 field[i] = src + 1;
2075 }
2076 }
2077
2078 // An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common,
2079 // but it is (strictly) malformed, because the first * is eliding both
2080 // the Setwidth and the Addstyle fields. If the Addstyle field is a
2081 // number, then assume the above incorrect form was used and shift all
2082 // the rest of the fields up by one, so the number gets interpreted
2083 // as a pixelsize.
2084
2086 if (atoi(field[XLFD_ADD_STYLE]) != 0) {
2087 for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) {
2088 field[j + 1] = field[j];
2089 }
2090 field[XLFD_ADD_STYLE] = 0;
2091 i++;
2092 }
2093 }
2094
2095 // Bail if we don't have enough of the fields (up to pointsize).
2096
2097 if (i < XLFD_FAMILY) {
2098 return kFALSE;
2099 }
2101 xa->fFoundry = GetUid(field[XLFD_FOUNDRY]);
2102 }
2104 xa->fFA.fFamily = GetUid(field[XLFD_FAMILY]);
2105 }
2108 }
2111 if (xa->fSlant == kFontSlantRoman) {
2112 xa->fFA.fSlant = kFontSlantRoman;
2113 } else {
2114 xa->fFA.fSlant = kFontSlantItalic;
2115 }
2116 }
2119 }
2120 // XLFD_ADD_STYLE ignored.
2121
2122 // Pointsize in tenths of a point, but treat it as tenths of a pixel.
2123
2125 if (field[XLFD_POINT_SIZE][0] == '[') {
2126
2127 // Some X fonts have the point size specified as follows:
2128 //
2129 // [ N1 N2 N3 N4 ]
2130 //
2131 // where N1 is the point size (in points, not decipoints!), and
2132 // N2, N3, and N4 are some additional numbers that I don't know
2133 // the purpose of, so I ignore them.
2134
2135 xa->fFA.fPointsize = atoi(field[XLFD_POINT_SIZE] + 1);
2136 } else {
2137 char *end;
2138
2139 xa->fFA.fPointsize = strtol(field[XLFD_POINT_SIZE], &end, 0);
2140 if (errno == ERANGE || end == field[XLFD_POINT_SIZE]) {
2141 return kFALSE;
2142 }
2143 xa->fFA.fPointsize /= 10;
2144 }
2145 }
2146
2147 // Pixel height of font. If specified, overrides pointsize.
2148
2150 if (field[XLFD_PIXEL_SIZE][0] == '[') {
2151
2152 // Some X fonts have the pixel size specified as follows:
2153 //
2154 // [ N1 N2 N3 N4 ]
2155 //
2156 // where N1 is the pixel size, and where N2, N3, and N4
2157 // are some additional numbers that I don't know
2158 // the purpose of, so I ignore them.
2159
2160 xa->fFA.fPointsize = atoi(field[XLFD_PIXEL_SIZE] + 1);
2161 } else {
2162 char *end;
2163
2164 xa->fFA.fPointsize = strtol(field[XLFD_PIXEL_SIZE], &end, 0);
2165 if (errno == ERANGE || end == field[XLFD_PIXEL_SIZE]) {
2166 return kFALSE;
2167 }
2168 }
2169 }
2170 xa->fFA.fPointsize = -xa->fFA.fPointsize;
2171
2172 // XLFD_RESOLUTION_X ignored.
2173
2174 // XLFD_RESOLUTION_Y ignored.
2175
2176 // XLFD_SPACING ignored.
2177
2178 // XLFD_AVERAGE_WIDTH ignored.
2179
2182 }
2184 xa->fEncoding = atoi(field[XLFD_ENCODING]);
2185 }
2186
2187 return kTRUE;
2188}
2189
2190////////////////////////////////////////////////////////////////////////////////
2191/// Given a lookup table, map a string to a number in the table.
2192///
2193/// If strKey was equal to the string keys of one of the elements in the
2194/// table, returns the numeric key of that element. Returns the numKey
2195/// associated with the last element (the NULL string one) in the table
2196/// if strKey was not equal to any of the string keys in the table.
2197
2199{
2200 const FontStateMap_t *m;
2201
2202 if (!map->fStrKey) {
2203 return 0;
2204 }
2205
2206 for (m = map; m->fStrKey != 0; m++) {
2207 if (strcasecmp(strKey, m->fStrKey) == 0) {
2208 return m->fNumKey;
2209 }
2210 }
2211 return m->fNumKey;
2212}
2213
2214////////////////////////////////////////////////////////////////////////////////
2215/// Given a lookup table, map a number to a string in the table.
2216///
2217/// If numKey was equal to the numeric key of one of the elements in the
2218/// table, returns the string key of that element. Returns NULL if numKey
2219/// was not equal to any of the numeric keys in the table
2220
2222{
2223 for ( ; map->fStrKey != 0; map++) {
2224 if (numKey == map->fNumKey) return map->fStrKey;
2225 }
2226 return 0;
2227}
2228
2229////////////////////////////////////////////////////////////////////////////////
2230/// Helper function for ParseXLFD(). Determines if a field in the XLFD was
2231/// set to a non-null, non-don't-care value.
2232///
2233/// The return value is kFALSE if the field in the XLFD was not set and
2234/// should be ignored, kTRUE otherwise.
2235///
2236/// field -- The field of the XLFD to check. Strictly speaking, only when
2237/// the string is "*" does it mean don't-care. However, an
2238/// unspecified or question mark is also interpreted as don't-care.
2239
2241{
2242 char ch;
2243
2244 if (!field || !strlen(field)) {
2245 return kFALSE;
2246 }
2247 ch = field[0];
2248
2249 return (ch != '*' && ch != '?');
2250}
2251
2252////////////////////////////////////////////////////////////////////////////////
2253/// Given a font, return a textual string identifying it.
2254
2256{
2257 return font->GetName();
2258}
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// Return information about the font families that are available on the
2262/// current display.
2263///
2264/// An array of strings is returned holding a list of all the available font
2265/// families. The array is terminated with a NULL pointer.
2266
2268{
2269 Int_t i, numNames;
2270 char *family, *end, *p;
2271
2273 familyTable.SetOwner();
2274
2275 char **nameList;
2276 char **dst;
2277
2278 // coverity[returned_null]
2279 // coverity[dereference]
2280 nameList = gVirtualX->ListFonts("*", 10000, numNames);
2281
2282 for (i = 0; i < numNames; i++) {
2283 if (nameList[i][0] != '-') {
2284 continue;
2285 }
2286 family = strchr(nameList[i] + 1, '-');
2287 if (!family) {
2288 continue;
2289 }
2290 family++;
2291 end = strchr(family, '-');
2292 if (!end) {
2293 continue;
2294 }
2295 *end = '\0';
2296 for (p = family; *p != '\0'; p++) {
2297 if (isupper(UChar_t(*p))) {
2298 *p = tolower(UChar_t(*p));
2299 }
2300 }
2301 if (!familyTable.FindObject(family)) {
2302 familyTable.Add(new TObjString(family));
2303 }
2304 }
2305
2306 UInt_t entries = familyTable.GetEntries();
2307 dst = new char*[entries+1];
2308
2309 TIter next(&familyTable);
2310 i = 0;
2311 TObject *obj;
2312
2313 while ((obj = next())) {
2314 dst[i] = StrDup(obj->GetName());
2315 i++;
2316 }
2317 dst[i] = 0;
2318
2319 gVirtualX->FreeFontNames(nameList);
2320 return dst;
2321}
2322
2323////////////////////////////////////////////////////////////////////////////////
2324/// Delete an array of families allocated GetFontFamilies() method
2325
2327{
2328 Int_t i;
2329
2330 if (!f) return;
2331
2332 for (i = 0; f[i] != 0; ++i) {
2333 delete[] f[i];
2334 }
2335 delete[] f;
2336}
2337
2338////////////////////////////////////////////////////////////////////////////////
2339/// Given a desired set of attributes for a font, find a font with the
2340/// closest matching attributes and create a new TGFont object.
2341/// The return value is a pointer to a TGFont object that represents the
2342/// font with the desired attributes. If a font with the desired attributes
2343/// could not be constructed, some other font will be substituted
2344/// automatically.
2345///
2346/// Every call to this procedure returns a new TGFont object, even if the
2347/// specified attributes have already been seen before.
2348
2350{
2354 TString buf;
2355 char **nameList;
2356 TGFont *font;
2358 const char *fmt, *family;
2359
2360 family = fa->fFamily;
2361 if (!family) {
2362 family = "*";
2363 }
2364 pixelsize = -fa->fPointsize;
2365
2366 if (pixelsize < 0) {
2367 double d;
2368 d = -pixelsize * 25.4/72;
2369 Int_t xx; Int_t yy; UInt_t ww; UInt_t hh;
2370 gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), xx, yy, ww, hh);
2371 d *= ww;
2372
2373 d /= gVirtualX->ScreenWidthMM();
2374 d += 0.5;
2375 pixelsize = (int) d;
2376 }
2377
2378 // Couldn't find exact match. Now fall back to other available physical fonts.
2379
2380 fmt = "-*-%.240s-*-*-*-*-*-*-*-*-*-*-*-*";
2381 buf = TString::Format(fmt, family);
2382 nameList = gVirtualX->ListFonts(buf.Data(), 32768, numNames);
2383 if (!numNames) {
2384 // Try getting some system font.
2385
2386 buf = TString::Format(fmt, "fixed");
2387 // coverity[returned_null]
2388 // coverity[dereference]
2389 nameList = gVirtualX->ListFonts(buf.Data(), 32768, numNames);
2390
2391 if (!numNames) {
2392
2393getsystem:
2394 fontStruct = gVirtualX->LoadQueryFont("fixed");
2395
2396 if (!fontStruct) {
2397 fontStruct = gVirtualX->LoadQueryFont("*");
2398 if (!fontStruct) {
2399 return 0;
2400 }
2401 }
2402 goto end;
2403 }
2404 }
2405
2406 // Inspect each of the XLFDs and pick the one that most closely
2407 // matches the desired attributes.
2408
2409 bestIdx = 0;
2411 bestScaleableIdx = 0;
2413
2414 for (i = 0; i < numNames; i++) {
2415 score = 0;
2416 scaleable = 0;
2417 if (!ParseXLFD(nameList[i], &xa)) {
2418 continue;
2419 }
2420 xaPixelsize = -xa.fFA.fPointsize;
2421
2422 // Since most people used to use -adobe-* in their XLFDs,
2423 // preserve the preference for "adobe" foundry. Otherwise
2424 // some applications looks may change slightly if another foundry
2425 // is chosen.
2426
2427 if (xa.fFoundry && (strcasecmp(xa.fFoundry, "adobe") != 0)) {
2428 score += 3000;
2429 }
2430 if (!xa.fFA.fPointsize) {
2431
2432 // A scaleable font is almost always acceptable, but the
2433 // corresponding bitmapped font would be better.
2434
2435 score += 10;
2436 scaleable = 1;
2437 } else {
2438
2439 // A font that is too small is better than one that is too big.
2440
2441 if (xaPixelsize > pixelsize) {
2442 score += (xaPixelsize - pixelsize) * 120;
2443 } else {
2444 score += (pixelsize - xaPixelsize) * 100;
2445 }
2446 }
2447
2448 score += TMath::Abs(xa.fFA.fWeight - fa->fWeight) * 30;
2449 score += TMath::Abs(xa.fFA.fSlant - fa->fSlant) * 25;
2450
2451 if (xa.fSlant == kFontSlantOblique) {
2452
2453 // Italic fonts are preferred over oblique.
2454
2455 //score += 4;
2456 }
2457 if (xa.fSetwidth != kFontSWNormal) {
2458
2459 // The normal setwidth is highly preferred.
2460
2461 score += 2000;
2462 }
2463 if (xa.fCharset == kFontCSOther) {
2464
2465 // The standard character set is highly preferred over
2466 // foreign languages charsets (because we don't support
2467 // other languages yet).
2468
2469 score += 11000;
2470 }
2471 if ((xa.fCharset == kFontCSNormal) && (xa.fEncoding != 1)) {
2472
2473 // The '1' encoding for the characters above 0x7f is highly
2474 // preferred over the other encodings.
2475
2476 score += 8000;
2477 }
2478 if (scaleable) {
2479 if (score < bestScaleableScore) {
2480 bestScaleableIdx = i;
2482 }
2483 } else {
2484 if (score < bestScore) {
2485 bestIdx = i;
2486 bestScore = score;
2487 }
2488 }
2489 if (!score) {
2490 break;
2491 }
2492 }
2493
2494 // Now we know which is the closest matching scaleable font and the
2495 // closest matching bitmapped font. If the scaleable font was a
2496 // better match, try getting the scaleable font; however, if the
2497 // scalable font was not actually available in the desired pointsize,
2498 // fall back to the closest bitmapped font.
2499
2500 fontStruct = 0;
2501
2503 char *str, *rest;
2504
2505 // Fill in the desired pointsize info for this font.
2506
2507tryscale:
2509 for (i = 0; i < XLFD_PIXEL_SIZE - 1; i++) {
2510 str = strchr(str + 1, '-');
2511 }
2512 rest = str;
2513 for (i = XLFD_PIXEL_SIZE - 1; i < XLFD_REGISTRY; i++) {
2514 rest = strchr(rest + 1, '-');
2515 }
2516 *str = '\0';
2517 buf = TString::Format("%.240s-*-%d-*-*-*-*-*%s", nameList[bestScaleableIdx], pixelsize, rest);
2518 *str = '-';
2519 fontStruct = gVirtualX->LoadQueryFont(buf.Data());
2521 }
2522 if (!fontStruct) {
2523 buf = nameList[bestIdx];
2524 fontStruct = gVirtualX->LoadQueryFont(buf.Data());
2525
2526 if (!fontStruct) {
2527
2528 // This shouldn't happen because the font name is one of the
2529 // names that X gave us to use, but it does anyhow.
2530
2532 goto tryscale;
2533 } else {
2534 gVirtualX->FreeFontNames(nameList);
2535 goto getsystem;
2536 }
2537 }
2538 }
2539 gVirtualX->FreeFontNames(nameList);
2540
2541end:
2542 font = MakeFont(fontPtr, fontStruct, buf);
2543 font->fFA.fUnderline = fa->fUnderline;
2544 font->fFA.fOverstrike = fa->fOverstrike;
2545
2546 return font;
2547}
2548
2549////////////////////////////////////////////////////////////////////////////////
2550/// The return value is a pointer to an TGFont object that represents the
2551/// native font. If a native font by the given name could not be found,
2552/// the return value is NULL.
2553///
2554/// Every call to this procedure returns a new TGFont object, even if the
2555/// name has already been seen before. The caller should call FreeFont
2556/// when the font is no longer needed.
2557
2559{
2561 fixedDefault = fixedDefault && ((*name == '-') || (*name == '*'));
2563
2564 if (!fontStruct) {
2565 return 0;
2566 }
2567
2568 return MakeFont(0, fontStruct, name);
2569}
2570
2571////////////////////////////////////////////////////////////////////////////////
2572/// Helper for GetNativeFont() and GetFontFromAttributes(). Creates and
2573/// initializes a new TGFont object.
2574///
2575/// font -- If non-NULL, store the information in this existing TGFont
2576/// object, rather than creating a new one; the existing
2577/// contents of the font will be released. If NULL, a new
2578/// TGFont object is created.
2579/// fontStruct -- information about font.
2580/// fontName -- The string passed to TVirtualX::LoadQueryFont() to construct the
2581/// fontStruct.
2582
2584 const char *fontName)
2585{
2586 TGFont *newFont;
2587
2589 char *p;
2590 char buf[4];
2592
2593 if (font) {
2594 gVirtualX->FreeFontStruct(font->fFontStruct);
2595 newFont = font;
2596 } else {
2597 newFont = new TGFont(fontName);
2598 }
2599
2600 if (!ParseXLFD(fontName, &xa)) {
2601 newFont->fFA.fFamily = GetUid(fontName);
2602 } else {
2603 newFont->fFA = xa.fFA;
2604 }
2605
2606 if (newFont->fFA.fPointsize < 0) {
2607 double d;
2608 Int_t xx; Int_t yy; UInt_t ww; UInt_t hh;
2609 gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), xx, yy, ww, hh);
2610 d = -newFont->fFA.fPointsize * 72/25.4;
2611 d *= gVirtualX->ScreenWidthMM();
2612 d /= ww;
2613 d += 0.5;
2614 newFont->fFA.fPointsize = (int) d;
2615 }
2616
2617 Int_t ascent;
2618 Int_t descent;
2619 gVirtualX->GetFontProperties(fontStruct, ascent, descent);
2620
2621 newFont->fFM.fAscent = ascent;
2622 newFont->fFM.fDescent = descent;
2623 newFont->fFM.fLinespace = ascent + descent;
2624 newFont->fFM.fMaxWidth = gVirtualX->TextWidth(fontStruct, "@", 1);
2625 newFont->fFM.fFixed = kTRUE;
2626 newFont->fFontStruct = fontStruct;
2627 newFont->fFontH = gVirtualX->GetFontHandle(fontStruct);
2628
2629 // Classify the characters.
2630
2631 firstChar = 0x20; //fontStruct->min_char_or_byte2;
2632 lastChar = 0xff; //fontStruct->max_char_or_byte2;
2633
2634 for (i = 0; i < 256; i++) {
2635 if ((i == 160) || (i == 173) || (i == 177) ||
2636 (i < firstChar) || (i > lastChar)) {
2637 newFont->fTypes[i] = kCharReplace;
2638 } else {
2639 newFont->fTypes[i] = kCharNormal;
2640 }
2641 }
2642
2643 // Compute the widths for all the normal characters. Any other
2644 // characters are given an initial width of 0. Also, this determines
2645 // if this is a fixed or variable width font, by comparing the widths
2646 // of all the normal characters.
2647
2648 char ch[2] = {0, 0};
2649 width = 0;
2650 for (i = 0; i < 256; i++) {
2651 if (newFont->fTypes[i] != kCharNormal) {
2652 n = 0;
2653 } else {
2654 ch[0] = i;
2655 n = gVirtualX->TextWidth(fontStruct, ch, 1);
2656 }
2657 newFont->fWidths[i] = n;
2658 if (n) {
2659 if (!width) {
2660 width = n;
2661 } else if (width != n) {
2662 newFont->fFM.fFixed = kFALSE;
2663 }
2664 }
2665 }
2666
2667 // Compute the widths of the characters that should be replaced with
2668 // control character expansions. If the appropriate chars are not
2669 // available in this font, then control character expansions will not
2670 // be used; control chars will be invisible & zero-width.
2671
2672 replaceOK = kTRUE;
2673 for (p = gHexChars; *p != '\0'; p++) {
2674 if ((UChar_t(*p) < firstChar) || (UChar_t(*p) > lastChar)) {
2675 replaceOK = kFALSE;
2676 break;
2677 }
2678 }
2679 for (i = 0; i < 256; i++) {
2680 if (newFont->fTypes[i] == kCharReplace) {
2681 if (replaceOK) {
2682 n = GetControlCharSubst(i, buf);
2683 for (; --n >= 0;) {
2684 newFont->fWidths[i] += newFont->fWidths[UChar_t(buf[n])];
2685 }
2686 } else {
2687 newFont->fTypes[i] = kCharSkip;
2688 }
2689 }
2690 }
2691
2692 newFont->fUnderlinePos = descent >> 1;
2693 newFont->fBarHeight = newFont->fWidths[(int)'I']/3;
2694
2695 if (newFont->fBarHeight == 0) {
2696 newFont->fBarHeight = 1;
2697 }
2698
2699 if (newFont->fUnderlinePos + newFont->fBarHeight > descent) {
2700
2701 // If this set of cobbled together values would cause the bottom of
2702 // the underline bar to stick below the descent of the font, jack
2703 // the underline up a bit higher.
2704
2705 newFont->fBarHeight = descent - newFont->fUnderlinePos;
2706
2707 if (!newFont->fBarHeight) {
2708 newFont->fUnderlinePos--;
2709 newFont->fBarHeight = 1;
2710 }
2711 }
2712
2713 return newFont;
2714}
2715
2716////////////////////////////////////////////////////////////////////////////////
2717/// When displaying text in a widget, a backslashed escape sequence is
2718/// substituted for control characters that occur in the text. Given a
2719/// control character, fill in a buffer with the replacement string that
2720/// should be displayed.
2721///
2722/// The return value is the length of the substitute string, buf is
2723/// filled with the substitute string; it is not '\0' terminated.
2724///
2725/// c -- The control character to be replaced.
2726/// buf -- Buffer that gets replacement string. It only needs to be
2727/// 4 characters long.
2728
2729static Int_t GetControlCharSubst(Int_t c, char buf[4])
2730{
2731 buf[0] = '\\';
2732
2733 if (((UInt_t)c < sizeof(gMapChars)) && (gMapChars[c] != 0)) {
2734 buf[1] = gMapChars[c];
2735 return 2;
2736 } else {
2737 buf[1] = 'x';
2738 buf[2] = gHexChars[(c >> 4) & 0xf];
2739 buf[3] = gHexChars[c & 0xf];
2740 return 4;
2741 }
2742}
Handle_t FontH_t
Font handle (as opposed to Font_t which is an index)
Definition GuiTypes.h:35
Handle_t GContext_t
Graphics context handle.
Definition GuiTypes.h:38
Handle_t Drawable_t
Drawable handle.
Definition GuiTypes.h:31
Handle_t FontStruct_t
Pointer to font structure.
Definition GuiTypes.h:39
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Int_t kMaxInt
Definition RtypesCore.h:119
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
constexpr Int_t kFatal
Definition TError.h:50
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
#define MAX_LINES
#define XLFD_NUMFIELDS
Definition TGFont.cxx:90
#define FONT_FAMILY
Definition TGFont.cxx:65
#define FONT_WEIGHT
Definition TGFont.cxx:67
static const FontStateMap_t gWeightMap[]
Definition TGFont.cxx:195
static char * GetToken(char *str)
Definition TGFont.cxx:1893
#define XLFD_FOUNDRY
Definition TGFont.cxx:76
#define MAXUSE
static const FontStateMap_t gXlfdCharsetMap[]
Definition TGFont.cxx:246
ECharType
Definition TGFont.cxx:186
@ kCharReplace
Definition TGFont.cxx:186
@ kCharSkip
Definition TGFont.cxx:186
@ kCharNormal
Definition TGFont.cxx:186
#define XLFD_SETWIDTH
Definition TGFont.cxx:80
static const FontStateMap_t gUnderlineMap[]
Definition TGFont.cxx:207
EFontSpacing
Definition TGFont.cxx:158
@ kFontCharcell
Definition TGFont.cxx:161
@ kFontProportional
Definition TGFont.cxx:158
@ kFontMono
Definition TGFont.cxx:160
@ kFontFixed
Definition TGFont.cxx:159
EFontCharset
Definition TGFont.cxx:168
@ kFontCSSymbol
Definition TGFont.cxx:169
@ kFontCSNormal
Definition TGFont.cxx:168
@ kFontCSOther
Definition TGFont.cxx:170
#define XLFD_ENCODING
Definition TGFont.cxx:89
static char gMapChars[]
Definition TGFont.cxx:263
#define XLFD_PIXEL_SIZE
Definition TGFont.cxx:82
static const FontStateMap_t gOverstrikeMap[]
Definition TGFont.cxx:212
#define FONT_OVERSTRIKE
Definition TGFont.cxx:70
#define XLFD_POINT_SIZE
Definition TGFont.cxx:83
#define XLFD_REGISTRY
Definition TGFont.cxx:88
#define XLFD_SLANT
Definition TGFont.cxx:79
#define FONT_SIZE
Definition TGFont.cxx:66
#define XLFD_WEIGHT
Definition TGFont.cxx:78
#define XLFD_FAMILY
Definition TGFont.cxx:77
#define XLFD_ADD_STYLE
Definition TGFont.cxx:81
static int GetControlCharSubst(int c, char buf[4])
When displaying text in a widget, a backslashed escape sequence is substituted for control characters...
Definition TGFont.cxx:2729
static const FontStateMap_t gXlfdSlantMap[]
Definition TGFont.cxx:231
#define FONT_UNDERLINE
Definition TGFont.cxx:69
static const FontStateMap_t gSlantMap[]
Definition TGFont.cxx:201
static char gHexChars[]
Definition TGFont.cxx:256
#define FONT_NUMFIELDS
Definition TGFont.cxx:71
EFontSetWidth
Definition TGFont.cxx:163
@ kFontSWCondence
Definition TGFont.cxx:164
@ kFontSWExpand
Definition TGFont.cxx:165
@ kFontSWNormal
Definition TGFont.cxx:163
@ kFontSWUnknown
Definition TGFont.cxx:166
#define FONT_SLANT
Definition TGFont.cxx:68
static const FontStateMap_t gXlfdgWeightMap[]
Definition TGFont.cxx:220
static const FontStateMap_t gXlfdSetwidthMap[]
Definition TGFont.cxx:238
EFontWeight
Definition TGFont.h:34
@ kFontWeightBold
Definition TGFont.h:37
@ kFontWeightNormal
Definition TGFont.h:35
@ kFontWeightUnknown
Definition TGFont.h:41
EFontSlant
Definition TGFont.h:44
@ kFontSlantOblique
Definition TGFont.h:47
@ kFontSlantUnknown
Definition TGFont.h:48
@ kFontSlantRoman
Definition TGFont.h:45
@ kFontSlantItalic
Definition TGFont.h:46
@ kTextIgnoreTabs
Definition TGFont.h:30
@ kTextWholeWords
Definition TGFont.h:27
@ kTextPartialOK
Definition TGFont.h:29
@ kTextAtLeastOne
Definition TGFont.h:28
@ kTextIgnoreNewlines
Definition TGFont.h:31
@ kTextCenterX
Definition TGWidget.h:25
@ kTextRight
Definition TGWidget.h:24
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize fs
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void gc
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
#define gROOT
Definition TROOT.h:411
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
char * StrDup(const char *str)
Duplicate the string str.
Definition TString.cxx:2563
#define gVirtualX
Definition TVirtualX.h:337
#define snprintf
Definition civetweb.c:1579
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Window client.
Definition TGClient.h:37
FontStruct_t GetFontByName(const char *name, Bool_t fixedDefault=kTRUE) const
Get a font by name.
Definition TGClient.cxx:433
Bool_t ParseFontName(const char *string, FontAttributes_t *fa)
Converts a string into a set of font attributes that can be used to construct a font.
Definition TGFont.cxx:1955
TGFont * GetFont(const char *font, Bool_t fixedDefault=kTRUE)
Get the specified font.
Definition TGFont.cxx:1555
const char * NameOfFont(TGFont *font)
Given a font, return a textual string identifying it.
Definition TGFont.cxx:2255
THashTable * fList
Definition TGFont.h:220
char ** GetFontFamilies()
Return information about the font families that are available on the current display.
Definition TGFont.cxx:2267
TGFontPool(const TGFontPool &fp)=delete
Bool_t ParseXLFD(const char *string, XLFDAttributes_t *xa)
Break up a fully specified XLFD into a set of font attributes.
Definition TGFont.cxx:2047
int FindStateNum(const FontStateMap_t *map, const char *strKey)
Given a lookup table, map a string to a number in the table.
Definition TGFont.cxx:2198
TGFont * GetNativeFont(const char *name, Bool_t fixedDefault=kTRUE)
The return value is a pointer to an TGFont object that represents the native font.
Definition TGFont.cxx:2558
const char * GetUid(const char *string)
Given a string, this procedure returns a unique identifier for the string.
Definition TGFont.cxx:1782
Bool_t FieldSpecified(const char *field)
Helper function for ParseXLFD().
Definition TGFont.cxx:2240
THashTable * fUidTable
Definition TGFont.h:221
TGFont * FindFontByHandle(FontH_t font) const
Find font based on its font handle. Returns 0 if font is not found.
Definition TGFont.cxx:1758
THashTable * fNamedTable
Definition TGFont.h:222
void FreeFont(const TGFont *font)
Free font. If ref count is 0 delete font.
Definition TGFont.cxx:1715
char ** GetAttributeInfo(const FontAttributes_t *fa)
Return information about the font attributes as an array of strings.
Definition TGFont.cxx:1802
const char * FindStateString(const FontStateMap_t *map, int numKey)
Given a lookup table, map a number to a string in the table.
Definition TGFont.cxx:2221
void FreeFontFamilies(char **f)
Delete an array of families allocated GetFontFamilies() method.
Definition TGFont.cxx:2326
TGFont * GetFontFromAttributes(FontAttributes_t *fa, TGFont *fontPtr)
Given a desired set of attributes for a font, find a font with the closest matching attributes and cr...
Definition TGFont.cxx:2349
TGFont * MakeFont(TGFont *font, FontStruct_t fontStruct, const char *fontName)
Helper for GetNativeFont() and GetFontFromAttributes().
Definition TGFont.cxx:2583
~TGFontPool() override
Cleanup font pool.
Definition TGFont.cxx:1541
TGFont * FindFont(FontStruct_t font) const
Find font based on its font struct. Returns 0 if font is not found.
Definition TGFont.cxx:1741
void Print(Option_t *option="") const override
List all fonts in the pool.
Definition TGFont.cxx:1873
void FreeAttributeInfo(char **info)
Free attributes info.
Definition TGFont.cxx:1856
Encapsulate fonts used in the GUI system.
Definition TGFont.h:140
char fTypes[256]
Array giving types of all characters in the font, used when displaying control characters.
Definition TGFont.h:156
void GetFontMetrics(FontMetrics_t *m) const
Get font metrics.
Definition TGFont.cxx:283
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:614
friend class TGTextLayout
Definition TGFont.h:143
void DrawCharsExp(Drawable_t dst, GContext_t gc, const char *source, Int_t numChars, Int_t x, Int_t y) const
Draw a string of characters on the screen.
Definition TGFont.cxx:1460
Int_t fBarHeight
Height of underline or overstrike bar (used for simulating a native underlined or strikeout font).
Definition TGFont.h:159
TObjString * fNamedHash
Pointer to the named object TGFont was based on.
Definition TGFont.h:150
Int_t fWidths[256]
Array giving widths of all possible characters in the font.
Definition TGFont.h:158
static TClass * Class()
Int_t MeasureChars(const char *source, Int_t numChars, Int_t maxLength, Int_t flags, Int_t *length) const
Determine the number of characters from the string that will fit in the given horizontal span.
Definition TGFont.cxx:485
~TGFont() override
Delete font.
Definition TGFont.cxx:273
Int_t fTabWidth
Width of tabs in this font (pixels).
Definition TGFont.h:151
Int_t TextWidth(const char *string, Int_t numChars=-1) const
A wrapper function for the more complicated interface of MeasureChars.
Definition TGFont.cxx:572
Int_t fUnderlineHeight
Height of underline bar (used for drawing underlines on a non-underlined font).
Definition TGFont.h:154
FontStruct_t operator()() const
Not inline due to a bug in g++ 2.96 20000731 (Red Hat Linux 7.0)
Definition TGFont.cxx:297
FontAttributes_t fFA
Actual font attributes obtained when the font was created.
Definition TGFont.h:149
LayoutChunk_t * NewChunk(TGTextLayout *layout, int *maxPtr, const char *start, int numChars, int curX, int newX, int y) const
Helper function for ComputeTextLayout().
Definition TGFont.cxx:1407
FontMetrics_t fFM
Cached font metrics.
Definition TGFont.h:148
Int_t XTextWidth(const char *string, Int_t numChars=-1) const
Return text width in pixels.
Definition TGFont.cxx:587
void SavePrimitive(std::ostream &out, Option_t *="") override
Save the used font as a C++ statement(s) on output stream out.
Definition TGFont.cxx:1881
TGTextLayout * ComputeTextLayout(const char *string, Int_t numChars, Int_t wrapLength, Int_t justify, Int_t flags, UInt_t *width, UInt_t *height) const
Computes the amount of screen space needed to display a multi-line, justified string of text.
Definition TGFont.cxx:658
Int_t fUnderlinePos
Offset from baseline to origin of underline bar (used for drawing underlines on a non-underlined font...
Definition TGFont.h:152
Int_t PostscriptFontName(TString *dst) const
Return the name of the corresponding Postscript font for this TGFont.
Definition TGFont.cxx:340
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't overflow the X coordinate space.
Definition TGFont.cxx:1490
FontStruct_t fFontStruct
Low level graphics fontstruct.
Definition TGFont.h:146
void Print(Option_t *option="") const override
Print font info.
Definition TGFont.cxx:305
TGClient * fClient
Connection to display server.
Definition TGObject.h:25
Is used to keep track of string measurement information when using the text layout facilities.
Definition TGFont.h:106
void DrawText(Drawable_t dst, GContext_t gc, Int_t x, Int_t y, Int_t firstChar, Int_t lastChar) const
Use the information in the TGTextLayout object to display a multi-line, justified string of text.
Definition TGFont.cxx:920
Int_t PointToChar(Int_t x, Int_t y) const
Use the information in the TGTextLayout token to determine the character closest to the given point.
Definition TGFont.cxx:1000
Int_t IntersectText(Int_t x, Int_t y, Int_t w, Int_t h) const
Determines whether a text layout lies entirely inside, entirely outside, or overlaps a given rectangl...
Definition TGFont.cxx:1254
const TGFont * fFont
The font used when laying out the text.
Definition TGFont.h:111
void ToPostscript(TString *dst) const
Outputs the contents of a text layout in Postscript format.
Definition TGFont.cxx:1331
Int_t fNumChunks
Number of chunks actually used in following array.
Definition TGFont.h:114
Int_t DistanceToText(Int_t x, Int_t y) const
Computes the distance in pixels from the given point to the given text layout.
Definition TGFont.cxx:1188
Int_t CharBbox(Int_t index, Int_t *x, Int_t *y, Int_t *w, Int_t *h) const
Use the information in the TGTextLayout token to return the bounding box for the character specified ...
Definition TGFont.cxx:1106
LayoutChunk_t * fChunks
Array of chunks. The actual size will be maxChunks.
Definition TGFont.h:115
Int_t fWidth
The maximum width of all lines in the text layout.
Definition TGFont.h:113
void UnderlineChar(Drawable_t dst, GContext_t gc, Int_t x, Int_t y, Int_t underline) const
Use the information in the TGTextLayout object to display an underline below an individual character.
Definition TGFont.cxx:967
const char * fString
The string that was laid out.
Definition TGFont.h:112
~TGTextLayout() override
destructor
Definition TGFont.cxx:897
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
void Add(TObject *obj) override
Add object to the hash table.
TObject * Remove(TObject *obj) override
Remove object from the hashtable.
TObject * FindObject(const char *name) const override
Find object using its name.
void Print(Option_t *option, Int_t recurse) const override
Print the collection header and its elements.
FontAttributes_t fFA
Definition TGFont.cxx:154
Int_t fDeletePending
Definition TGFont.cxx:153
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TString fName
Definition TNamed.h:32
Collectable string class.
Definition TObjString.h:28
const char * GetName() const override
Returns name of object.
Definition TObjString.h:38
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:457
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
Definitions for TRefCnt, base class for reference counted objects.
Definition TRefCnt.h:27
UInt_t References() const
Definition TRefCnt.h:38
Basic string class.
Definition TString.h:138
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
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:2384
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Double_t Hypot(Double_t x, Double_t y)
Returns sqrt(x*x + y*y)
Definition TMath.cxx:59
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
const char * fFamily
Definition TGFont.h:63
Int_t fWeight
Definition TGFont.h:65
Int_t fPointsize
Definition TGFont.h:64
Int_t fUnderline
Definition TGFont.h:67
Int_t fOverstrike
Definition TGFont.h:68
Bool_t fFixed
Definition TGFont.h:57
Int_t fAscent
Definition TGFont.h:53
Int_t fDescent
Definition TGFont.h:54
const char * fStrKey
Definition TGFont.cxx:193
Int_t fDisplayWidth
Definition TGFont.cxx:119
Int_t fNumChars
Definition TGFont.cxx:105
Int_t fNumDisplayChars
Definition TGFont.cxx:106
Int_t fTotalWidth
Definition TGFont.cxx:116
const char * fStart
Definition TGFont.cxx:102
FontAttributes_t fFA
Definition TGFont.cxx:130
const char * fFoundry
Definition TGFont.cxx:131
TMarker m
Definition textangle.C:8