SkTextBlobPriv.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright 2018 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. #ifndef SkTextBlobPriv_DEFINED
  8. #define SkTextBlobPriv_DEFINED
  9. #include "include/core/SkColorFilter.h"
  10. #include "include/core/SkDrawLooper.h"
  11. #include "include/core/SkFont.h"
  12. #include "include/core/SkImageFilter.h"
  13. #include "include/core/SkMaskFilter.h"
  14. #include "include/core/SkPathEffect.h"
  15. #include "include/core/SkShader.h"
  16. #include "include/core/SkTextBlob.h"
  17. #include "include/core/SkTypeface.h"
  18. #include "src/core/SkPaintPriv.h"
  19. #include "src/core/SkSafeMath.h"
  20. class SkReadBuffer;
  21. class SkWriteBuffer;
  22. class SkTextBlobPriv {
  23. public:
  24. /**
  25. * Serialize to a buffer.
  26. */
  27. static void Flatten(const SkTextBlob& , SkWriteBuffer&);
  28. /**
  29. * Recreate an SkTextBlob that was serialized into a buffer.
  30. *
  31. * @param SkReadBuffer Serialized blob data.
  32. * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
  33. * invalid.
  34. */
  35. static sk_sp<SkTextBlob> MakeFromBuffer(SkReadBuffer&);
  36. };
  37. class SkTextBlobBuilderPriv {
  38. public:
  39. static const SkTextBlobBuilder::RunBuffer& AllocRunText(SkTextBlobBuilder* builder,
  40. const SkFont& font, int count, SkScalar x, SkScalar y, int textByteCount,
  41. SkString lang, const SkRect* bounds = nullptr) {
  42. return builder->allocRunText(font, count, x, y, textByteCount, lang, bounds);
  43. }
  44. static const SkTextBlobBuilder::RunBuffer& AllocRunTextPosH(SkTextBlobBuilder* builder,
  45. const SkFont& font, int count, SkScalar y, int textByteCount, SkString lang,
  46. const SkRect* bounds = nullptr) {
  47. return builder->allocRunTextPosH(font, count, y, textByteCount, lang, bounds);
  48. }
  49. static const SkTextBlobBuilder::RunBuffer& AllocRunTextPos(SkTextBlobBuilder* builder,
  50. const SkFont& font, int count, int textByteCount, SkString lang,
  51. const SkRect* bounds = nullptr) {
  52. return builder->allocRunTextPos(font, count, textByteCount, lang, bounds);
  53. }
  54. };
  55. //
  56. // Textblob data is laid out into externally-managed storage as follows:
  57. //
  58. // -----------------------------------------------------------------------------
  59. // | SkTextBlob | RunRecord | Glyphs[] | Pos[] | RunRecord | Glyphs[] | Pos[] | ...
  60. // -----------------------------------------------------------------------------
  61. //
  62. // Each run record describes a text blob run, and can be used to determine the (implicit)
  63. // location of the following record.
  64. //
  65. // Extended Textblob runs have more data after the Pos[] array:
  66. //
  67. // -------------------------------------------------------------------------
  68. // ... | RunRecord | Glyphs[] | Pos[] | TextSize | Clusters[] | Text[] | ...
  69. // -------------------------------------------------------------------------
  70. //
  71. // To determine the length of the extended run data, the TextSize must be read.
  72. //
  73. // Extended Textblob runs may be mixed with non-extended runs.
  74. SkDEBUGCODE(static const unsigned kRunRecordMagic = 0xb10bcafe;)
  75. class SkTextBlob::RunRecord {
  76. public:
  77. RunRecord(uint32_t count, uint32_t textSize, const SkPoint& offset, const SkFont& font, GlyphPositioning pos)
  78. : fFont(font)
  79. , fCount(count)
  80. , fOffset(offset)
  81. , fFlags(pos) {
  82. SkASSERT(static_cast<unsigned>(pos) <= Flags::kPositioning_Mask);
  83. SkDEBUGCODE(fMagic = kRunRecordMagic);
  84. if (textSize > 0) {
  85. fFlags |= kExtended_Flag;
  86. *this->textSizePtr() = textSize;
  87. }
  88. }
  89. uint32_t glyphCount() const {
  90. return fCount;
  91. }
  92. const SkPoint& offset() const {
  93. return fOffset;
  94. }
  95. const SkFont& font() const {
  96. return fFont;
  97. }
  98. GlyphPositioning positioning() const {
  99. return static_cast<GlyphPositioning>(fFlags & kPositioning_Mask);
  100. }
  101. uint16_t* glyphBuffer() const {
  102. static_assert(SkIsAlignPtr(sizeof(RunRecord)), "");
  103. // Glyphs are stored immediately following the record.
  104. return reinterpret_cast<uint16_t*>(const_cast<RunRecord*>(this) + 1);
  105. }
  106. // can be aliased with pointBuffer() or xformBuffer()
  107. SkScalar* posBuffer() const {
  108. // Position scalars follow the (aligned) glyph buffer.
  109. return reinterpret_cast<SkScalar*>(reinterpret_cast<uint8_t*>(this->glyphBuffer()) +
  110. SkAlign4(fCount * sizeof(uint16_t)));
  111. }
  112. // alias for posBuffer()
  113. SkPoint* pointBuffer() const {
  114. SkASSERT(this->positioning() == (GlyphPositioning)2);
  115. return reinterpret_cast<SkPoint*>(this->posBuffer());
  116. }
  117. // alias for posBuffer()
  118. SkRSXform* xformBuffer() const {
  119. SkASSERT(this->positioning() == (GlyphPositioning)3);
  120. return reinterpret_cast<SkRSXform*>(this->posBuffer());
  121. }
  122. uint32_t textSize() const { return isExtended() ? *this->textSizePtr() : 0; }
  123. uint32_t* clusterBuffer() const {
  124. // clusters follow the textSize.
  125. return isExtended() ? 1 + this->textSizePtr() : nullptr;
  126. }
  127. char* textBuffer() const {
  128. return isExtended()
  129. ? reinterpret_cast<char*>(this->clusterBuffer() + fCount)
  130. : nullptr;
  131. }
  132. static size_t StorageSize(uint32_t glyphCount, uint32_t textSize,
  133. SkTextBlob::GlyphPositioning positioning,
  134. SkSafeMath* safe);
  135. static const RunRecord* First(const SkTextBlob* blob);
  136. static const RunRecord* Next(const RunRecord* run);
  137. void validate(const uint8_t* storageTop) const;
  138. private:
  139. friend class SkTextBlobBuilder;
  140. enum Flags {
  141. kPositioning_Mask = 0x03, // bits 0-1 reserved for positioning
  142. kLast_Flag = 0x04, // set for the last blob run
  143. kExtended_Flag = 0x08, // set for runs with text/cluster info
  144. };
  145. static const RunRecord* NextUnchecked(const RunRecord* run);
  146. static size_t PosCount(uint32_t glyphCount,
  147. SkTextBlob::GlyphPositioning positioning,
  148. SkSafeMath* safe);
  149. uint32_t* textSizePtr() const;
  150. void grow(uint32_t count);
  151. bool isExtended() const {
  152. return fFlags & kExtended_Flag;
  153. }
  154. SkFont fFont;
  155. uint32_t fCount;
  156. SkPoint fOffset;
  157. uint32_t fFlags;
  158. SkDEBUGCODE(unsigned fMagic;)
  159. };
  160. /**
  161. * Iterate through all of the text runs of the text blob. For example:
  162. * for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
  163. * .....
  164. * }
  165. */
  166. class SkTextBlobRunIterator {
  167. public:
  168. SkTextBlobRunIterator(const SkTextBlob* blob);
  169. enum GlyphPositioning : uint8_t {
  170. kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph.
  171. kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph.
  172. kFull_Positioning = 2, // Point positioning -- two scalars per glyph.
  173. kRSXform_Positioning = 3, // RSXform positioning -- four scalars per glyph.
  174. };
  175. bool done() const {
  176. return !fCurrentRun;
  177. }
  178. void next();
  179. uint32_t glyphCount() const {
  180. SkASSERT(!this->done());
  181. return fCurrentRun->glyphCount();
  182. }
  183. const uint16_t* glyphs() const {
  184. SkASSERT(!this->done());
  185. return fCurrentRun->glyphBuffer();
  186. }
  187. const SkScalar* pos() const {
  188. SkASSERT(!this->done());
  189. return fCurrentRun->posBuffer();
  190. }
  191. // alias for pos()
  192. const SkPoint* points() const {
  193. return fCurrentRun->pointBuffer();
  194. }
  195. // alias for pos()
  196. const SkRSXform* xforms() const {
  197. return fCurrentRun->xformBuffer();
  198. }
  199. const SkPoint& offset() const {
  200. SkASSERT(!this->done());
  201. return fCurrentRun->offset();
  202. }
  203. const SkFont& font() const {
  204. SkASSERT(!this->done());
  205. return fCurrentRun->font();
  206. }
  207. GlyphPositioning positioning() const;
  208. uint32_t* clusters() const {
  209. SkASSERT(!this->done());
  210. return fCurrentRun->clusterBuffer();
  211. }
  212. uint32_t textSize() const {
  213. SkASSERT(!this->done());
  214. return fCurrentRun->textSize();
  215. }
  216. char* text() const {
  217. SkASSERT(!this->done());
  218. return fCurrentRun->textBuffer();
  219. }
  220. bool isLCD() const;
  221. private:
  222. const SkTextBlob::RunRecord* fCurrentRun;
  223. SkDEBUGCODE(uint8_t* fStorageTop;)
  224. };
  225. #endif // SkTextBlobPriv_DEFINED