Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2014 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 SkFont_DEFINED
      9 #define SkFont_DEFINED
     10 
     11 #include "SkFontTypes.h"
     12 #include "SkScalar.h"
     13 #include "SkTypeface.h"
     14 
     15 class SkMatrix;
     16 class SkPaint;
     17 class SkPath;
     18 struct SkFontMetrics;
     19 
     20 /** \class SkFont
     21     SkFont controls options applied when drawing and measuring text.
     22 */
     23 class SK_API SkFont {
     24 public:
     25     /** Whether edge pixels draw opaque or with partial transparency.
     26     */
     27     enum class Edging {
     28         kAlias,              //!< no transparent pixels on glyph edges
     29         kAntiAlias,          //!< may have transparent pixels on glyph edges
     30         kSubpixelAntiAlias,  //!< glyph positioned in pixel using transparency
     31     };
     32 
     33     /** Constructs SkFont with default values.
     34 
     35         @return  default initialized SkFont
     36     */
     37     SkFont();
     38 
     39     /** Constructs SkFont with default values with SkTypeface and size in points.
     40 
     41         @param typeface  font and style used to draw and measure text
     42         @param size      typographic height of text
     43         @return          initialized SkFont
     44     */
     45     SkFont(sk_sp<SkTypeface> typeface, SkScalar size);
     46 
     47     /** Constructs SkFont with default values with SkTypeface.
     48 
     49         @param typeface  font and style used to draw and measure text
     50         @return          initialized SkFont
     51     */
     52     explicit SkFont(sk_sp<SkTypeface> typeface);
     53 
     54 
     55     /** Constructs SkFont with default values with SkTypeface and size in points,
     56         horizontal scale, and horizontal skew. Horizontal scale emulates condensed
     57         and expanded fonts. Horizontal skew emulates oblique fonts.
     58 
     59         @param typeface  font and style used to draw and measure text
     60         @param size      typographic height of text
     61         @param scaleX    text horizontal scale
     62         @param skewX     additional shear on x-axis relative to y-axis
     63         @return          initialized SkFont
     64     */
     65     SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX);
     66 
     67 
     68     /** Compares SkFont and font, and returns true if they are equivalent.
     69         May return false if SkTypeface has identical contents but different pointers.
     70 
     71         @param font  font to compare
     72         @return      true if SkFont pair are equivalent
     73     */
     74     bool operator==(const SkFont& font) const;
     75 
     76     /** Compares SkFont and font, and returns true if they are not equivalent.
     77         May return true if SkTypeface has identical contents but different pointers.
     78 
     79         @param font  font to compare
     80         @return      true if SkFont pair are not equivalent
     81     */
     82     bool operator!=(const SkFont& font) const { return !(*this == font); }
     83 
     84     /** If true, instructs the font manager to always hint glyphs.
     85         Returned value is only meaningful if platform uses FreeType as the font manager.
     86 
     87         @return  true if all glyphs are hinted
     88     */
     89     bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); }
     90 
     91     /** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.
     92 
     93         @return  true if glyphs may be font bitmaps
     94     */
     95     bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); }
     96 
     97     /** Returns true if glyphs at different sub-pixel positions may differ on pixel edge coverage.
     98 
     99         @return  true if glyph positioned in pixel using transparency
    100     */
    101     bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
    102 
    103     /** Returns true if text is converted to SkPath before drawing and measuring.
    104 
    105         @return  true glyph hints are never applied
    106     */
    107     bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); }
    108 
    109     /** Returns true if bold is approximated by increasing the stroke width when creating glyph
    110         bitmaps from outlines.
    111 
    112         @return  bold is approximated through stroke width
    113     */
    114     bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
    115 
    116     /** Sets whether to always hint glyphs.
    117         If forceAutoHinting is set, instructs the font manager to always hint glyphs.
    118 
    119         Only affects platforms that use FreeType as the font manager.
    120 
    121         @param forceAutoHinting  setting to always hint glyphs
    122     */
    123     void setForceAutoHinting(bool forceAutoHinting);
    124 
    125     /** Requests, but does not require, to use bitmaps in fonts instead of outlines.
    126 
    127         @param embeddedBitmaps  setting to use bitmaps in fonts
    128     */
    129     void setEmbeddedBitmaps(bool embeddedBitmaps);
    130 
    131     /** Requests, but does not require, that glyphs respect sub-pixel positioning.
    132 
    133         @param subpixel  setting for sub-pixel positioning
    134     */
    135     void setSubpixel(bool subpixel);
    136 
    137     /** Requests, but does not require, that glyphs are converted to SkPath
    138         before drawing and measuring.
    139 
    140         @param linearMetrics  setting for converting glyphs to paths
    141     */
    142     void setLinearMetrics(bool linearMetrics);
    143 
    144     /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
    145 
    146         @param embolden  setting for bold approximation
    147     */
    148     void setEmbolden(bool embolden);
    149 
    150     /** Whether edge pixels draw opaque or with partial transparency.
    151 
    152         @return  one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
    153     */
    154     Edging getEdging() const { return (Edging)fEdging; }
    155 
    156     /** Requests, but does not require, that edge pixels draw opaque or with
    157         partial transparency.
    158 
    159         @param edging  one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
    160     */
    161     void setEdging(Edging edging);
    162 
    163     /** Sets level of glyph outline adjustment.
    164         Does not check for valid values of hintingLevel.
    165 
    166         @param hintingLevel  one of: SkFontHinting::kNone, SkFontHinting::kSlight,
    167                                      SkFontHinting::kNormal, SkFontHinting::kFull
    168     */
    169     void setHinting(SkFontHinting hintingLevel);
    170 
    171     /** Returns level of glyph outline adjustment.
    172 
    173         @return  one of: SkFontHinting::kNone, SkFontHinting::kSlight, SkFontHinting::kNormal,
    174                          SkFontHinting::kFull
    175      */
    176     SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
    177 
    178     /** Returns a font with the same attributes of this font, but with the specified size.
    179         Returns nullptr if size is less than zero, infinite, or NaN.
    180 
    181         @param size  typographic height of text
    182         @return      initialized SkFont
    183      */
    184     SkFont makeWithSize(SkScalar size) const;
    185 
    186     /** Returns SkTypeface if set, or nullptr.
    187         Does not alter SkTypeface SkRefCnt.
    188 
    189         @return  SkTypeface if previously set, nullptr otherwise
    190     */
    191     SkTypeface* getTypeface() const {return fTypeface.get(); }
    192 
    193     /** Returns SkTypeface if set, or the default typeface.
    194         Does not alter SkTypeface SkRefCnt.
    195 
    196         @return  SkTypeface if previously set or, a pointer to the default typeface if not
    197         previously set.
    198     */
    199     SkTypeface* getTypefaceOrDefault() const;
    200 
    201     /** Returns text size in points.
    202 
    203         @return  typographic height of text
    204     */
    205     SkScalar    getSize() const { return fSize; }
    206 
    207     /** Returns text scale on x-axis.
    208         Default value is 1.
    209 
    210         @return  text horizontal scale
    211     */
    212     SkScalar    getScaleX() const { return fScaleX; }
    213 
    214     /** Returns text skew on x-axis.
    215         Default value is zero.
    216 
    217         @return  additional shear on x-axis relative to y-axis
    218     */
    219     SkScalar    getSkewX() const { return fSkewX; }
    220 
    221     /** Increases SkTypeface SkRefCnt by one.
    222 
    223         @return  SkTypeface if previously set, nullptr otherwise
    224     */
    225     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
    226 
    227     /** Increases SkTypeface SkRefCnt by one.
    228 
    229         @return  SkTypeface if previously set or, a pointer to the default typeface if not
    230         previously set.
    231     */
    232     sk_sp<SkTypeface> refTypefaceOrDefault() const;
    233 
    234     /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
    235         Pass nullptr to clear SkTypeface and use the default typeface. Increments
    236         tf SkRefCnt by one.
    237 
    238         @param tf  font and style used to draw text
    239     */
    240     void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = tf; }
    241 
    242     /** Sets text size in points.
    243         Has no effect if textSize is not greater than or equal to zero.
    244 
    245         @param textSize  typographic height of text
    246     */
    247     void setSize(SkScalar textSize);
    248 
    249     /** Sets text scale on x-axis.
    250         Default value is 1.
    251 
    252         @param scaleX  text horizontal scale
    253     */
    254     void setScaleX(SkScalar scaleX);
    255 
    256     /** Sets text skew on x-axis.
    257         Default value is zero.
    258 
    259         @param skewX  additional shear on x-axis relative to y-axis
    260     */
    261     void setSkewX(SkScalar skewX);
    262 
    263     /** Converts text into glyph indices.
    264         Returns the number of glyph indices represented by text.
    265         SkTextEncoding specifies how text represents characters or glyphs.
    266         glyphs may be nullptr, to compute the glyph count.
    267 
    268         Does not check text for valid character codes or valid glyph indices.
    269 
    270         If byteLength equals zero, returns zero.
    271         If byteLength includes a partial character, the partial character is ignored.
    272 
    273         If encoding is kUTF8_SkTextEncoding and text contains an invalid UTF-8 sequence,
    274         zero is returned.
    275 
    276         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
    277         SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
    278         single glyph.  This function uses the default character-to-glyph
    279         mapping from the SkTypeface and maps characters not found in the
    280         SkTypeface to zero.
    281 
    282         If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied.
    283         The total glyph count is returned for subsequent buffer reallocation.
    284 
    285         @param text          character storage encoded with SkTextEncoding
    286         @param byteLength    length of character storage in bytes
    287         @param encoding      one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
    288                              kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
    289         @param glyphs        storage for glyph indices; may be nullptr
    290         @param maxGlyphCount storage capacity
    291         @return              number of glyphs represented by text of length byteLength
    292     */
    293     int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
    294                      SkGlyphID glyphs[], int maxGlyphCount) const;
    295 
    296     /** Returns glyph index for Unicode character.
    297 
    298         If the character is not supported by the SkTypeface, returns 0.
    299 
    300         @param uni  Unicode character
    301         @return     glyph index
    302     */
    303     SkGlyphID unicharToGlyph(SkUnichar uni) const;
    304 
    305     /** Returns number of glyphs represented by text.
    306 
    307         If encoding is kUTF8_SkTextEncoding, kUTF16_SkTextEncoding, or
    308         kUTF32_SkTextEncoding; then each Unicode codepoint is mapped to a
    309         single glyph.
    310 
    311         @param text          character storage encoded with SkTextEncoding
    312         @param byteLength    length of character storage in bytes
    313         @param encoding      one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
    314                              kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
    315         @return              number of glyphs represented by text of length byteLength
    316     */
    317     int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
    318         return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
    319     }
    320 
    321     /** Returns the advance width of text.
    322         The advance is the normal distance to move before drawing additional text.
    323         Returns the bounding box of text if bounds is not nullptr.
    324 
    325         @param text        character storage encoded with SkTextEncoding
    326         @param byteLength  length of character storage in bytes
    327         @param encoding    one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
    328                            kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
    329         @param bounds      returns bounding box relative to (0, 0) if not nullptr
    330         @return            number of glyphs represented by text of length byteLength
    331     */
    332     SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
    333                          SkRect* bounds = nullptr) const {
    334         return this->measureText(text, byteLength, encoding, bounds, nullptr);
    335     }
    336 
    337     /** Returns the advance width of text.
    338         The advance is the normal distance to move before drawing additional text.
    339         Returns the bounding box of text if bounds is not nullptr. paint
    340         stroke width or SkPathEffect may modify the advance with.
    341 
    342         @param text        character storage encoded with SkTextEncoding
    343         @param byteLength  length of character storage in bytes
    344         @param encoding    one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
    345                            kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
    346         @param bounds      returns bounding box relative to (0, 0) if not nullptr
    347         @param paint       optional; may be nullptr
    348         @return            number of glyphs represented by text of length byteLength
    349     */
    350     SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
    351                          SkRect* bounds, const SkPaint* paint) const;
    352 
    353     /** DEPRECATED
    354         Retrieves the advance and bounds for each glyph in glyphs.
    355         Both widths and bounds may be nullptr.
    356         If widths is not nullptr, widths must be an array of count entries.
    357         if bounds is not nullptr, bounds must be an array of count entries.
    358 
    359         @param glyphs      array of glyph indices to be measured
    360         @param count       number of glyphs
    361         @param widths      returns text advances for each glyph; may be nullptr
    362         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
    363     */
    364     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
    365         this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
    366     }
    367 
    368     // DEPRECATED
    369     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], std::nullptr_t) const {
    370         this->getWidths(glyphs, count, widths);
    371     }
    372 
    373     /** Retrieves the advance and bounds for each glyph in glyphs.
    374         Both widths and bounds may be nullptr.
    375         If widths is not nullptr, widths must be an array of count entries.
    376         if bounds is not nullptr, bounds must be an array of count entries.
    377 
    378         @param glyphs      array of glyph indices to be measured
    379         @param count       number of glyphs
    380         @param widths      returns text advances for each glyph
    381      */
    382     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[]) const {
    383         this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
    384     }
    385 
    386     /** Retrieves the advance and bounds for each glyph in glyphs.
    387         Both widths and bounds may be nullptr.
    388         If widths is not nullptr, widths must be an array of count entries.
    389         if bounds is not nullptr, bounds must be an array of count entries.
    390 
    391         @param glyphs      array of glyph indices to be measured
    392         @param count       number of glyphs
    393         @param widths      returns text advances for each glyph; may be nullptr
    394         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
    395         @param paint       optional, specifies stroking, SkPathEffect and SkMaskFilter
    396      */
    397     void getWidthsBounds(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[],
    398                          const SkPaint* paint) const;
    399 
    400 
    401     /** Retrieves the bounds for each glyph in glyphs.
    402         bounds must be an array of count entries.
    403         If paint is not nullptr, its stroking, SkPathEffect, and SkMaskFilter fields are respected.
    404 
    405         @param glyphs      array of glyph indices to be measured
    406         @param count       number of glyphs
    407         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
    408         @param paint       optional, specifies stroking, SkPathEffect, and SkMaskFilter
    409      */
    410     void getBounds(const uint16_t glyphs[], int count, SkRect bounds[],
    411                    const SkPaint* paint) const {
    412         this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
    413     }
    414 
    415     /** Retrieves the positions for each glyph, beginning at the specified origin. The caller
    416         must allocated at least count number of elements in the pos[] array.
    417 
    418         @param glyphs   array of glyph indices to be positioned
    419         @param count    number of glyphs
    420         @param pos      returns glyphs positions
    421         @param origin   location of the first glyph. Defaults to {0, 0}.
    422      */
    423     void getPos(const uint16_t glyphs[], int count, SkPoint pos[], SkPoint origin = {0, 0}) const;
    424 
    425     /** Retrieves the x-positions for each glyph, beginning at the specified origin. The caller
    426         must allocated at least count number of elements in the xpos[] array.
    427 
    428         @param glyphs   array of glyph indices to be positioned
    429         @param count    number of glyphs
    430         @param xpos     returns glyphs x-positions
    431         @param origin   x-position of the first glyph. Defaults to 0.
    432      */
    433     void getXPos(const uint16_t glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const;
    434 
    435     /** Returns path corresponding to glyph outline.
    436         If glyph has an outline, copies outline to path and returns true.
    437         path returned may be empty.
    438         If glyph is described by a bitmap, returns false and ignores path parameter.
    439 
    440         @param glyphID  index of glyph
    441         @param path     pointer to existing SkPath
    442         @return         true if glyphID is described by path
    443      */
    444     bool getPath(uint16_t glyphID, SkPath* path) const;
    445 
    446     /** Returns path corresponding to glyph array.
    447 
    448         @param glyphIDs      array of glyph indices
    449         @param count         number of glyphs
    450         @param glyphPathProc function returning one glyph description as path
    451         @param ctx           function context
    452    */
    453     void getPaths(const uint16_t glyphIDs[], int count,
    454                   void (*glyphPathProc)(const SkPath* pathOrNull, const SkMatrix& mx, void* ctx),
    455                   void* ctx) const;
    456 
    457     /** Returns SkFontMetrics associated with SkTypeface.
    458         The return value is the recommended spacing between lines: the sum of metrics
    459         descent, ascent, and leading.
    460         If metrics is not nullptr, SkFontMetrics is copied to metrics.
    461         Results are scaled by text size but does not take into account
    462         dimensions required by text scale, text skew, fake bold,
    463         style stroke, and SkPathEffect.
    464 
    465         @param metrics  storage for SkFontMetrics; may be nullptr
    466         @return         recommended spacing between lines
    467     */
    468     SkScalar getMetrics(SkFontMetrics* metrics) const;
    469 
    470     /** Returns the recommended spacing between lines: the sum of metrics
    471         descent, ascent, and leading.
    472         Result is scaled by text size but does not take into account
    473         dimensions required by stroking and SkPathEffect.
    474         Returns the same result as getMetrics().
    475 
    476         @return  recommended spacing between lines
    477     */
    478     SkScalar getSpacing() const { return this->getMetrics(nullptr); }
    479 
    480     /** Experimental.
    481      *  Dumps fields of the font to SkDebugf. May change its output over time, so clients should
    482      *  not rely on this for anything specific. Used to aid in debugging.
    483      */
    484     void dump() const;
    485 
    486 private:
    487     enum PrivFlags {
    488         kForceAutoHinting_PrivFlag      = 1 << 0,
    489         kEmbeddedBitmaps_PrivFlag       = 1 << 1,
    490         kSubpixel_PrivFlag              = 1 << 2,
    491         kLinearMetrics_PrivFlag         = 1 << 3,
    492         kEmbolden_PrivFlag              = 1 << 4,
    493     };
    494 
    495     static constexpr unsigned kAllFlags = 0x1F;
    496 
    497     sk_sp<SkTypeface> fTypeface;
    498     SkScalar    fSize;
    499     SkScalar    fScaleX;
    500     SkScalar    fSkewX;
    501     uint8_t     fFlags;
    502     uint8_t     fEdging;
    503     uint8_t     fHinting;
    504 
    505     SkScalar setupForAsPaths(SkPaint*);
    506     bool hasSomeAntiAliasing() const;
    507 
    508     void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
    509 
    510     friend class GrTextBlob;
    511     friend class SkCanonicalizeFont;
    512     friend class SkFontPriv;
    513     friend class SkGlyphRunListPainter;
    514     friend class SkPaint;
    515     friend class SkTextBlobCacheDiffCanvas;
    516     friend class SVGTextBuilder;
    517 };
    518 
    519 #endif
    520