diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-01 20:18:41 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-01 20:18:41 +0000 |
commit | b10b51f64dbd1cf44571a1eedb412378702d8cd4 (patch) | |
tree | d961bd1e2de79deff8c50079dce6d3733fc72103 /src/ports | |
parent | 9a43c18740d3251b4d52703a0247719a0aef6474 (diff) |
Implement onGetTableTags and onGetTableData on Windows.
Implements these and removes default implementation, making the
declaration in SkTypeface pure virtual.
Review URL: https://codereview.chromium.org/20672004/
git-svn-id: http://skia.googlecode.com/svn/trunk@10495 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rwxr-xr-x | src/ports/SkFontHost_win.cpp | 52 | ||||
-rw-r--r-- | src/ports/SkFontHost_win_dw.cpp | 98 |
2 files changed, 119 insertions, 31 deletions
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 381c20afbc..fe646d74b9 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -18,6 +18,7 @@ #include "SkOTTable_maxp.h" #include "SkOTUtils.h" #include "SkPath.h" +#include "SkSFNTHeader.h" #include "SkStream.h" #include "SkString.h" #include "SkTemplates.h" @@ -250,6 +251,9 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() 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; virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE; }; @@ -2050,6 +2054,54 @@ int LogFontTypeface::onGetUPEM() const { return upem; } +int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { + SkSFNTHeader header; + if (sizeof(header) != this->onGetTableData(0, 0, sizeof(header), &header)) { + return 0; + } + + int numTables = SkEndian_SwapBE16(header.numTables); + + if (tags) { + size_t size = numTables * sizeof(SkSFNTHeader::TableDirectoryEntry); + SkAutoSTMalloc<0x20, SkSFNTHeader::TableDirectoryEntry> dir(numTables); + if (size != this->onGetTableData(0, sizeof(header), size, dir.get())) { + return 0; + } + + for (int i = 0; i < numTables; ++i) { + tags[i] = SkEndian_SwapBE32(dir[i].tag); + } + } + return numTables; +} + +size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, + size_t length, void* data) const +{ + LOGFONT lf = fLogFont; + + HDC hdc = ::CreateCompatibleDC(NULL); + HFONT font = CreateFontIndirect(&lf); + HFONT savefont = (HFONT)SelectObject(hdc, font); + + tag = SkEndian_SwapBE32(tag); + if (NULL == data) { + length = 0; + } + DWORD bufferSize = GetFontData(hdc, tag, offset, data, length); + if (bufferSize == GDI_ERROR) { + call_ensure_accessible(lf); + bufferSize = GetFontData(hdc, tag, offset, data, length); + } + + SelectObject(hdc, savefont); + DeleteObject(font); + DeleteDC(hdc); + + return bufferSize == GDI_ERROR ? 0 : bufferSize; +} + SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const { SkScalerContext_GDI* ctx = SkNEW_ARGS(SkScalerContext_GDI, (const_cast<LogFontTypeface*>(this), desc)); diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp index 96bad37022..beec056e93 100644 --- a/src/ports/SkFontHost_win_dw.cpp +++ b/src/ports/SkFontHost_win_dw.cpp @@ -16,6 +16,7 @@ #include "SkEndian.h" #include "SkFontDescriptor.h" #include "SkFontHost.h" +#include "SkFontStream.h" #include "SkGlyph.h" #include "SkHRESULT.h" #include "SkMaskGamma.h" @@ -494,6 +495,9 @@ protected: virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; virtual int onCountGlyphs() const SK_OVERRIDE; virtual int onGetUPEM() 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; virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE; }; @@ -1084,6 +1088,61 @@ int DWriteFontTypeface::onGetUPEM() const { return metrics.designUnitsPerEm; } +int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { + DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType(); + if (type != DWRITE_FONT_FACE_TYPE_CFF && + type != DWRITE_FONT_FACE_TYPE_TRUETYPE && + type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) + { + return 0; + } + + int ttcIndex; + SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex)); + return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0; +} + +class AutoDWriteTable { +public: + AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFace), fExists(FALSE) { + // Any errors are ignored, user must check fExists anyway. + fontFace->TryGetFontTable(beTag, + reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists); + } + ~AutoDWriteTable() { + if (fExists) { + fFontFace->ReleaseFontTable(fLock); + } + } + + const uint8_t* fData; + UINT32 fSize; + BOOL fExists; +private: + // Borrowed reference, the user must ensure the fontFace stays alive. + IDWriteFontFace* fFontFace; + void* fLock; +}; + +size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, + size_t length, void* data) const +{ + AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag)); + if (!table.fExists) { + return 0; + } + + if (offset > table.fSize) { + return 0; + } + size_t size = SkTMin(length, table.fSize - offset); + if (NULL != data) { + memcpy(data, table.fData + offset, size); + } + + return size; +} + template <typename T> class SkAutoIDWriteUnregister { public: SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister) @@ -1328,35 +1387,12 @@ static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance return true; } -template<typename T> -class AutoDWriteTable { +template<typename T> class AutoTDWriteTable : public AutoDWriteTable { public: - AutoDWriteTable(IDWriteFontFace* fontFace) - : fFontFace(fontFace) - , fExists(FALSE) { - - const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, - T::TAG1, - T::TAG2, - T::TAG3); - // Any errors are ignored, user must check fExists anyway. - fontFace->TryGetFontTable(tag, - reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists); - } - ~AutoDWriteTable() { - if (fExists) { - fFontFace->ReleaseFontTable(fLock); - } - } - const T* operator->() const { return fData; } + static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2, T::TAG3); + AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { } - const T* fData; - UINT32 fSize; - BOOL fExists; -private: - // Borrowed reference, the user must ensure the fontFace stays alive. - IDWriteFontFace* fFontFace; - void* fLock; + const T* operator->() const { return reinterpret_cast<const T*>(fData); } }; SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( @@ -1418,10 +1454,10 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( return info; } - AutoDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get()); - AutoDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get()); - AutoDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get()); - AutoDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get()); + AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get()); + AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get()); + AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get()); + AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get()); if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) { info->fItalicAngle = 0; info->fAscent = dwfm.ascent;; |