aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-15 19:42:57 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-15 19:42:57 +0000
commit7bdd614a1940935d3badeb54f7aae75d76ea830d (patch)
treeaeb3d7e8d8b68cb9d1fb77a0def97f689a2876d7
parent78b38b130deb8bcfa41611039875ce0162542ac1 (diff)
Implement onCountGlyphs and onGetUPEM on Windows.
R=vandebo@chromium.org Review URL: https://codereview.chromium.org/19231003 git-svn-id: http://skia.googlecode.com/svn/trunk@10089 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkTypeface.h4
-rw-r--r--src/core/SkTypeface.cpp5
-rwxr-xr-xsrc/ports/SkFontHost_win.cpp78
-rw-r--r--src/ports/SkFontHost_win_dw.cpp12
-rw-r--r--tests/FontHostTest.cpp35
5 files changed, 111 insertions, 23 deletions
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index c84ae288a6..0fd2ddba1f 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -272,9 +272,9 @@ protected:
virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
int glyphCount) const;
- virtual int onCountGlyphs() const;
+ virtual int onCountGlyphs() const = 0;
- virtual int onGetUPEM() const;
+ virtual int onGetUPEM() const = 0;
virtual int onGetTableTags(SkFontTableTag tags[]) const;
virtual size_t onGetTableData(SkFontTableTag, size_t offset,
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index dcdd5e29f3..294323841c 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -214,11 +214,6 @@ int SkTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
return 0;
}
-int SkTypeface::onCountGlyphs() const {
- SkDebugf("onCountGlyphs unimplemented\n");
- return 0;
-}
-
int SkTypeface::onGetUPEM() const {
int upem = 0;
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index d07307e6fd..22385934ed 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -15,6 +15,7 @@
#include "SkFontHost.h"
#include "SkGlyph.h"
#include "SkMaskGamma.h"
+#include "SkOTTable_maxp.h"
#include "SkOTUtils.h"
#include "SkPath.h"
#include "SkStream.h"
@@ -140,12 +141,21 @@ static inline FIXED SkScalarToFIXED(SkScalar x) {
return SkFixedToFIXED(SkScalarToFixed(x));
}
-static unsigned calculateOutlineGlyphCount(HDC hdc) {
+static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
+ TEXTMETRIC textMetric;
+ if (0 == GetTextMetrics(hdc, &textMetric)) {
+ textMetric.tmPitchAndFamily = TMPF_VECTOR;
+ call_ensure_accessible(lf);
+ GetTextMetrics(hdc, &textMetric);
+ }
+
+ if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
+ return textMetric.tmLastChar;
+ }
+
// The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
- const DWORD maxpTag =
- SkEndian_SwapBE32(SkSetFourByteTag('m', 'a', 'x', 'p'));
uint16_t glyphs;
- if (GetFontData(hdc, maxpTag, 4, &glyphs, sizeof(glyphs)) != GDI_ERROR) {
+ if (GDI_ERROR != GetFontData(hdc, SkOTTableMaximumProfile::TAG, 4, &glyphs, sizeof(glyphs))) {
return SkEndian_SwapBE16(glyphs);
}
@@ -167,6 +177,28 @@ static unsigned calculateOutlineGlyphCount(HDC hdc) {
return min;
}
+static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) {
+ TEXTMETRIC textMetric;
+ if (0 == GetTextMetrics(hdc, &textMetric)) {
+ textMetric.tmPitchAndFamily = TMPF_VECTOR;
+ call_ensure_accessible(lf);
+ GetTextMetrics(hdc, &textMetric);
+ }
+
+ if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
+ return textMetric.tmMaxCharWidth;
+ }
+
+ OUTLINETEXTMETRIC otm;
+ unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
+ if (0 == otmRet) {
+ call_ensure_accessible(lf);
+ otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
+ }
+
+ return (0 == otmRet) ? 0 : otm.otmEMSquare;
+}
+
class LogFontTypeface : public SkTypeface {
public:
LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, bool serializeAsStream = false) :
@@ -228,6 +260,8 @@ protected:
SkAdvancedTypefaceMetrics::PerGlyphInfo,
const uint32_t*, uint32_t) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
+ virtual int onCountGlyphs() const SK_OVERRIDE;
+ virtual int onGetUPEM() const SK_OVERRIDE;
};
class FontMemResourceTypeface : public LogFontTypeface {
@@ -724,10 +758,8 @@ bool SkScalerContext_Windows::isValid() const {
unsigned SkScalerContext_Windows::generateGlyphCount() {
if (fGlyphCount < 0) {
- if (fType == SkScalerContext_Windows::kBitmap_Type) {
- return fTM.tmLastChar;
- }
- fGlyphCount = calculateOutlineGlyphCount(fDDC);
+ fGlyphCount = calculateGlyphCount(
+ fDDC, static_cast<const LogFontTypeface*>(this->getTypeface())->fLogFont);
}
return fGlyphCount;
}
@@ -1446,7 +1478,7 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
goto Error;
}
- glyphCount = calculateOutlineGlyphCount(hdc);
+ glyphCount = calculateGlyphCount(hdc, fLogFont);
info = new SkAdvancedTypefaceMetrics;
info->fEmSize = otm.otmEMSquare;
@@ -1684,6 +1716,34 @@ SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const {
return stream;
}
+int LogFontTypeface::onCountGlyphs() const {
+ HDC hdc = ::CreateCompatibleDC(NULL);
+ HFONT font = CreateFontIndirect(&fLogFont);
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+
+ unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
+
+ SelectObject(hdc, savefont);
+ DeleteObject(font);
+ DeleteDC(hdc);
+
+ return glyphCount;
+}
+
+int LogFontTypeface::onGetUPEM() const {
+ HDC hdc = ::CreateCompatibleDC(NULL);
+ HFONT font = CreateFontIndirect(&fLogFont);
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+
+ unsigned int upem = calculateUPEM(hdc, fLogFont);
+
+ SelectObject(hdc, savefont);
+ DeleteObject(font);
+ DeleteDC(hdc);
+
+ return upem;
+}
+
SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows,
(const_cast<LogFontTypeface*>(this), desc));
diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
index 29fa09857b..3772a092d3 100644
--- a/src/ports/SkFontHost_win_dw.cpp
+++ b/src/ports/SkFontHost_win_dw.cpp
@@ -492,6 +492,8 @@ protected:
SkAdvancedTypefaceMetrics::PerGlyphInfo,
const uint32_t*, uint32_t) const SK_OVERRIDE;
virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
+ virtual int onCountGlyphs() const SK_OVERRIDE;
+ virtual int onGetUPEM() const SK_OVERRIDE;
};
class SkScalerContext_Windows : public SkScalerContext {
@@ -1071,6 +1073,16 @@ void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
*isLocalStream = SkToBool(fDWriteFontFileLoader.get());
}
+int DWriteFontTypeface::onCountGlyphs() const {
+ return fDWriteFontFace->GetGlyphCount();
+}
+
+int DWriteFontTypeface::onGetUPEM() const {
+ DWRITE_FONT_METRICS metrics;
+ fDWriteFontFace->GetMetrics(&metrics);
+ return metrics.designUnitsPerEm;
+}
+
template <typename T> class SkAutoIDWriteUnregister {
public:
SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
diff --git a/tests/FontHostTest.cpp b/tests/FontHostTest.cpp
index 9a186dd57d..7358b1089a 100644
--- a/tests/FontHostTest.cpp
+++ b/tests/FontHostTest.cpp
@@ -29,20 +29,18 @@ static const struct TagSize {
};
// Test that getUnitsPerEm() agrees with a direct lookup in the 'head' table
-// (if that table is available.
+// (if that table is available).
static void test_unitsPerEm(skiatest::Reporter* reporter, SkTypeface* face) {
- int nativeUPEM = face->getUnitsPerEm();;
+ int nativeUPEM = face->getUnitsPerEm();
int tableUPEM = -1;
size_t size = face->getTableSize(kFontTableTag_head);
if (size) {
- SkAutoMalloc storage(size);
- char* ptr = (char*)storage.get();
- face->getTableData(kFontTableTag_head, 0, size, ptr);
// unitsPerEm is at offset 18 into the 'head' table.
- tableUPEM = SkEndian_SwapBE16(*(uint16_t*)&ptr[18]);
+ uint16_t rawUPEM;
+ face->getTableData(kFontTableTag_head, 18, sizeof(rawUPEM), &rawUPEM);
+ tableUPEM = SkEndian_SwapBE16(rawUPEM);
}
-// SkDebugf("--- typeface returned %d upem [%X]\n", nativeUPEM, face->uniqueID());
if (tableUPEM >= 0) {
REPORTER_ASSERT(reporter, tableUPEM == nativeUPEM);
@@ -52,6 +50,28 @@ static void test_unitsPerEm(skiatest::Reporter* reporter, SkTypeface* face) {
}
}
+// Test that countGlyphs() agrees with a direct lookup in the 'maxp' table
+// (if that table is available).
+static void test_countGlyphs(skiatest::Reporter* reporter, SkTypeface* face) {
+ int nativeGlyphs = face->countGlyphs();
+
+ int tableGlyphs = -1;
+ size_t size = face->getTableSize(kFontTableTag_maxp);
+ if (size) {
+ // glyphs is at offset 4 into the 'maxp' table.
+ uint16_t rawGlyphs;
+ face->getTableData(kFontTableTag_maxp, 4, sizeof(rawGlyphs), &rawGlyphs);
+ tableGlyphs = SkEndian_SwapBE16(rawGlyphs);
+ }
+
+ if (tableGlyphs >= 0) {
+ REPORTER_ASSERT(reporter, tableGlyphs == nativeGlyphs);
+ } else {
+ // not sure this is a bug, but lets report it for now as info.
+ SkDebugf("--- typeface returned 0 glyphs [%X]\n", face->uniqueID());
+ }
+}
+
static void test_fontstream(skiatest::Reporter* reporter,
SkStream* stream, int ttcIndex) {
int n = SkFontStream::GetTableTags(stream, ttcIndex, NULL);
@@ -157,6 +177,7 @@ static void test_tables(skiatest::Reporter* reporter) {
#endif
test_tables(reporter, face);
test_unitsPerEm(reporter, face);
+ test_countGlyphs(reporter, face);
face->unref();
}
}