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