blob: b2ac9f0f360c9adc2b0661608fff15fc34416ea0 [file] [log] [blame]
/*
* Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDER "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 THE COPYRIGHT HOLDER 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.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SHAPES_SHAPE_OUTSIDE_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SHAPES_SHAPE_OUTSIDE_INFO_H_
#include <memory>
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/layout/shapes/shape.h"
#include "third_party/blink/renderer/core/style/shape_value.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
namespace blink {
class LayoutBox;
class LineLayoutBlockFlow;
class FloatingObject;
class ShapeOutsideDeltas final {
DISALLOW_NEW();
public:
ShapeOutsideDeltas() : line_overlaps_shape_(false), is_valid_(false) {}
ShapeOutsideDeltas(LayoutUnit left_margin_box_delta,
LayoutUnit right_margin_box_delta,
bool line_overlaps_shape,
LayoutUnit border_box_line_top,
LayoutUnit line_height)
: left_margin_box_delta_(left_margin_box_delta),
right_margin_box_delta_(right_margin_box_delta),
border_box_line_top_(border_box_line_top),
line_height_(line_height),
line_overlaps_shape_(line_overlaps_shape),
is_valid_(true) {}
bool IsForLine(LayoutUnit border_box_line_top, LayoutUnit line_height) {
return is_valid_ && border_box_line_top_ == border_box_line_top &&
line_height_ == line_height;
}
bool IsValid() { return is_valid_; }
LayoutUnit LeftMarginBoxDelta() {
DCHECK(is_valid_);
return left_margin_box_delta_;
}
LayoutUnit RightMarginBoxDelta() {
DCHECK(is_valid_);
return right_margin_box_delta_;
}
bool LineOverlapsShape() {
DCHECK(is_valid_);
return line_overlaps_shape_;
}
private:
LayoutUnit left_margin_box_delta_;
LayoutUnit right_margin_box_delta_;
LayoutUnit border_box_line_top_;
LayoutUnit line_height_;
bool line_overlaps_shape_ : 1;
bool is_valid_ : 1;
};
class ShapeOutsideInfo final {
USING_FAST_MALLOC(ShapeOutsideInfo);
public:
void SetReferenceBoxLogicalSize(LayoutSize);
void SetPercentageResolutionInlineSize(LayoutUnit);
LayoutUnit ShapeLogicalTop() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().Y() +
LogicalTopOffset();
}
LayoutUnit ShapeLogicalBottom() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().MaxY() +
LogicalTopOffset();
}
LayoutUnit ShapeLogicalLeft() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().X() +
LogicalLeftOffset();
}
LayoutUnit ShapeLogicalRight() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().MaxX() +
LogicalLeftOffset();
}
LayoutUnit ShapeLogicalWidth() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().Width();
}
LayoutUnit ShapeLogicalHeight() const {
return ComputedShape().ShapeMarginLogicalBoundingBox().Height();
}
static std::unique_ptr<ShapeOutsideInfo> CreateInfo(
const LayoutBox& layout_box) {
return base::WrapUnique(new ShapeOutsideInfo(layout_box));
}
static bool IsEnabledFor(const LayoutBox&);
ShapeOutsideDeltas ComputeDeltasForContainingBlockLine(
const LineLayoutBlockFlow&,
const FloatingObject&,
LayoutUnit line_top,
LayoutUnit line_height);
static ShapeOutsideInfo& EnsureInfo(const LayoutBox& key) {
InfoMap& info_map = ShapeOutsideInfo::GetInfoMap();
if (ShapeOutsideInfo* info = info_map.at(&key))
return *info;
InfoMap::AddResult result =
info_map.insert(&key, ShapeOutsideInfo::CreateInfo(key));
return *result.stored_value->value;
}
static void RemoveInfo(const LayoutBox& key) { GetInfoMap().erase(&key); }
static ShapeOutsideInfo* Info(const LayoutBox& key) {
return GetInfoMap().at(&key);
}
static bool IsEmpty() { return GetInfoMap().IsEmpty(); }
void MarkShapeAsDirty() { shape_.reset(); }
bool IsShapeDirty() { return !shape_.get(); }
LayoutSize ShapeSize() const { return reference_box_logical_size_; }
bool IsComputingShape() const { return is_computing_shape_; }
LayoutRect ComputedShapePhysicalBoundingBox() const;
FloatPoint ShapeToLayoutObjectPoint(FloatPoint) const;
FloatSize ShapeToLayoutObjectSize(FloatSize) const;
const Shape& ComputedShape() const;
protected:
ShapeOutsideInfo(const LayoutBox& layout_box)
: layout_box_(layout_box), is_computing_shape_(false) {}
private:
std::unique_ptr<Shape> CreateShapeForImage(StyleImage*,
float shape_image_threshold,
WritingMode,
float margin) const;
LayoutUnit LogicalTopOffset() const;
LayoutUnit LogicalLeftOffset() const;
typedef HashMap<const LayoutBox*, std::unique_ptr<ShapeOutsideInfo>> InfoMap;
static InfoMap& GetInfoMap() {
DEFINE_STATIC_LOCAL(InfoMap, static_info_map, ());
return static_info_map;
}
const LayoutBox& layout_box_;
mutable std::unique_ptr<Shape> shape_;
LayoutSize reference_box_logical_size_;
LayoutUnit percentage_resolution_inline_size_;
ShapeOutsideDeltas shape_outside_deltas_;
mutable bool is_computing_shape_;
};
} // namespace blink
#endif