add template macro to "safely" perform casts w/o breaking strict-aliasing
fix aliasing warnings



git-svn-id: http://skia.googlecode.com/svn/trunk@674 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/Makefile b/Makefile
index 5829d07..4afa0df 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 GPP := g++
 C_INCLUDES := -Iinclude/config -Iinclude/core -Iinclude/effects -Iinclude/images -Iinclude/gpu -Iinclude/utils -Igpu/include
 
-CFLAGS := -Wall -O2 
+CFLAGS := -Wall -O2 -fstrict-aliasing
 CFLAGS_SSE2 = $(CFLAGS) -msse2
 LINKER_OPTS := -lpthread -lz
 DEFINES := -DSK_CAN_USE_FLOAT
@@ -126,7 +126,7 @@
 	@mkdir -p $(dir $@)
 	$(HIDE)$(CC) $(C_INCLUDES) $(CFLAGS) $(DEFINES) -c $< -o $@
 	@echo "compiling $@"
-    
+
 %.s : %.cpp
 	@mkdir -p $(dir $@)
 	$(CC) $(C_INCLUDES) $(CFLAGS) $(DEFINES) -S -c $< -o $@
@@ -163,7 +163,7 @@
 bench: $(BENCH_OBJS) out/libskia.a
 	@echo "linking bench..."
 	$(HIDE)$(GPP) $(BENCH_OBJS) out/libskia.a -o out/bench/bench $(LINKER_OPTS)
-	
+
 ##############################################################################
 
 # we let tests cheat and see private headers, so we can unittest modules
@@ -181,7 +181,7 @@
 tests: $(TESTS_OBJS) out/libskia.a
 	@echo "linking tests..."
 	$(HIDE)$(GPP) $(TESTS_OBJS) out/libskia.a -o out/tests/tests $(LINKER_OPTS)
-	
+
 ##############################################################################
 
 SKIMAGE_SRCS := skimage_main.cpp
diff --git a/bench/RectBench.cpp b/bench/RectBench.cpp
index 3874bb3..0c3eb56 100644
--- a/bench/RectBench.cpp
+++ b/bench/RectBench.cpp
@@ -31,14 +31,14 @@
             fColors[i] = rand.nextU() | 0xFF808080;
         }
     }
-    
+
     SkString fName;
     const char* computeName(const char root[]) {
         fName.set(root);
         fName.appendS32(fShift);
         return fName.c_str();
     }
-        
+
 protected:
     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
         c->drawRect(r, p);
@@ -82,7 +82,7 @@
     SkCanvas::PointMode fMode;
     const char* fName;
 
-    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) : 
+    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) :
         RectBench(param, 2), fMode(mode) {
         fName = name;
     }
@@ -105,8 +105,7 @@
         for (size_t i = 0; i < sizes; i++) {
             paint.setStrokeWidth(gSizes[i]);
             this->setupPaint(&paint);
-            canvas->drawPoints(fMode, N * 2,
-                               reinterpret_cast<const SkPoint*>(fRects), paint);
+            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
             paint.setColor(fColors[i]);
         }
     }
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index a491295..a799c2e 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -126,7 +126,21 @@
 
 #endif
 
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Use to cast a pointer to a different type, and maintaining strict-aliasing
+ */
+template <typename Dst> Dst GrTCast(const void* ptr) {
+    union {
+        const void* src;
+        Dst dst;
+    } data;
+    data.src = ptr;
+    return data.dst;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 /**
  * Type used to describe format of vertices in arrays
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index de4010f..87d69bc 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -533,13 +533,13 @@
 #if GR_COLLECT_STATS
     ++fStats.fTextureCreateCnt;
 #endif
-    
+
     static const GrGLTexture::TexParams DEFAULT_PARAMS = {
         GL_NEAREST,
         GL_CLAMP_TO_EDGE,
         GL_CLAMP_TO_EDGE
     };
-    
+
     GrGLTexture::GLTextureDesc glDesc;
     GLenum internalFormat;
 
@@ -614,17 +614,17 @@
     }
 
     GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
-    GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                        GL_TEXTURE_MAG_FILTER, 
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_MAG_FILTER,
                         DEFAULT_PARAMS.fFilter));
-    GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                        GL_TEXTURE_MIN_FILTER, 
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_MIN_FILTER,
                         DEFAULT_PARAMS.fFilter));
-    GR_GL(TexParameteri(GL_TEXTURE_2D, 
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
                         GL_TEXTURE_WRAP_S,
                         DEFAULT_PARAMS.fWrapS));
-    GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                        GL_TEXTURE_WRAP_T, 
+    GR_GL(TexParameteri(GL_TEXTURE_2D,
+                        GL_TEXTURE_WRAP_T,
                         DEFAULT_PARAMS.fWrapT));
 #if GR_COLLECT_STATS
     ++fStats.fTextureChngCnt;
@@ -1443,28 +1443,28 @@
 
             const GrGLTexture::TexParams& oldTexParams = nextTexture->getTexParams();
             GrGLTexture::TexParams newTexParams;
-            newTexParams.fFilter = fCurrDrawState.fSamplerState.isFilter() ? 
+            newTexParams.fFilter = fCurrDrawState.fSamplerState.isFilter() ?
                                                                 GL_LINEAR :
                                                                 GL_NEAREST;
             newTexParams.fWrapS = GrGLTexture::gWrapMode2GLWrap[fCurrDrawState.fSamplerState.getWrapX()];
             newTexParams.fWrapT = GrGLTexture::gWrapMode2GLWrap[fCurrDrawState.fSamplerState.getWrapY()];
 
             if (newTexParams.fFilter != oldTexParams.fFilter) {
-                GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                                    GL_TEXTURE_MAG_FILTER, 
+                GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                    GL_TEXTURE_MAG_FILTER,
                                     newTexParams.fFilter));
-                GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                                    GL_TEXTURE_MIN_FILTER, 
+                GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                    GL_TEXTURE_MIN_FILTER,
                                     newTexParams.fFilter));
             }
             if (newTexParams.fWrapS != oldTexParams.fWrapS) {
-                GR_GL(TexParameteri(GL_TEXTURE_2D, 
+                GR_GL(TexParameteri(GL_TEXTURE_2D,
                                     GL_TEXTURE_WRAP_S,
                                     newTexParams.fWrapS));
             }
             if (newTexParams.fWrapT != oldTexParams.fWrapT) {
-                GR_GL(TexParameteri(GL_TEXTURE_2D, 
-                                    GL_TEXTURE_WRAP_T, 
+                GR_GL(TexParameteri(GL_TEXTURE_2D,
+                                    GL_TEXTURE_WRAP_T,
                                     newTexParams.fWrapT));
             }
             nextTexture->setTexParams(newTexParams);
@@ -1594,7 +1594,7 @@
     // b) we set more state than just FBO based on the RT
     // So trash the HW state to force an RT flush next time
     if (fCurrDrawState.fRenderTarget == renderTarget) {
-        fCurrDrawState.fRenderTarget = (GrRenderTarget*)&fDefaultRenderTarget;
+        fCurrDrawState.fRenderTarget = fDefaultRenderTarget;
     }
     if (fHWDrawState.fRenderTarget == renderTarget) {
         fHWDrawState.fRenderTarget = NULL;
diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp
index e4360cd..516f542 100644
--- a/gpu/src/GrMatrix.cpp
+++ b/gpu/src/GrMatrix.cpp
@@ -1,19 +1,19 @@
-/*
-    Copyright 2010 Google Inc.
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
- */
-
+/*

+    Copyright 2010 Google Inc.

+

+    Licensed under the Apache License, Version 2.0 (the "License");

+    you may not use this file except in compliance with the License.

+    You may obtain a copy of the License at

+

+         http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing, software

+    distributed under the License is distributed on an "AS IS" BASIS,

+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+    See the License for the specific language governing permissions and

+    limitations under the License.

+ */

+

 

 #include "GrMatrix.h"

 #include "GrRect.h"

@@ -47,7 +47,7 @@
     &GrMatrix::mapPerspective,

     &GrMatrix::mapPerspective,

     &GrMatrix::mapPerspective,

-    

+

 // Scales are zero (every other is invalid because kScale_TypeBit must be set if

 // kZeroScale_TypeBit is set)

     &GrMatrix::mapInvalid,

@@ -58,7 +58,7 @@
     &GrMatrix::mapSwappedScale,

     &GrMatrix::mapInvalid,

     &GrMatrix::mapSwappedScaleAndTranslate,

-    

+

     // no optimizations for perspective matrices

     &GrMatrix::mapInvalid,

     &GrMatrix::mapZero,

@@ -71,29 +71,19 @@
 };

 

 const GrMatrix& GrMatrix::I() {

-    struct FakeMatrix {

-        int fTypeMask;

-        GrScalar fM[9];

-    };

-

-#if 0

-    GR_STATIC_ASSERT(offsetof(FakeMatrix, fTypeMask) == offsetof(GrMatrix, fTypeMask));

-    GR_STATIC_ASSERT(offsetof(FakeMatrix, fM) == offsetof(GrMatrix, fM));

-#endif

-

-    GR_STATIC_ASSERT(sizeof(FakeMatrix) == sizeof(GrMatrix));

-    static const FakeMatrix I = {0,

-                                 {GR_Scalar1, 0,          0,

-                                  0,          GR_Scalar1, 0,

-                                  0,          0,          gRESCALE}};

-    return *(const GrMatrix*)&I;

+    static GrMatrix* gIdent;

+    if (NULL == gIdent) {

+        gIdent = new GrMatrix;

+        gIdent->setIdentity();

+    }

+    return *gIdent;

 }

 

 void GrMatrix::setIdentity() {

     fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = 0;

     fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = 0;

     fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;

-    fTypeMask = 0; 

+    fTypeMask = 0;

 }

 

 void GrMatrix::setTranslate(GrScalar dx, GrScalar dy) {

@@ -127,7 +117,7 @@
         }

         return;

     }

-    

+

     if (b.isIdentity()) {

         GrAssert(!a.isIdentity());

         if (this != &a) {

@@ -138,10 +128,10 @@
         }

         return;

     }

-    

+

     // a and/or b could be this

     GrMatrix tmp;

-    

+

     // could do more optimizations based on type bits. Hopefully this call is

     // low frequency.

     // TODO: make this work for fixed point

@@ -149,14 +139,14 @@
         tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3];

         tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4];

         tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * gRESCALE;

-        

+

         tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3];

         tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4];

         tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * gRESCALE;

-   

+

         tmp.fM[6] = 0;

         tmp.fM[7] = 0;

-        tmp.fM[8] = gRESCALE * gRESCALE; 

+        tmp.fM[8] = gRESCALE * gRESCALE;

     } else {

         tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3] + a.fM[2] * b.fM[6];

         tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4] + a.fM[2] * b.fM[7];

@@ -184,17 +174,17 @@
 

 double GrMatrix::determinant() const {

     if (fTypeMask & kPerspective_TypeBit) {

-        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) + 

-                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) + 

+        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) +

+                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) +

                 fM[2]*((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);

     } else {

-        return (double)fM[0]*fM[4]*gRESCALE - 

+        return (double)fM[0]*fM[4]*gRESCALE -

                (double)fM[1]*fM[3]*gRESCALE;

     }

 }

 

 bool GrMatrix::invert(GrMatrix* inverted) const {

-    

+

     if (isIdentity()) {

         if (inverted != this) {

             inverted->setIdentity();

@@ -202,10 +192,10 @@
         return true;

     }

     static const double MIN_DETERMINANT_SQUARED = 1.e-16;

-    

+

     // could do more optimizations based on type bits. Hopefully this call is

     // low frequency.

-    

+

     double det = determinant();

 

     // check if we can't be inverted

@@ -216,9 +206,9 @@
     }

 

     double t[9];

-    

+

     if (fTypeMask & kPerspective_TypeBit) {

-        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]); 

+        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]);

         t[1] = ((double)fM[2]*fM[7] - (double)fM[1]*fM[8]);

         t[2] = ((double)fM[1]*fM[5] - (double)fM[2]*fM[4]);

         t[3] = ((double)fM[5]*fM[6] - (double)fM[3]*fM[8]);

@@ -232,7 +222,7 @@
             inverted->fM[i] = (GrScalar)(t[i] * det);

         }

     } else {

-        t[0] =  (double)fM[4]*gRESCALE; 

+        t[0] =  (double)fM[4]*gRESCALE;

         t[1] = -(double)fM[1]*gRESCALE;

         t[2] =  (double)fM[1]*fM[5] - (double)fM[2]*fM[4];

         t[3] = -(double)fM[3]*gRESCALE;

@@ -270,7 +260,7 @@
 }

 

 bool GrMatrix::isIdentity() const {

-    GrAssert((0 == fTypeMask) == 

+    GrAssert((0 == fTypeMask) ==

              (GR_Scalar1 == fM[kScaleX] && 0          == fM[kSkewX]  && 0          == fM[kTransX] &&

               0          == fM[kSkewY]  && GR_Scalar1 == fM[kScaleY] && 0          == fM[kTransY] &&

               0          == fM[kPersp0] && 0          == fM[kPersp1] && gRESCALE == fM[kPersp2]));

@@ -285,17 +275,17 @@
     }

 

     GrScalar stretch;

-    

+

     if (isIdentity()) {

         stretch = GR_Scalar1;

     } else if (!(fTypeMask & kSkew_TypeBit)) {

         stretch = GrMax(GrScalarAbs(fM[kScaleX]), GrScalarAbs(fM[kScaleY]));

-    } else if (fTypeMask & kZeroScale_TypeBit) {        

+    } else if (fTypeMask & kZeroScale_TypeBit) {

         stretch = GrMax(GrScalarAbs(fM[kSkewX]), GrScalarAbs(fM[kSkewY]));

-    } else {            

+    } else {

         // ignore the translation part of the matrix, just look at 2x2 portion.

         // compute singular values, take largest abs value.

-        // [a b; b c] = A^T*A 

+        // [a b; b c] = A^T*A

         GrScalar a = GrMul(fM[kScaleX], fM[kScaleX]) + GrMul(fM[kSkewY],  fM[kSkewY]);

         GrScalar b = GrMul(fM[kScaleX], fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kSkewY]);

         GrScalar c = GrMul(fM[kSkewX],  fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kScaleY]);

@@ -315,11 +305,11 @@
             GrScalar x = sqrtf(GrMul(aminusc,aminusc) + GrMul(4,(bSqd))) / 2;

             largerRoot = apluscdiv2 + x;

         }

-        

+

         stretch = sqrtf(largerRoot);

     }

 #if GR_DEBUG && 0

-    // test a bunch of vectors. None should be scaled by more than stretch 

+    // test a bunch of vectors. None should be scaled by more than stretch

     // (modulo some error) and we should find a vector that is scaled by almost

     // stretch.

     GrPoint pt;

@@ -329,7 +319,7 @@
         GrScalar y = sqrtf(1 - (x*x));

         pt.fX = fM[kScaleX]*x + fM[kSkewX]*y;

         pt.fY = fM[kSkewY]*x + fM[kScaleY]*y;

-        GrScalar d = pt.distanceToOrigin(); 

+        GrScalar d = pt.distanceToOrigin();

         GrAssert(d <= (1.0001 * stretch));

         max = GrMax(max, pt.distanceToOrigin());

     }

@@ -374,7 +364,7 @@
     }

     if (0 != fM[kTransX] || 0 != fM[kTransY]) {

         fTypeMask |= kTranslate_TypeBit;

-    }    

+    }

 }

 

 ////////////////////////////////////////////////////////////////////////////////

@@ -460,7 +450,7 @@
     if (src != dst) {

         for (uint32_t i = 0; i < count; ++i) {

             dst[i].fX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];

-            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];           

+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];

         }

     } else {

         for (uint32_t i = 0; i < count; ++i) {

@@ -482,7 +472,7 @@
             w = 1 / w;

         }

         dst[i].fX = GrMul(x, w);

-        dst[i].fY = GrMul(y, w);            

+        dst[i].fY = GrMul(y, w);

     }

 }

 

@@ -497,7 +487,7 @@
 void GrMatrix::mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {

     for (uint32_t i = 0; i < count; ++i) {

         dst[i].fX = fM[kTransX];

-        dst[i].fY = fM[kTransY];           

+        dst[i].fY = fM[kTransY];

     }

 }

 

@@ -548,7 +538,7 @@
     kTranslateY_MatrixType,

     kSwapScaleXY_MatrixType,

     kPersp_MatrixType,

-    

+

     kMatrixTypeCount

 };

 

@@ -559,59 +549,59 @@
             float angle = rand.nextF() * 2 *3.14159265358979323846f;

             GrScalar cosa = GrFloatToScalar(cosf(angle));

             GrScalar sina = GrFloatToScalar(sinf(angle));

-            matrix->setAll(cosa,      -sina,           0, 

-                           sina,       cosa,           0, 

+            matrix->setAll(cosa,      -sina,           0,

+                           sina,       cosa,           0,

                            0,          0,              GrMatrix::I()[8]);

         } break;

         case kScaleX_MatrixType: {

             GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));

-            matrix->setAll(scale,      0,              0, 

-                           0,          GR_Scalar1,     0, 

+            matrix->setAll(scale,      0,              0,

+                           0,          GR_Scalar1,     0,

                            0,          0,              GrMatrix::I()[8]);

         } break;

         case kScaleY_MatrixType: {

             GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));

-            matrix->setAll(GR_Scalar1, 0,              0, 

-                           0,          scale,          0, 

+            matrix->setAll(GR_Scalar1, 0,              0,

+                           0,          scale,          0,

                            0,          0,              GrMatrix::I()[8]);

         } break;

         case kSkewX_MatrixType: {

             GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));

-            matrix->setAll(GR_Scalar1, skew,           0, 

-                           0,          GR_Scalar1,     0, 

+            matrix->setAll(GR_Scalar1, skew,           0,

+                           0,          GR_Scalar1,     0,

                            0,          0,              GrMatrix::I()[8]);

-        } break;            

+        } break;

         case kSkewY_MatrixType: {

             GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));

-            matrix->setAll(GR_Scalar1, 0,              0, 

-                           skew,       GR_Scalar1,     0, 

+            matrix->setAll(GR_Scalar1, 0,              0,

+                           skew,       GR_Scalar1,     0,

                            0,          0,              GrMatrix::I()[8]);

         } break;

         case kTranslateX_MatrixType: {

             GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));

-            matrix->setAll(GR_Scalar1, 0,              trans, 

-                           0,          GR_Scalar1,     0, 

+            matrix->setAll(GR_Scalar1, 0,              trans,

+                           0,          GR_Scalar1,     0,

                            0,          0,              GrMatrix::I()[8]);

-        } break;            

+        } break;

         case kTranslateY_MatrixType: {

             GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));

-            matrix->setAll(GR_Scalar1, 0,              0, 

-                           0,          GR_Scalar1,     trans, 

+            matrix->setAll(GR_Scalar1, 0,              0,

+                           0,          GR_Scalar1,     trans,

                            0,          0,              GrMatrix::I()[8]);

-        } break; 

+        } break;

         case kSwapScaleXY_MatrixType: {

             GrScalar xy = GrFloatToScalar(rand.nextF(-2, 2));

             GrScalar yx = GrFloatToScalar(rand.nextF(-2, 2));

-            matrix->setAll(0,          xy,             0, 

-                           yx,         0,              0, 

+            matrix->setAll(0,          xy,             0,

+                           yx,         0,              0,

                            0,          0,              GrMatrix::I()[8]);

         } break;

         case kPersp_MatrixType: {

             GrScalar p0 = GrFloatToScalar(rand.nextF(-2, 2));

             GrScalar p1 = GrFloatToScalar(rand.nextF(-2, 2));

             GrScalar p2 = GrFloatToScalar(rand.nextF(-0.5f, 0.75f));

-            matrix->setAll(GR_Scalar1, 0,              0, 

-                           0,          GR_Scalar1,     0, 

+            matrix->setAll(GR_Scalar1, 0,              0,

+                           0,          GR_Scalar1,     0,

                            p0,         p1,             GrMul(p2,GrMatrix::I()[8]));

         } break;

         default:

@@ -624,7 +614,7 @@
 void GrMatrix::UnitTest() {

     GrRandom rand;

 

-    // Create a bunch of matrices and test point mapping, max stretch calc, 

+    // Create a bunch of matrices and test point mapping, max stretch calc,

     // inversion and multiply-by-inverse.

 #if GR_DEBUG

     for (int i = 0; i < 10000; ++i) {

@@ -638,14 +628,14 @@
         } else if (1 == i) {

             num = 0;

             a.setAll(0, GR_Scalar1, 0,

-                     GR_Scalar1, 0, 0, 

+                     GR_Scalar1, 0, 0,

                      0, 0, I()[8]);

         }

         for (int j = 0; j < num; ++j) {

             create_matrix(&b, rand);

             a.preConcat(b);

         }

-        

+

         GrScalar maxStretch = a.getMaxStretch();

         if (maxStretch > 0) {

             maxStretch = GrMul(GR_Scalar1 + GR_Scalar1 / 100, maxStretch);

@@ -655,7 +645,7 @@
         for (int j = 0; j < 9; ++j) {

             int mask, origMask = a.fTypeMask;

             GrScalar old = a[j];

-            

+

             a.set(j, GR_Scalar1);

             mask = a.fTypeMask;

             a.setTypeMask();

@@ -670,16 +660,16 @@
             mask = a.fTypeMask;

             a.setTypeMask();

             GrAssert(mask == a.fTypeMask);

-            

-            a.set(j, old);            

+

+            a.set(j, old);

             GrAssert(a.fTypeMask == origMask);

         }

-                     

+

         for (int j = 0; j < 100; ++j) {

             GrPoint pt;

             pt.fX = GrFloatToScalar(rand.nextF(-10, 10));

-            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));            

-            

+            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));

+

             GrPoint t0, t1, t2;

             t0 = a.mapPoint(pt);             // map to a new point

             t1 = pt;

@@ -764,4 +754,5 @@
     }

 }

 

-
+

+

diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
index 1374a26..0264856 100644
--- a/gpu/src/GrTextContext.cpp
+++ b/gpu/src/GrTextContext.cpp
@@ -211,7 +211,7 @@
         }
         bool success = fDrawTarget->reserveAndLockGeometry(VLAYOUT,
                                                            fMaxVertices, 0,
-                                                           (void**)&fVertices,
+                                                   GrTCast<void**>(&fVertices),
                                                            NULL);
         GrAlwaysAssert(success);
     }
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 85f5421..17ed4c1 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -301,6 +301,20 @@
     return cond ? bits | mask : bits & ~mask;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Use to cast a pointer to a different type, and maintaining strict-aliasing
+ */
+template <typename Dst> Dst SkTCast(const void* ptr) {
+    union {
+        const void* src;
+        Dst dst;
+    } data;
+    data.src = ptr;
+    return data.dst;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 /** \class SkNoncopyable
@@ -311,7 +325,7 @@
 class SkNoncopyable {
 public:
     SkNoncopyable() {}
-    
+
 private:
     SkNoncopyable(const SkNoncopyable&);
     SkNoncopyable& operator=(const SkNoncopyable&);
@@ -322,7 +336,7 @@
     SkAutoFree() : fPtr(NULL) {}
     explicit SkAutoFree(void* ptr) : fPtr(ptr) {}
     ~SkAutoFree() { sk_free(fPtr); }
-    
+
     /** Return the currently allocate buffer, or null
     */
     void* get() const { return fPtr; }
@@ -336,7 +350,7 @@
         fPtr = ptr;
         return prev;
     }
-    
+
     /** Transfer ownership of the current ptr to the caller, setting the
         internal reference to null. Note the caller is reponsible for calling
         sk_free on the returned address.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 7c50ab3..2d5634c 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -711,7 +711,7 @@
 
     GrPoint* vertex;
     if (!fContext->reserveAndLockGeometry(layout, 4,
-                                          0, (void**)&vertex, NULL)) {
+                                          0, GrTCast<void**>(&vertex), NULL)) {
         return;
     }
 
@@ -750,7 +750,8 @@
 
     GrPoint* vertex;
     GrVertexLayout layout = GrGpu::kSeparateTexCoord_VertexLayoutBit;
-    if (!ctx->reserveAndLockGeometry(layout, 4, 0, (void**)&vertex, NULL)) {
+    if (!ctx->reserveAndLockGeometry(layout, 4, 0,
+                                     GrTCast<void**>(&vertex), NULL)) {
         return;
     }
 
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp
index 5c88717..3d57aa8 100644
--- a/src/gpu/SkGrFontScaler.cpp
+++ b/src/gpu/SkGrFontScaler.cpp
@@ -23,12 +23,12 @@
 public:
     explicit SkGrDescKey(const SkDescriptor& desc);
     virtual ~SkGrDescKey();
-    
+
 protected:
     // overrides
     virtual bool lt(const GrKey& rh) const;
     virtual bool eq(const GrKey& rh) const;
-    
+
 private:
     SkDescriptor* fDesc;
     enum {
@@ -42,7 +42,7 @@
 SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
     size_t size = desc.getLength();
     if (size <= sizeof(fStorage)) {
-        fDesc = (SkDescriptor*)fStorage;
+        fDesc = GrTCast<SkDescriptor*>(fStorage);
     } else {
         fDesc = SkDescriptor::Alloc(size);
     }
@@ -50,7 +50,7 @@
 }
 
 SkGrDescKey::~SkGrDescKey() {
-    if (fDesc != (SkDescriptor*)fStorage) {
+    if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
         SkDescriptor::Free(fDesc);
     }
 }
@@ -97,7 +97,7 @@
                                               GrGlyph::UnpackFixedY(packed));
     bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
     return true;
-    
+
 }
 
 bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
@@ -127,7 +127,7 @@
 }
 
 bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
-    
+
     const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
     const SkPath* skPath = fStrike->findPath(glyph);
     if (skPath) {
diff --git a/src/utils/SkParseColor.cpp b/src/utils/SkParseColor.cpp
index c451253..43d0737 100644
--- a/src/utils/SkParseColor.cpp
+++ b/src/utils/SkParseColor.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -21,7 +21,7 @@
 #include "SkString.h"
 
     // compress names 6 chars per long (packed 5 bits/char )
-        // note: little advantage to splitting chars across longs, since 3 longs at 2 unused bits each 
+        // note: little advantage to splitting chars across longs, since 3 longs at 2 unused bits each
         // allow for one additional split char (vs. the 18 unsplit chars in the three longs)
     // use extra two bits to represent:
         // 00 : final 6 (or fewer) chars (if 'a' is 0x01, zero could have special meaning)
@@ -185,6 +185,7 @@
 
 int colorNamesSize = sizeof(colorNames) / sizeof(colorNames[0]);
 
+#ifdef SK_SUPPORT_UNITTEST
 static void CreateTable() {
     SkString comment;
     size_t originalSize = 0;
@@ -226,6 +227,7 @@
     SkDebugf("// original = %d : replacement = %d\n", originalSize, replacement);
     SkASSERT(0); // always stop after creating table
 }
+#endif
 
 #endif
 
@@ -401,7 +403,7 @@
         }
         ch = *namePtr | 0x20;
         last = ch < 'a' || ch > 'z';
-        if (last) 
+        if (last)
             sixMatch &= ~1;
         len -= 6;
         *sixMatchPtr++ = sixMatch;
@@ -493,7 +495,7 @@
 //      if (end == NULL)
 //          return NULL;
         // !!! range check for errors?
-//      *colorPtr = SkColorSetARGB(SkScalarRound(array[0]), SkScalarRound(array[1]), 
+//      *colorPtr = SkColorSetARGB(SkScalarRound(array[0]), SkScalarRound(array[1]),
 //          SkScalarRound(array[2]), SkScalarRound(array[3]));
 //      return end;
     } else
@@ -518,9 +520,9 @@
         char bad[24];
         size_t len = strlen(nameRGB.name);
         memcpy(bad, nameRGB.name, len);
-        bad[len - 1] -= 1; 
+        bad[len - 1] -= 1;
         SkASSERT(FindColor(bad, &result) == false);
-        bad[len - 1] += 2; 
+        bad[len - 1] += 2;
         SkASSERT(FindColor(bad, &result) == false);
     }
     result = SK_ColorBLACK;
diff --git a/tests/BitmapCopyTest.cpp b/tests/BitmapCopyTest.cpp
index 7af8ac9..c07630d 100644
--- a/tests/BitmapCopyTest.cpp
+++ b/tests/BitmapCopyTest.cpp
@@ -269,7 +269,7 @@
                            boolStr(success));
                 reporter->reportFailed(str);
             }
-            
+
             bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
             if (success != canSucceed) {
                 SkString str;
@@ -310,7 +310,7 @@
                         REPORTER_ASSERT(reporter, copy.width() == 1);
                         REPORTER_ASSERT(reporter, copy.height() == 1);
                         REPORTER_ASSERT(reporter, copy.rowBytes() <= 4);
-                        
+
                         SkAutoLockPixels alp0(subset);
                         SkAutoLockPixels alp1(copy);
                         // they should both have, or both not-have, a colortable
@@ -464,7 +464,7 @@
                     for (size_t x = 0; x < subW; ++x)
                         for (size_t y = 0; y < subH; ++y)
                         {
-                            size_t index = y * subW + x;
+                            int index = y * subW + x;
                             SkASSERT(index < coords.length);
                             coords[index]->fX = x;
                             coords[index]->fY = y;