• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
bounds()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