Bug 665571 - Have DrawCellWithSnapping handles special NSZeroSize value in CellRenderSettings. r=mstange
authorMounir Lamouri <mounir.lamouri@gmail.com>
Fri, 08 Jul 2011 14:56:44 +0200
changeset 72565 0bd82b867cf012b05c1c283341f1ceea2dbe0ebc
parent 72564 364d2debc2a7c95797d1e03db5076ad0b8684183
child 72566 f53268a84b23ca67cb6cc5c8c867f0f2c582e37c
push id20738
push userkhuey@mozilla.com
push dateSun, 10 Jul 2011 03:19:43 +0000
treeherdermozilla-central@518a79e90444 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs665571
milestone8.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 665571 - Have DrawCellWithSnapping handles special NSZeroSize value in CellRenderSettings. r=mstange
widget/src/cocoa/nsNativeThemeCocoa.mm
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -275,16 +275,25 @@ static int EnumSizeForCocoaSize(NSContro
   if (cocoaControlSize == NSMiniControlSize)
     return miniControlSize;
   else if (cocoaControlSize == NSSmallControlSize)
     return smallControlSize;
   else
     return regularControlSize;
 }
 
+static NSControlSize CocoaSizeForEnum(PRInt32 enumControlSize) {
+  if (enumControlSize == miniControlSize)
+    return NSMiniControlSize;
+  else if (enumControlSize == smallControlSize)
+    return NSSmallControlSize;
+  else
+    return NSRegularControlSize;
+}
+
 static void InflateControlRect(NSRect* rect, NSControlSize cocoaControlSize, const float marginSet[][3][4])
 {
   if (!marginSet)
     return;
 
   static int osIndex = leopardOS;
   int controlSize = EnumSizeForCocoaSize(cocoaControlSize);
   const float* buttonMargins = marginSet[osIndex][controlSize];
@@ -552,16 +561,59 @@ struct CellRenderSettings {
   // A three-dimensional array,
   // with the first dimension being the OS version (only Leopard for the moment),
   // the second being the control size (mini, small, regular), and the third
   // being the 4 margin values (left, top, right, bottom).
   float margins[1][3][4];
 };
 
 /*
+ * This is a helper method that returns the required NSControlSize given a size
+ * and the size of the three controls plus a tolerance.
+ * size - The width or the height of the element to draw.
+ * sizes - An array with the all the width/height of the element for its
+ *         different sizes.
+ * tolerance - The tolerance as passed to DrawCellWithSnapping.
+ * NOTE: returns NSRegularControlSize if all values in 'sizes' are zero.
+ */
+static NSControlSize FindControlSize(CGFloat size, CGFloat* sizes, CGFloat tolerance)
+{
+  for (PRUint32 i = miniControlSize; i <= regularControlSize; ++i) {
+    if (sizes[i] == 0) {
+      continue;
+    }
+
+    CGFloat next = 0;
+    // Find next value.
+    for (PRUint32 j = i+1; j <= regularControlSize; ++j) {
+      if (sizes[j] != 0) {
+        next = sizes[j];
+        break;
+      }
+    }
+
+    // If it's the latest value, we pick it.
+    if (next == 0) {
+      return CocoaSizeForEnum(i);
+    }
+
+    if (size <= sizes[i] + tolerance && size < next) {
+      return CocoaSizeForEnum(i);
+    }
+  }
+
+  // If we are here, that means sizes[] was an array with only empty values
+  // or the algorithm above is wrong.
+  // The former can happen but the later would be wrong.
+  NS_ASSERTION(sizes[0] == 0 && sizes[1] == 0 && sizes[2] == 0,
+               "We found no control! We shouldn't be there!");
+  return CocoaSizeForEnum(regularControlSize);
+}
+
+/*
  * Draw the given NSCell into the given cgContext with a nice control size.
  *
  * This function is similar to DrawCellWithScaling, but it decides what
  * control size to use based on the destRect's size.
  * Scaling is only applied when the difference between the destRect's size
  * and the next smaller natural size is greater than snapTolerance. Otherwise
  * it snaps to the next smaller control size without scaling because unscaled
  * controls look nicer.
@@ -578,28 +630,22 @@ static void DrawCellWithSnapping(NSCell 
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   const float rectWidth = destRect.size.width, rectHeight = destRect.size.height;
   const NSSize *sizes = settings.naturalSizes;
   const NSSize miniSize = sizes[EnumSizeForCocoaSize(NSMiniControlSize)];
   const NSSize smallSize = sizes[EnumSizeForCocoaSize(NSSmallControlSize)];
   const NSSize regularSize = sizes[EnumSizeForCocoaSize(NSRegularControlSize)];
 
-  NSControlSize controlSizeX = NSRegularControlSize, controlSizeY = NSRegularControlSize;
   HIRect drawRect = destRect;
 
-  if (rectWidth <= miniSize.width + snapTolerance && rectWidth < smallSize.width)
-    controlSizeX = NSMiniControlSize;
-  else if(rectWidth <= smallSize.width + snapTolerance && rectWidth < regularSize.width)
-    controlSizeX = NSSmallControlSize;
-
-  if (rectHeight <= miniSize.height + snapTolerance && rectHeight < smallSize.height)
-    controlSizeY = NSMiniControlSize;
-  else if(rectHeight <= smallSize.height + snapTolerance && rectHeight < regularSize.height)
-    controlSizeY = NSSmallControlSize;
+  CGFloat controlWidths[3] = { miniSize.width, smallSize.width, regularSize.width };
+  NSControlSize controlSizeX = FindControlSize(rectWidth, controlWidths, snapTolerance);
+  CGFloat controlHeights[3] = { miniSize.height, smallSize.height, regularSize.height };
+  NSControlSize controlSizeY = FindControlSize(rectHeight, controlHeights, snapTolerance);
 
   NSControlSize controlSize = NSRegularControlSize;
   int sizeIndex = 0;
 
   // At some sizes, don't scale but snap.
   const NSControlSize smallerControlSize =
     EnumSizeForCocoaSize(controlSizeX) < EnumSizeForCocoaSize(controlSizeY) ?
     controlSizeX : controlSizeY;