Bug 695303 - Add a mozilla::clamped function to replace NS_CLAMP (so side affects of args are evaluated no more than once) and NS_MIN(max, NS_MAX(val, min)) (to make code clearer). r=bsmedberg.
authorJonathan Watt <jwatt@jwatt.org>
Fri, 28 Oct 2011 19:33:28 +0100
changeset 79383 21f2d6c4c976332daac4fb1ec3ca52c1b33811b3
parent 79382 57df319fe7f9df3b5aba3a46a51f5cd4e456497d
child 79384 76a6531600d74699389ae95ba8e1db8ce9014a19
push id21391
push usermak77@bonardo.net
push dateSat, 29 Oct 2011 08:32:26 +0000
treeherdermozilla-central@1a52298b6718 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs695303
milestone10.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 695303 - Add a mozilla::clamped function to replace NS_CLAMP (so side affects of args are evaluated no more than once) and NS_MIN(max, NS_MAX(val, min)) (to make code clearer). r=bsmedberg.
content/canvas/src/WebGLContextGL.cpp
content/svg/content/src/nsSVGFilters.cpp
dom/workers/RuntimeService.cpp
gfx/thebes/gfxGDIFontList.cpp
gfx/thebes/gfxQuaternion.h
gfx/ycbcr/ycbcr_to_rgb565.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsSimplePageSequence.cpp
layout/style/nsComputedDOMStyle.h
layout/tables/nsTableFrame.cpp
layout/xul/base/src/nsSliderFrame.cpp
layout/xul/base/src/nsStackLayout.cpp
netwerk/cache/nsDiskCacheBlockFile.cpp
netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
widget/src/android/nsWindow.cpp
xpcom/base/nscore.h
xpcom/string/public/nsAlgorithm.h
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -874,23 +874,23 @@ WebGLContext::CopyTexSubImage2D_base(Web
             || x+width <= 0
             || y >= framebufferHeight
             || y+height <= 0)
         {
             // we are completely outside of range, can exit now with buffer filled with zeros
             return NS_OK;
         }
 
-        GLint   actual_x             = NS_MIN(framebufferWidth, NS_MAX(0, x));
-        GLint   actual_x_plus_width  = NS_MIN(framebufferWidth, NS_MAX(0, x + width));
+        GLint   actual_x             = clamped(x, 0, framebufferWidth);
+        GLint   actual_x_plus_width  = clamped(x + width, 0, framebufferWidth);
         GLsizei actual_width   = actual_x_plus_width  - actual_x;
         GLint   actual_xoffset = xoffset + actual_x - x;
 
-        GLint   actual_y             = NS_MIN(framebufferHeight, NS_MAX(0, y));
-        GLint   actual_y_plus_height = NS_MIN(framebufferHeight, NS_MAX(0, y + height));
+        GLint   actual_y             = clamped(y, 0, framebufferHeight);
+        GLint   actual_y_plus_height = clamped(y + height, 0, framebufferHeight);
         GLsizei actual_height  = actual_y_plus_height - actual_y;
         GLint   actual_yoffset = yoffset + actual_y - y;
 
         gl->fCopyTexSubImage2D(target, level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
     }
 
     return NS_OK;
 }
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -1318,17 +1318,17 @@ nsSVGFEColorMatrixElement::Filter(nsSVGF
       float col[4];
       for (int i = 0, row = 0; i < 4; i++, row += 5) {
         col[i] =
           sourceData[targIndex + GFX_ARGB32_OFFSET_R] * colorMatrix[row + 0] +
           sourceData[targIndex + GFX_ARGB32_OFFSET_G] * colorMatrix[row + 1] +
           sourceData[targIndex + GFX_ARGB32_OFFSET_B] * colorMatrix[row + 2] +
           sourceData[targIndex + GFX_ARGB32_OFFSET_A] * colorMatrix[row + 3] +
           255 *                                         colorMatrix[row + 4];
-        col[i] = NS_MIN(NS_MAX(0.f, col[i]), 255.f);
+        col[i] = clamped(col[i], 0.f, 255.f);
       }
       targetData[targIndex + GFX_ARGB32_OFFSET_R] =
         static_cast<PRUint8>(col[0]);
       targetData[targIndex + GFX_ARGB32_OFFSET_G] =
         static_cast<PRUint8>(col[1]);
       targetData[targIndex + GFX_ARGB32_OFFSET_B] =
         static_cast<PRUint8>(col[2]);
       targetData[targIndex + GFX_ARGB32_OFFSET_A] =
@@ -1560,17 +1560,17 @@ nsSVGFECompositeElement::Filter(nsSVGFil
     for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
       for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
         PRUint32 targIndex = y * stride + 4 * x;
         for (PRInt32 i = 0; i < 4; i++) {
           PRUint8 i1 = targetData[targIndex + i];
           PRUint8 i2 = sourceData[targIndex + i];
           float result = k1Scaled*i1*i2 + k2*i1 + k3*i2 + k4Scaled;
           targetData[targIndex + i] =
-                       static_cast<PRUint8>(NS_MIN(NS_MAX(0.f, result), 255.f));
+                       static_cast<PRUint8>(clamped(result, 0.f, 255.f));
         }
       }
     }
     return NS_OK;
   }
 
   // Cairo supports the operation we are trying to perform
 
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -214,17 +214,17 @@ PrefCallback(const char* aPrefName, void
       newOptions |= JSOPTION_METHODJIT_ALWAYS;
     }
     RuntimeService::SetDefaultJSContextOptions(newOptions);
     rts->UpdateAllWorkerJSContextOptions();
   }
 #ifdef JS_GC_ZEAL
   else if (!strcmp(aPrefName, gPrefsToWatch[PREF_gczeal])) {
     PRInt32 gczeal = Preferences::GetInt(gPrefsToWatch[PREF_gczeal]);
-    RuntimeService::SetDefaultGCZeal(PRUint8(NS_MIN(NS_MAX(gczeal, 0), 3)));
+    RuntimeService::SetDefaultGCZeal(PRUint8(clamped(gczeal, 0, 3)));
     rts->UpdateAllWorkerGCZeal();
   }
 #endif
   return 0;
 }
 
 void
 ErrorReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aReport)
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -473,17 +473,17 @@ GDIFontFamily::FamilyAddStylesProc(const
                                         const NEWTEXTMETRICEXW *nmetrics,
                                         DWORD fontType, LPARAM data)
 {
     const NEWTEXTMETRICW& metrics = nmetrics->ntmTm;
     LOGFONTW logFont = lpelfe->elfLogFont;
     GDIFontFamily *ff = reinterpret_cast<GDIFontFamily*>(data);
 
     // Some fonts claim to support things > 900, but we don't so clamp the sizes
-    logFont.lfWeight = NS_MAX<LONG>(NS_MIN<LONG>(logFont.lfWeight, 900), 100);
+    logFont.lfWeight = clamped(logFont.lfWeight, LONG(100), LONG(900));
 
     gfxWindowsFontType feType = GDIFontEntry::DetermineFontType(metrics, fontType);
 
     GDIFontEntry *fe = nsnull;
     for (PRUint32 i = 0; i < ff->mAvailableFonts.Length(); ++i) {
         fe = static_cast<GDIFontEntry*>(ff->mAvailableFonts[i].get());
         if (feType > fe->mFontType) {
             // if the new type is better than the old one, remove the old entries
--- a/gfx/thebes/gfxQuaternion.h
+++ b/gfx/thebes/gfxQuaternion.h
@@ -35,16 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_QUATERNION_H
 #define GFX_QUATERNION_H
 
 #include "mozilla/gfx/BasePoint4D.h"
 #include "gfx3DMatrix.h"
+#include "nsAlgorithm.h"
 
 struct THEBES_API gfxQuaternion : public mozilla::gfx::BasePoint4D<gfxFloat, gfxQuaternion> {
     typedef mozilla::gfx::BasePoint4D<gfxFloat, gfxQuaternion> Super;
 
     gfxQuaternion() : Super() {}
     gfxQuaternion(gfxFloat aX, gfxFloat aY, gfxFloat aZ, gfxFloat aW) : Super(aX, aY, aZ, aW) {}
 
     gfxQuaternion(const gfx3DMatrix& aMatrix) {
@@ -57,17 +58,17 @@ struct THEBES_API gfxQuaternion : public
             x = -x;
         if(aMatrix[0][2] > aMatrix[2][0])
             y = -y;
         if(aMatrix[1][0] > aMatrix[0][1])
             z = -z;
     }
 
     gfxQuaternion Slerp(const gfxQuaternion &aOther, gfxFloat aCoeff) {
-        gfxFloat dot = NS_CLAMP(DotProduct(aOther), -1.0, 1.0);
+        gfxFloat dot = mozilla::clamped(DotProduct(aOther), -1.0, 1.0);
         if (dot == 1.0) {
             return *this;
         }
 
         gfxFloat theta = acos(dot);
         gfxFloat rsintheta = 1/sqrt(1 - dot*dot);
         gfxFloat w = sin(aCoeff*theta)*rsintheta;
 
@@ -86,16 +87,16 @@ struct THEBES_API gfxQuaternion : public
         temp[0][0] = 1 - 2 * (y * y + z * z);
         temp[0][1] = 2 * (x * y + w * z);
         temp[0][2] = 2 * (x * z - w * y);
         temp[1][0] = 2 * (x * y - w * z);
         temp[1][1] = 1 - 2 * (x * x + z * z);
         temp[1][2] = 2 * (y * z + w * x);
         temp[2][0] = 2 * (x * z + w * y);
         temp[2][1] = 2 * (y * z - w * x);
-        temp[2][2] = 1 - 2 * (x * x + y * y);
+        temp[2][2] = 1 - 2 * (x * x + y * y);
 
         return temp;
     }
 
 };
 
-#endif /* GFX_QUATERNION_H */
\ No newline at end of file
+#endif /* GFX_QUATERNION_H */
--- a/gfx/ycbcr/ycbcr_to_rgb565.cpp
+++ b/gfx/ycbcr/ycbcr_to_rgb565.cpp
@@ -37,16 +37,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdlib.h>
 #include <limits.h>
 #include "nsDebug.h"
 #include "ycbcr_to_rgb565.h"
+#include "nsAlgorithm.h"
 
 
 
 #ifdef HAVE_YCBCR_TO_RGB565
 
 namespace mozilla {
 
 namespace gfx {
@@ -146,19 +147,19 @@ static PRUint16 yu2rgb565(int y, int u, 
     {-14240,    8704,    -17696},
     {-14240+128,8704+64, -17696+128},
     {-14240+256,8704+128,-17696+256},
     {-14240+384,8704+192,-17696+384}
   };
   int r;
   int g;
   int b;
-  r = NS_CLAMP((74*y+102*v+DITHER_BIAS[dither][0])>>9, 0, 31);
-  g = NS_CLAMP((74*y-25*u-52*v+DITHER_BIAS[dither][1])>>8, 0, 63);
-  b = NS_CLAMP((74*y+129*u+DITHER_BIAS[dither][2])>>9, 0, 31);
+  r = clamped((74*y+102*v+DITHER_BIAS[dither][0])>>9, 0, 31);
+  g = clamped((74*y-25*u-52*v+DITHER_BIAS[dither][1])>>8, 0, 63);
+  b = clamped((74*y+129*u+DITHER_BIAS[dither][2])>>9, 0, 31);
   return (PRUint16)(r<<11 | g<<5 | b);
 }
 
 static void ScaleYCbCr420ToRGB565_Bilinear_Row_C(
  const yuv2rgb565_row_scale_bilinear_ctx *ctx, int dither){
   int x;
   int source_x_q16;
   source_x_q16 = ctx->source_x0_q16;
@@ -453,20 +454,20 @@ NS_GFX_(void) ScaleYCbCrToRGB565(const P
     ctx.width = width;
     ctx.source_x0_q16 = source_x0_q16;
     ctx.source_dx_q16 = source_dx_q16;
     ctx.source_uv_xoffs_q16 = source_uv_xoffs_q16;
     for (y=0; y<height; y++) {
       int source_y;
       ctx.rgb_row = (PRUint16 *)(rgb_buf + y*rgb_pitch);
       source_y = source_y0_q16>>16;
-      source_y = NS_CLAMP(source_y, ymin, ymax);
+      source_y = clamped(source_y, ymin, ymax);
       ctx.y_row = y_buf + source_y*y_pitch;
       source_y = (source_y0_q16+source_uv_yoffs_q16)>>(16+y_shift);
-      source_y = NS_CLAMP(source_y, uvmin, uvmax);
+      source_y = clamped(source_y, uvmin, uvmax);
       source_y0_q16 += source_dy_q16;
       ctx.u_row = u_buf + source_y*uv_pitch;
       ctx.v_row = v_buf + source_y*uv_pitch;
       (*scale_row)(&ctx, dither);
       dither ^= 2;
     }
   }
   /*Bilinear scaling.*/
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -47,16 +47,18 @@
 #include "nsHTMLParts.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsCOMPtr.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
 #include "nsCSSRendering.h"
 
+using namespace mozilla;
+
 class nsColumnSetFrame : public nsHTMLContainerFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsColumnSetFrame(nsStyleContext* aContext);
 
   NS_IMETHOD SetInitialChildList(ChildListID     aListID,
                                  nsFrameList&    aChildList);
@@ -1014,18 +1016,18 @@ nsColumnSetFrame::Reflow(nsPresContext* 
         // differently.
         nextGuess = knownFeasibleHeight - 1;
       } else if (unboundedLastColumn) {
         // Make a guess by dividing that into N columns. Add some slop
         // to try to make it on the feasible side.  The constant of
         // 600 twips is arbitrary. It's about two line-heights.
         nextGuess = colData.mSumHeight/config.mBalanceColCount + 600;
         // Sanitize it
-        nextGuess = NS_MIN(NS_MAX(nextGuess, knownInfeasibleHeight + 1),
-                           knownFeasibleHeight - 1);
+        nextGuess = clamped(nextGuess, knownInfeasibleHeight + 1,
+                                       knownFeasibleHeight - 1);
       } else if (knownFeasibleHeight == NS_INTRINSICSIZE) {
         // This can happen when we had a next-in-flow so we didn't
         // want to do an unbounded height measuring step. Let's just increase
         // from the infeasible height by some reasonable amount.
         nextGuess = knownInfeasibleHeight*2 + 600;
       }
       // Don't bother guessing more than our height constraint.
       nextGuess = NS_MIN(availableContentHeight, nextGuess);
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1321,17 +1321,17 @@ public:
   nsPoint mStartPos;
   nsPoint mDestination;
   nsSMILKeySpline mTimingFunctionX;
   nsSMILKeySpline mTimingFunctionY;
   bool mIsSmoothScroll;
 
 protected:
   double ProgressAt(TimeStamp aTime) {
-    return NS_MIN(1.0, NS_MAX(0.0, (aTime - mStartTime) / mDuration));
+    return clamped((aTime - mStartTime) / mDuration, 0.0, 1.0);
   }
 
   nscoord VelocityComponent(double aTimeProgress,
                             nsSMILKeySpline& aTimingFunction,
                             nscoord aStart, nscoord aDestination);
 
   // Initializes the timing function in such a way that the current velocity is
   // preserved.
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -577,24 +577,24 @@ nsObjectFrame::GetDesiredSize(nsPresCont
   
   aMetrics.width = aReflowState.ComputedWidth();
   aMetrics.height = aReflowState.ComputedHeight();
 
   // for EMBED and APPLET, default to 240x200 for compatibility
   nsIAtom *atom = mContent->Tag();
   if (atom == nsGkAtoms::applet || atom == nsGkAtoms::embed) {
     if (aMetrics.width == NS_UNCONSTRAINEDSIZE) {
-      aMetrics.width = NS_MIN(NS_MAX(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
-                                     aReflowState.mComputedMinWidth),
-                              aReflowState.mComputedMaxWidth);
+      aMetrics.width = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
+                               aReflowState.mComputedMinWidth,
+                               aReflowState.mComputedMaxWidth);
     }
     if (aMetrics.height == NS_UNCONSTRAINEDSIZE) {
-      aMetrics.height = NS_MIN(NS_MAX(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT),
-                                      aReflowState.mComputedMinHeight),
-                               aReflowState.mComputedMaxHeight);
+      aMetrics.height = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT),
+                                aReflowState.mComputedMinHeight,
+                                aReflowState.mComputedMaxHeight);
     }
 
 #if defined (MOZ_WIDGET_GTK2)
     // We need to make sure that the size of the object frame does not
     // exceed the maximum size of X coordinates.  See bug #225357 for
     // more information.  In theory Gtk2 can handle large coordinates,
     // but underlying plugins can't.
     aMetrics.height = NS_MIN(aPresContext->DevPixelsToAppUnits(PR_INT16_MAX), aMetrics.height);
--- a/layout/generic/nsSimplePageSequence.cpp
+++ b/layout/generic/nsSimplePageSequence.cpp
@@ -207,20 +207,20 @@ nsSimplePageSequenceFrame::Reflow(nsPres
     mPageData->mPrintSettings->GetPrintRange(&printType);
     mPrintRangeType = printType;
 
     nsIntMargin edgeTwips;
     mPageData->mPrintSettings->GetEdgeInTwips(edgeTwips);
 
     // sanity check the values. three inches are sometimes needed
     PRInt32 inchInTwips = NS_INCHES_TO_INT_TWIPS(3.0);
-    edgeTwips.top = NS_MIN(NS_MAX(edgeTwips.top, 0), inchInTwips);
-    edgeTwips.bottom = NS_MIN(NS_MAX(edgeTwips.bottom, 0), inchInTwips);
-    edgeTwips.left = NS_MIN(NS_MAX(edgeTwips.left, 0), inchInTwips);
-    edgeTwips.right = NS_MIN(NS_MAX(edgeTwips.right, 0), inchInTwips);
+    edgeTwips.top    = clamped(edgeTwips.top,    0, inchInTwips);
+    edgeTwips.bottom = clamped(edgeTwips.bottom, 0, inchInTwips);
+    edgeTwips.left   = clamped(edgeTwips.left,   0, inchInTwips);
+    edgeTwips.right  = clamped(edgeTwips.right,  0, inchInTwips);
 
     mPageData->mEdgePaperMargin =
       aPresContext->CSSTwipsToAppUnits(edgeTwips + unwriteableTwips);
   }
 
   // *** Special Override ***
   // If this is a sub-sdoc (meaning it doesn't take the whole page)
   // and if this Document is in the upper left hand corner
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -439,18 +439,18 @@ private:
   /**
    * Method to set aValue to aCoord.  If aCoord is a percentage value and
    * aPercentageBaseGetter is not null, aPercentageBaseGetter is called.  If it
    * returns true, the percentage base it outputs in its out param is used
    * to compute an nscoord value.  If the getter is null or returns false,
    * the percent value of aCoord is set as a percent value on aValue.  aTable,
    * if not null, is the keyword table to handle eStyleUnit_Enumerated.  When
    * calling SetAppUnits on aValue (for coord or percent values), the value
-   * passed in will be NS_MAX of the value in aMinAppUnits and the NS_MIN of
-   * the actual value in aCoord and the value in aMaxAppUnits.
+   * passed in will be clamped to be no less than aMinAppUnits and no more than
+   * aMaxAppUnits.
    *
    * XXXbz should caller pass in some sort of bitfield indicating which units
    * can be expected or something?
    */
   void SetValueToCoord(nsROCSSPrimitiveValue* aValue,
                        const nsStyleCoord& aCoord,
                        bool aClampNegativeCalc,
                        PercentageBaseGetter aPercentageBaseGetter = nsnull,
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -4852,17 +4852,17 @@ struct BCCorners
 {
   BCCorners(PRInt32 aNumCorners,
             PRInt32 aStartIndex);
 
   ~BCCorners() { delete [] corners; }
 
   BCCornerInfo& operator [](PRInt32 i) const
   { NS_ASSERTION((i >= startIndex) && (i <= endIndex), "program error");
-    return corners[NS_MAX(NS_MIN(i, endIndex), startIndex) - startIndex]; }
+    return corners[clamped(i, startIndex, endIndex) - startIndex]; }
 
   PRInt32       startIndex;
   PRInt32       endIndex;
   BCCornerInfo* corners;
 };
 
 BCCorners::BCCorners(PRInt32 aNumCorners,
                      PRInt32 aStartIndex)
@@ -4878,17 +4878,17 @@ struct BCCellBorders
 {
   BCCellBorders(PRInt32 aNumBorders,
                 PRInt32 aStartIndex);
 
   ~BCCellBorders() { delete [] borders; }
 
   BCCellBorder& operator [](PRInt32 i) const
   { NS_ASSERTION((i >= startIndex) && (i <= endIndex), "program error");
-    return borders[NS_MAX(NS_MIN(i, endIndex), startIndex) - startIndex]; }
+    return borders[clamped(i, startIndex, endIndex) - startIndex]; }
 
   PRInt32       startIndex;
   PRInt32       endIndex;
   BCCellBorder* borders;
 };
 
 BCCellBorders::BCCellBorders(PRInt32 aNumBorders,
                              PRInt32 aStartIndex)
--- a/layout/xul/base/src/nsSliderFrame.cpp
+++ b/layout/xul/base/src/nsSliderFrame.cpp
@@ -401,17 +401,17 @@ nsSliderFrame::DoLayout(nsBoxLayoutState
     thumbSize.width = clientRect.width;
 
   PRInt32 curPos = GetCurrentPosition(scrollbar);
   PRInt32 minPos = GetMinPosition(scrollbar);
   PRInt32 maxPos = GetMaxPosition(scrollbar);
   PRInt32 pageIncrement = GetPageIncrement(scrollbar);
 
   maxPos = NS_MAX(minPos, maxPos);
-  curPos = NS_MAX(minPos, NS_MIN(curPos, maxPos));
+  curPos = clamped(curPos, minPos, maxPos);
 
   nscoord& availableLength = IsHorizontal() ? clientRect.width : clientRect.height;
   nscoord& thumbLength = IsHorizontal() ? thumbSize.width : thumbSize.height;
 
   if ((pageIncrement + maxPos - minPos) > 0 && thumbBox->GetFlex(aState) > 0) {
     float ratio = float(pageIncrement) / float(maxPos - minPos + pageIncrement);
     thumbLength = NS_MAX(thumbLength, NSToCoordRound(availableLength * ratio));
   }
@@ -682,17 +682,17 @@ nsSliderFrame::CurrentPositionChanged(ns
   if (mCurPos == curPos)
       return NS_OK;
 
   // get our current min and max position from our content node
   PRInt32 minPos = GetMinPosition(scrollbar);
   PRInt32 maxPos = GetMaxPosition(scrollbar);
 
   maxPos = NS_MAX(minPos, maxPos);
-  curPos = NS_MAX(minPos, NS_MIN(curPos, maxPos));
+  curPos = clamped(curPos, minPos, maxPos);
 
   // get the thumb's rect
   nsIFrame* thumbFrame = mFrames.FirstChild();
   if (!thumbFrame)
     return NS_OK; // The thumb may stream in asynchronously via XBL.
 
   nsRect thumbRect = thumbFrame->GetRect();
 
--- a/layout/xul/base/src/nsStackLayout.cpp
+++ b/layout/xul/base/src/nsStackLayout.cpp
@@ -47,16 +47,18 @@
 #include "nsCOMPtr.h"
 #include "nsBoxLayoutState.h"
 #include "nsBox.h"
 #include "nsBoxFrame.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsINameSpaceManager.h"
 
+using namespace mozilla;
+
 nsBoxLayout* nsStackLayout::gInstance = nsnull;
 
 #define SPECIFIED_LEFT (1 << NS_SIDE_LEFT)
 #define SPECIFIED_RIGHT (1 << NS_SIDE_RIGHT)
 #define SPECIFIED_TOP (1 << NS_SIDE_TOP)
 #define SPECIFIED_BOTTOM (1 << NS_SIDE_BOTTOM)
 
 nsresult
@@ -330,34 +332,34 @@ nsStackLayout::Layout(nsIBox* aBox, nsBo
           // Margins on the child are also included in the edge offsets
           if (offsetSpecified) {
             if (offsetSpecified & SPECIFIED_LEFT) {
               childRect.x = clientRect.x + offset.left + margin.left;
               if (offsetSpecified & SPECIFIED_RIGHT) {
                 nsSize min = child->GetMinSize(aState);
                 nsSize max = child->GetMaxSize(aState);
                 nscoord width = clientRect.width - offset.LeftRight() - margin.LeftRight();
-                childRect.width = NS_MAX(min.width, NS_MIN(max.width, width));
+                childRect.width = clamped(width, min.width, max.width);
               }
               else {
                 childRect.width = child->GetPrefSize(aState).width;
               }
             }
             else if (offsetSpecified & SPECIFIED_RIGHT) {
               childRect.width = child->GetPrefSize(aState).width;
               childRect.x = clientRect.XMost() - offset.right - margin.right - childRect.width;
             }
 
             if (offsetSpecified & SPECIFIED_TOP) {
               childRect.y = clientRect.y + offset.top + margin.top;
               if (offsetSpecified & SPECIFIED_BOTTOM) {
                 nsSize min = child->GetMinSize(aState);
                 nsSize max = child->GetMaxSize(aState);
                 nscoord height = clientRect.height - offset.TopBottom() - margin.TopBottom();
-                childRect.height = NS_MAX(min.height, NS_MIN(max.height, height));
+                childRect.height = clamped(height, min.height, max.height);
               }
               else {
                 childRect.height = child->GetPrefSize(aState).height;
               }
             }
             else if (offsetSpecified & SPECIFIED_BOTTOM) {
               childRect.height = child->GetPrefSize(aState).height;
               childRect.y = clientRect.YMost() - offset.bottom - margin.bottom - childRect.height;
--- a/netwerk/cache/nsDiskCacheBlockFile.cpp
+++ b/netwerk/cache/nsDiskCacheBlockFile.cpp
@@ -37,16 +37,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsDiskCache.h"
 #include "nsDiskCacheBlockFile.h"
 #include "mozilla/FileUtils.h"
 
+using namespace mozilla;
+
 /******************************************************************************
  * nsDiskCacheBlockFile - 
  *****************************************************************************/
 
 /******************************************************************************
  *  Open
  *****************************************************************************/
 nsresult
@@ -388,17 +390,17 @@ nsDiskCacheBlockFile::Write(PRInt32 offs
         if (upTo > maxPreallocate) {
             // grow the file as a multiple of minPreallocate
             mFileSize = ((upTo + minPreallocate - 1) / minPreallocate) * minPreallocate;
         } else {
             // Grow quickly between 1MB to 20MB
             if (mFileSize)
                 while(mFileSize < upTo)
                     mFileSize *= 2;
-            mFileSize = NS_MIN(maxPreallocate, NS_MAX(mFileSize, minPreallocate));
+            mFileSize = clamped(mFileSize, minPreallocate, maxPreallocate);
         }
         mFileSize = NS_MIN(mFileSize, maxFileSize);
         //  Appears to cause bug 617123?  Disabled for now.
         //mozilla::fallocate(mFD, mFileSize);
     }
     if (PR_Seek(mFD, offset, PR_SEEK_SET) != offset)
         return false;
     return PR_Write(mFD, buf, amount) == amount;
--- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
+++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp
@@ -46,16 +46,17 @@
  *
  * Date         Modified by     Description of modification
  * 03/27/2000   IBM Corp.       Added PR_CALLBACK for Optlink
  *                               use in OS2
  */
 
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/FTPChannelChild.h"
+using namespace mozilla;
 using namespace mozilla::net;
 
 #include "nsFtpProtocolHandler.h"
 #include "nsFTPChannel.h"
 #include "nsIURL.h"
 #include "nsIStandardURL.h"
 #include "nsCRT.h"
 #include "nsIComponentManager.h"
@@ -63,16 +64,17 @@ using namespace mozilla::net;
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIProgressEventSink.h"
 #include "prlog.h"
 #include "nsNetUtil.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsIObserverService.h"
 #include "nsEscape.h"
+#include "nsAlgorithm.h"
 
 //-----------------------------------------------------------------------------
 
 #if defined(PR_LOGGING)
 //
 // Log module for FTP Protocol logging...
 //
 // To enable logging (see prlog.h for full details):
@@ -146,24 +148,24 @@ nsFtpProtocolHandler::Init()
             mIdleTimeout = 5*60; // 5 minute default
 
         rv = branch->AddObserver(IDLE_TIMEOUT_PREF, this, true);
         if (NS_FAILED(rv)) return rv;
 
 	PRInt32 val;
 	rv = branch->GetIntPref(QOS_DATA_PREF, &val);
 	if (NS_SUCCEEDED(rv))
-	    mDataQoSBits = (PRUint8) NS_CLAMP(val, 0, 0xff);
+	    mDataQoSBits = (PRUint8) clamped(val, 0, 0xff);
 
 	rv = branch->AddObserver(QOS_DATA_PREF, this, true);
 	if (NS_FAILED(rv)) return rv;
 
 	rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
 	if (NS_SUCCEEDED(rv))
-	    mControlQoSBits = (PRUint8) NS_CLAMP(val, 0, 0xff);
+	    mControlQoSBits = (PRUint8) clamped(val, 0, 0xff);
 
 	rv = branch->AddObserver(QOS_CONTROL_PREF, this, true);
 	if (NS_FAILED(rv)) return rv;
     }
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
@@ -410,21 +412,21 @@ nsFtpProtocolHandler::Observe(nsISupport
         }
         PRInt32 val;
         nsresult rv = branch->GetIntPref(IDLE_TIMEOUT_PREF, &val);
         if (NS_SUCCEEDED(rv))
             mIdleTimeout = val;
 
 	rv = branch->GetIntPref(QOS_DATA_PREF, &val);
 	if (NS_SUCCEEDED(rv))
-	    mDataQoSBits = (PRUint8) NS_CLAMP(val, 0, 0xff);
+	    mDataQoSBits = (PRUint8) clamped(val, 0, 0xff);
 
 	rv = branch->GetIntPref(QOS_CONTROL_PREF, &val);
 	if (NS_SUCCEEDED(rv))
-	    mControlQoSBits = (PRUint8) NS_CLAMP(val, 0, 0xff);
+	    mControlQoSBits = (PRUint8) clamped(val, 0, 0xff);
     } else if (!strcmp(aTopic, "network:offline-about-to-go-offline")) {
         ClearAllConnections();
     } else if (!strcmp(aTopic, "net:clear-active-logins")) {
         ClearAllConnections();
         mSessionId++;
     } else {
         NS_NOTREACHED("unexpected topic");
     }
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -63,16 +63,19 @@
 #include "nsIOService.h"
 #include "nsICacheService.h"
 #include "nsDNSPrefetch.h"
 #include "nsChannelClassifier.h"
 #include "nsIRedirectResultListener.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "nsDOMError.h"
+#include "nsAlgorithm.h"
+
+using namespace mozilla;
 
 // Device IDs for various cache types
 const char kDiskDeviceID[] = "disk";
 const char kMemoryDeviceID[] = "memory";
 const char kOfflineDeviceID[] = "offline";
 
 // True if the local cache should be bypassed when processing a request.
 #define BYPASS_LOCAL_CACHE(loadFlags) \
@@ -3786,17 +3789,17 @@ nsHttpChannel::SetupFallbackChannel(cons
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsISupportsPriority
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::SetPriority(PRInt32 value)
 {
-    PRInt16 newValue = NS_CLAMP(value, PR_INT16_MIN, PR_INT16_MAX);
+    PRInt16 newValue = clamped(value, PR_INT16_MIN, PR_INT16_MAX);
     if (mPriority == newValue)
         return NS_OK;
     mPriority = newValue;
     if (mTransaction)
         gHttpHandler->RescheduleTransaction(mTransaction, mPriority);
     return NS_OK;
 }
 
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -71,16 +71,17 @@
 #include "nsNetCID.h"
 #include "prprf.h"
 #include "nsReadableUtils.h"
 #include "nsQuickSort.h"
 #include "nsNetUtil.h"
 #include "nsIOService.h"
 #include "nsAsyncRedirectVerifyHelper.h"
 #include "nsSocketTransportService2.h"
+#include "nsAlgorithm.h"
 
 #include "nsIXULAppInfo.h"
 
 #include "mozilla/net/NeckoChild.h"
 
 #if defined(XP_UNIX)
 #include <sys/utsname.h>
 #endif
@@ -94,16 +95,17 @@
 #endif
 
 #if defined(XP_OS2)
 #define INCL_DOSMISC
 #include <os2.h>
 #endif
 
 //-----------------------------------------------------------------------------
+using namespace mozilla;
 using namespace mozilla::net;
 #include "mozilla/net/HttpChannelChild.h"
 
 #include "mozilla/FunctionTimer.h"
 
 #ifdef DEBUG
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
@@ -828,97 +830,97 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
 
     //
     // HTTP options
     //
 
     if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) {
         rv = prefs->GetIntPref(HTTP_PREF("keep-alive.timeout"), &val);
         if (NS_SUCCEEDED(rv))
-            mIdleTimeout = (PRUint16) NS_CLAMP(val, 1, 0xffff);
+            mIdleTimeout = (PRUint16) clamped(val, 1, 0xffff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) {
         rv = prefs->GetIntPref(HTTP_PREF("request.max-attempts"), &val);
         if (NS_SUCCEEDED(rv))
-            mMaxRequestAttempts = (PRUint16) NS_CLAMP(val, 1, 0xffff);
+            mMaxRequestAttempts = (PRUint16) clamped(val, 1, 0xffff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) {
         rv = prefs->GetIntPref(HTTP_PREF("request.max-start-delay"), &val);
         if (NS_SUCCEEDED(rv)) {
-            mMaxRequestDelay = (PRUint16) NS_CLAMP(val, 0, 0xffff);
+            mMaxRequestDelay = (PRUint16) clamped(val, 0, 0xffff);
             if (mConnMgr)
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY,
                                       mMaxRequestDelay);
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
         rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val);
         if (NS_SUCCEEDED(rv)) {
 
-            mMaxConnections = (PRUint16) NS_CLAMP((PRUint32)val,
-                                                  1, MaxSocketCount());
+            mMaxConnections = (PRUint16) clamped((PRUint32)val,
+                                                 (PRUint32)1, MaxSocketCount());
 
             if (mConnMgr)
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
                                       mMaxConnections);
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("max-connections-per-server"))) {
         rv = prefs->GetIntPref(HTTP_PREF("max-connections-per-server"), &val);
         if (NS_SUCCEEDED(rv)) {
-            mMaxConnectionsPerServer = (PRUint8) NS_CLAMP(val, 1, 0xff);
+            mMaxConnectionsPerServer = (PRUint8) clamped(val, 1, 0xff);
             if (mConnMgr) {
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS_PER_HOST,
                                       mMaxConnectionsPerServer);
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS_PER_PROXY,
                                       mMaxConnectionsPerServer);
             }
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) {
         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-server"), &val);
         if (NS_SUCCEEDED(rv)) {
-            mMaxPersistentConnectionsPerServer = (PRUint8) NS_CLAMP(val, 1, 0xff);
+            mMaxPersistentConnectionsPerServer = (PRUint8) clamped(val, 1, 0xff);
             if (mConnMgr)
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST,
                                       mMaxPersistentConnectionsPerServer);
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) {
         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-proxy"), &val);
         if (NS_SUCCEEDED(rv)) {
-            mMaxPersistentConnectionsPerProxy = (PRUint8) NS_CLAMP(val, 1, 0xff);
+            mMaxPersistentConnectionsPerProxy = (PRUint8) clamped(val, 1, 0xff);
             if (mConnMgr)
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
                                       mMaxPersistentConnectionsPerProxy);
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("sendRefererHeader"))) {
         rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), &val);
         if (NS_SUCCEEDED(rv))
-            mReferrerLevel = (PRUint8) NS_CLAMP(val, 0, 0xff);
+            mReferrerLevel = (PRUint8) clamped(val, 0, 0xff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
         rv = prefs->GetIntPref(HTTP_PREF("redirection-limit"), &val);
         if (NS_SUCCEEDED(rv))
-            mRedirectionLimit = (PRUint8) NS_CLAMP(val, 0, 0xff);
+            mRedirectionLimit = (PRUint8) clamped(val, 0, 0xff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
         rv = prefs->GetIntPref(HTTP_PREF("connection-retry-timeout"), &val);
         if (NS_SUCCEEDED(rv))
-            mIdleSynTimeout = (PRUint16) NS_CLAMP(val, 0, 3000);
+            mIdleSynTimeout = (PRUint16) clamped(val, 0, 3000);
     }
 
     if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
         rv = prefs->GetBoolPref(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
         if (NS_SUCCEEDED(rv))
             mFastFallbackToIPv4 = cVar;
     }
 
@@ -975,17 +977,17 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
             else
                 mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("pipelining.maxrequests"))) {
         rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxrequests"), &val);
         if (NS_SUCCEEDED(rv)) {
-            mMaxPipelinedRequests = NS_CLAMP(val, 1, NS_HTTP_MAX_PIPELINED_REQUESTS);
+            mMaxPipelinedRequests = clamped(val, 1, NS_HTTP_MAX_PIPELINED_REQUESTS);
             if (mConnMgr)
                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PIPELINED_REQUESTS,
                                       mMaxPipelinedRequests);
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("pipelining.ssl"))) {
         rv = prefs->GetBoolPref(HTTP_PREF("pipelining.ssl"), &cVar);
@@ -1001,17 +1003,17 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
             else
                 mProxyCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
         }
     }
 
     if (PREF_CHANGED(HTTP_PREF("qos"))) {
         rv = prefs->GetIntPref(HTTP_PREF("qos"), &val);
         if (NS_SUCCEEDED(rv))
-            mQoSBits = (PRUint8) NS_CLAMP(val, 0, 0xff);
+            mQoSBits = (PRUint8) clamped(val, 0, 0xff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("sendSecureXSiteReferrer"))) {
         rv = prefs->GetBoolPref(HTTP_PREF("sendSecureXSiteReferrer"), &cVar);
         if (NS_SUCCEEDED(rv))
             mSendSecureXSiteReferrer = cVar;
     }
 
@@ -1074,17 +1076,17 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar);
         if (NS_SUCCEEDED(rv))
             mEnablePersistentHttpsCaching = cVar;
     }
 
     if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) {
         rv = prefs->GetIntPref(HTTP_PREF("phishy-userpass-length"), &val);
         if (NS_SUCCEEDED(rv))
-            mPhishyUserPassLength = (PRUint8) NS_CLAMP(val, 0, 0xff);
+            mPhishyUserPassLength = (PRUint8) clamped(val, 0, 0xff);
     }
 
     //
     // INTL options
     //
 
     if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
         nsCOMPtr<nsIPrefLocalizedString> pls;
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -1972,50 +1972,50 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI
   prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
 
   if (prefService) {
     PRInt32 intpref;
     bool boolpref;
     rv = prefService->GetIntPref("network.websocket.max-message-size", 
                                  &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mMaxMessageSize = NS_CLAMP(intpref, 1024, 1 << 30);
+      mMaxMessageSize = clamped(intpref, 1024, 1 << 30);
     }
     rv = prefService->GetIntPref("network.websocket.timeout.close", &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mCloseTimeout = NS_CLAMP(intpref, 1, 1800) * 1000;
+      mCloseTimeout = clamped(intpref, 1, 1800) * 1000;
     }
     rv = prefService->GetIntPref("network.websocket.timeout.open", &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mOpenTimeout = NS_CLAMP(intpref, 1, 1800) * 1000;
+      mOpenTimeout = clamped(intpref, 1, 1800) * 1000;
     }
     rv = prefService->GetIntPref("network.websocket.timeout.ping.request",
                                  &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mPingTimeout = NS_CLAMP(intpref, 0, 86400) * 1000;
+      mPingTimeout = clamped(intpref, 0, 86400) * 1000;
     }
     rv = prefService->GetIntPref("network.websocket.timeout.ping.response",
                                  &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mPingResponseTimeout = NS_CLAMP(intpref, 1, 3600) * 1000;
+      mPingResponseTimeout = clamped(intpref, 1, 3600) * 1000;
     }
     rv = prefService->GetBoolPref("network.websocket.extensions.stream-deflate",
                                   &boolpref);
     if (NS_SUCCEEDED(rv)) {
       mAllowCompression = boolpref ? 1 : 0;
     }
     rv = prefService->GetBoolPref("network.websocket.auto-follow-http-redirects",
                                   &boolpref);
     if (NS_SUCCEEDED(rv)) {
       mAutoFollowRedirects = boolpref ? 1 : 0;
     }
     rv = prefService->GetIntPref
       ("network.websocket.max-connections", &intpref);
     if (NS_SUCCEEDED(rv)) {
-      mMaxConcurrentConnections = NS_CLAMP(intpref, 1, 0xffff);
+      mMaxConcurrentConnections = clamped(intpref, 1, 0xffff);
     }
   }
 
   if (sWebSocketAdmissions &&
       sWebSocketAdmissions->ConnectedCount() >= mMaxConcurrentConnections)
   {
     // Checking this early creates an optimal fast-fail, but it is
     // also a time-of-check-time-of-use problem. So we will check again
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -796,18 +796,18 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe
                     obs->RemoveObserver(notifier, "ipc:content-created");
             }
         }
 
         case AndroidGeckoEvent::MOTION_EVENT: {
             win->UserActivity();
             if (!gTopLevelWindows.IsEmpty()) {
                 nsIntPoint pt(ae->P0());
-                pt.x = NS_MIN(NS_MAX(pt.x, 0), gAndroidBounds.width - 1);
-                pt.y = NS_MIN(NS_MAX(pt.y, 0), gAndroidBounds.height - 1);
+                pt.x = clamped(pt.x, 0, gAndroidBounds.width - 1);
+                pt.y = clamped(pt.y, 0, gAndroidBounds.height - 1);
                 nsWindow *target = win->FindWindowForPoint(pt);
 
 #if 0
                 ALOG("MOTION_EVENT %f,%f -> %p (visible: %d children: %d)", ae->P0().x, ae->P0().y, (void*)target,
                      target ? target->mIsVisible : 0,
                      target ? target->mChildren.Length() : 0);
 
                 DumpWindows();
--- a/xpcom/base/nscore.h
+++ b/xpcom/base/nscore.h
@@ -420,21 +420,16 @@ typedef PRUint32 nsrefcnt;
 
 /*
  * Use NS_STRINGIFY to form a string literal from the value of a macro.
  */
 #define NS_STRINGIFY_HELPER(x_) #x_
 #define NS_STRINGIFY(x_) NS_STRINGIFY_HELPER(x_)
 
 /*
- * Use NS_CLAMP to force a value (such as a preference) into a range.
- */
-#define NS_CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
-
-/*
  * These macros allow you to give a hint to the compiler about branch
  * probability so that it can better optimize.  Use them like this:
  *
  *  if (NS_LIKELY(v == 1)) {
  *    ... expected code path ...
  *  }
  *
  *  if (NS_UNLIKELY(v == 0)) {
--- a/xpcom/string/public/nsAlgorithm.h
+++ b/xpcom/string/public/nsAlgorithm.h
@@ -75,16 +75,29 @@ NS_MIN( const T& a, const T& b )
 template <class T>
 inline
 const T&
 NS_MAX( const T& a, const T& b )
   {
     return a > b ? a : b;
   }
 
+namespace mozilla {
+
+template <class T>
+inline
+const T&
+clamped( const T& a, const T& min, const T& max )
+  {
+    NS_ABORT_IF_FALSE(max >= min, "clamped(): max must be greater than or equal to min");
+    return NS_MIN(NS_MAX(a, min), max);
+  }
+
+}
+
 template <class T>
 inline
 T
 NS_ABS( const T& a )
   {
     return a < 0 ? -a : a;
   }