aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-01 20:18:41 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-01 20:18:41 +0000
commitb10b51f64dbd1cf44571a1eedb412378702d8cd4 (patch)
treed961bd1e2de79deff8c50079dce6d3733fc72103 /src/ports
parent9a43c18740d3251b4d52703a0247719a0aef6474 (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-xsrc/ports/SkFontHost_win.cpp52
-rw-r--r--src/ports/SkFontHost_win_dw.cpp98
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;;