|  | /* | 
|  | * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. | 
|  | * Copyright (C) 2013 Google 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 COMPUTER, INC. ``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 COMPUTER, INC. OR | 
|  | * 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 "platform/Widget.h" | 
|  |  | 
|  | #include "wtf/Assertions.h" | 
|  |  | 
|  | namespace blink { | 
|  |  | 
|  | Widget::Widget() | 
|  | : m_parent(nullptr) | 
|  | , m_selfVisible(false) | 
|  | , m_parentVisible(false) | 
|  | { | 
|  | } | 
|  |  | 
|  | Widget::~Widget() | 
|  | { | 
|  | } | 
|  |  | 
|  | DEFINE_TRACE(Widget) | 
|  | { | 
|  | visitor->trace(m_parent); | 
|  | } | 
|  |  | 
|  | void Widget::setParent(Widget* widget) | 
|  | { | 
|  | ASSERT(!widget || !m_parent); | 
|  | if (!widget || !widget->isVisible()) | 
|  | setParentVisible(false); | 
|  | m_parent = widget; | 
|  | if (widget && widget->isVisible()) | 
|  | setParentVisible(true); | 
|  | } | 
|  |  | 
|  | Widget* Widget::root() const | 
|  | { | 
|  | const Widget* top = this; | 
|  | while (top->parent()) | 
|  | top = top->parent(); | 
|  | if (top->isFrameView()) | 
|  | return const_cast<Widget*>(static_cast<const Widget*>(top)); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | IntRect Widget::convertFromRootFrame(const IntRect& rectInRootFrame) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntRect parentRect = parentWidget->convertFromRootFrame(rectInRootFrame); | 
|  | return convertFromContainingWidget(parentRect); | 
|  | } | 
|  | return rectInRootFrame; | 
|  | } | 
|  |  | 
|  | IntRect Widget::convertToRootFrame(const IntRect& localRect) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntRect parentRect = convertToContainingWidget(localRect); | 
|  | return parentWidget->convertToRootFrame(parentRect); | 
|  | } | 
|  | return localRect; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertFromRootFrame(const IntPoint& pointInRootFrame) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntPoint parentPoint = parentWidget->convertFromRootFrame(pointInRootFrame); | 
|  | return convertFromContainingWidget(parentPoint); | 
|  | } | 
|  | return pointInRootFrame; | 
|  | } | 
|  |  | 
|  | FloatPoint Widget::convertFromRootFrame(const FloatPoint& pointInRootFrame) const | 
|  | { | 
|  | // Widgets / windows are required to be IntPoint aligned, but we may need to convert | 
|  | // FloatPoint values within them (eg. for event co-ordinates). | 
|  | IntPoint flooredPoint = flooredIntPoint(pointInRootFrame); | 
|  | FloatPoint parentPoint = this->convertFromRootFrame(flooredPoint); | 
|  | FloatSize windowFraction = pointInRootFrame - flooredPoint; | 
|  | // Use linear interpolation handle any fractional value (eg. for iframes subject to a transform | 
|  | // beyond just a simple translation). | 
|  | // FIXME: Add FloatPoint variants of all co-ordinate space conversion APIs. | 
|  | if (!windowFraction.isEmpty()) { | 
|  | const int kFactor = 1000; | 
|  | IntPoint parentLineEnd = this->convertFromRootFrame(flooredPoint + roundedIntSize(windowFraction.scaledBy(kFactor))); | 
|  | FloatSize parentFraction = (parentLineEnd - parentPoint).scaledBy(1.0f / kFactor); | 
|  | parentPoint.move(parentFraction); | 
|  | } | 
|  | return parentPoint; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertToRootFrame(const IntPoint& localPoint) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntPoint parentPoint = convertToContainingWidget(localPoint); | 
|  | return parentWidget->convertToRootFrame(parentPoint); | 
|  | } | 
|  | return localPoint; | 
|  | } | 
|  |  | 
|  | IntRect Widget::convertToContainingWidget(const IntRect& localRect) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntRect parentRect(localRect); | 
|  | parentRect.setLocation(parentWidget->convertChildToSelf(this, localRect.location())); | 
|  | return parentRect; | 
|  | } | 
|  | return localRect; | 
|  | } | 
|  |  | 
|  | IntRect Widget::convertFromContainingWidget(const IntRect& parentRect) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) { | 
|  | IntRect localRect = parentRect; | 
|  | localRect.setLocation(parentWidget->convertSelfToChild(this, localRect.location())); | 
|  | return localRect; | 
|  | } | 
|  |  | 
|  | return parentRect; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertToContainingWidget(const IntPoint& localPoint) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) | 
|  | return parentWidget->convertChildToSelf(this, localPoint); | 
|  |  | 
|  | return localPoint; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertFromContainingWidget(const IntPoint& parentPoint) const | 
|  | { | 
|  | if (const Widget* parentWidget = parent()) | 
|  | return parentWidget->convertSelfToChild(this, parentPoint); | 
|  |  | 
|  | return parentPoint; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertChildToSelf(const Widget*, const IntPoint& point) const | 
|  | { | 
|  | return point; | 
|  | } | 
|  |  | 
|  | IntPoint Widget::convertSelfToChild(const Widget*, const IntPoint& point) const | 
|  | { | 
|  | return point; | 
|  | } | 
|  |  | 
|  | } // namespace blink |