| Index: src/ports/SkFontHost_win_dw.cpp
|
| ===================================================================
|
| --- src/ports/SkFontHost_win_dw.cpp (revision 8940)
|
| +++ src/ports/SkFontHost_win_dw.cpp (working copy)
|
| @@ -229,9 +229,7 @@
|
| SkAutoTUnref<SkStream> fStream;
|
|
|
| private:
|
| - StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(stream) {
|
| - stream->ref();
|
| - }
|
| + StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream)) { }
|
|
|
| ULONG fRefCount;
|
| };
|
| @@ -302,14 +300,11 @@
|
| StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
|
| IDWriteFontFileLoader* fontFileLoader)
|
| : fRefCount(1)
|
| - , fFactory(factory)
|
| + , fFactory(SkRefComPtr(factory))
|
| , fCurrentFile()
|
| - , fFontFileLoader(fontFileLoader)
|
| + , fFontFileLoader(SkRefComPtr(fontFileLoader))
|
| , fHasNext(true)
|
| -{
|
| - factory->AddRef();
|
| - fontFileLoader->AddRef();
|
| -}
|
| +{ }
|
|
|
| HRESULT StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
|
| if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
|
| @@ -359,8 +354,7 @@
|
| return E_FAIL;
|
| }
|
|
|
| - fCurrentFile.get()->AddRef();
|
| - *fontFile = fCurrentFile.get();
|
| + *fontFile = SkRefComPtr(fCurrentFile.get());
|
| return S_OK;
|
| }
|
|
|
| @@ -389,10 +383,8 @@
|
| private:
|
| StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
|
| : fRefCount(1)
|
| - , fFontFileLoader(fontFileLoader)
|
| - {
|
| - fontFileLoader->AddRef();
|
| - }
|
| + , fFontFileLoader(SkRefComPtr(fontFileLoader))
|
| + { }
|
|
|
| ULONG fRefCount;
|
| SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
|
| @@ -457,23 +449,13 @@
|
| StreamFontFileLoader* fontFileLoader = NULL,
|
| IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
|
| : SkTypeface(style, fontID, false)
|
| - , fDWriteFontCollectionLoader(fontCollectionLoader)
|
| - , fDWriteFontFileLoader(fontFileLoader)
|
| - , fDWriteFontFamily(fontFamily)
|
| - , fDWriteFont(font)
|
| - , fDWriteFontFace(fontFace) {
|
| + , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
|
| + , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
|
| + , fDWriteFontFamily(SkRefComPtr(fontFamily))
|
| + , fDWriteFont(SkRefComPtr(font))
|
| + , fDWriteFontFace(SkRefComPtr(fontFace))
|
| + { }
|
|
|
| - if (fontCollectionLoader != NULL) {
|
| - fontCollectionLoader->AddRef();
|
| - }
|
| - if (fontFileLoader != NULL) {
|
| - fontFileLoader->AddRef();
|
| - }
|
| - fontFamily->AddRef();
|
| - font->AddRef();
|
| - fontFace->AddRef();
|
| - }
|
| -
|
| public:
|
| SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
|
| SkTScopedComPtr<StreamFontFileLoader> fDWriteFontFileLoader;
|
| @@ -732,8 +714,7 @@
|
| if (NULL == face) {
|
| HRVM(get_default_font(font), "Could not get default font.");
|
| } else {
|
| - *font = static_cast<const DWriteFontTypeface*>(face)->fDWriteFont.get();
|
| - (*font)->AddRef();
|
| + *font = SkRefComPtr(static_cast<const DWriteFontTypeface*>(face)->fDWriteFont.get());
|
| }
|
| }
|
| static DWriteFontTypeface* GetDWriteFontByID(SkFontID fontID) {
|
| @@ -1090,41 +1071,91 @@
|
| *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
|
| }
|
|
|
| -static SkTypeface* create_from_stream(SkStream* stream) {
|
| +template <typename T> class SkAutoIDWriteUnregister {
|
| +public:
|
| + SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
|
| + : fFactory(factory), fUnregister(unregister)
|
| + { }
|
| +
|
| + ~SkAutoIDWriteUnregister() {
|
| + if (fUnregister) {
|
| + unregister(fFactory, fUnregister);
|
| + }
|
| + }
|
| +
|
| + T* detatch() {
|
| + T* old = fUnregister;
|
| + fUnregister = NULL;
|
| + return old;
|
| + }
|
| +
|
| +private:
|
| + HRESULT unregister(IDWriteFactory* factory, IDWriteFontFileLoader* unregister) {
|
| + return factory->UnregisterFontFileLoader(unregister);
|
| + }
|
| +
|
| + HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unregister) {
|
| + return factory->UnregisterFontCollectionLoader(unregister);
|
| + }
|
| +
|
| + IDWriteFactory* fFactory;
|
| + T* fUnregister;
|
| +};
|
| +
|
| +static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) {
|
| IDWriteFactory* factory;
|
| HRN(get_dwrite_factory(&factory));
|
|
|
| SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
|
| HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
|
| HRN(factory->RegisterFontFileLoader(fontFileLoader.get()));
|
| + SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
|
| + factory, fontFileLoader.get());
|
|
|
| - SkTScopedComPtr<StreamFontCollectionLoader> streamFontCollectionLoader;
|
| - HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &streamFontCollectionLoader));
|
| - HRN(factory->RegisterFontCollectionLoader(streamFontCollectionLoader.get()));
|
| + SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader;
|
| + HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollectionLoader));
|
| + HRN(factory->RegisterFontCollectionLoader(fontCollectionLoader.get()));
|
| + SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollectionLoader(
|
| + factory, fontCollectionLoader.get());
|
|
|
| - SkTScopedComPtr<IDWriteFontCollection> streamFontCollection;
|
| - HRN(factory->CreateCustomFontCollection(streamFontCollectionLoader.get(), NULL, 0,
|
| - &streamFontCollection));
|
| + SkTScopedComPtr<IDWriteFontCollection> fontCollection;
|
| + HRN(factory->CreateCustomFontCollection(fontCollectionLoader.get(), NULL, 0, &fontCollection));
|
|
|
| - SkTScopedComPtr<IDWriteFontFamily> fontFamily;
|
| - HRN(streamFontCollection->GetFontFamily(0, &fontFamily));
|
| + // Find the first non-simulated font which has the given ttc index.
|
| + UINT32 familyCount = fontCollection->GetFontFamilyCount();
|
| + for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) {
|
| + SkTScopedComPtr<IDWriteFontFamily> fontFamily;
|
| + HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily));
|
|
|
| - SkTScopedComPtr<IDWriteFont> font;
|
| - HRN(fontFamily->GetFont(0, &font));
|
| + UINT32 fontCount = fontFamily->GetFontCount();
|
| + for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
|
| + SkTScopedComPtr<IDWriteFont> font;
|
| + HRN(fontFamily->GetFont(fontIndex, &font));
|
| + if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
|
| + continue;
|
| + }
|
|
|
| - SkTScopedComPtr<IDWriteFontFace> fontFace;
|
| - HRN(font->CreateFontFace(&fontFace));
|
| + SkTScopedComPtr<IDWriteFontFace> fontFace;
|
| + HRN(font->CreateFontFace(&fontFace));
|
|
|
| - return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(),
|
| - fontFileLoader.get(), streamFontCollectionLoader.get());
|
| + UINT32 faceIndex = fontFace->GetIndex();
|
| + if (faceIndex == ttcIndex) {
|
| + return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(),
|
| + autoUnregisterFontFileLoader.detatch(),
|
| + autoUnregisterFontCollectionLoader.detatch());
|
| + }
|
| + }
|
| + }
|
| +
|
| + return NULL;
|
| }
|
|
|
| SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
|
| - return create_from_stream(stream);
|
| + return create_from_stream(stream, 0);
|
| }
|
|
|
| SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
|
| - *ttcIndex = 0;
|
| + *ttcIndex = fDWriteFontFace->GetIndex();
|
|
|
| UINT32 numFiles;
|
| HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL),
|
| @@ -1190,21 +1221,10 @@
|
| SkTypeface::Style style) {
|
| HRESULT hr;
|
| SkTScopedComPtr<IDWriteFontFamily> fontFamily;
|
| - SkTScopedComPtr<IDWriteFontCollectionLoader> fontCollectionLoader;
|
| - SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
|
| if (familyFace) {
|
| const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(familyFace);
|
| - face->fDWriteFontFamily.get()->AddRef();
|
| - *(&fontFamily) = face->fDWriteFontFamily.get();
|
| + *(&fontFamily) = SkRefComPtr(face->fDWriteFontFamily.get());
|
|
|
| - if (face->fDWriteFontCollectionLoader.get() != NULL) {
|
| - face->fDWriteFontCollectionLoader.get()->AddRef();
|
| - *(&fontCollectionLoader) = face->fDWriteFontCollectionLoader.get();
|
| -
|
| - face->fDWriteFontFileLoader.get()->AddRef();
|
| - *(&fontFileLoader) = face->fDWriteFontFileLoader.get();
|
| - }
|
| -
|
| } else if (familyName) {
|
| hr = get_by_family_name(familyName, &fontFamily);
|
| }
|
| @@ -1349,13 +1369,12 @@
|
| : fFontFace(fontFace)
|
| , fExists(FALSE) {
|
|
|
| - //fontFace->AddRef();
|
| const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0,
|
| T::TAG1,
|
| T::TAG2,
|
| T::TAG3);
|
| - // TODO: need to check for failure
|
| - /*HRESULT hr =*/ fontFace->TryGetFontTable(tag,
|
| + // Any errors are ignored, user must check fExists anyway.
|
| + fontFace->TryGetFontTable(tag,
|
| reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
|
| }
|
| ~AutoDWriteTable() {
|
| @@ -1369,7 +1388,7 @@
|
| UINT32 fSize;
|
| BOOL fExists;
|
| private:
|
| - //SkTScopedComPtr<IDWriteFontFace> fFontFace;
|
| + // Borrowed reference, the user must ensure the fontFace stays alive.
|
| IDWriteFontFace* fFontFace;
|
| void* fLock;
|
| };
|
| @@ -1673,7 +1692,7 @@
|
| return sset.matchStyle(fontstyle);
|
| }
|
| virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE {
|
| - return create_from_stream(stream);
|
| + return create_from_stream(stream, ttcIndex);
|
| }
|
| virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE {
|
| SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
|
|
|