зеркало из https://github.com/mozilla/moz-skia.git
Disable automatic font fallback of SkFontHost_android when building for WebKit
The internal font fallback mechanism prevents WebKit from getting the properties of the actually used font. Disable the internal fallback mechanism when building for WebKit and add SkGetFallbackFamilyNameForChar() to let the upper level know the fallback font for individial characters. This commits a change that was submitted for review by... wangxianzhu1 @ https://codereview.appspot.com/6572059/ BUG=913 (http://code.google.com/p/skia/issues/detail?id=913) Review URL: https://codereview.appspot.com/6640048 git-svn-id: http://skia.googlecode.com/svn/trunk@5866 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
f04c40ef1e
Коммит
bae1712d2e
|
@ -58,6 +58,19 @@ SK_API const char* SkGetFallbackScriptID(FallbackScripts script);
|
|||
*/
|
||||
SK_API FallbackScripts SkGetFallbackScriptFromID(const char* id);
|
||||
|
||||
/**
|
||||
* Return a new typeface of the font in the fallback font list containing
|
||||
* the specified chararacter. If no typeface is found, returns null.
|
||||
*/
|
||||
SK_API SkTypeface* SkCreateFallbackTypefaceForChar(SkUnichar uni,
|
||||
SkTypeface::Style style);
|
||||
|
||||
/**
|
||||
* Get the family name of the font in the fallback font list containing
|
||||
* the specified chararacter. if no font is found, returns false.
|
||||
*/
|
||||
SK_API bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name);
|
||||
|
||||
/**
|
||||
* For test only.
|
||||
* Load font config from given xml files, instead of those from Android system.
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "SkFontHost.h"
|
||||
#include "SkFontDescriptor.h"
|
||||
#include "SkGlyphCache.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkDescriptor.h"
|
||||
#include "SkMMapStream.h"
|
||||
|
@ -547,6 +546,7 @@ static void load_font_info() {
|
|||
malloc((names.count() + 1) * sizeof(char*));
|
||||
if (nameList == NULL) {
|
||||
// shouldn't get here
|
||||
SkDEBUGFAIL("Failed to allocate nameList");
|
||||
break;
|
||||
}
|
||||
if (gDefaultNames == NULL) {
|
||||
|
@ -602,7 +602,7 @@ static void init_system_fonts() {
|
|||
|
||||
load_font_info();
|
||||
|
||||
const FontInitRec* rec = gSystemFonts;
|
||||
FontInitRec* rec = gSystemFonts;
|
||||
SkTypeface* firstInFamily = NULL;
|
||||
int fallbackCount = 0;
|
||||
|
||||
|
@ -647,6 +647,17 @@ static void init_system_fonts() {
|
|||
rec[i].fFileName, fallbackCount, tf->uniqueID());
|
||||
#endif
|
||||
gFallbackFonts[fallbackCount++] = tf->uniqueID();
|
||||
|
||||
// Use the font file name as the name of the typeface.
|
||||
const char **nameList = (const char**)malloc(2 * sizeof(char*));
|
||||
if (nameList == NULL) {
|
||||
// shouldn't get here
|
||||
SkDEBUGFAIL("Failed to allocate nameList");
|
||||
break;
|
||||
}
|
||||
nameList[0] = rec[i].fFileName;
|
||||
nameList[1] = NULL;
|
||||
rec[i].fNames = nameList;
|
||||
}
|
||||
|
||||
firstInFamily = tf;
|
||||
|
@ -882,6 +893,13 @@ size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
|
|||
}
|
||||
|
||||
SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
||||
#ifdef SK_BUILD_FOR_ANDROID_NDK
|
||||
// Skia does not support font fallback for ndk applications in order to
|
||||
// enable clients such as WebKit to customize their font selection.
|
||||
// Clients can use GetFallbackFamilyNameForChar() to get the fallback
|
||||
// font for individual characters.
|
||||
return 0;
|
||||
#else
|
||||
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
|
||||
|
||||
load_system_fonts();
|
||||
|
@ -917,6 +935,7 @@ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
|||
// i.e. gFallbackFonts[0] != 0.
|
||||
const SkTypeface* firstTypeface = find_from_uniqueID(list[0]);
|
||||
return find_typeface(firstTypeface, origTypeface->style())->uniqueID();
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -926,10 +945,6 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Make sure system fonts are loaded first to comply with the assumption
|
||||
// that the font's uniqueID can be found using the find_uniqueID method.
|
||||
load_system_fonts();
|
||||
|
||||
bool isFixedWidth;
|
||||
SkTypeface::Style style;
|
||||
|
||||
|
@ -990,30 +1005,36 @@ static const int gFBScriptInfoCount = sizeof(gFBScriptInfo) / sizeof(FBScriptInf
|
|||
// ensure that if any value is added to the public enum it is also added here
|
||||
SK_COMPILE_ASSERT(gFBScriptInfoCount == kFallbackScriptNumber, FBScript_count_mismatch);
|
||||
|
||||
// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
|
||||
static SkFontID findFontIDForChar(SkUnichar uni, SkTypeface::Style style) {
|
||||
gFamilyHeadAndNameListMutex.acquire();
|
||||
SkTypeface* face = find_best_face(gDefaultFamily, style);
|
||||
gFamilyHeadAndNameListMutex.release();
|
||||
if (!face) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool typefaceContainsChar(SkTypeface* face, SkUnichar uni) {
|
||||
SkPaint paint;
|
||||
paint.setTypeface(face);
|
||||
paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
|
||||
|
||||
SkAutoGlyphCache autoCache(paint, NULL);
|
||||
SkGlyphCache* cache = autoCache.getCache();
|
||||
SkFontID fontID = 0;
|
||||
uint16_t glyphID;
|
||||
paint.textToGlyphs(&uni, sizeof(uni), &glyphID);
|
||||
return glyphID != 0;
|
||||
}
|
||||
|
||||
SkScalerContext* ctx = cache->getScalerContext();
|
||||
if (ctx) {
|
||||
return ctx->findTypefaceIdForChar(uni);
|
||||
static SkTypeface* findFallbackTypefaceForChar(SkUnichar uni) {
|
||||
SkASSERT(gFallbackFonts);
|
||||
const uint32_t* list = gFallbackFonts;
|
||||
for (int i = 0; list[i] != 0; i++) {
|
||||
SkTypeface* face = find_from_uniqueID(list[i]);
|
||||
if (typefaceContainsChar(face, uni)) {
|
||||
return face;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SkFontID findFallbackFontIDForChar(SkUnichar uni, SkTypeface::Style style) {
|
||||
const SkTypeface* tf = findFallbackTypefaceForChar(uni);
|
||||
if (!tf) {
|
||||
return 0;
|
||||
}
|
||||
return find_typeface(tf, style)->uniqueID();
|
||||
}
|
||||
|
||||
// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
|
||||
static void initFBScriptInfo() {
|
||||
if (gFBScriptInitialized) {
|
||||
|
@ -1030,7 +1051,7 @@ static void initFBScriptInfo() {
|
|||
// selects the best available style for the desired font. However, if
|
||||
// bold is requested and no bold font exists for the typeface containing
|
||||
// the character the next best style is chosen (e.g. normal).
|
||||
scriptInfo.fFontID = findFontIDForChar(scriptInfo.fChar, scriptInfo.fStyle);
|
||||
scriptInfo.fFontID = findFallbackFontIDForChar(scriptInfo.fChar, scriptInfo.fStyle);
|
||||
#if SK_DEBUG_FONTS
|
||||
SkDebugf("gFBScriptInfo[%s] --> %d", scriptInfo.fScriptID, scriptInfo.fFontID);
|
||||
#endif
|
||||
|
@ -1084,6 +1105,34 @@ FallbackScripts SkGetFallbackScriptFromID(const char* id) {
|
|||
return kFallbackScriptNumber; // Use kFallbackScriptNumber as an invalid value.
|
||||
}
|
||||
|
||||
SkTypeface* SkCreateFallbackTypefaceForChar(SkUnichar uni,
|
||||
SkTypeface::Style style) {
|
||||
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
|
||||
load_system_fonts();
|
||||
|
||||
SkTypeface* tf = findFallbackTypefaceForChar(uni);
|
||||
if (!tf) {
|
||||
return NULL;
|
||||
}
|
||||
tf = find_typeface(tf, style);
|
||||
// we ref(), since the semantic is to return a new instance
|
||||
tf->ref();
|
||||
return tf;
|
||||
}
|
||||
|
||||
bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) {
|
||||
SkASSERT(name);
|
||||
SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
|
||||
load_system_fonts();
|
||||
|
||||
const SkTypeface* tf = findFallbackTypefaceForChar(uni);
|
||||
if (!tf) {
|
||||
return false;
|
||||
}
|
||||
name->set(find_family_name(tf));
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkUseTestFontConfigFile(const char* mainconf, const char* fallbackconf,
|
||||
const char* fontsdir) {
|
||||
gTestMainConfigFile = mainconf;
|
||||
|
|
Загрузка…
Ссылка в новой задаче