SkWriteBuffer.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Copyright 2012 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. #include "src/core/SkWriteBuffer.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkData.h"
  10. #include "include/core/SkStream.h"
  11. #include "include/core/SkTypeface.h"
  12. #include "include/private/SkTo.h"
  13. #include "src/core/SkImagePriv.h"
  14. #include "src/core/SkPaintPriv.h"
  15. #include "src/core/SkPtrRecorder.h"
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////
  17. SkBinaryWriteBuffer::SkBinaryWriteBuffer()
  18. : fFactorySet(nullptr)
  19. , fTFSet(nullptr) {
  20. }
  21. SkBinaryWriteBuffer::SkBinaryWriteBuffer(void* storage, size_t storageSize)
  22. : fFactorySet(nullptr)
  23. , fTFSet(nullptr)
  24. , fWriter(storage, storageSize)
  25. {}
  26. SkBinaryWriteBuffer::~SkBinaryWriteBuffer() {}
  27. bool SkBinaryWriteBuffer::usingInitialStorage() const {
  28. return fWriter.usingInitialStorage();
  29. }
  30. void SkBinaryWriteBuffer::writeByteArray(const void* data, size_t size) {
  31. fWriter.write32(SkToU32(size));
  32. fWriter.writePad(data, size);
  33. }
  34. void SkBinaryWriteBuffer::writeBool(bool value) {
  35. fWriter.writeBool(value);
  36. }
  37. void SkBinaryWriteBuffer::writeScalar(SkScalar value) {
  38. fWriter.writeScalar(value);
  39. }
  40. void SkBinaryWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) {
  41. fWriter.write32(count);
  42. fWriter.write(value, count * sizeof(SkScalar));
  43. }
  44. void SkBinaryWriteBuffer::writeInt(int32_t value) {
  45. fWriter.write32(value);
  46. }
  47. void SkBinaryWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) {
  48. fWriter.write32(count);
  49. fWriter.write(value, count * sizeof(int32_t));
  50. }
  51. void SkBinaryWriteBuffer::writeUInt(uint32_t value) {
  52. fWriter.write32(value);
  53. }
  54. void SkBinaryWriteBuffer::writeString(const char* value) {
  55. fWriter.writeString(value);
  56. }
  57. void SkBinaryWriteBuffer::writeColor(SkColor color) {
  58. fWriter.write32(color);
  59. }
  60. void SkBinaryWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) {
  61. fWriter.write32(count);
  62. fWriter.write(color, count * sizeof(SkColor));
  63. }
  64. void SkBinaryWriteBuffer::writeColor4f(const SkColor4f& color) {
  65. fWriter.write(&color, sizeof(SkColor4f));
  66. }
  67. void SkBinaryWriteBuffer::writeColor4fArray(const SkColor4f* color, uint32_t count) {
  68. fWriter.write32(count);
  69. fWriter.write(color, count * sizeof(SkColor4f));
  70. }
  71. void SkBinaryWriteBuffer::writePoint(const SkPoint& point) {
  72. fWriter.writeScalar(point.fX);
  73. fWriter.writeScalar(point.fY);
  74. }
  75. void SkBinaryWriteBuffer::writePoint3(const SkPoint3& point) {
  76. this->writePad32(&point, sizeof(SkPoint3));
  77. }
  78. void SkBinaryWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) {
  79. fWriter.write32(count);
  80. fWriter.write(point, count * sizeof(SkPoint));
  81. }
  82. void SkBinaryWriteBuffer::writeMatrix(const SkMatrix& matrix) {
  83. fWriter.writeMatrix(matrix);
  84. }
  85. void SkBinaryWriteBuffer::writeIRect(const SkIRect& rect) {
  86. fWriter.write(&rect, sizeof(SkIRect));
  87. }
  88. void SkBinaryWriteBuffer::writeRect(const SkRect& rect) {
  89. fWriter.writeRect(rect);
  90. }
  91. void SkBinaryWriteBuffer::writeRegion(const SkRegion& region) {
  92. fWriter.writeRegion(region);
  93. }
  94. void SkBinaryWriteBuffer::writePath(const SkPath& path) {
  95. fWriter.writePath(path);
  96. }
  97. size_t SkBinaryWriteBuffer::writeStream(SkStream* stream, size_t length) {
  98. fWriter.write32(SkToU32(length));
  99. size_t bytesWritten = fWriter.readFromStream(stream, length);
  100. if (bytesWritten < length) {
  101. fWriter.reservePad(length - bytesWritten);
  102. }
  103. return bytesWritten;
  104. }
  105. bool SkBinaryWriteBuffer::writeToStream(SkWStream* stream) const {
  106. return fWriter.writeToStream(stream);
  107. }
  108. /* Format:
  109. * (subset) bounds
  110. * size (31bits)
  111. * data [ encoded, with raw width/height ]
  112. */
  113. void SkBinaryWriteBuffer::writeImage(const SkImage* image) {
  114. const SkIRect bounds = SkImage_getSubset(image);
  115. this->writeIRect(bounds);
  116. sk_sp<SkData> data;
  117. if (fProcs.fImageProc) {
  118. data = fProcs.fImageProc(const_cast<SkImage*>(image), fProcs.fImageCtx);
  119. }
  120. if (!data) {
  121. data = image->encodeToData();
  122. }
  123. size_t size = data ? data->size() : 0;
  124. if (!SkTFitsIn<int32_t>(size)) {
  125. size = 0; // too big to store
  126. }
  127. this->write32(SkToS32(size)); // writing 0 signals failure
  128. if (size) {
  129. this->writePad32(data->data(), size);
  130. }
  131. }
  132. void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) {
  133. // Write 32 bits (signed)
  134. // 0 -- default font
  135. // >0 -- index
  136. // <0 -- custom (serial procs)
  137. if (obj == nullptr) {
  138. fWriter.write32(0);
  139. } else if (fProcs.fTypefaceProc) {
  140. auto data = fProcs.fTypefaceProc(obj, fProcs.fTypefaceCtx);
  141. if (data) {
  142. size_t size = data->size();
  143. if (!SkTFitsIn<int32_t>(size)) {
  144. size = 0; // fall back to default font
  145. }
  146. int32_t ssize = SkToS32(size);
  147. fWriter.write32(-ssize); // negative to signal custom
  148. if (size) {
  149. this->writePad32(data->data(), size);
  150. }
  151. return;
  152. }
  153. // no data means fall through for std behavior
  154. }
  155. fWriter.write32(fTFSet ? fTFSet->add(obj) : 0);
  156. }
  157. void SkBinaryWriteBuffer::writePaint(const SkPaint& paint) {
  158. SkPaintPriv::Flatten(paint, *this);
  159. }
  160. void SkBinaryWriteBuffer::setFactoryRecorder(sk_sp<SkFactorySet> rec) {
  161. fFactorySet = std::move(rec);
  162. }
  163. void SkBinaryWriteBuffer::setTypefaceRecorder(sk_sp<SkRefCntSet> rec) {
  164. fTFSet = std::move(rec);
  165. }
  166. void SkBinaryWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
  167. if (nullptr == flattenable) {
  168. this->write32(0);
  169. return;
  170. }
  171. /*
  172. * We can write 1 of 2 versions of the flattenable:
  173. * 1. index into fFactorySet : This assumes the writer will later
  174. * resolve the function-ptrs into strings for its reader. SkPicture
  175. * does exactly this, by writing a table of names (matching the indices)
  176. * up front in its serialized form.
  177. * 2. string name of the flattenable or index into fFlattenableDict: We
  178. * store the string to allow the reader to specify its own factories
  179. * after write time. In order to improve compression, if we have
  180. * already written the string, we write its index instead.
  181. */
  182. SkFlattenable::Factory factory = flattenable->getFactory();
  183. SkASSERT(factory);
  184. if (fFactorySet) {
  185. this->write32(fFactorySet->add(factory));
  186. } else {
  187. if (uint32_t* indexPtr = fFlattenableDict.find(factory)) {
  188. // We will write the index as a 32-bit int. We want the first byte
  189. // that we send to be zero - this will act as a sentinel that we
  190. // have an index (not a string). This means that we will send the
  191. // the index shifted left by 8. The remaining 24-bits should be
  192. // plenty to store the index. Note that this strategy depends on
  193. // being little endian.
  194. SkASSERT(0 == *indexPtr >> 24);
  195. this->write32(*indexPtr << 8);
  196. } else {
  197. const char* name = flattenable->getTypeName();
  198. SkASSERT(name);
  199. // Otherwise write the string. Clients should not use the empty
  200. // string as a name, or we will have a problem.
  201. SkASSERT(0 != strcmp("", name));
  202. this->writeString(name);
  203. // Add key to dictionary.
  204. fFlattenableDict.set(factory, fFlattenableDict.count() + 1);
  205. }
  206. }
  207. // make room for the size of the flattened object
  208. (void)fWriter.reserve(sizeof(uint32_t));
  209. // record the current size, so we can subtract after the object writes.
  210. size_t offset = fWriter.bytesWritten();
  211. // now flatten the object
  212. flattenable->flatten(*this);
  213. size_t objSize = fWriter.bytesWritten() - offset;
  214. // record the obj's size
  215. fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize));
  216. }