summaryrefslogtreecommitdiff
path: root/Source/WebCore/page/GestureTapHighlighter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/page/GestureTapHighlighter.cpp')
-rw-r--r--Source/WebCore/page/GestureTapHighlighter.cpp272
1 files changed, 0 insertions, 272 deletions
diff --git a/Source/WebCore/page/GestureTapHighlighter.cpp b/Source/WebCore/page/GestureTapHighlighter.cpp
deleted file mode 100644
index 7b1c0abb5..000000000
--- a/Source/WebCore/page/GestureTapHighlighter.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
- *
- * 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "GestureTapHighlighter.h"
-
-#include "Element.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "GraphicsTypes.h"
-#include "MainFrame.h"
-#include "Node.h"
-#include "Page.h"
-#include "RenderBoxModelObject.h"
-#include "RenderInline.h"
-#include "RenderLayer.h"
-#include "RenderObject.h"
-#include "RenderView.h"
-
-namespace WebCore {
-
-namespace {
-
-inline LayoutPoint ownerFrameToMainFrameOffset(const RenderObject* o)
-{
- ASSERT(o->node());
- Frame& containingFrame = o->frame();
-
- Frame& mainFrame = containingFrame.page()->mainFrame();
-
- LayoutPoint mainFramePoint = mainFrame.view()->windowToContents(containingFrame.view()->contentsToWindow(IntPoint()));
- return mainFramePoint;
-}
-
-AffineTransform localToAbsoluteTransform(const RenderObject* o)
-{
- AffineTransform transform;
- LayoutPoint referencePoint;
-
- while (o) {
- RenderObject* nextContainer = o->container();
- if (!nextContainer)
- break;
-
- LayoutSize containerOffset = o->offsetFromContainer(nextContainer, referencePoint);
- TransformationMatrix t;
- o->getTransformFromContainer(nextContainer, containerOffset, t);
-
- transform = t.toAffineTransform() * transform;
- referencePoint.move(containerOffset);
- o = nextContainer;
- }
-
- return transform;
-}
-
-inline bool contains(const LayoutRect& rect, int x)
-{
- return !rect.isEmpty() && x >= rect.x() && x <= rect.maxX();
-}
-
-inline bool strikes(const LayoutRect& a, const LayoutRect& b)
-{
- return !a.isEmpty() && !b.isEmpty()
- && a.x() <= b.maxX() && b.x() <= a.maxX()
- && a.y() <= b.maxY() && b.y() <= a.maxY();
-}
-
-inline void shiftXEdgesToContainIfStrikes(LayoutRect& rect, LayoutRect& other, bool isFirst)
-{
- if (rect.isEmpty())
- return;
-
- if (other.isEmpty() || !strikes(rect, other))
- return;
-
- LayoutUnit leftSide = std::min(rect.x(), other.x());
- LayoutUnit rightSide = std::max(rect.maxX(), other.maxX());
-
- rect.shiftXEdgeTo(leftSide);
- rect.shiftMaxXEdgeTo(rightSide);
-
- if (isFirst)
- other.shiftMaxXEdgeTo(rightSide);
- else
- other.shiftXEdgeTo(leftSide);
-}
-
-inline void addHighlightRect(Path& path, const LayoutRect& rect, const LayoutRect& prev, const LayoutRect& next)
-{
- // The rounding check depends on the rects not intersecting eachother,
- // or being contained for that matter.
- ASSERT(!rect.intersects(prev));
- ASSERT(!rect.intersects(next));
-
- if (rect.isEmpty())
- return;
-
- const int rounding = 4;
-
- FloatRect copy(rect);
- copy.inflateX(rounding);
- copy.inflateY(rounding / 2);
-
- FloatSize rounded(rounding * 1.8, rounding * 1.8);
- FloatSize squared(0, 0);
-
- path.addBeziersForRoundedRect(copy,
- contains(prev, rect.x()) ? squared : rounded,
- contains(prev, rect.maxX()) ? squared : rounded,
- contains(next, rect.x()) ? squared : rounded,
- contains(next, rect.maxX()) ? squared : rounded);
-}
-
-Path absolutePathForRenderer(RenderObject* const o)
-{
- ASSERT(o);
-
- Vector<IntRect> rects;
- LayoutPoint frameOffset = ownerFrameToMainFrameOffset(o);
- o->addFocusRingRects(rects, frameOffset);
-
- if (rects.isEmpty())
- return Path();
-
- // The basic idea is to allow up to three different boxes in order to highlight
- // text with line breaks more nicer than using a bounding box.
-
- // Merge all center boxes (all but the first and the last).
- LayoutRect mid;
-
- // Set the end value to integer. It ensures that no unsigned int overflow occurs
- // in the test expression, in case of empty rects vector.
- int end = rects.size() - 1;
- for (int i = 1; i < end; ++i)
- mid.uniteIfNonZero(rects.at(i));
-
- LayoutRect first;
- LayoutRect last;
-
- // Add the first box, but merge it with the center boxes if it intersects or if the center box is empty.
- if (rects.size() && !rects.first().isEmpty()) {
- // If the mid box is empty at this point, unite it with the first box. This allows the first box to be
- // united with the last box if they intersect in the following check for last. Not uniting them would
- // trigger in assert in addHighlighRect due to the first and the last box intersecting, but being passed
- // as two separate boxes.
- if (mid.isEmpty() || mid.intersects(rects.first()))
- mid.unite(rects.first());
- else {
- first = rects.first();
- shiftXEdgesToContainIfStrikes(mid, first, /* isFirst */ true);
- }
- }
-
- // Add the last box, but merge it with the center boxes if it intersects.
- if (rects.size() > 1 && !rects.last().isEmpty()) {
- // Adjust center boxes to boundary of last
- if (mid.intersects(rects.last()))
- mid.unite(rects.last());
- else {
- last = rects.last();
- shiftXEdgesToContainIfStrikes(mid, last, /* isFirst */ false);
- }
- }
-
- Vector<LayoutRect> drawableRects;
- if (!first.isEmpty())
- drawableRects.append(first);
- if (!mid.isEmpty())
- drawableRects.append(mid);
- if (!last.isEmpty())
- drawableRects.append(last);
-
- // Clip the overflow rects if needed, before the ring path is formed to
- // ensure rounded highlight rects.
- for (int i = drawableRects.size() - 1; i >= 0; --i) {
- LayoutRect& ringRect = drawableRects.at(i);
- LayoutPoint ringRectLocation = ringRect.location();
-
- ringRect.moveBy(-frameOffset);
-
- RenderLayer* layer = o->enclosingLayer();
- RenderObject* currentRenderer = o;
-
- // Check ancestor layers for overflow clip and intersect them.
- for (; layer; layer = layer->parent()) {
- RenderLayerModelObject* layerRenderer = &layer->renderer();
-
- if (layerRenderer->hasOverflowClip() && layerRenderer != currentRenderer) {
- bool containerSkipped = false;
- // Skip ancestor layers that are not containers for the current renderer.
- currentRenderer->container(layerRenderer, &containerSkipped);
- if (containerSkipped)
- continue;
- FloatQuad ringQuad = currentRenderer->localToContainerQuad(FloatQuad(ringRect), layerRenderer);
- // Ignore quads that are not rectangular, since we can not currently highlight them nicely.
- if (ringQuad.isRectilinear())
- ringRect = ringQuad.enclosingBoundingBox();
- else
- ringRect = LayoutRect();
- currentRenderer = layerRenderer;
-
- ASSERT(layerRenderer->isBox());
- ringRect.intersect(toRenderBox(layerRenderer)->borderBoxRect());
-
- if (ringRect.isEmpty())
- break;
- }
- }
-
- if (ringRect.isEmpty()) {
- drawableRects.remove(i);
- continue;
- }
- // After clipping, reset the original position so that parents' transforms apply correctly.
- ringRect.setLocation(ringRectLocation);
- }
-
- Path path;
- for (size_t i = 0; i < drawableRects.size(); ++i) {
- LayoutRect prev = i ? drawableRects.at(i - 1) : LayoutRect();
- LayoutRect next = i < (drawableRects.size() - 1) ? drawableRects.at(i + 1) : LayoutRect();
- addHighlightRect(path, drawableRects.at(i), prev, next);
- }
-
- path.transform(localToAbsoluteTransform(o));
- return path;
-}
-
-} // anonymous namespace
-
-namespace GestureTapHighlighter {
-
-Path pathForNodeHighlight(const Node* node)
-{
- RenderObject* renderer = node->renderer();
-
- if (!renderer || (!renderer->isBox() && !renderer->isRenderInline()))
- return Path();
-
- return absolutePathForRenderer(renderer);
-}
-
-} // namespace GestureTapHighlighter
-
-} // namespace WebCore