xftxlfd.c revision de3c0529
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 _X_UNUSED, FcBool complete _X_UNUSED) 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 char *save; 93 int pixel; 94 int point; 95 int resx; 96 int resy; 97 int slant_value, weight_value; 98 double dpixel; 99 100 if (*xlfd != '-') 101 return NULL; 102 if (!(xlfd = strchr (foundry = ++xlfd, '-'))) return NULL; 103 if (!(xlfd = strchr (family = ++xlfd, '-'))) return NULL; 104 if (!(xlfd = strchr (weight_name = ++xlfd, '-'))) return NULL; 105 if (!(xlfd = strchr (slant = ++xlfd, '-'))) return NULL; 106 if (!(xlfd = strchr (/* setwidth_name = */ ++xlfd, '-'))) return NULL; 107 if (!(xlfd = strchr (/* add_style_name = */ ++xlfd, '-'))) return NULL; 108 if (!(xlfd = XftGetInt (++xlfd, &pixel))) return NULL; 109 if (!(xlfd = XftGetInt (++xlfd, &point))) return NULL; 110 if (!(xlfd = XftGetInt (++xlfd, &resx))) return NULL; 111 if (!(xlfd = XftGetInt (++xlfd, &resy))) return NULL; 112 if (!(xlfd = strchr (/* spacing = */ ++xlfd, '-'))) return NULL; 113 if (!(xlfd = strchr (/* average_width = */ ++xlfd, '-'))) return NULL; 114 if (!(xlfd = strchr (/* registry = */ ++xlfd, '-'))) return NULL; 115 /* make sure no fields follow this one */ 116 if ((/* xlfd = */ strchr (/* encoding = */ ++xlfd, '-'))) return NULL; 117 118 if (!pixel) 119 return NULL; 120 121 pat = FcPatternCreate (); 122 if (!pat) 123 return NULL; 124 125 save = (char *) malloc (strlen (foundry) + 1); 126 127 if (!save) { 128 FcPatternDestroy (pat); 129 return NULL; 130 } 131 132 if (!FcPatternAddString (pat, XFT_XLFD, (const FcChar8 *) xlfd_orig)) goto bail; 133 134 XftSplitStr (foundry, save); 135 if (save[0] && strcmp (save, "*") != 0) 136 if (!FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) save)) goto bail; 137 138 XftSplitStr (family, save); 139 if (save[0] && strcmp (save, "*") != 0) 140 if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) save)) goto bail; 141 142 weight_value = _XftMatchSymbolic (XftXlfdWeights, NUM_XLFD_WEIGHTS, 143 XftSplitStr (weight_name, save), 144 FC_WEIGHT_MEDIUM); 145 if (!FcPatternAddInteger (pat, FC_WEIGHT, weight_value)) 146 goto bail; 147 148 slant_value = _XftMatchSymbolic (XftXlfdSlants, NUM_XLFD_SLANTS, 149 XftSplitStr (slant, save), 150 FC_SLANT_ROMAN); 151 if (!FcPatternAddInteger (pat, FC_SLANT, slant_value)) 152 goto bail; 153 154 dpixel = (double) pixel; 155 156 if (point > 0) 157 { 158 if (!FcPatternAddDouble (pat, FC_SIZE, ((double) point) / 10.0)) goto bail; 159 if (pixel <= 0 && resy > 0) 160 { 161 dpixel = (double) point * (double) resy / 720.0; 162 } 163 } 164 165 if (dpixel > 0) 166 if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, dpixel)) goto bail; 167 168 free (save); 169 return pat; 170 171bail: 172 free (save); 173 FcPatternDestroy (pat); 174 return NULL; 175} 176