Bug 468507 - Use DrawCellWithSnapping when drawing push buttons, r=josh sr=dbaron
authorMarkus Stange <mstange@themasta.com>
Mon, 12 Jan 2009 20:22:59 +0100
changeset 23556 a4cc5f89569d33cd78d23180b53c7a78c2c66ddd
parent 23555 54cf0cbe42e80714ec9cca64771d5e51f7e51f86
child 23557 119de4e0e61280e5dc2b68276fbda23e55ed116f
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjosh, dbaron
bugs468507
milestone1.9.2a1pre
Bug 468507 - Use DrawCellWithSnapping when drawing push buttons, r=josh sr=dbaron
widget/src/cocoa/nsNativeThemeCocoa.mm
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -399,62 +399,62 @@ struct CellRenderSettings {
 };
 
 /*
  * 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 sSnapTolerance. Otherwise
+ * 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.
  */
-static const float sSnapTolerance = 2.0f;
 static void DrawCellWithSnapping(NSCell *cell,
                                  CGContextRef cgContext,
                                  const HIRect& destRect,
                                  const CellRenderSettings settings,
                                  float verticalAlignFactor,
-                                 NSView* view)
+                                 NSView* view,
+                                 float snapTolerance = 2.0f)
 {
   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 + sSnapTolerance && rectWidth < smallSize.width)
+  if (rectWidth <= miniSize.width + snapTolerance && rectWidth < smallSize.width)
     controlSizeX = NSMiniControlSize;
-  else if(rectWidth <= smallSize.width + sSnapTolerance && rectWidth < regularSize.width)
+  else if(rectWidth <= smallSize.width + snapTolerance && rectWidth < regularSize.width)
     controlSizeX = NSSmallControlSize;
 
-  if (rectHeight <= miniSize.height + sSnapTolerance && rectHeight < smallSize.height)
+  if (rectHeight <= miniSize.height + snapTolerance && rectHeight < smallSize.height)
     controlSizeY = NSMiniControlSize;
-  else if(rectHeight <= smallSize.height + sSnapTolerance && rectHeight < regularSize.height)
+  else if(rectHeight <= smallSize.height + snapTolerance && rectHeight < regularSize.height)
     controlSizeY = NSSmallControlSize;
 
   NSControlSize controlSize = NSRegularControlSize;
   int sizeIndex = 0;
 
   // At some sizes, don't scale but snap.
   const NSControlSize smallerControlSize =
     EnumSizeForCocoaSize(controlSizeX) < EnumSizeForCocoaSize(controlSizeY) ?
     controlSizeX : controlSizeY;
   const int smallerControlSizeIndex = EnumSizeForCocoaSize(smallerControlSize);
   const NSSize size = sizes[smallerControlSizeIndex];
   float diffWidth = size.width ? rectWidth - size.width : 0.0f;
   float diffHeight = size.height ? rectHeight - size.height : 0.0f;
   if (diffWidth >= 0.0f && diffHeight >= 0.0f &&
-      diffWidth <= sSnapTolerance && diffHeight <= sSnapTolerance) {
+      diffWidth <= snapTolerance && diffHeight <= snapTolerance) {
     // Snap to the smaller control size.
     controlSize = smallerControlSize;
     sizeIndex = smallerControlSizeIndex;
     // Resize and center the drawRect.
     if (sizes[sizeIndex].width) {
       drawRect.origin.x += ceil((destRect.size.width - sizes[sizeIndex].width) / 2);
       drawRect.size.width = sizes[sizeIndex].width;
     }
@@ -625,95 +625,73 @@ nsNativeThemeCocoa::DrawSearchField(CGCo
 
   DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings,
                        VerticalAlignFactor(aFrame), NativeViewForFrame(aFrame));
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 
-// These are the sizes that Gecko needs to request to draw if it wants
-// to get a standard-sized Aqua rounded bevel button drawn. Note that
-// the rects that draw these are actually a little bigger.
-#define NATURAL_MINI_ROUNDED_BUTTON_MIN_WIDTH 18
-#define NATURAL_MINI_ROUNDED_BUTTON_HEIGHT 16
-#define NATURAL_SMALL_ROUNDED_BUTTON_MIN_WIDTH 26
-#define NATURAL_SMALL_ROUNDED_BUTTON_HEIGHT 19
-#define NATURAL_REGULAR_ROUNDED_BUTTON_MIN_WIDTH 30
-#define NATURAL_REGULAR_ROUNDED_BUTTON_HEIGHT 22
-
-// These were calculated by testing all three sizes on the respective operating system.
-static const float pushButtonMargins[2][3][4] =
-{
-  { // Tiger
-    {1, 1, 1, 1}, // mini
-    {5, 1, 5, 1}, // small
-    {6, 0, 6, 2}  // regular
+static const CellRenderSettings pushButtonSettings = {
+  {
+    NSMakeSize(0, 16), // mini
+    NSMakeSize(0, 19), // small
+    NSMakeSize(0, 22)  // regular
+  },
+  {
+    NSMakeSize(18, 0), // mini
+    NSMakeSize(26, 0), // small
+    NSMakeSize(30, 0)  // regular
   },
-  { // Leopard
-    {0, 0, 0, 0}, // mini
-    {4, 0, 4, 1}, // small
-    {5, 0, 5, 2}  // regular
+  {
+    { // Tiger
+      {1, 1, 1, 1},    // mini
+      {5, 1, 5, 1},    // small
+      {6, 0, 6, 2}     // regular
+    },
+    { // Leopard
+      {0, 0, 0, 0},    // mini
+      {4, 0, 4, 1},    // small
+      {5, 0, 5, 2}     // regular
+    }
   }
 };
 
+
 // The height at which we start doing square buttons instead of rounded buttons
 // Rounded buttons look bad if drawn at a height greater than 26, so at that point
 // we switch over to doing square buttons which looks fine at any size.
 #define DO_SQUARE_BUTTON_HEIGHT 26
 
 void
 nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect, PRBool inIsDefault,
                                    PRBool inDisabled, PRInt32 inState, nsIFrame* aFrame)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
-  NSRect drawRect = NSMakeRect(inBoxRect.origin.x, inBoxRect.origin.y, inBoxRect.size.width, inBoxRect.size.height);
-
   BOOL isActive = FrameIsInActiveWindow(aFrame);
 
   [mPushButtonCell setEnabled:!inDisabled];
   [mPushButtonCell setHighlighted:(((inState & NS_EVENT_STATE_ACTIVE) &&
                                     (inState & NS_EVENT_STATE_HOVER) ||
                                     (inIsDefault && !inDisabled)) && 
                                    isActive)];
   [mPushButtonCell setShowsFirstResponder:(inState & NS_EVENT_STATE_FOCUS) && !inDisabled && isActive];
 
   // If the button is tall enough, draw the square button style so that buttons with
   // non-standard content look good. Otherwise draw normal rounded aqua buttons.
-  if (drawRect.size.height > DO_SQUARE_BUTTON_HEIGHT) {
+  if (inBoxRect.size.height > DO_SQUARE_BUTTON_HEIGHT) {
     [mPushButtonCell setBezelStyle:NSShadowlessSquareBezelStyle];
     DrawCellWithScaling(mPushButtonCell, cgContext, inBoxRect, NSRegularControlSize,
                         NSZeroSize, NSMakeSize(14, 0), NULL, NativeViewForFrame(aFrame));
   } else {
     [mPushButtonCell setBezelStyle:NSRoundedBezelStyle];
 
-    // Figure out what size cell control we're going to draw and grab its
-    // natural height and min width.
-    NSControlSize controlSize = NSRegularControlSize;
-    float naturalHeight = NATURAL_REGULAR_ROUNDED_BUTTON_HEIGHT;
-    float minWidth = NATURAL_REGULAR_ROUNDED_BUTTON_MIN_WIDTH;
-    if (drawRect.size.height <= NATURAL_MINI_ROUNDED_BUTTON_HEIGHT &&
-        drawRect.size.width >= NATURAL_MINI_ROUNDED_BUTTON_MIN_WIDTH) {
-      controlSize = NSMiniControlSize;
-      naturalHeight = NATURAL_MINI_ROUNDED_BUTTON_HEIGHT;
-      minWidth = NATURAL_MINI_ROUNDED_BUTTON_MIN_WIDTH;
-    }
-    else if (drawRect.size.height <= NATURAL_SMALL_ROUNDED_BUTTON_HEIGHT &&
-             drawRect.size.width >= NATURAL_SMALL_ROUNDED_BUTTON_MIN_WIDTH) {
-      controlSize = NSSmallControlSize;
-      naturalHeight = NATURAL_SMALL_ROUNDED_BUTTON_HEIGHT;
-      minWidth = NATURAL_SMALL_ROUNDED_BUTTON_MIN_WIDTH;
-    }
-    [mPushButtonCell setControlSize:controlSize];
-
-    DrawCellWithScaling(mPushButtonCell, cgContext, inBoxRect, controlSize,
-                        NSMakeSize(0.0f, naturalHeight),
-                        NSMakeSize(minWidth, 0.0f), pushButtonMargins,
-                        NativeViewForFrame(aFrame));
+    DrawCellWithSnapping(mPushButtonCell, cgContext, inBoxRect, pushButtonSettings,
+                         0.5f, NativeViewForFrame(aFrame), 1.0f);
   }
 
 #if DRAW_IN_FRAME_DEBUG
   CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.25);
   CGContextFillRect(cgContext, inBoxRect);
 #endif
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
@@ -2017,17 +1995,18 @@ nsNativeThemeCocoa::GetMinimumWidgetSize
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   aResult->SizeTo(0,0);
   *aIsOverridable = PR_TRUE;
 
   switch (aWidgetType) {
     case NS_THEME_BUTTON:
     {
-      aResult->SizeTo(NATURAL_MINI_ROUNDED_BUTTON_MIN_WIDTH, NATURAL_MINI_ROUNDED_BUTTON_HEIGHT);
+      aResult->SizeTo(pushButtonSettings.minimumSizes[miniControlSize].width,
+                      pushButtonSettings.naturalSizes[miniControlSize].height);
       break;
     }
 
     case NS_THEME_SPINNER:
     {
       SInt32 buttonHeight = 0, buttonWidth = 0;
       ::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
       ::GetThemeMetric(kThemeMetricLittleArrowsHeight, &buttonHeight);