1/** 2 * Copyright (C) 2003, 2006 Apple Computer, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include "config.h" 21#include "EllipsisBox.h" 22 23#include "Document.h" 24#include "GraphicsContext.h" 25#include "HitTestResult.h" 26#include "PaintInfo.h" 27#include "RootInlineBox.h" 28#include "TextRun.h" 29 30namespace WebCore { 31 32void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty, int lineTop, int lineBottom) 33{ 34 GraphicsContext* context = paintInfo.context; 35 RenderStyle* style = m_renderer->style(m_firstLine); 36 Color textColor = style->visitedDependentColor(CSSPropertyColor); 37 if (textColor != context->fillColor()) 38 context->setFillColor(textColor, style->colorSpace()); 39 bool setShadow = false; 40 if (style->textShadow()) { 41 context->setShadow(IntSize(style->textShadow()->x(), style->textShadow()->y()), 42 style->textShadow()->blur(), style->textShadow()->color(), style->colorSpace()); 43 setShadow = true; 44 } 45 46 if (selectionState() != RenderObject::SelectionNone) { 47 paintSelection(context, tx, ty, style, style->font()); 48 49 // Select the correct color for painting the text. 50 Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor(); 51 if (foreground.isValid() && foreground != textColor) 52 context->setFillColor(foreground, style->colorSpace()); 53 } 54 55 const String& str = m_str; 56 context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent())); 57 58 // Restore the regular fill color. 59 if (textColor != context->fillColor()) 60 context->setFillColor(textColor, style->colorSpace()); 61 62 if (setShadow) 63 context->clearShadow(); 64 65 if (m_markupBox) { 66 // Paint the markup box 67 tx += m_x + m_logicalWidth - m_markupBox->x(); 68 ty += m_y + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent()); 69 m_markupBox->paint(paintInfo, tx, ty, lineTop, lineBottom); 70 } 71} 72 73IntRect EllipsisBox::selectionRect(int tx, int ty) 74{ 75 RenderStyle* style = m_renderer->style(m_firstLine); 76 const Font& f = style->font(); 77 return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()), 78 IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight())); 79} 80 81void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font) 82{ 83 Color textColor = style->visitedDependentColor(CSSPropertyColor); 84 Color c = m_renderer->selectionBackgroundColor(); 85 if (!c.isValid() || !c.alpha()) 86 return; 87 88 // If the text color ends up being the same as the selection background, invert the selection 89 // background. 90 if (textColor == c) 91 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); 92 93 context->save(); 94 int y = root()->selectionTop(); 95 int h = root()->selectionHeight(); 96 context->clip(IntRect(m_x + tx, y + ty, m_logicalWidth, h)); 97 context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()), 98 IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace()); 99 context->restore(); 100} 101 102bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, int lineTop, int lineBottom) 103{ 104 tx += m_x; 105 ty += m_y; 106 107 // Hit test the markup box. 108 if (m_markupBox) { 109 RenderStyle* style = m_renderer->style(m_firstLine); 110 int mtx = tx + m_logicalWidth - m_markupBox->x(); 111 int mty = ty + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent()); 112 if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty, lineTop, lineBottom)) { 113 renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty)); 114 return true; 115 } 116 } 117 118 IntRect boundsRect = IntRect(tx, ty, m_logicalWidth, m_height); 119 if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(x, y))) { 120 renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); 121 if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, boundsRect)) 122 return true; 123 } 124 125 return false; 126} 127 128} // namespace WebCore 129