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 #include "text/GrTextContext.h"
     19 class GrColorSpaceInfo;
     20 class GrRenderTargetContext;
     21 #endif
     22 
     23 class SkGlyphRunPainterInterface;
     24 
     25 class SkStrikeCommon {
     26 public:
     27     static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment);
     28 
     29     // This assumes that position has the appropriate rounding term applied.
     30     static SkIPoint SubpixelLookup(SkAxisAlignment axisAlignment, SkPoint position);
     31 
     32     // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256.
     33     // This means that the maximum size a glyph can be is 256x256.
     34     static constexpr uint16_t kSkSideTooBigForAtlas = 256;
     35 
     36     static bool GlyphTooBigForAtlas(const SkGlyph& glyph);
     37 };
     38 
     39 class SkGlyphRunListPainter {
     40 public:
     41     // Constructor for SkBitmpapDevice.
     42     SkGlyphRunListPainter(const SkSurfaceProps& props,
     43                           SkColorType colorType,
     44                           SkColorSpace* cs,
     45                           SkStrikeCacheInterface* strikeCache);
     46 
     47 #if SK_SUPPORT_GPU
     48     // The following two ctors are used exclusively by the GPU, and will always use the global
     49     // strike cache.
     50     SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorSpaceInfo&);
     51     explicit SkGlyphRunListPainter(const GrRenderTargetContext& renderTargetContext);
     52 #endif  // SK_SUPPORT_GPU
     53 
     54     class BitmapDevicePainter {
     55     public:
     56         virtual ~BitmapDevicePainter() = default;
     57 
     58         virtual void paintPaths(SkSpan<const SkPathPos> pathsAndPositions,
     59                                 SkScalar scale,
     60                                 const SkPaint& paint) const = 0;
     61 
     62         virtual void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const = 0;
     63     };
     64 
     65     void drawForBitmapDevice(
     66             const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix,
     67             const BitmapDevicePainter* bitmapDevice);
     68 
     69 #if SK_SUPPORT_GPU
     70     // A nullptr for process means that the calls to the cache will be performed, but none of the
     71     // callbacks will be called.
     72     void processGlyphRunList(const SkGlyphRunList& glyphRunList,
     73                              const SkMatrix& viewMatrix,
     74                              const SkSurfaceProps& props,
     75                              bool contextSupportsDistanceFieldText,
     76                              const GrTextContext::Options& options,
     77                              SkGlyphRunPainterInterface* process);
     78 #endif  // SK_SUPPORT_GPU
     79 
     80     // TODO: Make this the canonical check for Skia.
     81     static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix);
     82 
     83 private:
     84     SkGlyphRunListPainter(const SkSurfaceProps& props, SkColorType colorType,
     85                           SkScalerContextFlags flags, SkStrikeCacheInterface* strikeCache);
     86 
     87     struct ScopedBuffers {
     88         ScopedBuffers(SkGlyphRunListPainter* painter, int size);
     89         ~ScopedBuffers();
     90         SkGlyphRunListPainter* fPainter;
     91     };
     92 
     93     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList);
     94 
     95     // TODO: Remove once I can hoist ensureBuffers above the list for loop in all cases.
     96     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun);
     97 
     98     /**
     99      *  @param fARGBPositions in source space
    100      *  @param fARGBGlyphsIDs the glyphs to process
    101      *  @param fGlyphPos used as scratch space
    102      *  @param maxSourceGlyphDimension the longest dimension of any glyph as if all fARGBGlyphsIDs
    103      *                                 were drawn in source space (as if viewMatrix were identity)
    104      */
    105     void processARGBFallback(SkScalar maxSourceGlyphDimension,
    106                              const SkPaint& runPaint,
    107                              const SkFont& runFont,
    108                              const SkMatrix& viewMatrix,
    109                              SkGlyphRunPainterInterface* process);
    110 
    111     // The props as on the actual device.
    112     const SkSurfaceProps fDeviceProps;
    113     // The props for when the bitmap device can't draw LCD text.
    114     const SkSurfaceProps fBitmapFallbackProps;
    115     const SkColorType fColorType;
    116     const SkScalerContextFlags fScalerContextFlags;
    117 
    118     SkStrikeCacheInterface* const fStrikeCache;
    119 
    120     int fMaxRunSize{0};
    121     SkAutoTMalloc<SkPoint> fPositions;
    122     SkAutoTMalloc<SkGlyphPos> fGlyphPos;
    123 
    124     std::vector<SkGlyphPos> fPaths;
    125 
    126     // Vectors for tracking ARGB fallback information.
    127     std::vector<SkGlyphID> fARGBGlyphsIDs;
    128     std::vector<SkPoint>   fARGBPositions;
    129 };
    130 
    131 // SkGlyphRunPainterInterface are all the ways that Ganesh generates glyphs. The first
    132 // distinction is between Device and Source.
    133 // * Device - the data in the cache is scaled to the device. There is no transformation from the
    134 //   cache to the screen.
    135 // * Source - the data in the cache needs to be scaled from the cache to source space using the
    136 //   factor cacheToSourceScale. When drawn the system must combine cacheToSourceScale and the
    137 //   deviceView matrix to transform the cache data onto the screen. This allows zooming and
    138 //   simple animation to reuse the same glyph data by just changing the transform.
    139 //
    140 // In addition to transformation type above, Masks, Paths, SDFT, and Fallback (or really the
    141 // rendering method of last resort) are the different
    142 // formats of data used from the cache.
    143 class SkGlyphRunPainterInterface {
    144 public:
    145     virtual ~SkGlyphRunPainterInterface() = default;
    146 
    147     virtual void startRun(const SkGlyphRun& glyphRun, bool useSDFT) = 0;
    148 
    149     virtual void processDeviceMasks(SkSpan<const SkGlyphPos> masks,
    150                                     SkStrikeInterface* strike) = 0;
    151 
    152     virtual void processSourcePaths(SkSpan<const SkGlyphPos> paths,
    153                                     SkStrikeInterface* strike, SkScalar cacheToSourceScale) = 0;
    154 
    155     virtual void processDevicePaths(SkSpan<const SkGlyphPos> paths) = 0;
    156 
    157     virtual void processSourceSDFT(SkSpan<const SkGlyphPos> masks,
    158                                    SkStrikeInterface* strike,
    159                                    const SkFont& runFont,
    160                                    SkScalar cacheToSourceScale,
    161                                    SkScalar minScale,
    162                                    SkScalar maxScale,
    163                                    bool hasWCoord) = 0;
    164 
    165     virtual void processSourceFallback(SkSpan<const SkGlyphPos> masks,
    166                                        SkStrikeInterface* strike,
    167                                        SkScalar cacheToSourceScale,
    168                                        bool hasW) = 0;
    169 
    170     virtual void processDeviceFallback(SkSpan<const SkGlyphPos> masks,
    171                                        SkStrikeInterface* strike) = 0;
    172 
    173 };
    174 
    175 #endif  // SkGlyphRunPainter_DEFINED
    176