1 /* 2 * Copyright 2020 Google LLC 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 #ifndef SkMatrixProvider_DEFINED 9 #define SkMatrixProvider_DEFINED 10 11 #include "include/core/SkM44.h" 12 #include "include/core/SkMatrix.h" 13 14 class SkMatrixProvider { 15 public: SkMatrixProvider(const SkMatrix & localToDevice)16 SkMatrixProvider(const SkMatrix& localToDevice) 17 : fLocalToDevice(localToDevice) 18 , fLocalToDevice33(localToDevice) {} 19 SkMatrixProvider(const SkM44 & localToDevice)20 SkMatrixProvider(const SkM44& localToDevice) 21 : fLocalToDevice(localToDevice) 22 , fLocalToDevice33(localToDevice.asM33()) {} 23 24 // Required until C++17 copy elision 25 SkMatrixProvider(const SkMatrixProvider&) = default; 26 ~SkMatrixProvider()27 virtual ~SkMatrixProvider() {} 28 29 // These should return the "same" matrix, as either a 3x3 or 4x4. Most sites in Skia still 30 // call localToDevice, and operate on SkMatrix. localToDevice()31 const SkMatrix& localToDevice() const { return fLocalToDevice33; } localToDevice44()32 const SkM44& localToDevice44() const { return fLocalToDevice; } 33 34 virtual bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const = 0; 35 36 virtual bool localToDeviceHitsPixelCenters() const = 0; 37 38 private: 39 friend class SkBaseDevice; 40 41 SkM44 fLocalToDevice; 42 SkMatrix fLocalToDevice33; // Cached SkMatrix version of above, for legacy usage 43 }; 44 45 class SkOverrideDeviceMatrixProvider : public SkMatrixProvider { 46 public: SkOverrideDeviceMatrixProvider(const SkMatrixProvider & parent,const SkMatrix & localToDevice)47 SkOverrideDeviceMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& localToDevice) 48 : SkMatrixProvider(localToDevice) 49 , fParent(parent) {} 50 getLocalToMarker(uint32_t id,SkM44 * localToMarker)51 bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override { 52 return fParent.getLocalToMarker(id, localToMarker); 53 } 54 55 // We've replaced parent's localToDevice matrix, 56 // so we can't guarantee localToDevice() hits pixel centers anymore. localToDeviceHitsPixelCenters()57 bool localToDeviceHitsPixelCenters() const override { return false; } 58 59 private: 60 const SkMatrixProvider& fParent; 61 }; 62 63 class SkPostTranslateMatrixProvider : public SkMatrixProvider { 64 public: SkPostTranslateMatrixProvider(const SkMatrixProvider & parent,SkScalar dx,SkScalar dy)65 SkPostTranslateMatrixProvider(const SkMatrixProvider& parent, SkScalar dx, SkScalar dy) 66 : SkMatrixProvider(SkM44::Translate(dx, dy) * parent.localToDevice44()) 67 , fParent(parent) {} 68 69 // Assume that the post-translation doesn't apply to any marked matrices getLocalToMarker(uint32_t id,SkM44 * localToMarker)70 bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override { 71 return fParent.getLocalToMarker(id, localToMarker); 72 } 73 74 // parent.localToDevice() is folded into our localToDevice(). localToDeviceHitsPixelCenters()75 bool localToDeviceHitsPixelCenters() const override { return true; } 76 77 private: 78 const SkMatrixProvider& fParent; 79 }; 80 81 class SkPreConcatMatrixProvider : public SkMatrixProvider { 82 public: SkPreConcatMatrixProvider(const SkMatrixProvider & parent,const SkMatrix & preMatrix)83 SkPreConcatMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& preMatrix) 84 : SkMatrixProvider(parent.localToDevice44() * SkM44(preMatrix)) 85 , fParent(parent) 86 , fPreMatrix(preMatrix) {} 87 getLocalToMarker(uint32_t id,SkM44 * localToMarker)88 bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override { 89 if (fParent.getLocalToMarker(id, localToMarker)) { 90 if (localToMarker) { 91 localToMarker->preConcat(fPreMatrix); 92 } 93 return true; 94 } 95 return false; 96 } 97 98 // parent.localToDevice() is folded into our localToDevice(). localToDeviceHitsPixelCenters()99 bool localToDeviceHitsPixelCenters() const override { return true; } 100 101 private: 102 const SkMatrixProvider& fParent; 103 const SkMatrix fPreMatrix; 104 }; 105 106 class SkSimpleMatrixProvider : public SkMatrixProvider { 107 public: SkSimpleMatrixProvider(const SkMatrix & localToDevice)108 SkSimpleMatrixProvider(const SkMatrix& localToDevice) 109 : SkMatrixProvider(localToDevice) {} 110 getLocalToMarker(uint32_t,SkM44 *)111 bool getLocalToMarker(uint32_t, SkM44*) const override { return false; } 112 113 // No trickiness to reason about here... we take this case to be axiomatically true. localToDeviceHitsPixelCenters()114 bool localToDeviceHitsPixelCenters() const override { return true; } 115 }; 116 117 #endif 118