Add a travis build definition for building without XFT
[notion.git] / de / fontset.c
blobfaf68723ae78991e203ff4be1448b85cb24ef9ac
1 /*
2 * notion/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.
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>.
11 * However, the code that this file is based on, was taken from:
13 * Copyright (c) 2013 - the Notion team
14 * Screen.cc for Blackbox - an X11 Window manager
15 * Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
16 * Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
18 * Permission is hereby granted, free of charge, to any person obtaining a
19 * copy of this software and associated documentation files (the "Software"),
20 * to deal in the Software without restriction, including without limitation
21 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
22 * and/or sell copies of the Software, and to permit persons to whom the
23 * Software is furnished to do so, subject to the following conditions:
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
31 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 * DEALINGS IN THE SOFTWARE.
37 #include <string.h>
38 #include <ctype.h>
39 #include <locale.h>
41 #include <ioncore/common.h>
42 #include <ioncore/global.h>
43 #include <ioncore/log.h>
45 #ifndef CF_FONT_ELEMENT_SIZE
46 #define CF_FONT_ELEMENT_SIZE 50
47 #endif
49 static const char *get_font_element(const char *pattern, char *buf,
50 int bufsiz, ...)
52 const char *p, *v;
53 char *p2;
54 va_list va;
56 va_start(va, bufsiz);
57 buf[bufsiz-1]=0;
58 buf[bufsiz-2]='*';
59 while((v=va_arg(va, char *))!=NULL){
60 p=libtu_strcasestr(pattern, v);
61 if(p){
62 strncpy(buf, p+1, bufsiz-2);
63 p2=strchr(buf, '-');
64 if(p2) *p2=0;
65 va_end(va);
66 return p;
69 va_end(va);
70 strncpy(buf, "*", bufsiz);
71 return NULL;
75 static const char *get_font_size(const char *pattern, int *size)
77 const char *p;
78 const char *p2=NULL;
79 int n=0;
81 for(p=pattern; 1; p++){
82 if(!*p){
83 if(p2!=NULL && n>1 && n<72){
84 *size=n; return p2+1;
85 }else{
86 *size=16; return NULL;
88 }else if(*p=='-'){
89 if(n>1 && n<72 && p2!=NULL){
90 *size=n;
91 return p2+1;
93 p2=p; n=0;
94 }else if(*p>='0' && *p<='9' && p2!=NULL){
95 n*=10;
96 n+=*p-'0';
97 }else{
98 p2=NULL; n=0;
103 XFontSet de_create_font_in_current_locale(const char *fontname)
105 XFontSet fs;
106 char **missing=NULL, *def="-";
107 int nmissing=0;
109 LOG(DEBUG, FONT, "Creating fontset for: %s", fontname);
111 fs=XCreateFontSet(ioncore_g.dpy, fontname, &missing, &nmissing, &def);
113 if(fs){
114 if(nmissing==0)
115 LOG(DEBUG, FONT, "Found a font without missing charsets for %s, returning it.", fontname);
116 else {
117 int i;
118 LOG(INFO, FONT, "Found a font with %d missing charsets for %s:", nmissing, fontname);
119 for(i=0;i<nmissing;i++)
120 LOG(DEBUG, FONT, "* %s", missing[i]);
122 }else{
123 LOG(WARN, FONT, "Found no font for %s.", fontname);
126 if(missing!=NULL)
127 XFreeStringList(missing);
129 return fs;
132 XFontSet de_create_font_in_c_locale(const char *fontname)
134 XFontSet fs;
135 char *lcc=NULL;
136 const char *lc;
138 LOG(DEBUG, FONT, "Trying to load %s with the C locale.", fontname);
140 lc=setlocale(LC_CTYPE, NULL);
141 if(lc!=NULL && strcmp(lc, "POSIX")!=0 && strcmp(lc, "C")!=0)
142 lcc=scopy(lc);
144 setlocale(LC_CTYPE, "C");
146 fs=de_create_font_in_current_locale(fontname);
148 if(lcc!=NULL){
149 setlocale(LC_CTYPE, lcc);
150 free(lcc);
153 return fs;
157 XFontSet de_create_font_kludged(const char *fontname)
159 XFontSet fs = NULL;
160 #ifndef CF_NO_FONTSET_KLUDGE
161 char *pattern2=NULL;
162 char weight[CF_FONT_ELEMENT_SIZE], slant[CF_FONT_ELEMENT_SIZE];
163 int pixel_size=0;
165 LOG(DEBUG, FONT, "Doing the fontset_kludge with fontname %s.", fontname);
167 get_font_element(fontname, weight, CF_FONT_ELEMENT_SIZE,
168 "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
169 get_font_element(fontname, slant, CF_FONT_ELEMENT_SIZE,
170 "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
171 get_font_size(fontname, &pixel_size);
173 if(!strcmp(weight, "*"))
174 strncpy(weight, "medium", CF_FONT_ELEMENT_SIZE);
175 if(!strcmp(slant, "*"))
176 strncpy(slant, "r", CF_FONT_ELEMENT_SIZE);
177 if(pixel_size<3)
178 pixel_size=3;
179 else if(pixel_size>97)
180 pixel_size=97;
182 if(ioncore_g.enc_utf8){
183 libtu_asprintf(&pattern2,
184 "%s,"
185 "-misc-fixed-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
186 "-misc-fixed-*-*-*-*-%d-*-*-*-*-*-*-*",
187 fontname, weight, slant, pixel_size, pixel_size);
188 }else{
189 libtu_asprintf(&pattern2,
190 "%s,"
191 "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
192 "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*",
193 fontname, weight, slant, pixel_size, pixel_size);
196 if(pattern2!=NULL){
197 LOG(DEBUG, FONT, "no_fontset_kludge resulted in fontname %s", pattern2);
199 fs = de_create_font_in_current_locale(pattern2);
201 free(pattern2);
204 #endif
205 return fs;
208 XFontSet de_create_font_set(const char *fontname)
210 XFontSet fs=de_create_font_in_current_locale(fontname);
212 if (fs)
213 return fs;
215 fs=de_create_font_in_c_locale(fontname);
217 if (fs)
218 return fs;
220 fs = de_create_font_kludged(fontname);
222 if (fs)
223 return fs;
225 /* The final fallback... */
226 warn(TR("Could not load font %s"), fontname);
227 return de_create_font_in_current_locale("-*-*-*-*-*-*-*-*-*-*-*-*-*-*");