diff options
Diffstat (limited to 'Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp')
-rw-r--r-- | Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp | 144 |
1 files changed, 59 insertions, 85 deletions
diff --git a/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp index 59d1a7de5..346879569 100644 --- a/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp +++ b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp @@ -42,20 +42,21 @@ #include "SimpleLineLayoutResolver.h" #include "Text.h" #include "TextPaintStyle.h" +#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), ColorSpaceDeviceRGB); context.setFillColor(Color::transparent, ColorSpaceDeviceRGB); - context.drawRect(snappedRect); + LayoutRect rect(borderRect); + rect.moveBy(paintOffset); + context.drawRect(pixelSnappedIntRect(rect)); } void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset) @@ -67,33 +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(); GraphicsContext& context = *paintInfo.context; - const FontCascade& font = style.fontCascade(); - TextPaintStyle textPaintStyle = computeTextPaintStyle(flow.frame(), style, paintInfo); + + 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 strokeOverflow = ceilf(flow.style().textStrokeWidth()); - float deviceScaleFactor = flow.document().deviceScaleFactor(); - for (const auto& run : resolver.rangeForRect(paintRect)) { - FloatRect rect = run.rect(); - rect.inflate(strokeOverflow); - if (!rect.intersects(paintRect) || run.start() == run.end()) + 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)); - context.drawText(font, textRun, textOrigin); + context.drawText(font, textRun, run.baseline() + adjustedPaintOffset); if (debugBordersEnabled) - paintDebugBorders(context, LayoutRect(run.rect()), paintOffset); + paintDebugBorders(context, run.rect(), adjustedPaintOffset); } } @@ -109,7 +111,8 @@ 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); @@ -120,8 +123,8 @@ bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTes 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; } @@ -131,92 +134,63 @@ bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTes void collectFlowOverflow(RenderBlockFlow& flow, const Layout& layout) { auto resolver = lineResolver(flow, layout); - float strokeOverflow = ceilf(flow.style().textStrokeWidth()); for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { - auto rect = LayoutRect(*it); - rect.inflate(strokeOverflow); + 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 (const 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); + float x = firstLineRect.x(); + float y = firstLineRect.y(); + float width = right - left; + float height = bottom - y; + return enclosingIntRect(FloatRect(x, y, width, height)); } -IntPoint computeFirstRunLocation(const RenderObject& renderer, const Layout& layout) -{ - auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout); - const auto& it = resolver.rangeForRenderer(renderer); - auto begin = it.begin(); - if (begin == it.end()) - return IntPoint(0, 0); - - return flooredIntPoint((*begin).rect().location()); -} - -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 (const 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 (const 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; - - auto resolver = runResolver(flow, layout); + auto resolver = runResolver(toRenderBlockFlow(*textRenderer.parent()), layout); for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { const auto& run = *it; - 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 rect = run.rect(); + quads.append(textRenderer.localToAbsoluteQuad(FloatQuad(rect), 0, wasFixed)); } + return quads; } -#endif } } |