Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2018 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkFontPriv_DEFINED
      9 #define SkFontPriv_DEFINED
     10 
     11 #include "SkFont.h"
     12 #include "SkMatrix.h"
     13 #include "SkTypeface.h"
     14 
     15 class SkReadBuffer;
     16 class SkWriteBuffer;
     17 
     18 class SkFontPriv {
     19 public:
     20     /*  This is the size we use when we ask for a glyph's path. We then
     21      *  post-transform it as we draw to match the request.
     22      *  This is done to try to re-use cache entries for the path.
     23      *
     24      *  This value is somewhat arbitrary. In theory, it could be 1, since
     25      *  we store paths as floats. However, we get the path from the font
     26      *  scaler, and it may represent its paths as fixed-point (or 26.6),
     27      *  so we shouldn't ask for something too big (might overflow 16.16)
     28      *  or too small (underflow 26.6).
     29      *
     30      *  This value could track kMaxSizeForGlyphCache, assuming the above
     31      *  constraints, but since we ask for unhinted paths, the two values
     32      *  need not match per-se.
     33      */
     34     static constexpr int kCanonicalTextSizeForPaths  = 64;
     35 
     36     static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM, SkScalar maxLimit);
     37 
     38     static SkScalar MaxCacheSize2(SkScalar maxLimit);
     39 
     40     /**
     41      *  Return a matrix that applies the paint's text values: size, scale, skew
     42      */
     43     static SkMatrix MakeTextMatrix(SkScalar size, SkScalar scaleX, SkScalar skewX) {
     44         SkMatrix m = SkMatrix::MakeScale(size * scaleX, size);
     45         if (skewX) {
     46             m.postSkew(skewX, 0);
     47         }
     48         return m;
     49     }
     50 
     51     static SkMatrix MakeTextMatrix(const SkFont& font) {
     52         return MakeTextMatrix(font.getSize(), font.getScaleX(), font.getSkewX());
     53     }
     54 
     55     static void ScaleFontMetrics(SkFontMetrics*, SkScalar);
     56 
     57     // returns -1 if buffer is invalid for specified encoding
     58     static int ValidCountText(const void* text, size_t length, SkTextEncoding);
     59 
     60     /**
     61         Returns the union of bounds of all glyphs.
     62         Returned dimensions are computed by font manager from font data,
     63         ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
     64 
     65         If text size is large, text scale is one, and text skew is zero,
     66         returns the bounds as:
     67         { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
     68 
     69         @return  union of bounds of all glyphs
     70      */
     71     static SkRect GetFontBounds(const SkFont&);
     72 
     73     static bool IsFinite(const SkFont& font) {
     74         return SkScalarIsFinite(font.fSize) &&
     75                SkScalarIsFinite(font.fScaleX) &&
     76                SkScalarIsFinite(font.fSkewX);
     77     }
     78 
     79     // Returns the number of elements (characters or glyphs) in the array.
     80     static int CountTextElements(const void* text, size_t byteLength, SkTextEncoding);
     81 
     82     static void GlyphsToUnichars(const SkFont&, const uint16_t glyphs[], int count, SkUnichar[]);
     83 
     84     static void Flatten(const SkFont&, SkWriteBuffer& buffer);
     85     static bool Unflatten(SkFont*, SkReadBuffer& buffer);
     86 };
     87 
     88 class SkAutoToGlyphs {
     89 public:
     90     SkAutoToGlyphs(const SkFont& font, const void* text, size_t length, SkTextEncoding encoding) {
     91         if (encoding == kGlyphID_SkTextEncoding || length == 0) {
     92             fGlyphs = reinterpret_cast<const uint16_t*>(text);
     93             fCount = length >> 1;
     94         } else {
     95             fCount = font.countText(text, length, encoding);
     96             fStorage.reset(fCount);
     97             font.textToGlyphs(text, length, encoding, fStorage.get(), fCount);
     98             fGlyphs = fStorage.get();
     99         }
    100     }
    101 
    102     int count() const { return fCount; }
    103     const uint16_t* glyphs() const { return fGlyphs; }
    104 
    105 private:
    106     SkAutoSTArray<32, uint16_t> fStorage;
    107     const uint16_t* fGlyphs;
    108     int             fCount;
    109 };
    110 
    111 #endif
    112