summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp')
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp548
1 files changed, 275 insertions, 273 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
index f7c64d16f4b..f7253f1faa3 100644
--- a/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
+++ b/Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp
@@ -50,318 +50,320 @@ extern "C" {
#include <unicode/ucnv.h>
-#define kFontFamilyName 1
-#define kFontStyleName 2
-#define kFontFullName 4
-#define kPreferredFamilyName 16
-#define kPreferredSubfamilyName 17
+#define kFontFamilyName 1
+#define kFontStyleName 2
+#define kFontFullName 4
+#define kPreferredFamilyName 16
+#define kPreferredSubfamilyName 17
-static UConverter* macRomanConv = NULL;
-static UConverter* utf16beConv = NULL;
-static UConverter* utf8Conv = NULL;
+static UConverter* macRomanConv = NULL;
+static UConverter* utf16beConv = NULL;
+static UConverter* utf8Conv = NULL;
static char*
convertToUtf8(UConverter* conv, const unsigned char* name, int len)
{
- char* buffer1 = NULL;
- char* buffer2 = NULL;
- int bufSize = -1;
-
- if (2 * (len + 1) > bufSize) {
- if (buffer1 != NULL) {
- delete[] buffer1;
- delete[] buffer2;
- }
- bufSize = 2 * len + 100;
- buffer1 = new char[bufSize];
- buffer2 = new char[bufSize];
- }
-
- UErrorCode status = U_ZERO_ERROR;
- len = ucnv_toUChars(conv, (UChar*)buffer1, bufSize, (const char*)name, len, &status);
- len = ucnv_fromUChars(utf8Conv, buffer2, bufSize, (UChar*)buffer1, len, &status);
- buffer2[len] = 0;
-
- return buffer2;
+ char* buffer1 = NULL;
+ char* buffer2 = NULL;
+ int bufSize = -1;
+
+ if (2 * (len + 1) > bufSize) {
+ if (buffer1 != NULL) {
+ delete[] buffer1;
+ delete[] buffer2;
+ }
+ bufSize = 2 * len + 100;
+ buffer1 = new char[bufSize];
+ buffer2 = new char[bufSize];
+ }
+
+ UErrorCode status = U_ZERO_ERROR;
+ len = ucnv_toUChars(conv, (UChar*)buffer1, bufSize, (const char*)name, len, &status);
+ len = ucnv_fromUChars(utf8Conv, buffer2, bufSize, (UChar*)buffer1, len, &status);
+ buffer2[len] = 0;
+
+ delete[] buffer1;
+ return buffer2;
}
XeTeXFontMgr::NameCollection*
XeTeXFontMgr_FC::readNames(FcPattern* pat)
{
- NameCollection* names = new NameCollection;
-
- char* pathname;
- if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch)
- return names;
- int index;
- if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
- return names;
-
- FT_Face face;
- if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0)
- return names;
-
- const char* name = FT_Get_Postscript_Name(face);
- if (name == NULL)
- return names;
- names->psName = name;
-
- // for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig
- if (FT_IS_SFNT(face)) {
- std::list<std::string> familyNames;
- std::list<std::string> subFamilyNames;
- FT_SfntName nameRec;
- for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) {
- char* utf8name = NULL;
- if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0)
- continue;
- switch (nameRec.name_id) {
- case kFontFullName:
- case kFontFamilyName:
- case kFontStyleName:
- case kPreferredFamilyName:
- case kPreferredSubfamilyName:
- {
- bool preferredName = false;
- if (nameRec.platform_id == TT_PLATFORM_MACINTOSH
- && nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) {
- utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len);
- preferredName = true;
- }
- else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE)
- || (nameRec.platform_id == TT_PLATFORM_MICROSOFT))
- utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len);
-
- if (utf8name != NULL) {
- std::list<std::string>* nameList = NULL;
- switch (nameRec.name_id) {
- case kFontFullName:
- nameList = &names->fullNames;
- break;
- case kFontFamilyName:
- nameList = &names->familyNames;
- break;
- case kFontStyleName:
- nameList = &names->styleNames;
- break;
- case kPreferredFamilyName:
- nameList = &familyNames;
- break;
- case kPreferredSubfamilyName:
- nameList = &subFamilyNames;
- break;
- }
- if (preferredName)
- prependToList(nameList, utf8name);
- else
- appendToList(nameList, utf8name);
- }
- }
- break;
- }
- }
- if (familyNames.size() > 0)
- names->familyNames = familyNames;
- if (subFamilyNames.size() > 0)
- names->styleNames = subFamilyNames;
- } else {
- index = 0;
- while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->fullNames, name);
- index = 0;
- while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->familyNames, name);
- index = 0;
- while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch)
- appendToList(&names->styleNames, name);
-
- if (names->fullNames.size() == 0) {
- std::string fullName(names->familyNames.front());
- if (names->styleNames.size() > 0) {
- fullName += " ";
- fullName += names->styleNames.front();
- }
- names->fullNames.push_back(fullName);
- }
- }
-
- FT_Done_Face(face);
-
- return names;
+ NameCollection* names = new NameCollection;
+
+ char* pathname;
+ if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch)
+ return names;
+ int index;
+ if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
+ return names;
+
+ FT_Face face;
+ if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0)
+ return names;
+
+ const char* name = FT_Get_Postscript_Name(face);
+ if (name == NULL)
+ return names;
+ names->psName = name;
+
+ // for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig
+ if (FT_IS_SFNT(face)) {
+ std::list<std::string> familyNames;
+ std::list<std::string> subFamilyNames;
+ FT_SfntName nameRec;
+ for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) {
+ char* utf8name = NULL;
+ if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0)
+ continue;
+ switch (nameRec.name_id) {
+ case kFontFullName:
+ case kFontFamilyName:
+ case kFontStyleName:
+ case kPreferredFamilyName:
+ case kPreferredSubfamilyName:
+ {
+ bool preferredName = false;
+ if (nameRec.platform_id == TT_PLATFORM_MACINTOSH
+ && nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) {
+ utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len);
+ preferredName = true;
+ }
+ else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE)
+ || (nameRec.platform_id == TT_PLATFORM_MICROSOFT))
+ utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len);
+
+ if (utf8name != NULL) {
+ std::list<std::string>* nameList = NULL;
+ switch (nameRec.name_id) {
+ case kFontFullName:
+ nameList = &names->fullNames;
+ break;
+ case kFontFamilyName:
+ nameList = &names->familyNames;
+ break;
+ case kFontStyleName:
+ nameList = &names->styleNames;
+ break;
+ case kPreferredFamilyName:
+ nameList = &familyNames;
+ break;
+ case kPreferredSubfamilyName:
+ nameList = &subFamilyNames;
+ break;
+ }
+ if (preferredName)
+ prependToList(nameList, utf8name);
+ else
+ appendToList(nameList, utf8name);
+ delete[] utf8name;
+ }
+ }
+ break;
+ }
+ }
+ if (familyNames.size() > 0)
+ names->familyNames = familyNames;
+ if (subFamilyNames.size() > 0)
+ names->styleNames = subFamilyNames;
+ } else {
+ index = 0;
+ while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->fullNames, name);
+ index = 0;
+ while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->familyNames, name);
+ index = 0;
+ while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch)
+ appendToList(&names->styleNames, name);
+
+ if (names->fullNames.size() == 0) {
+ std::string fullName(names->familyNames.front());
+ if (names->styleNames.size() > 0) {
+ fullName += " ";
+ fullName += names->styleNames.front();
+ }
+ names->fullNames.push_back(fullName);
+ }
+ }
+
+ FT_Done_Face(face);
+
+ return names;
}
void
XeTeXFontMgr_FC::getOpSizeRecAndStyleFlags(Font* theFont)
{
- XeTeXFontMgr::getOpSizeRecAndStyleFlags(theFont);
-
- if (theFont->weight == 0 && theFont->width == 0) {
- // try to get values from FontConfig, as it apparently wasn't an sfnt
- FcPattern* pat = theFont->fontRef;
- int value;
- if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &value) == FcResultMatch)
- theFont->weight = value;
- if (FcPatternGetInteger(pat, FC_WIDTH, 0, &value) == FcResultMatch)
- theFont->width = value;
- if (FcPatternGetInteger(pat, FC_SLANT, 0, &value) == FcResultMatch)
- theFont->slant = value;
- }
+ XeTeXFontMgr::getOpSizeRecAndStyleFlags(theFont);
+
+ if (theFont->weight == 0 && theFont->width == 0) {
+ // try to get values from FontConfig, as it apparently wasn't an sfnt
+ FcPattern* pat = theFont->fontRef;
+ int value;
+ if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &value) == FcResultMatch)
+ theFont->weight = value;
+ if (FcPatternGetInteger(pat, FC_WIDTH, 0, &value) == FcResultMatch)
+ theFont->width = value;
+ if (FcPatternGetInteger(pat, FC_SLANT, 0, &value) == FcResultMatch)
+ theFont->slant = value;
+ }
}
void
XeTeXFontMgr_FC::cacheFamilyMembers(const std::list<std::string>& familyNames)
{
- if (familyNames.size() == 0)
- return;
- for (int f = 0; f < allFonts->nfont; ++f) {
- FcPattern* pat = allFonts->fonts[f];
- if (platformRefToFont.find(pat) != platformRefToFont.end())
- continue;
- char* s;
- for (int i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- for (std::list<std::string>::const_iterator j = familyNames.begin(); j != familyNames.end(); ++j) {
- if (*j == s) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- delete names;
- goto cached;
- }
- }
- }
- cached:
- ;
- }
+ if (familyNames.size() == 0)
+ return;
+ for (int f = 0; f < allFonts->nfont; ++f) {
+ FcPattern* pat = allFonts->fonts[f];
+ if (platformRefToFont.find(pat) != platformRefToFont.end())
+ continue;
+ char* s;
+ for (int i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ for (std::list<std::string>::const_iterator j = familyNames.begin(); j != familyNames.end(); ++j) {
+ if (*j == s) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ delete names;
+ goto cached;
+ }
+ }
+ }
+ cached:
+ ;
+ }
}
void
XeTeXFontMgr_FC::searchForHostPlatformFonts(const std::string& name)
{
- if (cachedAll) // we've already loaded everything on an earlier search
- return;
-
- std::string famName;
- int hyph = name.find('-');
- if (hyph > 0 && hyph < name.length() - 1)
- famName.assign(name.begin(), name.begin() + hyph);
- else
- hyph = 0;
-
- bool found = false;
- while (1) {
- for (int f = 0; f < allFonts->nfont; ++f) {
- restart:
- FcPattern* pat = allFonts->fonts[f];
- if (platformRefToFont.find(pat) != platformRefToFont.end())
- continue;
-
- if (cachedAll) {
- // failed to find it via FC; add everything to our maps (potentially slow) as a last resort
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- delete names;
- continue;
- }
-
- char* s;
- int i;
- for (i = 0; FcPatternGetString(pat, FC_FULLNAME, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- if (name == s) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- }
-
- for (i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
- if (name == s || (hyph && famName == s)) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- char* t;
- for (int j = 0; FcPatternGetString(pat, FC_STYLE, j, (FcChar8**)&t) == FcResultMatch; ++j) {
- std::string full(s);
- full += " ";
- full += t;
- if (name == full) {
- NameCollection* names = readNames(pat);
- addToMaps(pat, names);
- cacheFamilyMembers(names->familyNames);
- delete names;
- found = true;
- goto next_font;
- }
- }
- }
-
- next_font:
- ;
- }
-
- if (found || cachedAll)
- break;
- cachedAll = true;
- }
+ if (cachedAll) // we've already loaded everything on an earlier search
+ return;
+
+ std::string famName;
+ int hyph = name.find('-');
+ if (hyph > 0 && hyph < name.length() - 1)
+ famName.assign(name.begin(), name.begin() + hyph);
+ else
+ hyph = 0;
+
+ bool found = false;
+ while (1) {
+ for (int f = 0; f < allFonts->nfont; ++f) {
+ restart:
+ FcPattern* pat = allFonts->fonts[f];
+ if (platformRefToFont.find(pat) != platformRefToFont.end())
+ continue;
+
+ if (cachedAll) {
+ // failed to find it via FC; add everything to our maps (potentially slow) as a last resort
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ delete names;
+ continue;
+ }
+
+ char* s;
+ int i;
+ for (i = 0; FcPatternGetString(pat, FC_FULLNAME, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ if (name == s) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ }
+
+ for (i = 0; FcPatternGetString(pat, FC_FAMILY, i, (FcChar8**)&s) == FcResultMatch; ++i) {
+ if (name == s || (hyph && famName == s)) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ char* t;
+ for (int j = 0; FcPatternGetString(pat, FC_STYLE, j, (FcChar8**)&t) == FcResultMatch; ++j) {
+ std::string full(s);
+ full += " ";
+ full += t;
+ if (name == full) {
+ NameCollection* names = readNames(pat);
+ addToMaps(pat, names);
+ cacheFamilyMembers(names->familyNames);
+ delete names;
+ found = true;
+ goto next_font;
+ }
+ }
+ }
+
+ next_font:
+ ;
+ }
+
+ if (found || cachedAll)
+ break;
+ cachedAll = true;
+ }
}
void
XeTeXFontMgr_FC::initialize()
{
- if (FcInit() == FcFalse) {
- fprintf(stderr, "fontconfig initialization failed!\n");
- exit(9);
- }
-
- if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
- fprintf(stderr, "FreeType initialization failed!\n");
- exit(9);
- }
-
- UErrorCode err = U_ZERO_ERROR;
- macRomanConv = ucnv_open("macintosh", &err);
- utf16beConv = ucnv_open("UTF16BE", &err);
- utf8Conv = ucnv_open("UTF8", &err);
- if (err != 0) {
- fprintf(stderr, "internal error; cannot read font names\n");
- exit(3);
- }
-
- FcPattern* pat = FcNameParse((const FcChar8*)":outline=true");
- FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX,
- FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_FONTFORMAT, NULL);
- allFonts = FcFontList(FcConfigGetCurrent(), pat, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pat);
-
- cachedAll = false;
+ if (FcInit() == FcFalse) {
+ fprintf(stderr, "fontconfig initialization failed!\n");
+ exit(9);
+ }
+
+ if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
+ fprintf(stderr, "FreeType initialization failed!\n");
+ exit(9);
+ }
+
+ UErrorCode err = U_ZERO_ERROR;
+ macRomanConv = ucnv_open("macintosh", &err);
+ utf16beConv = ucnv_open("UTF16BE", &err);
+ utf8Conv = ucnv_open("UTF8", &err);
+ if (err != 0) {
+ fprintf(stderr, "internal error; cannot read font names\n");
+ exit(3);
+ }
+
+ FcPattern* pat = FcNameParse((const FcChar8*)":outline=true");
+ FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX,
+ FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_FONTFORMAT, NULL);
+ allFonts = FcFontList(FcConfigGetCurrent(), pat, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pat);
+
+ cachedAll = false;
}
void
XeTeXFontMgr_FC::terminate()
{
- if (macRomanConv != NULL)
- ucnv_close(macRomanConv);
- if (utf16beConv != NULL)
- ucnv_close(utf16beConv);
- if (utf8Conv != NULL)
- ucnv_close(utf8Conv);
+ if (macRomanConv != NULL)
+ ucnv_close(macRomanConv);
+ if (utf16beConv != NULL)
+ ucnv_close(utf16beConv);
+ if (utf8Conv != NULL)
+ ucnv_close(utf8Conv);
}
std::string
XeTeXFontMgr_FC::getPlatformFontDesc(PlatformFontRef font) const
{
- std::string path;
- FcChar8* s;
- if (FcPatternGetString(font, FC_FILE, 0, (FcChar8**)&s) == FcResultMatch)
- path = (char*)s;
- else
- path = "[unknown]";
- return path;
+ std::string path;
+ FcChar8* s;
+ if (FcPatternGetString(font, FC_FILE, 0, (FcChar8**)&s) == FcResultMatch)
+ path = (char*)s;
+ else
+ path = "[unknown]";
+ return path;
}