172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com/*
272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * Copyright 2014 Google Inc.
372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com *
472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * Use of this source code is governed by a BSD-style license that can be
572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * found in the LICENSE file.
672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com */
772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#ifndef SkFontMgr_indirect_DEFINED
972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#define SkFontMgr_indirect_DEFINED
1072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
1172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkDataTable.h"
1272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkFontMgr.h"
1372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkFontStyle.h"
1472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkRemotableFontMgr.h"
1572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkTArray.h"
1672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkTypeface.h"
1772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
1872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkData;
1972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkStream;
2072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkString;
2172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkTypeface;
2272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
2372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SK_API SkFontMgr_Indirect : public SkFontMgr {
2472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.compublic:
2572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    // TODO: The SkFontMgr is only used for createFromStream/File/Data.
2672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    // In the future these calls should be broken out into their own interface
2772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    // with a name like SkFontRenderer.
2872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    SkFontMgr_Indirect(SkFontMgr* impl, SkRemotableFontMgr* proxy)
291ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com        : fImpl(SkRef(impl)), fProxy(SkRef(proxy)), fFamilyNamesInited(false)
301ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com    { }
3172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
3272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comprotected:
3372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual int onCountFamilies() const SK_OVERRIDE;
3472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE;
3572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE;
3672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
3772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE;
3872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
3972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
4072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com                                           const SkFontStyle& fontStyle) const SK_OVERRIDE;
4172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
42b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
4372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
4472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com                                                    const SkFontStyle&,
45b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    const char* bcp47[],
46b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    int bcp47Count,
47b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    SkUnichar character) const SK_OVERRIDE;
48b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman#else
49b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
50b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    const SkFontStyle&,
51b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    const char bcp47[],
52b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman                                                    SkUnichar character) const SK_OVERRIDE;
53b4f3d69b8e18128598b8f62dd6fc7ae0e761cd57bungeman#endif
5472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
5572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
5672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com                                         const SkFontStyle& fontStyle) const SK_OVERRIDE;
5772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
5872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE;
5972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE;
6072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE;
6172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
6272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
6372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com                                               unsigned styleBits) const SK_OVERRIDE;
6472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
6572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comprivate:
6672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    SkTypeface* createTypefaceFromFontId(const SkFontIdentity& fontId) const;
6772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
6872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    SkAutoTUnref<SkFontMgr> fImpl;
6972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    SkAutoTUnref<SkRemotableFontMgr> fProxy;
7072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
7172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    struct DataEntry {
723d21f21cac33743e7aedace9abf0473c5063199fbungeman@google.com        uint32_t fDataId;  // key1
73f76cbb884819830ea51ed090c7d7d4427bcbfdf5bungeman@google.com        uint32_t fTtcIndex;  // key2
7472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        SkTypeface* fTypeface;  // value: weak ref to typeface
7572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
7672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        DataEntry() { }
7772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
7872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        // This is a move!!!
7972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        DataEntry(DataEntry& that)
8072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            : fDataId(that.fDataId)
8172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            , fTtcIndex(that.fTtcIndex)
8272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            , fTypeface(that.fTypeface)
8372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        {
84c8f0d606e53823ab8e35bebdf2bbb023eae2bbbdbungeman@google.com            SkDEBUGCODE(that.fDataId = SkFontIdentity::kInvalidDataId;)
85c8f0d606e53823ab8e35bebdf2bbb023eae2bbbdbungeman@google.com            SkDEBUGCODE(that.fTtcIndex = 0xbbadbeef;)
8672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            that.fTypeface = NULL;
8772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        }
8872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
8972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        ~DataEntry() {
9072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            if (fTypeface) {
9172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com                fTypeface->weak_unref();
9272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com            }
9372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com        }
9472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    };
9572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    /**
9672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com     *  This cache is essentially { dataId: { ttcIndex: typeface } }
9772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com     *  For data caching we want a mapping from data id to weak references to
9872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com     *  typefaces with that data id. By storing the index next to the typeface,
9972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com     *  this data cache also acts as a typeface cache.
10072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com     */
10172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    mutable SkTArray<DataEntry> fDataCache;
10272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    mutable SkMutex fDataCacheMutex;
10372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
10472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    mutable SkAutoTUnref<SkDataTable> fFamilyNames;
1051ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com    mutable bool fFamilyNamesInited;
1061ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com    mutable SkMutex fFamilyNamesMutex;
10772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    static void set_up_family_names(const SkFontMgr_Indirect* self);
10872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
10972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com    friend class SkStyleSet_Indirect;
11072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com};
11172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com
11272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#endif
113