blob: 720d2224cd2d4118f33a51b32af7b58f61256769 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GeometryMapper_h
#define GeometryMapper_h
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/paint/PropertyTreeState.h"
#include "platform/transforms/TransformationMatrix.h"
#include "wtf/HashMap.h"
namespace blink {
struct PrecomputedDataForAncestor {
// Maps from a transform node that is a descendant of the ancestor to the
// combined transform between the descendant's and the ancestor's coordinate
// space.
HashMap<const TransformPaintPropertyNode*, TransformationMatrix>
toAncestorTransforms;
// Maps from a descendant clip node to its equivalent "clip visual rect" in
// the space of the ancestor. The clip visual rect is defined as the
// intersection of all clips between the descendant and the ancestor (*not*
// including the ancestor) in the clip tree, individually transformed from
// their localTransformSpace into the ancestor's localTransformSpace.
HashMap<const ClipPaintPropertyNode*, FloatRect> toAncestorClipRects;
static std::unique_ptr<PrecomputedDataForAncestor> create() {
return wrapUnique(new PrecomputedDataForAncestor());
}
};
// GeometryMapper is a helper class for fast computations of transformed and
// visual rects in different PropertyTreeStates. The design document has a
// number of details on use cases, algorithmic definitions, and running times.
//
// NOTE: A GeometryMapper object is only valid for property trees that do not
// change. If any mutation occurs, a new GeometryMapper object must be allocated
// corresponding to the new state.
//
// Design document: http://bit.ly/28P4FDA
//
// TODO(chrishtr): take effect tree into account.
class PLATFORM_EXPORT GeometryMapper {
public:
GeometryMapper() {}
// The runtime of m calls among localToVisualRectInAncestorSpace,
// localToAncestorRect or ancestorToLocalRect with the same |ancestorState|
// parameter is guaranteed to be O(n + m), where n is the number of transform
// and clip nodes in their respective property trees.
// If the clips and transforms of |sourceState| are equal to or descendants of
// those of |destinationState|, returns the same value as
// localToVisualRectInAncestorSpace. Otherwise, maps the input rect to the
// transform state which is the least common ancestor of
// |sourceState.transform| and |destinationState.transform|, then multiplies
// it by the the inverse transform mapping from the least common ancestor to
// |destinationState.transform|.
//
// Sets |success| to whether that inverse transform is invertible. If it is
// not, returns the input rect.
FloatRect mapToVisualRectInDestinationSpace(
const FloatRect&,
const PropertyTreeState& sourceState,
const PropertyTreeState& destinationState,
bool& success);
// Same as mapToVisualRectInDestinationSpace() except that *no* clip is
// applied.
FloatRect mapRectToDestinationSpace(const FloatRect&,
const PropertyTreeState& sourceState,
const PropertyTreeState& destinationState,
bool& success);
// Maps from a rect in |localTransformSpace| to its visual rect in
// |ancestorState|. This is computed by multiplying the rect by its combined
// transform between |localTransformSpace| and |ancestorSpace|, then
// flattening into 2D space, then intersecting by the "clip visual rect" for
// |localTransformState|'s clips. See above for the definition of "clip visual
// rect".
//
// Note that the clip of |ancestorState| is *not* applied.
//
// If any of the paint property tree nodes in |localTransformState| are not
// equal to or a descendant of that in |ancestorState|, returns the passed-in
// rect and sets |success| to false. Otherwise, sets |success| to true.
FloatRect localToVisualRectInAncestorSpace(
const FloatRect&,
const PropertyTreeState& localTransformState,
const PropertyTreeState& ancestorState,
bool& success);
// Maps from a rect in |localTransformSpace| to its transformed rect in
// |ancestorSpace|. This is computed by multiplying the rect by the combined
// transform between |localTransformState| and |ancestorState|, then
// flattening into 2D space.
//
// If any of the paint property tree nodes in |localTransformState| are not
// equal to or a descendant of that in |ancestorState|, returns the passed-in
// rec and sets |success| to false. Otherwise, sets |success| to true.
FloatRect localToAncestorRect(const FloatRect&,
const PropertyTreeState& localTransformState,
const PropertyTreeState& ancestorState,
bool& success);
// Maps from a rect in |ancestorSpace| to its transformed rect in
// |localTransformSpace|. This is computed by multiplying the rect by the
// inverse combined transform between |localTransformState| and
// |ancestorState|, if the transform is invertible.
//
// If any of the paint property tree nodes in |localTransformState| are not
// equal to or a descendant of that in |ancestorState|, returns the passed-in
// rect and sets |success| to false. Otherwise, sets |success| to true.
FloatRect ancestorToLocalRect(const FloatRect&,
const PropertyTreeState& localTransformState,
const PropertyTreeState& ancestorState,
bool& success);
private:
// Used by mapToVisualRectInDestinationSpace() after fast mapping (assuming
// destination is an ancestor of source) failed.
FloatRect slowMapToVisualRectInDestinationSpace(
const FloatRect&,
const PropertyTreeState& sourceState,
const PropertyTreeState& destinationState,
bool& success);
// Used by mapRectToDestinationSpace() after fast mapping (assuming
// destination is an ancestor of source) failed.
FloatRect slowMapRectToDestinationSpace(
const FloatRect&,
const PropertyTreeState& sourceState,
const PropertyTreeState& destinationState,
bool& success);
// Returns the matrix used in |LocalToAncestorRect|. Sets |success| to false
// iff |localTransformNode| is not equal to or a descendant of
// |ancestorState.transform|.
const TransformationMatrix& localToAncestorMatrix(
const TransformPaintPropertyNode* localTransformNode,
const PropertyTreeState& ancestorState,
bool& success);
// Returns the "clip visual rect" between |localTransformState| and
// |ancestorState|. See above for the definition of "clip visual rect".
FloatRect localToAncestorClipRect(
const PropertyTreeState& localTransformState,
const PropertyTreeState& ancestorState,
bool& success);
// Returns the precomputed data if already set, or adds and memoizes a new
// PrecomputedDataForAncestor otherwise.
PrecomputedDataForAncestor& getPrecomputedDataForAncestor(
const PropertyTreeState&);
// Returns the least common ancestor in the transform tree.
static const TransformPaintPropertyNode* leastCommonAncestor(
const TransformPaintPropertyNode*,
const TransformPaintPropertyNode*);
friend class GeometryMapperTest;
HashMap<const TransformPaintPropertyNode*,
std::unique_ptr<PrecomputedDataForAncestor>>
m_data;
const TransformationMatrix m_identity;
DISALLOW_COPY_AND_ASSIGN(GeometryMapper);
};
} // namespace blink
#endif // GeometryMapper_h