1 /*
2  * Copyright 2014 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 "SkLocalMatrixShader.h"
9 
CreateProc(SkReadBuffer & buffer)10 SkFlattenable* SkLocalMatrixShader::CreateProc(SkReadBuffer& buffer) {
11     SkMatrix lm;
12     buffer.readMatrix(&lm);
13     SkAutoTUnref<SkShader> baseShader(buffer.readShader());
14     if (!baseShader) {
15         return nullptr;
16     }
17     return baseShader->newWithLocalMatrix(lm);
18 }
19 
flatten(SkWriteBuffer & buffer) const20 void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const {
21     buffer.writeMatrix(this->getLocalMatrix());
22     buffer.writeFlattenable(fProxyShader.get());
23 }
24 
onCreateContext(const ContextRec & rec,void * storage) const25 SkShader::Context* SkLocalMatrixShader::onCreateContext(const ContextRec& rec,
26                                                         void* storage) const {
27     ContextRec newRec(rec);
28     SkMatrix tmp;
29     if (rec.fLocalMatrix) {
30         tmp.setConcat(*rec.fLocalMatrix, this->getLocalMatrix());
31         newRec.fLocalMatrix = &tmp;
32     } else {
33         newRec.fLocalMatrix = &this->getLocalMatrix();
34     }
35     return fProxyShader->createContext(newRec, storage);
36 }
37 
38 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const39 void SkLocalMatrixShader::toString(SkString* str) const {
40     str->append("SkLocalMatrixShader: (");
41 
42     fProxyShader->toString(str);
43 
44     this->INHERITED::toString(str);
45 
46     str->append(")");
47 }
48 #endif
49 
newWithLocalMatrix(const SkMatrix & localMatrix) const50 SkShader* SkShader::newWithLocalMatrix(const SkMatrix& localMatrix) const {
51     if (localMatrix.isIdentity()) {
52         return SkRef(const_cast<SkShader*>(this));
53     }
54 
55     const SkMatrix* lm = &localMatrix;
56 
57     SkShader* baseShader = const_cast<SkShader*>(this);
58     SkMatrix otherLocalMatrix;
59     SkAutoTUnref<SkShader> proxy(this->refAsALocalMatrixShader(&otherLocalMatrix));
60     if (proxy) {
61         otherLocalMatrix.preConcat(localMatrix);
62         lm = &otherLocalMatrix;
63         baseShader = proxy.get();
64     }
65 
66     return new SkLocalMatrixShader(baseShader, *lm);
67 }
68