diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2014-03-14 21:23:32 +0000 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2014-03-14 21:23:32 +0000 |
commit | 0af7dc6b7a6b59b735efb25e93dd4e62be2126d5 (patch) | |
tree | c08c1b55d7ae0793a37a9e621a1adebb740f12c8 /Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp | |
parent | 97f7834d79c2ef1a3a7a3d0ed038881a2fb1f459 (diff) |
Sync XeTeX
git-svn-id: svn://tug.org/texlive/trunk@33175 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp')
-rw-r--r-- | Build/source/texk/web2c/xetexdir/XeTeXFontMgr_FC.cpp | 548 |
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; } |