diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp')
-rw-r--r-- | Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp | 200 |
1 files changed, 73 insertions, 127 deletions
diff --git a/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp index ff04fbb15..346879569 100644 --- a/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp +++ b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp @@ -35,48 +35,28 @@ #include "InlineTextBox.h" #include "PaintInfo.h" #include "RenderBlockFlow.h" -#include "RenderIterator.h" #include "RenderStyle.h" #include "RenderText.h" #include "RenderView.h" #include "Settings.h" #include "SimpleLineLayoutResolver.h" #include "Text.h" -#include "TextDecorationPainter.h" #include "TextPaintStyle.h" -#include "TextPainter.h" - -#if ENABLE(TREE_DEBUGGING) -#include <stdio.h> -#endif +#include <wtf/unicode/Unicode.h> namespace WebCore { namespace SimpleLineLayout { -static void paintDebugBorders(GraphicsContext& context, LayoutRect borderRect, const LayoutPoint& paintOffset) +static void paintDebugBorders(GraphicsContext& context, const LayoutRect& borderRect, const LayoutPoint& paintOffset) { - borderRect.moveBy(paintOffset); - IntRect snappedRect = snappedIntRect(borderRect); - if (snappedRect.isEmpty()) + if (borderRect.isEmpty()) return; GraphicsContextStateSaver stateSaver(context); - context.setStrokeColor(Color(0, 255, 0)); - context.setFillColor(Color::transparent); - context.drawRect(snappedRect); -} - -static FloatRect computeOverflow(const RenderBlockFlow& flow, const FloatRect& layoutRect) -{ - auto overflowRect = layoutRect; - auto strokeOverflow = std::ceil(flow.style().textStrokeWidth()); - overflowRect.inflate(strokeOverflow); - - auto letterSpacing = flow.style().fontCascade().letterSpacing(); - if (letterSpacing >= 0) - return overflowRect; - // Last letter's negative spacing shrinks layout rect. Push it to visual overflow. - overflowRect.expand(-letterSpacing, 0); - return overflowRect; + context.setStrokeColor(Color(0, 255, 0), ColorSpaceDeviceRGB); + context.setFillColor(Color::transparent, ColorSpaceDeviceRGB); + LayoutRect rect(borderRect); + rect.moveBy(paintOffset); + context.drawRect(pixelSnappedIntRect(rect)); } void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset) @@ -88,48 +68,34 @@ void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& pai if (style.visibility() != VISIBLE) return; + RenderText& textRenderer = toRenderText(*flow.firstChild()); + ASSERT(!textRenderer.firstTextBox()); + bool debugBordersEnabled = flow.frame().settings().simpleLineLayoutDebugBordersEnabled(); - TextPainter textPainter(paintInfo.context()); - textPainter.setFont(style.fontCascade()); - textPainter.setTextPaintStyle(computeTextPaintStyle(flow.frame(), style, paintInfo)); - - Optional<TextDecorationPainter> textDecorationPainter; - if (style.textDecorationsInEffect() != TextDecorationNone) { - const RenderText* textRenderer = childrenOfType<RenderText>(flow).first(); - if (textRenderer) { - textDecorationPainter = TextDecorationPainter(paintInfo.context(), style.textDecorationsInEffect(), *textRenderer, false); - textDecorationPainter->setFont(style.fontCascade()); - textDecorationPainter->setBaseline(style.fontMetrics().ascent()); - } - } + GraphicsContext& context = *paintInfo.context; + + const Font& font = style.font(); + TextPaintStyle textPaintStyle = computeTextPaintStyle(textRenderer, style, paintInfo); + GraphicsContextStateSaver stateSaver(context, textPaintStyle.strokeWidth > 0); + + updateGraphicsContext(context, textPaintStyle); + LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); LayoutRect paintRect = paintInfo.rect; - paintRect.moveBy(-paintOffset); + paintRect.moveBy(-adjustedPaintOffset); auto resolver = runResolver(flow, layout); - float deviceScaleFactor = flow.document().deviceScaleFactor(); - for (auto run : resolver.rangeForRect(paintRect)) { - if (run.start() == run.end()) - continue; - - FloatRect rect = run.rect(); - FloatRect visualOverflowRect = computeOverflow(flow, rect); - if (paintRect.y() > visualOverflowRect.maxY() || paintRect.maxY() < visualOverflowRect.y()) + auto range = resolver.rangeForRect(paintRect); + for (auto it = range.begin(), end = range.end(); it != end; ++it) { + const auto& run = *it; + if (!run.rect().intersects(paintRect)) continue; - TextRun textRun(run.text()); textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize()); - // x position indicates the line offset from the rootbox. It's always 0 in case of simple line layout. - textRun.setXPos(0); - FloatPoint textOrigin = FloatPoint(rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor)); - textPainter.paintText(textRun, textRun.length(), rect, textOrigin); - if (textDecorationPainter) { - textDecorationPainter->setWidth(rect.width()); - textDecorationPainter->paintTextDecoration(textRun, textOrigin, rect.location() + paintOffset); - } + context.drawText(font, textRun, run.baseline() + adjustedPaintOffset); if (debugBordersEnabled) - paintDebugBorders(paintInfo.context(), LayoutRect(run.rect()), paintOffset); + paintDebugBorders(context, run.rect(), adjustedPaintOffset); } } @@ -145,17 +111,20 @@ bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTes if (style.visibility() != VISIBLE || style.pointerEvents() == PE_NONE) return false; - RenderObject& renderer = *flow.firstChild(); + RenderText& textRenderer = toRenderText(*flow.firstChild()); + LayoutRect rangeRect = locationInContainer.boundingBox(); rangeRect.moveBy(-accumulatedOffset); auto resolver = lineResolver(flow, layout); - for (FloatRect lineRect : resolver.rangeForRect(rangeRect)) { + auto range = resolver.rangeForRect(rangeRect); + for (auto it = range.begin(), end = range.end(); it != end; ++it) { + auto lineRect = *it; lineRect.moveBy(accumulatedOffset); if (!locationInContainer.intersects(lineRect)) continue; - renderer.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); - if (!result.addNodeToRectBasedTestResult(renderer.node(), request, locationInContainer, lineRect)) + textRenderer.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); + if (!result.addNodeToRectBasedTestResult(textRenderer.textNode(), request, locationInContainer, lineRect)) return true; } @@ -164,87 +133,64 @@ bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTes void collectFlowOverflow(RenderBlockFlow& flow, const Layout& layout) { - for (auto lineRect : lineResolver(flow, layout)) { - LayoutRect visualOverflowRect = LayoutRect(computeOverflow(flow, lineRect)); - flow.addLayoutOverflow(LayoutRect(lineRect)); - flow.addVisualOverflow(visualOverflowRect); + auto resolver = lineResolver(flow, layout); + for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { + auto rect = *it; + flow.addLayoutOverflow(rect); + flow.addVisualOverflow(rect); } } -IntRect computeBoundingBox(const RenderObject& renderer, const Layout& layout) +IntRect computeTextBoundingBox(const RenderText& textRenderer, const Layout& layout) { - auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout); - FloatRect boundingBoxRect; - for (auto run : resolver.rangeForRenderer(renderer)) { - FloatRect rect = run.rect(); - if (boundingBoxRect == FloatRect()) - boundingBoxRect = rect; - else - boundingBoxRect.uniteEvenIfEmpty(rect); + auto resolver = lineResolver(toRenderBlockFlow(*textRenderer.parent()), layout); + auto it = resolver.begin(); + auto end = resolver.end(); + if (it == end) + return IntRect(); + auto firstLineRect = *it; + float left = firstLineRect.x(); + float right = firstLineRect.maxX(); + float bottom = firstLineRect.maxY(); + for (++it; it != end; ++it) { + auto rect = *it; + if (rect.x() < left) + left = rect.x(); + if (rect.maxX() > right) + right = rect.maxX(); + if (rect.maxY() > bottom) + bottom = rect.maxY(); } - return enclosingIntRect(boundingBoxRect); -} - -IntPoint computeFirstRunLocation(const RenderObject& renderer, const Layout& layout) -{ - auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout); - auto range = resolver.rangeForRenderer(renderer); - auto begin = range.begin(); - if (begin == range.end()) - return IntPoint(0, 0); - return flooredIntPoint((*begin).rect().location()); + float x = firstLineRect.x(); + float y = firstLineRect.y(); + float width = right - left; + float height = bottom - y; + return enclosingIntRect(FloatRect(x, y, width, height)); } -Vector<IntRect> collectAbsoluteRects(const RenderObject& renderer, const Layout& layout, const LayoutPoint& accumulatedOffset) +Vector<IntRect> collectTextAbsoluteRects(const RenderText& textRenderer, const Layout& layout, const LayoutPoint& accumulatedOffset) { Vector<IntRect> rects; - auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout); - for (auto run : resolver.rangeForRenderer(renderer)) { - FloatRect rect = run.rect(); + auto resolver = runResolver(toRenderBlockFlow(*textRenderer.parent()), layout); + for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { + const auto& run = *it; + auto rect = run.rect(); rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size()))); } return rects; } -Vector<FloatQuad> collectAbsoluteQuads(const RenderObject& renderer, const Layout& layout, bool* wasFixed) +Vector<FloatQuad> collectTextAbsoluteQuads(const RenderText& textRenderer, const Layout& layout, bool* wasFixed) { Vector<FloatQuad> quads; - auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout); - for (auto run : resolver.rangeForRenderer(renderer)) - quads.append(renderer.localToAbsoluteQuad(FloatQuad(run.rect()), UseTransforms, wasFixed)); - return quads; -} - -#if ENABLE(TREE_DEBUGGING) -static void printPrefix(int& printedCharacters, int depth) -{ - fprintf(stderr, "------- --"); - printedCharacters = 0; - while (++printedCharacters <= depth * 2) - fputc(' ', stderr); -} - -void showLineLayoutForFlow(const RenderBlockFlow& flow, const Layout& layout, int depth) -{ - int printedCharacters = 0; - printPrefix(printedCharacters, depth); - - fprintf(stderr, "SimpleLineLayout (%u lines, %u runs) (%p)\n", layout.lineCount(), layout.runCount(), &layout); - ++depth; - - for (auto run : runResolver(flow, layout)) { - FloatRect rect = run.rect(); - printPrefix(printedCharacters, depth); - if (run.start() < run.end()) { - fprintf(stderr, "line %u run(%u, %u) (%.2f, %.2f) (%.2f, %.2f) \"%s\"\n", run.lineIndex(), run.start(), run.end(), - rect.x(), rect.y(), rect.width(), rect.height(), run.text().toStringWithoutCopying().utf8().data()); - } else { - ASSERT(run.start() == run.end()); - fprintf(stderr, "line break %u run(%u, %u) (%.2f, %.2f) (%.2f, %.2f)\n", run.lineIndex(), run.start(), run.end(), rect.x(), rect.y(), rect.width(), rect.height()); - } + auto resolver = runResolver(toRenderBlockFlow(*textRenderer.parent()), layout); + for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { + const auto& run = *it; + auto rect = run.rect(); + quads.append(textRenderer.localToAbsoluteQuad(FloatQuad(rect), 0, wasFixed)); } + return quads; } -#endif } } |