refactoring for SK_FONTHOST_USES_FONTMGR option
BUG=
R=bungeman@google.com
Review URL: https://codereview.chromium.org/21149008
git-svn-id: http://skia.googlecode.com/svn/trunk@10440 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h
index 4c5013f..e847b76 100644
--- a/include/core/SkFontHost.h
+++ b/include/core/SkFontHost.h
@@ -12,6 +12,8 @@
#include "SkTypeface.h"
+//#define SK_FONTHOST_USES_FONTMGR
+
class SkDescriptor;
class SkScalerContext;
struct SkScalerContextRec;
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index 429a24b..fccbe1f 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -240,6 +240,17 @@
SkStream* openStream(int* ttcIndex) const;
/**
+ * Search within this typeface's family for a best match to the
+ * specified style, and return a ref to that typeface. Note: the
+ * returned object could be this, if it is the best match, or it
+ * could be a different typeface. Either way, the caller must balance
+ * this call with unref() on the returned object.
+ *
+ * Will never return NULL.
+ */
+ SkTypeface* refMatchingStyle(Style) const;
+
+ /**
* Return a scalercontext for the given descriptor. If this fails, then
* if allowFailure is true, this returns NULL, else it returns a
* dummy scalercontext that will not crash, but will draw nothing.
@@ -287,6 +298,13 @@
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
size_t length, void* data) const;
+ // TODO: make this pure-virtual when all ports have overridden it
+ virtual SkTypeface* onRefMatchingStyle(Style styleBits) const {
+ SkASSERT(!"unimplemented");
+ this->ref();
+ return const_cast<SkTypeface*>(this);
+ }
+
private:
SkFontID fUniqueID;
Style fStyle;
diff --git a/include/ports/SkFontMgr.h b/include/ports/SkFontMgr.h
index 09df51e..d243825 100644
--- a/include/ports/SkFontMgr.h
+++ b/include/ports/SkFontMgr.h
@@ -31,6 +31,8 @@
typedef SkRefCnt INHERITED;
};
+class SkTypeface;
+
class SK_API SkFontMgr : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkFontMgr)
@@ -73,6 +75,9 @@
*/
SkTypeface* createFromFile(const char path[], int ttcIndex = 0);
+ SkTypeface* legacyCreateTypeface(const char familyName[],
+ unsigned typefaceStyleBits);
+
/**
* Return a ref to the default fontmgr. The caller must call unref() on
* the returned object.
@@ -95,6 +100,9 @@
virtual SkTypeface* onCreateFromStream(SkStream*, int ttcIndex) = 0;
virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) = 0;
+ // TODO: make this pure-virtual once all ports know about it
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits);
private:
static SkFontMgr* Factory(); // implemented by porting layer
diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp
index 734b3aa..11f6813 100644
--- a/src/core/SkFontHost.cpp
+++ b/src/core/SkFontHost.cpp
@@ -68,7 +68,6 @@
#include "SkFontMgr.h"
-
SK_DEFINE_INST_COUNT(SkFontStyleSet)
class SkEmptyFontStyleSet : public SkFontStyleSet {
@@ -174,6 +173,17 @@
return this->onCreateFromFile(path, ttcIndex);
}
+SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[],
+ unsigned styleBits) {
+ return this->onLegacyCreateTypeface(familyName, styleBits);
+}
+
+SkTypeface* SkFontMgr::onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) {
+ SkASSERT(!"unimplemented");
+ return NULL;
+}
+
SkFontMgr* SkFontMgr::RefDefault() {
static SkFontMgr* gFM;
if (NULL == gFM) {
@@ -185,3 +195,43 @@
}
return SkRef(gFM);
}
+
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_FONTHOST_USES_FONTMGR
+
+#if 0
+static SkFontStyle TypefaceStyleBitsToFontStyle(SkTypeface::Style styleBits) {
+ SkFontStyle::Weight weight = (styleBits & SkTypeface::kBold) ?
+ SkFontStyle::kBold_Weight :
+ SkFontStyle::kNormal_Weight;
+ SkFontStyle::Width width = SkFontStyle::kNormal_Width;
+ SkFontStyle::Slant slant = (styleBits & SkTypeface::kItalic) ?
+ SkFontStyle::kUpright_Slant :
+ SkFontStyle::kItalic_Slant;
+ return SkFontStyle(weight, width, slant);
+}
+#endif
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+ const char familyName[],
+ SkTypeface::Style style) {
+ if (familyFace) {
+ return familyFace->refMatchingStyle(style);
+ } else {
+ SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+ return fm->legacyCreateTypeface(familyName, style);
+ }
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+ return fm->createFromFile(path);
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+ return fm->createFromStream(stream);
+}
+
+#endif
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index bea7985..915b0e3 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -209,6 +209,10 @@
return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
}
+SkTypeface* SkTypeface::refMatchingStyle(Style style) const {
+ return this->onRefMatchingStyle(style);
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 2586dfd..381c20a 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -250,6 +250,7 @@
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE;
virtual int onGetUPEM() const SK_OVERRIDE;
+ virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE;
};
class FontMemResourceTypeface : public LogFontTypeface {
@@ -522,10 +523,10 @@
//////////////////////////////////////////////////////////////////////////////
#define BUFFERSIZE (1 << 13)
-class SkScalerContext_Windows : public SkScalerContext {
+class SkScalerContext_GDI : public SkScalerContext {
public:
- SkScalerContext_Windows(SkTypeface*, const SkDescriptor* desc);
- virtual ~SkScalerContext_Windows();
+ SkScalerContext_GDI(SkTypeface*, const SkDescriptor* desc);
+ virtual ~SkScalerContext_GDI();
// Returns true if the constructor was able to complete all of its
// initializations (which may include calling GDI).
@@ -592,7 +593,7 @@
}
}
-SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface,
+SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
const SkDescriptor* desc)
: SkScalerContext(rawTypeface, desc)
, fDDC(0)
@@ -707,7 +708,7 @@
if (fTM.tmPitchAndFamily & TMPF_VECTOR) {
// Truetype or PostScript.
// Stroked FON also gets here (TMPF_VECTOR), but we don't handle it.
- fType = SkScalerContext_Windows::kTrueType_Type;
+ fType = SkScalerContext_GDI::kTrueType_Type;
// fPost2x2 is column-major, left handed (y down).
// XFORM 2x2 is row-major, left handed (y down).
@@ -753,7 +754,7 @@
} else {
// Assume bitmap
- fType = SkScalerContext_Windows::kBitmap_Type;
+ fType = SkScalerContext_GDI::kBitmap_Type;
xform.eM11 = 1.0f;
xform.eM12 = 0.0f;
@@ -773,7 +774,7 @@
fOffscreen.init(fFont, xform);
}
-SkScalerContext_Windows::~SkScalerContext_Windows() {
+SkScalerContext_GDI::~SkScalerContext_GDI() {
if (fDDC) {
::SelectObject(fDDC, fSavefont);
::DeleteDC(fDDC);
@@ -786,11 +787,11 @@
}
}
-bool SkScalerContext_Windows::isValid() const {
+bool SkScalerContext_GDI::isValid() const {
return fDDC && fFont;
}
-unsigned SkScalerContext_Windows::generateGlyphCount() {
+unsigned SkScalerContext_GDI::generateGlyphCount() {
if (fGlyphCount < 0) {
fGlyphCount = calculateGlyphCount(
fDDC, static_cast<const LogFontTypeface*>(this->getTypeface())->fLogFont);
@@ -798,7 +799,7 @@
return fGlyphCount;
}
-uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
+uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar uni) {
uint16_t index = 0;
WCHAR c[2];
// TODO(ctguil): Support characters that generate more than one glyph.
@@ -823,14 +824,14 @@
return index;
}
-void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
+void SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) {
this->generateMetrics(glyph);
}
-void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
+void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
SkASSERT(fDDC);
- if (fType == SkScalerContext_Windows::kBitmap_Type) {
+ if (fType == SkScalerContext_GDI::kBitmap_Type) {
SIZE size;
WORD glyphs = glyph->getGlyphID(0);
if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
@@ -918,7 +919,7 @@
}
static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
-void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
+void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
if (!(mx || my)) {
return;
}
@@ -933,7 +934,7 @@
SkASSERT(fDDC);
#ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
- if (fType == SkScalerContext_Windows::kBitmap_Type) {
+ if (fType == SkScalerContext_GDI::kBitmap_Type) {
#endif
if (mx) {
mx->fTop = SkIntToScalar(-fTM.tmAscent);
@@ -1252,7 +1253,7 @@
return x - (x >> 8);
}
-void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
+void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
SkASSERT(fDDC);
const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
@@ -1602,7 +1603,7 @@
}
}
-DWORD SkScalerContext_Windows::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
+DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
{
GLYPHMETRICS gm;
@@ -1639,7 +1640,7 @@
return total_size;
}
-void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
+void SkScalerContext_GDI::generatePath(const SkGlyph& glyph, SkPath* path) {
SkASSERT(&glyph && path);
SkASSERT(fDDC);
@@ -1984,10 +1985,6 @@
return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference);
}
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
- return create_from_stream(stream);
-}
-
SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const {
*ttcIndex = 0;
@@ -2054,7 +2051,7 @@
}
SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
- SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows,
+ SkScalerContext_GDI* ctx = SkNEW_ARGS(SkScalerContext_GDI,
(const_cast<LogFontTypeface*>(this), desc));
if (!ctx->isValid()) {
SkDELETE(ctx);
@@ -2063,36 +2060,6 @@
return ctx;
}
-/** Return the closest matching typeface given either an existing family
- (specified by a typeface in that family) or by a familyName, and a
- requested style.
- 1) If familyFace is null, use familyName.
- 2) If familyName is null, use familyFace.
- 3) If both are null, return the default font that best matches style
- This MUST not return NULL.
- */
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[],
- SkTypeface::Style style) {
- LOGFONT lf;
- if (NULL == familyFace && NULL == familyName) {
- lf = get_default_font();
- } else if (familyFace) {
- LogFontTypeface* face = (LogFontTypeface*)familyFace;
- lf = face->fLogFont;
- } else {
- logfont_for_name(familyName, &lf);
- }
- setStyle(&lf, style);
- return SkCreateTypefaceFromLOGFONT(lf);
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
- SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
- return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
-}
-
void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
@@ -2147,6 +2114,26 @@
}
}
+static SkTypeface* create_typeface(const SkTypeface* familyFace,
+ const char familyName[],
+ unsigned styleBits) {
+ LOGFONT lf;
+ if (NULL == familyFace && NULL == familyName) {
+ lf = get_default_font();
+ } else if (familyFace) {
+ LogFontTypeface* face = (LogFontTypeface*)familyFace;
+ lf = face->fLogFont;
+ } else {
+ logfont_for_name(familyName, &lf);
+ }
+ setStyle(&lf, (SkTypeface::Style)styleBits);
+ return SkCreateTypefaceFromLOGFONT(lf);
+}
+
+SkTypeface* LogFontTypeface::onRefMatchingStyle(Style style) const {
+ return create_typeface(this, NULL, style);
+}
+
///////////////////////////////////////////////////////////////////////////////
#include "SkFontMgr.h"
@@ -2314,10 +2301,36 @@
return this->createFromStream(stream);
}
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) SK_OVERRIDE {
+ return create_typeface(NULL, familyName, styleBits);
+ }
+
private:
SkTDArray<ENUMLOGFONTEX> fLogFontArray;
};
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef SK_FONTHOST_USES_FONTMGR
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+ const char familyName[],
+ SkTypeface::Style styleBits) {
+ return create_typeface(familyFace, familyName, styleBits);
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
+ return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ return create_from_stream(stream);
+}
+
+#endif
+
SkFontMgr* SkFontMgr::Factory() {
return SkNEW(SkFontMgrGDI);
}
diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
index 3772a09..96bad37 100644
--- a/src/ports/SkFontHost_win_dw.cpp
+++ b/src/ports/SkFontHost_win_dw.cpp
@@ -494,12 +494,13 @@
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE;
virtual int onGetUPEM() const SK_OVERRIDE;
+ virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE;
};
-class SkScalerContext_Windows : public SkScalerContext {
+class SkScalerContext_DW : public SkScalerContext {
public:
- SkScalerContext_Windows(DWriteFontTypeface*, const SkDescriptor* desc);
- virtual ~SkScalerContext_Windows();
+ SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc);
+ virtual ~SkScalerContext_DW();
protected:
virtual unsigned generateGlyphCount() SK_OVERRIDE;
@@ -723,7 +724,7 @@
return static_cast<DWriteFontTypeface*>(SkTypefaceCache::FindByID(fontID));
}
-SkScalerContext_Windows::SkScalerContext_Windows(DWriteFontTypeface* typeface,
+SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
const SkDescriptor* desc)
: SkScalerContext(typeface, desc)
, fTypeface(SkRef(typeface))
@@ -740,23 +741,23 @@
fOffscreen.init(fTypeface->fDWriteFontFace.get(), fXform, SkScalarToFloat(fRec.fTextSize));
}
-SkScalerContext_Windows::~SkScalerContext_Windows() {
+SkScalerContext_DW::~SkScalerContext_DW() {
}
-unsigned SkScalerContext_Windows::generateGlyphCount() {
+unsigned SkScalerContext_DW::generateGlyphCount() {
if (fGlyphCount < 0) {
fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount();
}
return fGlyphCount;
}
-uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
+uint16_t SkScalerContext_DW::generateCharToGlyph(SkUnichar uni) {
uint16_t index = 0;
fTypeface->fDWriteFontFace->GetGlyphIndices(reinterpret_cast<UINT32*>(&uni), 1, &index);
return index;
}
-void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
+void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
//Delta is the difference between the right/left side bearing metric
//and where the right/left side bearing ends up after hinting.
//DirectWrite does not provide this information.
@@ -791,7 +792,7 @@
glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
}
-void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
+void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
glyph->fWidth = 0;
this->generateAdvance(glyph);
@@ -853,7 +854,7 @@
glyph->fTop = SkToS16(bbox.top);
}
-void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx,
+void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
SkPaint::FontMetrics* my) {
if (!(mx || my))
return;
@@ -987,7 +988,7 @@
}
}
-void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
+void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
SkAutoMutexAcquire ac(gFTMutex);
const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
@@ -1026,7 +1027,7 @@
}
}
-void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
+void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
SkAutoMutexAcquire ac(gFTMutex);
SkASSERT(&glyph && path);
@@ -1162,10 +1163,6 @@
return NULL;
}
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
- return create_from_stream(stream, 0);
-}
-
SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
*ttcIndex = fDWriteFontFace->GetIndex();
@@ -1196,7 +1193,7 @@
}
SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
- return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<DWriteFontTypeface*>(this), desc));
+ return SkNEW_ARGS(SkScalerContext_DW, (const_cast<DWriteFontTypeface*>(this), desc));
}
static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** fontFamily) {
@@ -1220,55 +1217,6 @@
return S_FALSE;
}
-/** Return the closest matching typeface given either an existing family
- (specified by a typeface in that family) or by a familyName, and a
- requested style.
- 1) If familyFace is null, use familyName.
- 2) If familyName is null, use familyFace.
- 3) If both are null, return the default font that best matches style
- This MUST not return NULL.
- */
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[],
- SkTypeface::Style style) {
- HRESULT hr;
- SkTScopedComPtr<IDWriteFontFamily> fontFamily;
- if (familyFace) {
- const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(familyFace);
- *(&fontFamily) = SkRefComPtr(face->fDWriteFontFamily.get());
-
- } else if (familyName) {
- hr = get_by_family_name(familyName, &fontFamily);
- }
-
- if (NULL == fontFamily.get()) {
- //No good family found, go with default.
- SkTScopedComPtr<IDWriteFont> font;
- hr = get_default_font(&font);
- hr = font->GetFontFamily(&fontFamily);
- }
-
- SkTScopedComPtr<IDWriteFont> font;
- DWRITE_FONT_WEIGHT weight = (style & SkTypeface::kBold)
- ? DWRITE_FONT_WEIGHT_BOLD
- : DWRITE_FONT_WEIGHT_NORMAL;
- DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_UNDEFINED;
- DWRITE_FONT_STYLE italic = (style & SkTypeface::kItalic)
- ? DWRITE_FONT_STYLE_ITALIC
- : DWRITE_FONT_STYLE_NORMAL;
- hr = fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font);
-
- SkTScopedComPtr<IDWriteFontFace> fontFace;
- hr = font->CreateFontFace(&fontFace);
-
- return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
- printf("SkFontHost::CreateTypefaceFromFile unimplemented");
- return NULL;
-}
-
void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
@@ -1564,6 +1512,46 @@
return info;
}
+static SkTypeface* create_typeface(const SkTypeface* familyFace,
+ const char familyName[],
+ unsigned style) {
+ HRESULT hr;
+ SkTScopedComPtr<IDWriteFontFamily> fontFamily;
+ if (familyFace) {
+ const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(familyFace);
+ *(&fontFamily) = SkRefComPtr(face->fDWriteFontFamily.get());
+
+ } else if (familyName) {
+ hr = get_by_family_name(familyName, &fontFamily);
+ }
+
+ if (NULL == fontFamily.get()) {
+ //No good family found, go with default.
+ SkTScopedComPtr<IDWriteFont> font;
+ hr = get_default_font(&font);
+ hr = font->GetFontFamily(&fontFamily);
+ }
+
+ SkTScopedComPtr<IDWriteFont> font;
+ DWRITE_FONT_WEIGHT weight = (style & SkTypeface::kBold)
+ ? DWRITE_FONT_WEIGHT_BOLD
+ : DWRITE_FONT_WEIGHT_NORMAL;
+ DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_UNDEFINED;
+ DWRITE_FONT_STYLE italic = (style & SkTypeface::kItalic)
+ ? DWRITE_FONT_STYLE_ITALIC
+ : DWRITE_FONT_STYLE_NORMAL;
+ hr = fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font);
+
+ SkTScopedComPtr<IDWriteFontFace> fontFace;
+ hr = font->CreateFontFace(&fontFace);
+
+ return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
+}
+
+SkTypeface* DWriteFontTypeface::onRefMatchingStyle(Style style) const {
+ return create_typeface(this, NULL, style);
+}
+
///////////////////////////////////////////////////////////////////////////////
#include "SkFontMgr.h"
@@ -1720,6 +1708,11 @@
SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
return this->createFromStream(stream, ttcIndex);
}
+
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) SK_OVERRIDE {
+ return create_typeface(NULL, familyName, styleBits);
+ }
};
void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
@@ -1750,6 +1743,27 @@
}
}
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef SK_FONTHOST_USES_FONTMGR
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+ const char familyName[],
+ SkTypeface::Style style) {
+ return create_typeface(familyFace, familyName, style);
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ printf("SkFontHost::CreateTypefaceFromFile unimplemented");
+ return NULL;
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ return create_from_stream(stream, 0);
+}
+
+#endif
+
SkFontMgr* SkFontMgr::Factory() {
IDWriteFactory* factory;
HRNM(get_dwrite_factory(&factory), "Could not get factory.");