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