TextPaintStyle.cpp [plain text]
#include "config.h"
#include "TextPaintStyle.h"
#include "FocusController.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "Page.h"
#include "PaintInfo.h"
#include "RenderStyle.h"
#include "RenderText.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "Settings.h"
namespace WebCore {
TextPaintStyle::TextPaintStyle(const Color& color)
: fillColor(color)
, strokeColor(color)
{
}
static Color adjustColorForVisibilityOnBackground(const Color& textColor, const Color& backgroundColor)
{
int d = differenceSquared(textColor, backgroundColor);
if (d > 65025)
return textColor;
int distanceFromWhite = differenceSquared(textColor, Color::white);
int distanceFromBlack = differenceSquared(textColor, Color::black);
if (distanceFromWhite < distanceFromBlack)
return textColor.dark();
return textColor.light();
}
TextPaintStyle computeTextPaintStyle(const Frame& frame, const RenderStyle& lineStyle, const PaintInfo& paintInfo)
{
TextPaintStyle paintStyle;
#if ENABLE(LETTERPRESS)
paintStyle.useLetterpressEffect = lineStyle.textDecorationsInEffect() & TextDecorationLetterpress;
#endif
paintStyle.strokeWidth = lineStyle.textStrokeWidth();
if (paintInfo.forceTextColor()) {
paintStyle.fillColor = paintInfo.forcedTextColor();
paintStyle.strokeColor = paintInfo.forcedTextColor();
paintStyle.emphasisMarkColor = paintInfo.forcedTextColor();
return paintStyle;
}
if (lineStyle.insideDefaultButton()) {
Page* page = frame.page();
if (page && page->focusController().isActive()) {
paintStyle.fillColor = page->theme().systemColor(CSSValueActivebuttontext);
return paintStyle;
}
}
paintStyle.fillColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextFillColor);
bool forceBackgroundToWhite = false;
if (frame.document() && frame.document()->printing()) {
if (lineStyle.printColorAdjust() == PrintColorAdjustEconomy)
forceBackgroundToWhite = true;
if (frame.settings().shouldPrintBackgrounds())
forceBackgroundToWhite = false;
}
if (forceBackgroundToWhite)
paintStyle.fillColor = adjustColorForVisibilityOnBackground(paintStyle.fillColor, Color::white);
paintStyle.strokeColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
if (forceBackgroundToWhite)
paintStyle.strokeColor = adjustColorForVisibilityOnBackground(paintStyle.strokeColor, Color::white);
paintStyle.emphasisMarkColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextEmphasisColor);
if (forceBackgroundToWhite)
paintStyle.emphasisMarkColor = adjustColorForVisibilityOnBackground(paintStyle.emphasisMarkColor, Color::white);
return paintStyle;
}
TextPaintStyle computeTextSelectionPaintStyle(const TextPaintStyle& textPaintStyle, const RenderText& renderer, const RenderStyle& lineStyle, const PaintInfo& paintInfo, bool& paintSelectedTextOnly, bool& paintSelectedTextSeparately, const ShadowData*& selectionShadow)
{
paintSelectedTextOnly = (paintInfo.phase == PaintPhaseSelection);
paintSelectedTextSeparately = false;
selectionShadow = (paintInfo.forceTextColor()) ? nullptr : lineStyle.textShadow();
TextPaintStyle selectionPaintStyle = textPaintStyle;
#if ENABLE(TEXT_SELECTION)
Color foreground = paintInfo.forceTextColor() ? paintInfo.forcedTextColor() : renderer.selectionForegroundColor();
if (foreground.isValid() && foreground != selectionPaintStyle.fillColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionPaintStyle.fillColor = foreground;
}
Color emphasisMarkForeground = paintInfo.forceTextColor() ? paintInfo.forcedTextColor() : renderer.selectionEmphasisMarkColor();
if (emphasisMarkForeground.isValid() && emphasisMarkForeground != selectionPaintStyle.emphasisMarkColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionPaintStyle.emphasisMarkColor = emphasisMarkForeground;
}
if (auto* pseudoStyle = renderer.getCachedPseudoStyle(SELECTION)) {
const ShadowData* shadow = paintInfo.forceTextColor() ? nullptr : pseudoStyle->textShadow();
if (shadow != selectionShadow) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionShadow = shadow;
}
float strokeWidth = pseudoStyle->textStrokeWidth();
if (strokeWidth != selectionPaintStyle.strokeWidth) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionPaintStyle.strokeWidth = strokeWidth;
}
Color stroke = paintInfo.forceTextColor() ? paintInfo.forcedTextColor() : pseudoStyle->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
if (stroke != selectionPaintStyle.strokeColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionPaintStyle.strokeColor = stroke;
}
}
#else
UNUSED_PARAM(renderer);
UNUSED_PARAM(lineStyle);
UNUSED_PARAM(paintInfo);
#endif
return selectionPaintStyle;
}
void updateGraphicsContext(GraphicsContext& context, const TextPaintStyle& paintStyle, FillColorType fillColorType)
{
TextDrawingModeFlags mode = context.textDrawingMode();
TextDrawingModeFlags newMode = mode;
#if ENABLE(LETTERPRESS)
if (paintStyle.useLetterpressEffect)
newMode |= TextModeLetterpress;
else
newMode &= ~TextModeLetterpress;
#endif
if (paintStyle.strokeWidth > 0)
newMode |= TextModeStroke;
if (mode != newMode) {
context.setTextDrawingMode(newMode);
mode = newMode;
}
Color fillColor = fillColorType == UseEmphasisMarkColor ? paintStyle.emphasisMarkColor : paintStyle.fillColor;
if (mode & TextModeFill && (fillColor != context.fillColor()))
context.setFillColor(fillColor);
if (mode & TextModeStroke) {
if (paintStyle.strokeColor != context.strokeColor())
context.setStrokeColor(paintStyle.strokeColor);
if (paintStyle.strokeWidth != context.strokeThickness())
context.setStrokeThickness(paintStyle.strokeWidth);
}
}
}