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
This commit is contained in:
reed@google.com 2013-07-30 17:47:39 +00:00
parent 2d859346dd
commit 30ddd615c4
7 changed files with 229 additions and 120 deletions

View File

@ -12,6 +12,8 @@
#include "SkTypeface.h"
//#define SK_FONTHOST_USES_FONTMGR
class SkDescriptor;
class SkScalerContext;
struct SkScalerContextRec;

View File

@ -239,6 +239,17 @@ public:
*/
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
@ -287,6 +298,13 @@ protected:
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;

View File

@ -31,6 +31,8 @@ private:
typedef SkRefCnt INHERITED;
};
class SkTypeface;
class SK_API SkFontMgr : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkFontMgr)
@ -73,6 +75,9 @@ public:
*/
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 @@ protected:
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

View File

@ -68,7 +68,6 @@ SkFontStyle::SkFontStyle(int weight, int width, Slant slant) {
#include "SkFontMgr.h"
SK_DEFINE_INST_COUNT(SkFontStyleSet)
class SkEmptyFontStyleSet : public SkFontStyleSet {
@ -174,6 +173,17 @@ SkTypeface* SkFontMgr::createFromFile(const char path[], int ttcIndex) {
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 @@ SkFontMgr* SkFontMgr::RefDefault() {
}
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

View File

@ -209,6 +209,10 @@ SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
}
SkTypeface* SkTypeface::refMatchingStyle(Style style) const {
return this->onRefMatchingStyle(style);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

View File

@ -250,6 +250,7 @@ protected:
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 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
//////////////////////////////////////////////////////////////////////////////
#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 @@ static BYTE compute_quality(const SkScalerContext::Rec& rec) {
}
}
SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface,
SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
const SkDescriptor* desc)
: SkScalerContext(rawTypeface, desc)
, fDDC(0)
@ -707,7 +708,7 @@ SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface,
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 @@ SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface,
} 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 @@ SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface,
fOffscreen.init(fFont, xform);
}
SkScalerContext_Windows::~SkScalerContext_Windows() {
SkScalerContext_GDI::~SkScalerContext_GDI() {
if (fDDC) {
::SelectObject(fDDC, fSavefont);
::DeleteDC(fDDC);
@ -786,11 +787,11 @@ SkScalerContext_Windows::~SkScalerContext_Windows() {
}
}
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 @@ unsigned SkScalerContext_Windows::generateGlyphCount() {
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 @@ uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
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 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
}
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 @@ void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
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 @@ static inline unsigned clamp255(unsigned x) {
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 @@ static void sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD
}
}
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 @@ DWORD SkScalerContext_Windows::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
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 @@ static SkTypeface* create_from_stream(SkStream* stream) {
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 @@ int LogFontTypeface::onGetUPEM() const {
}
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 @@ SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc
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 @@ void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
}
}
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 @@ protected:
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);
}

View File

@ -494,12 +494,13 @@ protected:
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 @@ static DWriteFontTypeface* GetDWriteFontByID(SkFontID fontID) {
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 @@ SkScalerContext_Windows::SkScalerContext_Windows(DWriteFontTypeface* typeface,
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 @@ void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
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 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
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 @@ static void rgb_to_lcd32(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
}
}
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::generateImage(const SkGlyph& glyph) {
}
}
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 @@ static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) {
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 @@ SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
}
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 @@ static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** f
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 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
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 @@ protected:
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 @@ void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString*
}
}
///////////////////////////////////////////////////////////////////////////////
#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.");