* PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ Copyright © 2002-2003 by Juliusz Chroboczek
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <freetype/ttnameid.h>
#include <freetype/t1tables.h>
-#include "data.h"
+#if (FREETYPE_MINOR > 1 || (FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 4))
+#include <freetype/ftbdf.h>
+#include <freetype/ftmodule.h>
+#define USE_FTBDF
+#define HAS_BDF_PROPERTY(f) ((f) && (f)->driver && \
+ (f)->driver->root.clazz->get_interface)
+#define MY_Get_BDF_Property(f,n,p) (HAS_BDF_PROPERTY(f) ? \
+ FT_Get_BDF_Property(f,n,p) : \
+ FT_Err_Invalid_Argument)
+#endif
+
/*
* Keep Han languages separated by eliminating languages
return FcTrue;
}
-static char*
-notice_foundry(char *notice)
+/* Order is significant. For example, some B&H fonts are hinted by
+ URW++, and both strings appear in the notice. */
+
+static const struct {
+ const FcChar8 *notice;
+ const FcChar8 *foundry;
+} FcNoticeFoundries[] = {
+ { (const FcChar8*) "Bigelow", (const FcChar8 *) "b&h" },
+ { (const FcChar8*) "Adobe", (const FcChar8 *) "adobe" },
+ { (const FcChar8*) "Bitstream", (const FcChar8 *) "bitsteam" },
+ { (const FcChar8*) "Monotype", (const FcChar8 *) "monotype" },
+ { (const FcChar8*) "Linotype", (const FcChar8 *) "linotype" },
+ { (const FcChar8*) "LINOTYPE-HELL", (const FcChar8 *) "linotype" },
+ { (const FcChar8*) "IBM", (const FcChar8 *) "ibm" },
+ { (const FcChar8*) "URW", (const FcChar8 *) "urw" },
+ { (const FcChar8*) "International Typeface Corporation",
+ (const FcChar8 *) "itc" },
+ { (const FcChar8*) "Tiro Typeworks",(const FcChar8 *) "tiro" },
+ { (const FcChar8*) "XFree86", (const FcChar8 *) "xfree86" },
+ { (const FcChar8*) "Microsoft", (const FcChar8 *) "microsoft" },
+ { (const FcChar8*) "Omega", (const FcChar8 *) "omega" },
+ { (const FcChar8*) "Font21", (const FcChar8 *) "hwan" },
+ { (const FcChar8*) "HanYang System",(const FcChar8 *) "hanyang" }
+};
+
+#define NUM_NOTICE_FOUNDRIES (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
+
+static const FcChar8 *
+FcNoticeFoundry(const char *notice)
{
int i;
- for(i = 0; i < sizeof(notice_foundries) / sizeof(notice_foundries[0]); i++)
- if(notice && strstr(notice, notice_foundries[i][0]))
- return notice_foundries[i][1];
- return NULL;
+
+ if (notice)
+ for(i = 0; i < NUM_NOTICE_FOUNDRIES; i++)
+ if (strstr ((const char *) notice, (const char *) FcNoticeFoundries[i].notice))
+ return FcNoticeFoundries[i].foundry;
+ return 0;
}
-static int
-vendor_match(signed char *vendor, char *vendor_string)
+static FcBool
+FcVendorMatch(const char *vendor, const char *vendor_string)
{
/* vendor is not necessarily NUL-terminated. */
int i, len;
+
len = strlen(vendor_string);
- if(memcmp(vendor, vendor_string, len) != 0)
- return 0;
- for(i = len; i < 4; i++)
- if(vendor[i] != ' ' && vendor[i] != '\0')
- return 0;
- return 1;
+ if (memcmp(vendor, vendor_string, len) != 0)
+ return FcFalse;
+ for (i = len; i < 4; i++)
+ if (vendor[i] != ' ' && vendor[i] != '\0')
+ return FcFalse;
+ return FcTrue;
}
-static char*
-vendor_foundry(signed char *vendor)
+/* This table is partly taken from ttmkfdir by Joerg Pommnitz. */
+
+/* It should not contain useless entries (such as UNKN) nor duplicate
+ entries for padding both with spaces and NULs. */
+
+static const struct {
+ const FcChar8 *vendor;
+ const FcChar8 *foundry;
+} FcVendorFoundries[] = {
+ { (const FcChar8*) "ADBE", (const FcChar8 *) "adobe"},
+ { (const FcChar8*) "AGFA", (const FcChar8 *) "agfa"},
+ { (const FcChar8*) "ALTS", (const FcChar8 *) "altsys"},
+ { (const FcChar8*) "APPL", (const FcChar8 *) "apple"},
+ { (const FcChar8*) "ARPH", (const FcChar8 *) "arphic"},
+ { (const FcChar8*) "ATEC", (const FcChar8 *) "alltype"},
+ { (const FcChar8*) "B&H", (const FcChar8 *) "b&h"},
+ { (const FcChar8*) "BITS", (const FcChar8 *) "bitstream"},
+ { (const FcChar8*) "CANO", (const FcChar8 *) "cannon"},
+ { (const FcChar8*) "DYNA", (const FcChar8 *) "dynalab"},
+ { (const FcChar8*) "EPSN", (const FcChar8 *) "epson"},
+ { (const FcChar8*) "FJ", (const FcChar8 *) "fujitsu"},
+ { (const FcChar8*) "IBM", (const FcChar8 *) "ibm"},
+ { (const FcChar8*) "ITC", (const FcChar8 *) "itc"},
+ { (const FcChar8*) "IMPR", (const FcChar8 *) "impress"},
+ { (const FcChar8*) "LARA", (const FcChar8 *) "larabiefonts"},
+ { (const FcChar8*) "LEAF", (const FcChar8 *) "interleaf"},
+ { (const FcChar8*) "LETR", (const FcChar8 *) "letraset"},
+ { (const FcChar8*) "LINO", (const FcChar8 *) "linotype"},
+ { (const FcChar8*) "MACR", (const FcChar8 *) "macromedia"},
+ { (const FcChar8*) "MONO", (const FcChar8 *) "monotype"},
+ { (const FcChar8*) "MS", (const FcChar8 *) "microsoft"},
+ { (const FcChar8*) "MT", (const FcChar8 *) "monotype"},
+ { (const FcChar8*) "NEC", (const FcChar8 *) "nec"},
+ { (const FcChar8*) "PARA", (const FcChar8 *) "paratype"},
+ { (const FcChar8*) "QMSI", (const FcChar8 *) "qms"},
+ { (const FcChar8*) "RICO", (const FcChar8 *) "ricoh"},
+ { (const FcChar8*) "URW", (const FcChar8 *) "urw"},
+ { (const FcChar8*) "Y&Y", (const FcChar8 *) "y&y"}
+};
+
+#define NUM_VENDOR_FOUNDRIES (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
+
+static const FcChar8 *
+FcVendorFoundry(const char *vendor)
{
int i;
- for(i = 0; i < sizeof(vendor_foundries) / sizeof(vendor_foundries[0]); i++)
- if(vendor_match(vendor, vendor_foundries[i][0]))
- return vendor_foundries[i][1];
- return NULL;
+
+ if (vendor)
+ for(i = 0; i < NUM_VENDOR_FOUNDRIES; i++)
+ if (FcVendorMatch (vendor, FcVendorFoundries[i].vendor))
+ return FcVendorFoundries[i].foundry;
+ return 0;
}
FcCharSet *cs;
FcLangSet *ls;
FT_Library ftLibrary;
- FcChar8 *family;
- FcChar8 *style;
- FcChar8 *foundry;
+ FcChar8 *family = 0;
+ FcChar8 *style = 0;
+ const FcChar8 *foundry = 0;
int spacing;
TT_OS2 *os2;
PS_FontInfoRec psfontinfo;
*/
os2 = (TT_OS2 *) FT_Get_Sfnt_Table (face, ft_sfnt_os2);
+ /*
+ * Look first in the OS/2 table for the foundry, if
+ * not found here, the various notices will be searched for
+ * that information, either from the sfnt name tables or
+ * the Postscript FontInfo dictionary. Finally, the
+ * BDF properties will queried.
+ */
+
if (os2 && os2->version >= 0x0001 && os2->version != 0xffff)
- foundry = vendor_foundry(os2->achVendID);
- else
- foundry = NULL;
+ foundry = FcVendorFoundry(os2->achVendID);
/*
* Grub through the name table looking for family
* and style names. FreeType makes quite a hash
* of them
*/
- family = 0;
- style = 0;
- foundry = 0;
snamec = FT_Get_Sfnt_Name_Count (face);
for (snamei = 0; snamei < snamec; snamei++)
{
break;
case TT_NAME_ID_TRADEMARK:
case TT_NAME_ID_MANUFACTURER:
+ /* If the foundry wasn't found in the OS/2 table, look here */
if(!foundry)
- foundry = notice_foundry(utf8);
+ foundry = FcNoticeFoundry(utf8);
break;
}
if (utf8)
free (style);
}
- if(foundry) {
- if(!FcPatternAddString (pat, FC_FOUNDRY, foundry))
- goto bail;
- }
-
if (!FcPatternAddString (pat, FC_FILE, file))
goto bail1;
exclusiveLang = FcCodePageRange[i].lang;
}
}
-
- foundry = vendor_foundry(os2->achVendID);
-
}
if (os2 && os2->version != 0xffff)
if (FT_Get_PS_Font_Info(face, &psfontinfo) == 0)
{
- if (FcStrCmpIgnoreCase((FcChar8 *)"thin", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_THIN;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"extralight", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_EXTRALIGHT;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"ultralight", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_ULTRALIGHT;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"light", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_LIGHT;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"regular", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_REGULAR;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"normal", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_NORMAL;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"medium", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_MEDIUM;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"demibold", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_DEMIBOLD;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"semibold", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_SEMIBOLD;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"extrabold", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_EXTRABOLD;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"ultrabold", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_EXTRABOLD;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"bold", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_BOLD;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"black", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_BLACK;
- else if (FcStrCmpIgnoreCase((FcChar8 *)"heavy", (FcChar8 *) psfontinfo.weight) == 0)
- weight = FC_WEIGHT_BLACK;
+ if (psfontinfo.weight)
+ {
+ static struct {
+ char *name;
+ int value;
+ } ps_weights[] = {
+ { "thin", FC_WEIGHT_THIN },
+ { "extralight", FC_WEIGHT_EXTRALIGHT },
+ { "ultralight", FC_WEIGHT_ULTRALIGHT },
+ { "light", FC_WEIGHT_LIGHT },
+ { "regular", FC_WEIGHT_REGULAR },
+ { "normal", FC_WEIGHT_NORMAL },
+ { "medium", FC_WEIGHT_MEDIUM },
+ { "demibold", FC_WEIGHT_DEMIBOLD },
+ { "semibold", FC_WEIGHT_SEMIBOLD },
+ { "bold", FC_WEIGHT_BOLD },
+ { "extrabold", FC_WEIGHT_EXTRABOLD },
+ { "ultrabold", FC_WEIGHT_ULTRABOLD },
+ { "black", FC_WEIGHT_BLACK },
+ { "heavy", FC_WEIGHT_HEAVY },
+ };
+#define NUM_PS_WEIGHTS (sizeof (ps_weights) / sizeof (ps_weights[0]))
+ int w;
+ for (w = 0; w < NUM_PS_WEIGHTS; w++)
+ if (!FcStrCmpIgnoreCase ((FcChar8 *) ps_weights[w].name,
+ (FcChar8 *) psfontinfo.weight))
+ {
+ weight = ps_weights[w].value;
+ break;
+ }
+ }
if (psfontinfo.italic_angle < 0)
slant = FC_SLANT_ITALIC;
slant = FC_SLANT_ROMAN;
if(!foundry)
- foundry = notice_foundry(psfontinfo.notice);
+ foundry = FcNoticeFoundry(psfontinfo.notice);
}
+#ifdef USE_FTBDF
+ /*
+ * Finally, look for a FOUNDRY BDF property if no other
+ * mechanism has managed to locate a foundry
+ */
+
+ if (!foundry)
+ {
+ int rc;
+ BDF_PropertyRec prop;
+ rc = MY_Get_BDF_Property(face, "FOUNDRY", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM)
+ foundry = prop.u.atom;
+ }
+
+ if (width == -1)
+ {
+ BDF_PropertyRec prop;
+ if (MY_Get_BDF_Property(face, "RELATIVE_SETWIDTH", &prop) == 0 &&
+ (prop.type == BDF_PROPERTY_TYPE_INTEGER ||
+ prop.type == BDF_PROPERTY_TYPE_CARDINAL))
+ {
+ FT_Int32 value;
+
+ if (prop.type == BDF_PROPERTY_TYPE_INTEGER)
+ value = prop.u.integer;
+ else
+ value = (FT_Int32) prop.u.cardinal;
+ switch ((value + 5) / 10) {
+ case 1: width = FC_WIDTH_ULTRACONDENSED; break;
+ case 2: width = FC_WIDTH_EXTRACONDENSED; break;
+ case 3: width = FC_WIDTH_CONDENSED; break;
+ case 4: width = FC_WIDTH_SEMICONDENSED; break;
+ case 5: width = FC_WIDTH_NORMAL; break;
+ case 6: width = FC_WIDTH_SEMIEXPANDED; break;
+ case 7: width = FC_WIDTH_EXPANDED; break;
+ case 8: width = FC_WIDTH_EXTRAEXPANDED; break;
+ case 9: width = FC_WIDTH_ULTRAEXPANDED; break;
+ }
+ }
+ else if (MY_Get_BDF_Property (face, "SETWIDTH_NAME", &prop) == 0 &&
+ prop.type == BDF_PROPERTY_TYPE_ATOM)
+ {
+ static struct {
+ FcChar8 *width_name;
+ int width;
+ } FcSetWidths[] = {
+ { "Condensed", FC_WIDTH_CONDENSED },
+ { "SemiCondensed", FC_WIDTH_SEMICONDENSED },
+ { "Normal", FC_WIDTH_NORMAL },
+ };
+ int i;
+
+ if (FcDebug () & FC_DBG_SCANV)
+ printf ("\nsetwidth: %s\n", prop.u.atom);
+ for (i = 0; i < sizeof (FcSetWidths) / sizeof (FcSetWidths[0]); i++)
+ if (!FcStrCmpIgnoreCase ((FcChar8 *) prop.u.atom,
+ FcSetWidths[i].width_name))
+ {
+ width = FcSetWidths[i].width;
+ break;
+ }
+ }
+ }
+
+#endif
+
if (!FcPatternAddInteger (pat, FC_SLANT, slant))
goto bail1;
if (!FcPatternAddInteger (pat, FC_WIDTH, width))
goto bail1;
+ if(foundry)
+ {
+ if(!FcPatternAddString (pat, FC_FOUNDRY, foundry))
+ goto bail1;
+ }
+
/*
* Compute the unicode coverage for the font
*/