100d5c2c6523321d25b32905ff4822f083a4173eefmalita/*
200d5c2c6523321d25b32905ff4822f083a4173eefmalita * Copyright 2014 Google Inc.
300d5c2c6523321d25b32905ff4822f083a4173eefmalita *
400d5c2c6523321d25b32905ff4822f083a4173eefmalita * Use of this source code is governed by a BSD-style license that can be
500d5c2c6523321d25b32905ff4822f083a4173eefmalita * found in the LICENSE file.
600d5c2c6523321d25b32905ff4822f083a4173eefmalita */
700d5c2c6523321d25b32905ff4822f083a4173eefmalita
800d5c2c6523321d25b32905ff4822f083a4173eefmalita#ifndef SkTextBlob_DEFINED
900d5c2c6523321d25b32905ff4822f083a4173eefmalita#define SkTextBlob_DEFINED
1000d5c2c6523321d25b32905ff4822f083a4173eefmalita
11bf521ff9415b3bdb1acde7b8d18139df176236e5bungeman#include "../private/SkTemplates.h"
124a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita#include "../private/SkAtomics.h"
1300d5c2c6523321d25b32905ff4822f083a4173eefmalita#include "SkPaint.h"
144f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary#include "SkString.h"
1500d5c2c6523321d25b32905ff4822f083a4173eefmalita#include "SkRefCnt.h"
1600d5c2c6523321d25b32905ff4822f083a4173eefmalita
17b7425173f96e93b090787e2386ba5f022b6c2869fmalitaclass SkReadBuffer;
18b7425173f96e93b090787e2386ba5f022b6c2869fmalitaclass SkWriteBuffer;
19b7425173f96e93b090787e2386ba5f022b6c2869fmalita
208e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reedstruct SkSerialProcs;
218e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reedstruct SkDeserialProcs;
228e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed
23aaa3056e46ed9004097dc784db94c3a97d070569Mike Reedtypedef void (*SkTypefaceCatalogerProc)(SkTypeface*, void* ctx);
24aaa3056e46ed9004097dc784db94c3a97d070569Mike Reedtypedef sk_sp<SkTypeface> (*SkTypefaceResolverProc)(uint32_t id, void* ctx);
25b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed
2600d5c2c6523321d25b32905ff4822f083a4173eefmalita/** \class SkTextBlob
2700d5c2c6523321d25b32905ff4822f083a4173eefmalita
2800d5c2c6523321d25b32905ff4822f083a4173eefmalita    SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
2900d5c2c6523321d25b32905ff4822f083a4173eefmalita*/
30b47cd4b3d6daad037651daa20fae6770285966d6mtkleinclass SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
3100d5c2c6523321d25b32905ff4822f083a4173eefmalitapublic:
3200d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
333dc40ac9f968eee95eef5e8ee811e0640691df0ffmalita     *  Returns a conservative blob bounding box.
3400d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
3500d5c2c6523321d25b32905ff4822f083a4173eefmalita    const SkRect& bounds() const { return fBounds; }
3600d5c2c6523321d25b32905ff4822f083a4173eefmalita
3700d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
3800d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  Return a non-zero, unique value representing the text blob.
3900d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
402af858354d913397a6c316ef46a5d52d686e10abjoshualitt    uint32_t uniqueID() const { return fUniqueID; }
4100d5c2c6523321d25b32905ff4822f083a4173eefmalita
42228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita    /**
43228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *  Serialize to a buffer.
44228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     */
45228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita    void flatten(SkWriteBuffer&) const;
46228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita
47228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita    /**
48228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *  Recreate an SkTextBlob that was serialized into a buffer.
49228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *
50228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *  @param  SkReadBuffer Serialized blob data.
51228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *  @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
52228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     *          invalid.
53228a6f275d7c5c17c48c20b57df971d9848f5dfffmalita     */
542ab9057b31ee92060b9769ea1adfada51c11c010reed    static sk_sp<SkTextBlob> MakeFromBuffer(SkReadBuffer&);
552ab9057b31ee92060b9769ea1adfada51c11c010reed
564f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    enum GlyphPositioning : uint8_t {
5700d5c2c6523321d25b32905ff4822f083a4173eefmalita        kDefault_Positioning      = 0, // Default glyph advances -- zero scalars per glyph.
5800d5c2c6523321d25b32905ff4822f083a4173eefmalita        kHorizontal_Positioning   = 1, // Horizontal positioning -- one scalar per glyph.
5900d5c2c6523321d25b32905ff4822f083a4173eefmalita        kFull_Positioning         = 2  // Point positioning -- two scalars per glyph.
6000d5c2c6523321d25b32905ff4822f083a4173eefmalita    };
6100d5c2c6523321d25b32905ff4822f083a4173eefmalita
62b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed    /**
63b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  Serialize the typeface into a data blob, storing type uniqueID of each referenced typeface.
64b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  During this process, each time a typeface is encountered, it is passed to the catalog,
65b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  allowing the caller to what typeface IDs will need to be resolved in Deserialize().
66b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     */
67aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed    sk_sp<SkData> serialize(SkTypefaceCatalogerProc, void* ctx) const;
68b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed
69b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed    /**
70b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  Re-create a text blob previously serialized. Since the serialized form records the uniqueIDs
71b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  of its typefaces, deserialization requires that the caller provide the corresponding
72b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     *  SkTypefaces for those IDs.
73b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed     */
74aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed    static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size,
75aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed                                         SkTypefaceResolverProc, void* ctx);
76aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed
778e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed    sk_sp<SkData> serialize(const SkSerialProcs&) const;
78f6eb1f9b63da45b7dbd4f26a6edf9d968ac4a517Mike Reed    sk_sp<SkData> serialize() const;
798e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed    static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size, const SkDeserialProcs&);
80f6eb1f9b63da45b7dbd4f26a6edf9d968ac4a517Mike Reed    static sk_sp<SkTextBlob> Deserialize(const void* data, size_t size);
818e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed
82337797580de42cdb722caab4bed121311ed7d0d2halcanaryprivate:
83b47cd4b3d6daad037651daa20fae6770285966d6mtklein    friend class SkNVRefCnt<SkTextBlob>;
843c196def91726913a417e703ac482bb2dbbfff27fmalita    class RunRecord;
853c196def91726913a417e703ac482bb2dbbfff27fmalita
863a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita    explicit SkTextBlob(const SkRect& bounds);
873c196def91726913a417e703ac482bb2dbbfff27fmalita
88b47cd4b3d6daad037651daa20fae6770285966d6mtklein    ~SkTextBlob();
89072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon
90072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    // Memory for objects of this class is created with sk_malloc rather than operator new and must
91072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    // be freed with sk_free.
92072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    void operator delete(void* p) { sk_free(p); }
93072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    void* operator new(size_t) {
94b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner        SK_ABORT("All blobs are created by placement new.");
95072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon        return sk_malloc_throw(0);
96072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    }
97072803144a623f1a59eb73ca5f3ddf45222b5e06bsalomon    void* operator new(size_t, void* p) { return p; }
9800d5c2c6523321d25b32905ff4822f083a4173eefmalita
99b7425173f96e93b090787e2386ba5f022b6c2869fmalita    static unsigned ScalarsPerGlyph(GlyphPositioning pos);
100b7425173f96e93b090787e2386ba5f022b6c2869fmalita
1014a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita    // Call when this blob is part of the key to a cache entry. This allows the cache
1024a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita    // to know automatically those entries can be purged when this SkTextBlob is deleted.
103474d68791965f20f8e0dfa2bfb4d87300f1f29e0Jim Van Verth    void notifyAddedToCache(uint32_t cacheID) const {
104474d68791965f20f8e0dfa2bfb4d87300f1f29e0Jim Van Verth        fCacheID.store(cacheID);
1054a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita    }
1064a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita
1074a01ac9e410e7b78fb04c8632e0676082b9408aaFlorin Malita    friend class GrTextBlobCache;
10800d5c2c6523321d25b32905ff4822f083a4173eefmalita    friend class SkTextBlobBuilder;
109337797580de42cdb722caab4bed121311ed7d0d2halcanary    friend class SkTextBlobRunIterator;
11000d5c2c6523321d25b32905ff4822f083a4173eefmalita
111474d68791965f20f8e0dfa2bfb4d87300f1f29e0Jim Van Verth    const SkRect               fBounds;
112474d68791965f20f8e0dfa2bfb4d87300f1f29e0Jim Van Verth    const uint32_t             fUniqueID;
113474d68791965f20f8e0dfa2bfb4d87300f1f29e0Jim Van Verth    mutable SkAtomic<uint32_t> fCacheID;
11400d5c2c6523321d25b32905ff4822f083a4173eefmalita
1153c196def91726913a417e703ac482bb2dbbfff27fmalita    SkDEBUGCODE(size_t fStorageSize;)
11600d5c2c6523321d25b32905ff4822f083a4173eefmalita
1173c196def91726913a417e703ac482bb2dbbfff27fmalita    // The actual payload resides in externally-managed storage, following the object.
1183c196def91726913a417e703ac482bb2dbbfff27fmalita    // (see the .cpp for more details)
11900d5c2c6523321d25b32905ff4822f083a4173eefmalita
12000d5c2c6523321d25b32905ff4822f083a4173eefmalita    typedef SkRefCnt INHERITED;
12100d5c2c6523321d25b32905ff4822f083a4173eefmalita};
12200d5c2c6523321d25b32905ff4822f083a4173eefmalita
12300d5c2c6523321d25b32905ff4822f083a4173eefmalita/** \class SkTextBlobBuilder
12400d5c2c6523321d25b32905ff4822f083a4173eefmalita
12500d5c2c6523321d25b32905ff4822f083a4173eefmalita    Helper class for constructing SkTextBlobs.
12600d5c2c6523321d25b32905ff4822f083a4173eefmalita */
1273053dfaefd12abd220d961e7e4c661e6eb8ba90ejbromanclass SK_API SkTextBlobBuilder {
12800d5c2c6523321d25b32905ff4822f083a4173eefmalitapublic:
1293c196def91726913a417e703ac482bb2dbbfff27fmalita    SkTextBlobBuilder();
13000d5c2c6523321d25b32905ff4822f083a4173eefmalita
13100d5c2c6523321d25b32905ff4822f083a4173eefmalita    ~SkTextBlobBuilder();
13200d5c2c6523321d25b32905ff4822f083a4173eefmalita
13300d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
1343a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita     *  Returns an immutable SkTextBlob for the current runs/glyphs,
1353a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita     *  or nullptr if no runs were allocated.
1363a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita     *
1373a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita     *  The builder is reset and can be reused.
13800d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
1392ab9057b31ee92060b9769ea1adfada51c11c010reed    sk_sp<SkTextBlob> make();
1402ab9057b31ee92060b9769ea1adfada51c11c010reed
14100d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
14200d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  Glyph and position buffers associated with a run.
14300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
1444f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  A run is a sequence of glyphs sharing the same font metrics
1454f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  and positioning mode.
1464f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *
1474f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  If textByteCount is 0, utf8text and clusters will be NULL (no
1484f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  character information will be associated with the glyphs).
1494f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *
1504f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  utf8text will point to a buffer of size textByteCount bytes.
1514f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *
1524f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  clusters (if not NULL) will point to an array of size count.
1534f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  For each glyph, give the byte-offset into the text for the
1544f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  first byte in the first character in that glyph's cluster.
1554f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  Each value in the array should be an integer less than
1564f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  textByteCount.  Values in the array should either be
1574f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  monotonically increasing (left-to-right text) or monotonically
1584f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  decreasing (right-to-left text).  This definiton is conviently
1594f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  the same as used by Harfbuzz's hb_glyph_info_t::cluster field,
1604f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  except that Harfbuzz interleaves glyphs and clusters.
16100d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
16200d5c2c6523321d25b32905ff4822f083a4173eefmalita    struct RunBuffer {
163d0e95a524c20932e0f4e68bab43995188a281395halcanary        SkGlyphID* glyphs;
16400d5c2c6523321d25b32905ff4822f083a4173eefmalita        SkScalar* pos;
1654f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary        char* utf8text;
1664f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary        uint32_t* clusters;
16700d5c2c6523321d25b32905ff4822f083a4173eefmalita    };
16800d5c2c6523321d25b32905ff4822f083a4173eefmalita
16900d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
17000d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  Allocates a new default-positioned run and returns its writable glyph buffer
17100d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  for direct manipulation.
17200d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
17300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param font    The font to be used for this run.
17400d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param count   Number of glyphs.
17500d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param x,y     Position within the blob.
1764f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param textByteCount length of the original UTF-8 text that
1774f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 corresponds to this sequence of glyphs.  If 0,
1784f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 text will not be included in the textblob.
1794f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param lang    Language code, currently unimplemented.
18000d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
18100d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                 be used when computing the blob bounds, to avoid re-measuring.
18200d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
18300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @return        A writable glyph buffer, valid until the next allocRun() or
18400d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                 build() call. The buffer is guaranteed to hold @count@ glyphs.
18500d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
1864f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    const RunBuffer& allocRunText(const SkPaint& font,
1874f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                  int count,
1884f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                  SkScalar x,
1894f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                  SkScalar y,
1904f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                  int textByteCount,
1914f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                  SkString lang,
192a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                                  const SkRect* bounds = nullptr);
19300d5c2c6523321d25b32905ff4822f083a4173eefmalita    const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
194a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                              const SkRect* bounds = nullptr) {
1954f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary        return this->allocRunText(font, count, x, y, 0, SkString(), bounds);
1964f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    }
19700d5c2c6523321d25b32905ff4822f083a4173eefmalita
19800d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
19900d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  Allocates a new horizontally-positioned run and returns its writable glyph and position
20000d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  buffers for direct manipulation.
20100d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
20200d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param font    The font to be used for this run.
20300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param count   Number of glyphs.
20400d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param y       Vertical offset within the blob.
2054f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param textByteCount length of the original UTF-8 text that
2064f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 corresponds to this sequence of glyphs.  If 0,
2074f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 text will not be included in the textblob.
2084f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param lang    Language code, currently unimplemented.
20900d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param bounds  Optional run bounding box. If known in advance (!= NULL), it will
21000d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                 be used when computing the blob bounds, to avoid re-measuring.
21100d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
21200d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @return        Writable glyph and position buffers, valid until the next allocRun()
21300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                 or build() call. The buffers are guaranteed to hold @count@ elements.
21400d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
2154f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
2164f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                      int textByteCount, SkString lang,
217a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                                      const SkRect* bounds = nullptr);
21800d5c2c6523321d25b32905ff4822f083a4173eefmalita    const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
219a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                                  const SkRect* bounds = nullptr) {
2204f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary        return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds);
2214f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    }
22200d5c2c6523321d25b32905ff4822f083a4173eefmalita
22300d5c2c6523321d25b32905ff4822f083a4173eefmalita    /**
22400d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  Allocates a new fully-positioned run and returns its writable glyph and position
22500d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  buffers for direct manipulation.
22600d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
22700d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param font   The font to be used for this run.
22800d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param count  Number of glyphs.
2294f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param textByteCount length of the original UTF-8 text that
2304f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 corresponds to this sequence of glyphs.  If 0,
2314f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *                 text will not be included in the textblob.
2324f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary     *  @param lang    Language code, currently unimplemented.
23300d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @param bounds Optional run bounding box. If known in advance (!= NULL), it will
23400d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                be used when computing the blob bounds, to avoid re-measuring.
23500d5c2c6523321d25b32905ff4822f083a4173eefmalita     *
23600d5c2c6523321d25b32905ff4822f083a4173eefmalita     *  @return       Writable glyph and position buffers, valid until the next allocRun()
23700d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                or build() call. The glyph buffer and position buffer are
23800d5c2c6523321d25b32905ff4822f083a4173eefmalita     *                guaranteed to hold @count@ and 2 * @count@ elements, respectively.
23900d5c2c6523321d25b32905ff4822f083a4173eefmalita     */
2404f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
2414f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                                     int textByteCount, SkString lang,
242a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                                     const SkRect* bounds = nullptr);
2434f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    const RunBuffer& allocRunPos(const SkPaint& font, int count,
244a93a14a99816d25b773f0b12868143702baf44bfBen Wagner                                 const SkRect* bounds = nullptr) {
2454f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary        return this->allocRunTextPos(font, count, 0, SkString(), bounds);
2464f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary    }
24700d5c2c6523321d25b32905ff4822f083a4173eefmalita
24800d5c2c6523321d25b32905ff4822f083a4173eefmalitaprivate:
2493c196def91726913a417e703ac482bb2dbbfff27fmalita    void reserve(size_t size);
25000d5c2c6523321d25b32905ff4822f083a4173eefmalita    void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
2514f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary                       int count, int textBytes, SkPoint offset, const SkRect* bounds);
2523c196def91726913a417e703ac482bb2dbbfff27fmalita    bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
253d923a71a113d97dc87b4424c25d5b5019331db24Florin Malita                  uint32_t count, SkPoint offset);
25400d5c2c6523321d25b32905ff4822f083a4173eefmalita    void updateDeferredBounds();
25500d5c2c6523321d25b32905ff4822f083a4173eefmalita
2563dc40ac9f968eee95eef5e8ee811e0640691df0ffmalita    static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&);
2573dc40ac9f968eee95eef5e8ee811e0640691df0ffmalita    static SkRect TightRunBounds(const SkTextBlob::RunRecord&);
2583dc40ac9f968eee95eef5e8ee811e0640691df0ffmalita
2593c196def91726913a417e703ac482bb2dbbfff27fmalita    SkAutoTMalloc<uint8_t> fStorage;
2603c196def91726913a417e703ac482bb2dbbfff27fmalita    size_t                 fStorageSize;
2613c196def91726913a417e703ac482bb2dbbfff27fmalita    size_t                 fStorageUsed;
26200d5c2c6523321d25b32905ff4822f083a4173eefmalita
2633c196def91726913a417e703ac482bb2dbbfff27fmalita    SkRect                 fBounds;
2643c196def91726913a417e703ac482bb2dbbfff27fmalita    int                    fRunCount;
2653c196def91726913a417e703ac482bb2dbbfff27fmalita    bool                   fDeferredBounds;
2663c196def91726913a417e703ac482bb2dbbfff27fmalita    size_t                 fLastRun; // index into fStorage
26700d5c2c6523321d25b32905ff4822f083a4173eefmalita
2683c196def91726913a417e703ac482bb2dbbfff27fmalita    RunBuffer              fCurrentRunBuffer;
26900d5c2c6523321d25b32905ff4822f083a4173eefmalita};
27000d5c2c6523321d25b32905ff4822f083a4173eefmalita
27100d5c2c6523321d25b32905ff4822f083a4173eefmalita#endif // SkTextBlob_DEFINED
272