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

Unified Diff: trunk/src/ports/SkFontConfigInterface_direct.cpp

Issue 14305007: check-point for linux fontmgr impl (Closed) Base URL: http://skia.googlecode.com/svn/
Patch Set: Created 7 years, 8 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 | « trunk/include/ports/SkFontStyle.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: trunk/src/ports/SkFontConfigInterface_direct.cpp
===================================================================
--- trunk/src/ports/SkFontConfigInterface_direct.cpp (revision 8807)
+++ trunk/src/ports/SkFontConfigInterface_direct.cpp (working copy)
@@ -13,9 +13,91 @@
#include <fontconfig/fontconfig.h>
+#include "SkBuffer.h"
#include "SkFontConfigInterface.h"
#include "SkStream.h"
+size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const {
+ size_t size = sizeof(fID) + sizeof(fTTCIndex);
+ size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, width, italic
+ size += sizeof(int32_t) + fString.size(); // store length+data
+ if (addr) {
+ SkWBuffer buffer(addr, size);
+
+ buffer.write32(fID);
+ buffer.write32(fTTCIndex);
+ buffer.write32(fString.size());
+ buffer.write32(fStyle.weight());
+ buffer.write32(fStyle.width());
+ buffer.write8(fStyle.slant());
+ buffer.write(fString.c_str(), fString.size());
+ buffer.padToAlign4();
+
+ SkASSERT(buffer.pos() == size);
+ }
+ return size;
+}
+
+size_t SkFontConfigInterface::FontIdentity::readFromMemory(const void* addr,
+ size_t size) {
+ SkRBuffer buffer(addr, size);
+
+ fID = buffer.readU32();
+ fTTCIndex = buffer.readU32();
+ size_t strLen = buffer.readU32();
+ int weight = buffer.readU32();
+ int width = buffer.readU32();
+ SkFontStyle::Slant slant = (SkFontStyle::Slant)buffer.readU8();
+ fStyle = SkFontStyle(weight, width, slant);
+ fString.resize(strLen);
+ buffer.read(fString.writable_str(), strLen);
+ buffer.skipToAlign4();
+
+ return buffer.pos(); // the actual number of bytes read
+}
+
+#ifdef SK_DEBUG
+static void make_iden(SkFontConfigInterface::FontIdentity* iden) {
+ iden->fID = 10;
+ iden->fTTCIndex = 2;
+ iden->fString.set("Hello world");
+ iden->fStyle = SkFontStyle(300, 6, SkFontStyle::kItalic_Slant);
+}
+
+static void test_writeToMemory(const SkFontConfigInterface::FontIdentity& iden0,
+ int initValue) {
+ SkFontConfigInterface::FontIdentity iden1;
+
+ size_t size0 = iden0.writeToMemory(NULL);
+
+ SkAutoMalloc storage(size0);
+ memset(storage.get(), initValue, size0);
+
+ size_t size1 = iden0.writeToMemory(storage.get());
+ SkASSERT(size0 == size1);
+
+ SkASSERT(iden0 != iden1);
+ size_t size2 = iden1.readFromMemory(storage.get(), size1);
+ SkASSERT(size2 == size1);
+ SkASSERT(iden0 == iden1);
+}
+
+static void fontconfiginterface_unittest() {
+ SkFontConfigInterface::FontIdentity iden0, iden1;
+
+ SkASSERT(iden0 == iden1);
+
+ make_iden(&iden0);
+ SkASSERT(iden0 != iden1);
+
+ make_iden(&iden1);
+ SkASSERT(iden0 == iden1);
+
+ test_writeToMemory(iden0, 0);
+ test_writeToMemory(iden0, 0);
+}
+#endif
+
class SkFontConfigInterfaceDirect : public SkFontConfigInterface {
public:
SkFontConfigInterfaceDirect();
@@ -51,23 +133,6 @@
return gDirect;
}
-#if 0
-int SkFontConfigInterface::countFamilies() { return 0; }
-
-int SkFontConfigInterface::getFamilySet(int index, SkString* outFamilyName,
- FontIdentity outIdentities[],
- int maxCount) {
- return 0;
-}
-
-int SkFontConfigInterface::matchFamilySet(const char familyName[],
- SkString* outFamilyName,
- FontIdentity outIdentities[],
- int maxCount) {
- return 0;
-}
-#endif
-
///////////////////////////////////////////////////////////////////////////////
// Returns the string from the pattern, or NULL
@@ -354,7 +419,11 @@
#define kMaxFontFamilyLength 2048
SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() {
+ SkAutoMutexAcquire ac(mutex_);
+
FcInit();
+
+ SkDEBUGCODE(fontconfiginterface_unittest();)
}
SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() {
@@ -490,6 +559,8 @@
}
SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
+ SkAutoMutexAcquire ac(mutex_);
+
FcPattern* pat = FcPatternCreate();
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0);
if (NULL == os) {
@@ -523,5 +594,130 @@
bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[],
SkString* outFamilyName,
SkTArray<FontIdentity>* ids) {
+ SkAutoMutexAcquire ac(mutex_);
+
+#if 0
+ std::string familyStr(familyName ? familyName : "");
+ if (familyStr.length() > kMaxFontFamilyLength) {
+ return false;
+ }
+
+ SkAutoMutexAcquire ac(mutex_);
+
+ FcPattern* pattern = FcPatternCreate();
+
+ if (familyName) {
+ FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
+ }
+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+
+ FcConfigSubstitute(NULL, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ // Font matching:
+ // CSS often specifies a fallback list of families:
+ // font-family: a, b, c, serif;
+ // However, fontconfig will always do its best to find *a* font when asked
+ // for something so we need a way to tell if the match which it has found is
+ // "good enough" for us. Otherwise, we can return NULL which gets piped up
+ // and lets WebKit know to try the next CSS family name. However, fontconfig
+ // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
+ // wish to support that.
+ //
+ // Thus, if a specific family is requested we set @family_requested. Then we
+ // record two strings: the family name after config processing and the
+ // family name after resolving. If the two are equal, it's a good match.
+ //
+ // So consider the case where a user has mapped Arial to Helvetica in their
+ // config.
+ // requested family: "Arial"
+ // post_config_family: "Helvetica"
+ // post_match_family: "Helvetica"
+ // -> good match
+ //
+ // and for a missing font:
+ // requested family: "Monaco"
+ // post_config_family: "Monaco"
+ // post_match_family: "Times New Roman"
+ // -> BAD match
+ //
+ // However, we special-case fallback fonts; see IsFallbackFontAllowed().
+
+ const char* post_config_family = get_name(pattern, FC_FAMILY);
+
+ FcResult result;
+ FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
+ if (!font_set) {
+ FcPatternDestroy(pattern);
+ return false;
+ }
+
+ FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
+ if (!match) {
+ FcPatternDestroy(pattern);
+ FcFontSetDestroy(font_set);
+ return false;
+ }
+
+ FcPatternDestroy(pattern);
+
+ // From here out we just extract our results from 'match'
+
+ if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResultMatch) {
+ FcFontSetDestroy(font_set);
+ return false;
+ }
+
+ FcChar8* c_filename;
+ if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) {
+ FcFontSetDestroy(font_set);
+ return false;
+ }
+
+ int face_index;
+ if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
+ FcFontSetDestroy(font_set);
+ return false;
+ }
+
+ FcFontSetDestroy(font_set);
+
+ if (outIdentity) {
+ outIdentity->fTTCIndex = face_index;
+ outIdentity->fString.set((const char*)c_filename);
+ }
+ if (outFamilyName) {
+ outFamilyName->set((const char*)post_config_family);
+ }
+ if (outStyle) {
+ *outStyle = GetFontStyle(match);
+ }
+ return true;
+
+////////////////////
+
+ int count;
+ FcPattern** match = MatchFont(font_set, post_config_family, &count);
+ if (!match) {
+ FcPatternDestroy(pattern);
+ FcFontSetDestroy(font_set);
+ return NULL;
+ }
+
+ FcPatternDestroy(pattern);
+
+ SkTDArray<FcPattern*> trimmedMatches;
+ for (int i = 0; i < count; ++i) {
+ const char* justName = find_just_name(get_name(match[i], FC_FILE));
+ if (!is_lower(*justName)) {
+ *trimmedMatches.append() = match[i];
+ }
+ }
+
+ SkFontStyleSet_FC* sset = SkNEW_ARGS(SkFontStyleSet_FC,
+ (trimmedMatches.begin(),
+ trimmedMatches.count()));
+#endif
return false;
}
+
« no previous file with comments | « trunk/include/ports/SkFontStyle.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698