d3c509b6f3811bef18a3bc310f1404c57e27879a
[platform/upstream/groff.git] / src / libs / libxutil / XFontName.c
1 /* Copyright (C) 2014  Free Software Foundation, Inc.
2
3 This file is part of groff.
4
5 groff is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 groff is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 for more details.
14
15 The GNU General Public License version 2 (GPL2) is available in the
16 internet at <http://www.gnu.org/licenses/gpl-2.0.txt>. */
17
18 /*
19  * XFontName.c
20  *
21  * build/parse X Font name strings
22  */
23
24 #include <X11/Xlib.h>
25 #include <X11/Xos.h>
26 #include "XFontName.h"
27 #include <ctype.h>
28
29 static char *
30 extractStringField (char *name, char *buffer, int size,
31                     unsigned int *attrp, unsigned int bit)
32 {
33         char    *buf = buffer;
34
35         if (!*name)
36                 return 0;
37         while (*name && *name != '-' && size > 0) {
38                 *buf++ = *name++;
39                 --size;
40         }
41         if (size <= 0)
42                 return 0;
43         *buf = '\0';
44         if (buffer[0] != '*' || buffer[1] != '\0')
45                 *attrp |= bit;
46         if (*name == '-')
47                 return name+1;
48         return name;
49 }
50
51 static char *
52 extractUnsignedField (char *name, unsigned int *result,
53                       unsigned int *attrp, unsigned int bit)
54 {
55         char            buf[256];
56         char            *c;
57         unsigned int    i;
58
59         name = extractStringField (name, buf, sizeof (buf), attrp, bit);
60         if (!name)
61                 return 0;
62         if (!(*attrp & bit))
63                 return name;
64         i = 0;
65         for (c = buf; *c; c++) {
66                 if (!isdigit (*c))
67                         return 0;
68                 i = i * 10 + (*c - '0');
69         }
70         *result = i;
71         return name;
72 }
73
74 Bool
75 XParseFontName (XFontNameString fontNameString, XFontName *fontName,
76                 unsigned int *fontNameAttributes)
77 {
78         char            *name = fontNameString;
79         XFontName       temp;
80         unsigned int    attributes = 0;
81
82 #define GetString(field,bit)\
83         if (!(name = extractStringField \
84                 (name, temp.field, sizeof (temp.field),\
85                 &attributes, bit))) \
86                 return False;
87
88 #define GetUnsigned(field,bit)\
89         if (!(name = extractUnsignedField \
90                 (name, &temp.field, \
91                 &attributes, bit))) \
92                 return False;
93
94         GetString (Registry, FontNameRegistry)
95         GetString (Foundry, FontNameFoundry)
96         GetString (FamilyName, FontNameFamilyName)
97         GetString (WeightName, FontNameWeightName)
98         GetString (Slant, FontNameSlant)
99         GetString (SetwidthName, FontNameSetwidthName)
100         GetString (AddStyleName, FontNameAddStyleName)
101         GetUnsigned (PixelSize, FontNamePixelSize)
102         GetUnsigned (PointSize, FontNamePointSize)
103         GetUnsigned (ResolutionX, FontNameResolutionX)
104         GetUnsigned (ResolutionY, FontNameResolutionY)
105         GetString (Spacing, FontNameSpacing)
106         GetUnsigned (AverageWidth, FontNameAverageWidth)
107         GetString (CharSetRegistry, FontNameCharSetRegistry)
108         if (!*name) {
109                 temp.CharSetEncoding[0] = '\0';
110                 attributes |= FontNameCharSetEncoding;
111         } else {
112                 GetString (CharSetEncoding, FontNameCharSetEncoding)
113         }
114         *fontName = temp;
115         *fontNameAttributes = attributes;
116         return True;
117 }
118
119 static char *
120 utoa (unsigned int u, char *s, int size)
121 {
122         char    *t;
123
124         t = s + size;
125         *--t = '\0';
126         do
127                 *--t = (u % 10) + '0';
128         while (u /= 10);
129         return t;
130 }
131
132 Bool
133 XFormatFontName (XFontName *fontName, unsigned int fontNameAttributes,
134                  XFontNameString fontNameString)
135 {
136         char            tmp[256];
137         char            *name = tmp, *f;
138         int             left = sizeof (tmp) - 1;
139         char            number[32];
140
141 #define PutString(field, bit)\
142         f = (fontNameAttributes & bit) ? \
143                 fontName->field \
144                 : (char *)"*"; \
145         if ((left -= strlen (f)) < 0) \
146                 return False; \
147         while (*f) \
148                 if ((*name++ = *f++) == '-') \
149                         return False; 
150 #define PutHyphen()\
151         if (--left < 0) \
152                 return False; \
153         *name++ = '-';
154
155 #define PutUnsigned(field, bit) \
156         f = (fontNameAttributes & bit) ? \
157                 utoa (fontName->field, number, sizeof (number)) \
158                 : (char *)"*"; \
159         if ((left -= strlen (f)) < 0) \
160                 return False; \
161         while (*f) \
162                 *name++ = *f++;
163
164         PutString (Registry, FontNameRegistry)
165         PutHyphen ();
166         PutString (Foundry, FontNameFoundry)
167         PutHyphen ();
168         PutString (FamilyName, FontNameFamilyName)
169         PutHyphen ();
170         PutString (WeightName, FontNameWeightName)
171         PutHyphen ();
172         PutString (Slant, FontNameSlant)
173         PutHyphen ();
174         PutString (SetwidthName, FontNameSetwidthName)
175         PutHyphen ();
176         PutString (AddStyleName, FontNameAddStyleName)
177         PutHyphen ();
178         PutUnsigned (PixelSize, FontNamePixelSize)
179         PutHyphen ();
180         PutUnsigned (PointSize, FontNamePointSize)
181         PutHyphen ();
182         PutUnsigned (ResolutionX, FontNameResolutionX)
183         PutHyphen ();
184         PutUnsigned (ResolutionY, FontNameResolutionY)
185         PutHyphen ();
186         PutString (Spacing, FontNameSpacing)
187         PutHyphen ();
188         PutUnsigned (AverageWidth, FontNameAverageWidth)
189         PutHyphen ();
190         PutString (CharSetRegistry, FontNameCharSetRegistry)
191         PutHyphen ();
192         PutString (CharSetEncoding, FontNameCharSetEncoding)
193         *name = '\0';
194         strcpy (fontNameString, tmp);
195         return True;
196 }
197
198 Bool
199 XCompareFontName (XFontName *name1, XFontName *name2,
200                   unsigned int fontNameAttributes)
201 {
202 #define CompareString(field,bit) \
203         if (fontNameAttributes & bit) \
204                 if (strcmp (name1->field, name2->field)) \
205                         return False;
206
207 #define CompareUnsigned(field,bit) \
208         if (fontNameAttributes & bit) \
209                 if (name1->field != name2->field) \
210                         return False;
211
212         CompareString (Registry, FontNameRegistry)
213         CompareString (Foundry, FontNameFoundry)
214         CompareString (FamilyName, FontNameFamilyName)
215         CompareString (WeightName, FontNameWeightName)
216         CompareString (Slant, FontNameSlant)
217         CompareString (SetwidthName, FontNameSetwidthName)
218         CompareString (AddStyleName, FontNameAddStyleName)
219         CompareUnsigned (PixelSize, FontNamePixelSize)
220         CompareUnsigned (PointSize, FontNamePointSize)
221         CompareUnsigned (ResolutionX, FontNameResolutionX)
222         CompareUnsigned (ResolutionY, FontNameResolutionY)
223         CompareString (Spacing, FontNameSpacing)
224         CompareUnsigned (AverageWidth, FontNameAverageWidth)
225         CompareString (CharSetRegistry, FontNameCharSetRegistry)
226         CompareString (CharSetEncoding, FontNameCharSetEncoding)
227         return True;
228 }
229
230 Bool
231 XCopyFontName (XFontName *name1, XFontName *name2,
232                unsigned int fontNameAttributes)
233 {
234 #define CopyString(field,bit) \
235         if (fontNameAttributes & bit) \
236                 strcpy (name2->field, name1->field);
237
238 #define CopyUnsigned(field,bit) \
239         if (fontNameAttributes & bit) \
240                 name2->field = name1->field;
241
242         CopyString (Registry, FontNameRegistry)
243         CopyString (Foundry, FontNameFoundry)
244         CopyString (FamilyName, FontNameFamilyName)
245         CopyString (WeightName, FontNameWeightName)
246         CopyString (Slant, FontNameSlant)
247         CopyString (SetwidthName, FontNameSetwidthName)
248         CopyString (AddStyleName, FontNameAddStyleName)
249         CopyUnsigned (PixelSize, FontNamePixelSize)
250         CopyUnsigned (PointSize, FontNamePointSize)
251         CopyUnsigned (ResolutionX, FontNameResolutionX)
252         CopyUnsigned (ResolutionY, FontNameResolutionY)
253         CopyString (Spacing, FontNameSpacing)
254         CopyUnsigned (AverageWidth, FontNameAverageWidth)
255         CopyString (CharSetRegistry, FontNameCharSetRegistry)
256         CopyString (CharSetEncoding, FontNameCharSetEncoding)
257         return True;
258 }