Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Unified Diff: src/ports/SkFontConfigInterface_android.cpp

Issue 445143002: Remove Android FontConfigInterface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/ports/SkTypeface_android.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontConfigInterface_android.cpp
diff --git a/src/ports/SkFontConfigInterface_android.cpp b/src/ports/SkFontConfigInterface_android.cpp
deleted file mode 100644
index 4e435cd616f4a99395b775742e5c76ba1e8af14c..0000000000000000000000000000000000000000
--- a/src/ports/SkFontConfigInterface_android.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkFontConfigInterface.h"
-#include "SkTypeface_android.h"
-
-#include "SkFontConfigParser_android.h"
-#include "SkFontConfigTypeface.h"
-#include "SkFontHost_FreeType_common.h"
-#include "SkFontMgr.h"
-#include "SkGlyphCache.h"
-#include "SkPaint.h"
-#include "SkString.h"
-#include "SkStream.h"
-#include "SkThread.h"
-#include "SkTypefaceCache.h"
-#include "SkTArray.h"
-#include "SkTDict.h"
-#include "SkTSearch.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#ifndef SK_DEBUG_FONTS
- #define SK_DEBUG_FONTS 0
-#endif
-
-#if SK_DEBUG_FONTS
- #define DEBUG_FONT(args) SkDebugf args
-#else
- #define DEBUG_FONT(args)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-// For test only.
-static const char* gTestMainConfigFile = NULL;
-static const char* gTestFallbackConfigFile = NULL;
-static const char* gTestFontFilePrefix = NULL;
-
-///////////////////////////////////////////////////////////////////////////////
-
-typedef int32_t FontRecID;
-#define INVALID_FONT_REC_ID -1
-
-typedef int32_t FamilyRecID;
-#define INVALID_FAMILY_REC_ID -1
-
-// used to record our notion of the pre-existing fonts
-struct FontRec {
- SkAutoTUnref<SkTypeface> fTypeface;
- SkString fFileName;
- SkTypeface::Style fStyle;
- bool fIsValid;
- FamilyRecID fFamilyRecID;
-};
-
-struct FamilyRec {
- FamilyRec() {
- memset(fFontRecID, INVALID_FONT_REC_ID, sizeof(fFontRecID));
- }
-
- static const int FONT_STYLE_COUNT = 4;
- FontRecID fFontRecID[FONT_STYLE_COUNT];
- bool fIsFallbackFont;
- SkString fFallbackName;
- SkPaintOptionsAndroid fPaintOptions;
-};
-
-
-typedef SkTDArray<FamilyRecID> FallbackFontList;
-
-class SkFontConfigInterfaceAndroid : public SkFontConfigInterface {
-public:
- SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*>& fontFamilies);
- virtual ~SkFontConfigInterfaceAndroid();
-
- virtual bool matchFamilyName(const char familyName[],
- SkTypeface::Style requested,
- FontIdentity* outFontIdentifier,
- SkString* outFamilyName,
- SkTypeface::Style* outStyle) SK_OVERRIDE;
- virtual SkStream* openStream(const FontIdentity&) SK_OVERRIDE;
-
- // new APIs
- virtual SkDataTable* getFamilyNames() SK_OVERRIDE;
- virtual bool matchFamilySet(const char inFamilyName[],
- SkString* outFamilyName,
- SkTArray<FontIdentity>*) SK_OVERRIDE;
-
- /**
- * Get the family name of the font in the default fallback font list that
- * contains the specified chararacter. if no font is found, returns false.
- */
- bool getFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* name);
-
-private:
- void addFallbackFamily(FamilyRecID fontRecID);
- SkTypeface* getTypefaceForFontRec(FontRecID fontRecID);
- FallbackFontList* findFallbackFontList(const SkLanguage& lang, bool isOriginal = true);
-
- SkTArray<FontRec, true> fFonts;
- SkTArray<FamilyRec, true> fFontFamilies;
- SkTDict<FamilyRecID> fFamilyNameDict;
- FamilyRecID fDefaultFamilyRecID;
-
- // (SkLanguage)<->(fallback chain index) translation
- SkTDict<FallbackFontList*> fFallbackFontDict;
- SkTDict<FallbackFontList*> fFallbackFontAliasDict;
- FallbackFontList fDefaultFallbackList;
-
- // fallback info for current locale
- SkString fCachedLocale;
- FallbackFontList* fLocaleFallbackFontList;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-SK_DECLARE_STATIC_MUTEX(gGetSingletonInterfaceMutex);
-static SkFontConfigInterfaceAndroid* getSingletonInterface() {
- static SkFontConfigInterfaceAndroid* gFontConfigInterface;
-
- SkAutoMutexAcquire ac(gGetSingletonInterfaceMutex);
- if (NULL == gFontConfigInterface) {
- // load info from a configuration file that we can use to populate the
- // system/fallback font structures
- SkTDArray<FontFamily*> fontFamilies;
- if (!gTestMainConfigFile) {
- SkFontConfigParser::GetFontFamilies(fontFamilies);
- } else {
- SkFontConfigParser::GetTestFontFamilies(fontFamilies, gTestMainConfigFile,
- gTestFallbackConfigFile);
- }
-
- gFontConfigInterface = new SkFontConfigInterfaceAndroid(fontFamilies);
-
- // cleanup the data we received from the parser
- fontFamilies.deleteAll();
- }
- return gFontConfigInterface;
-}
-
-SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBaseMutex*) {
- // Doesn't need passed-in mutex because getSingletonInterface() uses one
- return getSingletonInterface();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static bool has_font(const SkTArray<FontRec, true>& array, const SkString& filename) {
- for (int i = 0; i < array.count(); i++) {
- if (array[i].fFileName == filename) {
- return true;
- }
- }
- return false;
-}
-
-#ifndef SK_FONT_FILE_PREFIX
- #define SK_FONT_FILE_PREFIX "/fonts/"
-#endif
-
-static void get_path_for_sys_fonts(SkString* full, const SkString& name) {
- if (gTestFontFilePrefix) {
- full->set(gTestFontFilePrefix);
- } else {
- full->set(getenv("ANDROID_ROOT"));
- full->append(SK_FONT_FILE_PREFIX);
- }
- full->append(name);
-}
-
-static void insert_into_name_dict(SkTDict<FamilyRecID>& familyNameDict,
- const char* name, FamilyRecID familyRecID) {
- SkAutoAsciiToLC tolc(name);
- if (familyNameDict.find(tolc.lc())) {
- SkDebugf("---- system font attempting to use a the same name [%s] for"
- "multiple families. skipping subsequent occurrences", tolc.lc());
- } else {
- familyNameDict.set(tolc.lc(), familyRecID);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkFontConfigInterfaceAndroid::SkFontConfigInterfaceAndroid(SkTDArray<FontFamily*>& fontFamilies) :
- fFonts(fontFamilies.count()),
- fFontFamilies(fontFamilies.count() / FamilyRec::FONT_STYLE_COUNT),
- fFamilyNameDict(1024),
- fDefaultFamilyRecID(INVALID_FAMILY_REC_ID),
- fFallbackFontDict(128),
- fFallbackFontAliasDict(128),
- fLocaleFallbackFontList(NULL) {
-
- for (int i = 0; i < fontFamilies.count(); ++i) {
- FontFamily* family = fontFamilies[i];
-
- // defer initializing the familyRec until we can be sure that at least
- // one of it's children contains a valid font file
- FamilyRec* familyRec = NULL;
- FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
-
- for (int j = 0; j < family->fFonts.count(); ++j) {
- SkString filename;
- get_path_for_sys_fonts(&filename, family->fFonts[j].fFileName);
-
- if (has_font(fFonts, filename)) {
- DEBUG_FONT(("---- system font and fallback font files specify a duplicate "
- "font %s, skipping the second occurrence", filename.c_str()));
- }
-
- FontRec& fontRec = fFonts.push_back();
- fontRec.fFileName = filename;
- fontRec.fStyle = SkTypeface::kNormal;
- fontRec.fIsValid = false;
- fontRec.fFamilyRecID = familyRecID;
-
- const FontRecID fontRecID = fFonts.count() - 1;
-
- SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(filename.c_str()));
- if (stream.get() != NULL) {
- bool isFixedWidth;
- SkString name;
- fontRec.fIsValid = SkTypeface_FreeType::ScanFont(stream.get(), 0,
- &name, &fontRec.fStyle,
- &isFixedWidth);
- } else {
- if (!family->fIsFallbackFont) {
- SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
- }
- }
-
- if (fontRec.fIsValid) {
- DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s",
- i, fFonts.count() - 1, family->fIsFallbackFont, filename.c_str()));
- } else {
- DEBUG_FONT(("---- SystemFonts[%d][%d] fallback=%d file=%s (INVALID)",
- i, fFonts.count() - 1, family->fIsFallbackFont, filename.c_str()));
- continue;
- }
-
- // create a familyRec now that we know that at least one font in
- // the family is valid
- if (familyRec == NULL) {
- familyRec = &fFontFamilies.push_back();
- familyRecID = fFontFamilies.count() - 1;
- fontRec.fFamilyRecID = familyRecID;
-
- familyRec->fIsFallbackFont = family->fIsFallbackFont;
- familyRec->fPaintOptions = family->fFonts[j].fPaintOptions;
-
- } else if (familyRec->fPaintOptions != family->fFonts[j].fPaintOptions) {
- SkDebugf("Every font file within a family must have identical"
- "language and variant attributes");
- sk_throw();
- }
-
- // add this font to the current familyRec
- if (INVALID_FONT_REC_ID != familyRec->fFontRecID[fontRec.fStyle]) {
- DEBUG_FONT(("Overwriting familyRec for style[%d] old,new:(%d,%d)",
- fontRec.fStyle, familyRec->fFontRecID[fontRec.fStyle],
- fontRecID));
- }
- familyRec->fFontRecID[fontRec.fStyle] = fontRecID;
- }
-
- if (familyRec) {
- if (familyRec->fIsFallbackFont) {
- // add the font to the appropriate fallback chains and also insert a
- // unique name into the familyNameDict for internal usage
- addFallbackFamily(familyRecID);
- } else {
- // add the names that map to this family to the dictionary for easy lookup
- const SkTArray<SkString>& names = family->fNames;
- if (names.empty()) {
- SkDEBUGFAIL("ERROR: non-fallback font with no name");
- continue;
- }
-
- for (int i = 0; i < names.count(); i++) {
- insert_into_name_dict(fFamilyNameDict, names[i].c_str(), familyRecID);
- }
- }
- }
- }
-
- DEBUG_FONT(("---- We have %d system fonts", fFonts.count()));
-
- if (fFontFamilies.count() > 0) {
- fDefaultFamilyRecID = 0;
- }
-
- // scans the default fallback font chain, adding every entry to every other
- // fallback font chain to which it does not belong. this results in every
- // language-specific fallback font chain having all of its fallback fonts at
- // the front of the chain, and everything else at the end.
- FallbackFontList* fallbackList;
- SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
- const char* fallbackLang = iter.next(&fallbackList);
- while(fallbackLang != NULL) {
- for (int i = 0; i < fDefaultFallbackList.count(); i++) {
- FamilyRecID familyRecID = fDefaultFallbackList[i];
- const SkString& fontLang = fFontFamilies[familyRecID].fPaintOptions.getLanguage().getTag();
- if (strcmp(fallbackLang, fontLang.c_str()) != 0) {
- fallbackList->push(familyRecID);
- }
- }
- // move to the next fallback list in the dictionary
- fallbackLang = iter.next(&fallbackList);
- }
-}
-
-SkFontConfigInterfaceAndroid::~SkFontConfigInterfaceAndroid() {
- // iterate through and cleanup fFallbackFontDict
- SkTDict<FallbackFontList*>::Iter iter(fFallbackFontDict);
- FallbackFontList* fallbackList;
- while(iter.next(&fallbackList) != NULL) {
- SkDELETE(fallbackList);
- }
-}
-
-void SkFontConfigInterfaceAndroid::addFallbackFamily(FamilyRecID familyRecID) {
- SkASSERT(familyRecID < fFontFamilies.count());
- FamilyRec& familyRec = fFontFamilies[familyRecID];
- SkASSERT(familyRec.fIsFallbackFont);
-
- // add the fallback family to the name dictionary. This is
- // needed by getFallbackFamilyNameForChar() so that fallback
- // families can be identified by a unique name. The unique
- // identifier that we've chosen is the familyID in hex (e.g. '0F##fallback').
- familyRec.fFallbackName.printf("%.2x##fallback", familyRecID);
- insert_into_name_dict(fFamilyNameDict, familyRec.fFallbackName.c_str(), familyRecID);
-
- // add to the default fallback list
- fDefaultFallbackList.push(familyRecID);
-
- // stop here if it is the default language tag
- const SkString& languageTag = familyRec.fPaintOptions.getLanguage().getTag();
- if (languageTag.isEmpty()) {
- return;
- }
-
- // add to the appropriate language's custom fallback list
- FallbackFontList* customList = NULL;
- if (!fFallbackFontDict.find(languageTag.c_str(), &customList)) {
- DEBUG_FONT(("---- Created fallback list for \"%s\"", languageTag.c_str()));
- customList = SkNEW(FallbackFontList);
- fFallbackFontDict.set(languageTag.c_str(), customList);
- }
- SkASSERT(customList != NULL);
- customList->push(familyRecID);
-}
-
-
-static FontRecID find_best_style(const FamilyRec& family, SkTypeface::Style style) {
-
- const FontRecID* fontRecIDs = family.fFontRecID;
-
- if (fontRecIDs[style] != INVALID_FONT_REC_ID) { // exact match
- return fontRecIDs[style];
- }
- // look for a matching bold
- style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
- if (fontRecIDs[style] != INVALID_FONT_REC_ID) {
- return fontRecIDs[style];
- }
- // look for the plain
- if (fontRecIDs[SkTypeface::kNormal] != INVALID_FONT_REC_ID) {
- return fontRecIDs[SkTypeface::kNormal];
- }
- // look for anything
- for (int i = 0; i < FamilyRec::FONT_STYLE_COUNT; i++) {
- if (fontRecIDs[i] != INVALID_FONT_REC_ID) {
- return fontRecIDs[i];
- }
- }
- // should never get here, since the fontRecID list should not be empty
- SkDEBUGFAIL("No valid fonts exist for this family");
- return -1;
-}
-
-bool SkFontConfigInterfaceAndroid::matchFamilyName(const char familyName[],
- SkTypeface::Style style,
- FontIdentity* outFontIdentifier,
- SkString* outFamilyName,
- SkTypeface::Style* outStyle) {
- // clip to legal style bits
- style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
- bool exactNameMatch = false;
-
- FamilyRecID familyRecID = INVALID_FAMILY_REC_ID;
- if (NULL != familyName) {
- SkAutoAsciiToLC tolc(familyName);
- if (fFamilyNameDict.find(tolc.lc(), &familyRecID)) {
- exactNameMatch = true;
- }
- } else {
- familyRecID = fDefaultFamilyRecID;
-
- }
-
- // If no matching family name is found then return false. This allows clients
- // to be able to search for other fonts instead of forcing them to use the
- // default font.
- if (INVALID_FAMILY_REC_ID == familyRecID) {
- return false;
- }
-
- FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], style);
- FontRec& fontRec = fFonts[fontRecID];
-
- if (NULL != outFontIdentifier) {
- outFontIdentifier->fID = fontRecID;
- outFontIdentifier->fTTCIndex = 0;
- outFontIdentifier->fString.set(fontRec.fFileName);
-// outFontIdentifier->fStyle = fontRec.fStyle;
- }
-
- if (NULL != outFamilyName) {
- if (exactNameMatch) {
- outFamilyName->set(familyName);
- } else {
- // find familyName from list of names
- const char* familyName = NULL;
- SkAssertResult(fFamilyNameDict.findKey(familyRecID, &familyName));
- SkASSERT(familyName);
- outFamilyName->set(familyName);
- }
- }
-
- if (NULL != outStyle) {
- *outStyle = fontRec.fStyle;
- }
-
- return true;
-}
-
-SkStream* SkFontConfigInterfaceAndroid::openStream(const FontIdentity& identity) {
- return SkStream::NewFromFile(identity.fString.c_str());
-}
-
-SkDataTable* SkFontConfigInterfaceAndroid::getFamilyNames() {
- SkTDArray<const char*> names;
- SkTDArray<size_t> sizes;
-
- SkTDict<FamilyRecID>::Iter iter(fFamilyNameDict);
- const char* familyName = iter.next(NULL);
- while(familyName != NULL) {
- *names.append() = familyName;
- *sizes.append() = strlen(familyName) + 1;
-
- // move to the next familyName in the dictionary
- familyName = iter.next(NULL);
- }
-
- return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
- sizes.begin(), names.count());
-}
-
-bool SkFontConfigInterfaceAndroid::matchFamilySet(const char inFamilyName[],
- SkString* outFamilyName,
- SkTArray<FontIdentity>*) {
- return false;
-}
-
-static bool find_proc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
- const FontRecID* fontRecID = (const FontRecID*)ctx;
- FontRecID currFontRecID = ((FontConfigTypeface*)face)->getIdentity().fID;
- return currFontRecID == *fontRecID;
-}
-
-SkTypeface* SkFontConfigInterfaceAndroid::getTypefaceForFontRec(FontRecID fontRecID) {
- FontRec& fontRec = fFonts[fontRecID];
- SkTypeface* face = fontRec.fTypeface.get();
- if (!face) {
- // look for it in the typeface cache
- face = SkTypefaceCache::FindByProcAndRef(find_proc, &fontRecID);
-
- // if it is not in the cache then create it
- if (!face) {
- const char* familyName = NULL;
- SkAssertResult(fFamilyNameDict.findKey(fontRec.fFamilyRecID, &familyName));
- SkASSERT(familyName);
- face = SkTypeface::CreateFromName(familyName, fontRec.fStyle);
- }
-
- // store the result for subsequent lookups
- fontRec.fTypeface.reset(face);
- }
- SkASSERT(face);
- return face;
-}
-
-bool SkFontConfigInterfaceAndroid::getFallbackFamilyNameForChar(SkUnichar uni,
- const char* lang,
- SkString* name) {
- const SkString locale(lang);
- if (NULL == fLocaleFallbackFontList || locale != fCachedLocale) {
- fCachedLocale = locale;
- fLocaleFallbackFontList = this->findFallbackFontList(locale);
- }
- FallbackFontList* fallbackFontList = fLocaleFallbackFontList;
-
- for (int i = 0; i < fallbackFontList->count(); i++) {
- FamilyRecID familyRecID = fallbackFontList->getAt(i);
-
- // if it is not one of the accepted variants then move to the next family
- int32_t acceptedVariants = SkPaintOptionsAndroid::kDefault_Variant |
- SkPaintOptionsAndroid::kElegant_Variant;
- if (!(fFontFamilies[familyRecID].fPaintOptions.getFontVariant() & acceptedVariants)) {
- continue;
- }
-
- FontRecID fontRecID = find_best_style(fFontFamilies[familyRecID], SkTypeface::kNormal);
- SkTypeface* face = this->getTypefaceForFontRec(fontRecID);
-
- SkPaint paint;
- paint.setTypeface(face);
- paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
-
- uint16_t glyphID;
- paint.textToGlyphs(&uni, sizeof(uni), &glyphID);
- if (glyphID != 0) {
- name->set(fFontFamilies[familyRecID].fFallbackName);
- return true;
- }
- }
- return false;
-}
-
-FallbackFontList* SkFontConfigInterfaceAndroid::findFallbackFontList(const SkLanguage& lang,
- bool isOriginal) {
- const SkString& langTag = lang.getTag();
- if (langTag.isEmpty()) {
- return &fDefaultFallbackList;
- }
-
- FallbackFontList* fallbackFontList;
- if (fFallbackFontDict.find(langTag.c_str(), langTag.size(), &fallbackFontList) ||
- fFallbackFontAliasDict.find(langTag.c_str(), langTag.size(), &fallbackFontList)) {
- return fallbackFontList;
- }
-
- // attempt a recursive fuzzy match
- SkLanguage parent = lang.getParent();
- fallbackFontList = findFallbackFontList(parent, false);
-
- // cache the original lang so we don't have to do the recursion again.
- if (isOriginal) {
- DEBUG_FONT(("---- Created fallback list alias for \"%s\"", langTag.c_str()));
- fFallbackFontAliasDict.set(langTag.c_str(), fallbackFontList);
- }
- return fallbackFontList;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool SkGetFallbackFamilyNameForChar(SkUnichar uni, const char* lang, SkString* name) {
- SkFontConfigInterfaceAndroid* fontConfig = getSingletonInterface();
- return fontConfig->getFallbackFamilyNameForChar(uni, lang, name);
-}
-
-void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
- const char* fontsdir) {
- gTestMainConfigFile = mainconf;
- gTestFallbackConfigFile = fallbackconf;
- gTestFontFilePrefix = fontsdir;
- SkASSERT(gTestMainConfigFile);
- SkASSERT(gTestFallbackConfigFile);
- SkASSERT(gTestFontFilePrefix);
- SkDEBUGF(("Use Test Config File Main %s, Fallback %s, Font Dir %s",
- gTestMainConfigFile, gTestFallbackConfigFile, gTestFontFilePrefix));
-}
-
-void SkGetTestFontConfiguration(const char** mainconf, const char** fallbackconf,
- const char** fontsdir) {
- *mainconf = gTestMainConfigFile;
- *fallbackconf = gTestFallbackConfigFile;
- *fontsdir = gTestFontFilePrefix;
-}
« no previous file with comments | « include/ports/SkTypeface_android.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698