summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
commite15dd966d523731101f70ccf768bba12435a0208 (patch)
treeae9cb828a24ded2585a41af3f21411523b47897d /Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
downloadWebKitGtk-tarball-e15dd966d523731101f70ccf768bba12435a0208.tar.gz
webkitgtk-2.10.2webkitgtk-2.10.2
Diffstat (limited to 'Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp')
-rw-r--r--Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp222
1 files changed, 222 insertions, 0 deletions
diff --git a/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
new file mode 100644
index 000000000..59d1a7de5
--- /dev/null
+++ b/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SimpleLineLayoutFunctions.h"
+
+#include "FontCache.h"
+#include "Frame.h"
+#include "GraphicsContext.h"
+#include "HitTestLocation.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
+#include "InlineTextBox.h"
+#include "PaintInfo.h"
+#include "RenderBlockFlow.h"
+#include "RenderStyle.h"
+#include "RenderText.h"
+#include "RenderView.h"
+#include "Settings.h"
+#include "SimpleLineLayoutResolver.h"
+#include "Text.h"
+#include "TextPaintStyle.h"
+
+namespace WebCore {
+namespace SimpleLineLayout {
+
+static void paintDebugBorders(GraphicsContext& context, LayoutRect borderRect, const LayoutPoint& paintOffset)
+{
+ borderRect.moveBy(paintOffset);
+ IntRect snappedRect = snappedIntRect(borderRect);
+ if (snappedRect.isEmpty())
+ return;
+ GraphicsContextStateSaver stateSaver(context);
+ context.setStrokeColor(Color(0, 255, 0), ColorSpaceDeviceRGB);
+ context.setFillColor(Color::transparent, ColorSpaceDeviceRGB);
+ context.drawRect(snappedRect);
+}
+
+void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ if (paintInfo.phase != PaintPhaseForeground)
+ return;
+
+ RenderStyle& style = flow.style();
+ if (style.visibility() != VISIBLE)
+ return;
+
+ bool debugBordersEnabled = flow.frame().settings().simpleLineLayoutDebugBordersEnabled();
+
+ GraphicsContext& context = *paintInfo.context;
+ const FontCascade& font = style.fontCascade();
+ TextPaintStyle textPaintStyle = computeTextPaintStyle(flow.frame(), style, paintInfo);
+ GraphicsContextStateSaver stateSaver(context, textPaintStyle.strokeWidth > 0);
+
+ updateGraphicsContext(context, textPaintStyle);
+ LayoutRect paintRect = paintInfo.rect;
+ paintRect.moveBy(-paintOffset);
+
+ 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())
+ 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);
+ if (debugBordersEnabled)
+ paintDebugBorders(context, LayoutRect(run.rect()), paintOffset);
+ }
+}
+
+bool hitTestFlow(const RenderBlockFlow& flow, const Layout& layout, const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
+{
+ if (hitTestAction != HitTestForeground)
+ return false;
+
+ if (!layout.runCount())
+ return false;
+
+ RenderStyle& style = flow.style();
+ if (style.visibility() != VISIBLE || style.pointerEvents() == PE_NONE)
+ return false;
+
+ RenderObject& renderer = *flow.firstChild();
+ LayoutRect rangeRect = locationInContainer.boundingBox();
+ rangeRect.moveBy(-accumulatedOffset);
+
+ auto resolver = lineResolver(flow, layout);
+ 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))
+ return true;
+ }
+
+ return false;
+}
+
+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);
+ flow.addLayoutOverflow(rect);
+ flow.addVisualOverflow(rect);
+ }
+}
+
+IntRect computeBoundingBox(const RenderObject& renderer, 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);
+ }
+ return enclosingIntRect(boundingBoxRect);
+}
+
+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> rects;
+ auto resolver = runResolver(downcast<RenderBlockFlow>(*renderer.parent()), layout);
+ for (const auto& run : resolver.rangeForRenderer(renderer)) {
+ FloatRect 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> 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);
+ 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());
+ }
+ }
+}
+#endif
+
+}
+}