#endif
}
+///////////////////////////////////////////////////////////////////////////////
+
+static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) {
+ sk_bzero(dst, 16 * sizeof(SkMScalar));
+ dst[0][0] = src[SkMatrix::kMScaleX];
+ dst[1][0] = src[SkMatrix::kMSkewX];
+ dst[3][0] = src[SkMatrix::kMTransX];
+ dst[0][1] = src[SkMatrix::kMSkewY];
+ dst[1][1] = src[SkMatrix::kMScaleY];
+ dst[3][1] = src[SkMatrix::kMTransY];
+ dst[2][2] = dst[3][3] = 1;
+}
+
+SkMatrix44::SkMatrix44(const SkMatrix& src) {
+ initFromMatrix(fMat, src);
+}
+
+SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
+ initFromMatrix(fMat, src);
+ return *this;
+}
+
+SkMatrix44::operator SkMatrix() const {
+ SkMatrix dst;
+ dst.reset(); // setup our perspective correctly for identity
+
+ dst[SkMatrix::kMScaleX] = SkMScalarToFloat(fMat[0][0]);
+ dst[SkMatrix::kMSkewX] = SkMScalarToFloat(fMat[1][0]);
+ dst[SkMatrix::kMTransX] = SkMScalarToFloat(fMat[3][0]);
+
+ dst[SkMatrix::kMSkewY] = SkMScalarToFloat(fMat[0][1]);
+ dst[SkMatrix::kMScaleY] = SkMScalarToFloat(fMat[1][1]);
+ dst[SkMatrix::kMTransY] = SkMScalarToFloat(fMat[3][1]);
+
+ return dst;
+}
+
+
#ifndef SkMatrix44_DEFINED
#define SkMatrix44_DEFINED
+#include "SkMatrix.h"
#include "SkScalar.h"
// uncomment this to use doubles for matrix44
SkMatrix44(const SkMatrix44&);
SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
+ SkMatrix44& operator=(const SkMatrix44& src) {
+ memcpy(this, &src, sizeof(*this));
+ return *this;
+ }
+
bool operator==(const SkMatrix44& other) const {
return !memcmp(this, &other, sizeof(*this));
}
bool operator!=(const SkMatrix44& other) const {
return !!memcmp(this, &other, sizeof(*this));
}
-
+
+ SkMatrix44(const SkMatrix&);
+ SkMatrix44& operator=(const SkMatrix& src);
+ operator SkMatrix() const;
+
bool isIdentity() const;
void setIdentity();
void reset() { this->setIdentity(); }
#include "SkTypes.h"
#include "SkRefCnt.h"
+#include "SkPoint.h"
+struct SkGlyph;
struct SkIRect;
struct SkPoint;
struct SkRect;
Returns the result from onIRect.
*/
bool doIRect(const SkIRect&);
- bool doIRect(const SkIRect& , uint16_t glyphID);
+ bool doIRectGlyph(const SkIRect& , int x, int y, const SkGlyph&);
+
protected:
/** Override in your subclass. This is called with the device bounds of an
object (text, geometry, image) just before it is drawn. If your method
return false;
}
+ /** Passed to onIRectGlyph with the information about the current glyph.
+ LSB and RSB are fixed-point (16.16) coordinates of the start and end
+ of the glyph's advance
+ */
+ struct GlyphRec {
+ SkIPoint fLSB; //!< fixed-point left-side-bearing of the glyph
+ SkIPoint fRSB; //!< fixed-point right-side-bearing of the glyph
+ uint16_t fGlyphID;
+ uint16_t fFlags; //!< currently set to 0
+ };
+
/** Optionally, override in your subclass to receive the glyph ID when
text drawing supplies the device bounds of the object.
*/
- virtual bool onIRect(const SkIRect& r, uint16_t glyphID) {
+ virtual bool onIRectGlyph(const SkIRect& r, const GlyphRec&) {
return onIRect(r);
}
SkScalar getPerspX() const { return fMat[kMPersp0]; }
SkScalar getPerspY() const { return fMat[kMPersp1]; }
+ SkScalar& operator[](int index) {
+ SkASSERT((unsigned)index < 9);
+ this->setTypeMask(kUnknown_Mask);
+ return fMat[index];
+ }
+
void set(int index, SkScalar value) {
SkASSERT((unsigned)index < 9);
fMat[index] = value;
return;
}
}
-
- if (state.fBounder->doIRect(cr, glyph.getGlyphID())) {
+
+ // we need to pass the origin, which we approximate with our
+ // (unadjusted) left,top coordinates (the caller called fixedfloor)
+ if (state.fBounder->doIRectGlyph(cr,
+ left - glyph.fLeft,
+ top - glyph.fTop, glyph)) {
mask.fRowBytes = glyph.rowBytes();
mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
mask.fImage = (uint8_t*)aa;
return rr.intersect(fClip->getBounds(), r) && this->onIRect(rr);
}
-bool SkBounder::doIRect(const SkIRect& r, uint16_t glyphID) {
+// TODO: change the prototype to take fixed, and update the callers
+bool SkBounder::doIRectGlyph(const SkIRect& r, int x, int y,
+ const SkGlyph& glyph) {
SkIRect rr;
- return rr.intersect(fClip->getBounds(), r) && this->onIRect(rr, glyphID);
+ if (!rr.intersect(fClip->getBounds(), r)) {
+ return false;
+ }
+ GlyphRec rec;
+ rec.fLSB.set(SkIntToFixed(x), SkIntToFixed(y));
+ rec.fRSB.set(rec.fLSB.fX + glyph.fAdvanceX,
+ rec.fLSB.fY + glyph.fAdvanceY);
+ rec.fGlyphID = glyph.getGlyphID();
+ rec.fFlags = 0;
+ return this->onIRectGlyph(rr, rec);
}
bool SkBounder::doHairline(const SkPoint& pt0, const SkPoint& pt1,