Make ProgName a local variable
[wmaker-crm.git] / util / fontconv.c
blob4c420cc09a0751e40d174f80be08cefa31cb46f9
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include <WINGs/WUtil.h>
8 #include "../src/wconfig.h"
10 #define DEFAULT_FONT "sans serif:pixelsize=12"
12 /* X Font Name Suffix field names */
13 enum {
14 FOUNDRY,
15 FAMILY_NAME,
16 WEIGHT_NAME,
17 SLANT,
18 SETWIDTH_NAME,
19 ADD_STYLE_NAME,
20 PIXEL_SIZE,
21 POINT_SIZE,
22 RESOLUTION_X,
23 RESOLUTION_Y,
24 SPACING,
25 AVERAGE_WIDTH,
26 CHARSET_REGISTRY,
27 CHARSET_ENCODING
30 static int countChar(char *str, char c)
32 int count = 0;
34 if (!str)
35 return 0;
37 for (; *str != 0; str++) {
38 if (*str == c) {
39 count++;
43 return count;
46 typedef struct str {
47 char *str;
48 int len;
49 } str;
51 #define XLFD_TOKENS 14
53 static str *getXLFDTokens(char *xlfd)
55 static str tokens[XLFD_TOKENS];
56 int i, len, size;
57 char *ptr;
59 /* XXX: why does this assume there can't ever be XFNextPrefix? */
60 if (!xlfd || *xlfd != '-' || countChar(xlfd, '-') != XLFD_TOKENS)
61 return NULL;
63 memset(tokens, 0, sizeof(str) * XLFD_TOKENS);
65 len = strlen(xlfd);
67 for (ptr = xlfd, i = 0; i < XLFD_TOKENS && len > 0; i++) {
68 /* skip one '-' */
69 ptr++;
70 len--;
71 if (len <= 0)
72 break;
73 size = strcspn(ptr, "-,");
74 tokens[i].str = ptr;
75 tokens[i].len = size;
76 ptr += size;
77 len -= size;
80 return tokens;
83 static int strToInt(str * token)
85 static char buf[32]; /* enough for an Incredibly Big Number */
87 if (token->len == 0 ||
88 token->str[0] == '*' ||
89 token->len >= sizeof(buf))
90 return -1;
92 memset(buf, 0, sizeof(buf));
93 strncpy(buf, token->str, token->len);
95 /* the code using this will gracefully handle overflows */
96 return (int)strtol(buf, NULL, 10);
99 static char *mapWeightToName(str * weight)
101 char *normalNames[] = { "medium", "normal", "regular" };
102 static char buf[32];
103 size_t i;
105 if (weight->len == 0)
106 return "";
108 for (i = 0; i < sizeof(normalNames) / sizeof(char *); i++) {
109 if (strlen(normalNames[i]) == weight->len && strncmp(normalNames[i], weight->str, weight->len)) {
110 return "";
114 snprintf(buf, sizeof(buf), ":%.*s", weight->len, weight->str);
116 return buf;
119 static char *mapSlantToName(str * slant)
121 if (slant->len == 0)
122 return "";
124 switch (slant->str[0]) {
125 case 'i':
126 return ":italic";
127 case 'o':
128 return ":oblique";
129 case 'r':
130 default:
131 return "";
135 char *xlfdToFc(char *xlfd, char *useFamily, Bool keepXLFD)
137 str *tokens, *family, *weight, *slant;
138 char *name, buf[64];
139 int size, pixelsize;
141 tokens = getXLFDTokens(xlfd);
142 if (!tokens)
143 return wstrdup(DEFAULT_FONT);
145 family = &(tokens[FAMILY_NAME]);
146 weight = &(tokens[WEIGHT_NAME]);
147 slant = &(tokens[SLANT]);
148 pixelsize = strToInt(&tokens[PIXEL_SIZE]);
149 size = strToInt(&tokens[POINT_SIZE]);
151 if (useFamily) {
152 name = wstrdup(useFamily);
153 } else {
154 if (family->len == 0 || family->str[0] == '*')
155 return wstrdup(DEFAULT_FONT);
157 snprintf(buf, sizeof(buf), "%.*s", family->len, family->str);
158 name = wstrdup(buf);
161 if (size > 0 && pixelsize <= 0) {
162 snprintf(buf, sizeof(buf), "-%d", size / 10);
163 name = wstrappend(name, buf);
166 name = wstrappend(name, mapWeightToName(weight));
167 name = wstrappend(name, mapSlantToName(slant));
169 if (size <= 0 && pixelsize <= 0) {
170 name = wstrappend(name, ":pixelsize=12");
171 } else if (pixelsize > 0) {
172 /* if pixelsize is present size will be ignored so we skip it */
173 snprintf(buf, sizeof(buf), ":pixelsize=%d", pixelsize);
174 name = wstrappend(name, buf);
177 if (keepXLFD) {
178 name = wstrappend(name, ":xlfd=");
179 name = wstrappend(name, xlfd);
182 return name;
185 /* return converted font (if conversion is needed) else the original font */
186 char *convertFont(char *font, Bool keepXLFD)
188 if (font[0] == '-') {
189 if (MB_CUR_MAX < 2) {
190 return xlfdToFc(font, NULL, keepXLFD);
191 } else {
192 return xlfdToFc(font, "sans serif", keepXLFD);
194 } else {
195 return font;