]> git.decadent.org.uk Git - ion3.git/blob - de/fontset.c
[svn-inject] Installing original source of ion3
[ion3.git] / de / fontset.c
1 /*
2  * ion/de/fontset.c
3  * 
4  * This file contains routines to attempt to add fonts to a font pattern
5  * so that XCreateFontSet will not fail because the given font(s) do not
6  * contain all the characters required by the locale. The original code
7  * was apparently written by Tomohiro Kubota; see
8  * <http://www.debian.org/doc/manuals/intro-i18n/ch-examples.en.html#s13.4.5>.
9  * 
10  */
11
12 #include <string.h>
13 #include <ctype.h>
14 #include <locale.h>
15
16 #include <ioncore/common.h>
17 #include <ioncore/global.h>
18
19 #ifndef CF_FONT_ELEMENT_SIZE
20 #define CF_FONT_ELEMENT_SIZE 50
21 #endif
22
23 #define FNT_D(X) /*X*/
24
25
26 static const char *get_font_element(const char *pattern, char *buf,
27                                     int bufsiz, ...) 
28 {
29     const char *p, *v;
30     char *p2;
31     va_list va;
32     
33     va_start(va, bufsiz);
34     buf[bufsiz-1]=0;
35     buf[bufsiz-2]='*';
36     while((v=va_arg(va, char *))!=NULL){
37         p=libtu_strcasestr(pattern, v);
38         if(p){
39             strncpy(buf, p+1, bufsiz-2);
40             p2=strchr(buf, '-');
41             if(p2) *p2=0;
42             va_end(va);
43             return p;
44         }
45     }
46     va_end(va);
47     strncpy(buf, "*", bufsiz);
48     return NULL;
49 }
50
51
52 static const char *get_font_size(const char *pattern, int *size) 
53 {
54     const char *p;
55     const char *p2=NULL;
56     int n=0;
57     
58     for(p=pattern; 1; p++){
59         if(!*p){
60             if(p2!=NULL && n>1 && n<72){
61                 *size=n; return p2+1;
62             }else{
63                 *size=16; return NULL;
64             }
65         }else if(*p=='-'){
66             if(n>1 && n<72 && p2!=NULL){
67                 *size=n;
68                 return p2+1;
69             }
70             p2=p; n=0;
71         }else if(*p>='0' && *p<='9' && p2!=NULL){
72             n*=10;
73             n+=*p-'0';
74         }else{
75             p2=NULL; n=0;
76         }
77     }
78 }
79
80
81 XFontSet de_create_font_set(const char *fontname) 
82 {
83     XFontSet fs;
84     char **missing=NULL, *def="-";
85     int nmissing, pixel_size=0;
86     char weight[CF_FONT_ELEMENT_SIZE], slant[CF_FONT_ELEMENT_SIZE];
87     const char *nfontname=fontname;
88     char *pattern2=NULL;
89     int i;
90     
91     FNT_D(fprintf(stderr, "FNTRQ: %s\n", fontname));
92     
93     fs=XCreateFontSet(ioncore_g.dpy, fontname, &missing, &nmissing, &def);
94
95     if(fs && nmissing==0){
96         if(missing!=NULL) 
97             XFreeStringList(missing);
98         return fs;
99     }
100     
101     /* Not a warning, nothing serious */
102     FNT_D(fprintf(stderr, "Failed to load fontset.\n"));
103     
104     if(!fs){
105         char *lcc=NULL;
106         const char *lc;
107         if(missing!=NULL)
108             XFreeStringList(missing);
109         
110         lc=setlocale(LC_CTYPE, NULL);
111         if(lc!=NULL && strcmp(lc, "POSIX")!=0 && strcmp(lc, "C")!=0)
112             lcc=scopy(lc);
113         
114         setlocale(LC_CTYPE, "C");
115         
116         fs=XCreateFontSet(ioncore_g.dpy, fontname, &missing, &nmissing, &def);
117         
118         if(lcc!=NULL){
119             setlocale(LC_CTYPE, lcc);
120             free(lcc);
121         }
122     }
123
124 #ifndef CF_NO_FONTSET_KLUDGE    
125
126     if(fs){
127         XFontStruct **fontstructs;
128         char **fontnames;
129         XFontsOfFontSet(fs, &fontstructs, &fontnames);
130         nfontname=fontnames[0];
131     }
132
133     get_font_element(nfontname, weight, CF_FONT_ELEMENT_SIZE,
134                      "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
135     get_font_element(nfontname, slant, CF_FONT_ELEMENT_SIZE,
136                      "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
137     get_font_size(nfontname, &pixel_size);
138     
139     if(!strcmp(weight, "*"))
140         strncpy(weight, "medium", CF_FONT_ELEMENT_SIZE);
141     if(!strcmp(slant, "*"))
142         strncpy(slant, "r", CF_FONT_ELEMENT_SIZE);
143     if(pixel_size<3)
144         pixel_size=3;
145     else if(pixel_size>97)
146         pixel_size=97;
147     
148     if(ioncore_g.enc_utf8){
149         libtu_asprintf(&pattern2,
150                        "%s,"
151                        "-misc-fixed-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
152                        "-misc-fixed-*-*-*-*-%d-*-*-*-*-*-*-*",
153                        fontname, weight, slant, pixel_size, pixel_size);
154     }else{
155         libtu_asprintf(&pattern2,
156                        "%s,"
157                        "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
158                        "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*",
159                        fontname, weight, slant, pixel_size, pixel_size);
160     }
161     
162     if(pattern2==NULL)
163         return NULL;
164
165     FNT_D(fprintf(stderr, "NRQ: %s\n", pattern2));
166     
167     nfontname=pattern2;
168     
169     if(nmissing)
170         XFreeStringList(missing);
171     if(fs)
172         XFreeFontSet(ioncore_g.dpy, fs);
173
174     FNT_D(if(fs) fprintf(stderr, "Trying '%s'.\n", nfontname));
175     
176     fs=XCreateFontSet(ioncore_g.dpy, nfontname, &missing, &nmissing, &def);
177     
178     free(pattern2);
179     
180 #endif
181     
182     if(missing!=NULL) 
183         XFreeStringList(missing);
184
185     return fs;
186 }