1 module gui.font; 2 3 import deimos.X11.X; 4 import deimos.X11.Xlib; 5 import deimos.X11.Xutil; 6 import std.c.stdlib; 7 import std..string; 8 import std.algorithm; 9 10 import cboxapp; 11 import types; 12 13 /** 14 * Font object to encapsulate the X font. 15 */ 16 struct Fnt 17 { 18 int ascent; /// Ascent of the font 19 int descent;/// Descent of the font 20 uint h; /// Height of the font. This equates to ascent + descent. 21 XFontSet set; // Font set to use 22 XFontStruct *xfont; /// The X font we're covering. 23 Display* dpy; 24 25 /** 26 * Ctor. Creates a Fnt object wrapping the specified font for a given display. 27 * Params: 28 * dpy= X display 29 * fontname= Name of the font to wrap (X font name) 30 * Example: 31 * --- 32 * auto f = Fnt(display, "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"); 33 * --- 34 */ 35 this(Display *dpy, in string fontname) 36 { 37 if(AppDisplay.instance().dpy is null) { 38 exit(EXIT_FAILURE); 39 } 40 41 this,dpy = dpy; 42 char *def; 43 char **missing; 44 int n; 45 46 this.set = XCreateFontSet(AppDisplay.instance().dpy, cast(char*)fontname.toStringz, &missing, &n, &def); 47 48 if(missing) { 49 while(n--) { 50 //lout("drw: missing fontset: %s", missing[n].fromStringz); 51 } 52 XFreeStringList(missing); 53 } 54 55 if(this.set) { 56 XFontStruct **xfonts; 57 char **font_names; 58 XExtentsOfFontSet(this.set); 59 n = XFontsOfFontSet(this.set, &xfonts, &font_names); 60 while(n--) { 61 this.ascent = max(this.ascent, (*xfonts).ascent); 62 this.descent = max(this.descent,(*xfonts).descent); 63 xfonts++; 64 } 65 } 66 67 else { 68 this.xfont = XLoadQueryFont(AppDisplay.instance().dpy, cast(char*)(fontname.toStringz)); 69 if(this.xfont is null) { 70 this.xfont = XLoadQueryFont(AppDisplay.instance().dpy, cast(char*)("fixed".toStringz)); 71 if(this.xfont is null) { 72 //lout("error, cannot load font: %s", fontname); 73 exit(EXIT_FAILURE); 74 } 75 } 76 this.ascent = this.xfont.ascent; 77 this.descent = this.xfont.descent; 78 } 79 80 this.h = this.ascent + this.descent; 81 } 82 83 /** 84 * Destroy the X resources for this font. 85 */ 86 private void destroy(Display* dpy) 87 { 88 if(this.set) { 89 XFreeFontSet(dpy, this.set); 90 } 91 else if(this.xfont) { 92 XFreeFont(dpy, this.xfont); 93 } 94 this.set = null; 95 this.xfont = null; 96 } 97 98 /** 99 * Free the given font object associated with a display. This will release 100 * the GC allocated memory. 101 * Params: 102 * fnt= Pointer to the font to destroy. 103 * dpy= Display associated with the font to destroy 104 * Example: 105 * --- 106 * auto f = Fnt(display, "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"); 107 * 108 * Fnt.free(f) 109 * --- 110 */ 111 static void free(Display* dpy, Fnt* fnt) 112 { 113 fnt.destroy(AppDisplay.instance().dpy); 114 DGC.free(fnt); 115 } 116 117 /** 118 * Get the font extents for a given string. 119 * Params: 120 * text= Text to get the extents 121 * tex= Extents struct to fill in with the font information 122 */ 123 void getexts(in string text, Extnts *tex) 124 { 125 XRectangle r; 126 127 if(text.length == 0) { 128 return; 129 } 130 if(this.set) { 131 XmbTextExtents(this.set, cast(char*)text.ptr, cast(int)text.length, null, &r); 132 tex.w = r.width; 133 tex.h = r.height; 134 } 135 else { 136 tex.h = this.ascent + this.descent; 137 tex.w = XTextWidth(this.xfont, cast(char*)text.ptr, cast(int)text.length); 138 } 139 } 140 141 /** 142 * Get the rendered width of a string for the wrapped font. 143 * Params: 144 * text= Text to get the width for 145 * Returns: 146 * Width of the text for the wrapped font. 147 */ 148 uint getexts_width(in string text) 149 { 150 Extnts tex; 151 152 this.getexts(text, &tex); 153 return tex.w; 154 } 155 }