more bug fixes..
[wmaker-crm.git] / util / fontconv.c
bloba10ba23d9acf9844386caef6ff5342cd7f1beb07
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: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 mapSlantToName(str *slant)
90 if (slant->len==0 || slant->str[0]=='*')
91 return "roman";
93 switch(slant->str[0]) {
94 case 'i':
95 return "italic";
96 case 'o':
97 return "oblique";
98 case 'r':
99 default:
100 return "roman";
105 char*
106 xlfdToFc(char *xlfd, char *useFamily, Bool keepXLFD)
108 str *tokens, *family, *weight, *slant;
109 char *name, buf[512];
110 int size, pixelsize;
112 tokens = getXLFDTokens(xlfd);
113 if (!tokens)
114 return wstrdup(DEFAULT_FONT);
116 family = &(tokens[1]);
117 weight = &(tokens[2]);
118 slant = &(tokens[3]);
120 if (useFamily) {
121 name = wstrdup(useFamily);
122 } else {
123 if (family->len==0 || family->str[0]=='*')
124 return wstrdup(DEFAULT_FONT);
126 sprintf(buf, "%.*s", family->len, family->str);
127 name = wstrdup(buf);
130 pixelsize = strToInt(&tokens[6]);
131 size = strToInt(&tokens[7]);
133 if (size<=0 && pixelsize<=0) {
134 name = wstrappend(name, ":pixelsize=12");
135 } else if (pixelsize>0) {
136 /* if pixelsize is present size will be ignored so we skip it */
137 sprintf(buf, ":pixelsize=%d", pixelsize);
138 name = wstrappend(name, buf);
139 } else {
140 sprintf(buf, "-%d", size/10);
141 name = wstrappend(name, buf);
144 if (weight->len>0 && weight->str[0]!='*') {
145 sprintf(buf, ":weight=%.*s", weight->len, weight->str);
146 name = wstrappend(name, buf);
149 if (slant->len>0 && slant->str[0]!='*') {
150 sprintf(buf, ":slant=%s", mapSlantToName(slant));
151 name = wstrappend(name, buf);
154 if (keepXLFD) {
155 name = wstrappend(name, ":xlfd=");
156 name = wstrappend(name, xlfd);
159 return name;
163 /* return converted font (if conversion is needed) else the original font */
164 char*
165 convertFont(char *font, Bool keepXLFD)
167 if (font[0]=='-') {
168 char *res;
169 char *tmp= wstrdup(font);
171 if (MB_CUR_MAX < 2) {
172 char *ptr = strchr(tmp, ',');
173 if (ptr) *ptr= 0;
174 res = xlfdToFc(tmp, NULL, keepXLFD);
175 } else {
176 res = xlfdToFc(tmp, "sans", keepXLFD);
178 wfree(tmp);
180 return res;
181 } else {
182 return font;