Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright 2015 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 GrTextUtils_DEFINED
      9 #define GrTextUtils_DEFINED
     10 
     11 #include "GrColor.h"
     12 #include "GrColorSpaceInfo.h"
     13 #include "SkColorFilter.h"
     14 #include "SkPaint.h"
     15 #include "SkScalar.h"
     16 #include "SkTextToPathIter.h"
     17 #include "SkTLazy.h"
     18 
     19 class GrAtlasTextBlob;
     20 class GrAtlasTextOp;
     21 class GrTextStrike;
     22 class GrClip;
     23 class GrColorSpaceXform;
     24 class GrContext;
     25 class GrGlyphCache;
     26 class GrPaint;
     27 class GrShaderCaps;
     28 class SkColorSpace;
     29 class SkDrawFilter;
     30 class SkGlyph;
     31 class SkMatrix;
     32 struct SkIRect;
     33 struct SkPoint;
     34 class SkGlyphCache;
     35 class SkTextBlobRunIterator;
     36 class SkSurfaceProps;
     37 
     38 /**
     39  * A class to house a bunch of common text utilities.  This class should *ONLY* have static
     40  * functions.  It is not a namespace only because we wish to friend SkPaint
     41  */
     42 class GrTextUtils {
     43 public:
     44     class Target {
     45     public:
     46         virtual ~Target() = default;
     47 
     48         int width() const { return fWidth; }
     49         int height() const { return fHeight; }
     50         const GrColorSpaceInfo& colorSpaceInfo() const { return fColorSpaceInfo; }
     51 
     52         virtual void addDrawOp(const GrClip&, std::unique_ptr<GrAtlasTextOp> op) = 0;
     53 
     54         virtual void drawPath(const GrClip&, const SkPath&, const SkPaint&,
     55                               const SkMatrix& viewMatrix, const SkMatrix* pathMatrix,
     56                               const SkIRect& clipBounds) = 0;
     57         virtual void makeGrPaint(GrMaskFormat, const SkPaint&, const SkMatrix& viewMatrix,
     58                                  GrPaint*) = 0;
     59 
     60     protected:
     61         Target(int width, int height, const GrColorSpaceInfo& colorSpaceInfo)
     62                 : fWidth(width), fHeight(height), fColorSpaceInfo(colorSpaceInfo) {}
     63 
     64     private:
     65         int fWidth;
     66         int fHeight;
     67         const GrColorSpaceInfo& fColorSpaceInfo;
     68     };
     69 
     70     /**
     71      *  This is used to wrap a SkPaint and its post-color filter color. It is also used by RunPaint
     72      *  (below). This keeps a pointer to the SkPaint it is initialized with and expects it to remain
     73      *  const. It is also used to transform to GrPaint.
     74      */
     75     class Paint {
     76     public:
     77         explicit Paint(const SkPaint* paint, const GrColorSpaceInfo* dstColorSpaceInfo)
     78                 : fPaint(paint), fDstColorSpaceInfo(dstColorSpaceInfo) {
     79             this->initFilteredColor();
     80         }
     81 
     82         // These expose the paint's color run through its color filter (if any). This is only valid
     83         // when drawing grayscale/lcd glyph masks and not when drawing color glyphs.
     84         GrColor filteredPremulColor() const { return fFilteredPremulColor; }
     85         SkColor luminanceColor() const { return fPaint->computeLuminanceColor(); }
     86 
     87         const SkPaint& skPaint() const { return *fPaint; }
     88         operator const SkPaint&() const { return this->skPaint(); }
     89 
     90         // Just for RunPaint's constructor
     91         const GrColorSpaceInfo* dstColorSpaceInfo() const { return fDstColorSpaceInfo; }
     92 
     93     protected:
     94         void initFilteredColor();
     95         Paint() = default;
     96         const SkPaint* fPaint;
     97         const GrColorSpaceInfo* fDstColorSpaceInfo;
     98         // This is the paint's color run through its color filter, if present. This color should
     99         // be used except when rendering bitmap text, in which case the bitmap must be filtered in
    100         // the fragment shader.
    101         GrColor fFilteredPremulColor;
    102     };
    103 
    104     /**
    105      *  An extension of Paint that incorporated per-run modifications to the paint text settings and
    106      *  application of a draw filter. It expects its constructor arguments to remain alive and const
    107      *  during its lifetime.
    108      */
    109     class RunPaint : public Paint {
    110     public:
    111         RunPaint(const Paint* paint, SkDrawFilter* filter, const SkSurfaceProps& props)
    112                 : fOriginalPaint(paint), fFilter(filter), fProps(props) {
    113             // Initially we represent the original paint.
    114             fPaint = &fOriginalPaint->skPaint();
    115             fDstColorSpaceInfo = fOriginalPaint->dstColorSpaceInfo();
    116             fFilteredPremulColor = fOriginalPaint->filteredPremulColor();
    117         }
    118 
    119         bool modifyForRun(std::function<void(SkPaint*)> paintModFunc);
    120 
    121     private:
    122         SkTLazy<SkPaint> fModifiedPaint;
    123         const Paint* fOriginalPaint;
    124         SkDrawFilter* fFilter;
    125         const SkSurfaceProps& fProps;
    126     };
    127 
    128     static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
    129 
    130     static bool ShouldDisableLCD(const SkPaint& paint);
    131 
    132     class PathTextIter : SkTextBaseIter {
    133     public:
    134         PathTextIter(const char text[], size_t length, const SkPaint& paint,
    135                      bool applyStrokeAndPathEffects)
    136             : SkTextBaseIter(text, length, paint, applyStrokeAndPathEffects) {
    137         }
    138 
    139         const SkPaint&  getPaint() const { return fPaint; }
    140         SkScalar        getPathScale() const { return fScale; }
    141         const char*     getText() const { return fText; }
    142 
    143         /**
    144          *  Returns false when all of the text has been consumed
    145          *  Will set skGlyph if the maskformat is ARGB, and path otherwise. The other will be null.
    146          *  If the glyph is zero-width, both will be null.
    147          */
    148         bool next(const SkGlyph** skGlyph, const SkPath** path, SkScalar* xpos);
    149     };
    150 };
    151 
    152 #endif
    153