SkLocalMatrixShader.cpp revision 96fb7489ba46909c3f81bb2d94755e7d4ccb5fad
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 "SkShader.h" 9#include "SkReadBuffer.h" 10#include "SkWriteBuffer.h" 11 12class SkLocalMatrixShader : public SkShader { 13public: 14 SkLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix) 15 : fProxyShader(SkRef(proxy)) 16 , fProxyLocalMatrix(localMatrix) 17 {} 18 19 virtual size_t contextSize() const SK_OVERRIDE { 20 return fProxyShader->contextSize(); 21 } 22 23 virtual BitmapType asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 24 TileMode* mode) const SK_OVERRIDE { 25 return fProxyShader->asABitmap(bitmap, matrix, mode); 26 } 27 28 virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE { 29 return fProxyShader->asAGradient(info); 30 } 31 32 // TODO: need to augment this API to pass in a localmatrix (which we can augment) 33 virtual GrEffectRef* asNewEffect(GrContext* ctx, const SkPaint& paint, 34 const SkMatrix* localMatrix) const SK_OVERRIDE { 35 SkMatrix tmp = fProxyLocalMatrix; 36 if (localMatrix) { 37 tmp.preConcat(*localMatrix); 38 } 39 return fProxyShader->asNewEffect(ctx, paint, &tmp); 40 } 41 42 virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const SK_OVERRIDE { 43 if (localMatrix) { 44 *localMatrix = fProxyLocalMatrix; 45 } 46 return SkRef(fProxyShader.get()); 47 } 48 49 SK_TO_STRING_OVERRIDE() 50 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixShader) 51 52protected: 53 SkLocalMatrixShader(SkReadBuffer&); 54 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 55 virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE; 56 57private: 58 SkAutoTUnref<SkShader> fProxyShader; 59 SkMatrix fProxyLocalMatrix; 60 61 typedef SkShader INHERITED; 62}; 63 64SkLocalMatrixShader::SkLocalMatrixShader(SkReadBuffer& buffer) : INHERITED(buffer) { 65 buffer.readMatrix(&fProxyLocalMatrix); 66 fProxyShader.reset(buffer.readFlattenable<SkShader>()); 67 if (NULL == fProxyShader.get()) { 68 sk_throw(); 69 } 70} 71 72void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const { 73 this->INHERITED::flatten(buffer); 74 buffer.writeMatrix(fProxyLocalMatrix); 75 buffer.writeFlattenable(fProxyShader.get()); 76} 77 78SkShader::Context* SkLocalMatrixShader::onCreateContext(const ContextRec& rec, 79 void* storage) const { 80 ContextRec newRec(rec); 81 SkMatrix tmp; 82 if (rec.fLocalMatrix) { 83 tmp.setConcat(fProxyLocalMatrix, *rec.fLocalMatrix); 84 newRec.fLocalMatrix = &tmp; 85 } else { 86 newRec.fLocalMatrix = &fProxyLocalMatrix; 87 } 88 return fProxyShader->createContext(newRec, storage); 89} 90 91#ifndef SK_IGNORE_TO_STRING 92void SkLocalMatrixShader::toString(SkString* str) const { 93 str->append("SkLocalMatrixShader: ("); 94 95 fProxyShader->toString(str); 96 97 this->INHERITED::toString(str); 98 99 str->append(")"); 100} 101#endif 102 103SkShader* SkShader::CreateLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix) { 104 if (localMatrix.isIdentity()) { 105 return SkRef(proxy); 106 } 107 108 const SkMatrix* lm = &localMatrix; 109 110 SkMatrix otherLocalMatrix; 111 SkAutoTUnref<SkShader> otherProxy(proxy->refAsALocalMatrixShader(&otherLocalMatrix)); 112 if (otherProxy.get()) { 113 otherLocalMatrix.preConcat(localMatrix); 114 lm = &otherLocalMatrix; 115 proxy = otherProxy.get(); 116 } 117 118 return SkNEW_ARGS(SkLocalMatrixShader, (proxy, *lm)); 119} 120