Fix periodic focus bug
[wmaker-crm.git] / util / fontconv.c
blob0f07abfd9202164672712b48c79cf9b4d1d30d02
2 #include <string.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <WINGs/WUtil.h>
7 #include "../src/wconfig.h"
9 #define DEFAULT_FONT "sans serif:pixelsize=12"
11 static int
12 countChar(char *str, char c)
14 int count = 0;
16 if (!str)
17 return 0;
19 for (; *str!=0; str++) {
20 if (*str == c) {
21 count++;
25 return count;
29 typedef struct str {
30 char *str;
31 int len;
32 } str;
34 #define XLFD_TOKENS 14
37 static str*
38 getXLFDTokens(char *xlfd)
40 static str tokens[XLFD_TOKENS];
41 int i, len, size;
42 char *ptr;
44 if (!xlfd || *xlfd!='-' || countChar(xlfd, '-')<XLFD_TOKENS)
45 return NULL;
47 memset(tokens, 0, sizeof(str)*XLFD_TOKENS);
49 len = strlen(xlfd);
51 for (ptr=xlfd, i=0; i<XLFD_TOKENS && len>0; i++) {
52 /* skip one '-' */
53 ptr++;
54 len--;
55 if (len <= 0)
56 break;
57 size = strcspn(ptr, "-,");
58 tokens[i].str = ptr;
59 tokens[i].len = size;
60 ptr += size;
61 len -= size;
64 return tokens;
68 static int
69 strToInt(str *token)
71 int res=0, pos, c;
73 if (token->len==0 || token->str[0]=='*') {
74 return -1;
75 } else {
76 for (res=0, pos=0; pos<token->len; pos++) {
77 c = token->str[pos] - '0';
78 if (c<0 || c>9)
79 break;
80 res = res*10 + c;
83 return res;
87 static char*
88 mapWeightToName(str *weight)
90 char *normalNames[] = {"medium", "normal", "regular"};
91 static char buf[32];
92 int i;
94 if (weight->len==0)
95 return "";
97 for (i=0; i<sizeof(normalNames)/sizeof(char*); i++) {
98 if (strlen(normalNames[i])==weight->len &&
99 strncmp(normalNames[i], weight->str, weight->len))
101 return "";
105 snprintf(buf, sizeof(buf), ":%.*s", weight->len, weight->str);
107 return buf;
111 static char*
112 mapSlantToName(str *slant)
114 if (slant->len==0)
115 return "";
117 switch(slant->str[0]) {
118 case 'i':
119 return ":italic";
120 case 'o':
121 return ":oblique";
122 case 'r':
123 default:
124 return "";
129 char*
130 xlfdToFc(char *xlfd, char *useFamily, Bool keepXLFD)
132 str *tokens, *family, *weight, *slant;
133 char *name, buf[64], *slt;
134 int size, pixelsize;
136 tokens = getXLFDTokens(xlfd);
137 if (!tokens)
138 return wstrdup(DEFAULT_FONT);
140 family = &(tokens[1]);
141 weight = &(tokens[2]);
142 slant = &(tokens[3]);
143 pixelsize = strToInt(&tokens[6]);
144 size = strToInt(&tokens[7]);
146 if (useFamily) {
147 name = wstrdup(useFamily);
148 } else {
149 if (family->len==0 || family->str[0]=='*')
150 return wstrdup(DEFAULT_FONT);
152 snprintf(buf, sizeof(buf), "%.*s", family->len, family->str);
153 name = wstrdup(buf);
156 if (size>0 && pixelsize<=0) {
157 snprintf(buf, sizeof(buf), "-%d", size/10);
158 name = wstrappend(name, buf);
161 name = wstrappend(name, mapWeightToName(weight));
162 name = wstrappend(name, mapSlantToName(slant));
164 if (size<=0 && pixelsize<=0) {
165 name = wstrappend(name, ":pixelsize=12");
166 } else if (pixelsize>0) {
167 /* if pixelsize is present size will be ignored so we skip it */
168 snprintf(buf, sizeof(buf), ":pixelsize=%d", pixelsize);
169 name = wstrappend(name, buf);
172 if (keepXLFD) {
173 name = wstrappend(name, ":xlfd=");
174 name = wstrappend(name, xlfd);
177 return name;
181 /* return converted font (if conversion is needed) else the original font */
182 char*
183 convertFont(char *font, Bool keepXLFD)
185 if (font[0]=='-') {
186 if (MB_CUR_MAX < 2) {
187 return xlfdToFc(font, NULL, keepXLFD);
188 } else {
189 return xlfdToFc(font, "sans serif", keepXLFD);
191 } else {
192 return font;