Home | History | Annotate | Download | only in minikin
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef MINIKIN_FONT_H
     18 #define MINIKIN_FONT_H
     19 
     20 #include <string>
     21 
     22 #include "minikin/FontFamily.h"
     23 #include "minikin/Hyphenator.h"
     24 
     25 // An abstraction for platform fonts, allowing Minikin to be used with
     26 // multiple actual implementations of fonts.
     27 
     28 namespace minikin {
     29 
     30 class FontCollection;
     31 class MinikinFont;
     32 
     33 // Possibly move into own .h file?
     34 // Note: if you add a field here, either add it to LayoutCacheKey or to skipCache()
     35 struct MinikinPaint {
     36     MinikinPaint(const std::shared_ptr<FontCollection>& font)
     37             : size(0),
     38               scaleX(0),
     39               skewX(0),
     40               letterSpacing(0),
     41               wordSpacing(0),
     42               paintFlags(0),
     43               localeListId(0),
     44               familyVariant(FontFamily::Variant::DEFAULT),
     45               fontFeatureSettings(),
     46               font(font) {}
     47 
     48     bool skipCache() const { return !fontFeatureSettings.empty(); }
     49 
     50     float size;
     51     float scaleX;
     52     float skewX;
     53     float letterSpacing;
     54     float wordSpacing;
     55     uint32_t paintFlags;
     56     uint32_t localeListId;
     57     FontStyle fontStyle;
     58     FontFamily::Variant familyVariant;
     59     std::string fontFeatureSettings;
     60     std::shared_ptr<FontCollection> font;
     61 
     62     void copyFrom(const MinikinPaint& paint) { *this = paint; }
     63 
     64     MinikinPaint(MinikinPaint&&) = default;
     65     MinikinPaint& operator=(MinikinPaint&&) = default;
     66 
     67     inline bool operator==(const MinikinPaint& paint) {
     68         return size == paint.size && scaleX == paint.scaleX && skewX == paint.skewX &&
     69                letterSpacing == paint.letterSpacing && wordSpacing == paint.wordSpacing &&
     70                paintFlags == paint.paintFlags && localeListId == paint.localeListId &&
     71                fontStyle == paint.fontStyle && familyVariant == paint.familyVariant &&
     72                fontFeatureSettings == paint.fontFeatureSettings && font.get() == paint.font.get();
     73     }
     74 
     75 private:
     76     // Forbid implicit copy and assign. Use copyFrom instead.
     77     MinikinPaint(const MinikinPaint&) = default;
     78     MinikinPaint& operator=(const MinikinPaint&) = default;
     79 };
     80 
     81 // Only a few flags affect layout, but those that do should have values
     82 // consistent with Android's paint flags.
     83 enum MinikinPaintFlags {
     84     LinearTextFlag = 0x40,
     85 };
     86 
     87 struct MinikinRect {
     88     float mLeft = 0.0;
     89     float mTop = 0.0;
     90     float mRight = 0.0;
     91     float mBottom = 0.0;
     92     bool isEmpty() const { return mLeft == mRight || mTop == mBottom; }
     93     void set(const MinikinRect& r) {
     94         mLeft = r.mLeft;
     95         mTop = r.mTop;
     96         mRight = r.mRight;
     97         mBottom = r.mBottom;
     98     }
     99     void offset(float dx, float dy) {
    100         mLeft += dx;
    101         mTop += dy;
    102         mRight += dx;
    103         mBottom += dy;
    104     }
    105     void setEmpty() { mLeft = mTop = mRight = mBottom = 0.0; }
    106     void join(const MinikinRect& r);
    107 };
    108 
    109 // For holding vertical extents.
    110 struct MinikinExtent {
    111     float ascent = 0.0;    // negative
    112     float descent = 0.0;   // positive
    113     float line_gap = 0.0;  // positive
    114 
    115     void reset() { ascent = descent = line_gap = 0.0; }
    116 
    117     void extendBy(const MinikinExtent& e) {
    118         ascent = std::min(ascent, e.ascent);
    119         descent = std::max(descent, e.descent);
    120         line_gap = std::max(line_gap, e.line_gap);
    121     }
    122 };
    123 
    124 class MinikinFont {
    125 public:
    126     explicit MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {}
    127 
    128     virtual ~MinikinFont() {}
    129 
    130     virtual float GetHorizontalAdvance(uint32_t glyph_id, const MinikinPaint& paint,
    131                                        const FontFakery& fakery) const = 0;
    132 
    133     virtual void GetBounds(MinikinRect* bounds, uint32_t glyph_id, const MinikinPaint& paint,
    134                            const FontFakery& fakery) const = 0;
    135 
    136     virtual void GetFontExtent(MinikinExtent* extent, const MinikinPaint& paint,
    137                                const FontFakery& fakery) const = 0;
    138 
    139     // Override if font can provide access to raw data
    140     virtual const void* GetFontData() const { return nullptr; }
    141 
    142     // Override if font can provide access to raw data
    143     virtual size_t GetFontSize() const { return 0; }
    144 
    145     // Override if font can provide access to raw data.
    146     // Returns index within OpenType collection
    147     virtual int GetFontIndex() const { return 0; }
    148 
    149     virtual const std::vector<minikin::FontVariation>& GetAxes() const = 0;
    150 
    151     virtual std::shared_ptr<MinikinFont> createFontWithVariation(
    152             const std::vector<FontVariation>&) const {
    153         return nullptr;
    154     }
    155 
    156     static uint32_t MakeTag(char c1, char c2, char c3, char c4) {
    157         return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | (uint32_t)c4;
    158     }
    159 
    160     int32_t GetUniqueId() const { return mUniqueId; }
    161 
    162 private:
    163     const int32_t mUniqueId;
    164 };
    165 
    166 }  // namespace minikin
    167 
    168 #endif  // MINIKIN_FONT_H
    169