• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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