summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authorjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-06 18:03:51 +0000
committerjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-06 18:03:51 +0000
commit1c0d89daeb89cb344f5852720ff4ea6edad8aad3 (patch)
tree14451754940535e9d86a0f60e374a4760176a143 /skia
parent897bd8cbf71370ec7a57446bc27e858336682632 (diff)
downloadchromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.zip
chromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.tar.gz
chromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.tar.bz2
Make SkFontHost_fontconfig support TTC font files.
In addition to this change, third_party/skia/src/port/SkFontHost_Freetype.cpp needs a couple of lines changed. The Skia part is at http://codereview.appspot.com/1847046/show BUG=50389 TEST=Install ttf-wqy-microhei package on Ubuntu and go to http://i18nl10n.com/chrome/ttc2.html. Latin letters in the 1st line should be monospaced while they're proportional in the second line. Review URL: http://codereview.chromium.org/2870073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55262 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ext/SkFontHost_fontconfig.cpp67
-rw-r--r--skia/ext/SkFontHost_fontconfig_direct.cpp55
-rw-r--r--skia/ext/SkFontHost_fontconfig_direct.h7
-rw-r--r--skia/ext/SkFontHost_fontconfig_impl.h22
-rw-r--r--skia/ext/SkFontHost_fontconfig_ipc.cpp20
-rw-r--r--skia/ext/SkFontHost_fontconfig_ipc.h6
6 files changed, 119 insertions, 58 deletions
diff --git a/skia/ext/SkFontHost_fontconfig.cpp b/skia/ext/SkFontHost_fontconfig.cpp
index 97d300b..68a3820 100644
--- a/skia/ext/SkFontHost_fontconfig.cpp
+++ b/skia/ext/SkFontHost_fontconfig.cpp
@@ -67,9 +67,11 @@ static unsigned global_next_remote_font_id;
// This is the maximum size of the font cache.
static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB
-// UniqueIds are encoded as (fileid << 8) | style
+// UniqueIds are encoded as (filefaceid << 8) | style
+// For system fonts, filefaceid = (fileid << 4) | face_index.
+// For remote fonts, filefaceid = fileid.
-static unsigned UniqueIdToFileId(unsigned uniqueid)
+static unsigned UniqueIdToFileFaceId(unsigned uniqueid)
{
return uniqueid >> 8;
}
@@ -79,18 +81,18 @@ static SkTypeface::Style UniqueIdToStyle(unsigned uniqueid)
return static_cast<SkTypeface::Style>(uniqueid & 0xff);
}
-static unsigned FileIdAndStyleToUniqueId(unsigned fileid,
- SkTypeface::Style style)
+static unsigned FileFaceIdAndStyleToUniqueId(unsigned filefaceid,
+ SkTypeface::Style style)
{
SkASSERT((style & 0xff) == style);
- return (fileid << 8) | static_cast<int>(style);
+ return (filefaceid << 8) | static_cast<int>(style);
}
static const unsigned kRemoteFontMask = 0x00800000u;
-static bool IsRemoteFont(unsigned fileid)
+static bool IsRemoteFont(unsigned filefaceid)
{
- return fileid & kRemoteFontMask;
+ return filefaceid & kRemoteFontMask;
}
class FontConfigTypeface : public SkTypeface {
@@ -102,7 +104,7 @@ public:
~FontConfigTypeface()
{
const uint32_t id = uniqueID();
- if (IsRemoteFont(UniqueIdToFileId(id))) {
+ if (IsRemoteFont(UniqueIdToFileFaceId(id))) {
SkAutoMutexAcquire ac(global_remote_font_map_lock);
std::map<uint32_t, std::pair<uint8_t*, size_t> >::iterator iter
= global_remote_fonts.find(id);
@@ -125,9 +127,9 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
if (familyFace) {
// Given the fileid we can ask fontconfig for the familyname of the
// font.
- const unsigned fileid = UniqueIdToFileId(familyFace->uniqueID());
- if (!GetFcImpl()->Match(
- &resolved_family_name, NULL, true /* fileid valid */, fileid, "",
+ const unsigned filefaceid = UniqueIdToFileFaceId(familyFace->uniqueID());
+ if (!GetFcImpl()->Match(&resolved_family_name, NULL,
+ true /* filefaceid valid */, filefaceid, "",
NULL, 0, NULL, NULL)) {
return NULL;
}
@@ -137,8 +139,9 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
bool bold = style & SkTypeface::kBold;
bool italic = style & SkTypeface::kItalic;
- unsigned fileid;
- if (!GetFcImpl()->Match(NULL, &fileid, false, -1, /* no fileid */
+ unsigned filefaceid;
+ if (!GetFcImpl()->Match(NULL, &filefaceid,
+ false, -1, /* no filefaceid */
resolved_family_name, data, bytelength,
&bold, &italic)) {
return NULL;
@@ -147,7 +150,8 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
(bold ? SkTypeface::kBold : 0) |
(italic ? SkTypeface::kItalic : 0));
- const unsigned id = FileIdAndStyleToUniqueId(fileid, resulting_style);
+ const unsigned id = FileFaceIdAndStyleToUniqueId(filefaceid,
+ resulting_style);
SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (resulting_style, id));
{
@@ -180,7 +184,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
unsigned id = 0;
{
SkAutoMutexAcquire ac(global_remote_font_map_lock);
- id = FileIdAndStyleToUniqueId(
+ id = FileFaceIdAndStyleToUniqueId(
global_next_remote_font_id | kRemoteFontMask, style);
if (++global_next_remote_font_id >= kRemoteFontMask)
@@ -206,7 +210,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
// static
bool SkFontHost::ValidFontID(SkFontID uniqueID) {
- if (IsRemoteFont(UniqueIdToFileId(uniqueID))) {
+ if (IsRemoteFont(UniqueIdToFileFaceId(uniqueID))) {
// remote font
SkAutoMutexAcquire ac(global_remote_font_map_lock);
return global_remote_fonts.find(uniqueID) != global_remote_fonts.end();
@@ -301,9 +305,9 @@ class SkFileDescriptorStream : public SkStream {
// static
SkStream* SkFontHost::OpenStream(uint32_t id)
{
- const unsigned fileid = UniqueIdToFileId(id);
+ const unsigned filefaceid = UniqueIdToFileFaceId(id);
- if (IsRemoteFont(fileid)) {
+ if (IsRemoteFont(filefaceid)) {
// remote font
SkAutoMutexAcquire ac(global_remote_font_map_lock);
std::map<uint32_t, std::pair<uint8_t*, size_t> >::const_iterator iter
@@ -315,7 +319,7 @@ SkStream* SkFontHost::OpenStream(uint32_t id)
}
// system font
- const int fd = GetFcImpl()->Open(fileid);
+ const int fd = GetFcImpl()->Open(filefaceid);
if (fd < 0)
return NULL;
@@ -329,3 +333,28 @@ size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar)
else
return 0; // nothing to do
}
+
+// static
+size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
+ int32_t* index) {
+ const unsigned filefaceid = UniqueIdToFileFaceId(fontID);
+
+ if (IsRemoteFont(filefaceid))
+ return 0;
+
+ if (index) {
+ *index = filefaceid & 0xfu;
+ // 1 is a bogus return value.
+ // We had better change the signature of this function in Skia
+ // to return bool to indicate success/failure and have another
+ // out param for fileName length.
+ if (!path)
+ return 1;
+ }
+
+ if (path)
+ SkASSERT(!"SkFontHost::GetFileName does not support the font path "
+ "retrieval.");
+
+ return 0;
+}
diff --git a/skia/ext/SkFontHost_fontconfig_direct.cpp b/skia/ext/SkFontHost_fontconfig_direct.cpp
index 15238bd..fd2853c 100644
--- a/skia/ext/SkFontHost_fontconfig_direct.cpp
+++ b/skia/ext/SkFontHost_fontconfig_direct.cpp
@@ -88,6 +88,17 @@ bool IsMetricCompatibleReplacement(const char* font_a, const char* font_b)
return class_a != OTHER && class_a == class_b;
}
+inline unsigned FileFaceIdToFileId(unsigned filefaceid)
+{
+ return filefaceid >> 4;
+}
+
+inline unsigned FileIdAndFaceIndexToFileFaceId(unsigned fileid, int face_index)
+{
+ SkASSERT((face_index & 0xfu) == face_index);
+ return (fileid << 4) | face_index;
+}
+
} // anonymous namespace
FontConfigDirect::FontConfigDirect()
@@ -111,8 +122,8 @@ static bool IsFallbackFontAllowed(const std::string& family)
}
bool FontConfigDirect::Match(std::string* result_family,
- unsigned* result_fileid,
- bool fileid_valid, unsigned fileid,
+ unsigned* result_filefaceid,
+ bool filefaceid_valid, unsigned filefaceid,
const std::string& family,
const void* data, size_t characters_bytes,
bool* is_bold, bool* is_italic) {
@@ -122,15 +133,21 @@ bool FontConfigDirect::Match(std::string* result_family,
SkAutoMutexAcquire ac(mutex_);
FcPattern* pattern = FcPatternCreate();
- if (fileid_valid) {
+ if (filefaceid_valid) {
const std::map<unsigned, std::string>::const_iterator
- i = fileid_to_filename_.find(fileid);
+ i = fileid_to_filename_.find(FileFaceIdToFileId(filefaceid));
if (i == fileid_to_filename_.end()) {
FcPatternDestroy(pattern);
return false;
}
-
- FcPatternAddString(pattern, FC_FILE, (FcChar8*) i->second.c_str());
+ int face_index = filefaceid & 0xfu;
+ FcPatternAddString(pattern, FC_FILE,
+ reinterpret_cast<const FcChar8*>(i->second.c_str()));
+ // face_index is added only when family is empty because it is not
+ // necessary to uniquiely identify a font if both file and
+ // family are given.
+ if (family.empty())
+ FcPatternAddInteger(pattern, FC_INDEX, face_index);
}
if (!family.empty()) {
FcPatternAddString(pattern, FC_FAMILY, (FcChar8*) family.c_str());
@@ -272,12 +289,18 @@ bool FontConfigDirect::Match(std::string* result_family,
FcFontSetDestroy(font_set);
return false;
}
- const std::string filename((char *) c_filename);
+ int face_index;
+ if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
+ FcFontSetDestroy(font_set);
+ return false;
+ }
+ const std::string filename(reinterpret_cast<char*>(c_filename));
- unsigned out_fileid;
- if (fileid_valid) {
- out_fileid = fileid;
+ unsigned out_filefaceid;
+ if (filefaceid_valid) {
+ out_filefaceid = filefaceid;
} else {
+ unsigned out_fileid;
const std::map<std::string, unsigned>::const_iterator
i = filename_to_fileid_.find(filename);
if (i == filename_to_fileid_.end()) {
@@ -287,10 +310,14 @@ bool FontConfigDirect::Match(std::string* result_family,
} else {
out_fileid = i->second;
}
+ // fileid stored in filename_to_fileid_ and fileid_to_filename_ is
+ // unique only up to the font file. We have to encode face_index for
+ // the out param.
+ out_filefaceid = FileIdAndFaceIndexToFileFaceId(out_fileid, face_index);
}
- if (result_fileid)
- *result_fileid = out_fileid;
+ if (result_filefaceid)
+ *result_filefaceid = out_filefaceid;
FcChar8* c_family;
if (FcPatternGetString(match, FC_FAMILY, 0, &c_family)) {
@@ -332,10 +359,10 @@ bool FontConfigDirect::Match(std::string* result_family,
return true;
}
-int FontConfigDirect::Open(unsigned fileid) {
+int FontConfigDirect::Open(unsigned filefaceid) {
SkAutoMutexAcquire ac(mutex_);
const std::map<unsigned, std::string>::const_iterator
- i = fileid_to_filename_.find(fileid);
+ i = fileid_to_filename_.find(FileFaceIdToFileId(filefaceid));
if (i == fileid_to_filename_.end())
return -1;
diff --git a/skia/ext/SkFontHost_fontconfig_direct.h b/skia/ext/SkFontHost_fontconfig_direct.h
index 8606523..e338633 100644
--- a/skia/ext/SkFontHost_fontconfig_direct.h
+++ b/skia/ext/SkFontHost_fontconfig_direct.h
@@ -30,15 +30,16 @@ class FontConfigDirect : public FontConfigInterface {
FontConfigDirect();
// FontConfigInterface implementation. Thread safe.
- virtual bool Match(std::string* result_family, unsigned* result_fileid,
- bool fileid_valid, unsigned fileid,
+ virtual bool Match(std::string* result_family, unsigned* result_filefaceid,
+ bool filefaceid_valid, unsigned filefaceid,
const std::string& family,
const void* characters, size_t characters_bytes,
bool* is_bold, bool* is_italic);
- virtual int Open(unsigned fileid);
+ virtual int Open(unsigned filefaceid);
private:
SkMutex mutex_;
+ // fileid stored in two maps below are unique per font file.
std::map<unsigned, std::string> fileid_to_filename_;
std::map<std::string, unsigned> filename_to_fileid_;
unsigned next_file_id_;
diff --git a/skia/ext/SkFontHost_fontconfig_impl.h b/skia/ext/SkFontHost_fontconfig_impl.h
index c34f3d9..49ccc9d 100644
--- a/skia/ext/SkFontHost_fontconfig_impl.h
+++ b/skia/ext/SkFontHost_fontconfig_impl.h
@@ -34,10 +34,10 @@ class FontConfigInterface {
/** Performs config match
*
* @param result_family (output) on success, the resulting family name.
- * @param result_fileid (output) on success, the resulting file id.
- * @param fileid_valid if true, then |fileid| is valid
- * @param fileid the fileid (as returned by this function) which we are
- * trying to match.
+ * @param result_filefaceid (output) on success, the resulting fileface id.
+ * @param filefaceid_valid if true, then |filefaceid| is valid
+ * @param filefaceid the filefaceid (as returned by this function)
+ * which we are trying to match.
* @param family (optional) the family of the font that we are trying to
* match. If the length of the |family| is greater then
* kMaxFontFamilyLength, this function should immediately return false.
@@ -46,21 +46,25 @@ class FontConfigInterface {
* @param is_bold (optional, set to NULL to ignore, in/out)
* @param is_italic (optional, set to NULL to ignore, in/out)
* @return true iff successful.
+ * Note that |filefaceid| uniquely identifies <font file, face_index) :
+ * system font: filefaceid =
+ * (fileid(unique per font file) << 4 | face_index)
+ * remote font: filefaceid = fileid
*/
virtual bool Match(
std::string* result_family,
- unsigned* result_fileid,
- bool fileid_valid,
- unsigned fileid,
+ unsigned* result_filefaceid,
+ bool filefaceid_valid,
+ unsigned filefaceid,
const std::string& family,
const void* characters,
size_t characters_bytes,
bool* is_bold,
bool* is_italic) = 0;
- /** Open a font file given the fileid as returned by Match
+ /** Open a font file given the filefaceid as returned by Match.
*/
- virtual int Open(unsigned fileid) = 0;
+ virtual int Open(unsigned filefaceid) = 0;
static const unsigned kMaxFontFamilyLength = 2048;
};
diff --git a/skia/ext/SkFontHost_fontconfig_ipc.cpp b/skia/ext/SkFontHost_fontconfig_ipc.cpp
index 0c95072..23a07f4 100644
--- a/skia/ext/SkFontHost_fontconfig_ipc.cpp
+++ b/skia/ext/SkFontHost_fontconfig_ipc.cpp
@@ -37,8 +37,8 @@ FontConfigIPC::~FontConfigIPC() {
}
bool FontConfigIPC::Match(std::string* result_family,
- unsigned* result_fileid,
- bool fileid_valid, unsigned fileid,
+ unsigned* result_filefaceid,
+ bool filefaceid_valid, unsigned filefaceid,
const std::string& family,
const void* characters, size_t characters_bytes,
bool* is_bold, bool* is_italic) {
@@ -47,9 +47,9 @@ bool FontConfigIPC::Match(std::string* result_family,
Pickle request;
request.WriteInt(METHOD_MATCH);
- request.WriteBool(fileid_valid);
- if (fileid_valid)
- request.WriteUInt32(fileid);
+ request.WriteBool(filefaceid_valid);
+ if (filefaceid_valid)
+ request.WriteUInt32(filefaceid);
request.WriteBool(is_bold && *is_bold);
request.WriteBool(is_bold && *is_italic);
@@ -74,17 +74,17 @@ bool FontConfigIPC::Match(std::string* result_family,
if (!result)
return false;
- uint32_t reply_fileid;
+ uint32_t reply_filefaceid;
std::string reply_family;
bool resulting_bold, resulting_italic;
- if (!reply.ReadUInt32(&iter, &reply_fileid) ||
+ if (!reply.ReadUInt32(&iter, &reply_filefaceid) ||
!reply.ReadString(&iter, &reply_family) ||
!reply.ReadBool(&iter, &resulting_bold) ||
!reply.ReadBool(&iter, &resulting_italic)) {
return false;
}
- *result_fileid = reply_fileid;
+ *result_filefaceid = reply_filefaceid;
if (result_family)
*result_family = reply_family;
@@ -96,10 +96,10 @@ bool FontConfigIPC::Match(std::string* result_family,
return true;
}
-int FontConfigIPC::Open(unsigned fileid) {
+int FontConfigIPC::Open(unsigned filefaceid) {
Pickle request;
request.WriteInt(METHOD_OPEN);
- request.WriteUInt32(fileid);
+ request.WriteUInt32(filefaceid);
int result_fd = -1;
uint8_t reply_buf[256];
diff --git a/skia/ext/SkFontHost_fontconfig_ipc.h b/skia/ext/SkFontHost_fontconfig_ipc.h
index aacec8c..9a10c6e 100644
--- a/skia/ext/SkFontHost_fontconfig_ipc.h
+++ b/skia/ext/SkFontHost_fontconfig_ipc.h
@@ -32,12 +32,12 @@ class FontConfigIPC : public FontConfigInterface {
~FontConfigIPC();
// FontConfigInterface implementation.
- virtual bool Match(std::string* result_family, unsigned* result_fileid,
- bool fileid_valid, unsigned fileid,
+ virtual bool Match(std::string* result_family, unsigned* result_filefaceid,
+ bool filefaceid_valid, unsigned filefaceid,
const std::string& family,
const void* characters, size_t characters_bytes,
bool* is_bold, bool* is_italic);
- virtual int Open(unsigned fileid);
+ virtual int Open(unsigned filefaceid);
enum Method {
METHOD_MATCH = 0,