Bug 772726. Part 8: Add Rect::NudgeToIntegers and share improved nudging code among all nudging APIs. r=bas
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 12 Sep 2012 17:24:09 +1200
changeset 107555 5daf1f385a84739da287334ae04a6f9b2acf891d
parent 107554 6ffdab09eff621f3bc33521e65c36be4af213dcc
child 107556 b1a999da36e6dae207c5a9eeba9cd66faf088b87
push id15110
push userrocallahan@mozilla.com
push dateThu, 20 Sep 2012 02:14:08 +0000
treeherdermozilla-inbound@6694b77fb670 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs772726
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 772726. Part 8: Add Rect::NudgeToIntegers and share improved nudging code among all nudging APIs. r=bas
gfx/2d/Makefile.in
gfx/2d/Matrix.cpp
gfx/2d/Rect.h
gfx/2d/Tools.h
gfx/thebes/gfx3DMatrix.cpp
gfx/thebes/gfxMatrix.cpp
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -25,21 +25,23 @@ EXPORTS_mozilla/gfx	= \
         BaseRect.h \
         BaseSize.h \
         Blur.h \
         PathHelpers.h \
         Point.h \
         Matrix.h \
         Rect.h \
         Types.h \
+        Tools.h \
         UserData.h \
 	$(NULL)
 
 CPPSRCS	= \
-	Factory.cpp \
+        Factory.cpp \
+        Rect.cpp \
         Matrix.cpp \
         DrawTargetCairo.cpp \
         SourceSurfaceCairo.cpp \
         PathCairo.cpp \
         Blur.cpp \
         ScaledFontBase.cpp \
         DrawTargetDual.cpp \
         ImageScaling.cpp \
--- a/gfx/2d/Matrix.cpp
+++ b/gfx/2d/Matrix.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Matrix.h"
+#include "Tools.h"
 #include <math.h>
 
 namespace mozilla {
 namespace gfx {
 
 Matrix
 Matrix::Rotation(Float aAngle)
 {
@@ -51,24 +52,16 @@ Matrix::TransformBounds(const Rect &aRec
       min_y = quad[i].y;
     if (quad[i].y > max_y)
       max_y = quad[i].y;
   }
 
   return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
 }
 
-static void NudgeToInteger(float *aVal)
-{
-  float r = floorf(*aVal + 0.5f);
-  if (fabsf(*aVal - r) < 1e-4f) {
-    *aVal = r;
-  }
-}
-
 void
 Matrix::NudgeToIntegers()
 {
   NudgeToInteger(&_11);
   NudgeToInteger(&_12);
   NudgeToInteger(&_21);
   NudgeToInteger(&_22);
   NudgeToInteger(&_31);
--- a/gfx/2d/Rect.h
+++ b/gfx/2d/Rect.h
@@ -47,16 +47,18 @@ struct Rect :
     Rect(Point aPos, mozilla::gfx::Size aSize) :
         Super(aPos, aSize) {}
     Rect(Float _x, Float _y, Float _width, Float _height) :
         Super(_x, _y, _width, _height) {}
     explicit Rect(const IntRect& rect) :
         Super(float(rect.x), float(rect.y),
               float(rect.width), float(rect.height)) {}
 
+    GFX2D_API void NudgeToIntegers();
+
     bool ToIntRect(IntRect *aOut)
     {
       *aOut = IntRect(int32_t(X()), int32_t(Y()),
                     int32_t(Width()), int32_t(Height()));
       return Rect(Float(aOut->x), Float(aOut->y), 
                   Float(aOut->width), Float(aOut->height)).IsEqualEdges(*this);
     }
 };
--- a/gfx/2d/Tools.h
+++ b/gfx/2d/Tools.h
@@ -2,16 +2,18 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_TOOLS_H_
 #define MOZILLA_GFX_TOOLS_H_
 
 #include "Types.h"
+#include "Point.h"
+#include <math.h>
 #if defined(_MSC_VER) && (_MSC_VER < 1600)
 #define hypotf _hypotf
 #endif
 
 namespace mozilla {
 namespace gfx {
 
 static inline bool
@@ -41,16 +43,30 @@ static inline bool
 FuzzyEqual(Float aA, Float aB, Float aErr)
 {
   if ((aA + aErr > aB) && (aA - aErr < aB)) {
     return true;
   }
   return false;
 }
 
+static inline void
+NudgeToInteger(float *aVal)
+{
+  float r = floorf(*aVal + 0.5f);
+  // The error threshold should be proportional to the rounded value. This
+  // bounds the relative error introduced by the nudge operation. However,
+  // when the rounded value is 0, the error threshold can't be proportional
+  // to the rounded value (we'd never round), so we just choose the same
+  // threshold as for a rounded value of 1.
+  if (FuzzyEqual(r, *aVal, r == 0.0f ? 1e-6f : fabs(r*1e-6f))) {
+    *aVal = r;
+  }
+}
+
 static inline Float
 Distance(Point aA, Point aB)
 {
   return hypotf(aB.x - aA.x, aB.y - aA.y);
 }
 
 static inline int
 BytesPerPixel(SurfaceFormat aFormat)
--- a/gfx/thebes/gfx3DMatrix.cpp
+++ b/gfx/thebes/gfx3DMatrix.cpp
@@ -1,18 +1,21 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxMatrix.h"
 #include "gfx3DMatrix.h"
+#include "mozilla/gfx/Tools.h"
 #include <math.h>
 #include <algorithm>
+
 using namespace std;
+using namespace mozilla::gfx;
 
 /* Force small values to zero.  We do this to avoid having sin(360deg)
  * evaluate to a tiny but nonzero value.
  */
 static double FlushToZero(double aVal)
 {
   if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON)
     return 0.0f;
@@ -805,24 +808,16 @@ bool gfx3DMatrix::IsBackfaceVisible() co
   // Inverse()._33 < 0;
   gfxFloat det = Determinant();
   float _33 = _12*_24*_41 - _14*_22*_41 +
               _14*_21*_42 - _11*_24*_42 -
               _12*_21*_44 + _11*_22*_44;
   return (_33 * det) < 0;
 }
 
-static void NudgeToInteger(float *aVal)
-{
-  float r = floorf(*aVal + 0.5f);
-  if (fabsf(*aVal - r) < 1e-4f) {
-    *aVal = r;
-  }
-}
-
 void gfx3DMatrix::NudgeToIntegers(void)
 {
   NudgeToInteger(&_11);
   NudgeToInteger(&_12);
   NudgeToInteger(&_13);
   NudgeToInteger(&_14);
   NudgeToInteger(&_21);
   NudgeToInteger(&_22);
--- a/gfx/thebes/gfxMatrix.cpp
+++ b/gfx/thebes/gfxMatrix.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxMatrix.h"
 #include "cairo.h"
+#include "mozilla/gfx/Tools.h"
 
 #define CAIRO_MATRIX(x) reinterpret_cast<cairo_matrix_t*>((x))
 #define CONST_CAIRO_MATRIX(x) reinterpret_cast<const cairo_matrix_t*>((x))
 
 const gfxMatrix&
 gfxMatrix::Reset()
 {
     cairo_matrix_init_identity(CAIRO_MATRIX(this));
@@ -122,20 +123,18 @@ gfxMatrix::TransformBounds(const gfxRect
 
     return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
 }
 
 
 static void NudgeToInteger(double *aVal)
 {
     float f = float(*aVal);
-    float r = NS_roundf(f);
-    if (f == r) {
-        *aVal = r;
-    }
+    mozilla::gfx::NudgeToInteger(&f);
+    *aVal = f;
 }
 
 void
 gfxMatrix::NudgeToIntegers(void)
 {
     NudgeToInteger(&xx);
     NudgeToInteger(&xy);
     NudgeToInteger(&yx);