X11workbench Toolkit  1.0
font_helper.c
Go to the documentation of this file.
1 // __ _ _ _ //
3 // / _| ___ _ __ | |_ | |__ ___ | | _ __ ___ _ __ ___ //
4 // | |_ / _ \ | '_ \ | __| | '_ \ / _ \| || '_ \ / _ \| '__|/ __| //
5 // | _|| (_) || | | || |_ | | | || __/| || |_) || __/| | _| (__ //
6 // |_| \___/ |_| |_| \__|_____|_| |_| \___||_|| .__/ \___||_|(_)\___| //
7 // |_____| |_| //
8 // basic font enumeration and selection //
9 // //
11 
12 /*****************************************************************************
13 
14  X11workbench - X11 programmer's 'work bench' application and toolkit
15  Copyright (c) 2010-2019 by Bob Frazier (aka 'Big Bad Bombastic Bob')
16 
17 
18  DISCLAIMER: The X11workbench application and toolkit software are supplied
19  'as-is', with no warranties, either implied or explicit.
20  Any claims to alleged functionality or features should be
21  considered 'preliminary', and might not function as advertised.
22 
23  MIT-like license:
24 
25  There is no restriction as to what you can do with this software, so long
26  as you include the above copyright notice and DISCLAIMER for any distributed
27  work that is equal to or derived from this one, along with this paragraph
28  that explains the terms of the license if the source is also being made
29  available. A "derived work" describes a work that uses a significant portion
30  of the source files or algorithms that are included with this one.
31  Specifically excluded from this are files that were generated by the software,
32  or anything that is included with the software that is part of another package
33  (such as files that were created or added during the 'configure' process).
34  Specifically included is the use of part or all of any of the X11 workbench
35  toolkit source or header files in your distributed application. If you do not
36  ship the source, the above copyright statement is still required to be placed
37  in a reasonably prominent place, such as documentation, splash screens, and/or
38  'about the application' dialog boxes.
39 
40  Use and distribution are in accordance with GPL, LGPL, and/or the above
41  MIT-like license. See COPYING and README files for more information.
42 
43 
44  Additional information at http://sourceforge.net/projects/X11workbench
45 
46 ******************************************************************************/
47 
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <unistd.h>
59 #include <memory.h>
60 #include <string.h>
61 #include <strings.h>
62 #include <signal.h>
63 #include <time.h>
64 #include <X11/cursorfont.h>
65 
66 //#include <locale.h>
67 
68 #include "window_helper.h" // for debug output; also includes platform.h and font_helper.h
69 #include "draw_text.h"
70 
71 #define FONT_DUMP_DEBUG_LEVEL DebugLevel_Heavy
72 
73 
74 // globals
75 
76 static int bDisableAntiAlias = 0;
77 static int bEnableTrueTypeFonts = 0;
78 
79 // libXft aka Freetype -
80 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
81 FT_Library __ftlib = NULL; /* located in font_helper.c */
82 static int bInitFtLibOnce = 0;
83 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
84 
85 
86 void __internal_disable_antialias(void)
87 {
88  bDisableAntiAlias = 1;
89 }
90 
91 void __internal_enable_antialias(void)
92 {
93  bDisableAntiAlias = 0;
94 }
95 
97 {
98 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
99 
100  // see https://www.freedesktop.org/wiki/Software/Xft/
101  // and https://cgit.freedesktop.org/xorg/lib/libXft/
102  // this software requires libXft2 and is not compatible
103  // with any earlier version...
104 
105 #if XFT_VERSION < 20000
106 #warning - You need libXft version 2 or greater - true type fonts disabled
107  bInitFtLibOnce = 0;
108  bEnableTrueTypeFonts = 0;
109 #else
110 
111  if(!bInitFtLibOnce)
112  {
113  // this must only be called once...
114  if(XftInit(0) == FcTrue && XftInitFtLibrary() == FcTrue )
115  {
116  bInitFtLibOnce = 1;
117 
118  if(XftDefaultHasRender(WBGetDefaultDisplay()))
119  {
120  bEnableTrueTypeFonts = 1;
121  }
122  else
123  {
124  WB_ERROR_PRINT("Unable to render true type fonts, disabled\n");
125  }
126 
127 // __ftlib = _XftFTlibrary; // the libXft cached value (this does not actually work)
128  if(FT_Init_FreeType(&__ftlib))
129  {
130  __ftlib = NULL;
131  WB_WARN_PRINT("Unable to get own copy of FreeType library, disabled\n");
132  }
133  }
134  else
135  {
136  WB_ERROR_PRINT("Unable to initialize libXft - truetype fonts not enabled\n");
137  }
138  }
139 #endif // XFT_VERSION < 20000
140 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
141 
142  // TODO: other global initialization things for font_helper
143 }
144 
146 {
147 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
148  if(bInitFtLibOnce)
149  {
150  // TODO: any uninitialization goes here. for now there is none.
151 
152  bInitFtLibOnce = 0;
153  }
154 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
155 }
156 
158 {
159  return !bDisableAntiAlias; // for now, just do this
160 }
161 
162 void WBFontSetEnableAntiAlias(int bEnable)
163 {
164  bDisableAntiAlias = bEnable ? 1 : 0;
165 }
166 
167 
168 WB_FONT WBCopyFont(Display *pDisplay, WB_FONTC pOldFont)
169 {
170 WB_FONT pRval;
171 
172  if(!pDisplay)
173  {
174  pDisplay = WBGetDefaultDisplay();
175  }
176 
177  if(!pOldFont)
178  {
179  pOldFont = WBGetDefaultFont();
180 
181  if(!pOldFont)
182  {
183  WB_WARN_PRINT("%s returns NULL (WBGetDefaultFont returns NULL)\n", __FUNCTION__);
184 
185  return NULL;
186  }
187  }
188 
189  pRval = (WB_FONT)WBAlloc(sizeof(*pRval));
190  if(pRval)
191  {
192  memset(pRval, 0, sizeof(*pRval));
193 
194  pRval->pDisplay = pDisplay;
195  pRval->iAscent = pRval->iDescent = pRval->iHeight = pRval->iAvgCharWidth = pRval->iMaxCharWidth = -1;
196 
197 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
198  if(pOldFont->pxftFont)
199  {
200  pRval->pxftFont = XftFontCopy(pDisplay, pOldFont->pxftFont);
201  if(!pRval->pxftFont)
202  {
203  goto bad_font;
204  }
205 // pRval->pxftFontInfo = copy something from old one
206  }
207  else
208 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
209  {
210  if(pOldFont->fsFont != None)
211  {
212  pRval->fsFont = WBCopyModifyFontSet(pDisplay, pOldFont->fsFont, 0, 0);
213 
214  if(pRval->fsFont == None)
215  {
216  WB_WARN_PRINT("%s returns NULL (unable to copy font set)\n", __FUNCTION__);
217 
218  goto bad_font;
219  }
220  }
221  /*else*/ if(pOldFont->pFontStruct)
222  {
223  pRval->pFontStruct = WBCopyFontX(pOldFont->pFontStruct);
224  if(!pRval->pFontStruct)
225  {
226  WB_WARN_PRINT("%s returns NULL (unable to copy font struct)\n", __FUNCTION__);
227 
228  goto bad_font;
229  }
230  }
231 
232  if(!pOldFont->pFontStruct && pOldFont->fsFont == None)
233  {
234  WB_WARN_PRINT("%s returns NULL (bad font)\n", __FUNCTION__);
235 bad_font:
236  WBFreeFont(pDisplay, pRval);
237 
238  return NULL;
239  }
240  }
241  }
242  else
243  {
244  WB_WARN_PRINT("%s returns NULL (no memory for structure)\n", __FUNCTION__);
245  }
246 
247  return pRval;
248 }
249 
250 void WBFreeFont(Display *pDisplay, WB_FONT pFont)
251 {
252  if(!pDisplay)
253  {
254  pDisplay = WBGetDefaultDisplay();
255  }
256 
257  if(pFont)
258  {
259 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
260  if(pFont->pxftFont)
261  {
262  XftFontClose(pDisplay, pFont->pxftFont);
263  pFont->pxftFont = NULL;
264  }
265  if(pFont->pxftFontInfo != None)
266  {
267  XftFontInfoDestroy(pDisplay, pFont->pxftFontInfo);
268  pFont->pxftFontInfo = NULL;
269  }
270 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
271 
272  if(pFont->fsFont != None)
273  {
274  XFreeFontSet(pDisplay, pFont->fsFont);
275  pFont->fsFont = None;
276  }
277 
278  if(pFont->pFontStruct)
279  {
280  XFreeFont(pDisplay, pFont->pFontStruct);
281  // TODO: should I call XUnloadFont at all? how about XFreeFontInfo ?
282 
283  pFont->pFontStruct = NULL; // help eliminate potential re-use in possible buggy code
284  }
285 
286  WBFree(pFont);
287  }
288 }
289 
290 
291 WB_FONT WBLoadFont(Display *pDisplay, const char *szFontName,
292  int iFontSize, int iFlags)
293 {
294 WB_FONT pRval;
295 
296  if(!pDisplay)
297  {
298  pDisplay = WBGetDefaultDisplay();
299  }
300 
301  pRval = (WB_FONT)WBAlloc(sizeof(*pRval));
302  if(pRval)
303  {
304  memset(pRval, 0, sizeof(*pRval));
305 
306  pRval->pDisplay = pDisplay; // cache it
307  pRval->iAscent = pRval->iDescent = pRval->iHeight = pRval->iAvgCharWidth = pRval->iMaxCharWidth = -1;
308 
309 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
310 
311 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
312 
313 // if(!pRval->pxftFont)
314 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
315  {
316  pRval->pFontStruct = WBLoadFontX(pDisplay, szFontName, iFontSize, iFlags);
317 
318  if(!pRval->pFontStruct)
319  {
320 //bad_font:
321  WBFree(pRval);
322 
323  WB_WARN_PRINT("%s returns NULL (WBLoadFontXl returns NULL)\n", __FUNCTION__);
324 
325  pRval = NULL;
326  }
327  else
328  {
329  pRval->fsFont = WBFontSetFromFont(pDisplay, pRval->pFontStruct);
330 
331  // TODO: check for error?
332  }
333  }
334  }
335  else
336  {
337  WB_WARN_PRINT("%s returns NULL (no memory for structure)\n", __FUNCTION__);
338  }
339 
340  return pRval;
341 }
342 
344 {
345 int iRval = 0;
346 Display *pDisplay;
347 WB_FONT pFont = (WB_FONT)pFont0;
348 
349 
350  if(!pFont || !pFont->pDisplay)
351  {
352  WB_WARN_PRINT("%s returns zero (bad param, %p, %p)\n",
353  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
354 
355  return 0;
356  }
357 
358  pDisplay = pFont->pDisplay;
359 
360  if(pFont->iAvgCharWidth >= 0)
361  {
362  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
363  "%s returns (cached) font avg char width %d\n", __FUNCTION__, pFont->iAvgCharWidth);
364  return pFont->iAvgCharWidth;
365  }
366 
367 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
368  if(pFont->pxftFont)
369  {
370  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
371 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
372  }
373  else
374 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
375  {
376  if(pFont->fsFont)
377  {
378  iRval = WBFontSetAvgCharWidth(pDisplay, pFont->fsFont);
379  }
380  else if(pFont->pFontStruct)
381  {
382  iRval = WBFontAvgCharWidthX(pDisplay, pFont->pFontStruct);
383  }
384 
385  pFont->iAvgCharWidth = iRval;
386  }
387 
388  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
389  "%s returns font avg char width %d\n", __FUNCTION__, iRval);
390 
391  return iRval;
392 }
393 
395 {
396 int iRval = 0;
397 Display *pDisplay;
398 WB_FONT pFont = (WB_FONT)pFont0;
399 
400 
401  if(!pFont || !pFont->pDisplay)
402  {
403  WB_WARN_PRINT("%s returns zero (bad param, %p, %p)\n",
404  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
405 
406  return 0;
407  }
408 
409  pDisplay = pFont->pDisplay;
410 
411  if(pFont->iMaxCharWidth >= 0)
412  {
413  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
414  "%s returns (cached) font max char width %d\n", __FUNCTION__, pFont->iMaxCharWidth);
415  return pFont->iMaxCharWidth;
416  }
417 
418 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
419  if(pFont->pxftFont)
420  {
421  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
422 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
423  }
424  else
425 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
426  {
427  XCharStruct xc = WBFontMaxBounds(pFont);
428 
429  iRval = xc.width;
430 
431  if(iRval > 0) // values > 0 assume it's right
432  {
433  pFont->iAvgCharWidth = iRval;
434  }
435  }
436 
437  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
438  "%s returns font max char width %d\n", __FUNCTION__, iRval);
439 
440  return iRval;
441 }
442 
444 {
445 int iRval = 0;
446 Display *pDisplay;
447 WB_FONT pFont = (WB_FONT)pFont0;
448 
449 
450  if(!pFont || !pFont->pDisplay)
451  {
452  WB_WARN_PRINT("%s returns zero (bad param, %p, %p)\n",
453  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
454 
455  return 0;
456  }
457 
458  pDisplay = pFont->pDisplay;
459 
460  if(pFont->iDescent >= 0)
461  {
462  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
463  "%s returns (cached) font descent %d\n", __FUNCTION__, pFont->iDescent);
464  return pFont->iDescent;
465  }
466 
467 
468 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
469  if(pFont->pxftFont)
470  {
471  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
472 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
473  }
474  else
475 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
476  {
477  if(pFont->fsFont)
478  {
479  iRval = WBFontSetDescent(pDisplay, pFont->fsFont);
480  }
481  else if(pFont->pFontStruct)
482  {
483  iRval = pFont->pFontStruct->descent;
484  }
485 
486  pFont->iDescent = iRval; // cached for next time
487  }
488 
489  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
490  "%s returns font descent %d\n", __FUNCTION__, iRval);
491 
492  return iRval;
493 }
494 
496 {
497 int iRval = 0;
498 Display *pDisplay;
499 WB_FONT pFont = (WB_FONT)pFont0;
500 
501 
502  if(!pFont || !pFont->pDisplay)
503  {
504  WB_WARN_PRINT("%s returns zero (bad param, %p, %p)\n",
505  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
506 
507  return 0;
508  }
509 
510  pDisplay = pFont->pDisplay;
511 
512  if(pFont->iAscent >= 0)
513  {
514  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
515  "%s returns (cached) font ascent %d\n", __FUNCTION__, pFont->iAscent);
516  return pFont->iAscent;
517  }
518 
519 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
520  if(pFont->pxftFont)
521  {
522  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
523 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
524  }
525  else
526 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
527  {
528  if(pFont->fsFont)
529  {
530  iRval = WBFontSetAscent(pDisplay, pFont->fsFont);
531  }
532  else if(pFont->pFontStruct)
533  {
534  iRval = pFont->pFontStruct->ascent;
535  }
536 
537  pFont->iAscent = iRval; // cached for next time
538  }
539 
540  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
541  "%s returns font ascent %d\n", __FUNCTION__, iRval);
542 
543  return iRval;
544 }
545 
547 {
548 int iRval = 0;
549 Display *pDisplay;
550 WB_FONT pFont = (WB_FONT)pFont0;
551 
552 
553  if(!pFont || !pFont->pDisplay)
554  {
555  WB_WARN_PRINT("%s returns zero (bad param, %p, %p)\n",
556  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
557 
558  return 0;
559  }
560 
561  pDisplay = pFont->pDisplay;
562 
563  if(pFont->iHeight >= 0)
564  {
565  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
566  "%s returns (cached) font height %d\n", __FUNCTION__, pFont->iHeight);
567  return pFont->iHeight;
568  }
569 
570 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
571  if(pFont->pxftFont)
572  {
573  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
574 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
575  }
576  else
577 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
578  {
579 #warning review that this is the right way to handle this, or if there is a better way
580 
581  iRval = WBFontAscent(pFont0) + WBFontDescent(pFont0);
582 
583  pFont->iHeight = iRval; // cached for next time
584  }
585 
586  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
587  "%s returns font height %d\n", __FUNCTION__, iRval);
588 
589  return iRval;
590 }
591 
592 XCharStruct WBFontMaxBounds(WB_FONTC pFont0)
593 {
594 XCharStruct rVal;
595 Display *pDisplay;
596 WB_FONT pFont = (WB_FONT)pFont0;
597 
598 
599  memset(&rVal, 0, sizeof(rVal));
600 
601  if(!pFont || !pFont->pDisplay)
602  {
603  WB_WARN_PRINT("%s returns 'zero' struct (bad param, %p, %p)\n",
604  __FUNCTION__, pFont, (void *)(pFont ? pFont->pDisplay : NULL));
605 
606  return rVal; // return the zero'd structure if this happens
607  }
608 
609  pDisplay = pFont->pDisplay;
610 
611  if(pFont->max_bounds.lbearing != 0 ||
612  pFont->max_bounds.rbearing != 0 ||
613  pFont->max_bounds.width != 0 ||
614  pFont->max_bounds.ascent != 0 ||
615  pFont->max_bounds.descent != 0)
616  {
617  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
618  "%s returns (cached) font extent %d %d %d %d %d\n",
619  __FUNCTION__,
620  pFont->max_bounds.lbearing, pFont->max_bounds.rbearing,
621  pFont->max_bounds.width, pFont->max_bounds.ascent, pFont->max_bounds.descent);
622 
623  return pFont->max_bounds;
624  }
625 
626 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
627  if(pFont->pxftFont)
628  {
629  WB_ERROR_PRINT("ERROR: %s font has 'pfxftFont' non-NULL\n", __FUNCTION__);
630 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
631  }
632  else
633 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
634  {
635  if(pFont->fsFont)
636  {
637  rVal = WBFontSetMaxBounds(pDisplay, pFont->fsFont);
638  }
639  else if(pFont->pFontStruct)
640  {
641  rVal.lbearing = pFont->pFontStruct->max_bounds.lbearing;
642  rVal.rbearing = pFont->pFontStruct->max_bounds.rbearing;
643  rVal.width = pFont->pFontStruct->max_bounds.width;
644  rVal.ascent = pFont->pFontStruct->max_bounds.ascent;
645  rVal.descent = pFont->pFontStruct->max_bounds.descent;
646 
647  memcpy(&rVal, &(pFont->pFontStruct->max_bounds), sizeof(rVal));
648  }
649 
650  memcpy(&(pFont->max_bounds), &rVal, sizeof(pFont->max_bounds));
651  }
652 
653  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
654  "%s returns font extent %d %d %d %d %d\n",
655  __FUNCTION__, rVal.lbearing, rVal.rbearing, rVal.width, rVal.ascent, rVal.descent);
656 
657  return rVal;
658 }
659 
660 WB_FONT WBCopyModifyFont(Display *pDisplay, WB_FONTC pOriginal,
661  int iFontSize, int iFlags)
662 {
663 WB_FONT pRval = NULL;
664 
665 
666  if(!iFontSize && !iFlags)
667  {
668  return WBCopyFont(pDisplay, pOriginal);
669  }
670 
671  if(!pDisplay)
672  {
673  pDisplay = WBGetDefaultDisplay();
674  }
675 
676  if(!pOriginal)
677  {
678  pOriginal = WBGetDefaultFont();
679 
680  if(!pOriginal)
681  {
682  WB_WARN_PRINT("%s returns NULL (pOriginal is NULL)\n", __FUNCTION__);
683 
684  return NULL;
685  }
686  }
687 
688  pRval = (WB_FONT)WBAlloc(sizeof(*pRval));
689  if(pRval)
690  {
691  memset(pRval, 0, sizeof(*pRval));
692 
693  pRval->pDisplay = pDisplay;
694  pRval->iAscent = pRval->iDescent = pRval->iHeight = pRval->iAvgCharWidth = pRval->iMaxCharWidth = -1;
695 
696 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
697 
698 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
699 
700 // if(!pRval->pxftFont)
701 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
702  {
703  if(pOriginal->fsFont)
704  {
705  pRval->fsFont = WBCopyModifyFontSet(pDisplay, pOriginal->fsFont, iFontSize, iFlags);
706 
707  if(pRval->fsFont == None)
708  {
709  WB_WARN_PRINT("%s returns NULL (unable to copy font set)\n", __FUNCTION__);
710 
711  goto bad_font;
712  }
713  }
714  /* else */ if(pOriginal->pFontStruct)
715  {
716  pRval->pFontStruct = WBLoadModifyFontX(pDisplay, pOriginal->pFontStruct, iFontSize, iFlags);
717 
718  // for now I make a copy of both of these when present
719  // so only if both are NULL do I warn...
720  if(pRval->fsFont == None && !pRval->pFontStruct)
721  {
722  WB_WARN_PRINT("%s returns NULL (unable to copy font struct)\n", __FUNCTION__);
723 
724  goto bad_font;
725  }
726  }
727 
728  if(!pOriginal->pFontStruct && pOriginal->fsFont == None)
729  {
730  WB_WARN_PRINT("%s returns NULL (bad font)\n", __FUNCTION__);
731 bad_font:
732  WBFreeFont(pDisplay, pRval);
733 
734  return NULL;
735  }
736  }
737  }
738  else
739  {
740  WB_WARN_PRINT("%s returns NULL (not enough memory for structure)\n", __FUNCTION__);
741  }
742 
743  return pRval;
744 }
745 
746 
747 int WBTextWidth(WB_FONTC pFont, const char *szText, int cbText)
748 {
749 int iLen, iRval = 0;
750 
751 
752  if(!pFont || !cbText || !szText || (cbText < 0 && !*szText))
753  {
754  WB_ERROR_PRINT("TEMPORARY: %s - returning zero (bad parameter %p %p %d)\n",
755  __FUNCTION__, pFont, szText, cbText);
756  return 0;
757  }
758  else if(cbText < 0)
759  {
760  iLen = strlen(szText);
761  }
762  else
763  {
764  iLen = cbText;
765  }
766 
767 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
768  if(pFont->pxftFont)
769  {
770  WB_ERROR_PRINT("ERROR: %s font initialization has 'pfxftFont' non-NULL\n", __FUNCTION__);
771 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
772  }
773  else
774 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
775  if(pFont->fsFont != None)
776  {
777  iRval = WB_TEXT_ESCAPEMENT(pFont->fsFont, szText, iLen);
778  }
779  else if(pFont->pFontStruct)
780  {
781  iRval = XTextWidth(pFont->pFontStruct, szText, iLen);
782  }
783 
784  WB_DEBUG_PRINT(DebugLevel_Heavy | DebugSubSystem_Font,
785  "%s returns text width %d for \"%-.*s\"\n", __FUNCTION__, iRval, iLen, szText);
786 
787  return iRval;
788 }
789 
790 void WBTextExtent(WB_FONTC pFont, const char *szText, int cbText, WB_EXTENT *pExtent)
791 {
792 int iLen;
793 
794 
795  if(!pFont || !cbText || !szText || (cbText < 0 && !*szText))
796  {
797  WB_ERROR_PRINT("TEMPORARY: %s - returning zero (bad parameter %p %p %d)\n",
798  __FUNCTION__, pFont, szText, cbText);
799  return;
800  }
801  else if(cbText < 0)
802  {
803  iLen = strlen(szText);
804  }
805  else
806  {
807  iLen = cbText;
808  }
809 
810 
811 #ifdef X11WORKBENCH_TOOLKIT_HAVE_XFT
812  if(pFont->pxftFont)
813  {
814  WB_ERROR_PRINT("ERROR: %s font initialization has 'pfxftFont' non-NULL\n", __FUNCTION__);
815 #warning TODO: IMPLEMENT THIS PART for Xft FONTS
816  }
817  else
818 #endif // X11WORKBENCH_TOOLKIT_HAVE_XFT
819  if(pFont->fsFont != None)
820  {
821  XRectangle rct, rct2;
822 
823  memset(&rct2, 0, sizeof(rct2));
824 
826  WB_TEXT_EXTENTS(pFont->fsFont, szText, iLen, &rct, &rct2);
828 
829  pExtent->width = rct2.width;
830  pExtent->height = rct2.height;
831  }
832  else if(pFont->pFontStruct)
833  {
834  int iDir, iAsc, iDesc;
835  XCharStruct cs;
836 
837  memset(&cs, 0, sizeof(cs));
838 
840  XTextExtents(pFont->pFontStruct, szText, iLen, &iDir, &iAsc, &iDesc, &cs);
842 
843  pExtent->width = cs.width;
844  pExtent->height = cs.ascent + cs.descent;
845  }
846 }
847 
848 
849 
850 
int iMaxCharWidth
RESERVED - cached max character width (-1 if not valid). do not access this directly.
Definition: font_helper.h:160
'window helper' main header file for the X11workbench Toolkit API
void WBFontSetEnableAntiAlias(int bEnable)
returns non-zero value if certain fonts should be anti-aliased when rendered
Definition: font_helper.c:162
void WBFreeFont(Display *pDisplay, WB_FONT pFont)
free a WB_FONT that was created using one of the WBFont APIs
Definition: font_helper.c:250
void __internal_font_helper_exit(void)
un-initialization for font helper - call once at end of program (WBExit() does this for you)
Definition: font_helper.c:145
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
Definition: debug_helper.h:364
unsigned int width
the 'width' value of the extent.
int WBFontHeight(WB_FONTC pFont0)
Get the maximum character height from a WB_FONT.
Definition: font_helper.c:546
int WBFontAscent(WB_FONTC pFont0)
Get the maximum character ascent from a WB_FONT.
Definition: font_helper.c:495
Utilities for copying and drawing text, determining text extents, and so on.
XFontStruct * WBLoadModifyFontX(Display *pDisplay, const XFontStruct *pOriginal, int iFontSize, int iFlags)
load and modify a font according to the specified size and flags
Definition: font_legacy.c:1269
int WBFontAvgCharWidth(WB_FONTC pFont0)
Get the average character width for a font.
Definition: font_helper.c:343
WB_FONT WBCopyFont(Display *pDisplay, WB_FONTC pOldFont)
make a copy of an existing font (best when assigning to a window)
Definition: font_helper.c:168
XFontSet WBFontSetFromFont(Display *pDisplay, const XFontStruct *pFont)
Creates an 'XFontSet' from an XFontStruct for a given display.
Definition: font_legacy.c:1579
WB_FONT WBCopyModifyFont(Display *pDisplay, WB_FONTC pOriginal, int iFontSize, int iFlags)
load and modify a font according to the specified size and flags
Definition: font_helper.c:660
#define WB_TEXT_ESCAPEMENT
Definition: font_helper.h:100
int iDescent
RESERVED - cached font descent (-1 if not valid). do not access this directly.
Definition: font_helper.h:157
int WBFontSetAvgCharWidth(Display *pDisplay, XFontSet fontSet)
Get the average character width for a font set.
Definition: font_legacy.c:1146
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
struct WBFont * WB_FONT
An allocated structure containing XFontStruct, XFontInfo, and XftFont [as applicable] for a specified...
WB_FONT WBLoadFont(Display *pDisplay, const char *szFontName, int iFontSize, int iFlags)
load a WB_FONT font object based on a font name, size, and font flags
Definition: font_helper.c:291
int WBFontAvgCharWidthX(Display *pDisplay, const XFontStruct *pFont)
Get the average character width for a font.
Definition: font_legacy.c:912
Display * pDisplay
The Display pointer associated with this font (to be used internally)
Definition: font_helper.h:162
int WBFontEnableAntiAlias(void)
returns non-zero value if certain fonts should be anti-aliased when rendered
Definition: font_helper.c:157
XFontStruct * WBCopyFontX(XFontStruct *pOldFont)
make a copy of an existing font (best when assigning to a window)
Definition: font_legacy.c:106
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
#define END_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro follows the call(s)
XCharStruct max_bounds
RESERVED - cached max bounds (all 0's if not valid). do not access this directly.
Definition: font_helper.h:161
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
Definition: debug_helper.h:474
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
XCharStruct WBFontMaxBounds(WB_FONTC pFont0)
Get a 'maximized' copy of 'max_bounds' (applicable to all font faces in the WB_FONT)
Definition: font_helper.c:592
int WBFontSetDescent(Display *pDisplay, XFontSet fontSet)
Get the maximum character descent from a font set.
Definition: font_legacy.c:1013
XFontSet fsFont
legacy 'XFontSet' for X11 raster fonts (UTF-8)
Definition: font_helper.h:168
int iAvgCharWidth
RESERVED - cached average character width (-1 if not valid). do not access this directly.
Definition: font_helper.h:159
internal wrapper struct for 'extent' definition
XFontStruct * pFontStruct
legacy 'XFontStruct' for X11 raster fonts
Definition: font_helper.h:167
int WBFontDescent(WB_FONTC pFont0)
Get the maximum character descent from a WB_FONT.
Definition: font_helper.c:443
int WBTextWidth(WB_FONTC pFont, const char *szText, int cbText)
Obtain the pixel width of specified text for a specified WB_FONT.
Definition: font_helper.c:747
XFontSet WBCopyModifyFontSet(Display *pDisplay, XFontSet fsOrig, int iFontSize, int iFlags)
copy and modify a font set according to the specified size and flags
Definition: font_legacy.c:1359
int WBFontMaxCharWidth(WB_FONTC pFont0)
Get the maximum character width for a font.
Definition: font_helper.c:394
int iAscent
RESERVED - cached font ascent (-1 if not valid). do not access this directly.
Definition: font_helper.h:156
void __internal_font_helper_init(void)
initialization for font helper - call once at start of program (WBInit() does this for you)
Definition: font_helper.c:96
#define BEGIN_XCALL_DEBUG_WRAPPER
wrapper macro for calls into the X11 library. This macro precedes the call(s)
#define WB_TEXT_EXTENTS
Definition: font_helper.h:99
An allocated structure containing XFontStruct, XFontInfo, and XftFont [as applicable] for a specified...
Definition: font_helper.h:152
unsigned int height
the 'height' value of the extent.
void WBTextExtent(WB_FONTC pFont, const char *szText, int cbText, WB_EXTENT *pExtent)
Obtain the pixel extent of specified text for a specified XFontSet.
Definition: font_helper.c:790
XCharStruct WBFontSetMaxBounds(Display *pDisplay, XFontSet fontSet)
Get a 'maximized' copy of the 'max_bounds' member for the font set.
Definition: font_legacy.c:1206
int WBFontSetAscent(Display *pDisplay, XFontSet fontSet)
Get the maximum character ascent from a font set.
Definition: font_legacy.c:1055
#define WB_WARN_PRINT(...)
Preferred method of implementing a 'warning level' debug message for all subsystems.
Definition: debug_helper.h:467
int iFlags
various bit flags
Definition: file_help.h:170
XFontStruct * WBLoadFontX(Display *pDisplay, const char *szFontName, int iFontSize, int iFlags)
load a font based on a font name, size, and font flags
Definition: font_legacy.c:772
int iHeight
RESERVED - cached font height (-1 if not valid). do not access this directly.
Definition: font_helper.h:158
WB_FONTC WBGetDefaultFont(void)
Returns a pointer to the default font WB_FONT for the default display. This is a shared resource; do ...