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