blob: 6b9633f4127e1760ab7fc855da6b3d4ae8eeec9c [file] [log] [blame]
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkMatrixProvider_DEFINED
#define SkMatrixProvider_DEFINED
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
class SkMatrixProvider {
public:
SkMatrixProvider(const SkMatrix& localToDevice)
: fLocalToDevice(localToDevice)
, fLocalToDevice33(localToDevice) {}
SkMatrixProvider(const SkM44& localToDevice)
: fLocalToDevice(localToDevice)
, fLocalToDevice33(localToDevice.asM33()) {}
virtual ~SkMatrixProvider() {}
// These should return the "same" matrix, as either a 3x3 or 4x4. Most sites in Skia still
// call localToDevice, and operate on SkMatrix.
const SkMatrix& localToDevice() const { return fLocalToDevice33; }
const SkM44& localToDevice44() const { return fLocalToDevice; }
virtual bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const = 0;
virtual bool localToDeviceHitsPixelCenters() const = 0;
private:
friend class SkBaseDevice;
SkM44 fLocalToDevice;
SkMatrix fLocalToDevice33; // Cached SkMatrix version of above, for legacy usage
};
class SkOverrideDeviceMatrixProvider : public SkMatrixProvider {
public:
SkOverrideDeviceMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& localToDevice)
: SkMatrixProvider(localToDevice)
, fParent(parent) {}
bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override {
return fParent.getLocalToMarker(id, localToMarker);
}
// We've replaced parent's localToDevice matrix,
// so we can't guarantee localToDevice() hits pixel centers anymore.
bool localToDeviceHitsPixelCenters() const override { return false; }
private:
const SkMatrixProvider& fParent;
};
class SkPostTranslateMatrixProvider : public SkMatrixProvider {
public:
SkPostTranslateMatrixProvider(const SkMatrixProvider& parent, SkScalar dx, SkScalar dy)
: SkMatrixProvider(SkM44::Translate(dx, dy) * parent.localToDevice44())
, fParent(parent) {}
// Assume that the post-translation doesn't apply to any marked matrices
bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override {
return fParent.getLocalToMarker(id, localToMarker);
}
// parent.localToDevice() is folded into our localToDevice().
bool localToDeviceHitsPixelCenters() const override { return true; }
private:
const SkMatrixProvider& fParent;
};
class SkPreConcatMatrixProvider : public SkMatrixProvider {
public:
SkPreConcatMatrixProvider(const SkMatrixProvider& parent, const SkMatrix& preMatrix)
: SkMatrixProvider(parent.localToDevice44() * SkM44(preMatrix))
, fParent(parent)
, fPreMatrix(preMatrix) {}
bool getLocalToMarker(uint32_t id, SkM44* localToMarker) const override {
if (fParent.getLocalToMarker(id, localToMarker)) {
if (localToMarker) {
localToMarker->preConcat(fPreMatrix);
}
return true;
}
return false;
}
// parent.localToDevice() is folded into our localToDevice().
bool localToDeviceHitsPixelCenters() const override { return true; }
private:
const SkMatrixProvider& fParent;
const SkMatrix fPreMatrix;
};
class SkSimpleMatrixProvider : public SkMatrixProvider {
public:
SkSimpleMatrixProvider(const SkMatrix& localToDevice)
: SkMatrixProvider(localToDevice) {}
bool getLocalToMarker(uint32_t, SkM44*) const override { return false; }
// No trickiness to reason about here... we take this case to be axiomatically true.
bool localToDeviceHitsPixelCenters() const override { return true; }
};
#endif