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