diff options
Diffstat (limited to 'Source/WebCore/page/GestureTapHighlighter.cpp')
-rw-r--r-- | Source/WebCore/page/GestureTapHighlighter.cpp | 272 |
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 |