asset_manager_font_provider.cc 4.1 KB
Newer Older
M
Michael Goderbauer 已提交
1
// Copyright 2013 The Flutter Authors. All rights reserved.
2 3 4 5 6
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/lib/ui/text/asset_manager_font_provider.h"

7
#include "flutter/fml/logging.h"
8 9 10 11 12 13 14 15 16
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/skia/include/core/SkTypeface.h"

namespace blink {

namespace {

17 18
void MappingReleaseProc(const void* ptr, void* context) {
  delete reinterpret_cast<fml::Mapping*>(context);
19 20 21 22 23
}

}  // anonymous namespace

AssetManagerFontProvider::AssetManagerFontProvider(
24
    std::shared_ptr<blink::AssetManager> asset_manager)
25 26 27 28 29 30 31 32 33 34 35
    : asset_manager_(asset_manager) {}

AssetManagerFontProvider::~AssetManagerFontProvider() = default;

// |FontAssetProvider|
size_t AssetManagerFontProvider::GetFamilyCount() const {
  return family_names_.size();
}

// |FontAssetProvider|
std::string AssetManagerFontProvider::GetFamilyName(int index) const {
36
  FML_DCHECK(index >= 0 && static_cast<size_t>(index) < family_names_.size());
37 38 39 40 41 42
  return family_names_[index];
}

// |FontAssetProvider|
SkFontStyleSet* AssetManagerFontProvider::MatchFamily(
    const std::string& family_name) {
43
  auto found = registered_families_.find(CanonicalFamilyName(family_name));
44 45 46 47 48 49 50 51
  if (found == registered_families_.end()) {
    return nullptr;
  }
  return SkRef(&found->second);
}

void AssetManagerFontProvider::RegisterAsset(std::string family_name,
                                             std::string asset) {
52 53
  std::string canonical_name = CanonicalFamilyName(family_name);
  auto family_it = registered_families_.find(canonical_name);
54 55 56 57 58

  if (family_it == registered_families_.end()) {
    family_names_.push_back(family_name);
    family_it = registered_families_
                    .emplace(std::piecewise_construct,
59
                             std::forward_as_tuple(canonical_name),
60 61 62 63 64 65 66 67
                             std::forward_as_tuple(asset_manager_))
                    .first;
  }

  family_it->second.registerAsset(asset);
}

AssetManagerFontStyleSet::AssetManagerFontStyleSet(
68
    std::shared_ptr<blink::AssetManager> asset_manager)
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    : asset_manager_(asset_manager) {}

AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;

void AssetManagerFontStyleSet::registerAsset(std::string asset) {
  assets_.emplace_back(asset);
}

int AssetManagerFontStyleSet::count() {
  return assets_.size();
}

void AssetManagerFontStyleSet::getStyle(int index,
                                        SkFontStyle*,
                                        SkString* style) {
84
  FML_DCHECK(false);
85 86 87 88 89 90 91 92 93
}

SkTypeface* AssetManagerFontStyleSet::createTypeface(int i) {
  size_t index = i;
  if (index >= assets_.size())
    return nullptr;

  TypefaceAsset& asset = assets_[index];
  if (!asset.typeface) {
94 95 96
    std::unique_ptr<fml::Mapping> asset_mapping =
        asset_manager_->GetAsMapping(asset.asset);
    if (asset_mapping == nullptr) {
97
      return nullptr;
98
    }
99

100 101 102 103
    fml::Mapping* asset_mapping_ptr = asset_mapping.release();
    sk_sp<SkData> asset_data = SkData::MakeWithProc(
        asset_mapping_ptr->GetMapping(), asset_mapping_ptr->GetSize(),
        MappingReleaseProc, asset_mapping_ptr);
104 105 106
    std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(asset_data);

    // Ownership of the stream is transferred.
107
    asset.typeface = SkTypeface::MakeFromStream(std::move(stream));
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    if (!asset.typeface)
      return nullptr;
  }

  return SkRef(asset.typeface.get());
}

SkTypeface* AssetManagerFontStyleSet::matchStyle(const SkFontStyle& pattern) {
  if (assets_.empty())
    return nullptr;

  for (const TypefaceAsset& asset : assets_)
    if (asset.typeface && asset.typeface->fontStyle() == pattern)
      return SkRef(asset.typeface.get());

  return SkRef(assets_[0].typeface.get());
}

126 127 128 129 130 131 132 133
AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(std::string a)
    : asset(std::move(a)) {}

AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(
    const AssetManagerFontStyleSet::TypefaceAsset& other) = default;

AssetManagerFontStyleSet::TypefaceAsset::~TypefaceAsset() = default;

134
}  // namespace blink