OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "core/paint/InlinePainter.h" |
| 7 |
| 8 #include "core/paint/BoxPainter.h" |
| 9 #include "core/paint/ObjectPainter.h" |
| 10 #include "core/rendering/GraphicsContextAnnotator.h" |
| 11 #include "core/rendering/PaintInfo.h" |
| 12 #include "core/rendering/RenderInline.h" |
| 13 #include "core/rendering/RenderTheme.h" |
| 14 #include "core/rendering/RootInlineBox.h" |
| 15 #include "platform/geometry/LayoutPoint.h" |
| 16 |
| 17 namespace blink { |
| 18 |
| 19 void InlinePainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
| 20 { |
| 21 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderInline); |
| 22 m_renderInline.lineBoxes()->paint(&m_renderInline, paintInfo, paintOffset); |
| 23 } |
| 24 |
| 25 void InlinePainter::paintOutline(PaintInfo& paintInfo, const LayoutPoint& paintO
ffset) |
| 26 { |
| 27 RenderStyle* styleToUse = m_renderInline.style(); |
| 28 if (!styleToUse->hasOutline()) |
| 29 return; |
| 30 |
| 31 if (styleToUse->outlineStyleIsAuto()) { |
| 32 if (RenderTheme::theme().shouldDrawDefaultFocusRing(&m_renderInline)) { |
| 33 // Only paint the focus ring by hand if the theme isn't able to draw
the focus ring. |
| 34 ObjectPainter(m_renderInline).paintFocusRing(paintInfo, paintOffset,
styleToUse); |
| 35 } |
| 36 return; |
| 37 } |
| 38 |
| 39 if (styleToUse->outlineStyle() == BNONE) |
| 40 return; |
| 41 |
| 42 Vector<LayoutRect> rects; |
| 43 |
| 44 rects.append(LayoutRect()); |
| 45 for (InlineFlowBox* curr = m_renderInline.firstLineBox(); curr; curr = curr-
>nextLineBox()) { |
| 46 RootInlineBox& root = curr->root(); |
| 47 LayoutUnit top = std::max<LayoutUnit>(root.lineTop(), curr->logicalTop()
); |
| 48 LayoutUnit bottom = std::min<LayoutUnit>(root.lineBottom(), curr->logica
lBottom()); |
| 49 rects.append(LayoutRect(curr->x(), top, curr->logicalWidth(), bottom - t
op)); |
| 50 } |
| 51 rects.append(LayoutRect()); |
| 52 |
| 53 Color outlineColor = m_renderInline.resolveColor(styleToUse, CSSPropertyOutl
ineColor); |
| 54 bool useTransparencyLayer = outlineColor.hasAlpha(); |
| 55 |
| 56 GraphicsContext* graphicsContext = paintInfo.context; |
| 57 if (useTransparencyLayer) { |
| 58 graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.
alpha()) / 255); |
| 59 outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineCo
lor.blue()); |
| 60 } |
| 61 |
| 62 for (unsigned i = 1; i < rects.size() - 1; i++) |
| 63 paintOutlineForLine(graphicsContext, paintOffset, rects.at(i - 1), rects
.at(i), rects.at(i + 1), outlineColor); |
| 64 |
| 65 if (useTransparencyLayer) |
| 66 graphicsContext->endLayer(); |
| 67 } |
| 68 |
| 69 void InlinePainter::paintOutlineForLine(GraphicsContext* graphicsContext, const
LayoutPoint& paintOffset, |
| 70 const LayoutRect& lastline, const LayoutRect& thisline, const LayoutRect& ne
xtline, const Color outlineColor) |
| 71 { |
| 72 RenderStyle* styleToUse = m_renderInline.style(); |
| 73 int outlineWidth = styleToUse->outlineWidth(); |
| 74 EBorderStyle outlineStyle = styleToUse->outlineStyle(); |
| 75 |
| 76 bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext); |
| 77 |
| 78 int offset = m_renderInline.style()->outlineOffset(); |
| 79 |
| 80 LayoutRect box(LayoutPoint(paintOffset.x() + thisline.x() - offset, paintOff
set.y() + thisline.y() - offset), |
| 81 LayoutSize(thisline.width() + offset, thisline.height() + offset)); |
| 82 |
| 83 IntRect pixelSnappedBox = pixelSnappedIntRect(box); |
| 84 if (pixelSnappedBox.width() < 0 || pixelSnappedBox.height() < 0) |
| 85 return; |
| 86 IntRect pixelSnappedLastLine = pixelSnappedIntRect(paintOffset.x() + lastlin
e.x(), 0, lastline.width(), 0); |
| 87 IntRect pixelSnappedNextLine = pixelSnappedIntRect(paintOffset.x() + nextlin
e.x(), 0, nextline.width(), 0); |
| 88 |
| 89 // left edge |
| 90 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 91 pixelSnappedBox.x() - outlineWidth, |
| 92 pixelSnappedBox.y() - (lastline.isEmpty() || thisline.x() < lastline.x()
|| (lastline.maxX() - 1) <= thisline.x() ? outlineWidth : 0), |
| 93 pixelSnappedBox.x(), |
| 94 pixelSnappedBox.maxY() + (nextline.isEmpty() || thisline.x() <= nextline
.x() || (nextline.maxX() - 1) <= thisline.x() ? outlineWidth : 0), |
| 95 BSLeft, |
| 96 outlineColor, outlineStyle, |
| 97 (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.maxX() -
1) <= thisline.x() ? outlineWidth : -outlineWidth), |
| 98 (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.maxX()
- 1) <= thisline.x() ? outlineWidth : -outlineWidth), |
| 99 antialias); |
| 100 |
| 101 // right edge |
| 102 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 103 pixelSnappedBox.maxX(), |
| 104 pixelSnappedBox.y() - (lastline.isEmpty() || lastline.maxX() < thisline.
maxX() || (thisline.maxX() - 1) <= lastline.x() ? outlineWidth : 0), |
| 105 pixelSnappedBox.maxX() + outlineWidth, |
| 106 pixelSnappedBox.maxY() + (nextline.isEmpty() || nextline.maxX() <= thisl
ine.maxX() || (thisline.maxX() - 1) <= nextline.x() ? outlineWidth : 0), |
| 107 BSRight, |
| 108 outlineColor, outlineStyle, |
| 109 (lastline.isEmpty() || lastline.maxX() < thisline.maxX() || (thisline.ma
xX() - 1) <= lastline.x() ? outlineWidth : -outlineWidth), |
| 110 (nextline.isEmpty() || nextline.maxX() <= thisline.maxX() || (thisline.m
axX() - 1) <= nextline.x() ? outlineWidth : -outlineWidth), |
| 111 antialias); |
| 112 // upper edge |
| 113 if (thisline.x() < lastline.x()) { |
| 114 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 115 pixelSnappedBox.x() - outlineWidth, |
| 116 pixelSnappedBox.y() - outlineWidth, |
| 117 std::min(pixelSnappedBox.maxX() + outlineWidth, (lastline.isEmpty()
? 1000000 : pixelSnappedLastLine.x())), |
| 118 pixelSnappedBox.y(), |
| 119 BSTop, outlineColor, outlineStyle, |
| 120 outlineWidth, |
| 121 (!lastline.isEmpty() && paintOffset.x() + lastline.x() + 1 < pixelSn
appedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth, |
| 122 antialias); |
| 123 } |
| 124 |
| 125 if (lastline.maxX() < thisline.maxX()) { |
| 126 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 127 std::max(lastline.isEmpty() ? -1000000 : pixelSnappedLastLine.maxX()
, pixelSnappedBox.x() - outlineWidth), |
| 128 pixelSnappedBox.y() - outlineWidth, |
| 129 pixelSnappedBox.maxX() + outlineWidth, |
| 130 pixelSnappedBox.y(), |
| 131 BSTop, outlineColor, outlineStyle, |
| 132 (!lastline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOf
fset.x() + lastline.maxX()) ? -outlineWidth : outlineWidth, |
| 133 outlineWidth, antialias); |
| 134 } |
| 135 |
| 136 if (thisline.x() == thisline.maxX()) { |
| 137 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 138 pixelSnappedBox.x() - outlineWidth, |
| 139 pixelSnappedBox.y() - outlineWidth, |
| 140 pixelSnappedBox.maxX() + outlineWidth, |
| 141 pixelSnappedBox.y(), |
| 142 BSTop, outlineColor, outlineStyle, |
| 143 outlineWidth, |
| 144 outlineWidth, |
| 145 antialias); |
| 146 } |
| 147 |
| 148 // lower edge |
| 149 if (thisline.x() < nextline.x()) { |
| 150 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 151 pixelSnappedBox.x() - outlineWidth, |
| 152 pixelSnappedBox.maxY(), |
| 153 std::min(pixelSnappedBox.maxX() + outlineWidth, !nextline.isEmpty()
? pixelSnappedNextLine.x() + 1 : 1000000), |
| 154 pixelSnappedBox.maxY() + outlineWidth, |
| 155 BSBottom, outlineColor, outlineStyle, |
| 156 outlineWidth, |
| 157 (!nextline.isEmpty() && paintOffset.x() + nextline.x() + 1 < pixelSn
appedBox.maxX() + outlineWidth) ? -outlineWidth : outlineWidth, |
| 158 antialias); |
| 159 } |
| 160 |
| 161 if (nextline.maxX() < thisline.maxX()) { |
| 162 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 163 std::max(!nextline.isEmpty() ? pixelSnappedNextLine.maxX() : -100000
0, pixelSnappedBox.x() - outlineWidth), |
| 164 pixelSnappedBox.maxY(), |
| 165 pixelSnappedBox.maxX() + outlineWidth, |
| 166 pixelSnappedBox.maxY() + outlineWidth, |
| 167 BSBottom, outlineColor, outlineStyle, |
| 168 (!nextline.isEmpty() && pixelSnappedBox.x() - outlineWidth < paintOf
fset.x() + nextline.maxX()) ? -outlineWidth : outlineWidth, |
| 169 outlineWidth, antialias); |
| 170 } |
| 171 |
| 172 if (thisline.x() == thisline.maxX()) { |
| 173 ObjectPainter::drawLineForBoxSide(graphicsContext, |
| 174 pixelSnappedBox.x() - outlineWidth, |
| 175 pixelSnappedBox.maxY(), |
| 176 pixelSnappedBox.maxX() + outlineWidth, |
| 177 pixelSnappedBox.maxY() + outlineWidth, |
| 178 BSBottom, outlineColor, outlineStyle, |
| 179 outlineWidth, |
| 180 outlineWidth, |
| 181 antialias); |
| 182 } |
| 183 } |
| 184 |
| 185 } // namespace blink |
OLD | NEW |