1bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien/*
2bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Copyright (C) 2013 The Android Open Source Project
3bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *
4bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Licensed under the Apache License, Version 2.0 (the "License");
5bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * you may not use this file except in compliance with the License.
6bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * You may obtain a copy of the License at
7bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *
8bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *      http://www.apache.org/licenses/LICENSE-2.0
9bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *
10bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Unless required by applicable law or agreed to in writing, software
11bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * distributed under the License is distributed on an "AS IS" BASIS,
12bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * See the License for the specific language governing permissions and
14bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * limitations under the License.
15bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien */
16bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
17bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#ifndef MINIKIN_FONT_H
18bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#define MINIKIN_FONT_H
19bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
205986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod#include <string>
21dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka#include <memory>
225986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod
239a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien#include <minikin/FontFamily.h>
24c7ef4000c1e840c3d3b66e85a40ebd34a5a2a8eeRoozbeh Pournader#include <minikin/Hyphenator.h>
25b80c1f19c58b927820a8a24bf2218e5645724608Raph Levien
26bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien// An abstraction for platform fonts, allowing Minikin to be used with
27bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien// multiple actual implementations of fonts.
28bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
2914e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonakanamespace minikin {
30bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
31bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienclass MinikinFont;
32bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
33bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien// Possibly move into own .h file?
345986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod// Note: if you add a field here, either add it to LayoutCacheKey or to skipCache()
35bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienstruct MinikinPaint {
36dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka    MinikinPaint() : font(nullptr), size(0), scaleX(0), skewX(0), letterSpacing(0), wordSpacing(0),
37acd401d02981af51419f4b740abb2c41e4980fdbSeigo Nonaka            paintFlags(0), fakery(), hyphenEdit(), fontFeatureSettings() { }
385986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod
395986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod    bool skipCache() const {
406c4d167bff33c24c239d77ddb1044b18d180766aRaph Levien        return !fontFeatureSettings.empty();
415986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod    }
425986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod
43bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien    MinikinFont *font;
44bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien    float size;
45448b0fd720d7ba902b9be224a287d08abe3ebea8Raph Levien    float scaleX;
46448b0fd720d7ba902b9be224a287d08abe3ebea8Raph Levien    float skewX;
478e7a3dae37e9a22b2c054aec852615843d71caf6Behdad Esfahbod    float letterSpacing;
48acd401d02981af51419f4b740abb2c41e4980fdbSeigo Nonaka    float wordSpacing;
493164d1a77eecf3185347a44342131f4275de824fRaph Levien    uint32_t paintFlags;
509a5f713add8cfb91ac2c9ed5c917309053201ab6Raph Levien    FontFakery fakery;
51d692d6a9791145d41d7778cdf6b40b20c2be8cb4Raph Levien    HyphenEdit hyphenEdit;
525986f6048ae21e0ec094c1f2ca0169d0ca6ec6b5Behdad Esfahbod    std::string fontFeatureSettings;
53bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien};
54bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
556740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levien// Only a few flags affect layout, but those that do should have values
566740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levien// consistent with Android's paint flags.
576740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levienenum MinikinPaintFlags {
586740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levien    LinearTextFlag = 0x40,
596740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levien};
606740536e3927d25bf5c2567e5f6e8c175973cbb7Raph Levien
61ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levienstruct MinikinRect {
62ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    float mLeft, mTop, mRight, mBottom;
63ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    bool isEmpty() const {
64ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        return mLeft == mRight || mTop == mBottom;
65ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    }
66ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    void set(const MinikinRect& r) {
67ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mLeft = r.mLeft;
68ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mTop = r.mTop;
69ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mRight = r.mRight;
70ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mBottom = r.mBottom;
71ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    }
72ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    void offset(float dx, float dy) {
73ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mLeft += dx;
74ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mTop += dy;
75ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mRight += dx;
76ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mBottom += dy;
77ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    }
78ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    void setEmpty() {
79ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        mLeft = mTop = mRight = mBottom = 0;
80ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    }
81ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    void join(const MinikinRect& r);
82ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien};
83ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
84aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien// Callback for freeing data
85aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levientypedef void (*MinikinDestroyFunc) (void* data);
86aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien
87dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonakaclass MinikinFont {
88bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienpublic:
8947b905f6840ea6776d6f6778915e7408a1ff8be4Chih-Hung Hsieh    explicit MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {}
906c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka
919afcc6e2bd4d89e4e1deb6e18c3c4daca4e114fdRaph Levien    virtual ~MinikinFont();
929afcc6e2bd4d89e4e1deb6e18c3c4daca4e114fdRaph Levien
93bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien    virtual float GetHorizontalAdvance(uint32_t glyph_id,
94bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien        const MinikinPaint &paint) const = 0;
95bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
96ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    virtual void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
97ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien        const MinikinPaint &paint) const = 0;
98ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
99aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    // Override if font can provide access to raw data
100aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    virtual const void* GetFontData() const {
101aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien        return nullptr;
102aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    }
103aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien
104aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    // Override if font can provide access to raw data
105aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    virtual size_t GetFontSize() const {
106aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien        return 0;
107aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    }
108aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien
109aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    // Override if font can provide access to raw data.
110aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    // Returns index within OpenType collection
111aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    virtual int GetFontIndex() const {
112aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien        return 0;
113aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien    }
114bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
11539654bb6441b55f99341b613fc1194121b1e740bSeigo Nonaka    virtual const std::vector<minikin::FontVariation>& GetAxes() const = 0;
11639654bb6441b55f99341b613fc1194121b1e740bSeigo Nonaka
117dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka    virtual std::shared_ptr<MinikinFont> createFontWithVariation(
118dfbc6e374259f9d81940b5195ac013b02429af27Seigo Nonaka            const std::vector<FontVariation>&) const {
119065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka        return nullptr;
120065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka    }
121065c46a665d562c93ffa82fda10dee52a16ac23bSeigo Nonaka
122bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien    static uint32_t MakeTag(char c1, char c2, char c3, char c4) {
123bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien        return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) |
124bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien            ((uint32_t)c3 << 8) | (uint32_t)c4;
125bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien    }
1266c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka
1276c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka    int32_t GetUniqueId() const { return mUniqueId; }
1286c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonakaprivate:
1296c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka    const int32_t mUniqueId;
130bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien};
131bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
13214e2d136aaef271ba131f917cf5f27baa31ae5adSeigo Nonaka}  // namespace minikin
133bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien
134bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#endif  // MINIKIN_FONT_H
135