Fix for WebKit bug 29968 - Selecting text with text-overflow ellipsis
[WebKit-https.git] / WebCore / rendering / EllipsisBox.cpp
index bea9d73..6ec3195 100644 (file)
@@ -23,6 +23,7 @@
 #include "Document.h"
 #include "GraphicsContext.h"
 #include "HitTestResult.h"
+#include "RootInlineBox.h"
 
 namespace WebCore {
 
@@ -40,9 +41,22 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
         setShadow = true;
     }
 
+    if (selectionState() != RenderObject::SelectionNone) {
+        paintSelection(context, tx, ty, style, style->font());
+
+        // Select the correct color for painting the text.
+        Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();
+        if (foreground.isValid() && foreground != textColor)
+            context->setFillColor(foreground, style->colorSpace());
+    }
+
     const String& str = m_str;
     context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent()));
 
+    // Restore the regular fill color.
+    if (textColor != context->fillColor())
+        context->setFillColor(textColor, style->colorSpace());
+
     if (setShadow)
         context->clearShadow();
 
@@ -54,6 +68,35 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
     }
 }
 
+IntRect EllipsisBox::selectionRect(int tx, int ty)
+{
+    RenderStyle* style = m_renderer->style(m_firstLine);
+    const Font& f = style->font();
+    return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+            IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
+}
+
+void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font)
+{
+    Color textColor = style->color();
+    Color c = m_renderer->selectionBackgroundColor();
+    if (!c.isValid() || !c.alpha())
+        return;
+
+    // If the text color ends up being the same as the selection background, invert the selection
+    // background.
+    if (textColor == c)
+        c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
+
+    context->save();
+    int y = root()->selectionTop();
+    int h = root()->selectionHeight();
+    context->clip(IntRect(m_x + tx, y + ty, m_width, h));
+    context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
+        IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
+    context->restore();
+}
+
 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
 {
     tx += m_x;