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