Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wfont_noxft.c
Commit [+]AuthorDateLineData
9aca0d5f dan2004-10-12 01:34:32 +00001
9aca0d5f dan2004-10-12 01:34:32 +00002#include "wconfig.h"
3
4#ifndef XFT
5
6#include "WINGsP.h"
7
8#include <wraster.h>
9#include <assert.h>
10#include <X11/Xlocale.h>
11
9aca0d5f dan2004-10-12 01:34:32 +000012static char *makeFontSetOfSize(char *fontset, int size);
13
9aca0d5f dan2004-10-12 01:34:32 +000014/* XLFD pattern matching */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020015static char *getElementFromXLFD(const char *xlfd, int index)
9aca0d5f dan2004-10-12 01:34:32 +000016{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020017 const char *p = xlfd;
18 while (*p != 0) {
19 if (*p == '-' && --index == 0) {
20 const char *end = strchr(p + 1, '-');
21 char *buf;
22 size_t len;
23 if (end == 0)
24 end = p + strlen(p);
25 len = end - (p + 1);
26 buf = wmalloc(len);
27 memcpy(buf, p + 1, len);
28 buf[len] = 0;
29 return buf;
30 }
31 p++;
32 }
33 return strdup("*");
9aca0d5f dan2004-10-12 01:34:32 +000034}
35
9aca0d5f dan2004-10-12 01:34:32 +000036/* XLFD pattern matching */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020037static char *generalizeXLFD(const char *xlfd)
9aca0d5f dan2004-10-12 01:34:32 +000038{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020039 char *buf;
40 int len;
41 char *weight = getElementFromXLFD(xlfd, 3);
42 char *slant = getElementFromXLFD(xlfd, 4);
43 char *pxlsz = getElementFromXLFD(xlfd, 7);
9aca0d5f dan2004-10-12 01:34:32 +000044
45#define Xstrlen(A) ((A)?strlen(A):0)
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020046 len = Xstrlen(xlfd) + Xstrlen(weight) + Xstrlen(slant) + Xstrlen(pxlsz) * 2 + 60;
9aca0d5f dan2004-10-12 01:34:32 +000047#undef Xstrlen
48
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020049 buf = wmalloc(len + 1);
50 snprintf(buf, len + 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
51 "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*", xlfd, weight, slant, pxlsz, pxlsz);
9aca0d5f dan2004-10-12 01:34:32 +000052
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020053 wfree(pxlsz);
54 wfree(slant);
55 wfree(weight);
9aca0d5f dan2004-10-12 01:34:32 +000056
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020057 return buf;
9aca0d5f dan2004-10-12 01:34:32 +000058}
59
60/* XLFD pattern matching */
61static XFontSet
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020062W_CreateFontSetWithGuess(Display * dpy, char *xlfd, char ***missing, int *nmissing, char **def_string)
9aca0d5f dan2004-10-12 01:34:32 +000063{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020064 XFontSet fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string);
65
66 if (fs != NULL && *nmissing == 0)
67 return fs;
68
69 /* for non-iso8859-1 language and iso8859-1 specification
70 (this fontset is only for pattern analysis) */
71 if (fs == NULL) {
72 if (*nmissing != 0)
73 XFreeStringList(*missing);
74 setlocale(LC_CTYPE, "C");
75 fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string);
76 setlocale(LC_CTYPE, "");
77 }
78
79 /* make XLFD font name for pattern analysis */
80 if (fs != NULL) {
81 XFontStruct **fontstructs;
82 char **fontnames;
83 if (XFontsOfFontSet(fs, &fontstructs, &fontnames) > 0)
84 xlfd = fontnames[0];
85 }
86
87 xlfd = generalizeXLFD(xlfd);
88
89 if (*nmissing != 0)
90 XFreeStringList(*missing);
91 if (fs != NULL)
92 XFreeFontSet(dpy, fs);
93
94 fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string);
95
96 wfree(xlfd);
97 return fs;
98}
9aca0d5f dan2004-10-12 01:34:32 +000099
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200100static char *xlfdFromFontName(char *fontName)
101{
102 char *systemFont, *boldSystemFont;
103 char *font;
104 int size;
105
106 systemFont = WINGsConfiguration.systemFont;
107 boldSystemFont = WINGsConfiguration.boldSystemFont;
108
109 size = WINGsConfiguration.defaultFontSize;
110
111 if (strcmp(fontName, "SystemFont") == 0) {
112 font = systemFont;
113 } else if (strncmp(fontName, "SystemFont-", 11) == 0) {
114 font = systemFont;
115 if (sscanf(&fontName[11], "%i", &size) != 1) {
116 size = WINGsConfiguration.defaultFontSize;
117 wwarning(_("Invalid size specification '%s' in %s. "
118 "Using default %d\n"), &fontName[11], fontName, size);
119 }
120 } else if (strcmp(fontName, "BoldSystemFont") == 0) {
121 font = boldSystemFont;
122 } else if (strncmp(fontName, "BoldSystemFont-", 15) == 0) {
123 font = boldSystemFont;
124 if (sscanf(&fontName[15], "%i", &size) != 1) {
125 size = WINGsConfiguration.defaultFontSize;
126 wwarning(_("Invalid size specification '%s' in %s. "
127 "Using default %d\n"), &fontName[15], fontName, size);
128 }
129 } else {
130 font = NULL;
131 }
132
133 return (font != NULL ? makeFontSetOfSize(font, size) : wstrdup(fontName));
134}
9aca0d5f dan2004-10-12 01:34:32 +0000135
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200136WMFont *WMCreateFontSet(WMScreen * scrPtr, char *fontName)
137{
138 WMFont *font;
139 Display *display = scrPtr->display;
140 char **missing;
141 int nmissing = 0;
142 char *defaultString;
143 char *fname;
144 XFontSetExtents *extents;
9aca0d5f dan2004-10-12 01:34:32 +0000145
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200146 fname = xlfdFromFontName(fontName);
9aca0d5f dan2004-10-12 01:34:32 +0000147
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200148 font = WMHashGet(scrPtr->fontSetCache, fname);
149 if (font) {
150 WMRetainFont(font);
151 wfree(fname);
152 return font;
153 }
9aca0d5f dan2004-10-12 01:34:32 +0000154
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200155 font = wmalloc(sizeof(WMFont));
156 memset(font, 0, sizeof(WMFont));
9aca0d5f dan2004-10-12 01:34:32 +0000157
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200158 font->notFontSet = 0;
9aca0d5f dan2004-10-12 01:34:32 +0000159
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200160 font->screen = scrPtr;
9aca0d5f dan2004-10-12 01:34:32 +0000161
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200162 font->font.set = W_CreateFontSetWithGuess(display, fname, &missing, &nmissing, &defaultString);
163 if (nmissing > 0 && font->font.set) {
164 int i;
9aca0d5f dan2004-10-12 01:34:32 +0000165
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200166 wwarning(_("the following character sets are missing in %s:"), fname);
167 for (i = 0; i < nmissing; i++) {
168 wwarning(missing[i]);
169 }
170 XFreeStringList(missing);
171 if (defaultString)
172 wwarning(_("the string \"%s\" will be used in place of any characters from those sets."),
173 defaultString);
174 }
175 if (!font->font.set) {
176 wfree(font);
177 wfree(fname);
178 return NULL;
179 }
9aca0d5f dan2004-10-12 01:34:32 +0000180
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200181 extents = XExtentsOfFontSet(font->font.set);
9aca0d5f dan2004-10-12 01:34:32 +0000182
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200183 font->height = extents->max_logical_extent.height;
184 font->y = font->height - (font->height + extents->max_logical_extent.y);
9aca0d5f dan2004-10-12 01:34:32 +0000185
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200186 font->refCount = 1;
9aca0d5f dan2004-10-12 01:34:32 +0000187
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200188 font->name = fname;
9aca0d5f dan2004-10-12 01:34:32 +0000189
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200190 assert(WMHashInsert(scrPtr->fontSetCache, font->name, font) == NULL);
191
192 return font;
193}
194
195WMFont *WMCreateNormalFont(WMScreen * scrPtr, char *fontName)
9aca0d5f dan2004-10-12 01:34:32 +0000196{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200197 WMFont *font;
198 Display *display = scrPtr->display;
199 char *fname, *ptr;
9aca0d5f dan2004-10-12 01:34:32 +0000200
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200201 fontName = xlfdFromFontName(fontName);
9aca0d5f dan2004-10-12 01:34:32 +0000202
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200203 if ((ptr = strchr(fontName, ','))) {
204 fname = wmalloc(ptr - fontName + 1);
205 strncpy(fname, fontName, ptr - fontName);
206 fname[ptr - fontName] = 0;
207 } else {
208 fname = wstrdup(fontName);
209 }
9aca0d5f dan2004-10-12 01:34:32 +0000210
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200211 wfree(fontName);
9aca0d5f dan2004-10-12 01:34:32 +0000212
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200213 font = WMHashGet(scrPtr->fontCache, fname);
214 if (font) {
215 WMRetainFont(font);
216 wfree(fname);
217 return font;
218 }
9aca0d5f dan2004-10-12 01:34:32 +0000219
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200220 font = wmalloc(sizeof(WMFont));
221 memset(font, 0, sizeof(WMFont));
9aca0d5f dan2004-10-12 01:34:32 +0000222
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200223 font->notFontSet = 1;
9aca0d5f dan2004-10-12 01:34:32 +0000224
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200225 font->screen = scrPtr;
9aca0d5f dan2004-10-12 01:34:32 +0000226
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200227 font->font.normal = XLoadQueryFont(display, fname);
228 if (!font->font.normal) {
229 wfree(font);
230 wfree(fname);
231 return NULL;
232 }
233 font->height = font->font.normal->ascent + font->font.normal->descent;
234 font->y = font->font.normal->ascent;
9aca0d5f dan2004-10-12 01:34:32 +0000235
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200236 font->refCount = 1;
9aca0d5f dan2004-10-12 01:34:32 +0000237
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200238 font->name = fname;
9aca0d5f dan2004-10-12 01:34:32 +0000239
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200240 assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000241
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200242 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000243}
244
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200245WMFont *WMCreateFont(WMScreen * scrPtr, char *fontName)
9aca0d5f dan2004-10-12 01:34:32 +0000246{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200247 return WMCreateFontWithFlags(scrPtr, fontName, WFDefaultFont);
9aca0d5f dan2004-10-12 01:34:32 +0000248}
249
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200250WMFont *WMCreateFontWithFlags(WMScreen * scrPtr, char *fontName, WMFontFlags flags)
9aca0d5f dan2004-10-12 01:34:32 +0000251{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200252 Bool multiByte = scrPtr->useMultiByte;
253 WMFont *font;
254
255 if (flags & WFFontSet) {
256 multiByte = True;
257 } else if (flags & WFNormalFont) {
258 multiByte = False;
259 }
260
261 if (multiByte) {
262 font = WMCreateFontSet(scrPtr, fontName);
263 } else {
264 font = WMCreateNormalFont(scrPtr, fontName);
265 }
266
267 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000268}
269
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200270WMFont *WMRetainFont(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000271{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200272 wassertrv(font != NULL, NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000273
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200274 font->refCount++;
9aca0d5f dan2004-10-12 01:34:32 +0000275
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200276 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000277}
278
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200279void WMReleaseFont(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000280{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200281 wassertr(font != NULL);
282
283 font->refCount--;
284 if (font->refCount < 1) {
285 if (font->notFontSet) {
286 XFreeFont(font->screen->display, font->font.normal);
287 } else {
288 XFreeFontSet(font->screen->display, font->font.set);
289 }
290
291 if (font->name) {
292 if (font->notFontSet) {
293 WMHashRemove(font->screen->fontCache, font->name);
294 } else {
295 WMHashRemove(font->screen->fontSetCache, font->name);
296 }
297 wfree(font->name);
298 }
299 wfree(font);
300 }
9aca0d5f dan2004-10-12 01:34:32 +0000301}
302
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200303Bool WMIsAntialiasingEnabled(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000304{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200305 return False;
9aca0d5f dan2004-10-12 01:34:32 +0000306}
307
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200308unsigned int WMFontHeight(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000309{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200310 wassertrv(font != NULL, 0);
9aca0d5f dan2004-10-12 01:34:32 +0000311
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200312 return font->height;
9aca0d5f dan2004-10-12 01:34:32 +0000313}
314
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200315char *WMGetFontName(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000316{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200317 wassertrv(font != NULL, NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000318
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200319 return font->name;
9aca0d5f dan2004-10-12 01:34:32 +0000320}
321
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200322WMFont *WMDefaultSystemFont(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000323{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200324 return WMRetainFont(scrPtr->normalFont);
9aca0d5f dan2004-10-12 01:34:32 +0000325}
326
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200327WMFont *WMDefaultBoldSystemFont(WMScreen * scrPtr)
9aca0d5f dan2004-10-12 01:34:32 +0000328{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200329 return WMRetainFont(scrPtr->boldFont);
9aca0d5f dan2004-10-12 01:34:32 +0000330}
331
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200332static WMFont *makeSystemFontOfSize(WMScreen * scrPtr, int size, Bool bold)
9aca0d5f dan2004-10-12 01:34:32 +0000333{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200334 WMFont *font;
335 char *fontSpec;
9aca0d5f dan2004-10-12 01:34:32 +0000336
337#define WConf WINGsConfiguration
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200338 if (bold) {
339 fontSpec = makeFontSetOfSize(WConf.boldSystemFont, size);
340 } else {
341 fontSpec = makeFontSetOfSize(WConf.systemFont, size);
342 }
9aca0d5f dan2004-10-12 01:34:32 +0000343#undef WConf
344
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200345 if (scrPtr->useMultiByte) {
346 font = WMCreateFontSet(scrPtr, fontSpec);
347 } else {
348 font = WMCreateNormalFont(scrPtr, fontSpec);
349 }
350
351 if (!font) {
352 if (scrPtr->useMultiByte) {
353 wwarning(_("could not load font set %s. Trying fixed."), fontSpec);
354 font = WMCreateFontSet(scrPtr, "fixed");
355 if (!font) {
356 font = WMCreateFontSet(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
357 }
358 } else {
359 wwarning(_("could not load font %s. Trying fixed."), fontSpec);
360 font = WMCreateNormalFont(scrPtr, "fixed");
361 }
362 if (!font) {
363 wwarning(_("could not load fixed font!"));
364 wfree(fontSpec);
365 return NULL;
366 }
367 }
368 wfree(fontSpec);
369
370 return font;
9aca0d5f dan2004-10-12 01:34:32 +0000371}
372
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200373WMFont *WMSystemFontOfSize(WMScreen * scrPtr, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000374{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200375 return makeSystemFontOfSize(scrPtr, size, False);
9aca0d5f dan2004-10-12 01:34:32 +0000376}
377
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200378WMFont *WMBoldSystemFontOfSize(WMScreen * scrPtr, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000379{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200380 return makeSystemFontOfSize(scrPtr, size, True);
9aca0d5f dan2004-10-12 01:34:32 +0000381}
382
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200383XFontSet WMGetFontFontSet(WMFont * font)
9aca0d5f dan2004-10-12 01:34:32 +0000384{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200385 wassertrv(font != NULL, NULL);
9aca0d5f dan2004-10-12 01:34:32 +0000386
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200387 if (!font->notFontSet && !font->antialiased)
388 return font->font.set;
9aca0d5f dan2004-10-12 01:34:32 +0000389
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200390 return NULL;
9aca0d5f dan2004-10-12 01:34:32 +0000391}
392
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200393int WMWidthOfString(WMFont * font, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000394{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200395 wassertrv(font != NULL, 0);
396 wassertrv(text != NULL, 0);
9aca0d5f dan2004-10-12 01:34:32 +0000397
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200398 if (font->notFontSet) {
399 return XTextWidth(font->font.normal, text, length);
400 } else {
401 XRectangle rect;
402 XRectangle AIXsucks;
9aca0d5f dan2004-10-12 01:34:32 +0000403
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200404 XmbTextExtents(font->font.set, text, length, &AIXsucks, &rect);
9aca0d5f dan2004-10-12 01:34:32 +0000405
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200406 return rect.width;
407 }
9aca0d5f dan2004-10-12 01:34:32 +0000408}
409
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200410void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000411{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200412 wassertr(font != NULL);
413
414 if (font->notFontSet) {
415 XSetFont(scr->display, scr->drawStringGC, font->font.normal->fid);
416 XSetForeground(scr->display, scr->drawStringGC, W_PIXEL(color));
417 XDrawString(scr->display, d, scr->drawStringGC, x, y + font->y, text, length);
418 } else {
419 XSetForeground(scr->display, scr->drawStringGC, W_PIXEL(color));
420 XmbDrawString(scr->display, d, font->font.set, scr->drawStringGC, x, y + font->y, text, length);
421 }
9aca0d5f dan2004-10-12 01:34:32 +0000422}
423
9aca0d5f dan2004-10-12 01:34:32 +0000424void
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200425WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * background,
426 WMFont * font, int x, int y, char *text, int length)
9aca0d5f dan2004-10-12 01:34:32 +0000427{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200428 wassertr(font != NULL);
429
430 if (font->notFontSet) {
431 XSetForeground(scr->display, scr->drawImStringGC, W_PIXEL(color));
432 XSetBackground(scr->display, scr->drawImStringGC, W_PIXEL(background));
433 XSetFont(scr->display, scr->drawImStringGC, font->font.normal->fid);
434 XDrawImageString(scr->display, d, scr->drawImStringGC, x, y + font->y, text, length);
435 } else {
436 XSetForeground(scr->display, scr->drawImStringGC, W_PIXEL(color));
437 XSetBackground(scr->display, scr->drawImStringGC, W_PIXEL(background));
438 XmbDrawImageString(scr->display, d, font->font.set, scr->drawImStringGC,
439 x, y + font->y, text, length);
440 }
9aca0d5f dan2004-10-12 01:34:32 +0000441}
442
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200443static char *makeFontSetOfSize(char *fontset, int size)
9aca0d5f dan2004-10-12 01:34:32 +0000444{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200445 char font[300], *f;
446 char *newfs = NULL;
447 char *ptr;
448
449 do {
450 char *tmp;
451 int end;
452
453 f = fontset;
454 ptr = strchr(fontset, ',');
455 if (ptr) {
456 int count = ptr - fontset;
457
458 if (count > 255) {
459 wwarning(_("font description %s is too large."), fontset);
460 } else {
461 memcpy(font, fontset, count);
462 font[count] = 0;
463 f = (char *)font;
464 }
465 }
466
467 if (newfs)
468 end = strlen(newfs);
469 else
470 end = 0;
471
472 tmp = wmalloc(end + strlen(f) + 8);
473 if (end != 0) {
474 sprintf(tmp, "%s,", newfs);
475 sprintf(tmp + end + 1, f, size);
476 } else {
477 sprintf(tmp + end, f, size);
478 }
479
480 if (newfs)
481 wfree(newfs);
482 newfs = tmp;
483
484 fontset = ptr + 1;
485 } while (ptr != NULL);
486
487 return newfs;
9aca0d5f dan2004-10-12 01:34:32 +0000488}
489
9aca0d5f dan2004-10-12 01:34:32 +0000490#define FONT_PROPS 14
491
492typedef struct {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200493 char *props[FONT_PROPS];
9aca0d5f dan2004-10-12 01:34:32 +0000494} W_FontAttributes;
495
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200496static void changeFontProp(char *buf, char *newprop, int position)
9aca0d5f dan2004-10-12 01:34:32 +0000497{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200498 char buf2[512];
499 char *ptr, *pptr, *rptr;
500 int count;
501
502 if (buf[0] != '-') {
503 /* // remove warning later. or maybe not */
504 wwarning(_("Invalid font specification: '%s'\n"), buf);
505 return;
506 }
507
508 ptr = pptr = rptr = buf;
509 count = 0;
510 while (*ptr && *ptr != ',') {
511 if (*ptr == '-') {
512 count++;
513 if (count - 1 == position + 1) {
514 rptr = ptr;
515 break;
516 }
517 if (count - 1 == position) {
518 pptr = ptr + 1;
519 }
520 }
521 ptr++;
522 }
523 if (position == FONT_PROPS - 1) {
524 rptr = ptr;
525 }
526
527 *pptr = 0;
528 snprintf(buf2, 512, "%s%s%s", buf, newprop, rptr);
529 strcpy(buf, buf2);
9aca0d5f dan2004-10-12 01:34:32 +0000530}
531
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200532static WMArray *getOptions(char *options)
9aca0d5f dan2004-10-12 01:34:32 +0000533{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200534 char *ptr, *ptr2, *str;
535 WMArray *result;
536 int count;
537
538 result = WMCreateArrayWithDestructor(2, (WMFreeDataProc *) wfree);
539
540 ptr = options;
541 while (1) {
542 ptr2 = strchr(ptr, ',');
543 if (!ptr2) {
544 WMAddToArray(result, wstrdup(ptr));
545 break;
546 } else {
547 count = ptr2 - ptr;
548 str = wmalloc(count + 1);
549 memcpy(str, ptr, count);
550 str[count] = 0;
551 WMAddToArray(result, str);
552 ptr = ptr2 + 1;
553 }
554 }
555
556 return result;
9aca0d5f dan2004-10-12 01:34:32 +0000557}
558
9aca0d5f dan2004-10-12 01:34:32 +0000559#define WFAUnchanged (NULL)
560/* Struct for font change operations */
561typedef struct WMFontAttributes {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200562 char *foundry;
563 char *family;
564 char *weight;
565 char *slant;
566 char *setWidth;
567 char *addStyle;
568 char *pixelSize;
569 char *pointSize;
570 char *resolutionX;
571 char *resolutionY;
572 char *spacing;
573 char *averageWidth;
574 char *registry;
575 char *encoding;
9aca0d5f dan2004-10-12 01:34:32 +0000576} WMFontAttributes;
577
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200578WMFont *WMCopyFontWithChanges(WMScreen * scrPtr, WMFont * font, const WMFontAttributes * changes)
9aca0d5f dan2004-10-12 01:34:32 +0000579{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200580 int index[FONT_PROPS], count[FONT_PROPS];
581 int totalProps, i, j, carry;
582 char fname[512];
583 WMFontFlags fFlags;
584 WMBag *props;
585 WMArray *options;
586 WMFont *result;
587 char *prop;
588
589 snprintf(fname, 512, "%s", font->name);
590
591 fFlags = (font->antialiased ? WFAntialiased : WFNotAntialiased);
592 fFlags |= (font->notFontSet ? WFNormalFont : WFFontSet);
593
594 props = WMCreateBagWithDestructor(1, (WMFreeDataProc *) WMFreeArray);
595
596 totalProps = 0;
597 for (i = 0; i < FONT_PROPS; i++) {
598 prop = ((W_FontAttributes *) changes)->props[i];
599 count[i] = index[i] = 0;
600 if (!prop) {
601 /* No change for this property */
602 continue;
603 } else if (strchr(prop, ',') == NULL) {
604 /* Simple option */
605 changeFontProp(fname, prop, i);
606 } else {
607 /* Option with fallback alternatives */
608 if ((changes == WFAEmphasized || changes == WFABoldEmphasized) &&
609 font->antialiased && strcmp(prop, "o,i") == 0) {
610 options = getOptions("i,o");
611 } else {
612 options = getOptions(prop);
613 }
614 WMInsertInBag(props, i, options);
615 count[i] = WMGetArrayItemCount(options);
616 if (totalProps == 0)
617 totalProps = 1;
618 totalProps = totalProps * count[i];
619 }
620 }
621
622 if (totalProps == 0) {
623 /* No options with fallback alternatives at all */
624 WMFreeBag(props);
625 return WMCreateFontWithFlags(scrPtr, fname, fFlags);
626 }
627
628 for (i = 0; i < totalProps; i++) {
629 for (j = 0; j < FONT_PROPS; j++) {
630 if (count[j] != 0) {
631 options = WMGetFromBag(props, j);
632 prop = WMGetFromArray(options, index[j]);
633 if (prop) {
634 changeFontProp(fname, prop, j);
635 }
636 }
637 }
638 result = WMCreateFontWithFlags(scrPtr, fname, fFlags);
639 if (result) {
640 WMFreeBag(props);
641 return result;
642 }
643 for (j = FONT_PROPS - 1, carry = 1; j >= 0; j--) {
644 if (count[j] != 0) {
645 index[j] += carry;
646 carry = (index[j] == count[j]);
647 index[j] %= count[j];
648 }
649 }
650 }
651
652 WMFreeBag(props);
653
654 return NULL;
9aca0d5f dan2004-10-12 01:34:32 +0000655}
656
657// should WFANormal also set "normal" or leave it alone?
658static const WMFontAttributes W_FANormal = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200659 WFAUnchanged, WFAUnchanged, "medium,normal,regular", "r", "normal",
660 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
661 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000662};
663
9aca0d5f dan2004-10-12 01:34:32 +0000664static const WMFontAttributes W_FABold = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200665 WFAUnchanged, WFAUnchanged, "bold", WFAUnchanged,
666 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
667 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000668};
669
9aca0d5f dan2004-10-12 01:34:32 +0000670static const WMFontAttributes W_FANotBold = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200671 WFAUnchanged, WFAUnchanged, "medium,normal,regular", WFAUnchanged,
672 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
673 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000674};
675
9aca0d5f dan2004-10-12 01:34:32 +0000676static const WMFontAttributes W_FAEmphasized = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200677 WFAUnchanged, WFAUnchanged, WFAUnchanged, "o,i",
678 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
679 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000680};
681
9aca0d5f dan2004-10-12 01:34:32 +0000682static const WMFontAttributes W_FANotEmphasized = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200683 WFAUnchanged, WFAUnchanged, WFAUnchanged, "r",
684 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
685 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000686};
687
9aca0d5f dan2004-10-12 01:34:32 +0000688static const WMFontAttributes W_FABoldEmphasized = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200689 WFAUnchanged, WFAUnchanged, "bold", "o,i",
690 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged,
691 WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged, WFAUnchanged
9aca0d5f dan2004-10-12 01:34:32 +0000692};
693
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200694const WMFontAttributes *WFANormal = &W_FANormal;
695const WMFontAttributes *WFABold = &W_FABold;
696const WMFontAttributes *WFANotBold = &W_FANotBold;
697const WMFontAttributes *WFAEmphasized = &W_FAEmphasized;
698const WMFontAttributes *WFANotEmphasized = &W_FANotEmphasized;
9aca0d5f dan2004-10-12 01:34:32 +0000699const WMFontAttributes *WFABoldEmphasized = &W_FABoldEmphasized;
700
9aca0d5f dan2004-10-12 01:34:32 +0000701#endif