1 /*
2  * XFontName.c
3  *
4  * build/parse X Font name strings
5  */
6 
7 # include	<X11/Xlib.h>
8 # include	<X11/Intrinsic.h>
9 # include	"XFontName.h"
10 #include	<ctype.h>
11 
12 static char *
extractStringField(char * name,char * buffer,int size,unsigned int * attrp,unsigned int bit)13 extractStringField (
14 	char		*name,
15 	char		*buffer,
16 	int		size,
17 	unsigned int	*attrp,
18 	unsigned int	bit)
19 {
20 	char	*buf = buffer;
21 
22 	if (!*name)
23 		return NULL;
24 	while (*name && *name != '-' && size > 0) {
25 		*buf++ = *name++;
26 		--size;
27 	}
28 	if (size <= 0)
29 		return NULL;
30 	*buf = '\0';
31 	if (buffer[0] != '*' || buffer[1] != '\0')
32 		*attrp |= bit;
33 	if (*name == '-')
34 		return name+1;
35 	return name;
36 }
37 
38 static char *
extractUnsignedField(char * name,unsigned int * result,unsigned int * attrp,unsigned int bit)39 extractUnsignedField (
40 	char		*name,
41 	unsigned int	*result,
42 	unsigned int	*attrp,
43 	unsigned int	bit)
44 {
45 	char		buf[256];
46 	char		*c;
47 	unsigned int	i;
48 
49 	name = extractStringField (name, buf, sizeof (buf), attrp, bit);
50 	if (!name)
51 		return NULL;
52 	if (!(*attrp & bit))
53 		return name;
54 	i = 0;
55 	for (c = buf; *c; c++) {
56 		if (!isdigit (*c))
57 			return NULL;
58 		i = i * 10 + (*c - '0');
59 	}
60 	*result = i;
61 	return name;
62 }
63 
64 Bool
XParseFontName(XFontNameString fontNameString,XFontName * fontName,unsigned int * fontNameAttributes)65 XParseFontName (XFontNameString fontNameString, XFontName *fontName,
66 		unsigned int *fontNameAttributes)
67 {
68 	char		*name = fontNameString;
69 	XFontName	temp;
70 	unsigned int	attributes = 0;
71 
72 #define GetString(field,bit)\
73 	if (!(name = extractStringField \
74 		(name, temp.field, sizeof (temp.field),\
75 		&attributes, bit))) \
76 		return False;
77 
78 #define GetUnsigned(field,bit)\
79 	if (!(name = extractUnsignedField \
80 		(name, &temp.field, \
81 		&attributes, bit))) \
82 		return False;
83 
84 	GetString (Registry, FontNameRegistry)
85 	GetString (Foundry, FontNameFoundry)
86 	GetString (FamilyName, FontNameFamilyName)
87 	GetString (WeightName, FontNameWeightName)
88 	GetString (Slant, FontNameSlant)
89 	GetString (SetwidthName, FontNameSetwidthName)
90 	GetString (AddStyleName, FontNameAddStyleName)
91 	GetUnsigned (PixelSize, FontNamePixelSize)
92 	GetUnsigned (PointSize, FontNamePointSize)
93 	GetUnsigned (ResolutionX, FontNameResolutionX)
94 	GetUnsigned (ResolutionY, FontNameResolutionY)
95 	GetString (Spacing, FontNameSpacing)
96 	GetUnsigned (AverageWidth, FontNameAverageWidth)
97 	GetString (CharSetRegistry, FontNameCharSetRegistry)
98 	if (!*name) {
99 		temp.CharSetEncoding[0] = '\0';
100 		attributes |= FontNameCharSetEncoding;
101 	} else {
102 		GetString (CharSetEncoding, FontNameCharSetEncoding)
103 	}
104 	*fontName = temp;
105 	*fontNameAttributes = attributes;
106 	return True;
107 }
108 
109 static char *
utoa(unsigned int u,char * s,int size)110 utoa (
111 	unsigned int	u,
112 	char		*s,
113 	int		size)
114 {
115 	char	*t;
116 
117 	t = s + size;
118 	*--t = '\0';
119 	do
120 		*--t = (u % 10) + '0';
121 	while (u /= 10);
122 	return t;
123 }
124 
125 Bool
XFormatFontName(XFontName * fontName,unsigned int fontNameAttributes,XFontNameString fontNameString)126 XFormatFontName (XFontName *fontName, unsigned int fontNameAttributes,
127 		 XFontNameString fontNameString)
128 {
129 	XFontNameString	tmp;
130 	char		*name = tmp;
131 	const char	*f;
132 	int		left = sizeof (tmp) - 1;
133 	char		number[32];
134 
135 #define PutString(field, bit)\
136 	f = (fontNameAttributes & bit) ? \
137 		fontName->field \
138 		: "*"; \
139 	if ((left -= strlen (f)) < 0) \
140 		return False; \
141 	while (*f) \
142 		if ((*name++ = *f++) == '-') \
143 			return False;
144 #define PutHyphen()\
145 	if (--left < 0) \
146 		return False; \
147 	*name++ = '-';
148 
149 #define PutUnsigned(field, bit) \
150 	f = (fontNameAttributes & bit) ? \
151 		utoa (fontName->field, number, sizeof (number)) \
152 		: "*"; \
153 	if ((left -= strlen (f)) < 0) \
154 		return False; \
155 	while (*f) \
156 		*name++ = *f++;
157 
158 	PutString (Registry, FontNameRegistry)
159 	PutHyphen ();
160 	PutString (Foundry, FontNameFoundry)
161 	PutHyphen ();
162 	PutString (FamilyName, FontNameFamilyName)
163 	PutHyphen ();
164 	PutString (WeightName, FontNameWeightName)
165 	PutHyphen ();
166 	PutString (Slant, FontNameSlant)
167 	PutHyphen ();
168 	PutString (SetwidthName, FontNameSetwidthName)
169 	PutHyphen ();
170 	PutString (AddStyleName, FontNameAddStyleName)
171 	PutHyphen ();
172 	PutUnsigned (PixelSize, FontNamePixelSize)
173 	PutHyphen ();
174 	PutUnsigned (PointSize, FontNamePointSize)
175 	PutHyphen ();
176 	PutUnsigned (ResolutionX, FontNameResolutionX)
177 	PutHyphen ();
178 	PutUnsigned (ResolutionY, FontNameResolutionY)
179 	PutHyphen ();
180 	PutString (Spacing, FontNameSpacing)
181 	PutHyphen ();
182 	PutUnsigned (AverageWidth, FontNameAverageWidth)
183 	PutHyphen ();
184 	PutString (CharSetRegistry, FontNameCharSetRegistry)
185 	PutHyphen ();
186 	PutString (CharSetEncoding, FontNameCharSetEncoding)
187 	*name = '\0';
188 	strcpy (fontNameString, tmp);
189 	return True;
190 }
191