4 * Copyright (c) Tuomo Valkonen 1999-2008.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <ioncore/common.h>
21 static DEFont *fonts=NULL;
24 DEFont *de_load_font(const char *fontname)
27 XFontSet fontset=NULL;
28 XFontStruct *fontstruct=NULL;
30 assert(fontname!=NULL);
32 /* There shouldn't be that many fonts... */
33 for(fnt=fonts; fnt!=NULL; fnt=fnt->next){
34 if(strcmp(fnt->pattern, fontname)==0){
41 fontset=de_create_font_set(fontname);
43 if(XContextDependentDrawing(fontset)){
44 warn(TR("Fontset for font pattern '%s' implements context "
45 "dependent drawing, which is unsupported. Expect "
46 "clutter."), fontname);
50 fontstruct=XLoadQueryFont(ioncore_g.dpy, fontname);
53 if(fontstruct==NULL && fontset==NULL){
54 if(strcmp(fontname, CF_FALLBACK_FONT_NAME)!=0){
56 warn(TR("Could not load font \"%s\", trying \"%s\""),
57 fontname, CF_FALLBACK_FONT_NAME);
58 fnt=de_load_font(CF_FALLBACK_FONT_NAME);
60 warn(TR("Failed to load fallback font."));
72 fnt->fontstruct=fontstruct;
73 fnt->pattern=scopy(fontname);
78 LINK_ITEM(fonts, fnt, next, prev);
84 bool de_set_font_for_style(DEStyle *style, DEFont *font)
87 de_free_font(style->font);
92 if(style->font->fontstruct!=NULL){
93 XSetFont(ioncore_g.dpy, style->normal_gc,
94 style->font->fontstruct->fid);
101 bool de_load_font_for_style(DEStyle *style, const char *fontname)
103 if(style->font!=NULL)
104 de_free_font(style->font);
106 style->font=de_load_font(fontname);
108 if(style->font==NULL)
111 if(style->font->fontstruct!=NULL){
112 XSetFont(ioncore_g.dpy, style->normal_gc,
113 style->font->fontstruct->fid);
120 void de_free_font(DEFont *font)
122 if(--font->refcount!=0)
125 if(font->fontset!=NULL)
126 XFreeFontSet(ioncore_g.dpy, font->fontset);
127 if(font->fontstruct!=NULL)
128 XFreeFont(ioncore_g.dpy, font->fontstruct);
129 if(font->pattern!=NULL)
132 UNLINK_ITEM(fonts, font, next, prev);
143 void debrush_get_font_extents(DEBrush *brush, GrFontExtents *fnte)
145 if(brush->d->font==NULL){
146 DE_RESET_FONT_EXTENTS(fnte);
150 defont_get_font_extents(brush->d->font, fnte);
154 void defont_get_font_extents(DEFont *font, GrFontExtents *fnte)
156 if(font->fontset!=NULL){
157 XFontSetExtents *ext=XExtentsOfFontSet(font->fontset);
160 fnte->max_height=ext->max_logical_extent.height;
161 fnte->max_width=ext->max_logical_extent.width;
162 fnte->baseline=-ext->max_logical_extent.y;
164 }else if(font->fontstruct!=NULL){
165 XFontStruct *fnt=font->fontstruct;
166 fnte->max_height=fnt->ascent+fnt->descent;
167 fnte->max_width=fnt->max_bounds.width;
168 fnte->baseline=fnt->ascent;
173 DE_RESET_FONT_EXTENTS(fnte);
177 uint debrush_get_text_width(DEBrush *brush, const char *text, uint len)
179 if(brush->d->font==NULL || text==NULL || len==0)
182 return defont_get_text_width(brush->d->font, text, len);
186 uint defont_get_text_width(DEFont *font, const char *text, uint len)
188 if(font->fontset!=NULL){
190 #ifdef CF_DE_USE_XUTF8
191 if(ioncore_g.enc_utf8)
192 Xutf8TextExtents(font->fontset, text, len, NULL, &lext);
195 XmbTextExtents(font->fontset, text, len, NULL, &lext);
197 }else if(font->fontstruct!=NULL){
198 return XTextWidth(font->fontstruct, text, len);
208 /*{{{ String drawing */
211 void debrush_do_draw_string_default(DEBrush *brush, int x, int y,
212 const char *str, int len, bool needfill,
213 DEColourGroup *colours)
215 GC gc=brush->d->normal_gc;
217 if(brush->d->font==NULL)
220 XSetForeground(ioncore_g.dpy, gc, colours->fg);
223 if(brush->d->font->fontset!=NULL){
224 #ifdef CF_DE_USE_XUTF8
225 if(ioncore_g.enc_utf8)
226 Xutf8DrawString(ioncore_g.dpy, brush->win,
227 brush->d->font->fontset,
231 XmbDrawString(ioncore_g.dpy, brush->win,
232 brush->d->font->fontset,
234 }else if(brush->d->font->fontstruct!=NULL){
235 XDrawString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
238 XSetBackground(ioncore_g.dpy, gc, colours->bg);
239 if(brush->d->font->fontset!=NULL){
240 #ifdef CF_DE_USE_XUTF8
241 if(ioncore_g.enc_utf8)
242 Xutf8DrawImageString(ioncore_g.dpy, brush->win,
243 brush->d->font->fontset,
247 XmbDrawImageString(ioncore_g.dpy, brush->win,
248 brush->d->font->fontset,
250 }else if(brush->d->font->fontstruct!=NULL){
251 XDrawImageString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
257 void debrush_do_draw_string(DEBrush *brush, int x, int y,
258 const char *str, int len, bool needfill,
259 DEColourGroup *colours)
261 CALL_DYN(debrush_do_draw_string, brush, (brush, x, y, str, len,
266 void debrush_draw_string(DEBrush *brush, int x, int y,
267 const char *str, int len, bool needfill)
269 DEColourGroup *cg=debrush_get_current_colour_group(brush);
271 debrush_do_draw_string(brush, x, y, str, len, needfill, cg);