Change to the linux kernel coding style
[wmaker-crm.git] / util / fontconv.c
1
2 #include <string.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <WINGs/WUtil.h>
6
7 #include "../src/wconfig.h"
8
9 #define DEFAULT_FONT "sans serif:pixelsize=12"
10
11 static int countChar(char *str, char c)
12 {
13         int count = 0;
14
15         if (!str)
16                 return 0;
17
18         for (; *str != 0; str++) {
19                 if (*str == c) {
20                         count++;
21                 }
22         }
23
24         return count;
25 }
26
27 typedef struct str {
28         char *str;
29         int len;
30 } str;
31
32 #define XLFD_TOKENS 14
33
34 static str *getXLFDTokens(char *xlfd)
35 {
36         static str tokens[XLFD_TOKENS];
37         int i, len, size;
38         char *ptr;
39
40         if (!xlfd || *xlfd != '-' || countChar(xlfd, '-') < XLFD_TOKENS)
41                 return NULL;
42
43         memset(tokens, 0, sizeof(str) * XLFD_TOKENS);
44
45         len = strlen(xlfd);
46
47         for (ptr = xlfd, i = 0; i < XLFD_TOKENS && len > 0; i++) {
48                 /* skip one '-' */
49                 ptr++;
50                 len--;
51                 if (len <= 0)
52                         break;
53                 size = strcspn(ptr, "-,");
54                 tokens[i].str = ptr;
55                 tokens[i].len = size;
56                 ptr += size;
57                 len -= size;
58         }
59
60         return tokens;
61 }
62
63 static int strToInt(str * token)
64 {
65         int res = 0, pos, c;
66
67         if (token->len == 0 || token->str[0] == '*') {
68                 return -1;
69         } else {
70                 for (res = 0, pos = 0; pos < token->len; pos++) {
71                         c = token->str[pos] - '0';
72                         if (c < 0 || c > 9)
73                                 break;
74                         res = res * 10 + c;
75                 }
76         }
77         return res;
78 }
79
80 static char *mapWeightToName(str * weight)
81 {
82         char *normalNames[] = { "medium", "normal", "regular" };
83         static char buf[32];
84         int i;
85
86         if (weight->len == 0)
87                 return "";
88
89         for (i = 0; i < sizeof(normalNames) / sizeof(char *); i++) {
90                 if (strlen(normalNames[i]) == weight->len && strncmp(normalNames[i], weight->str, weight->len)) {
91                         return "";
92                 }
93         }
94
95         snprintf(buf, sizeof(buf), ":%.*s", weight->len, weight->str);
96
97         return buf;
98 }
99
100 static char *mapSlantToName(str * slant)
101 {
102         if (slant->len == 0)
103                 return "";
104
105         switch (slant->str[0]) {
106         case 'i':
107                 return ":italic";
108         case 'o':
109                 return ":oblique";
110         case 'r':
111         default:
112                 return "";
113         }
114 }
115
116 char *xlfdToFc(char *xlfd, char *useFamily, Bool keepXLFD)
117 {
118         str *tokens, *family, *weight, *slant;
119         char *name, buf[64];
120         int size, pixelsize;
121
122         tokens = getXLFDTokens(xlfd);
123         if (!tokens)
124                 return wstrdup(DEFAULT_FONT);
125
126         family = &(tokens[1]);
127         weight = &(tokens[2]);
128         slant = &(tokens[3]);
129         pixelsize = strToInt(&tokens[6]);
130         size = strToInt(&tokens[7]);
131
132         if (useFamily) {
133                 name = wstrdup(useFamily);
134         } else {
135                 if (family->len == 0 || family->str[0] == '*')
136                         return wstrdup(DEFAULT_FONT);
137
138                 snprintf(buf, sizeof(buf), "%.*s", family->len, family->str);
139                 name = wstrdup(buf);
140         }
141
142         if (size > 0 && pixelsize <= 0) {
143                 snprintf(buf, sizeof(buf), "-%d", size / 10);
144                 name = wstrappend(name, buf);
145         }
146
147         name = wstrappend(name, mapWeightToName(weight));
148         name = wstrappend(name, mapSlantToName(slant));
149
150         if (size <= 0 && pixelsize <= 0) {
151                 name = wstrappend(name, ":pixelsize=12");
152         } else if (pixelsize > 0) {
153                 /* if pixelsize is present size will be ignored so we skip it */
154                 snprintf(buf, sizeof(buf), ":pixelsize=%d", pixelsize);
155                 name = wstrappend(name, buf);
156         }
157
158         if (keepXLFD) {
159                 name = wstrappend(name, ":xlfd=");
160                 name = wstrappend(name, xlfd);
161         }
162
163         return name;
164 }
165
166 /* return converted font (if conversion is needed) else the original font */
167 char *convertFont(char *font, Bool keepXLFD)
168 {
169         if (font[0] == '-') {
170                 if (MB_CUR_MAX < 2) {
171                         return xlfdToFc(font, NULL, keepXLFD);
172                 } else {
173                         return xlfdToFc(font, "sans serif", keepXLFD);
174                 }
175         } else {
176                 return font;
177         }
178 }