| 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 |