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
8#include "src/core/SkAutoMalloc.h"
9#include "src/core/SkCanvasPriv.h"
10#include "src/core/SkReadBuffer.h"
11#include "src/core/SkWriter32.h"
12
13#include <locale>
14
15SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix,
16 const SkPaint* paint, const SkRect& bounds)
17: fCanvas(canvas)
18, fSaveCount(canvas->getSaveCount())
19{
20 if (paint) {
21 SkRect newBounds = bounds;
22 if (matrix) {
23 matrix->mapRect(&newBounds);
24 }
25 canvas->saveLayer(&newBounds, paint);
26 } else if (matrix) {
27 canvas->save();
28 }
29
30 if (matrix) {
31 canvas->concat(*matrix);
32 }
33}
34
35SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
36 fCanvas->restoreToCount(fSaveCount);
37}
38
39///////////////////////////////////////////////////////////////////////////////////////////////////
40
41bool SkCanvasPriv::ReadLattice(SkReadBuffer& buffer, SkCanvas::Lattice* lattice) {
42 lattice->fXCount = buffer.readInt();
43 lattice->fXDivs = buffer.skipT<int32_t>(lattice->fXCount);
44 lattice->fYCount = buffer.readInt();
45 lattice->fYDivs = buffer.skipT<int32_t>(lattice->fYCount);
46 int flagCount = buffer.readInt();
47 lattice->fRectTypes = nullptr;
48 lattice->fColors = nullptr;
49 if (flagCount) {
50 lattice->fRectTypes = buffer.skipT<SkCanvas::Lattice::RectType>(flagCount);
51 lattice->fColors = buffer.skipT<SkColor>(flagCount);
52 }
53 lattice->fBounds = buffer.skipT<SkIRect>();
54 return buffer.isValid();
55}
56
57size_t SkCanvasPriv::WriteLattice(void* buffer, const SkCanvas::Lattice& lattice) {
58 int flagCount = lattice.fRectTypes ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0;
59
60 const size_t size = (1 + lattice.fXCount + 1 + lattice.fYCount + 1) * sizeof(int32_t) +
61 SkAlign4(flagCount * sizeof(SkCanvas::Lattice::RectType)) +
62 SkAlign4(flagCount * sizeof(SkColor)) +
63 sizeof(SkIRect);
64
65 if (buffer) {
66 SkWriter32 writer(buffer, size);
67 writer.write32(lattice.fXCount);
68 writer.write(lattice.fXDivs, lattice.fXCount * sizeof(uint32_t));
69 writer.write32(lattice.fYCount);
70 writer.write(lattice.fYDivs, lattice.fYCount * sizeof(uint32_t));
71 writer.write32(flagCount);
72 writer.writePad(lattice.fRectTypes, flagCount * sizeof(uint8_t));
73 writer.write(lattice.fColors, flagCount * sizeof(SkColor));
74 SkASSERT(lattice.fBounds);
75 writer.write(lattice.fBounds, sizeof(SkIRect));
76 SkASSERT(writer.bytesWritten() == size);
77 }
78 return size;
79};
80
81void SkCanvasPriv::WriteLattice(SkWriteBuffer& buffer, const SkCanvas::Lattice& lattice) {
82 const size_t size = WriteLattice(nullptr, lattice);
83 SkAutoSMalloc<1024> storage(size);
84 WriteLattice(storage.get(), lattice);
85 buffer.writePad32(storage.get(), size);
86}
87
88void SkCanvasPriv::GetDstClipAndMatrixCounts(const SkCanvas::ImageSetEntry set[], int count,
89 int* totalDstClipCount, int* totalMatrixCount) {
90 int dstClipCount = 0;
91 int maxMatrixIndex = -1;
92 for (int i = 0; i < count; ++i) {
93 dstClipCount += 4 * set[i].fHasClip;
94 if (set[i].fMatrixIndex > maxMatrixIndex) {
95 maxMatrixIndex = set[i].fMatrixIndex;
96 }
97 }
98
99 *totalDstClipCount = dstClipCount;
100 *totalMatrixCount = maxMatrixIndex + 1;
101}
102
103bool SkCanvasPriv::ValidateMarker(const char* name) {
104 if (!name) {
105 return false;
106 }
107
108 std::locale loc(std::locale::classic());
109 if (!std::isalpha(*name, loc)) {
110 return false;
111 }
112 while (*(++name)) {
113 if (!std::isalnum(*name, loc) && *name != '_') {
114 return false;
115 }
116 }
117 return true;
118}
119