4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
14 #include <libtu/objp.h>
15 #include <ioncore/common.h>
24 static DEFont *fonts=NULL;
27 DEFont *de_load_font(const char *fontname)
30 XFontSet fontset=NULL;
31 XFontStruct *fontstruct=NULL;
33 assert(fontname!=NULL);
35 /* There shouldn't be that many fonts... */
36 for(fnt=fonts; fnt!=NULL; fnt=fnt->next){
37 if(strcmp(fnt->pattern, fontname)==0){
44 fontset=de_create_font_set(fontname);
46 if(XContextDependentDrawing(fontset)){
47 warn(TR("Fontset for font pattern '%s' implements context "
48 "dependent drawing, which is unsupported. Expect "
49 "clutter."), fontname);
53 fontstruct=XLoadQueryFont(ioncore_g.dpy, fontname);
56 if(fontstruct==NULL && fontset==NULL){
57 if(strcmp(fontname, CF_FALLBACK_FONT_NAME)!=0){
59 warn(TR("Could not load font \"%s\", trying \"%s\""),
60 fontname, CF_FALLBACK_FONT_NAME);
61 fnt=de_load_font(CF_FALLBACK_FONT_NAME);
63 warn(TR("Failed to load fallback font."));
75 fnt->fontstruct=fontstruct;
76 fnt->pattern=scopy(fontname);
81 LINK_ITEM(fonts, fnt, next, prev);
87 bool de_set_font_for_style(DEStyle *style, DEFont *font)
90 de_free_font(style->font);
95 if(style->font->fontstruct!=NULL){
96 XSetFont(ioncore_g.dpy, style->normal_gc,
97 style->font->fontstruct->fid);
104 bool de_load_font_for_style(DEStyle *style, const char *fontname)
106 if(style->font!=NULL)
107 de_free_font(style->font);
109 style->font=de_load_font(fontname);
111 if(style->font==NULL)
114 if(style->font->fontstruct!=NULL){
115 XSetFont(ioncore_g.dpy, style->normal_gc,
116 style->font->fontstruct->fid);
123 void de_free_font(DEFont *font)
125 if(--font->refcount!=0)
128 if(font->fontset!=NULL)
129 XFreeFontSet(ioncore_g.dpy, font->fontset);
130 if(font->fontstruct!=NULL)
131 XFreeFont(ioncore_g.dpy, font->fontstruct);
132 if(font->pattern!=NULL)
135 UNLINK_ITEM(fonts, font, next, prev);
146 void debrush_get_font_extents(DEBrush *brush, GrFontExtents *fnte)
148 if(brush->d->font==NULL){
149 DE_RESET_FONT_EXTENTS(fnte);
153 defont_get_font_extents(brush->d->font, fnte);
157 void defont_get_font_extents(DEFont *font, GrFontExtents *fnte)
159 if(font->fontset!=NULL){
160 XFontSetExtents *ext=XExtentsOfFontSet(font->fontset);
163 fnte->max_height=ext->max_logical_extent.height;
164 fnte->max_width=ext->max_logical_extent.width;
165 fnte->baseline=-ext->max_logical_extent.y;
167 }else if(font->fontstruct!=NULL){
168 XFontStruct *fnt=font->fontstruct;
169 fnte->max_height=fnt->ascent+fnt->descent;
170 fnte->max_width=fnt->max_bounds.width;
171 fnte->baseline=fnt->ascent;
176 DE_RESET_FONT_EXTENTS(fnte);
180 uint debrush_get_text_width(DEBrush *brush, const char *text, uint len)
182 if(brush->d->font==NULL || text==NULL || len==0)
185 return defont_get_text_width(brush->d->font, text, len);
189 uint defont_get_text_width(DEFont *font, const char *text, uint len)
191 if(font->fontset!=NULL){
193 #ifdef CF_DE_USE_XUTF8
194 if(ioncore_g.enc_utf8)
195 Xutf8TextExtents(font->fontset, text, len, NULL, &lext);
198 XmbTextExtents(font->fontset, text, len, NULL, &lext);
200 }else if(font->fontstruct!=NULL){
201 return XTextWidth(font->fontstruct, text, len);
211 /*{{{ String drawing */
214 void debrush_do_draw_string_default(DEBrush *brush, int x, int y,
215 const char *str, int len, bool needfill,
216 DEColourGroup *colours)
218 GC gc=brush->d->normal_gc;
220 if(brush->d->font==NULL)
223 XSetForeground(ioncore_g.dpy, gc, colours->fg);
226 if(brush->d->font->fontset!=NULL){
227 #ifdef CF_DE_USE_XUTF8
228 if(ioncore_g.enc_utf8)
229 Xutf8DrawString(ioncore_g.dpy, brush->win,
230 brush->d->font->fontset,
234 XmbDrawString(ioncore_g.dpy, brush->win,
235 brush->d->font->fontset,
237 }else if(brush->d->font->fontstruct!=NULL){
238 XDrawString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
241 XSetBackground(ioncore_g.dpy, gc, colours->bg);
242 if(brush->d->font->fontset!=NULL){
243 #ifdef CF_DE_USE_XUTF8
244 if(ioncore_g.enc_utf8)
245 Xutf8DrawImageString(ioncore_g.dpy, brush->win,
246 brush->d->font->fontset,
250 XmbDrawImageString(ioncore_g.dpy, brush->win,
251 brush->d->font->fontset,
253 }else if(brush->d->font->fontstruct!=NULL){
254 XDrawImageString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
260 void debrush_do_draw_string(DEBrush *brush, int x, int y,
261 const char *str, int len, bool needfill,
262 DEColourGroup *colours)
264 CALL_DYN(debrush_do_draw_string, brush, (brush, x, y, str, len,
269 void debrush_draw_string(DEBrush *brush, int x, int y,
270 const char *str, int len, bool needfill)
272 DEColourGroup *cg=debrush_get_current_colour_group(brush);
274 debrush_do_draw_string(brush, x, y, str, len, needfill, cg);