зеркало из https://github.com/mozilla/moz-skia.git
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
This commit is contained in:
Родитель
78b38b130d
Коммит
7bdd614a19
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче