diff options
author | Kohsuke Yatoh <kyatoh@google.com> | 2021-01-22 15:31:50 -0800 |
---|---|---|
committer | Kohsuke Yatoh <kyatoh@google.com> | 2021-01-23 19:26:03 +0000 |
commit | df817a7dc8e66e87b63c38815058d24b021be578 (patch) | |
tree | ee1d557d7a4833d714160d419e8edd0a77c8578e | |
parent | bcba17031d7619fa253ec34b7b830d39378935f6 (diff) | |
download | minikin-df817a7dc8e66e87b63c38815058d24b021be578.tar.gz |
Split Font.cpp from FontFamily.cpp.
Test: atest minikin_tests
Change-Id: I0d65899c865d410b63dac758b8250084a20da7ae
-rw-r--r-- | libs/minikin/Android.bp | 1 | ||||
-rw-r--r-- | libs/minikin/Font.cpp | 125 | ||||
-rw-r--r-- | libs/minikin/FontFamily.cpp | 93 |
3 files changed, 126 insertions, 93 deletions
diff --git a/libs/minikin/Android.bp b/libs/minikin/Android.bp index c0fe9e0..8746d87 100644 --- a/libs/minikin/Android.bp +++ b/libs/minikin/Android.bp @@ -27,6 +27,7 @@ cc_library { "BoundsCache.cpp", "CmapCoverage.cpp", "Emoji.cpp", + "Font.cpp", "FontCollection.cpp", "FontFamily.cpp", "FontFileParser.cpp", diff --git a/libs/minikin/Font.cpp b/libs/minikin/Font.cpp new file mode 100644 index 0000000..30a2734 --- /dev/null +++ b/libs/minikin/Font.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "Minikin" + +#include "minikin/Font.h" + +#include <vector> + +#include <hb-ot.h> +#include <hb.h> +#include <log/log.h> + +#include "minikin/HbUtils.h" +#include "minikin/MinikinFont.h" + +#include "FontUtils.h" +#include "MinikinInternal.h" + +namespace minikin { + +std::shared_ptr<Font> Font::Builder::build() { + if (mIsWeightSet && mIsSlantSet) { + // No need to read OS/2 header of the font file. + return std::shared_ptr<Font>( + new Font(std::move(mTypeface), FontStyle(mWeight, mSlant), prepareFont(mTypeface))); + } + + HbFontUniquePtr font = prepareFont(mTypeface); + FontStyle styleFromFont = analyzeStyle(font); + if (!mIsWeightSet) { + mWeight = styleFromFont.weight(); + } + if (!mIsSlantSet) { + mSlant = styleFromFont.slant(); + } + return std::shared_ptr<Font>( + new Font(std::move(mTypeface), FontStyle(mWeight, mSlant), std::move(font))); +} + +const std::shared_ptr<MinikinFont>& Font::typeface() const { + std::lock_guard lock(mTypefaceMutex); + if (mTypeface) return mTypeface; + initTypefaceLocked(); + return mTypeface; +} + +const HbFontUniquePtr& Font::baseFont() const { + std::lock_guard lock(mTypefaceMutex); + if (mBaseFont) return mBaseFont; + initTypefaceLocked(); + mBaseFont = prepareFont(mTypeface); + return mBaseFont; +} + +void Font::initTypefaceLocked() const { + if (mTypeface) return; + MINIKIN_ASSERT(mTypefaceLoader, "mTypefaceLoader should not be empty when mTypeface is null"); + mTypeface = mTypefaceLoader(); +} + +// static +HbFontUniquePtr Font::prepareFont(const std::shared_ptr<MinikinFont>& typeface) { + const char* buf = reinterpret_cast<const char*>(typeface->GetFontData()); + size_t size = typeface->GetFontSize(); + uint32_t ttcIndex = typeface->GetFontIndex(); + + HbBlobUniquePtr blob(hb_blob_create(buf, size, HB_MEMORY_MODE_READONLY, nullptr, nullptr)); + HbFaceUniquePtr face(hb_face_create(blob.get(), ttcIndex)); + HbFontUniquePtr parent(hb_font_create(face.get())); + hb_ot_font_set_funcs(parent.get()); + + uint32_t upem = hb_face_get_upem(face.get()); + hb_font_set_scale(parent.get(), upem, upem); + + HbFontUniquePtr font(hb_font_create_sub_font(parent.get())); + std::vector<hb_variation_t> variations; + variations.reserve(typeface->GetAxes().size()); + for (const FontVariation& variation : typeface->GetAxes()) { + variations.push_back({variation.axisTag, variation.value}); + } + hb_font_set_variations(font.get(), variations.data(), variations.size()); + return font; +} + +// static +FontStyle Font::analyzeStyle(const HbFontUniquePtr& font) { + HbBlob os2Table(font, MinikinFont::MakeTag('O', 'S', '/', '2')); + if (!os2Table) { + return FontStyle(); + } + + int weight; + bool italic; + if (!::minikin::analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) { + return FontStyle(); + } + // TODO: Update weight/italic based on fvar value. + return FontStyle(static_cast<uint16_t>(weight), static_cast<FontStyle::Slant>(italic)); +} + +std::unordered_set<AxisTag> Font::getSupportedAxes() const { + HbBlob fvarTable(baseFont(), MinikinFont::MakeTag('f', 'v', 'a', 'r')); + if (!fvarTable) { + return std::unordered_set<AxisTag>(); + } + std::unordered_set<AxisTag> supportedAxes; + analyzeAxes(fvarTable.get(), fvarTable.size(), &supportedAxes); + return supportedAxes; +} + +} // namespace minikin diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp index 743ee3a..ef262e9 100644 --- a/libs/minikin/FontFamily.cpp +++ b/libs/minikin/FontFamily.cpp @@ -19,11 +19,8 @@ #include "minikin/FontFamily.h" #include <algorithm> -#include <cstdint> #include <vector> -#include <hb-ot.h> -#include <hb.h> #include <log/log.h> #include "minikin/CmapCoverage.h" @@ -38,96 +35,6 @@ namespace minikin { -std::shared_ptr<Font> Font::Builder::build() { - if (mIsWeightSet && mIsSlantSet) { - // No need to read OS/2 header of the font file. - return std::shared_ptr<Font>( - new Font(std::move(mTypeface), FontStyle(mWeight, mSlant), prepareFont(mTypeface))); - } - - HbFontUniquePtr font = prepareFont(mTypeface); - FontStyle styleFromFont = analyzeStyle(font); - if (!mIsWeightSet) { - mWeight = styleFromFont.weight(); - } - if (!mIsSlantSet) { - mSlant = styleFromFont.slant(); - } - return std::shared_ptr<Font>( - new Font(std::move(mTypeface), FontStyle(mWeight, mSlant), std::move(font))); -} - -const std::shared_ptr<MinikinFont>& Font::typeface() const { - std::lock_guard lock(mTypefaceMutex); - if (mTypeface) return mTypeface; - initTypefaceLocked(); - return mTypeface; -} - -const HbFontUniquePtr& Font::baseFont() const { - std::lock_guard lock(mTypefaceMutex); - if (mBaseFont) return mBaseFont; - initTypefaceLocked(); - mBaseFont = prepareFont(mTypeface); - return mBaseFont; -} - -void Font::initTypefaceLocked() const { - if (mTypeface) return; - MINIKIN_ASSERT(mTypefaceLoader, "mTypefaceLoader should not be empty when mTypeface is null"); - mTypeface = mTypefaceLoader(); -} - -// static -HbFontUniquePtr Font::prepareFont(const std::shared_ptr<MinikinFont>& typeface) { - const char* buf = reinterpret_cast<const char*>(typeface->GetFontData()); - size_t size = typeface->GetFontSize(); - uint32_t ttcIndex = typeface->GetFontIndex(); - - HbBlobUniquePtr blob(hb_blob_create(buf, size, HB_MEMORY_MODE_READONLY, nullptr, nullptr)); - HbFaceUniquePtr face(hb_face_create(blob.get(), ttcIndex)); - HbFontUniquePtr parent(hb_font_create(face.get())); - hb_ot_font_set_funcs(parent.get()); - - uint32_t upem = hb_face_get_upem(face.get()); - hb_font_set_scale(parent.get(), upem, upem); - - HbFontUniquePtr font(hb_font_create_sub_font(parent.get())); - std::vector<hb_variation_t> variations; - variations.reserve(typeface->GetAxes().size()); - for (const FontVariation& variation : typeface->GetAxes()) { - variations.push_back({variation.axisTag, variation.value}); - } - hb_font_set_variations(font.get(), variations.data(), variations.size()); - return font; -} - -// static -FontStyle Font::analyzeStyle(const HbFontUniquePtr& font) { - HbBlob os2Table(font, MinikinFont::MakeTag('O', 'S', '/', '2')); - if (!os2Table) { - return FontStyle(); - } - - int weight; - bool italic; - if (!::minikin::analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) { - return FontStyle(); - } - // TODO: Update weight/italic based on fvar value. - return FontStyle(static_cast<uint16_t>(weight), static_cast<FontStyle::Slant>(italic)); -} - -std::unordered_set<AxisTag> Font::getSupportedAxes() const { - HbBlob fvarTable(baseFont(), MinikinFont::MakeTag('f', 'v', 'a', 'r')); - if (!fvarTable) { - return std::unordered_set<AxisTag>(); - } - std::unordered_set<AxisTag> supportedAxes; - analyzeAxes(fvarTable.get(), fvarTable.size(), &supportedAxes); - return supportedAxes; -} - FontFamily::FontFamily(std::vector<std::shared_ptr<Font>>&& fonts) : FontFamily(FamilyVariant::DEFAULT, std::move(fonts)) {} |