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 SkTextBlob_DEFINED
      9 #define SkTextBlob_DEFINED
     10 
     11 #include "SkPaint.h"
     12 #include "SkRefCnt.h"
     13 #include "SkTArray.h"
     14 #include "SkTDArray.h"
     15 
     16 class SkReadBuffer;
     17 class SkWriteBuffer;
     18 
     19 /** \class SkTextBlob
     20 
     21     SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
     22 */
     23 class SK_API SkTextBlob : public SkRefCnt {
     24 public:
     25     /**
     26      *  Returns the blob bounding box.
     27      */
     28     const SkRect& bounds() const { return fBounds; }
     29 
     30     /**
     31      *  Return a non-zero, unique value representing the text blob.
     32      */
     33     uint32_t uniqueID() const;
     34 
     35     /**
     36      *  Serialize to a buffer.
     37      */
     38     void flatten(SkWriteBuffer&) const;
     39 
     40     /**
     41      *  Recreate an SkTextBlob that was serialized into a buffer.
     42      *
     43      *  @param  SkReadBuffer Serialized blob data.
     44      *  @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
     45      *          invalid.
     46      */
     47     static const SkTextBlob* CreateFromBuffer(SkReadBuffer&);
     48 
     49 private:
     50     enum GlyphPositioning {
     51         kDefault_Positioning      = 0, // Default glyph advances -- zero scalars per glyph.
     52         kHorizontal_Positioning   = 1, // Horizontal positioning -- one scalar per glyph.
     53         kFull_Positioning         = 2  // Point positioning -- two scalars per glyph.
     54     };
     55 
     56     class RunRecord;
     57 
     58     class RunIterator {
     59     public:
     60         RunIterator(const SkTextBlob* blob);
     61 
     62         bool done() const;
     63         void next();
     64 
     65         uint32_t glyphCount() const;
     66         const uint16_t* glyphs() const;
     67         const SkScalar* pos() const;
     68         const SkPoint& offset() const;
     69         void applyFontToPaint(SkPaint*) const;
     70         GlyphPositioning positioning() const;
     71 
     72     private:
     73         const RunRecord* fCurrentRun;
     74         int              fRemainingRuns;
     75 
     76         SkDEBUGCODE(uint8_t* fStorageTop;)
     77     };
     78 
     79     SkTextBlob(int runCount, const SkRect& bounds);
     80 
     81     virtual ~SkTextBlob();
     82     virtual void internal_dispose() const SK_OVERRIDE;
     83 
     84     static unsigned ScalarsPerGlyph(GlyphPositioning pos);
     85 
     86     friend class SkBaseDevice;
     87     friend class SkTextBlobBuilder;
     88     friend class TextBlobTester;
     89 
     90     const int        fRunCount;
     91     const SkRect     fBounds;
     92     mutable uint32_t fUniqueID;
     93 
     94     SkDEBUGCODE(size_t fStorageSize;)
     95 
     96     // The actual payload resides in externally-managed storage, following the object.
     97     // (see the .cpp for more details)
     98 
     99     typedef SkRefCnt INHERITED;
    100 };
    101 
    102 /** \class SkTextBlobBuilder
    103 
    104     Helper class for constructing SkTextBlobs.
    105  */
    106 class SK_API SkTextBlobBuilder {
    107 public:
    108     SkTextBlobBuilder();
    109 
    110     ~SkTextBlobBuilder();
    111 
    112     /**
    113      *  Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
    114      *  can be reused.
    115      */
    116     const SkTextBlob* build();
    117 
    118     /**
    119      *  Glyph and position buffers associated with a run.
    120      *
    121      *  A run is a sequence of glyphs sharing the same font metrics and positioning mode.
    122      */
    123     struct RunBuffer {
    124         uint16_t* glyphs;
    125         SkScalar* pos;
    126     };
    127 
    128     /**
    129      *  Allocates a new default-positioned run and returns its writable glyph buffer
    130      *  for direct manipulation.
    131      *
    132      *  @param font    The font to be used for this run.
    133      *  @param count   Number of glyphs.
    134      *  @param x,y     Position within the blob.
    135      *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
    136      *                 be used when computing the blob bounds, to avoid re-measuring.
    137      *
    138      *  @return        A writable glyph buffer, valid until the next allocRun() or
    139      *                 build() call. The buffer is guaranteed to hold @count@ glyphs.
    140      */
    141     const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
    142                               const SkRect* bounds = NULL);
    143 
    144     /**
    145      *  Allocates a new horizontally-positioned run and returns its writable glyph and position
    146      *  buffers for direct manipulation.
    147      *
    148      *  @param font    The font to be used for this run.
    149      *  @param count   Number of glyphs.
    150      *  @param y       Vertical offset within the blob.
    151      *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
    152      *                 be used when computing the blob bounds, to avoid re-measuring.
    153      *
    154      *  @return        Writable glyph and position buffers, valid until the next allocRun()
    155      *                 or build() call. The buffers are guaranteed to hold @count@ elements.
    156      */
    157     const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
    158                                   const SkRect* bounds = NULL);
    159 
    160     /**
    161      *  Allocates a new fully-positioned run and returns its writable glyph and position
    162      *  buffers for direct manipulation.
    163      *
    164      *  @param font   The font to be used for this run.
    165      *  @param count  Number of glyphs.
    166      *  @param bounds Optional run bounding box. If known in advance (!= NULL), it will
    167      *                be used when computing the blob bounds, to avoid re-measuring.
    168      *
    169      *  @return       Writable glyph and position buffers, valid until the next allocRun()
    170      *                or build() call. The glyph buffer and position buffer are
    171      *                guaranteed to hold @count@ and 2 * @count@ elements, respectively.
    172      */
    173     const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
    174 
    175 private:
    176     void reserve(size_t size);
    177     void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
    178                        int count, SkPoint offset, const SkRect* bounds);
    179     bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
    180                   int count, SkPoint offset);
    181     void updateDeferredBounds();
    182 
    183     SkAutoTMalloc<uint8_t> fStorage;
    184     size_t                 fStorageSize;
    185     size_t                 fStorageUsed;
    186 
    187     SkRect                 fBounds;
    188     int                    fRunCount;
    189     bool                   fDeferredBounds;
    190     size_t                 fLastRun; // index into fStorage
    191 
    192     RunBuffer              fCurrentRunBuffer;
    193 };
    194 
    195 #endif // SkTextBlob_DEFINED
    196