xftxlfd.c revision 2836776b
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 * 84c76ae52dSmrgXftXlfdParse (const char *xlfd_orig, FcBool ignore_scalable, FcBool complete) 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 const char *registry; 93c76ae52dSmrg const char *encoding; 94c76ae52dSmrg char *save; 95c76ae52dSmrg int pixel; 96c76ae52dSmrg int point; 97c76ae52dSmrg int resx; 98c76ae52dSmrg int resy; 99c76ae52dSmrg int slant_value, weight_value; 100c76ae52dSmrg double dpixel; 101c76ae52dSmrg 102c76ae52dSmrg if (*xlfd != '-') 1030d590c07Smrg return NULL; 1040d590c07Smrg if (!(xlfd = strchr (foundry = ++xlfd, '-'))) return NULL; 1050d590c07Smrg if (!(xlfd = strchr (family = ++xlfd, '-'))) return NULL; 1060d590c07Smrg if (!(xlfd = strchr (weight_name = ++xlfd, '-'))) return NULL; 1070d590c07Smrg if (!(xlfd = strchr (slant = ++xlfd, '-'))) return NULL; 1080d590c07Smrg if (!(xlfd = strchr (/* setwidth_name = */ ++xlfd, '-'))) return NULL; 1090d590c07Smrg if (!(xlfd = strchr (/* add_style_name = */ ++xlfd, '-'))) return NULL; 1100d590c07Smrg if (!(xlfd = XftGetInt (++xlfd, &pixel))) return NULL; 1110d590c07Smrg if (!(xlfd = XftGetInt (++xlfd, &point))) return NULL; 1120d590c07Smrg if (!(xlfd = XftGetInt (++xlfd, &resx))) return NULL; 1130d590c07Smrg if (!(xlfd = XftGetInt (++xlfd, &resy))) return NULL; 1140d590c07Smrg if (!(xlfd = strchr (/* spacing = */ ++xlfd, '-'))) return NULL; 1150d590c07Smrg if (!(xlfd = strchr (/* average_width = */ ++xlfd, '-'))) return NULL; 1160d590c07Smrg if (!(xlfd = strchr (registry = ++xlfd, '-'))) return NULL; 117c76ae52dSmrg /* make sure no fields follow this one */ 1180d590c07Smrg if ((xlfd = strchr (encoding = ++xlfd, '-'))) return NULL; 119c76ae52dSmrg 120c76ae52dSmrg if (!pixel) 1210d590c07Smrg return NULL; 1222836776bSmrg 123c76ae52dSmrg pat = FcPatternCreate (); 124c76ae52dSmrg if (!pat) 1250d590c07Smrg return NULL; 1262836776bSmrg 127c76ae52dSmrg save = (char *) malloc (strlen (foundry) + 1); 1282836776bSmrg 129c76ae52dSmrg if (!save) { 130c76ae52dSmrg FcPatternDestroy (pat); 1310d590c07Smrg return NULL; 132c76ae52dSmrg } 133c76ae52dSmrg 134c76ae52dSmrg if (!FcPatternAddString (pat, XFT_XLFD, (FcChar8 *) xlfd_orig)) goto bail; 1352836776bSmrg 136c76ae52dSmrg XftSplitStr (foundry, save); 137c76ae52dSmrg if (save[0] && strcmp (save, "*") != 0) 138c76ae52dSmrg if (!FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) save)) goto bail; 1392836776bSmrg 140c76ae52dSmrg XftSplitStr (family, save); 141c76ae52dSmrg if (save[0] && strcmp (save, "*") != 0) 142c76ae52dSmrg if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) save)) goto bail; 1432836776bSmrg 144c76ae52dSmrg weight_value = _XftMatchSymbolic (XftXlfdWeights, NUM_XLFD_WEIGHTS, 145c76ae52dSmrg XftSplitStr (weight_name, save), 146c76ae52dSmrg FC_WEIGHT_MEDIUM); 1472836776bSmrg if (!FcPatternAddInteger (pat, FC_WEIGHT, weight_value)) 148c76ae52dSmrg goto bail; 1492836776bSmrg 150c76ae52dSmrg slant_value = _XftMatchSymbolic (XftXlfdSlants, NUM_XLFD_SLANTS, 151c76ae52dSmrg XftSplitStr (slant, save), 152c76ae52dSmrg FC_SLANT_ROMAN); 1532836776bSmrg if (!FcPatternAddInteger (pat, FC_SLANT, slant_value)) 154c76ae52dSmrg goto bail; 1552836776bSmrg 156c76ae52dSmrg dpixel = (double) pixel; 1572836776bSmrg 158c76ae52dSmrg if (point > 0) 159c76ae52dSmrg { 160c76ae52dSmrg if (!FcPatternAddDouble (pat, FC_SIZE, ((double) point) / 10.0)) goto bail; 161c76ae52dSmrg if (pixel <= 0 && resy > 0) 162c76ae52dSmrg { 163c76ae52dSmrg dpixel = (double) point * (double) resy / 720.0; 164c76ae52dSmrg } 165c76ae52dSmrg } 1662836776bSmrg 167c76ae52dSmrg if (dpixel > 0) 168c76ae52dSmrg if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, dpixel)) goto bail; 1692836776bSmrg 170c76ae52dSmrg free (save); 171c76ae52dSmrg return pat; 1722836776bSmrg 173c76ae52dSmrgbail: 174c76ae52dSmrg free (save); 175c76ae52dSmrg FcPatternDestroy (pat); 1760d590c07Smrg return NULL; 177c76ae52dSmrg} 178