1f80a6dcdSmrg/*
2f80a6dcdSmrg * XFontName.c
3f80a6dcdSmrg *
4f80a6dcdSmrg * build/parse X Font name strings
5f80a6dcdSmrg */
600994698Smrg#ifdef HAVE_CONFIG_H
700994698Smrg# include "config.h"
800994698Smrg#endif
9f80a6dcdSmrg
1000994698Smrg#include	<X11/Xlib.h>
1100994698Smrg#include	<X11/Intrinsic.h>
1200994698Smrg#include	"XFontName.h"
13f80a6dcdSmrg#include	<ctype.h>
14f80a6dcdSmrg
1500994698Smrgstatic const char *
1600994698SmrgextractStringField(const char *name, char *buffer, int size,
1700994698Smrg                   unsigned int *attrp, unsigned int bit)
18f80a6dcdSmrg{
1900994698Smrg    char *buf = buffer;
2000994698Smrg
2100994698Smrg    if (!*name)
2200994698Smrg        return NULL;
2300994698Smrg    while (*name && *name != '-' && size > 0) {
2400994698Smrg        *buf++ = *name++;
2500994698Smrg        --size;
2600994698Smrg    }
2700994698Smrg    if (size <= 0)
2800994698Smrg        return NULL;
2900994698Smrg    *buf = '\0';
3000994698Smrg    if (buffer[0] != '*' || buffer[1] != '\0')
3100994698Smrg        *attrp |= bit;
3200994698Smrg    if (*name == '-')
3300994698Smrg        return name + 1;
3400994698Smrg    return name;
35f80a6dcdSmrg}
36f80a6dcdSmrg
3700994698Smrgstatic const char *
3800994698SmrgextractUnsignedField(const char *name, unsigned int *result,
3900994698Smrg                     unsigned int *attrp, unsigned int bit)
40f80a6dcdSmrg{
4100994698Smrg    char buf[256];
4200994698Smrg    unsigned int i;
4300994698Smrg
4400994698Smrg    name = extractStringField(name, buf, sizeof(buf), attrp, bit);
4500994698Smrg    if (!name)
4600994698Smrg        return NULL;
4700994698Smrg    if (!(*attrp & bit))
4800994698Smrg        return name;
4900994698Smrg    i = 0;
5000994698Smrg    for (char *c = buf; *c; c++) {
5100994698Smrg        if (!isdigit(*c))
5200994698Smrg            return NULL;
5300994698Smrg        i = i * 10 + (*c - '0');
5400994698Smrg    }
5500994698Smrg    *result = i;
5600994698Smrg    return name;
57f80a6dcdSmrg}
58f80a6dcdSmrg
59f80a6dcdSmrgBool
6000994698SmrgXParseFontName(const char *fontNameString, XFontName *fontName,
6100994698Smrg               unsigned int *fontNameAttributes)
62f80a6dcdSmrg{
6300994698Smrg    const char *name = fontNameString;
6400994698Smrg    XFontName temp;
6500994698Smrg    unsigned int attributes = 0;
66f80a6dcdSmrg
6700994698Smrg#define GetString(field,bit)  do { \
68f80a6dcdSmrg	if (!(name = extractStringField \
69f80a6dcdSmrg		(name, temp.field, sizeof (temp.field),\
70f80a6dcdSmrg		&attributes, bit))) \
7100994698Smrg		return False; \
7200994698Smrg    } while(0)
73f80a6dcdSmrg
7400994698Smrg#define GetUnsigned(field,bit)  do { \
75f80a6dcdSmrg	if (!(name = extractUnsignedField \
76f80a6dcdSmrg		(name, &temp.field, \
77f80a6dcdSmrg		&attributes, bit))) \
7800994698Smrg		return False; \
7900994698Smrg    } while(0)
8000994698Smrg
8100994698Smrg    GetString(Registry, FontNameRegistry);
8200994698Smrg    GetString(Foundry, FontNameFoundry);
8300994698Smrg    GetString(FamilyName, FontNameFamilyName);
8400994698Smrg    GetString(WeightName, FontNameWeightName);
8500994698Smrg    GetString(Slant, FontNameSlant);
8600994698Smrg    GetString(SetwidthName, FontNameSetwidthName);
8700994698Smrg    GetString(AddStyleName, FontNameAddStyleName);
8800994698Smrg    GetUnsigned(PixelSize, FontNamePixelSize);
8900994698Smrg    GetUnsigned(PointSize, FontNamePointSize);
9000994698Smrg    GetUnsigned(ResolutionX, FontNameResolutionX);
9100994698Smrg    GetUnsigned(ResolutionY, FontNameResolutionY);
9200994698Smrg    GetString(Spacing, FontNameSpacing);
9300994698Smrg    GetUnsigned(AverageWidth, FontNameAverageWidth);
9400994698Smrg    GetString(CharSetRegistry, FontNameCharSetRegistry);
9500994698Smrg    if (!*name) {
9600994698Smrg        temp.CharSetEncoding[0] = '\0';
9700994698Smrg        attributes |= FontNameCharSetEncoding;
9800994698Smrg    }
9900994698Smrg    else {
10000994698Smrg        GetString(CharSetEncoding, FontNameCharSetEncoding);
10100994698Smrg    }
10200994698Smrg    *fontName = temp;
10300994698Smrg    *fontNameAttributes = attributes;
10400994698Smrg    return True;
105f80a6dcdSmrg}
106f80a6dcdSmrg
107f80a6dcdSmrgstatic char *
10800994698Smrgutoa(unsigned int u, char *s, int size)
109f80a6dcdSmrg{
11000994698Smrg    char *t;
11100994698Smrg
11200994698Smrg    t = s + size;
11300994698Smrg    *--t = '\0';
11400994698Smrg    do
11500994698Smrg        *--t = (u % 10) + '0';
11600994698Smrg    while (u /= 10);
11700994698Smrg    return t;
118f80a6dcdSmrg}
119f80a6dcdSmrg
120f80a6dcdSmrgBool
12100994698SmrgXFormatFontName(XFontName *fontName, unsigned int fontNameAttributes,
12200994698Smrg                XFontNameString fontNameString)
123f80a6dcdSmrg{
12400994698Smrg    XFontNameString tmp;
12500994698Smrg    char *name = tmp;
12600994698Smrg    const char *f;
12700994698Smrg    int left = sizeof(tmp) - 1;
12800994698Smrg    char number[32];
129f80a6dcdSmrg
13000994698Smrg#define PutString(field, bit) do { \
131f80a6dcdSmrg	f = (fontNameAttributes & bit) ? \
132f80a6dcdSmrg		fontName->field \
133f80a6dcdSmrg		: "*"; \
134f80a6dcdSmrg	if ((left -= strlen (f)) < 0) \
135f80a6dcdSmrg		return False; \
136f80a6dcdSmrg	while (*f) \
137f80a6dcdSmrg		if ((*name++ = *f++) == '-') \
13800994698Smrg			return False; \
13900994698Smrg    } while(0)
14000994698Smrg
14100994698Smrg#define PutHyphen() do { \
142f80a6dcdSmrg	if (--left < 0) \
143f80a6dcdSmrg		return False; \
14400994698Smrg	*name++ = '-'; \
14500994698Smrg    } while(0)
146f80a6dcdSmrg
14700994698Smrg#define PutUnsigned(field, bit) do { \
148f80a6dcdSmrg	f = (fontNameAttributes & bit) ? \
149f80a6dcdSmrg		utoa (fontName->field, number, sizeof (number)) \
150f80a6dcdSmrg		: "*"; \
151f80a6dcdSmrg	if ((left -= strlen (f)) < 0) \
152f80a6dcdSmrg		return False; \
153f80a6dcdSmrg	while (*f) \
15400994698Smrg		*name++ = *f++; \
15500994698Smrg    } while(0)
15600994698Smrg
15700994698Smrg    PutString(Registry, FontNameRegistry);
15800994698Smrg    PutHyphen();
15900994698Smrg    PutString(Foundry, FontNameFoundry);
16000994698Smrg    PutHyphen();
16100994698Smrg    PutString(FamilyName, FontNameFamilyName);
16200994698Smrg    PutHyphen();
16300994698Smrg    PutString(WeightName, FontNameWeightName);
16400994698Smrg    PutHyphen();
16500994698Smrg    PutString(Slant, FontNameSlant);
16600994698Smrg    PutHyphen();
16700994698Smrg    PutString(SetwidthName, FontNameSetwidthName);
16800994698Smrg    PutHyphen();
16900994698Smrg    PutString(AddStyleName, FontNameAddStyleName);
17000994698Smrg    PutHyphen();
17100994698Smrg    PutUnsigned(PixelSize, FontNamePixelSize);
17200994698Smrg    PutHyphen();
17300994698Smrg    PutUnsigned(PointSize, FontNamePointSize);
17400994698Smrg    PutHyphen();
17500994698Smrg    PutUnsigned(ResolutionX, FontNameResolutionX);
17600994698Smrg    PutHyphen();
17700994698Smrg    PutUnsigned(ResolutionY, FontNameResolutionY);
17800994698Smrg    PutHyphen();
17900994698Smrg    PutString(Spacing, FontNameSpacing);
18000994698Smrg    PutHyphen();
18100994698Smrg    PutUnsigned(AverageWidth, FontNameAverageWidth);
18200994698Smrg    PutHyphen();
18300994698Smrg    PutString(CharSetRegistry, FontNameCharSetRegistry);
18400994698Smrg    PutHyphen();
18500994698Smrg    PutString(CharSetEncoding, FontNameCharSetEncoding);
18600994698Smrg    *name = '\0';
18700994698Smrg    strncpy (fontNameString, tmp, sizeof(XFontNameString));
18800994698Smrg    fontNameString[sizeof(XFontNameString) - 1] = '\0';
18900994698Smrg    return True;
190f80a6dcdSmrg}
191