1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkWriteBuffer.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkData.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDeduper.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPixelRef.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPtrRecorder.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypeface.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////////////// 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkBinaryWriteBuffer::SkBinaryWriteBuffer() 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fFactorySet(nullptr) 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fTFSet(nullptr) { 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkBinaryWriteBuffer::SkBinaryWriteBuffer(void* storage, size_t storageSize) 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fFactorySet(nullptr) 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fWriter(storage, storageSize) 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fTFSet(nullptr) { 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkBinaryWriteBuffer::~SkBinaryWriteBuffer() { 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSafeUnref(fFactorySet); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSafeUnref(fTFSet); 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeByteArray(const void* data, size_t size) { 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(SkToU32(size)); 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writePad(data, size); 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeBool(bool value) { 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeBool(value); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeScalar(SkScalar value) { 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeScalar(value); 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) { 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(count); 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(value, count * sizeof(SkScalar)); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeInt(int32_t value) { 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(value); 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) { 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(count); 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(value, count * sizeof(int32_t)); 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeUInt(uint32_t value) { 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(value); 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeString(const char* value) { 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeString(value); 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeColor(SkColor color) { 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(color); 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) { 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(count); 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(color, count * sizeof(SkColor)); 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeColor4f(const SkColor4f& color) { 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(&color, sizeof(SkColor4f)); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeColor4fArray(const SkColor4f* color, uint32_t count) { 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(count); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(color, count * sizeof(SkColor4f)); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writePoint(const SkPoint& point) { 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeScalar(point.fX); 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeScalar(point.fY); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) { 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(count); 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(point, count * sizeof(SkPoint)); 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeMatrix(const SkMatrix& matrix) { 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeMatrix(matrix); 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeIRect(const SkIRect& rect) { 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write(&rect, sizeof(SkIRect)); 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeRect(const SkRect& rect) { 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeRect(rect); 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeRegion(const SkRegion& region) { 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writeRegion(region); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writePath(const SkPath& path) { 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.writePath(path); 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsize_t SkBinaryWriteBuffer::writeStream(SkStream* stream, size_t length) { 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(SkToU32(length)); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t bytesWritten = fWriter.readFromStream(stream, length); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (bytesWritten < length) { 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.reservePad(length - bytesWritten); 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return bytesWritten; 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkBinaryWriteBuffer::writeToStream(SkWStream* stream) { 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fWriter.writeToStream(stream); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeImage(const SkImage* image) { 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDeduper) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(fDeduper->findOrDefineImage(const_cast<SkImage*>(image))); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writeInt(image->width()); 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writeInt(image->height()); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto write_data = [this](sk_sp<SkData> data, int sign) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = data ? data->size() : 0; 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!sk_64_isS32(size)) { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size = 0; // too big to store 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size) { 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(SkToS32(size) * sign); 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writePad32(data->data(), size); // does nothing if size == 0 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(0); // origin-x 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(0); // origin-y 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(0); // signal no image 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /* 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * What follows is a 32bit encoded size. 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 0 : failure, nothing else to do 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * <0 : negative (int32_t) of a custom encoded blob using SerialProcs 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * >0 : standard encoded blob size (use MakeFromEncoded) 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkData> data; 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int sign = 1; // +1 signals standard encoder 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fProcs.fImageProc) { 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data = fProcs.fImageProc(const_cast<SkImage*>(image), fProcs.fImageCtx); 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sign = -1; // +1 signals custom encoder 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We check data, since a custom proc can return nullptr, in which case we behave as if 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // there was no custom proc. 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!data) { 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data = image->encodeToData(); 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sign = 1; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot write_data(std::move(data), sign); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) { 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDeduper) { 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(fDeduper->findOrDefineTypeface(obj)); 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Write 32 bits (signed) 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 0 -- default font 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // >0 -- index 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // <0 -- custom (serial procs) 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (obj == nullptr) { 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(0); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (fProcs.fTypefaceProc) { 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto data = fProcs.fTypefaceProc(obj, fProcs.fTypefaceCtx); 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (data) { 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = data->size(); 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!sk_64_isS32(size)) { 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size = 0; // fall back to default font 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int32_t ssize = SkToS32(size); 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(-ssize); // negative to signal custom 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (size) { 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writePad32(data->data(), size); 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // no data means fall through for std behavior 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.write32(fTFSet ? fTFSet->add(obj) : 0); 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writePaint(const SkPaint& paint) { 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.flatten(*this); 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkFactorySet* SkBinaryWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRefCnt_SafeAssign(fFactorySet, rec); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return rec; 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkRefCntSet* SkBinaryWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRefCnt_SafeAssign(fTFSet, rec); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return rec; 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkBinaryWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == flattenable) { 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(0); 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fDeduper) { 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(fDeduper->findOrDefineFactory(const_cast<SkFlattenable*>(flattenable))); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /* 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * We can write 1 of 2 versions of the flattenable: 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 1. index into fFactorySet : This assumes the writer will later 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * resolve the function-ptrs into strings for its reader. SkPicture 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * does exactly this, by writing a table of names (matching the indices) 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * up front in its serialized form. 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 2. string name of the flattenable or index into fFlattenableDict: We 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * store the string to allow the reader to specify its own factories 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * after write time. In order to improve compression, if we have 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * already written the string, we write its index instead. 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fFactorySet) { 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFlattenable::Factory factory = flattenable->getFactory(); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(factory); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(fFactorySet->add(factory)); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const char* name = flattenable->getTypeName(); 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(name); 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkString key(name); 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (uint32_t* indexPtr = fFlattenableDict.find(key)) { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We will write the index as a 32-bit int. We want the first byte 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // that we send to be zero - this will act as a sentinel that we 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // have an index (not a string). This means that we will send the 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the index shifted left by 8. The remaining 24-bits should be 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // plenty to store the index. Note that this strategy depends on 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // being little endian. 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(0 == *indexPtr >> 24); 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->write32(*indexPtr << 8); 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Otherwise write the string. Clients should not use the empty 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // string as a name, or we will have a problem. 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(strcmp("", name)); 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->writeString(name); 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Add key to dictionary. 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFlattenableDict.set(key, fFlattenableDict.count() + 1); 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // make room for the size of the flattened object 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (void)fWriter.reserve(sizeof(uint32_t)); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // record the current size, so we can subtract after the object writes. 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t offset = fWriter.bytesWritten(); 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // now flatten the object 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot flattenable->flatten(*this); 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t objSize = fWriter.bytesWritten() - offset; 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // record the obj's size 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 282