xftxlfd.c revision c76ae52d
1c76ae52dSmrg/*
2c76ae52dSmrg * $Id: xftxlfd.c,v 1.1.1.1 2008/07/30 02:49:11 mrg Exp $
3c76ae52dSmrg *
4c76ae52dSmrg * Copyright © 2000 Keith Packard
5c76ae52dSmrg *
6c76ae52dSmrg * Permission to use, copy, modify, distribute, and sell this software and its
7c76ae52dSmrg * documentation for any purpose is hereby granted without fee, provided that
8c76ae52dSmrg * the above copyright notice appear in all copies and that both that
9c76ae52dSmrg * copyright notice and this permission notice appear in supporting
10c76ae52dSmrg * documentation, and that the name of Keith Packard not be used in
11c76ae52dSmrg * advertising or publicity pertaining to distribution of the software without
12c76ae52dSmrg * specific, written prior permission.  Keith Packard makes no
13c76ae52dSmrg * representations about the suitability of this software for any purpose.  It
14c76ae52dSmrg * is provided "as is" without express or implied warranty.
15c76ae52dSmrg *
16c76ae52dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17c76ae52dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18c76ae52dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19c76ae52dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20c76ae52dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21c76ae52dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22c76ae52dSmrg * PERFORMANCE OF THIS SOFTWARE.
23c76ae52dSmrg */
24c76ae52dSmrg
25c76ae52dSmrg#include "xftint.h"
26c76ae52dSmrg
27c76ae52dSmrgstatic XftSymbolic XftXlfdWeights[] = {
28c76ae52dSmrg    {	"light",    FC_WEIGHT_LIGHT	},
29c76ae52dSmrg    {	"medium",   FC_WEIGHT_MEDIUM	},
30c76ae52dSmrg    {	"regular",  FC_WEIGHT_MEDIUM	},
31c76ae52dSmrg    {	"demibold", FC_WEIGHT_DEMIBOLD },
32c76ae52dSmrg    {	"bold",	    FC_WEIGHT_BOLD	},
33c76ae52dSmrg    {	"black",    FC_WEIGHT_BLACK	},
34c76ae52dSmrg};
35c76ae52dSmrg
36c76ae52dSmrg#define NUM_XLFD_WEIGHTS    (sizeof XftXlfdWeights/sizeof XftXlfdWeights[0])
37c76ae52dSmrg
38c76ae52dSmrgstatic XftSymbolic XftXlfdSlants[] = {
39c76ae52dSmrg    {	"r",	    FC_SLANT_ROMAN	},
40c76ae52dSmrg    {	"i",	    FC_SLANT_ITALIC	},
41c76ae52dSmrg    {	"o",	    FC_SLANT_OBLIQUE	},
42c76ae52dSmrg};
43c76ae52dSmrg
44c76ae52dSmrg#define NUM_XLFD_SLANTS    (sizeof XftXlfdSlants/sizeof XftXlfdSlants[0])
45c76ae52dSmrg
46c76ae52dSmrg/*
47c76ae52dSmrg * Cut out one XLFD field, placing it in 'save' and return
48c76ae52dSmrg * the start of 'save'
49c76ae52dSmrg */
50c76ae52dSmrgstatic char *
51c76ae52dSmrgXftSplitStr (const char *field, char *save)
52c76ae52dSmrg{
53c76ae52dSmrg    char    *s = save;
54c76ae52dSmrg    char    c;
55c76ae52dSmrg
56c76ae52dSmrg    while (*field)
57c76ae52dSmrg    {
58c76ae52dSmrg	if (*field == '-')
59c76ae52dSmrg	    break;
60c76ae52dSmrg	c = *field++;
61c76ae52dSmrg	*save++ = c;
62c76ae52dSmrg    }
63c76ae52dSmrg    *save = 0;
64c76ae52dSmrg    return s;
65c76ae52dSmrg}
66c76ae52dSmrg
67c76ae52dSmrg/*
68c76ae52dSmrg * convert one XLFD numeric field.  Return -1 if the field is '*'
69c76ae52dSmrg */
70c76ae52dSmrg
71c76ae52dSmrgstatic const char *
72c76ae52dSmrgXftGetInt(const char *ptr, int *val)
73c76ae52dSmrg{
74c76ae52dSmrg    if (*ptr == '*') {
75c76ae52dSmrg	*val = -1;
76c76ae52dSmrg	ptr++;
77c76ae52dSmrg    } else
78c76ae52dSmrg	for (*val = 0; *ptr >= '0' && *ptr <= '9';)
79c76ae52dSmrg	    *val = *val * 10 + *ptr++ - '0';
80c76ae52dSmrg    if (*ptr == '-')
81c76ae52dSmrg	return ptr;
82c76ae52dSmrg    return (char *) 0;
83c76ae52dSmrg}
84c76ae52dSmrg
85c76ae52dSmrg_X_EXPORT FcPattern *
86c76ae52dSmrgXftXlfdParse (const char *xlfd_orig, FcBool ignore_scalable, FcBool complete)
87c76ae52dSmrg{
88c76ae52dSmrg    FcPattern	*pat;
89c76ae52dSmrg    const char	*xlfd = xlfd_orig;
90c76ae52dSmrg    const char	*foundry;
91c76ae52dSmrg    const char	*family;
92c76ae52dSmrg    const char	*weight_name;
93c76ae52dSmrg    const char	*slant;
94c76ae52dSmrg    const char	*registry;
95c76ae52dSmrg    const char	*encoding;
96c76ae52dSmrg    char	*save;
97c76ae52dSmrg    int		pixel;
98c76ae52dSmrg    int		point;
99c76ae52dSmrg    int		resx;
100c76ae52dSmrg    int		resy;
101c76ae52dSmrg    int		slant_value, weight_value;
102c76ae52dSmrg    double	dpixel;
103c76ae52dSmrg
104c76ae52dSmrg    if (*xlfd != '-')
105c76ae52dSmrg	return 0;
106c76ae52dSmrg    if (!(xlfd = strchr (foundry = ++xlfd, '-'))) return 0;
107c76ae52dSmrg    if (!(xlfd = strchr (family = ++xlfd, '-'))) return 0;
108c76ae52dSmrg    if (!(xlfd = strchr (weight_name = ++xlfd, '-'))) return 0;
109c76ae52dSmrg    if (!(xlfd = strchr (slant = ++xlfd, '-'))) return 0;
110c76ae52dSmrg    if (!(xlfd = strchr (/* setwidth_name = */ ++xlfd, '-'))) return 0;
111c76ae52dSmrg    if (!(xlfd = strchr (/* add_style_name = */ ++xlfd, '-'))) return 0;
112c76ae52dSmrg    if (!(xlfd = XftGetInt (++xlfd, &pixel))) return 0;
113c76ae52dSmrg    if (!(xlfd = XftGetInt (++xlfd, &point))) return 0;
114c76ae52dSmrg    if (!(xlfd = XftGetInt (++xlfd, &resx))) return 0;
115c76ae52dSmrg    if (!(xlfd = XftGetInt (++xlfd, &resy))) return 0;
116c76ae52dSmrg    if (!(xlfd = strchr (/* spacing = */ ++xlfd, '-'))) return 0;
117c76ae52dSmrg    if (!(xlfd = strchr (/* average_width = */ ++xlfd, '-'))) return 0;
118c76ae52dSmrg    if (!(xlfd = strchr (registry = ++xlfd, '-'))) return 0;
119c76ae52dSmrg    /* make sure no fields follow this one */
120c76ae52dSmrg    if ((xlfd = strchr (encoding = ++xlfd, '-'))) return 0;
121c76ae52dSmrg
122c76ae52dSmrg    if (!pixel)
123c76ae52dSmrg	return 0;
124c76ae52dSmrg
125c76ae52dSmrg    pat = FcPatternCreate ();
126c76ae52dSmrg    if (!pat)
127c76ae52dSmrg	return 0;
128c76ae52dSmrg
129c76ae52dSmrg    save = (char *) malloc (strlen (foundry) + 1);
130c76ae52dSmrg
131c76ae52dSmrg    if (!save) {
132c76ae52dSmrg	FcPatternDestroy (pat);
133c76ae52dSmrg	return 0;
134c76ae52dSmrg    }
135c76ae52dSmrg
136c76ae52dSmrg    if (!FcPatternAddString (pat, XFT_XLFD, (FcChar8 *) xlfd_orig)) goto bail;
137c76ae52dSmrg
138c76ae52dSmrg    XftSplitStr (foundry, save);
139c76ae52dSmrg    if (save[0] && strcmp (save, "*") != 0)
140c76ae52dSmrg	if (!FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) save)) goto bail;
141c76ae52dSmrg
142c76ae52dSmrg    XftSplitStr (family, save);
143c76ae52dSmrg    if (save[0] && strcmp (save, "*") != 0)
144c76ae52dSmrg	if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) save)) goto bail;
145c76ae52dSmrg
146c76ae52dSmrg    weight_value = _XftMatchSymbolic (XftXlfdWeights, NUM_XLFD_WEIGHTS,
147c76ae52dSmrg				      XftSplitStr (weight_name, save),
148c76ae52dSmrg				      FC_WEIGHT_MEDIUM);
149c76ae52dSmrg    if (!FcPatternAddInteger (pat, FC_WEIGHT, weight_value))
150c76ae52dSmrg	goto bail;
151c76ae52dSmrg
152c76ae52dSmrg    slant_value = _XftMatchSymbolic (XftXlfdSlants, NUM_XLFD_SLANTS,
153c76ae52dSmrg				     XftSplitStr (slant, save),
154c76ae52dSmrg				     FC_SLANT_ROMAN);
155c76ae52dSmrg    if (!FcPatternAddInteger (pat, FC_SLANT, slant_value))
156c76ae52dSmrg	goto bail;
157c76ae52dSmrg
158c76ae52dSmrg    dpixel = (double) pixel;
159c76ae52dSmrg
160c76ae52dSmrg    if (point > 0)
161c76ae52dSmrg    {
162c76ae52dSmrg	if (!FcPatternAddDouble (pat, FC_SIZE, ((double) point) / 10.0)) goto bail;
163c76ae52dSmrg	if (pixel <= 0 && resy > 0)
164c76ae52dSmrg	{
165c76ae52dSmrg	    dpixel = (double) point * (double) resy / 720.0;
166c76ae52dSmrg	}
167c76ae52dSmrg    }
168c76ae52dSmrg
169c76ae52dSmrg    if (dpixel > 0)
170c76ae52dSmrg	if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, dpixel)) goto bail;
171c76ae52dSmrg
172c76ae52dSmrg    free (save);
173c76ae52dSmrg    return pat;
174c76ae52dSmrg
175c76ae52dSmrgbail:
176c76ae52dSmrg    free (save);
177c76ae52dSmrg    FcPatternDestroy (pat);
178c76ae52dSmrg    return 0;
179c76ae52dSmrg}
180