Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      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 SkGlyphRunPainter_DEFINED
      9 #define SkGlyphRunPainter_DEFINED
     10 
     11 #include "SkDistanceFieldGen.h"
     12 #include "SkGlyphRun.h"
     13 #include "SkScalerContext.h"
     14 #include "SkSurfaceProps.h"
     15 #include "SkTextBlobPriv.h"
     16 
     17 #if SK_SUPPORT_GPU
     18 class GrColorSpaceInfo;
     19 class GrRenderTargetContext;
     20 #endif
     21 
     22 class SkStrikeInterface {
     23 public:
     24     virtual ~SkStrikeInterface() = default;
     25     virtual SkVector rounding() const = 0;
     26     virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
     27     virtual bool hasImage(const SkGlyph& glyph) = 0;
     28     virtual bool hasPath(const SkGlyph& glyph) = 0;
     29 };
     30 
     31 class SkStrikeCommon {
     32 public:
     33     static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment);
     34 
     35     // This assumes that position has the appropriate rounding term applied.
     36     static SkIPoint SubpixelLookup(SkAxisAlignment axisAlignment, SkPoint position);
     37 
     38     // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256.
     39     // This means that the maximum size a glyph can be is 256x256.
     40     static constexpr uint16_t kSkSideTooBigForAtlas = 256;
     41 
     42     static bool GlyphTooBigForAtlas(const SkGlyph& glyph);
     43 };
     44 
     45 class SkGlyphRunListPainter {
     46 public:
     47     // Constructor for SkBitmpapDevice.
     48     SkGlyphRunListPainter(
     49             const SkSurfaceProps& props, SkColorType colorType, SkScalerContextFlags flags);
     50 
     51 #if SK_SUPPORT_GPU
     52     SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorSpaceInfo&);
     53     explicit SkGlyphRunListPainter(const GrRenderTargetContext& renderTargetContext);
     54 #endif
     55 
     56     struct PathAndPos {
     57         const SkPath* path;
     58         SkPoint position;
     59     };
     60 
     61     struct GlyphAndPos {
     62         const SkGlyph* glyph;
     63         SkPoint position;
     64     };
     65 
     66     class BitmapDevicePainter {
     67     public:
     68         virtual ~BitmapDevicePainter() = default;
     69 
     70         virtual void paintPaths(SkSpan<const PathAndPos> pathsAndPositions,
     71                                 SkScalar scale,
     72                                 const SkPaint& paint) const = 0;
     73 
     74         virtual void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const = 0;
     75     };
     76 
     77     void drawForBitmapDevice(
     78             const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix,
     79             const BitmapDevicePainter* bitmapDevice);
     80 
     81     template <typename EmptiesT, typename MasksT, typename PathsT>
     82     void drawGlyphRunAsBMPWithPathFallback(
     83             SkStrikeInterface* cache, const SkGlyphRun& glyphRun,
     84             SkPoint origin, const SkMatrix& deviceMatrix,
     85             EmptiesT&& processEmpties, MasksT&& processMasks, PathsT&& processPaths);
     86 
     87     enum NeedsTransform : bool { kTransformDone = false, kDoTransform = true };
     88 
     89     using ARGBFallback =
     90     std::function<void(const SkPaint& fallbackPaint, // The run paint maybe with a new text size
     91                        const SkFont& fallbackFont,
     92                        SkSpan<const SkGlyphID> fallbackGlyphIDs, // Colored glyphs
     93                        SkSpan<const SkPoint> fallbackPositions,  // Positions of above glyphs
     94                        SkScalar fallbackTextScale,               // Scale factor for glyph
     95                        const SkMatrix& glyphCacheMatrix,         // Matrix of glyph cache
     96                        NeedsTransform handleTransformLater)>;    // Positions / glyph transformed
     97 
     98     // Draw glyphs as paths with fallback to scaled ARGB glyphs if color is needed.
     99     // PerPath - perPath(const SkGlyph&, SkPoint position)
    100     // FallbackARGB - fallbackARGB(SkSpan<const SkGlyphID>, SkSpan<const SkPoint>)
    101     // For each glyph that is not ARGB call perPath. If the glyph is ARGB then store the glyphID
    102     // and the position in fallback vectors. After all the glyphs are processed, pass the
    103     // fallback glyphIDs and positions to fallbackARGB.
    104     template <typename PerEmptyT, typename PerPath>
    105     void drawGlyphRunAsPathWithARGBFallback(
    106             SkStrikeInterface* cache, const SkGlyphRun& glyphRun,
    107             SkPoint origin, const SkPaint& paint, const SkMatrix& viewMatrix, SkScalar textScale,
    108             PerEmptyT&& perEmpty, PerPath&& perPath, ARGBFallback&& fallbackARGB);
    109 
    110     template <typename PerEmptyT, typename PerSDFT, typename PerPathT>
    111     void drawGlyphRunAsSDFWithARGBFallback(
    112             SkStrikeInterface* cache, const SkGlyphRun& glyphRun,
    113             SkPoint origin, const SkPaint& runPaint, const SkMatrix& viewMatrix, SkScalar textRatio,
    114             PerEmptyT&& perEmpty, PerSDFT&& perSDF, PerPathT&& perPath, ARGBFallback&& perFallback);
    115 
    116     // TODO: Make this the canonical check for Skia.
    117     static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix);
    118 
    119 private:
    120     struct ScopedBuffers {
    121         ScopedBuffers(SkGlyphRunListPainter* painter, int size);
    122         ~ScopedBuffers();
    123         SkGlyphRunListPainter* fPainter;
    124     };
    125 
    126     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList);
    127 
    128     // TODO: Remove once I can hoist ensureBuffers above the list for loop in all cases.
    129     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun);
    130 
    131     void processARGBFallback(
    132             SkScalar maxGlyphDimension, const SkPaint& fallbackPaint, const SkFont& fallbackFont,
    133             const SkMatrix& viewMatrix, SkScalar textScale, ARGBFallback argbFallback);
    134 
    135     // The props as on the actual device.
    136     const SkSurfaceProps fDeviceProps;
    137     // The props for when the bitmap device can't draw LCD text.
    138     const SkSurfaceProps fBitmapFallbackProps;
    139     const SkColorType fColorType;
    140     const SkScalerContextFlags fScalerContextFlags;
    141 
    142     int fMaxRunSize{0};
    143     SkAutoTMalloc<SkPoint> fPositions;
    144     SkAutoTMalloc<GlyphAndPos> fMasks;
    145 
    146     std::vector<GlyphAndPos> fPaths;
    147 
    148     // Vectors for tracking ARGB fallback information.
    149     std::vector<SkGlyphID> fARGBGlyphsIDs;
    150     std::vector<SkPoint>   fARGBPositions;
    151 };
    152 
    153 #endif  // SkGlyphRunPainter_DEFINED
    154