]> git.decadent.org.uk Git - ion3.git/blob - de/fontset.c
Update cfg_kludge_flash for Flash 10
[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. 
7  *
8  * The original code was apparently written by Tomohiro Kubota; see
9  * <http://www.debian.org/doc/manuals/intro-i18n/ch-examples.en.html#s13.4.5>.
10  *
11  * However, the code that this file is based on, was taken from:
12  *
13  * Screen.cc for Blackbox - an X11 Window manager
14  * Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
15  * Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining a
18  * copy of this software and associated documentation files (the "Software"),
19  * to deal in the Software without restriction, including without limitation
20  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21  * and/or sell copies of the Software, and to permit persons to whom the
22  * Software is furnished to do so, subject to the following conditions:
23  *
24  * The above copyright notice and this permission notice shall be included in
25  * all copies or substantial portions of the Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33  * DEALINGS IN THE SOFTWARE.
34  */
35
36 #include <string.h>
37 #include <ctype.h>
38 #include <locale.h>
39
40 #include <ioncore/common.h>
41 #include <ioncore/global.h>
42
43 #ifndef CF_FONT_ELEMENT_SIZE
44 #define CF_FONT_ELEMENT_SIZE 50
45 #endif
46
47 #define FNT_D(X) /*X*/
48
49
50 static const char *get_font_element(const char *pattern, char *buf,
51                                     int bufsiz, ...) 
52 {
53     const char *p, *v;
54     char *p2;
55     va_list va;
56     
57     va_start(va, bufsiz);
58     buf[bufsiz-1]=0;
59     buf[bufsiz-2]='*';
60     while((v=va_arg(va, char *))!=NULL){
61         p=libtu_strcasestr(pattern, v);
62         if(p){
63             strncpy(buf, p+1, bufsiz-2);
64             p2=strchr(buf, '-');
65             if(p2) *p2=0;
66             va_end(va);
67             return p;
68         }
69     }
70     va_end(va);
71     strncpy(buf, "*", bufsiz);
72     return NULL;
73 }
74
75
76 static const char *get_font_size(const char *pattern, int *size) 
77 {
78     const char *p;
79     const char *p2=NULL;
80     int n=0;
81     
82     for(p=pattern; 1; p++){
83         if(!*p){
84             if(p2!=NULL && n>1 && n<72){
85                 *size=n; return p2+1;
86             }else{
87                 *size=16; return NULL;
88             }
89         }else if(*p=='-'){
90             if(n>1 && n<72 && p2!=NULL){
91                 *size=n;
92                 return p2+1;
93             }
94             p2=p; n=0;
95         }else if(*p>='0' && *p<='9' && p2!=NULL){
96             n*=10;
97             n+=*p-'0';
98         }else{
99             p2=NULL; n=0;
100         }
101     }
102 }
103
104
105 XFontSet de_create_font_set(const char *fontname) 
106 {
107     XFontSet fs;
108     char **missing=NULL, *def="-";
109     int nmissing, pixel_size=0;
110     char weight[CF_FONT_ELEMENT_SIZE], slant[CF_FONT_ELEMENT_SIZE];
111     const char *nfontname=fontname;
112     char *pattern2=NULL;
113     int i;
114     
115     FNT_D(fprintf(stderr, "FNTRQ: %s\n", fontname));
116     
117     fs=XCreateFontSet(ioncore_g.dpy, fontname, &missing, &nmissing, &def);
118
119     if(fs && nmissing==0){
120         if(missing!=NULL) 
121             XFreeStringList(missing);
122         return fs;
123     }
124     
125     /* Not a warning, nothing serious */
126     FNT_D(fprintf(stderr, "Failed to load fontset.\n"));
127     
128     if(!fs){
129         char *lcc=NULL;
130         const char *lc;
131         if(missing!=NULL)
132             XFreeStringList(missing);
133         
134         lc=setlocale(LC_CTYPE, NULL);
135         if(lc!=NULL && strcmp(lc, "POSIX")!=0 && strcmp(lc, "C")!=0)
136             lcc=scopy(lc);
137         
138         setlocale(LC_CTYPE, "C");
139         
140         fs=XCreateFontSet(ioncore_g.dpy, fontname, &missing, &nmissing, &def);
141         
142         if(lcc!=NULL){
143             setlocale(LC_CTYPE, lcc);
144             free(lcc);
145         }
146     }
147
148 #ifndef CF_NO_FONTSET_KLUDGE    
149
150     if(fs){
151         XFontStruct **fontstructs;
152         char **fontnames;
153         XFontsOfFontSet(fs, &fontstructs, &fontnames);
154         nfontname=fontnames[0];
155     }
156
157     get_font_element(nfontname, weight, CF_FONT_ELEMENT_SIZE,
158                      "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
159     get_font_element(nfontname, slant, CF_FONT_ELEMENT_SIZE,
160                      "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
161     get_font_size(nfontname, &pixel_size);
162     
163     if(!strcmp(weight, "*"))
164         strncpy(weight, "medium", CF_FONT_ELEMENT_SIZE);
165     if(!strcmp(slant, "*"))
166         strncpy(slant, "r", CF_FONT_ELEMENT_SIZE);
167     if(pixel_size<3)
168         pixel_size=3;
169     else if(pixel_size>97)
170         pixel_size=97;
171     
172     if(ioncore_g.enc_utf8){
173         libtu_asprintf(&pattern2,
174                        "%s,"
175                        "-misc-fixed-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
176                        "-misc-fixed-*-*-*-*-%d-*-*-*-*-*-*-*",
177                        fontname, weight, slant, pixel_size, pixel_size);
178     }else{
179         libtu_asprintf(&pattern2,
180                        "%s,"
181                        "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
182                        "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*",
183                        fontname, weight, slant, pixel_size, pixel_size);
184     }
185     
186     if(pattern2==NULL)
187         return NULL;
188
189     FNT_D(fprintf(stderr, "NRQ: %s\n", pattern2));
190     
191     nfontname=pattern2;
192     
193     if(nmissing)
194         XFreeStringList(missing);
195     if(fs)
196         XFreeFontSet(ioncore_g.dpy, fs);
197
198     FNT_D(if(fs) fprintf(stderr, "Trying '%s'.\n", nfontname));
199     
200     fs=XCreateFontSet(ioncore_g.dpy, nfontname, &missing, &nmissing, &def);
201     
202     free(pattern2);
203     
204 #endif
205     
206     if(missing!=NULL) 
207         XFreeStringList(missing);
208
209     return fs;
210 }