convert matrix <--> matrix44
authorreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 1 Mar 2010 14:54:05 +0000 (14:54 +0000)
committerreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 1 Mar 2010 14:54:05 +0000 (14:54 +0000)
add glyphrec to bounder

git-svn-id: http://skia.googlecode.com/svn/trunk@516 2bbb7eff-a529-9590-31e7-b0007b416f81

experimental/SkMatrix44.cpp
experimental/SkMatrix44.h
include/core/SkBounder.h
include/core/SkMatrix.h
src/core/SkDraw.cpp

index b2b8c30..841eec2 100644 (file)
@@ -269,4 +269,42 @@ void SkMatrix44::dump() const {
 #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;
+}
+
+
 
index f865590..b0e7148 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SkMatrix44_DEFINED
 #define SkMatrix44_DEFINED
 
+#include "SkMatrix.h"
 #include "SkScalar.h"
 
 // uncomment this to use doubles for matrix44
@@ -89,13 +90,22 @@ public:
        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(); }
index 00fbbc6..bda5c97 100644 (file)
@@ -19,7 +19,9 @@
 
 #include "SkTypes.h"
 #include "SkRefCnt.h"
+#include "SkPoint.h"
 
+struct SkGlyph;
 struct SkIRect;
 struct SkPoint;
 struct SkRect;
@@ -38,7 +40,8 @@ public:
        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
@@ -50,10 +53,21 @@ protected:
         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);
     }
 
index 741c349..7ef7d8c 100644 (file)
@@ -102,6 +102,12 @@ public:
     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;
index 8bf4c08..f112d4b 100644 (file)
@@ -1370,8 +1370,12 @@ static void D1G_Bounder(const SkDraw1Glyph& state,
                                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;
@@ -2249,9 +2253,20 @@ bool SkBounder::doIRect(const SkIRect& r) {
     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,