|
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 "RootInlineBox.h" |
|
27 |
|
28 namespace WebCore { |
|
29 |
|
30 void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty) |
|
31 { |
|
32 GraphicsContext* context = paintInfo.context; |
|
33 RenderStyle* style = m_renderer->style(m_firstLine); |
|
34 Color textColor = style->visitedDependentColor(CSSPropertyColor); |
|
35 if (textColor != context->fillColor()) |
|
36 context->setFillColor(textColor, style->colorSpace()); |
|
37 bool setShadow = false; |
|
38 if (style->textShadow()) { |
|
39 context->setShadow(IntSize(style->textShadow()->x(), style->textShadow()->y()), |
|
40 style->textShadow()->blur(), style->textShadow()->color(), style->colorSpace()); |
|
41 setShadow = true; |
|
42 } |
|
43 |
|
44 if (selectionState() != RenderObject::SelectionNone) { |
|
45 paintSelection(context, tx, ty, style, style->font()); |
|
46 |
|
47 // Select the correct color for painting the text. |
|
48 Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor(); |
|
49 if (foreground.isValid() && foreground != textColor) |
|
50 context->setFillColor(foreground, style->colorSpace()); |
|
51 } |
|
52 |
|
53 const String& str = m_str; |
|
54 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())); |
|
55 |
|
56 // Restore the regular fill color. |
|
57 if (textColor != context->fillColor()) |
|
58 context->setFillColor(textColor, style->colorSpace()); |
|
59 |
|
60 if (setShadow) |
|
61 context->clearShadow(); |
|
62 |
|
63 if (m_markupBox) { |
|
64 // Paint the markup box |
|
65 tx += m_x + m_width - m_markupBox->x(); |
|
66 ty += m_y + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent()); |
|
67 m_markupBox->paint(paintInfo, tx, ty); |
|
68 } |
|
69 } |
|
70 |
|
71 IntRect EllipsisBox::selectionRect(int tx, int ty) |
|
72 { |
|
73 RenderStyle* style = m_renderer->style(m_firstLine); |
|
74 const Font& f = style->font(); |
|
75 return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()), |
|
76 IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight())); |
|
77 } |
|
78 |
|
79 void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font) |
|
80 { |
|
81 Color textColor = style->visitedDependentColor(CSSPropertyColor); |
|
82 Color c = m_renderer->selectionBackgroundColor(); |
|
83 if (!c.isValid() || !c.alpha()) |
|
84 return; |
|
85 |
|
86 // If the text color ends up being the same as the selection background, invert the selection |
|
87 // background. |
|
88 if (textColor == c) |
|
89 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); |
|
90 |
|
91 context->save(); |
|
92 int y = root()->selectionTop(); |
|
93 int h = root()->selectionHeight(); |
|
94 context->clip(IntRect(m_x + tx, y + ty, m_width, h)); |
|
95 context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()), |
|
96 IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace()); |
|
97 context->restore(); |
|
98 } |
|
99 |
|
100 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) |
|
101 { |
|
102 tx += m_x; |
|
103 ty += m_y; |
|
104 |
|
105 // Hit test the markup box. |
|
106 if (m_markupBox) { |
|
107 RenderStyle* style = m_renderer->style(m_firstLine); |
|
108 int mtx = tx + m_width - m_markupBox->x(); |
|
109 int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent()); |
|
110 if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) { |
|
111 renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty)); |
|
112 return true; |
|
113 } |
|
114 } |
|
115 |
|
116 IntRect boundsRect = IntRect(tx, ty, m_width, m_height); |
|
117 if (visibleToHitTesting() && boundsRect.intersects(result.rectFromPoint(x, y))) { |
|
118 renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); |
|
119 if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, boundsRect)) |
|
120 return true; |
|
121 } |
|
122 |
|
123 return false; |
|
124 } |
|
125 |
|
126 } // namespace WebCore |