Ensure weight/slant values present even when style is supplied (bug 9313).
[platform/upstream/fontconfig.git] / src / fcdefault.c
1 /*
2  * $RCSId: xc/lib/fontconfig/src/fcdefault.c,v 1.2 2002/07/09 22:08:14 keithp Exp $
3  *
4  * Copyright © 2001 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of Keith Packard not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  Keith Packard makes no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include "fcint.h"
26 #include <locale.h>
27
28 static const struct {
29     FcObject    field;
30     FcBool      value;
31 } FcBoolDefaults[] = {
32     { FC_HINTING_OBJECT,           FcTrue       },  /* !FT_LOAD_NO_HINTING */
33     { FC_VERTICAL_LAYOUT_OBJECT,   FcFalse      },  /* FC_LOAD_VERTICAL_LAYOUT */
34     { FC_AUTOHINT_OBJECT,          FcFalse      },  /* FC_LOAD_FORCE_AUTOHINT */
35     { FC_GLOBAL_ADVANCE_OBJECT,    FcTrue       },  /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
36     { FC_EMBEDDED_BITMAP_OBJECT,   FcTrue       },  /* !FC_LOAD_NO_BITMAP */
37     { FC_DECORATIVE_OBJECT,        FcFalse      },
38 };
39
40 #define NUM_FC_BOOL_DEFAULTS    (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
41
42 FcChar8 *
43 FcGetDefaultLang (void)
44 {
45     static char lang_local [128] = {0};
46     char        *ctype;
47     char        *territory;
48     char        *after;
49     int         lang_len, territory_len;
50
51     if (lang_local [0])
52         return (FcChar8 *) lang_local;
53
54     ctype = setlocale (LC_CTYPE, NULL);
55
56     /*
57      * Check if setlocale (LC_ALL, "") has been called
58      */
59     if (!ctype || !strcmp (ctype, "C"))
60     {
61         ctype = getenv ("LC_ALL");
62         if (!ctype)
63         {
64             ctype = getenv ("LC_CTYPE");
65             if (!ctype)
66                 ctype = getenv ("LANG");
67         }
68     }
69
70     /* ignore missing or empty ctype */
71     if (ctype && *ctype != '\0')
72     {
73         territory = strchr (ctype, '_');
74         if (territory)
75         {
76             lang_len = territory - ctype;
77             territory = territory + 1;
78             after = strchr (territory, '.');
79             if (!after)
80             {
81                 after = strchr (territory, '@');
82                 if (!after)
83                     after = territory + strlen (territory);
84             }
85             territory_len = after - territory;
86             if (lang_len + 1 + territory_len + 1 <= (int) sizeof (lang_local))
87             {
88                 strncpy (lang_local, ctype, lang_len);
89                 lang_local[lang_len] = '-';
90                 strncpy (lang_local + lang_len + 1, territory, territory_len);
91                 lang_local[lang_len + 1 + territory_len] = '\0';
92             }
93         }
94         else
95         {
96             after = strchr (ctype, '.');
97             if (!after)
98             {
99                 after = strchr (ctype, '@');
100                 if (!after)
101                     after = ctype + strlen (ctype);
102             }
103             lang_len = after - ctype;
104             if (lang_len + 1 <= (int) sizeof (lang_local))
105             {
106                 strncpy (lang_local, ctype, lang_len);
107                 lang_local[lang_len] = '\0';
108             }
109         }
110     }
111
112     /* set default lang to en */
113     if (!lang_local [0])
114         strcpy (lang_local, "en");
115
116     return (FcChar8 *) lang_local;
117 }
118
119 void
120 FcDefaultSubstitute (FcPattern *pattern)
121 {
122     FcValue v;
123     int     i;
124
125     if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
126         FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM);
127
128     if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch)
129         FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN);
130
131     if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch)
132         FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL);
133
134     for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
135         if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
136             FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
137     
138     if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch)
139     {
140         double  dpi, size, scale;
141
142         if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
143         {
144             size = 12.0;
145             (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
146             FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
147         }
148         if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
149         {
150             scale = 1.0;
151             (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
152             FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
153         }
154         size *= scale;
155         if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
156         {
157             dpi = 75.0;
158             (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
159             FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
160         }
161         size *= dpi / 72.0;
162         FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
163     }
164
165     if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) == FcResultNoMatch)
166     {
167         FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang ());
168     }
169     if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
170     {
171         FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff);
172     }
173
174     if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
175     {
176         FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL);
177     }
178 }
179 #define __fcdefault__
180 #include "fcaliastail.h"
181 #undef __fcdefault__