Home | History | Annotate | Download | only in text
      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 GrStencilAndCoverTextContext_DEFINED
      9 #define GrStencilAndCoverTextContext_DEFINED
     10 
     11 #include "GrRenderTargetContext.h"
     12 #include "GrStyle.h"
     13 #include "SkDrawFilter.h"
     14 #include "SkOpts.h"
     15 #include "SkTHash.h"
     16 #include "SkTInternalLList.h"
     17 #include "SkTLList.h"
     18 #include "SkTextBlob.h"
     19 #include "ops/GrDrawPathOp.h"
     20 
     21 class GrAtlasTextContext;
     22 class GrTextStrike;
     23 class GrPath;
     24 class SkSurfaceProps;
     25 
     26 /*
     27  * This class implements text rendering using stencil and cover path rendering
     28  * (by the means of GrOpList::drawPath).
     29  */
     30 class GrStencilAndCoverTextContext {
     31 public:
     32     static GrStencilAndCoverTextContext* Create(GrAtlasTextContext* fallbackTextContext);
     33 
     34     void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, const SkPaint&,
     35                   const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
     36                   size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds);
     37     void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
     38                      const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
     39                      size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
     40                      const SkPoint& offset, const SkIRect& clipBounds);
     41     void drawTextBlob(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
     42                       const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*,
     43                       SkScalar x, SkScalar y,
     44                       SkDrawFilter*, const SkIRect& clipBounds);
     45 
     46     virtual ~GrStencilAndCoverTextContext();
     47 
     48 private:
     49     GrStencilAndCoverTextContext(GrAtlasTextContext* fallbackTextContext);
     50 
     51     bool canDraw(const SkPaint& skPaint, const SkMatrix&) {
     52         return this->internalCanDraw(skPaint);
     53     }
     54 
     55     bool internalCanDraw(const SkPaint&);
     56 
     57     void uncachedDrawTextBlob(GrContext*, GrRenderTargetContext* rtc,
     58                               const GrClip& clip, const SkPaint& skPaint,
     59                               const SkMatrix& viewMatrix,
     60                               const SkSurfaceProps&,
     61                               const SkTextBlob* blob,
     62                               SkScalar x, SkScalar y,
     63                               SkDrawFilter* drawFilter,
     64                               const SkIRect& clipBounds);
     65 
     66     class FallbackBlobBuilder;
     67 
     68     class TextRun {
     69     public:
     70         TextRun(const SkPaint& fontAndStroke);
     71         ~TextRun();
     72 
     73         void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y);
     74 
     75         void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
     76                         int scalarsPerPosition, const SkPoint& offset);
     77 
     78         void draw(GrContext*, GrRenderTargetContext*, const GrClip&, const SkMatrix&,
     79                   const SkSurfaceProps&, SkScalar x, SkScalar y, const SkIRect& clipBounds,
     80                   GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
     81 
     82         void releaseGlyphCache() const;
     83 
     84         size_t computeSizeInCache() const;
     85 
     86         GrAA aa() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; }
     87 
     88     private:
     89         typedef GrDrawPathRangeOp::InstanceData InstanceData;
     90 
     91         SkGlyphCache* getGlyphCache() const;
     92         sk_sp<GrPathRange> createGlyphs(GrResourceProvider*) const;
     93         void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*);
     94 
     95         GrStyle                         fStyle;
     96         SkPaint                         fFont;
     97         SkScalar                        fTextRatio;
     98         float                           fTextInverseRatio;
     99         bool                            fUsingRawGlyphPaths;
    100         GrUniqueKey                     fGlyphPathsKey;
    101         int                             fTotalGlyphCount;
    102         sk_sp<InstanceData>             fInstanceData;
    103         int                             fFallbackGlyphCount;
    104         sk_sp<SkTextBlob>               fFallbackTextBlob;
    105         mutable SkGlyphCache*           fDetachedGlyphCache;
    106         mutable GrGpuResource::UniqueID fLastDrawnGlyphsID;
    107     };
    108 
    109     // Text blobs/caches.
    110 
    111     class TextBlob : public SkTLList<TextRun, 1> {
    112     public:
    113         typedef SkTArray<uint32_t, true> Key;
    114 
    115         static const Key& GetKey(const TextBlob* blob) { return blob->key(); }
    116 
    117         static uint32_t Hash(const Key& key) {
    118             SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map.
    119             return SkOpts::hash(key.begin(), sizeof(uint32_t) * key.count());
    120         }
    121 
    122         TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint)
    123             : fKey(&blobId, 1) { this->init(skBlob, skPaint); }
    124 
    125         TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint)
    126             : fKey(key) {
    127             // 1-length keys are unterstood to be the blob id and must use the other constructor.
    128             SkASSERT(fKey.count() > 1);
    129             this->init(skBlob, skPaint);
    130         }
    131 
    132         const Key& key() const { return fKey; }
    133 
    134         size_t cpuMemorySize() const { return fCpuMemorySize; }
    135 
    136     private:
    137         void init(const SkTextBlob*, const SkPaint&);
    138 
    139         const SkSTArray<1, uint32_t, true>   fKey;
    140         size_t                               fCpuMemorySize;
    141 
    142         SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
    143     };
    144 
    145     const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&);
    146     void purgeToFit(const TextBlob&);
    147 
    148     GrAtlasTextContext*                                       fFallbackTextContext;
    149     SkTHashMap<uint32_t, TextBlob*>                           fBlobIdCache;
    150     SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob>   fBlobKeyCache;
    151     SkTInternalLList<TextBlob>                                fLRUList;
    152     size_t                                                    fCacheSize;
    153 };
    154 
    155 #endif
    156