xftxlfd.c revision c76ae52d
1/* 2 * $Id: xftxlfd.c,v 1.1.1.1 2008/07/30 02:49:11 mrg Exp $ 3 * 4 * Copyright © 2000 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 "xftint.h" 26 27static XftSymbolic XftXlfdWeights[] = { 28 { "light", FC_WEIGHT_LIGHT }, 29 { "medium", FC_WEIGHT_MEDIUM }, 30 { "regular", FC_WEIGHT_MEDIUM }, 31 { "demibold", FC_WEIGHT_DEMIBOLD }, 32 { "bold", FC_WEIGHT_BOLD }, 33 { "black", FC_WEIGHT_BLACK }, 34}; 35 36#define NUM_XLFD_WEIGHTS (sizeof XftXlfdWeights/sizeof XftXlfdWeights[0]) 37 38static XftSymbolic XftXlfdSlants[] = { 39 { "r", FC_SLANT_ROMAN }, 40 { "i", FC_SLANT_ITALIC }, 41 { "o", FC_SLANT_OBLIQUE }, 42}; 43 44#define NUM_XLFD_SLANTS (sizeof XftXlfdSlants/sizeof XftXlfdSlants[0]) 45 46/* 47 * Cut out one XLFD field, placing it in 'save' and return 48 * the start of 'save' 49 */ 50static char * 51XftSplitStr (const char *field, char *save) 52{ 53 char *s = save; 54 char c; 55 56 while (*field) 57 { 58 if (*field == '-') 59 break; 60 c = *field++; 61 *save++ = c; 62 } 63 *save = 0; 64 return s; 65} 66 67/* 68 * convert one XLFD numeric field. Return -1 if the field is '*' 69 */ 70 71static const char * 72XftGetInt(const char *ptr, int *val) 73{ 74 if (*ptr == '*') { 75 *val = -1; 76 ptr++; 77 } else 78 for (*val = 0; *ptr >= '0' && *ptr <= '9';) 79 *val = *val * 10 + *ptr++ - '0'; 80 if (*ptr == '-') 81 return ptr; 82 return (char *) 0; 83} 84 85_X_EXPORT FcPattern * 86XftXlfdParse (const char *xlfd_orig, FcBool ignore_scalable, FcBool complete) 87{ 88 FcPattern *pat; 89 const char *xlfd = xlfd_orig; 90 const char *foundry; 91 const char *family; 92 const char *weight_name; 93 const char *slant; 94 const char *registry; 95 const char *encoding; 96 char *save; 97 int pixel; 98 int point; 99 int resx; 100 int resy; 101 int slant_value, weight_value; 102 double dpixel; 103 104 if (*xlfd != '-') 105 return 0; 106 if (!(xlfd = strchr (foundry = ++xlfd, '-'))) return 0; 107 if (!(xlfd = strchr (family = ++xlfd, '-'))) return 0; 108 if (!(xlfd = strchr (weight_name = ++xlfd, '-'))) return 0; 109 if (!(xlfd = strchr (slant = ++xlfd, '-'))) return 0; 110 if (!(xlfd = strchr (/* setwidth_name = */ ++xlfd, '-'))) return 0; 111 if (!(xlfd = strchr (/* add_style_name = */ ++xlfd, '-'))) return 0; 112 if (!(xlfd = XftGetInt (++xlfd, &pixel))) return 0; 113 if (!(xlfd = XftGetInt (++xlfd, &point))) return 0; 114 if (!(xlfd = XftGetInt (++xlfd, &resx))) return 0; 115 if (!(xlfd = XftGetInt (++xlfd, &resy))) return 0; 116 if (!(xlfd = strchr (/* spacing = */ ++xlfd, '-'))) return 0; 117 if (!(xlfd = strchr (/* average_width = */ ++xlfd, '-'))) return 0; 118 if (!(xlfd = strchr (registry = ++xlfd, '-'))) return 0; 119 /* make sure no fields follow this one */ 120 if ((xlfd = strchr (encoding = ++xlfd, '-'))) return 0; 121 122 if (!pixel) 123 return 0; 124 125 pat = FcPatternCreate (); 126 if (!pat) 127 return 0; 128 129 save = (char *) malloc (strlen (foundry) + 1); 130 131 if (!save) { 132 FcPatternDestroy (pat); 133 return 0; 134 } 135 136 if (!FcPatternAddString (pat, XFT_XLFD, (FcChar8 *) xlfd_orig)) goto bail; 137 138 XftSplitStr (foundry, save); 139 if (save[0] && strcmp (save, "*") != 0) 140 if (!FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) save)) goto bail; 141 142 XftSplitStr (family, save); 143 if (save[0] && strcmp (save, "*") != 0) 144 if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) save)) goto bail; 145 146 weight_value = _XftMatchSymbolic (XftXlfdWeights, NUM_XLFD_WEIGHTS, 147 XftSplitStr (weight_name, save), 148 FC_WEIGHT_MEDIUM); 149 if (!FcPatternAddInteger (pat, FC_WEIGHT, weight_value)) 150 goto bail; 151 152 slant_value = _XftMatchSymbolic (XftXlfdSlants, NUM_XLFD_SLANTS, 153 XftSplitStr (slant, save), 154 FC_SLANT_ROMAN); 155 if (!FcPatternAddInteger (pat, FC_SLANT, slant_value)) 156 goto bail; 157 158 dpixel = (double) pixel; 159 160 if (point > 0) 161 { 162 if (!FcPatternAddDouble (pat, FC_SIZE, ((double) point) / 10.0)) goto bail; 163 if (pixel <= 0 && resy > 0) 164 { 165 dpixel = (double) point * (double) resy / 720.0; 166 } 167 } 168 169 if (dpixel > 0) 170 if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, dpixel)) goto bail; 171 172 free (save); 173 return pat; 174 175bail: 176 free (save); 177 FcPatternDestroy (pat); 178 return 0; 179} 180