Commit cb7f065b authored by hyatt's avatar hyatt
Browse files

Add selection foreground color on Win32.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@14827 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5db72767
2006-06-12 Dave Hyatt <hyatt@apple.com>
Add the notion of a selection foreground color to the engine for
Win32. Rename existing selectionColor methods to be
selectionBackgroundColor instead.
Change the 60% alpha blend rule for transparent selection to
instead be a range from 60-80%, with less transparency being
used as needed to ensure the transformed color more closely
approximates the original operating system color when blended
with a white background.
Reviewed by mjs
* platform/Color.cpp:
(WebCore::blend):
(WebCore::Color::blendWithWhite):
* platform/Color.h:
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::paintSelection):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::fillHorizontalSelectionGap):
(WebCore::RenderBlock::fillVerticalSelectionGap):
(WebCore::RenderBlock::fillLeftSelectionGap):
(WebCore::RenderBlock::fillRightSelectionGap):
* rendering/RenderHTMLCanvas.cpp:
(WebCore::RenderHTMLCanvas::paint):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paint):
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::paint):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::selectionBackgroundColor):
(WebCore::RenderObject::selectionForegroundColor):
* rendering/RenderObject.h:
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::activeSelectionBackgroundColor):
(WebCore::RenderTheme::inactiveSelectionBackgroundColor):
(WebCore::RenderTheme::platformActiveSelectionBackgroundColor):
(WebCore::RenderTheme::platformInactiveSelectionBackgroundColor):
(WebCore::RenderTheme::platformActiveSelectionForegroundColor):
(WebCore::RenderTheme::platformInactiveSelectionForegroundColor):
* rendering/RenderTheme.h:
* rendering/RenderThemeMac.h:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::platformActiveSelectionBackgroundColor):
(WebCore::RenderThemeMac::platformInactiveSelectionBackgroundColor):
* rendering/RenderThemeWin.cpp:
(WebCore::RenderThemeWin::platformActiveSelectionBackgroundColor):
(WebCore::RenderThemeWin::platformInactiveSelectionBackgroundColor):
(WebCore::RenderThemeWin::platformActiveSelectionForegroundColor):
(WebCore::RenderThemeWin::platformInactiveSelectionForegroundColor):
* rendering/RenderThemeWin.h:
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::paint):
2006-06-12 John Sullivan <sullivan@apple.com>
Reviewed by Darin Adler.
......
......@@ -218,19 +218,33 @@ static int blend(int c, int a)
float alpha = (float)(a) / 255;
int whiteBlend = 255 - a;
c -= whiteBlend;
c = max(0, c);
return min(255, (int)(c / alpha)); // Clamp to be within 0-255
return (int)(c / alpha);
}
Color Color::blendWithWhite(int alpha) const
const int cStartAlpha = 153; // 60%
const int cEndAlpha = 204; // 80%;
const int cAlphaIncrement = 17; // Increments in between.
Color Color::blendWithWhite() const
{
// If the color contains alpha already, we leave it alone.
if (hasAlpha())
return *this;
// We have a solid color. Convert to an equivalent color that looks the same when blended with white
// at the alpha specified.
return Color(blend(red(), alpha), blend(green(), alpha), blend(blue(), alpha), alpha);
Color newColor;
for (int alpha = cStartAlpha; alpha <= cEndAlpha; alpha += cAlphaIncrement) {
// We have a solid color. Convert to an equivalent color that looks the same when blended with white
// at the current alpha. Try using less transparency if the numbers end up being negative.
int r = blend(red(), alpha);
int g = blend(green(), alpha);
int b = blend(blue(), alpha);
newColor = Color(r, g, b, alpha);
if (r >= 0 && g >= 0 && b >= 0)
break;
}
return newColor;
}
void Color::getRGBA(float& r, float& g, float& b, float& a) const
......
......@@ -79,7 +79,7 @@ public:
Color light() const;
Color dark() const;
Color blendWithWhite(int alpha) const;
Color blendWithWhite() const;
static const RGBA32 black = 0xFF000000;
static const RGBA32 white = 0xFFFFFFFF;
......
......@@ -322,16 +322,19 @@ void InlineTextBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
Color selectionColor = i.p->pen().color();
ShadowData* selectionTextShadow = 0;
if (haveSelection) {
// Check foreground color first.
Color foreground = object()->selectionForegroundColor();
if (foreground.isValid() && foreground != selectionColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionColor = foreground;
}
RenderStyle* pseudoStyle = object()->getPseudoStyle(RenderStyle::SELECTION);
if (pseudoStyle) {
if (pseudoStyle->color() != selectionColor || pseudoStyle->textShadow()) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
if (pseudoStyle->color() != selectionColor)
selectionColor = pseudoStyle->color();
if (pseudoStyle->textShadow())
selectionTextShadow = pseudoStyle->textShadow();
}
if (pseudoStyle && pseudoStyle->textShadow()) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
if (pseudoStyle->textShadow())
selectionTextShadow = pseudoStyle->textShadow();
}
}
......@@ -437,10 +440,9 @@ void InlineTextBox::paintSelection(GraphicsContext* p, int tx, int ty, RenderSty
if (sPos >= ePos)
return;
// Macintosh-style text highlighting is to draw with a particular background color, not invert.
Color textColor = style->color();
Color c = object()->selectionColor();
if (!c.isValid())
Color c = object()->selectionBackgroundColor();
if (!c.isValid() || c.alpha() == 0)
return;
// If the text color ends up being the same as the selection background, invert the selection
......
......@@ -1637,7 +1637,7 @@ IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos,
return IntRect();
IntRect gapRect(xPos, yPos, width, height);
if (i)
i->p->fillRect(gapRect, selObj->selectionColor());
i->p->fillRect(gapRect, selObj->selectionBackgroundColor());
return gapRect;
}
......@@ -1659,7 +1659,7 @@ IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int las
IntRect gapRect(left, top, width, height);
if (i)
i->p->fillRect(gapRect, selectionColor());
i->p->fillRect(gapRect, selectionBackgroundColor());
return gapRect;
}
......@@ -1673,7 +1673,7 @@ IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yP
IntRect gapRect(left, top, width, height);
if (i)
i->p->fillRect(gapRect, selObj->selectionColor());
i->p->fillRect(gapRect, selObj->selectionBackgroundColor());
return gapRect;
}
......@@ -1688,7 +1688,7 @@ IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int y
IntRect gapRect(left, top, width, height);
if (i)
i->p->fillRect(gapRect, selObj->selectionColor());
i->p->fillRect(gapRect, selObj->selectionBackgroundColor());
return gapRect;
}
......
......@@ -77,7 +77,7 @@ void RenderHTMLCanvas::paint(PaintInfo& i, int tx, int ty)
IntRect(x + borderLeft() + paddingLeft(), y + borderTop() + paddingTop(), contentWidth(), contentHeight()));
if (drawSelectionTint)
i.p->fillRect(selectionRect(), selectionColor());
i.p->fillRect(selectionRect(), selectionBackgroundColor());
}
void RenderHTMLCanvas::layout()
......
......@@ -266,7 +266,7 @@ void RenderImage::paint(PaintInfo& i, int _tx, int _ty)
p->drawImage(image(), rect, compositeOperator);
if (drawSelectionTint)
p->fillRect(selectionRect(), selectionColor());
p->fillRect(selectionRect(), selectionBackgroundColor());
}
}
......
......@@ -187,7 +187,7 @@ void RenderListMarker::paint(PaintInfo& i, int _tx, int _ty)
if (m_listImage && !m_listImage->isErrorImage()) {
p->drawImage(m_listImage->image(), marker.location());
if (selectionState() != SelectionNone)
p->fillRect(selectionRect(), selectionColor());
p->fillRect(selectionRect(), selectionBackgroundColor());
return;
}
......@@ -197,7 +197,7 @@ void RenderListMarker::paint(PaintInfo& i, int _tx, int _ty)
#endif
if (selectionState() != SelectionNone)
p->fillRect(selectionRect(), selectionColor());
p->fillRect(selectionRect(), selectionBackgroundColor());
const Color color(style()->color());
p->setPen(color);
......
......@@ -1891,15 +1891,33 @@ bool RenderObject::shouldSelect() const
return false;
}
Color RenderObject::selectionColor() const
Color RenderObject::selectionBackgroundColor() const
{
Color color;
if (style()->userSelect() != SELECT_NONE) {
RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);
if (pseudoStyle && pseudoStyle->backgroundColor().isValid())
color = pseudoStyle->backgroundColor().blendWithWhite(selectionColorOverlayAlpha);
color = pseudoStyle->backgroundColor().blendWithWhite();
else
color = document()->frame()->isActive() ? theme()->activeSelectionColor() : theme()->inactiveSelectionColor();
color = document()->frame()->isActive() ?
theme()->activeSelectionBackgroundColor() :
theme()->inactiveSelectionBackgroundColor();
}
return color;
}
Color RenderObject::selectionForegroundColor() const
{
Color color;
if (style()->userSelect() != SELECT_NONE) {
RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);
if (pseudoStyle)
color = pseudoStyle->color();
else
color = document()->frame()->isActive() ?
theme()->platformActiveSelectionForegroundColor() :
theme()->platformInactiveSelectionForegroundColor();
}
return color;
......
......@@ -71,8 +71,6 @@ class RenderTable;
class RenderText;
class VisiblePosition;
const int selectionColorOverlayAlpha = 60 * 255 / 100;
enum PaintPhase {
PaintPhaseBlockBackground,
PaintPhaseChildBlockBackground,
......@@ -793,9 +791,10 @@ public:
// since it fires the selectstart DOM event.
bool shouldSelect() const;
// Obtains the selection background color that should be used when painting a selection.
Color selectionColor() const;
// Obtains the selection colors that should be used when painting a selection.
Color selectionBackgroundColor() const;
Color selectionForegroundColor() const;
// Whether or not a given block needs to paint selection gaps.
virtual bool shouldPaintSelectionGaps() const { return false; }
......
......@@ -120,34 +120,44 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const RenderObject::PaintInfo
return false;
}
Color RenderTheme::activeSelectionColor() const
Color RenderTheme::activeSelectionBackgroundColor() const
{
static Color activeSelectionColor;
if (!activeSelectionColor.isValid())
activeSelectionColor = platformActiveSelectionColor().blendWithWhite(selectionColorOverlayAlpha);
activeSelectionColor = platformActiveSelectionBackgroundColor().blendWithWhite();
return activeSelectionColor;
}
Color RenderTheme::inactiveSelectionColor() const
Color RenderTheme::inactiveSelectionBackgroundColor() const
{
static Color inactiveSelectionColor;
if (!inactiveSelectionColor.isValid())
inactiveSelectionColor = platformInactiveSelectionColor().blendWithWhite(selectionColorOverlayAlpha);
inactiveSelectionColor = platformInactiveSelectionBackgroundColor().blendWithWhite();
return inactiveSelectionColor;
}
Color RenderTheme::platformActiveSelectionColor() const
Color RenderTheme::platformActiveSelectionBackgroundColor() const
{
// Use a blue color by default if the platform theme doesn't define anything.
return Color(0, 0, 255);
}
Color RenderTheme::platformInactiveSelectionColor() const
Color RenderTheme::platformInactiveSelectionBackgroundColor() const
{
// Use a grey color by default if the platform theme doesn't define anything.
return Color(128, 128, 128);
}
Color RenderTheme::platformActiveSelectionForegroundColor() const
{
return Color();
}
Color RenderTheme::platformInactiveSelectionForegroundColor() const
{
return Color();
}
short RenderTheme::baselinePosition(const RenderObject* o) const
{
return o->height() + o->marginTop();
......
......@@ -89,13 +89,15 @@ public:
virtual bool supportsHover(const RenderStyle* style) const { return false; }
// The selection color.
Color activeSelectionColor() const;
Color inactiveSelectionColor() const;
Color activeSelectionBackgroundColor() const;
Color inactiveSelectionBackgroundColor() const;
// The platform selection color.
virtual Color platformActiveSelectionColor() const;
virtual Color platformInactiveSelectionColor() const;
virtual Color platformActiveSelectionBackgroundColor() const;
virtual Color platformInactiveSelectionBackgroundColor() const;
virtual Color platformActiveSelectionForegroundColor() const;
virtual Color platformInactiveSelectionForegroundColor() const;
protected:
// Methods for state querying
bool isChecked(const RenderObject* o) const;
......
......@@ -52,8 +52,8 @@ public:
virtual void paintResizeControl(GraphicsContext*, const IntRect&);
virtual Color platformActiveSelectionColor() const;
virtual Color platformInactiveSelectionColor() const;
virtual Color platformActiveSelectionBackgroundColor() const;
virtual Color platformInactiveSelectionBackgroundColor() const;
protected:
// Methods for each appearance value.
......
......@@ -56,13 +56,13 @@ RenderThemeMac::RenderThemeMac()
{
}
Color RenderThemeMac::platformActiveSelectionColor() const
Color RenderThemeMac::platformActiveSelectionBackgroundColor() const
{
NSColor* color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
return Color((int)(255 * [color redComponent]), (int)(255 * [color greenComponent]), (int)(255 * [color blueComponent]));
}
Color RenderThemeMac::platformInactiveSelectionColor() const
Color RenderThemeMac::platformInactiveSelectionBackgroundColor() const
{
NSColor* color = [[NSColor secondarySelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
return Color((int)(255 * [color redComponent]), (int)(255 * [color greenComponent]), (int)(255 * [color blueComponent]));
......
......@@ -122,18 +122,29 @@ void RenderThemeWin::close()
m_buttonTheme = m_textFieldTheme = 0;
}
Color RenderThemeWin::platformActiveSelectionColor() const
Color RenderThemeWin::platformActiveSelectionBackgroundColor() const
{
COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
}
Color RenderThemeWin::platformInactiveSelectionColor() const
Color RenderThemeWin::platformInactiveSelectionBackgroundColor() const
{
COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
COLORREF color = GetSysColor(COLOR_GRAYTEXT);
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
}
Color RenderThemeWin::platformActiveSelectionForegroundColor() const
{
COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
}
Color RenderThemeWin::platformInactiveSelectionForegroundColor() const
{
return Color::white;
}
void RenderThemeWin::addIntrinsicMargins(RenderStyle* style) const
{
// Cut out the intrinsic margins completely if we end up using a small font size
......
......@@ -48,8 +48,10 @@ public:
// A method asking if the theme's controls actually care about redrawing when hovered.
virtual bool supportsHover(const RenderStyle*) const { return true; }
virtual Color platformActiveSelectionColor() const;
virtual Color platformInactiveSelectionColor() const;
virtual Color platformActiveSelectionBackgroundColor() const;
virtual Color platformInactiveSelectionBackgroundColor() const;
virtual Color platformActiveSelectionForegroundColor() const;
virtual Color platformInactiveSelectionForegroundColor() const;
virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{ return paintButton(o, i, r); }
......
......@@ -192,7 +192,7 @@ void RenderWidget::paint(PaintInfo& i, int tx, int ty)
// Paint a partially transparent wash over selected widgets.
if (isSelected() && !document()->printing())
i.p->fillRect(selectionRect(), selectionColor());
i.p->fillRect(selectionRect(), selectionBackgroundColor());
}
void RenderWidget::focusIn(Widget*)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment