aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-06 22:53:04 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-06 22:53:04 +0000
commit990d85f02ba6efaf6f3d75262d7ed650edc8afd5 (patch)
treea78ea0deb1c45b661ac1bdd25036cafc35229f9b /src/ports
parent2273f9b45fb78b0cc7df81f96f74b0c3c0e6cc37 (diff)
Add getFamilyNames to SkTypeface.
Review URL: https://codereview.chromium.org/21716005 git-svn-id: http://skia.googlecode.com/svn/trunk@10589 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp13
-rw-r--r--src/ports/SkFontHost_FreeType_common.h2
-rwxr-xr-xsrc/ports/SkFontHost_mac.cpp26
-rwxr-xr-xsrc/ports/SkFontHost_win.cpp129
-rw-r--r--src/ports/SkFontHost_win_dw.cpp50
5 files changed, 154 insertions, 66 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 3a32ea40c4..c5542a9ddf 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -17,6 +17,7 @@
#include "SkGlyph.h"
#include "SkMask.h"
#include "SkMaskGamma.h"
+#include "SkOTUtils.h"
#include "SkAdvancedTypefaceMetrics.h"
#include "SkScalerContext.h"
#include "SkStream.h"
@@ -1402,6 +1403,18 @@ int SkTypeface_FreeType::onCountGlyphs() const {
return fGlyphCount;
}
+SkTypeface::LocalizedStrings* SkTypeface_FreeType::onGetFamilyNames() const {
+ SkTypeface::LocalizedStrings* nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
+ if (NULL == nameIter) {
+ SkString familyName;
+ this->getFamilyName(&familyName);
+ SkString language("und"); //undetermined
+ nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
+ }
+ return nameIter;
+}
+
int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const {
AutoFTAccess fta(this);
FT_Face face = fta.face();
diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h
index d3df9ce85b..5c069d042d 100644
--- a/src/ports/SkFontHost_FreeType_common.h
+++ b/src/ports/SkFontHost_FreeType_common.h
@@ -64,6 +64,8 @@ protected:
int glyphCount) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE;
+ virtual LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE;
+
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const SK_OVERRIDE;
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 71fa5ebdb0..9600730f67 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -95,6 +95,7 @@ public:
operator CFRef() const { return fCFRef; }
CFRef get() const { return fCFRef; }
+ CFRef* operator&() { SkASSERT(fCFRef == NULL); return &fCFRef; }
private:
CFRef fCFRef;
};
@@ -453,6 +454,7 @@ protected:
virtual int onGetUPEM() const SK_OVERRIDE;
virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
+ virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE;
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const SK_OVERRIDE;
@@ -1748,6 +1750,30 @@ int SkTypeface_Mac::onGetUPEM() const {
return CGFontGetUnitsPerEm(cgFont);
}
+SkTypeface::LocalizedStrings* SkTypeface_Mac::onGetFamilyNames() const {
+ SkTypeface::LocalizedStrings* nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
+ if (NULL == nameIter) {
+ AutoCFRelease<CFStringRef> cfLanguage;
+ AutoCFRelease<CFStringRef> cfFamilyName(
+ CTFontCopyLocalizedName(fFontRef, kCTFontFamilyNameKey, &cfLanguage));
+
+ SkString skLanguage;
+ SkString skFamilyName;
+ if (cfLanguage.get()) {
+ CFStringToSkString(cfLanguage.get(), &skLanguage);
+ } else {
+ skLanguage = "und"; //undetermined
+ }
+ if (cfFamilyName.get()) {
+ CFStringToSkString(cfFamilyName.get(), &skFamilyName);
+ }
+
+ nameIter = new SkOTUtils::LocalizedStrings_SingleName(skFamilyName, skLanguage);
+ }
+ return nameIter;
+}
+
// If, as is the case with web fonts, the CTFont data isn't available,
// the CGFont data may work. While the CGFont may always provide the
// right result, leave the CTFont code path to minimize disruption.
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index fe646d74b9..d52774ca6d 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -16,6 +16,7 @@
#include "SkGlyph.h"
#include "SkMaskGamma.h"
#include "SkOTTable_maxp.h"
+#include "SkOTTable_name.h"
#include "SkOTUtils.h"
#include "SkPath.h"
#include "SkSFNTHeader.h"
@@ -96,6 +97,26 @@ static void tchar_to_skstring(const TCHAR t[], SkString* s) {
#endif
}
+static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkString* familyName) {
+ int fontNameLen; //length of fontName in TCHARS.
+ if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
+ call_ensure_accessible(lf);
+ if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
+ fontNameLen = 0;
+ }
+ }
+
+ SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
+ if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
+ call_ensure_accessible(lf);
+ if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
+ fontName[0] = 0;
+ }
+ }
+
+ tchar_to_skstring(fontName.get(), familyName);
+}
+
static void make_canonical(LOGFONT* lf) {
lf->lfHeight = -2048;
lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY;
@@ -223,10 +244,6 @@ public:
(textMetric.tmPitchAndFamily & TMPF_DEVICE));
}
- void getFamilyName(SkString* name) const {
- tchar_to_skstring(fLogFont.lfFaceName, name);
- }
-
LOGFONT fLogFont;
bool fSerializeAsStream;
bool fCanBeLCD;
@@ -251,6 +268,7 @@ protected:
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE;
virtual int onGetUPEM() const SK_OVERRIDE;
+ virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE;
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const SK_OVERRIDE;
@@ -1715,21 +1733,8 @@ void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
HDC deviceContext = ::CreateCompatibleDC(NULL);
HFONT savefont = (HFONT)SelectObject(deviceContext, font);
- int fontNameLen; //length of fontName in TCHARS.
- if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
- call_ensure_accessible(fLogFont);
- if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
- fontNameLen = 0;
- }
- }
-
- SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
- if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
- call_ensure_accessible(fLogFont);
- if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
- fontName[0] = 0;
- }
- }
+ SkString familyName;
+ dcfontname_to_skstring(deviceContext, fLogFont, &familyName);
if (deviceContext) {
::SelectObject(deviceContext, savefont);
@@ -1739,9 +1744,6 @@ void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
::DeleteObject(font);
}
- SkString familyName;
- tchar_to_skstring(fontName.get(), &familyName);
-
desc->setFamilyName(familyName.c_str());
*isLocalStream = this->fSerializeAsStream;
}
@@ -2054,6 +2056,18 @@ int LogFontTypeface::onGetUPEM() const {
return upem;
}
+SkTypeface::LocalizedStrings* LogFontTypeface::onGetFamilyNames() const {
+ SkTypeface::LocalizedStrings* nameIter =
+ SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
+ if (NULL == nameIter) {
+ SkString familyName;
+ this->getFamilyName(&familyName);
+ SkString language("und"); //undetermined
+ nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
+ }
+ return nameIter;
+}
+
int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
SkSFNTHeader header;
if (sizeof(header) != this->onGetTableData(0, 0, sizeof(header), &header)) {
@@ -2191,21 +2205,25 @@ SkTypeface* LogFontTypeface::onRefMatchingStyle(Style style) const {
#include "SkFontMgr.h"
#include "SkDataTable.h"
-static bool valid_logfont_for_enum(const LOGFONT& lf, DWORD fontType) {
- return TRUETYPE_FONTTYPE == fontType
- && lf.lfFaceName[0]
- && lf.lfFaceName[0] != '@'
- && OUT_STROKE_PRECIS == lf.lfOutPrecision
- // without the chraset check, we got LOTS of dups of the same font
- // is there a better check (other than searching the array for
- // the same name?
- && 0 == lf.lfCharSet
- ;
-}
-
-static int CALLBACK enum_fonts_proc(const LOGFONT* lf, const TEXTMETRIC*,
- DWORD fontType, LPARAM builderParam) {
- if (valid_logfont_for_enum(*lf, fontType)) {
+static bool valid_logfont_for_enum(const LOGFONT& lf) {
+ // TODO: Vector FON is unsupported and should not be listed.
+ return
+ // Ignore implicit vertical variants.
+ lf.lfFaceName[0] && lf.lfFaceName[0] != '@'
+
+ // DEFAULT_CHARSET is used to get all fonts, but also implies all
+ // character sets. Filter assuming all fonts support ANSI_CHARSET.
+ && ANSI_CHARSET == lf.lfCharSet
+ ;
+}
+
+/** An EnumFontFamExProc implementation which interprets builderParam as
+ * an SkTDArray<ENUMLOGFONTEX>* and appends logfonts which
+ * pass the valid_logfont_for_enum predicate.
+ */
+static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*,
+ DWORD fontType, LPARAM builderParam) {
+ if (valid_logfont_for_enum(*lf)) {
SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderParam;
*array->append() = *(ENUMLOGFONTEX*)lf;
}
@@ -2221,8 +2239,13 @@ static SkFontStyle compute_fontstyle(const LOGFONT& lf) {
class SkFontStyleSetGDI : public SkFontStyleSet {
public:
SkFontStyleSetGDI(const TCHAR familyName[]) {
+ LOGFONT lf;
+ sk_bzero(&lf, sizeof(lf));
+ lf.lfCharSet = DEFAULT_CHARSET;
+ _tcscpy_s(lf.lfFaceName, familyName);
+
HDC hdc = ::CreateCompatibleDC(NULL);
- ::EnumFonts(hdc, familyName, enum_fonts_proc, (LPARAM)&fArray);
+ ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0);
::DeleteDC(hdc);
}
@@ -2260,29 +2283,9 @@ private:
SkTDArray<ENUMLOGFONTEX> fArray;
};
-static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC* tm,
- DWORD fontType, LPARAM builderParam) {
- if (valid_logfont_for_enum(*lf, fontType)) {
- SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderParam;
- *array->append() = *(ENUMLOGFONTEX*)lf;
-#if 0
- SkString str;
- tchar_to_skstring(lf->lfFaceName, &str);
- SkDebugf("fam:%s height:%d width:%d esc:%d orien:%d weight:%d ital:%d char:%d clip:%d qual:%d pitch:%d\n",
- str.c_str(), lf->lfHeight, lf->lfWidth, lf->lfEscapement, lf->lfOrientation,
- lf->lfWeight, lf->lfItalic, lf->lfCharSet, lf->lfClipPrecision, lf->lfQuality,
- lf->lfPitchAndFamily);
-#endif
- }
- return 1; // non-zero means continue
-}
-
class SkFontMgrGDI : public SkFontMgr {
- void init() {
- if (!fLogFontArray.isEmpty()) {
- return;
- }
-
+public:
+ SkFontMgrGDI() {
LOGFONT lf;
sk_bzero(&lf, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET;
@@ -2292,23 +2295,17 @@ class SkFontMgrGDI : public SkFontMgr {
::DeleteDC(hdc);
}
-public:
- SkFontMgrGDI() {}
-
protected:
virtual int onCountFamilies() SK_OVERRIDE {
- this->init();
return fLogFontArray.count();
}
virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
- this->init();
SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName);
}
virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
- this->init();
SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
return SkNEW_ARGS(SkFontStyleSetGDI, (fLogFontArray[index].elfLogFont.lfFaceName));
}
diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
index beec056e93..cee8b362b2 100644
--- a/src/ports/SkFontHost_win_dw.cpp
+++ b/src/ports/SkFontHost_win_dw.cpp
@@ -495,6 +495,7 @@ protected:
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE;
virtual int onGetUPEM() const SK_OVERRIDE;
+ virtual SkTypeface::LocalizedStrings* onGetFamilyNames() const SK_OVERRIDE;
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const SK_OVERRIDE;
@@ -1088,6 +1089,54 @@ int DWriteFontTypeface::onGetUPEM() const {
return metrics.designUnitsPerEm;
}
+class LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings {
+public:
+ /** Takes ownership of the IDWriteLocalizedStrings. */
+ explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings)
+ : fIndex(0), fStrings(strings)
+ { }
+
+ virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE {
+ if (fIndex >= fStrings->GetCount()) {
+ return false;
+ }
+
+ // String
+ UINT32 stringLength;
+ HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get string length.");
+ stringLength += 1;
+
+ SkSMallocWCHAR wString(stringLength);
+ HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could not get string.");
+
+ HRB(wchar_to_skstring(wString.get(), &localizedString->fString));
+
+ // Locale
+ UINT32 localeLength;
+ HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not get locale length.");
+ localeLength += 1;
+
+ SkSMallocWCHAR wLocale(localeLength);
+ HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Could not get locale.");
+
+ HRB(wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
+
+ ++fIndex;
+ return true;
+ }
+
+private:
+ UINT32 fIndex;
+ SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
+};
+
+SkTypeface::LocalizedStrings* DWriteFontTypeface::onGetFamilyNames() const {
+ SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
+ HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
+
+ return new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
+}
+
int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
if (type != DWRITE_FONT_FACE_TYPE_CFF &&
@@ -1656,6 +1705,7 @@ public:
DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
SkTScopedComPtr<IDWriteFont> font;
+ // TODO: perhaps use GetMatchingFonts and get the least simulated?
HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
"Could not match font in family.");