151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman/* 251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * Copyright 2014 Google Inc. 351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * 451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * Use of this source code is governed by a BSD-style license that can be 551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * found in the LICENSE file. 651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman */ 751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 8df2ec358be78820550f334bc7224ae18e3d25390bungeman#include "SkTypes.h" 9df2ec358be78820550f334bc7224ae18e3d25390bungeman// SkTypes will include Windows.h, which will pull in all of the GDI defines. 10df2ec358be78820550f334bc7224ae18e3d25390bungeman// GDI #defines GetGlyphIndices to GetGlyphIndicesA or GetGlyphIndicesW, but 11df2ec358be78820550f334bc7224ae18e3d25390bungeman// IDWriteFontFace has a method called GetGlyphIndices. Since this file does 12df2ec358be78820550f334bc7224ae18e3d25390bungeman// not use GDI, undefing GetGlyphIndices makes things less confusing. 13df2ec358be78820550f334bc7224ae18e3d25390bungeman#undef GetGlyphIndices 14df2ec358be78820550f334bc7224ae18e3d25390bungeman 15b374d6a62c0259387d90cad74753d8bad9ee1beabungeman#include "SkDWrite.h" 1651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkDWriteFontFileStream.h" 1751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontDescriptor.h" 1851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontStream.h" 1951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_head.h" 2051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_hhea.h" 2151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_OS_2.h" 2251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_post.h" 2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext.h" 2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext_win_dw.h" 2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypeface_win_dw.h" 2651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkUtils.h" 2751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 28b374d6a62c0259387d90cad74753d8bad9ee1beabungemanvoid DWriteFontTypeface::onGetFamilyName(SkString* familyName) const { 29b374d6a62c0259387d90cad74753d8bad9ee1beabungeman SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; 30b374d6a62c0259387d90cad74753d8bad9ee1beabungeman HRV(fDWriteFontFamily->GetFamilyNames(&familyNames)); 31b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 32b374d6a62c0259387d90cad74753d8bad9ee1beabungeman sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, familyName); 33b374d6a62c0259387d90cad74753d8bad9ee1beabungeman} 34b374d6a62c0259387d90cad74753d8bad9ee1beabungeman 3551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanvoid DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 3651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman bool* isLocalStream) const { 3751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // Get the family name. 385e7b4f967b37cc303a20b87617446605f26f1867bungeman SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; 395e7b4f967b37cc303a20b87617446605f26f1867bungeman HRV(fDWriteFontFamily->GetFamilyNames(&familyNames)); 4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 4151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkString utf8FamilyName; 42b374d6a62c0259387d90cad74753d8bad9ee1beabungeman sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, &utf8FamilyName); 4351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman desc->setFamilyName(utf8FamilyName.c_str()); 45d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman desc->setFontIndex(fDWriteFontFace->GetIndex()); 4651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); 4751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 4851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 4951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf8(const void** chars) { 5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return SkUTF8_NextUnichar((const char**)chars); 5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf16(const void** chars) { 5451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return SkUTF16_NextUnichar((const uint16_t**)chars); 5551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 5651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 5751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf32(const void** chars) { 5851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const SkUnichar** uniChars = (const SkUnichar**)chars; 5951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkUnichar uni = **uniChars; 6051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *uniChars += 1; 6151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return uni; 6251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 6351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 6451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemantypedef SkUnichar (*EncodingProc)(const void**); 6551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 6651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic EncodingProc find_encoding_proc(SkTypeface::Encoding enc) { 6751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman static const EncodingProc gProcs[] = { 6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman next_utf8, next_utf16, next_utf32 6951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman }; 7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs)); 7151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return gProcs[enc]; 7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 7351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 7451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 7551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman uint16_t glyphs[], int glyphCount) const 7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{ 7751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (NULL == glyphs) { 7851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman EncodingProc next_ucs4_proc = find_encoding_proc(encoding); 7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (int i = 0; i < glyphCount; ++i) { 8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const SkUnichar c = next_ucs4_proc(&chars); 8151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman BOOL exists; 8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fDWriteFont->HasCharacter(c, &exists); 8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (!exists) { 8451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return i; 8551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 8651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 8751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return glyphCount; 8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman switch (encoding) { 9151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman case SkTypeface::kUTF8_Encoding: 9251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman case SkTypeface::kUTF16_Encoding: { 9351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman static const int scratchCount = 256; 9451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT32 scratch[scratchCount]; 9551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman EncodingProc next_ucs4_proc = find_encoding_proc(encoding); 9651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCount) { 9751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int glyphsLeft = glyphCount - baseGlyph; 9851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int limit = SkTMin(glyphsLeft, scratchCount); 9951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (int i = 0; i < limit; ++i) { 10051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman scratch[i] = next_ucs4_proc(&chars); 10151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 10251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]); 10351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 10451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman break; 10551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 10651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman case SkTypeface::kUTF32_Encoding: { 10751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars); 10851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs); 10951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman break; 11051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 11151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman default: 11251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SK_CRASH(); 11351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 11451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 11551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (int i = 0; i < glyphCount; ++i) { 11651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (0 == glyphs[i]) { 11751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return i; 11851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 11951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 12051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return glyphCount; 12151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 12251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 12351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCountGlyphs() const { 12451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return fDWriteFontFace->GetGlyphCount(); 12551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 12651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 12751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetUPEM() const { 12851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman DWRITE_FONT_METRICS metrics; 12951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fDWriteFontFace->GetMetrics(&metrics); 13051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return metrics.designUnitsPerEm; 13151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 13251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 13351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings { 13451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic: 13551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman /** Takes ownership of the IDWriteLocalizedStrings. */ 13651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings) 13751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman : fIndex(0), fStrings(strings) 13851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman { } 13951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 14051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE { 14151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (fIndex >= fStrings->GetCount()) { 14251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return false; 14351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 14451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 14551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // String 1465e7b4f967b37cc303a20b87617446605f26f1867bungeman UINT32 stringLen; 1475e7b4f967b37cc303a20b87617446605f26f1867bungeman HRBM(fStrings->GetStringLength(fIndex, &stringLen), "Could not get string length."); 14851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 1495e7b4f967b37cc303a20b87617446605f26f1867bungeman SkSMallocWCHAR wString(stringLen+1); 1505e7b4f967b37cc303a20b87617446605f26f1867bungeman HRBM(fStrings->GetString(fIndex, wString.get(), stringLen+1), "Could not get string."); 15151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 1525e7b4f967b37cc303a20b87617446605f26f1867bungeman HRB(sk_wchar_to_skstring(wString.get(), stringLen, &localizedString->fString)); 15351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 15451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // Locale 1555e7b4f967b37cc303a20b87617446605f26f1867bungeman UINT32 localeLen; 1565e7b4f967b37cc303a20b87617446605f26f1867bungeman HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLen), "Could not get locale length."); 15751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 1585e7b4f967b37cc303a20b87617446605f26f1867bungeman SkSMallocWCHAR wLocale(localeLen+1); 1595e7b4f967b37cc303a20b87617446605f26f1867bungeman HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLen+1), "Could not get locale."); 16051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 1615e7b4f967b37cc303a20b87617446605f26f1867bungeman HRB(sk_wchar_to_skstring(wLocale.get(), localeLen, &localizedString->fLanguage)); 16251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 16351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman ++fIndex; 16451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return true; 16551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 16651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 16751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate: 16851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT32 fIndex; 16951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteLocalizedStrings> fStrings; 17051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}; 17151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 17251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const { 17351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; 17451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names."); 17551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 17651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release()); 17751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 17851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 17951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { 18051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType(); 18151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (type != DWRITE_FONT_FACE_TYPE_CFF && 18251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman type != DWRITE_FONT_FACE_TYPE_TRUETYPE && 18351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) 18451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman { 18551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return 0; 18651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 18751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 18851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int ttcIndex; 18951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex)); 19051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0; 19151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 19251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 19351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemansize_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 19451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman size_t length, void* data) const 19551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{ 19651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag)); 19751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (!table.fExists) { 19851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return 0; 19951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 20051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 20151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (offset > table.fSize) { 20251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return 0; 20351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 20451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman size_t size = SkTMin(length, table.fSize - offset); 20549f085dddff10473b6ebf832a974288300224e60bsalomon if (data) { 20651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman memcpy(data, table.fData + offset, size); 20751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 20851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 20951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return size; 21051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 21151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 21251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const { 21351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *ttcIndex = fDWriteFontFace->GetIndex(); 21451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 21551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT32 numFiles; 21651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL), 21751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman "Could not get number of font files."); 21851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (numFiles != 1) { 21951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return NULL; 22051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 22151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 22251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteFontFile> fontFile; 22351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files."); 22451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 22551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const void* fontFileKey; 22651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT32 fontFileKeySize; 22751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize), 22851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman "Could not get font file reference key."); 22951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 23051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader; 23151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader."); 23251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 23351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteFontFileStream> fontFileStream; 23451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize, 23551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman &fontFileStream), 23651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman "Could not create font file stream."); 23751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 23851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return SkNEW_ARGS(SkDWriteFontFileStream, (fontFileStream.get())); 23951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 24051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 24151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const { 24251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return SkNEW_ARGS(SkScalerContext_DW, (const_cast<DWriteFontTypeface*>(this), desc)); 24351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 24451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 24551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanvoid DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { 24651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || 24751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) 24851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman { 24951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->fMaskFormat = SkMask::kA8_Format; 25051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 25151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 252410780677af260e32948b02c0725ef6ad761260cbungeman unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag | 253410780677af260e32948b02c0725ef6ad761260cbungeman SkScalerContext::kDevKernText_Flag | 25451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkScalerContext::kForceAutohinting_Flag | 25551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkScalerContext::kEmbolden_Flag | 25651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkScalerContext::kLCD_BGROrder_Flag | 25751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkScalerContext::kLCD_Vertical_Flag; 25851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->fFlags &= ~flagsWeDontSupport; 25951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 26051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkPaint::Hinting h = rec->getHinting(); 26151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // DirectWrite does not provide for hinting hints. 26251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman h = SkPaint::kSlight_Hinting; 26351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->setHinting(h); 26451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 26551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#if SK_FONT_HOST_USE_SYSTEM_SETTINGS 26651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman IDWriteFactory* factory = get_dwrite_factory(); 26751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (factory != NULL) { 26851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams; 26951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) { 27051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman float gamma = defaultRenderingParams->GetGamma(); 27151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->setDeviceGamma(gamma); 27251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->setPaintGamma(gamma); 27351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 27451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman rec->setContrast(defaultRenderingParams->GetEnhancedContrast()); 27551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 27651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 27751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif 27851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 27951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 28051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman/////////////////////////////////////////////////////////////////////////////// 28151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman//PDF Support 28251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 28351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanusing namespace skia_advanced_typeface_metrics_utils; 28451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 28551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Construct Glyph to Unicode table. 28651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Unicode code points that require conjugate pairs in utf16 are not 28751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// supported. 28851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// TODO(bungeman): This never does what anyone wants. 28951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// What is really wanted is the text to glyphs mapping 29051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic void populate_glyph_to_unicode(IDWriteFontFace* fontFace, 29151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const unsigned glyphCount, 29251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTDArray<SkUnichar>* glyphToUnicode) { 29351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRESULT hr = S_OK; 29451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 29551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //Do this like free type instead 296df2ec358be78820550f334bc7224ae18e3d25390bungeman SkAutoTMalloc<SkUnichar> glyphToUni(glyphCount); 297df2ec358be78820550f334bc7224ae18e3d25390bungeman int maxGlyph = -1; 29851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (UINT32 c = 0; c < 0x10FFFF; ++c) { 29951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT16 glyph; 30051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman hr = fontFace->GetGlyphIndices(&c, 1, &glyph); 301df2ec358be78820550f334bc7224ae18e3d25390bungeman SkASSERT(glyph < glyphCount); 302df2ec358be78820550f334bc7224ae18e3d25390bungeman if (0 < glyph) { 303df2ec358be78820550f334bc7224ae18e3d25390bungeman maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph); 304df2ec358be78820550f334bc7224ae18e3d25390bungeman glyphToUni[glyph] = c; 30551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 30651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 30751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 308aace9976cddfa2f3e65f2ba263a5b66c7f0b923dbungeman SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode); 30951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 31051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 31151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance) { 31251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkASSERT(advance); 31351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 31451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman UINT16 glyphId = gId; 31551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman DWRITE_GLYPH_METRICS gm; 31651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRESULT hr = fontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm); 31751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 31851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (FAILED(hr)) { 31951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *advance = 0; 32051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return false; 32151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 32251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 32351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *advance = gm.advanceWidth; 32451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return true; 32551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 32651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 32751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( 32851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo, 32951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const uint32_t* glyphIDs, 33051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman uint32_t glyphIDsCount) const { 33151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 33251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkAdvancedTypefaceMetrics* info = NULL; 33351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 33451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman HRESULT hr = S_OK; 33551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 33651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman const unsigned glyphCount = fDWriteFontFace->GetGlyphCount(); 33751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 33851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman DWRITE_FONT_METRICS dwfm; 33951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fDWriteFontFace->GetMetrics(&dwfm); 34051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 34151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info = new SkAdvancedTypefaceMetrics; 34251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fEmSize = dwfm.designUnitsPerEm; 34351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fLastGlyphID = SkToU16(glyphCount - 1); 34451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStyle = 0; 3450f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; 34651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 3476d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman // SkAdvancedTypefaceMetrics::fFontName is in theory supposed to be 3486d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman // the PostScript name of the font. However, due to the way it is currently 3496d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman // used, it must actually be a family name. 35051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; 35151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman hr = fDWriteFontFamily->GetFamilyNames(&familyNames); 35251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 3535e7b4f967b37cc303a20b87617446605f26f1867bungeman UINT32 familyNameLen; 3545e7b4f967b37cc303a20b87617446605f26f1867bungeman hr = familyNames->GetStringLength(0, &familyNameLen); 35551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 3565e7b4f967b37cc303a20b87617446605f26f1867bungeman SkSMallocWCHAR familyName(familyNameLen+1); 3575e7b4f967b37cc303a20b87617446605f26f1867bungeman hr = familyNames->GetString(0, familyName.get(), familyNameLen+1); 35851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 3595e7b4f967b37cc303a20b87617446605f26f1867bungeman hr = sk_wchar_to_skstring(familyName.get(), familyNameLen, &info->fFontName); 36051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 36151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { 36251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode)); 36351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 36451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 36551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); 36651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || 36751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { 36851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; 36951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } else { 37051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fType = SkAdvancedTypefaceMetrics::kOther_Font; 37151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fItalicAngle = 0; 37251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fAscent = dwfm.ascent;; 37351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fDescent = dwfm.descent; 37451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStemV = 0; 37551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fCapHeight = dwfm.capHeight; 37651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fBBox = SkIRect::MakeEmpty(); 37751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return info; 37851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 37951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 38051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get()); 38151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get()); 38251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get()); 38351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get()); 38451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) { 38551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fItalicAngle = 0; 38651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fAscent = dwfm.ascent;; 38751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fDescent = dwfm.descent; 38851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStemV = 0; 38951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fCapHeight = dwfm.capHeight; 39051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fBBox = SkIRect::MakeEmpty(); 39151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return info; 39251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 39351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 39451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //There exist CJK fonts which set the IsFixedPitch and Monospace bits, 39551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //but have full width, latin half-width, and half-width kana. 39651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman bool fixedWidth = (postTable->isFixedPitch && 39751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics))); 39851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //Monospace 39951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (fixedWidth) { 40051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; 40151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 40251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //Italic 40351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (os2Table->version.v0.fsSelection.field.Italic) { 40451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style; 40551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 40651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //Script 40751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType.value) { 40851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style; 40951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //Serif 41051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType.value && 41151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value && 41251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value) { 41351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style; 41451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 41551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 41651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16; 41751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 41851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fAscent = SkToS16(dwfm.ascent); 41951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fDescent = SkToS16(dwfm.descent); 42051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fCapHeight = SkToS16(dwfm.capHeight); 42151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 42251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin), 42351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax), 42451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax), 42551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin)); 42651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 42751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //TODO: is this even desired? It seems PDF only wants this value for Type1 42851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman //fonts, and we only get here for TrueType fonts. 42951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStemV = 0; 43051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman /* 43151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // Figure out a good guess for StemV - Min width of i, I, !, 1. 43251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman // This probably isn't very good with an italic font. 43351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int16_t min_width = SHRT_MAX; 43451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStemV = 0; 43551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman char stem_chars[] = {'i', 'I', '!', '1'}; 43651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) { 43751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman ABC abcWidths; 43851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) { 43951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int16_t width = abcWidths.abcB; 44051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (width > 0 && width < min_width) { 44151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman min_width = width; 44251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fStemV = min_width; 44351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 44451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 44551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 44651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman */ 44751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 4480f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) { 44951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman if (fixedWidth) { 45051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman appendRange(&info->fGlyphWidths, 0); 45151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman int16_t advance; 45251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman getWidthAdvance(fDWriteFontFace.get(), 1, &advance); 45351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fGlyphWidths->fAdvance.append(1, &advance); 45451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman finishRange(info->fGlyphWidths.get(), 0, 45551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman SkAdvancedTypefaceMetrics::WidthRange::kDefault); 45651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } else { 45751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman info->fGlyphWidths.reset( 45851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman getAdvanceData(fDWriteFontFace.get(), 45951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman glyphCount, 46051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman glyphIDs, 46151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman glyphIDsCount, 46251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman getWidthAdvance)); 46351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 46451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman } 46551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman 46651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman return info; 46751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman} 468