OLD | NEW |
1 /** | 1 /** |
2 * Copyright (C) 2003, 2006 Apple Computer, Inc. | 2 * Copyright (C) 2003, 2006 Apple Computer, Inc. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
18 */ | 18 */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "core/rendering/EllipsisBox.h" | 21 #include "core/rendering/EllipsisBox.h" |
22 | 22 |
| 23 #include "core/paint/EllipsisBoxPainter.h" |
23 #include "core/rendering/HitTestResult.h" | 24 #include "core/rendering/HitTestResult.h" |
24 #include "core/rendering/InlineTextBox.h" | 25 #include "core/rendering/InlineTextBox.h" |
25 #include "core/rendering/PaintInfo.h" | 26 #include "core/rendering/PaintInfo.h" |
26 #include "core/rendering/RenderBlock.h" | 27 #include "core/rendering/RenderBlock.h" |
27 #include "core/rendering/RootInlineBox.h" | 28 #include "core/rendering/RootInlineBox.h" |
28 #include "core/rendering/TextPainter.h" | |
29 #include "core/rendering/TextRunConstructor.h" | 29 #include "core/rendering/TextRunConstructor.h" |
30 #include "core/rendering/style/ShadowList.h" | 30 #include "core/rendering/style/ShadowList.h" |
31 #include "platform/fonts/Font.h" | 31 #include "platform/fonts/Font.h" |
32 #include "platform/graphics/GraphicsContextStateSaver.h" | |
33 #include "platform/text/TextRun.h" | 32 #include "platform/text/TextRun.h" |
34 | 33 |
35 namespace blink { | 34 namespace blink { |
36 | 35 |
37 void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, La
youtUnit lineTop, LayoutUnit lineBottom) | 36 void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, La
youtUnit lineTop, LayoutUnit lineBottom) |
38 { | 37 { |
39 GraphicsContext* context = paintInfo.context; | 38 EllipsisBoxPainter(*this).paint(paintInfo, paintOffset, lineTop, lineBottom)
; |
40 RenderStyle* style = renderer().style(isFirstLineStyle()); | |
41 const Font& font = style->font(); | |
42 FloatPoint boxOrigin = locationIncludingFlipping(); | |
43 boxOrigin.moveBy(FloatPoint(paintOffset)); | |
44 if (!isHorizontal()) | |
45 boxOrigin.move(0, -virtualLogicalHeight()); | |
46 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight
())); | |
47 GraphicsContextStateSaver stateSaver(*context); | |
48 if (!isHorizontal()) | |
49 context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clock
wise)); | |
50 FloatPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().asce
nt()); | |
51 | |
52 bool isPrinting = renderer().document().printing(); | |
53 bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip &&
selectionState() != RenderObject::SelectionNone; | |
54 | |
55 if (haveSelection) | |
56 paintSelection(context, boxOrigin, style, font); | |
57 else if (paintInfo.phase == PaintPhaseSelection) | |
58 return; | |
59 | |
60 TextPainter::Style textStyle = TextPainter::textPaintingStyle(renderer(), st
yle, paintInfo.forceBlackText(), isPrinting); | |
61 if (haveSelection) | |
62 textStyle = TextPainter::selectionPaintingStyle(renderer(), true, paintI
nfo.forceBlackText(), isPrinting, textStyle); | |
63 | |
64 TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun:
:AllowTrailingExpansion); | |
65 TextPainter textPainter(context, font, textRun, textOrigin, boxRect, isHoriz
ontal()); | |
66 textPainter.paint(0, m_str.length(), m_str.length(), textStyle); | |
67 | |
68 paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); | |
69 } | 39 } |
70 | 40 |
71 InlineBox* EllipsisBox::markupBox() const | 41 InlineBox* EllipsisBox::markupBox() const |
72 { | 42 { |
73 if (!m_shouldPaintMarkupBox || !renderer().isRenderBlock()) | 43 if (!m_shouldPaintMarkupBox || !renderer().isRenderBlock()) |
74 return 0; | 44 return 0; |
75 | 45 |
76 RenderBlock& block = toRenderBlock(renderer()); | 46 RenderBlock& block = toRenderBlock(renderer()); |
77 RootInlineBox* lastLine = block.lineAtIndex(block.lineCount() - 1); | 47 RootInlineBox* lastLine = block.lineAtIndex(block.lineCount() - 1); |
78 if (!lastLine) | 48 if (!lastLine) |
79 return 0; | 49 return 0; |
80 | 50 |
81 // If the last line-box on the last line of a block is a link, -webkit-line-
clamp paints that box after the ellipsis. | 51 // If the last line-box on the last line of a block is a link, -webkit-line-
clamp paints that box after the ellipsis. |
82 // It does not actually move the link. | 52 // It does not actually move the link. |
83 InlineBox* anchorBox = lastLine->lastChild(); | 53 InlineBox* anchorBox = lastLine->lastChild(); |
84 if (!anchorBox || !anchorBox->renderer().style()->isLink()) | 54 if (!anchorBox || !anchorBox->renderer().style()->isLink()) |
85 return 0; | 55 return 0; |
86 | 56 |
87 return anchorBox; | 57 return anchorBox; |
88 } | 58 } |
89 | 59 |
90 void EllipsisBox::paintMarkupBox(PaintInfo& paintInfo, const LayoutPoint& paintO
ffset, LayoutUnit lineTop, LayoutUnit lineBottom, RenderStyle* style) | |
91 { | |
92 InlineBox* markupBox = this->markupBox(); | |
93 if (!markupBox) | |
94 return; | |
95 | |
96 LayoutPoint adjustedPaintOffset = paintOffset; | |
97 adjustedPaintOffset.move(x() + m_logicalWidth - markupBox->x(), | |
98 y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->rende
rer().style(isFirstLineStyle())->fontMetrics().ascent())); | |
99 markupBox->paint(paintInfo, adjustedPaintOffset, lineTop, lineBottom); | |
100 } | |
101 | |
102 IntRect EllipsisBox::selectionRect() | 60 IntRect EllipsisBox::selectionRect() |
103 { | 61 { |
104 RenderStyle* style = renderer().style(isFirstLineStyle()); | 62 RenderStyle* style = renderer().style(isFirstLineStyle()); |
105 const Font& font = style->font(); | 63 const Font& font = style->font(); |
106 return enclosingIntRect(font.selectionRectForText(constructTextRun(&renderer
(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft()
, logicalTop() + root().selectionTopAdjustedForPrecedingBlock()), root().selecti
onHeightAdjustedForPrecedingBlock())); | 64 return enclosingIntRect(font.selectionRectForText(constructTextRun(&renderer
(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft()
, logicalTop() + root().selectionTopAdjustedForPrecedingBlock()), root().selecti
onHeightAdjustedForPrecedingBlock())); |
107 } | 65 } |
108 | 66 |
109 void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& box
Origin, RenderStyle* style, const Font& font) | |
110 { | |
111 Color textColor = renderer().resolveColor(style, CSSPropertyColor); | |
112 Color c = renderer().selectionBackgroundColor(); | |
113 if (!c.alpha()) | |
114 return; | |
115 | |
116 // If the text color ends up being the same as the selection background, inv
ert the selection | |
117 // background. | |
118 if (textColor == c) | |
119 c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); | |
120 | |
121 GraphicsContextStateSaver stateSaver(*context); | |
122 LayoutUnit selectionBottom = root().selectionBottom(); | |
123 LayoutUnit top = root().selectionTop(); | |
124 LayoutUnit h = root().selectionHeight(); | |
125 const int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode(
) ? selectionBottom - logicalBottom() : logicalTop() - top); | |
126 const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); | |
127 FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h.toFloat())); | |
128 context->clip(clipRect); | |
129 context->drawHighlightForText(font, constructTextRun(&renderer(), font, m_st
r, style, TextRun::AllowTrailingExpansion), localOrigin, h, c); | |
130 } | |
131 | |
132 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, LayoutUnit lineTop, LayoutUnit lineBottom) | 67 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
lt, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOf
fset, LayoutUnit lineTop, LayoutUnit lineBottom) |
133 { | 68 { |
134 LayoutPoint adjustedLocation = accumulatedOffset + roundedLayoutPoint(topLef
t()); | 69 LayoutPoint adjustedLocation = accumulatedOffset + roundedLayoutPoint(topLef
t()); |
135 | 70 |
136 // Hit test the markup box. | 71 // Hit test the markup box. |
137 if (InlineBox* markupBox = this->markupBox()) { | 72 if (InlineBox* markupBox = this->markupBox()) { |
138 RenderStyle* style = renderer().style(isFirstLineStyle()); | 73 RenderStyle* style = renderer().style(isFirstLineStyle()); |
139 LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x(); | 74 LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x(); |
140 LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() -
(markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics()
.ascent()); | 75 LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() -
(markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics()
.ascent()); |
141 if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutP
oint(mtx, mty), lineTop, lineBottom)) { | 76 if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutP
oint(mtx, mty), lineTop, lineBottom)) { |
142 renderer().updateHitTestResult(result, locationInContainer.point() -
LayoutSize(mtx, mty)); | 77 renderer().updateHitTestResult(result, locationInContainer.point() -
LayoutSize(mtx, mty)); |
143 return true; | 78 return true; |
144 } | 79 } |
145 } | 80 } |
146 | 81 |
147 FloatPoint boxOrigin = locationIncludingFlipping(); | 82 FloatPoint boxOrigin = locationIncludingFlipping(); |
148 boxOrigin.moveBy(accumulatedOffset); | 83 boxOrigin.moveBy(accumulatedOffset); |
149 FloatRect boundsRect(boxOrigin, size()); | 84 FloatRect boundsRect(boxOrigin, size()); |
150 if (visibleToHitTestRequest(request) && boundsRect.intersects(HitTestLocatio
n::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) { | 85 if (visibleToHitTestRequest(request) && boundsRect.intersects(HitTestLocatio
n::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) { |
151 renderer().updateHitTestResult(result, locationInContainer.point() - toL
ayoutSize(adjustedLocation)); | 86 renderer().updateHitTestResult(result, locationInContainer.point() - toL
ayoutSize(adjustedLocation)); |
152 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc
ationInContainer, boundsRect)) | 87 if (!result.addNodeToRectBasedTestResult(renderer().node(), request, loc
ationInContainer, boundsRect)) |
153 return true; | 88 return true; |
154 } | 89 } |
155 | 90 |
156 return false; | 91 return false; |
157 } | 92 } |
158 | 93 |
159 } // namespace blink | 94 } // namespace blink |
OLD | NEW |