<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[169685] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/169685">169685</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2014-06-08 17:02:00 -0700 (Sun, 08 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Mac] checkboxes and radio buttons animate incorrectly
https://bugs.webkit.org/show_bug.cgi?id=133619
&lt;rdar://problem/16478676&gt;

Reviewed by Sam Weinig.

As many people have noticed, the new checkboxes and radio
buttons jump around during their animation. To fix this
I've added yet another magic set of numbers to our
native form positioning - this time the placement
of the controls when rendering on the animated path.
This is quite annoying, since there doesn't appear
to be any pattern to the offsets (or margins) given
a control size, and this case also needed a sub-pixel
offset to display correctly on retina machines.

* platform/mac/ThemeMac.mm:
(WebCore::checkboxMargins): Add comment so I know what the values mean.
(WebCore::checkboxOffsets): Add the magic translation values for animated states.
(WebCore::radioMargins): Ditto.
(WebCore::radioOffsets):
(WebCore::paintToggleButton): Paint with these new offsets.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformmacThemeMacmm">trunk/Source/WebCore/platform/mac/ThemeMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169684 => 169685)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-08 23:21:31 UTC (rev 169684)
+++ trunk/Source/WebCore/ChangeLog        2014-06-09 00:02:00 UTC (rev 169685)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2014-06-08  Dean Jackson  &lt;dino@apple.com&gt;
+
+        [Mac] checkboxes and radio buttons animate incorrectly
+        https://bugs.webkit.org/show_bug.cgi?id=133619
+        &lt;rdar://problem/16478676&gt;
+
+        Reviewed by Sam Weinig.
+
+        As many people have noticed, the new checkboxes and radio
+        buttons jump around during their animation. To fix this
+        I've added yet another magic set of numbers to our
+        native form positioning - this time the placement
+        of the controls when rendering on the animated path.
+        This is quite annoying, since there doesn't appear
+        to be any pattern to the offsets (or margins) given
+        a control size, and this case also needed a sub-pixel
+        offset to display correctly on retina machines.
+
+        * platform/mac/ThemeMac.mm:
+        (WebCore::checkboxMargins): Add comment so I know what the values mean.
+        (WebCore::checkboxOffsets): Add the magic translation values for animated states.
+        (WebCore::radioMargins): Ditto.
+        (WebCore::radioOffsets):
+        (WebCore::paintToggleButton): Paint with these new offsets.
+
</ins><span class="cx"> 2014-06-07  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Regression r168397 - Form layout is incorrect on OS X Yosemite
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacThemeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/ThemeMac.mm (169684 => 169685)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/ThemeMac.mm        2014-06-08 23:21:31 UTC (rev 169684)
+++ trunk/Source/WebCore/platform/mac/ThemeMac.mm        2014-06-09 00:02:00 UTC (rev 169685)
</span><span class="lines">@@ -282,6 +282,7 @@
</span><span class="cx"> {
</span><span class="cx">     static const int margins[3][4] =
</span><span class="cx">     {
</span><ins>+        // top left right bottom
</ins><span class="cx">         { 3, 4, 4, 2 },
</span><span class="cx">         { 4, 3, 3, 3 },
</span><span class="cx">         { 4, 3, 3, 3 },
</span><span class="lines">@@ -298,7 +299,17 @@
</span><span class="cx">     // Use the font size to determine the intrinsic width of the control.
</span><span class="cx">     return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes());
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+static const std::array&lt;FloatSize, 3&gt;&amp; checkboxOffsets()
+{
+    // This provides the positioning tweak we need to place controls
+    // at the right location during animation.
+    static const std::array&lt;FloatSize, 3&gt; sizes = { { FloatSize(0, 2), FloatSize(2, 1.5), FloatSize(3, 3) } };
+    return sizes;
+}
+#endif
+
</ins><span class="cx"> // Radio Buttons
</span><span class="cx"> 
</span><span class="cx"> static const std::array&lt;IntSize, 3&gt;&amp; radioSizes()
</span><span class="lines">@@ -311,6 +322,7 @@
</span><span class="cx"> {
</span><span class="cx">     static const int margins[3][4] =
</span><span class="cx">     {
</span><ins>+        // top left right bottom
</ins><span class="cx">         { 2, 2, 4, 2 },
</span><span class="cx">         { 3, 2, 3, 2 },
</span><span class="cx">         { 1, 0, 2, 0 },
</span><span class="lines">@@ -318,6 +330,16 @@
</span><span class="cx">     return margins[controlSize];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+static const std::array&lt;FloatSize, 3&gt;&amp; radioOffsets()
+{
+    // This provides the positioning tweak we need to place controls
+    // at the right location during animation.
+    static const std::array&lt;FloatSize, 3&gt; sizes = { { FloatSize(0, 2), FloatSize(1, 2), FloatSize(0, 1) } };
+    return sizes;
+}
+#endif
+
</ins><span class="cx"> static LengthSize radioSize(const Font&amp; font, const LengthSize&amp; zoomedSize, float zoomFactor)
</span><span class="cx"> {
</span><span class="cx">     // If the width and height are both specified, then we have nothing to do.
</span><span class="lines">@@ -422,21 +444,24 @@
</span><span class="cx"> 
</span><span class="cx">     LocalCurrentGraphicsContext localContext(context);
</span><span class="cx">     NSView *view = ThemeMac::ensuredView(scrollView, controlStates);
</span><del>-    bool drawStatically = true;
</del><ins>+
</ins><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
</span><del>-    drawStatically = ![toggleButtonCell _stateAnimationRunning];
-#endif
-    if (drawStatically)
-        [toggleButtonCell drawWithFrame:NSRect(inflatedRect) inView:view];
-    else {
-        // FIXME: This isn't quite correct at the moment due to the way the tick mark extends out of the control.
</del><ins>+    if ([toggleButtonCell _stateAnimationRunning]) {
+        // AppKit's drawWithFrame appears to render the cell centered in the
+        // provided rectangle/frame, so we need to manually position the
+        // animated cell at the correct location.
</ins><span class="cx">         context-&gt;translate(inflatedRect.x(), inflatedRect.y());
</span><span class="cx">         context-&gt;scale(FloatSize(1, -1));
</span><span class="cx">         context-&gt;translate(0, -inflatedRect.height());
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
</del><ins>+        FloatSize controlOffsets = buttonType == CheckboxPart ? checkboxOffsets()[controlSize] : radioOffsets()[controlSize];
+        context-&gt;translate(controlOffsets);
</ins><span class="cx">         [toggleButtonCell _renderCurrentAnimationFrameInContext:context-&gt;platformContext() atLocation:NSMakePoint(0, 0)];
</span><ins>+    } else
+        [toggleButtonCell drawWithFrame:NSRect(inflatedRect) inView:view];
+#else
+    [toggleButtonCell drawWithFrame:NSRect(inflatedRect) inView:view];
</ins><span class="cx"> #endif
</span><del>-    }
</del><ins>+
</ins><span class="cx">     bool needsRepaint = false;
</span><span class="cx">     if (controlStates-&gt;states() &amp; ControlStates::FocusState)
</span><span class="cx">         needsRepaint = drawCellFocusRing(toggleButtonCell, inflatedRect, view);
</span></span></pre>
</div>
</div>

</body>
</html>