Import Cobalt 12.89101
Change-Id: I225b849391c5f9c1632811b81ee2391ac2a44666
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index e6c9c94..06db324 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-88774
\ No newline at end of file
+89101
\ No newline at end of file
diff --git a/src/cobalt/input/input_poller_impl.cc b/src/cobalt/input/input_poller_impl.cc
index 008c249..847e4ef 100644
--- a/src/cobalt/input/input_poller_impl.cc
+++ b/src/cobalt/input/input_poller_impl.cc
@@ -63,30 +63,30 @@
switch (input_event->key_code()) {
case kSbKeyGamepadLeftStickUp: {
key_offset_map_[kSbKeyGamepadLeftStickUp] =
- input_event->position().y();
- key_offset_map_[kSbKeyGamepadLeftStickDown] =
-input_event->position().y();
+ key_offset_map_[kSbKeyGamepadLeftStickDown] =
+ input_event->position().y();
break;
}
case kSbKeyGamepadLeftStickLeft: {
key_offset_map_[kSbKeyGamepadLeftStickLeft] =
- input_event->position().x();
- key_offset_map_[kSbKeyGamepadLeftStickRight] =
-input_event->position().x();
+ key_offset_map_[kSbKeyGamepadLeftStickRight] =
+ input_event->position().x();
break;
}
case kSbKeyGamepadRightStickUp: {
key_offset_map_[kSbKeyGamepadRightStickUp] =
- input_event->position().y();
- key_offset_map_[kSbKeyGamepadRightStickDown] =
-input_event->position().y();
+ key_offset_map_[kSbKeyGamepadRightStickDown] =
+ input_event->position().y();
break;
}
case kSbKeyGamepadRightStickLeft: {
key_offset_map_[kSbKeyGamepadRightStickLeft] =
- input_event->position().x();
- key_offset_map_[kSbKeyGamepadRightStickRight] =
-input_event->position().x();
+ key_offset_map_[kSbKeyGamepadRightStickRight] =
+ input_event->position().x();
break;
}
default:
diff --git a/src/cobalt/layout/anonymous_block_box.cc b/src/cobalt/layout/anonymous_block_box.cc
index db8843f..4dd67af 100644
--- a/src/cobalt/layout/anonymous_block_box.cc
+++ b/src/cobalt/layout/anonymous_block_box.cc
@@ -40,6 +40,9 @@
Box::Level AnonymousBlockBox::GetLevel() const { return kBlockLevel; }
AnonymousBlockBox* AnonymousBlockBox::AsAnonymousBlockBox() { return this; }
+const AnonymousBlockBox* AnonymousBlockBox::AsAnonymousBlockBox() const {
+ return this;
+}
void AnonymousBlockBox::SplitBidiLevelRuns() {
ContainerBox::SplitBidiLevelRuns();
diff --git a/src/cobalt/layout/anonymous_block_box.h b/src/cobalt/layout/anonymous_block_box.h
index abaaf20..8aa09a9 100644
--- a/src/cobalt/layout/anonymous_block_box.h
+++ b/src/cobalt/layout/anonymous_block_box.h
@@ -40,6 +40,7 @@
// From |Box|.
Level GetLevel() const OVERRIDE;
AnonymousBlockBox* AsAnonymousBlockBox() OVERRIDE;
+ const AnonymousBlockBox* AsAnonymousBlockBox() const OVERRIDE;
void SplitBidiLevelRuns() OVERRIDE;
diff --git a/src/cobalt/layout/box.cc b/src/cobalt/layout/box.cc
index 1c3663f..921466e 100644
--- a/src/cobalt/layout/box.cc
+++ b/src/cobalt/layout/box.cc
@@ -142,7 +142,8 @@
}
}
-LayoutUnit Box::GetContainingBlockLeftOffset(bool stop_at_transform) const {
+Vector2dLayoutUnit Box::GetContainingBlockOffsetFromRoot(
+ bool transform_forms_root) const {
// If the box is absolutely positioned, then its containing block is formed by
// the padding box instead of the content box, as described in
// http://www.w3.org/TR/CSS21/visudet.html#containing-block-details.
@@ -151,27 +152,11 @@
// all major browsers use the padding box of a transformed ancestor as the
// containing block for 'fixed' position elements.
return parent_ ? IsAbsolutelyPositioned()
- ? GetContainingBlock()->GetPaddingBoxLeftEdge(
- stop_at_transform)
- : GetContainingBlock()->GetContentBoxLeftEdge(
- stop_at_transform)
- : LayoutUnit();
-}
-
-LayoutUnit Box::GetContainingBlockTopOffset(bool stop_at_transform) const {
- // If the box is absolutely positioned, then its containing block is formed by
- // the padding box instead of the content box, as described in
- // http://www.w3.org/TR/CSS21/visudet.html#containing-block-details.
- // NOTE: While not explicitly stated in the spec, which specifies that the
- // containing block of a 'fixed' position element must always be the viewport,
- // all major browsers use the padding box of a transformed ancestor as the
- // containing block for 'fixed' position elements.
- return parent_ ? IsAbsolutelyPositioned()
- ? GetContainingBlock()->GetPaddingBoxTopEdge(
- stop_at_transform)
- : GetContainingBlock()->GetContentBoxTopEdge(
- stop_at_transform)
- : LayoutUnit();
+ ? GetContainingBlock()->GetPaddingBoxOffsetFromRoot(
+ transform_forms_root)
+ : GetContainingBlock()->GetContentBoxOffsetFromRoot(
+ transform_forms_root)
+ : Vector2dLayoutUnit();
}
void Box::SetStaticPositionLeftFromParent(LayoutUnit left) {
@@ -247,20 +232,14 @@
return margin_top() + GetBorderBoxHeight() + margin_bottom();
}
-LayoutUnit Box::GetMarginBoxLeftEdge(bool stop_at_transform) const {
- LayoutUnit containing_block_left_offset =
- (!stop_at_transform || !IsTransformed())
- ? GetContainingBlockLeftOffset(stop_at_transform)
- : LayoutUnit();
- return containing_block_left_offset + left();
-}
-
-LayoutUnit Box::GetMarginBoxTopEdge(bool stop_at_transform) const {
- LayoutUnit containing_block_top_offset =
- (!stop_at_transform || !IsTransformed())
- ? GetContainingBlockTopOffset(stop_at_transform)
- : LayoutUnit();
- return containing_block_top_offset + top();
+Vector2dLayoutUnit Box::GetMarginBoxOffsetFromRoot(
+ bool transform_forms_root) const {
+ Vector2dLayoutUnit containing_block_offset_from_root =
+ (!transform_forms_root || !IsTransformed())
+ ? GetContainingBlockOffsetFromRoot(transform_forms_root)
+ : Vector2dLayoutUnit();
+ return containing_block_offset_from_root +
+ margin_box_offset_from_containing_block();
}
LayoutUnit Box::GetMarginBoxRightEdgeOffsetFromContainingBlock() const {
@@ -285,6 +264,52 @@
: GetMarginBoxRightEdgeOffsetFromContainingBlock();
}
+RectLayoutUnit Box::GetBorderBoxFromRoot(bool transform_forms_root) const {
+ Vector2dLayoutUnit border_box_offset =
+ GetBorderBoxOffsetFromRoot(transform_forms_root);
+ return RectLayoutUnit(border_box_offset.x(), border_box_offset.y(),
+ GetBorderBoxWidth(), GetBorderBoxHeight());
+}
+
+RectLayoutUnit Box::GetTransformedBorderBoxFromRoot() const {
+ // Initialize the box corners to the border box.
+ RectLayoutUnit border_box =
+ GetBorderBoxFromRoot(true /*transform_forms_root*/);
+ std::vector<math::Vector2dF> box_corners;
+ box_corners.push_back(
+ math::Vector2dF(border_box.x().toFloat(), border_box.y().toFloat()));
+ box_corners.push_back(
+ math::Vector2dF((border_box.x() + border_box.width()).toFloat(),
+ border_box.y().toFloat()));
+ box_corners.push_back(
+ math::Vector2dF(border_box.x().toFloat(),
+ (border_box.y() + border_box.height()).toFloat()));
+ box_corners.push_back(
+ math::Vector2dF((border_box.x() + border_box.width()).toFloat(),
+ (border_box.y() + border_box.height()).toFloat()));
+
+ // Update the coordinates of the 4 corners by walking up to root and removing
+ // any transforms that have been applied.
+ for (const Box* check_box = this; check_box != NULL;
+ check_box = check_box->GetContainingBlock()) {
+ check_box->ApplyTransformActionToCoordinates(kExitTransform, &box_corners);
+ }
+
+ // Generate the new box from the min and max values of all of the corners.
+ math::Vector2dF& current_corner = box_corners[0];
+ math::Vector2dF min_corner(current_corner);
+ math::Vector2dF max_corner(current_corner);
+ for (size_t i = 1; i < 4; ++i) {
+ current_corner = box_corners[i];
+ min_corner.SetToMin(current_corner);
+ max_corner.SetToMax(current_corner);
+ }
+
+ return RectLayoutUnit(LayoutUnit(min_corner.x()), LayoutUnit(min_corner.y()),
+ LayoutUnit(max_corner.x() - min_corner.x()),
+ LayoutUnit(max_corner.y() - min_corner.y()));
+}
+
LayoutUnit Box::GetBorderBoxWidth() const {
return border_left_width() + GetPaddingBoxWidth() + border_right_width();
}
@@ -293,22 +318,18 @@
return border_top_width() + GetPaddingBoxHeight() + border_bottom_width();
}
-RectLayoutUnit Box::GetBorderBox(bool stop_at_transform) const {
- return RectLayoutUnit(GetBorderBoxLeftEdge(stop_at_transform),
- GetBorderBoxTopEdge(stop_at_transform),
- GetBorderBoxWidth(), GetBorderBoxHeight());
-}
-
SizeLayoutUnit Box::GetBorderBoxSize() const {
return SizeLayoutUnit(GetBorderBoxWidth(), GetBorderBoxHeight());
}
-LayoutUnit Box::GetBorderBoxLeftEdge(bool stop_at_transform) const {
- return GetMarginBoxLeftEdge(stop_at_transform) + margin_left();
+Vector2dLayoutUnit Box::GetBorderBoxOffsetFromRoot(
+ bool transform_forms_root) const {
+ return GetMarginBoxOffsetFromRoot(transform_forms_root) +
+ GetBorderBoxOffsetFromMarginBox();
}
-LayoutUnit Box::GetBorderBoxTopEdge(bool stop_at_transform) const {
- return GetMarginBoxTopEdge(stop_at_transform) + margin_top();
+Vector2dLayoutUnit Box::GetBorderBoxOffsetFromMarginBox() const {
+ return Vector2dLayoutUnit(margin_left(), margin_top());
}
LayoutUnit Box::GetPaddingBoxWidth() const {
@@ -323,12 +344,20 @@
return SizeLayoutUnit(GetPaddingBoxWidth(), GetPaddingBoxHeight());
}
-LayoutUnit Box::GetPaddingBoxLeftEdge(bool stop_at_transform) const {
- return GetBorderBoxLeftEdge(stop_at_transform) + border_left_width();
+Vector2dLayoutUnit Box::GetPaddingBoxOffsetFromRoot(
+ bool transform_forms_root) const {
+ return GetBorderBoxOffsetFromRoot(transform_forms_root) +
+ GetPaddingBoxOffsetFromBorderBox();
}
-LayoutUnit Box::GetPaddingBoxTopEdge(bool stop_at_transform) const {
- return GetBorderBoxTopEdge(stop_at_transform) + border_top_width();
+Vector2dLayoutUnit Box::GetPaddingBoxOffsetFromBorderBox() const {
+ return Vector2dLayoutUnit(border_left_width(), border_top_width());
+}
+
+Vector2dLayoutUnit Box::GetContentBoxOffsetFromRoot(
+ bool transform_forms_root) const {
+ return GetPaddingBoxOffsetFromRoot(transform_forms_root) +
+ GetContentBoxOffsetFromPaddingBox();
}
Vector2dLayoutUnit Box::GetContentBoxOffsetFromMarginBox() const {
@@ -370,14 +399,6 @@
return Vector2dLayoutUnit(padding_left(), padding_top());
}
-LayoutUnit Box::GetContentBoxLeftEdge(bool stop_at_transform) const {
- return GetPaddingBoxLeftEdge(stop_at_transform) + padding_left();
-}
-
-LayoutUnit Box::GetContentBoxTopEdge(bool stop_at_transform) const {
- return GetPaddingBoxTopEdge(stop_at_transform) + padding_top();
-}
-
LayoutUnit Box::GetInlineLevelBoxHeight() const { return GetMarginBoxHeight(); }
LayoutUnit Box::GetInlineLevelTopMargin() const { return LayoutUnit(); }
@@ -649,8 +670,11 @@
}
AnonymousBlockBox* Box::AsAnonymousBlockBox() { return NULL; }
+const AnonymousBlockBox* Box::AsAnonymousBlockBox() const { return NULL; }
ContainerBox* Box::AsContainerBox() { return NULL; }
const ContainerBox* Box::AsContainerBox() const { return NULL; }
+TextBox* Box::AsTextBox() { return NULL; }
+const TextBox* Box::AsTextBox() const { return NULL; }
#ifdef COBALT_BOX_DUMP_ENABLED
@@ -922,7 +946,7 @@
}
bool Box::IsUnderCoordinate(const Vector2dLayoutUnit& coordinate) const {
- RectLayoutUnit rect = GetBorderBox(true /*stop_at_transform*/);
+ RectLayoutUnit rect = GetBorderBoxFromRoot(true /*transform_forms_root*/);
bool res =
coordinate.x() >= rect.x() && coordinate.x() <= rect.x() + rect.width() &&
coordinate.y() >= rect.y() && coordinate.y() <= rect.y() + rect.height();
@@ -1589,40 +1613,69 @@
}
}
-void Box::UpdateCoordinateForTransform(math::Vector2dF* coordinate) const {
- // If the element has a transform, it needs to be applied.
- if (!computed_style()) {
- return;
- }
+void Box::ApplyTransformActionToCoordinate(TransformAction action,
+ math::Vector2dF* coordinate) const {
+ std::vector<math::Vector2dF> coordinate_vector;
+ coordinate_vector.push_back(*coordinate);
+ ApplyTransformActionToCoordinates(action, &coordinate_vector);
+ *coordinate = coordinate_vector[0];
+}
+
+void Box::ApplyTransformActionToCoordinates(
+ TransformAction action, std::vector<math::Vector2dF>* coordinates) const {
const scoped_refptr<cssom::PropertyValue>& transform =
computed_style()->transform();
- if (transform != cssom::KeywordValue::GetNone()) {
- LayoutUnit containing_block_left_offset =
- GetContainingBlockLeftOffset(true /*stop_at_transform*/);
- LayoutUnit containing_block_top_offset =
- GetContainingBlockTopOffset(true /*stop_at_transform*/);
+ if (transform == cssom::KeywordValue::GetNone()) {
+ return;
+ }
- math::Vector2dF border_box_offset(
- (containing_block_left_offset + left() + margin_left()).toFloat(),
- (containing_block_top_offset + top() + margin_top()).toFloat());
+ // The border box offset is calculated in two steps because we want to
+ // stop at the second transform and not the first (which is this box).
+ Vector2dLayoutUnit containing_block_offset_from_root =
+ GetContainingBlockOffsetFromRoot(true /*transform_forms_root*/);
+ Vector2dLayoutUnit border_box_offset_from_root =
+ (containing_block_offset_from_root +
+ margin_box_offset_from_containing_block() +
+ GetBorderBoxOffsetFromMarginBox());
- math::RectF rect = math::RectF(PointAtOffsetFromOrigin(border_box_offset),
- GetBorderBoxSize());
- math::Matrix3F matrix =
- GetCSSTransform(transform, computed_style()->transform_origin(), rect);
- if (!matrix.IsIdentity()) {
- // Transform the coordinate.
- math::PointF transformed_point =
- matrix.Inverse() * math::PointF(coordinate->x(), coordinate->y());
- coordinate->set_x(transformed_point.x());
- coordinate->set_y(transformed_point.y());
+ // Transform the coordinates.
+ math::Matrix3F matrix =
+ GetCSSTransform(transform, computed_style()->transform_origin(),
+ math::RectF(border_box_offset_from_root.x().toFloat(),
+ border_box_offset_from_root.y().toFloat(),
+ GetBorderBoxWidth().toFloat(),
+ GetBorderBoxHeight().toFloat()));
+ if (!matrix.IsIdentity()) {
+ if (action == kEnterTransform) {
+ matrix = matrix.Inverse();
}
- // The transformed box forms a new coordinate system and its containing
- // block's offset is considered (0,0) within it. Convert the coordinate to
- // the new system.
- *coordinate -= math::Vector2dF(containing_block_left_offset.toFloat(),
- containing_block_top_offset.toFloat());
+ for (std::vector<math::Vector2dF>::iterator coordinate_iter =
+ coordinates->begin();
+ coordinate_iter != coordinates->end(); ++coordinate_iter) {
+ math::Vector2dF& coordinate = *coordinate_iter;
+ math::PointF transformed_point =
+ matrix * math::PointF(coordinate.x(), coordinate.y());
+ coordinate.set_x(transformed_point.x());
+ coordinate.set_y(transformed_point.y());
+ }
+ }
+
+ // The transformed box forms a new coordinate system and its containing
+ // block's offset is the origin within it. Update the coordinates for their
+ // new origin.
+ math::Vector2dF containing_block_offset_from_root_as_float(
+ containing_block_offset_from_root.x().toFloat(),
+ containing_block_offset_from_root.y().toFloat());
+ for (std::vector<math::Vector2dF>::iterator coordinate_iter =
+ coordinates->begin();
+ coordinate_iter != coordinates->end(); ++coordinate_iter) {
+ math::Vector2dF& coordinate = *coordinate_iter;
+ if (action == kEnterTransform) {
+ coordinate -= containing_block_offset_from_root_as_float;
+ } else {
+ coordinate += containing_block_offset_from_root_as_float;
+ }
}
}
diff --git a/src/cobalt/layout/box.h b/src/cobalt/layout/box.h
index 7686c84..580ccbd 100644
--- a/src/cobalt/layout/box.h
+++ b/src/cobalt/layout/box.h
@@ -50,6 +50,7 @@
class AnonymousBlockBox;
class ContainerBox;
+class TextBox;
class UsedStyleProvider;
struct LayoutParams {
@@ -115,6 +116,11 @@
kIsBoxDescendant,
};
+ enum TransformAction {
+ kEnterTransform,
+ kExitTransform,
+ };
+
// Info tracked on container boxes encountered when a stacking context is
// generating its cross references.
struct StackingContextContainerBoxInfo {
@@ -213,13 +219,9 @@
// out-of-flow descendants. Does not update the position of the box.
void UpdateSize(const LayoutParams& layout_params);
- // Returns the left offset from root (or a transform if |stop_at_transform| is
- // true) to this box's containing block.
- LayoutUnit GetContainingBlockLeftOffset(bool stop_at_transform) const;
-
- // Returns the top offset from root (or a transform if |stop_at_transform| is
- // true) to this box's containing block.
- LayoutUnit GetContainingBlockTopOffset(bool stop_at_transform) const;
+ // Returns the offset from root to this box's containing block.
+ Vector2dLayoutUnit GetContainingBlockOffsetFromRoot(
+ bool transform_forms_root) const;
// Used values of "left" and "top" are publicly readable and writable so that
// they can be calculated and adjusted by the formatting context of
@@ -270,43 +272,53 @@
// border, padding, and content boxes.
// Margin box.
+ LayoutUnit margin_left() const { return margin_insets_.left(); }
+ LayoutUnit margin_top() const { return margin_insets_.top(); }
+ LayoutUnit margin_right() const { return margin_insets_.right(); }
+ LayoutUnit margin_bottom() const { return margin_insets_.bottom(); }
LayoutUnit GetMarginBoxWidth() const;
LayoutUnit GetMarginBoxHeight() const;
+
+ Vector2dLayoutUnit GetMarginBoxOffsetFromRoot(
+ bool transform_forms_root) const;
const Vector2dLayoutUnit& margin_box_offset_from_containing_block() const {
return margin_box_offset_from_containing_block_;
}
- LayoutUnit GetMarginBoxLeftEdge(bool stop_at_transform) const;
- LayoutUnit GetMarginBoxTopEdge(bool stop_at_transform) const;
LayoutUnit GetMarginBoxRightEdgeOffsetFromContainingBlock() const;
LayoutUnit GetMarginBoxBottomEdgeOffsetFromContainingBlock() const;
LayoutUnit GetMarginBoxStartEdgeOffsetFromContainingBlock(
BaseDirection base_direction) const;
LayoutUnit GetMarginBoxEndEdgeOffsetFromContainingBlock(
BaseDirection base_direction) const;
- LayoutUnit margin_left() const { return margin_insets_.left(); }
- LayoutUnit margin_top() const { return margin_insets_.top(); }
- LayoutUnit margin_right() const { return margin_insets_.right(); }
- LayoutUnit margin_bottom() const { return margin_insets_.bottom(); }
// Border box.
+ RectLayoutUnit GetBorderBoxFromRoot(bool transform_forms_root) const;
+ RectLayoutUnit GetTransformedBorderBoxFromRoot() const;
+
LayoutUnit GetBorderBoxWidth() const;
LayoutUnit GetBorderBoxHeight() const;
- RectLayoutUnit GetBorderBox(bool stop_at_transform) const;
SizeLayoutUnit GetBorderBoxSize() const;
- LayoutUnit GetBorderBoxLeftEdge(bool stop_at_transform) const;
- LayoutUnit GetBorderBoxTopEdge(bool stop_at_transform) const;
+
+ Vector2dLayoutUnit GetBorderBoxOffsetFromRoot(
+ bool transform_forms_root) const;
+ Vector2dLayoutUnit GetBorderBoxOffsetFromMarginBox() const;
// Padding box.
LayoutUnit GetPaddingBoxWidth() const;
LayoutUnit GetPaddingBoxHeight() const;
SizeLayoutUnit GetPaddingBoxSize() const;
- LayoutUnit GetPaddingBoxLeftEdge(bool stop_at_transform) const;
- LayoutUnit GetPaddingBoxTopEdge(bool stop_at_transform) const;
+
+ Vector2dLayoutUnit GetPaddingBoxOffsetFromRoot(
+ bool transform_forms_root) const;
+ Vector2dLayoutUnit GetPaddingBoxOffsetFromBorderBox() const;
// Content box.
LayoutUnit width() const { return content_size_.width(); }
LayoutUnit height() const { return content_size_.height(); }
const SizeLayoutUnit& content_box_size() const { return content_size_; }
+
+ Vector2dLayoutUnit GetContentBoxOffsetFromRoot(
+ bool transform_forms_root) const;
Vector2dLayoutUnit GetContentBoxOffsetFromMarginBox() const;
Vector2dLayoutUnit GetContentBoxOffsetFromPaddingBox() const;
LayoutUnit GetContentBoxLeftEdgeOffsetFromMarginBox() const;
@@ -317,8 +329,6 @@
BaseDirection base_direction) const;
LayoutUnit GetContentBoxEndEdgeOffsetFromContainingBlock(
BaseDirection base_direction) const;
- LayoutUnit GetContentBoxLeftEdge(bool stop_at_transform) const;
- LayoutUnit GetContentBoxTopEdge(bool stop_at_transform) const;
// The height of each inline-level box in the line box is calculated. For
// replaced elements, inline-block elements, and inline-table elements, this
@@ -486,8 +496,11 @@
// Poor man's reflection.
virtual AnonymousBlockBox* AsAnonymousBlockBox();
+ virtual const AnonymousBlockBox* AsAnonymousBlockBox() const;
virtual ContainerBox* AsContainerBox();
virtual const ContainerBox* AsContainerBox() const;
+ virtual TextBox* AsTextBox();
+ virtual const TextBox* AsTextBox() const;
#ifdef COBALT_BOX_DUMP_ENABLED
// Used by box generator to set a DOM node that produced this box.
@@ -549,9 +562,11 @@
static bool IsRenderedLater(RenderSequence render_sequence,
RenderSequence other_render_sequence);
- // Updates the passed coordinate corresponding to the transform applied to
- // this box.
- void UpdateCoordinateForTransform(math::Vector2dF* coordinate) const;
+ // Applies the specified transform action to the provided coordinates.
+ void ApplyTransformActionToCoordinate(TransformAction action,
+ math::Vector2dF* coordinate) const;
+ void ApplyTransformActionToCoordinates(
+ TransformAction action, std::vector<math::Vector2dF>* coordinates) const;
protected:
UsedStyleProvider* used_style_provider() const {
diff --git a/src/cobalt/layout/container_box.h b/src/cobalt/layout/container_box.h
index 3d184c4..a5b823f 100644
--- a/src/cobalt/layout/container_box.h
+++ b/src/cobalt/layout/container_box.h
@@ -240,6 +240,7 @@
// This mutual friendship is a result of the need to maintain 2-way links
// between boxes and containers.
friend class Box;
+ friend class LayoutBoxes;
DISALLOW_COPY_AND_ASSIGN(ContainerBox);
};
diff --git a/src/cobalt/layout/layout_boxes.cc b/src/cobalt/layout/layout_boxes.cc
index 6068bac..99787b8 100644
--- a/src/cobalt/layout/layout_boxes.cc
+++ b/src/cobalt/layout/layout_boxes.cc
@@ -15,6 +15,7 @@
#include "cobalt/layout/layout_boxes.h"
#include "cobalt/cssom/keyword_value.h"
+#include "cobalt/layout/anonymous_block_box.h"
#include "cobalt/layout/container_box.h"
#include "cobalt/layout/rect_layout_unit.h"
#include "cobalt/layout/size_layout_unit.h"
@@ -50,28 +51,19 @@
// . Replace each anonymous block box with its child box(es) and repeat this
// until no anonymous block boxes are left in the final list.
+ Boxes client_rect_boxes;
+ GetClientRectBoxes(boxes_, &client_rect_boxes);
+
scoped_refptr<dom::DOMRectList> dom_rect_list(new dom::DOMRectList());
- for (Boxes::const_iterator box_iterator = boxes_.begin();
- box_iterator != boxes_.end(); ++box_iterator) {
- Box* box = *box_iterator;
- do {
- scoped_refptr<dom::DOMRect> dom_rect(new dom::DOMRect());
-
- // TODO: Take transforms into account and recurse into anonymous block
- // boxes. Our current clients don't currently rely on GetClientRects() to
- // do that.
-
- dom_rect->set_x(
- box->GetBorderBoxLeftEdge(false /*stop_at_transform*/).toFloat());
- dom_rect->set_y(
- box->GetBorderBoxTopEdge(false /*stop_at_transform*/).toFloat());
- SizeLayoutUnit box_size = box->GetBorderBoxSize();
- dom_rect->set_width(box_size.width().toFloat());
- dom_rect->set_height(box_size.height().toFloat());
- dom_rect_list->AppendDOMRect(dom_rect);
-
- box = box->GetSplitSibling();
- } while (box != NULL);
+ for (Boxes::const_iterator box_iterator = client_rect_boxes.begin();
+ box_iterator != client_rect_boxes.end(); ++box_iterator) {
+ RectLayoutUnit transformed_border_box(
+ (*box_iterator)->GetTransformedBorderBoxFromRoot());
+ dom_rect_list->AppendDOMRect(
+ new dom::DOMRect(transformed_border_box.x().toFloat(),
+ transformed_border_box.y().toFloat(),
+ transformed_border_box.width().toFloat(),
+ transformed_border_box.height().toFloat()));
}
return dom_rect_list;
@@ -122,14 +114,16 @@
float LayoutBoxes::GetPaddingEdgeLeft() const {
DCHECK(!boxes_.empty());
return boxes_.front()
- ->GetPaddingBoxLeftEdge(false /*stop_at_transform*/)
+ ->GetPaddingBoxOffsetFromRoot(false /*transform_forms_root*/)
+ .x()
.toFloat();
}
float LayoutBoxes::GetPaddingEdgeTop() const {
DCHECK(!boxes_.empty());
return boxes_.front()
- ->GetPaddingBoxTopEdge(false /*stop_at_transform*/)
+ ->GetPaddingBoxOffsetFromRoot(false /*transform_forms_root*/)
+ .y()
.toFloat();
}
@@ -193,7 +187,8 @@
box_iterator != boxes_.end(); ++box_iterator) {
Box* box = *box_iterator;
do {
- bounding_rectangle.Union(box->GetBorderBox(false /*stop_at_transform*/));
+ bounding_rectangle.Union(
+ box->GetBorderBoxFromRoot(false /*transform_forms_root*/));
box = box->GetSplitSibling();
} while (box != NULL);
}
@@ -204,5 +199,28 @@
bounding_rectangle.height().toFloat());
}
+void LayoutBoxes::GetClientRectBoxes(const Boxes& boxes,
+ Boxes* client_rect_boxes) const {
+ for (Boxes::const_iterator box_iterator = boxes.begin();
+ box_iterator != boxes.end(); ++box_iterator) {
+ Box* box = *box_iterator;
+ do {
+ // Replace each anonymous block box with its child box(es) and repeat this
+ // until no anonymous block boxes are left in the final list.
+ const AnonymousBlockBox* anonymous_block_box = box->AsAnonymousBlockBox();
+ if (anonymous_block_box) {
+ GetClientRectBoxes(anonymous_block_box->child_boxes(),
+ client_rect_boxes);
+ } else if (!box->AsTextBox()) {
+ // Only add the box if it isn't a text box. Text boxes are anonymous
+ // inline boxes and shouldn't be included.
+ client_rect_boxes->push_back(box);
+ }
+
+ box = box->GetSplitSibling();
+ } while (box != NULL);
+ }
+}
+
} // namespace layout
} // namespace cobalt
diff --git a/src/cobalt/layout/layout_boxes.h b/src/cobalt/layout/layout_boxes.h
index 1d49883..e2733b1 100644
--- a/src/cobalt/layout/layout_boxes.h
+++ b/src/cobalt/layout/layout_boxes.h
@@ -67,6 +67,8 @@
// Returns the bounding rectangle of the border edges of the boxes.
math::RectF GetBoundingBorderRectangle() const;
+ void GetClientRectBoxes(const Boxes& boxes, Boxes* client_rect_boxes) const;
+
Boxes boxes_;
};
diff --git a/src/cobalt/layout/text_box.cc b/src/cobalt/layout/text_box.cc
index 79d8ba6..127b1d3 100644
--- a/src/cobalt/layout/text_box.cc
+++ b/src/cobalt/layout/text_box.cc
@@ -66,6 +66,9 @@
Box::Level TextBox::GetLevel() const { return kInlineLevel; }
+TextBox* TextBox::AsTextBox() { return this; }
+const TextBox* TextBox::AsTextBox() const { return this; }
+
bool TextBox::ValidateUpdateSizeInputs(const LayoutParams& params) {
// Also take into account mutable local state about (at least) whether white
// space should be collapsed or not.
diff --git a/src/cobalt/layout/text_box.h b/src/cobalt/layout/text_box.h
index 7fb798e..240fed1 100644
--- a/src/cobalt/layout/text_box.h
+++ b/src/cobalt/layout/text_box.h
@@ -43,6 +43,8 @@
// From |Box|.
Level GetLevel() const OVERRIDE;
+ TextBox* AsTextBox() OVERRIDE;
+ const TextBox* AsTextBox() const OVERRIDE;
void UpdateContentSizeAndMargins(const LayoutParams& layout_params) OVERRIDE;
diff --git a/src/cobalt/layout/topmost_event_target.cc b/src/cobalt/layout/topmost_event_target.cc
index 83cd9cc..44f2eb8 100644
--- a/src/cobalt/layout/topmost_event_target.cc
+++ b/src/cobalt/layout/topmost_event_target.cc
@@ -73,7 +73,10 @@
const Boxes& boxes = layout_boxes->boxes();
if (!boxes.empty()) {
const Box* box = boxes.front();
- box->UpdateCoordinateForTransform(&element_coordinate);
+ if (box->computed_style() && box->IsTransformed()) {
+ box->ApplyTransformActionToCoordinate(Box::kEnterTransform,
+ &element_coordinate);
+ }
ConsiderBoxes(html_element, layout_boxes, element_coordinate);
}
}
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform-expected.png b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform-expected.png
new file mode 100644
index 0000000..ae9f398
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform.html b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform.html
new file mode 100644
index 0000000..e44fa3f
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_transform.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<!--
+ | Test CSSOM View extensions to the Element Interface, verifying that
+ | getBoundingClientRect() works properly with transforms.
+ -->
+<html>
+<head>
+ <style>
+ body {
+ background-color: #FFFFFF;
+ margin: 0px;
+ font-family: Roboto;
+ font-size: 40px;
+ }
+ .absolutely-positioned-1 {
+ position: absolute;
+ transform: translateX(100px) translateY(50px);
+ left: 30px;
+ top: 10px;
+ width: 100px;
+ }
+ .absolutely-positioned-2 {
+ position: absolute;
+ transform: translateX(10px) translateY(-50px);
+ left: 120px;
+ top: 110px;
+ width: 150px;
+ }
+ </style>
+ <script>
+ if (window.testRunner) {
+ window.testRunner.waitUntilDone();
+ }
+
+ function verifyGetBoundingClientRectAttributesAreCorrect(id) {
+ var element = document.getElementById(id);
+ if (!element) {
+ document.body.style.backgroundColor = "#F44336";
+ } else {
+ var expected_left = 130;
+ var expected_top = 60;
+
+ bounding_rect = element.getBoundingClientRect();
+ if (bounding_rect["left"] != expected_left) {
+ console.log("getElementById(\'" + id +
+ "\').getBoundingClientRect()." + "left" + " == " +
+ bounding_rect["left"] + " != " + expected_left);
+ element.style.backgroundColor = "#F44336";
+ }
+
+ if (bounding_rect["top"] != expected_top) {
+ console.log("getElementById(\'" + id +
+ "\').getBoundingClientRect()." + "top" + " == " +
+ bounding_rect["top"] + " != " + expected_top);
+ element.style.backgroundColor = "#F44336";
+ }
+ }
+ }
+
+ function runTest() {
+ verifyGetBoundingClientRectAttributesAreCorrect("span-1");
+ verifyGetBoundingClientRectAttributesAreCorrect("span-2");
+ }
+
+ window.onload = function() {
+ runTest();
+
+ if (window.testRunner) {
+ window.testRunner.notifyDone();
+ }
+ }
+ </script>
+</head>
+<body>
+ <div id="div-1" class="absolutely-positioned-1">
+ <span id="span-1">Yes</span>
+ </div>
+ <div id="div-2" class="absolutely-positioned-2">
+ <span id="span-2">Yes</span>
+ </div>
+</body>
+</html>
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt b/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
index 7c45b36..88679e8 100644
--- a/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
+++ b/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
@@ -1,4 +1,5 @@
extensions_to_the_element_interface_client_top_left_width_height
extensions_to_the_element_interface_get_bounding_client_rect_with_box_splitting
+extensions_to_the_element_interface_get_bounding_client_rect_with_transform
extensions_to_the_html_element_interface_offset_top_left_width_height
-extensions_to_the_html_element_interface_offset_width_height_with_box_splitting
\ No newline at end of file
+extensions_to_the_html_element_interface_offset_width_height_with_box_splitting
diff --git a/src/cobalt/renderer/rasterizer/blitter/image.cc b/src/cobalt/renderer/rasterizer/blitter/image.cc
index f51569e..21a6b1c 100644
--- a/src/cobalt/renderer/rasterizer/blitter/image.cc
+++ b/src/cobalt/renderer/rasterizer/blitter/image.cc
@@ -96,7 +96,8 @@
SubmitOffscreenCallback submit_offscreen_callback, SbBlitterDevice device)
: size_(static_cast<int>(root->GetBounds().right()),
static_cast<int>(root->GetBounds().bottom())),
- is_opaque_(false) {
+ is_opaque_(false),
+ surface_(kSbBlitterInvalidSurface) {
initialize_image_ = base::Bind(
&SinglePlaneImage::InitializeImageFromRenderTree, base::Unretained(this),
root, submit_offscreen_callback, device);
diff --git a/src/starboard/CHANGELOG.md b/src/starboard/CHANGELOG.md
index 6bcc0d7..4b2c85c 100644
--- a/src/starboard/CHANGELOG.md
+++ b/src/starboard/CHANGELOG.md
@@ -69,6 +69,11 @@
Add `key_statuses_changed_callback` parameter to `SbDrmCreateSystem()` to
support MediaKeySession::keyStatuses and MediaKeySession::onkeystatuseschange.
+### Changes thumbstick direction
+
+Change the meaning of negative values for thumbstick position from bottom
+right to upper left.
+
## Version 5
### Add Speech Recognizer API
diff --git a/src/starboard/input.h b/src/starboard/input.h
index 9c1e2cc..3510230 100644
--- a/src/starboard/input.h
+++ b/src/starboard/input.h
@@ -176,7 +176,7 @@
// The value is |0| if this data is not applicable. For events with type
// kSbInputEventTypeMove and device_type kSbInputDeviceTypeGamepad, this field
// is interpreted as a stick position with the range [-1, 1], with positive
- // values for the up and left direction.
+ // values for the down and right direction.
SbInputVector position;
// The relative motion vector of this input. The value is |0| if this data is
diff --git a/src/starboard/shared/linux/dev_input/dev_input.cc b/src/starboard/shared/linux/dev_input/dev_input.cc
index d0bd7fe..27a6d10 100644
--- a/src/starboard/shared/linux/dev_input/dev_input.cc
+++ b/src/starboard/shared/linux/dev_input/dev_input.cc
@@ -987,36 +987,33 @@
SbInputVector input_vector;
// The mapping for the axis codes can vary from controller to controller.
// TODO: Include axis mapping for controllers with different layout.
+ // Report up and left as negative values.
switch (event.code) {
case ABS_X:
- // Report up and left as positive values.
- input_vector.x = -axis_value;
- input_vector.y = -device_info->axis_value[ABS_Y];
+ input_vector.x = axis_value;
+ input_vector.y = device_info->axis_value[ABS_Y];
key = kSbKeyGamepadLeftStickLeft;
location = kSbKeyLocationLeft;
return CreateMoveEventWithKey(window_, key, location, modifiers,
input_vector);
case ABS_Y: {
- // Report up and left as positive values.
- input_vector.x = -device_info->axis_value[ABS_X];
- input_vector.y = -axis_value;
+ input_vector.x = device_info->axis_value[ABS_X];
+ input_vector.y = axis_value;
key = kSbKeyGamepadLeftStickUp;
location = kSbKeyLocationLeft;
return CreateMoveEventWithKey(window_, key, location, modifiers,
input_vector);
}
case ABS_Z:
- // Report up and left as positive values.
- input_vector.x = -axis_value;
- input_vector.y = -device_info->axis_value[ABS_RZ];
+ input_vector.x = axis_value;
+ input_vector.y = device_info->axis_value[ABS_RZ];
key = kSbKeyGamepadRightStickLeft;
location = kSbKeyLocationRight;
return CreateMoveEventWithKey(window_, key, location, modifiers,
input_vector);
case ABS_RZ:
- // Report up and left as positive values.
- input_vector.x = -device_info->axis_value[ABS_Z];
- input_vector.y = -axis_value;
+ input_vector.x = device_info->axis_value[ABS_Z];
+ input_vector.y = axis_value;
key = kSbKeyGamepadRightStickUp;
location = kSbKeyLocationRight;
return CreateMoveEventWithKey(window_, key, location, modifiers,
@@ -1065,8 +1062,8 @@
device_info->touchpad_position_state = kTouchPadPositionNone;
if (touchpad_position_is_known) {
// Touch point is released, report last known position as unpress.
- input_vector.x = (device_info->axis_value[ABS_MT_POSITION_X] + 1 / 2);
- input_vector.y = (device_info->axis_value[ABS_MT_POSITION_Y] + 1 / 2);
+ input_vector.x = device_info->axis_value[ABS_MT_POSITION_X] * 2;
+ input_vector.y = device_info->axis_value[ABS_MT_POSITION_Y];
return CreateTouchPadEvent(window_, kSbInputEventTypeUnpress, key,
location, modifiers, input_vector);
}
@@ -1080,9 +1077,10 @@
: kSbInputEventTypePress;
device_info->touchpad_position_state |= kTouchPadPositionX;
if (IsTouchpadPositionKnown(device_info)) {
- // For touchpads, the range is [0..1].
- input_vector.x = (axis_value + 1) / 2;
- input_vector.y = (device_info->axis_value[ABS_MT_POSITION_Y] + 1) / 2;
+ // For touchpads, the unit range is [-1..1]. Negative values for top
+ // left.
+ input_vector.x = axis_value * 2; // Touch are is twice as wide.
+ input_vector.y = device_info->axis_value[ABS_MT_POSITION_Y];
return CreateTouchPadEvent(window_, type, key, location, modifiers,
input_vector);
}
@@ -1097,9 +1095,9 @@
: kSbInputEventTypePress;
device_info->touchpad_position_state |= kTouchPadPositionY;
if (IsTouchpadPositionKnown(device_info)) {
- // For touchpads, the range is [0..1].
- input_vector.x = (device_info->axis_value[ABS_MT_POSITION_X] + 1) / 2;
- input_vector.y = (axis_value + 1) / 2;
+ // For touchpads, the range is [-1..1]. Negative values for top left.
+ input_vector.x = device_info->axis_value[ABS_MT_POSITION_X] * 2;
+ input_vector.y = axis_value;
return CreateTouchPadEvent(window_, type, key, location, modifiers,
input_vector);
}
diff --git a/src/starboard/shared/uwp/application_uwp_key_event.cc b/src/starboard/shared/uwp/application_uwp_key_event.cc
index 73b7d27..abc3ef3 100644
--- a/src/starboard/shared/uwp/application_uwp_key_event.cc
+++ b/src/starboard/shared/uwp/application_uwp_key_event.cc
@@ -207,8 +207,8 @@
case VirtualKey::GamepadDPadDown: return kSbKeyGamepadDPadDown;
case VirtualKey::GamepadDPadLeft: return kSbKeyGamepadDPadLeft;
case VirtualKey::GamepadDPadRight: return kSbKeyGamepadDPadRight;
- case VirtualKey::GamepadMenu: return kSbKeyGamepad6;
- case VirtualKey::GamepadView: return kSbKeyGamepad5;
+ case VirtualKey::GamepadMenu: return kSbKeyMediaLaunchMediaSelect;
+ case VirtualKey::GamepadView: return kSbKeyF1;
case VirtualKey::GamepadLeftThumbstickButton:
return kSbKeyGamepadLeftStick;
case VirtualKey::GamepadRightThumbstickButton:
diff --git a/src/starboard/shared/win32/audio_sink.cc b/src/starboard/shared/win32/audio_sink.cc
index 5967211..7097582 100644
--- a/src/starboard/shared/win32/audio_sink.cc
+++ b/src/starboard/shared/win32/audio_sink.cc
@@ -183,6 +183,7 @@
uint64_t samples_played = 0;
int queued_buffers = 0;
bool was_playing = false; // The player starts out playing by default.
+ double current_volume = 1.0;
for (;;) {
{
ScopedLock lock(mutex_);
@@ -193,11 +194,18 @@
int frames_in_buffer, offset_in_frames;
bool is_playing, is_eos_reached;
bool is_playback_rate_zero;
- // TODO: Support |volume_| here as well...
+ bool should_set_volume;
{
ScopedLock lock(mutex_);
is_playback_rate_zero = playback_rate_ == 0.0;
+ should_set_volume = current_volume != volume_;
+ current_volume = volume_;
}
+
+ if (should_set_volume) {
+ CHECK_HRESULT_OK(source_voice_->SetVolume(current_volume));
+ }
+
update_source_status_func_(&frames_in_buffer, &offset_in_frames,
&is_playing, &is_eos_reached, context_);
if (is_playback_rate_zero) {