12a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 The Android Open Source Project
32a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
62a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org */
72a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
8325cb9aa17b94258b362082eb3a799524f4345f3vandebo@chromium.org#include "SkAdvancedTypefaceMetrics.h"
90f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo#include "SkEndian.h"
105526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com#include "SkFontDescriptor.h"
11f91c47d91d72a1d85e2d6701864b8d7accc81647bungeman#include "SkFontMgr.h"
12f93d71122e4fcfcdc674a0163455990b13855f2fbungeman#include "SkMakeUnique.h"
131b24933e52f50773de29332387a12721811f3012mtklein#include "SkMutex.h"
140f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo#include "SkOTTable_OS_2.h"
15ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein#include "SkOnce.h"
165526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com#include "SkStream.h"
175526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com#include "SkTypeface.h"
18e3aea10428d1597838fd563c92340beaf969a9b4bungeman#include "SkTypefaceCache.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20e3aea10428d1597838fd563c92340beaf969a9b4bungemanSkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch)
21e3aea10428d1597838fd563c92340beaf969a9b4bungeman    : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { }
222f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com
23a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungemanSkTypeface::~SkTypeface() { }
242f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com
255ef194c31ae498166bd9c468993514c5267ea077caryclark#ifdef SK_WHITELIST_SERIALIZED_TYPEFACES
265ef194c31ae498166bd9c468993514c5267ea077caryclarkextern void WhitelistSerializeTypeface(const SkTypeface*, SkWStream* );
275ef194c31ae498166bd9c468993514c5267ea077caryclark#define SK_TYPEFACE_DELEGATE WhitelistSerializeTypeface
285ef194c31ae498166bd9c468993514c5267ea077caryclark#else
295ef194c31ae498166bd9c468993514c5267ea077caryclark#define SK_TYPEFACE_DELEGATE nullptr
305ef194c31ae498166bd9c468993514c5267ea077caryclark#endif
3183ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark
32ee6a9919a362e16c1d84a870ce867d1ad7b8a141mbocsk_sp<SkTypeface> (*gCreateTypefaceDelegate)(const char[], SkFontStyle) = nullptr;
33ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc
345ef194c31ae498166bd9c468993514c5267ea077caryclarkvoid (*gSerializeTypefaceDelegate)(const SkTypeface*, SkWStream* ) = SK_TYPEFACE_DELEGATE;
3513b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> (*gDeserializeTypefaceDelegate)(SkStream* ) = nullptr;
3683ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark
372f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com///////////////////////////////////////////////////////////////////////////////
382f3dc9dc4c970bd066be329a842a791d91f524e2reed@google.com
39a821af83890d3b365c7b871f939737d47c48139cbungemannamespace {
40a821af83890d3b365c7b871f939737d47c48139cbungeman
415c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.comclass SkEmptyTypeface : public SkTypeface {
425c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.compublic:
43385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    static SkEmptyTypeface* Create() { return new SkEmptyTypeface; }
445c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.comprotected:
45e3aea10428d1597838fd563c92340beaf969a9b4bungeman    SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
46c4df655b37aea7097d3007b299de582ba517ef16commit-bot@chromium.org
4796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; }
48a9322c2d86aaef1085c267dfc43cf0747f170a86reed    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
49a9322c2d86aaef1085c267dfc43cf0747f170a86reed                                           const SkDescriptor*) const override {
5096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
515c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com    }
5236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onFilterRec(SkScalerContextRec*) const override { }
53209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
54209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary        return nullptr;
55209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    }
5636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
573c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
5836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                                uint16_t glyphs[], int glyphCount) const override {
593c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com        if (glyphs && glyphCount > 0) {
603c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com            sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
613c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com        }
623c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com        return 0;
633c996f8a15e5d8fada9550d978e9b5344b81d276bungeman@google.com    }
64fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein    int onCountGlyphs() const override { return 0; }
65fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein    int onGetUPEM() const override { return 0; }
665c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com    class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
675c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com    public:
6836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        bool next(SkTypeface::LocalizedString*) override { return false; }
695c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com    };
7036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFamilyName(SkString* familyName) const override {
71b374d6a62c0259387d90cad74753d8bad9ee1beabungeman        familyName->reset();
72b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    }
7336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
74385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        return new EmptyLocalizedStrings;
75fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein    }
76fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
77fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner                                     int coordinateCount) const override
78fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    {
79fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner        return 0;
80fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    }
8136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
8236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
835c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com        return 0;
845c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com    }
855c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com};
865c1d88dca00ad884dce6403c223d799dbe5258e3bungeman@google.com
87a821af83890d3b365c7b871f939737d47c48139cbungeman}
88a821af83890d3b365c7b871f939737d47c48139cbungeman
89148ec59001ca7d7e54aec580a048c6dd2a085991mtkleinSkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
90ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein    static SkOnce once[4];
91ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein    static SkTypeface* defaults[4];
92ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein
9378358bf624c7e7c09ffccf638c50870808d884d6mtklein    SkASSERT((int)style < 4);
94ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein    once[style]([style] {
95704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary        sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
9611a77c6e0634e2feb6fe4e74806db2fdd2a799ecbungeman        SkTypeface* t = fm->legacyCreateTypeface(nullptr, SkFontStyle::FromOldStyle(style));
97ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein        defaults[style] = t ? t : SkEmptyTypeface::Create();
986c59d80858f453a426df9b07fdf3a8cc01e0b906mtklein    });
99ffa4a9213b4e754adc210fa02a3c4b1ae8d3b6d0mtklein    return defaults[style];
100538f784e3d9b898ff90de9d766eddb9fa38f4a43reed@google.com}
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10213b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> SkTypeface::MakeDefault(Style style) {
10313b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    return sk_ref_sp(GetDefaultTypeface(style));
104fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com}
105fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com
106538f784e3d9b898ff90de9d766eddb9fa38f4a43reed@google.comuint32_t SkTypeface::UniqueID(const SkTypeface* face) {
10796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == face) {
108cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com        face = GetDefaultTypeface();
109b1d9d2ef2803bd55fdc886d13033b48f8450dd14reed@android.com    }
110538f784e3d9b898ff90de9d766eddb9fa38f4a43reed@google.com    return face->uniqueID();
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
113ef772ddb86e9ab5e7e2811c67ed75a24f3ce0e5ereed@android.combool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
11448fc0ea272916a04f947bcd5bfce44fdab1f16b4jin.a.yang    return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
119ee6a9919a362e16c1d84a870ce867d1ad7b8a141mbocsk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[],
120ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                                           SkFontStyle fontStyle) {
12183ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark    if (gCreateTypefaceDelegate) {
122ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc        sk_sp<SkTypeface> result = (*gCreateTypefaceDelegate)(name, fontStyle);
12383ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark        if (result) {
12483ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark            return result;
12583ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark        }
12683ca628cb6c959524edc3a696d7c3b5f7f1826bacaryclark    }
127ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc    if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant ||
128ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                            fontStyle.slant() == SkFontStyle::kUpright_Slant) &&
129ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                           (fontStyle.weight() == SkFontStyle::kBold_Weight ||
130ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                            fontStyle.weight() == SkFontStyle::kNormal_Weight)) {
131ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc        return MakeDefault(static_cast<SkTypeface::Style>(
132ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc            (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic :
133ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                                                               SkTypeface::kNormal) |
134ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc            (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold :
135ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc                                                               SkTypeface::kNormal)));
1364fa748d5801df66e46e6f4e98e07523d44d261a2djsollen@google.com    }
137704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
138ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc    return sk_sp<SkTypeface>(fm->legacyCreateTypeface(name, fontStyle));
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14113b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> SkTypeface::MakeFromTypeface(SkTypeface* family, Style s) {
142b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman    if (!family) {
14313b9c95295f4c5732e34574789e721a6bc08f7b4bungeman        return SkTypeface::MakeDefault(s);
144b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman    }
145b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman
146b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman    if (family->style() == s) {
14713b9c95295f4c5732e34574789e721a6bc08f7b4bungeman        return sk_ref_sp(family);
1484969044d0b86c6ef76aed2dad77f180ad45c91bbreed@google.com    }
149b14e4a0db5cb1b96cef5236585ee4572c5d95b97bungeman
150704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
15113b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    return sk_sp<SkTypeface>(fm->matchFaceStyle(family, SkFontStyle::FromOldStyle(s)));
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15413b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> SkTypeface::MakeFromStream(SkStreamAsset* stream, int index) {
155704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
15613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    return sk_sp<SkTypeface>(fm->createFromStream(stream, index));
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
159f93d71122e4fcfcdc674a0163455990b13855f2fbungemansk_sp<SkTypeface> SkTypeface::MakeFromFontData(std::unique_ptr<SkFontData> data) {
160704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
161f93d71122e4fcfcdc674a0163455990b13855f2fbungeman    return sk_sp<SkTypeface>(fm->createFromFontData(std::move(data)));
16241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman}
16341868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
16413b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> SkTypeface::MakeFromFile(const char path[], int index) {
165704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
16613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    return sk_sp<SkTypeface>(fm->createFromFile(path, index));
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1715526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.comvoid SkTypeface::serialize(SkWStream* wstream) const {
1725ef194c31ae498166bd9c468993514c5267ea077caryclark    if (gSerializeTypefaceDelegate) {
1735ef194c31ae498166bd9c468993514c5267ea077caryclark        (*gSerializeTypefaceDelegate)(this, wstream);
1745ef194c31ae498166bd9c468993514c5267ea077caryclark        return;
1755ef194c31ae498166bd9c468993514c5267ea077caryclark    }
1765526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com    bool isLocal = false;
177b8113780c3cfed640016b263194b7f1531d43312bungeman    SkFontDescriptor desc;
1785526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com    this->onGetFontDescriptor(&desc, &isLocal);
1795526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com
1801a4900e8be6086a824488dc98d4822e440815657mtklein    // Embed font data if it's a local font.
1815ae1312c9faa25531c07e591b4dff6804020f121bungeman    if (isLocal && !desc.hasFontData()) {
182f93d71122e4fcfcdc674a0163455990b13855f2fbungeman        desc.setFontData(this->onMakeFontData());
1835526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com    }
1841a4900e8be6086a824488dc98d4822e440815657mtklein    desc.serialize(wstream);
1851a4900e8be6086a824488dc98d4822e440815657mtklein}
1861a4900e8be6086a824488dc98d4822e440815657mtklein
18713b9c95295f4c5732e34574789e721a6bc08f7b4bungemansk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) {
1885ef194c31ae498166bd9c468993514c5267ea077caryclark    if (gDeserializeTypefaceDelegate) {
1895ef194c31ae498166bd9c468993514c5267ea077caryclark        return (*gDeserializeTypefaceDelegate)(stream);
1905ef194c31ae498166bd9c468993514c5267ea077caryclark    }
1913552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips
1923552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips    SkFontDescriptor desc;
1933552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips    if (!SkFontDescriptor::Deserialize(stream, &desc)) {
1943552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips        return nullptr;
1953552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips    }
1963552ba18ee41e135d6fc52228adae37794fc15ffrobertphillips
197f93d71122e4fcfcdc674a0163455990b13855f2fbungeman    std::unique_ptr<SkFontData> data = desc.detachFontData();
198d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    if (data) {
199f93d71122e4fcfcdc674a0163455990b13855f2fbungeman        sk_sp<SkTypeface> typeface(SkTypeface::MakeFromFontData(std::move(data)));
200d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman        if (typeface) {
201d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman            return typeface;
2025526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com        }
2035526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com    }
204ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc
205b8113780c3cfed640016b263194b7f1531d43312bungeman    return SkTypeface::MakeFromName(desc.getFamilyName(), desc.getStyle());
2062a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
207f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
208f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com///////////////////////////////////////////////////////////////////////////////
209f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
210fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagnerint SkTypeface::getVariationDesignPosition(
211fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner        SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
212fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner{
213fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    return this->onGetVariationDesignPosition(coordinates, coordinateCount);
214fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner}
215fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner
216f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.comint SkTypeface::countTables() const {
21796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return this->onGetTableTags(nullptr);
218f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com}
219f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
220f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.comint SkTypeface::getTableTags(SkFontTableTag tags[]) const {
2216c66d2f2b6525576524308c84eb952bb4bccf664reed@google.com    return this->onGetTableTags(tags);
222f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com}
223f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
224f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.comsize_t SkTypeface::getTableSize(SkFontTableTag tag) const {
22596fcdcc219d2a0d3579719b84b28bede76efba64halcanary    return this->onGetTableData(tag, 0, ~0U, nullptr);
226f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com}
227f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
228f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.comsize_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
229f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com                                void* data) const {
2306c66d2f2b6525576524308c84eb952bb4bccf664reed@google.com    return this->onGetTableData(tag, offset, length, data);
231f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com}
232f11508d7f4aae52739b9c4f3bb2da2fd78fa23d9reed@google.com
2335f213d9627d2eefa7da81cd97f36754f75eb4ae9bungemanSkStreamAsset* SkTypeface::openStream(int* ttcIndex) const {
2342cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com    int ttcIndexStorage;
23596fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == ttcIndex) {
2362cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com        // So our subclasses don't need to check for null param
2372cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com        ttcIndex = &ttcIndexStorage;
238fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    }
2392cdc6713fb04c46ecbc73a724029a8b266004ddfreed@google.com    return this->onOpenStream(ttcIndex);
240fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com}
241fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com
242f93d71122e4fcfcdc674a0163455990b13855f2fbungemanstd::unique_ptr<SkFontData> SkTypeface::makeFontData() const {
243f93d71122e4fcfcdc674a0163455990b13855f2fbungeman    return this->onMakeFontData();
24441868fe5625fc3bd70daa3f461c881b5db6a9265bungeman}
24541868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
24641868fe5625fc3bd70daa3f461c881b5db6a9265bungeman// This implementation is temporary until this method can be made pure virtual.
247f93d71122e4fcfcdc674a0163455990b13855f2fbungemanstd::unique_ptr<SkFontData> SkTypeface::onMakeFontData() const {
24841868fe5625fc3bd70daa3f461c881b5db6a9265bungeman    int index;
249f93d71122e4fcfcdc674a0163455990b13855f2fbungeman    std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
250f93d71122e4fcfcdc674a0163455990b13855f2fbungeman    return skstd::make_unique<SkFontData>(std::move(stream), index, nullptr, 0);
25141868fe5625fc3bd70daa3f461c881b5db6a9265bungeman};
25241868fe5625fc3bd70daa3f461c881b5db6a9265bungeman
253bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comint SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
254bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com                              uint16_t glyphs[], int glyphCount) const {
255bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    if (glyphCount <= 0) {
256bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        return 0;
257bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
25896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == chars || (unsigned)encoding > kUTF32_Encoding) {
259bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        if (glyphs) {
260bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
261bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        }
262bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        return 0;
263bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
264bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
265bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
266bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
267bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comint SkTypeface::countGlyphs() const {
268bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return this->onCountGlyphs();
269bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
270bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
2714b2af9c91d39c2176a32e7ba42a0276dca68034areed@google.comint SkTypeface::getUnitsPerEm() const {
27238c37ddbaf3b29cdacbc25d4aa2acca1869d276freed@google.com    // should we try to cache this in the base-class?
27338c37ddbaf3b29cdacbc25d4aa2acca1869d276freed@google.com    return this->onGetUPEM();
27438c37ddbaf3b29cdacbc25d4aa2acca1869d276freed@google.com}
27538c37ddbaf3b29cdacbc25d4aa2acca1869d276freed@google.com
27635fe7372b1b897a77578a220c334e1fb36d144e9reed@google.combool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count,
27735fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com                                           int32_t adjustments[]) const {
27835fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    SkASSERT(count >= 0);
27996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    // check for the only legal way to pass a nullptr.. everything is 0
28035fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    // in which case they just want to know if this face can possibly support
28135fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    // kerning (true) or never (false).
28296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == glyphs || nullptr == adjustments) {
28396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkASSERT(nullptr == glyphs);
28435fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com        SkASSERT(0 == count);
28596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkASSERT(nullptr == adjustments);
28635fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    }
28735fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
28835fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com}
28935fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com
290839702b61934914118ec557dd641be322eba3b5fbungeman@google.comSkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
291839702b61934914118ec557dd641be322eba3b5fbungeman@google.com    return this->onCreateFamilyNameIterator();
292a980269c2498836101146adc729ef780fb89824ebungeman@google.com}
293a980269c2498836101146adc729ef780fb89824ebungeman@google.com
29408df48d2411b33a9078f1621894d630f0b11cd60reed@google.comvoid SkTypeface::getFamilyName(SkString* name) const {
295b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    SkASSERT(name);
296b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    this->onGetFamilyName(name);
29708df48d2411b33a9078f1621894d630f0b11cd60reed@google.com}
29808df48d2411b33a9078f1621894d630f0b11cd60reed@google.com
299209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canarystd::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const {
300209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics();
3010f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
30201a16992cc9297d4985dc80e3177cc7475b9b385bungeman        SkOTTableOS2::Version::V2::Type::Field fsType;
30301a16992cc9297d4985dc80e3177cc7475b9b385bungeman        constexpr SkFontTableTag os2Tag = SkTEndian_SwapBE32(SkOTTableOS2::TAG);
30401a16992cc9297d4985dc80e3177cc7475b9b385bungeman        constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType);
30501a16992cc9297d4985dc80e3177cc7475b9b385bungeman        if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) {
30601a16992cc9297d4985dc80e3177cc7475b9b385bungeman            if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) {
3073287588a467ee579c3947fe13c6add5048b14aa9halcanary                result->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
3080f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            }
30901a16992cc9297d4985dc80e3177cc7475b9b385bungeman            if (fsType.NoSubsetting) {
3103287588a467ee579c3947fe13c6add5048b14aa9halcanary                result->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
3110f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            }
3120f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        }
3130f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
3140f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    return result;
3155526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com}
3165526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com
31735fe7372b1b897a77578a220c334e1fb36d144e9reed@google.combool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
31835fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com                                             int32_t adjustments[]) const {
31935fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com    return false;
32035fe7372b1b897a77578a220c334e1fb36d144e9reed@google.com}
321a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
322a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed///////////////////////////////////////////////////////////////////////////////
323a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
324a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed#include "SkDescriptor.h"
325a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed#include "SkPaint.h"
326a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
3276c59d80858f453a426df9b07fdf3a8cc01e0b906mtkleinSkRect SkTypeface::getBounds() const {
32859c12e3f0071acfa685346487e54a2a311066dacmtklein    fBoundsOnce([this] {
32959c12e3f0071acfa685346487e54a2a311066dacmtklein        if (!this->onComputeBounds(&fBounds)) {
33059c12e3f0071acfa685346487e54a2a311066dacmtklein            fBounds.setEmpty();
331a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed        }
3326c59d80858f453a426df9b07fdf3a8cc01e0b906mtklein    });
33359c12e3f0071acfa685346487e54a2a311066dacmtklein    return fBounds;
334a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed}
335a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
336a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breedbool SkTypeface::onComputeBounds(SkRect* bounds) const {
337a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    // we use a big size to ensure lots of significant bits from the scalercontext.
338a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    // then we scale back down to return our final answer (at 1-pt)
339a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    const SkScalar textSize = 2048;
340a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    const SkScalar invTextSize = 1 / textSize;
341a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
342a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    SkPaint paint;
34313b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    paint.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this)));
344a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    paint.setTextSize(textSize);
345a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    paint.setLinearText(true);
346a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
347a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    SkScalerContext::Rec rec;
34896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    SkScalerContext::MakeRec(paint, nullptr, nullptr, &rec);
349a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
350a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
351a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    SkDescriptor*    desc = ad.getDesc();
352a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    desc->init();
353a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
354a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed
355a9322c2d86aaef1085c267dfc43cf0747f170a86reed    SkScalerContextEffects noeffects;
3567cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, desc, true);
3577cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    if (!ctx) {
3587cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman        return false;
359a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed    }
3607cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman
3617cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    SkPaint::FontMetrics fm;
3627cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    ctx->getFontMetrics(&fm);
3637cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize,
3647cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman                fm.fXMax * invTextSize, fm.fBottom * invTextSize);
3657cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    return true;
366a0c814cffb7ba91e1c3b533e68ab591d9cee8f2breed}
367209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary
368209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canarystd::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::onGetAdvancedMetrics() const {
3692627b0473fc1f77cce4f40157818f39c6e366452Hal Canary    SkDEBUGFAIL("Typefaces that need to work with PDF backend must override this.");
370209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    return nullptr;
371209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary}
372