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