2009-06-08 Adam Langley <agl@google.com>
authoragl@chromium.org <agl@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Jun 2009 17:52:30 +0000 (17:52 +0000)
committeragl@chromium.org <agl@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Jun 2009 17:52:30 +0000 (17:52 +0000)
        Reviewed by Eric Siedel.

        Chromium Linux ignored the background color on <select>s. Rather
        than encode magic colours, we start with a base color (specified
        via CSS) and derive the other colors from it. Thus, setting the
        CSS background-color now correctly changes the colour of the
        control.

        This should not change the appearence controls without
        background-colors. However, <select>s with a background-color
        will now renderer correctly, which may require rebaselining
        pixel tests in the Chromium tree.

        https://bugs.webkit.org/show_bug.cgi?id=26030
        http://code.google.com/p/chromium/issues/detail?id=12596

        * platform/graphics/Color.cpp:
        (WebCore::Color::getHSL): new member
        * platform/graphics/Color.h:
        * rendering/RenderThemeChromiumLinux.cpp:
        (WebCore::RenderThemeChromiumLinux::systemColor):
        (WebCore::brightenColor):
        (WebCore::paintButtonLike):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@44503 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/css/themeChromiumLinux.css [new file with mode: 0644]
WebCore/platform/graphics/Color.cpp
WebCore/platform/graphics/Color.h
WebCore/rendering/RenderThemeChromiumLinux.cpp
WebCore/rendering/RenderThemeChromiumLinux.h

index ab883a00ef3dbbd7c46766aff25f577e29bc49e3..9b7797fee08566ced86d8c5542612362d3364ae9 100644 (file)
@@ -1,3 +1,29 @@
+2009-06-08  Adam Langley  <agl@google.com>
+
+        Reviewed by Eric Siedel.
+
+        Chromium Linux ignored the background color on <select>s. Rather
+        than encode magic colours, we start with a base color (specified
+        via CSS) and derive the other colors from it. Thus, setting the
+        CSS background-color now correctly changes the colour of the
+        control.
+
+        This should not change the appearence controls without
+        background-colors. However, <select>s with a background-color
+        will now renderer correctly, which may require rebaselining
+        pixel tests in the Chromium tree.
+
+        https://bugs.webkit.org/show_bug.cgi?id=26030
+        http://code.google.com/p/chromium/issues/detail?id=12596
+
+        * platform/graphics/Color.cpp:
+        (WebCore::Color::getHSL): new member
+        * platform/graphics/Color.h:
+        * rendering/RenderThemeChromiumLinux.cpp:
+        (WebCore::RenderThemeChromiumLinux::systemColor):
+        (WebCore::brightenColor):
+        (WebCore::paintButtonLike):
+
 2009-06-08  Victor Wang <victorw@chromium.org>
 
         Reviewed by Dimitri Glazkov.
diff --git a/WebCore/css/themeChromiumLinux.css b/WebCore/css/themeChromiumLinux.css
new file mode 100644 (file)
index 0000000..f8210c3
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* These styles override other user-agent styles for Chromium on Linux. */
+
+select {
+    background-color: #dddddd;
+    border: 0px;
+}
index e85ac0053d6a4cb256d5f7977797d2207c66e1c6..d98b202d4f125d49f836435a5d68468b6aa508f7 100644 (file)
@@ -321,6 +321,41 @@ void Color::getRGBA(double& r, double& g, double& b, double& a) const
     a = alpha() / 255.0;
 }
 
+void Color::getHSL(double& hue, double& saturation, double& lightness) const
+{
+    // http://en.wikipedia.org/wiki/HSL_color_space. This is a direct copy of
+    // the algorithm therein, although it's 360^o based and we end up wanting
+    // [0...1) based. It's clearer if we stick to 360^o until the end.
+    double r = static_cast<double>(red()) / 255.0;
+    double g = static_cast<double>(green()) / 255.0;
+    double b = static_cast<double>(blue()) / 255.0;
+    double max = std::max(std::max(r, g), b);
+    double min = std::min(std::min(r, g), b);
+
+    if (max == min)
+        hue = 0.0;
+    else if (max == r)
+        hue = (60.0 * ((g - b) / (max - min))) + 360.0;
+    else if (max == g)
+        hue = (60.0 * ((b - r) / (max - min))) + 120.0;
+    else
+        hue = (60.0 * ((r - g) / (max - min))) + 240.0;
+
+    if (hue >= 360.0)
+        hue -= 360.0;
+
+    // makeRGBAFromHSLA assumes that hue is in [0...1).
+    hue /= 360.0;
+
+    lightness = 0.5 * (max + min);
+    if (max == min)
+        saturation = 0.0;
+    else if (lightness <= 0.5)
+        saturation = ((max - min) / (max + min));
+    else
+        saturation = ((max - min) / (2.0 - (max + min)));
+}
+
 Color colorFromPremultipliedARGB(unsigned pixelColor)
 {
     RGBA32 rgba;
index 04bf4c4df08ab410703756c4b735ecce21762b57..032d0cb85b4c62f3beca9e057bb78d8c713ef207 100644 (file)
@@ -94,6 +94,7 @@ public:
     void setRGB(RGBA32 rgb) { m_color = rgb; m_valid = true; }
     void getRGBA(float& r, float& g, float& b, float& a) const;
     void getRGBA(double& r, double& g, double& b, double& a) const;
+    void getHSL(double& h, double& s, double& l) const;
 
     Color light() const;
     Color dark() const;
index 94ee64ff5ec2af08fd46345dfa224c4ca22d8f08..804940325214510d6b6ced63ffa99c925371dbbc 100644 (file)
@@ -123,10 +123,20 @@ RenderThemeChromiumLinux::RenderThemeChromiumLinux()
 {
 }
 
+Color RenderThemeChromiumLinux::systemColor(int cssValueId) const
+{
+    static const Color linuxButtonGrayColor(0xffdddddd);
+
+    if (cssValueId == CSSValueButtonface)
+        return linuxButtonGrayColor;
+    return RenderTheme::systemColor(cssValueId);
+}
+
 // Use the Windows style sheets to match their metrics.
 String RenderThemeChromiumLinux::extraDefaultStyleSheet()
 {
-    return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
+    return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)) +
+           String(themeChromiumLinuxUserAgentStyleSheet, sizeof(themeChromiumLinuxUserAgentStyleSheet));
 }
 
 String RenderThemeChromiumLinux::extraQuirksStyleSheet()
@@ -253,16 +263,36 @@ void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const
     setCheckboxSize(style);
 }
 
-static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) {
+static SkColor brightenColor(double h, double s, double l, float brightenAmount)
+{
+    l += brightenAmount;
+    if (l > 1.0)
+        l = 1.0;
+    if (l < 0.0)
+        l = 0.0;
+
+    return makeRGBAFromHSLA(h, s, l, 1.0);
+}
+
+static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
     SkCanvas* const canvas = i.context->platformContext()->canvas();
     SkPaint paint;
     SkRect skrect;
     const int right = rect.x() + rect.width();
     const int bottom = rect.y() + rect.height();
+    SkColor baseColor = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd);
+    if (o->style()->hasBackground())
+        baseColor = o->style()->backgroundColor().rgb();
+    double h, s, l;
+    Color(baseColor).getHSL(h, s, l);
+    // Our standard gradient is from 0xdd to 0xf8. This is the amount of
+    // increased luminance between those values.
+    SkColor lightColor(brightenColor(h, s, l, 0.105));
 
     // If the button is too small, fallback to drawing a single, solid color
     if (rect.width() < 5 || rect.height() < 5) {
-        paint.setARGB(0xff, 0xe9, 0xe9, 0xe9);
+        paint.setColor(baseColor);
         skrect.set(rect.x(), rect.y(), right, bottom);
         canvas->drawRect(skrect, paint);
         return;
@@ -282,20 +312,20 @@ static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObj
     p[lightEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y()));
     p[darkEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(bottom - 1));
     SkColor colors[2];
-    colors[0] = SkColorSetARGB(0xff, 0xf8, 0xf8, 0xf8);
-    colors[1] = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd);
+    colors[0] = lightColor;
+    colors[1] = baseColor;
 
-    SkShader* s = SkGradientShader::CreateLinear(
+    SkShader* shader = SkGradientShader::CreateLinear(
         p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL);
     paint.setStyle(SkPaint::kFill_Style);
-    paint.setShader(s);
-    s->unref();
+    paint.setShader(shader);
+    shader->unref();
 
     skrect.set(rect.x() + 1, rect.y() + 1, right - 1, bottom - 1);
     canvas->drawRect(skrect, paint);
 
     paint.setShader(NULL);
-    paint.setARGB(0xff, 0xce, 0xce, 0xce);
+    paint.setColor(brightenColor(h, s, l, -0.0588));
     canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint);
     canvas->drawPoint(right - 2, rect.y() + 1, paint);
     canvas->drawPoint(rect.x() + 1, bottom - 2, paint);
index 78385092f52ad1861d843b56b830e5b6d53b09eb..11239d9bebc6a19c12100c660c34153019127af2 100644 (file)
@@ -60,6 +60,7 @@ namespace WebCore {
 
         // System fonts.
         virtual void systemFont(int propId, FontDescription&) const;
+        virtual Color systemColor(int cssValidId) const;
 
         virtual int minimumMenuListSize(RenderStyle*) const;