Extend the geometry APIs. Add a RRect structure for rounded rect. Define helpers for manipulating transformation matrices. Define output formatters for geometry datatypes. BUG= R=viettrungluu@chromium.org, abarth, abarth@chromium.org, jamesr, viettrungluu Review URL: https://codereview.chromium.org/1517853002 . Review URL: https://codereview.chromium.org/1537633005 .
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/geometry.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/geometry.mojom.dart index 90422dd..cc4fbc7 100644 --- a/mojo/dart/packages/mojo_services/lib/mojo/geometry.mojom.dart +++ b/mojo/dart/packages/mojo_services/lib/mojo/geometry.mojom.dart
@@ -9,8 +9,6 @@ import 'package:mojo/bindings.dart' as bindings; import 'package:mojo/core.dart' as core; - - class Point extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ const bindings.StructDataHeader(16, 0) @@ -50,15 +48,13 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - result.x = decoder0.decodeInt32(8); } if (mainDataHeader.version >= 0) { - result.y = decoder0.decodeInt32(12); } return result; @@ -66,16 +62,18 @@ void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeInt32(x, 8); - + encoder0.encodeInt32(y, 12); } String toString() { return "Point(" - "x: $x" ", " - "y: $y" ")"; + "x: $x" + ", " + "y: $y" + ")"; } Map toJson() { @@ -86,7 +84,6 @@ } } - class PointF extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ const bindings.StructDataHeader(16, 0) @@ -126,15 +123,13 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - result.x = decoder0.decodeFloat(8); } if (mainDataHeader.version >= 0) { - result.y = decoder0.decodeFloat(12); } return result; @@ -142,16 +137,18 @@ void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeFloat(x, 8); - + encoder0.encodeFloat(y, 12); } String toString() { return "PointF(" - "x: $x" ", " - "y: $y" ")"; + "x: $x" + ", " + "y: $y" + ")"; } Map toJson() { @@ -162,7 +159,6 @@ } } - class Size extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ const bindings.StructDataHeader(16, 0) @@ -202,15 +198,13 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - result.width = decoder0.decodeInt32(8); } if (mainDataHeader.version >= 0) { - result.height = decoder0.decodeInt32(12); } return result; @@ -218,16 +212,18 @@ void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeInt32(width, 8); - + encoder0.encodeInt32(height, 12); } String toString() { return "Size(" - "width: $width" ", " - "height: $height" ")"; + "width: $width" + ", " + "height: $height" + ")"; } Map toJson() { @@ -238,7 +234,6 @@ } } - class Rect extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ const bindings.StructDataHeader(24, 0) @@ -280,23 +275,19 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - result.x = decoder0.decodeInt32(8); } if (mainDataHeader.version >= 0) { - result.y = decoder0.decodeInt32(12); } if (mainDataHeader.version >= 0) { - result.width = decoder0.decodeInt32(16); } if (mainDataHeader.version >= 0) { - result.height = decoder0.decodeInt32(20); } return result; @@ -304,22 +295,26 @@ void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeInt32(x, 8); - + encoder0.encodeInt32(y, 12); - + encoder0.encodeInt32(width, 16); - + encoder0.encodeInt32(height, 20); } String toString() { return "Rect(" - "x: $x" ", " - "y: $y" ", " - "width: $width" ", " - "height: $height" ")"; + "x: $x" + ", " + "y: $y" + ", " + "width: $width" + ", " + "height: $height" + ")"; } Map toJson() { @@ -332,7 +327,6 @@ } } - class RectF extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ const bindings.StructDataHeader(24, 0) @@ -374,23 +368,19 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - result.x = decoder0.decodeFloat(8); } if (mainDataHeader.version >= 0) { - result.y = decoder0.decodeFloat(12); } if (mainDataHeader.version >= 0) { - result.width = decoder0.decodeFloat(16); } if (mainDataHeader.version >= 0) { - result.height = decoder0.decodeFloat(20); } return result; @@ -398,22 +388,26 @@ void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeFloat(x, 8); - + encoder0.encodeFloat(y, 12); - + encoder0.encodeFloat(width, 16); - + encoder0.encodeFloat(height, 20); } String toString() { return "RectF(" - "x: $x" ", " - "y: $y" ", " - "width: $width" ", " - "height: $height" ")"; + "x: $x" + ", " + "y: $y" + ", " + "width: $width" + ", " + "height: $height" + ")"; } Map toJson() { @@ -426,6 +420,170 @@ } } +class RRect extends bindings.Struct { + static const List<bindings.StructDataHeader> kVersions = const [ + const bindings.StructDataHeader(56, 0) + ]; + int x = 0; + int y = 0; + int width = 0; + int height = 0; + int topLeftRadiusX = 0; + int topLeftRadiusY = 0; + int topRightRadiusX = 0; + int topRightRadiusY = 0; + int bottomLeftRadiusX = 0; + int bottomLeftRadiusY = 0; + int bottomRightRadiusX = 0; + int bottomRightRadiusY = 0; + + RRect() : super(kVersions.last.size); + + static RRect deserialize(bindings.Message message) { + var decoder = new bindings.Decoder(message); + var result = decode(decoder); + if (decoder.excessHandles != null) { + decoder.excessHandles.forEach((h) => h.close()); + } + return result; + } + + static RRect decode(bindings.Decoder decoder0) { + if (decoder0 == null) { + return null; + } + RRect result = new RRect(); + + var mainDataHeader = decoder0.decodeStructDataHeader(); + if (mainDataHeader.version <= kVersions.last.version) { + // Scan in reverse order to optimize for more recent versions. + for (int i = kVersions.length - 1; i >= 0; --i) { + if (mainDataHeader.version >= kVersions[i].version) { + if (mainDataHeader.size == kVersions[i].size) { + // Found a match. + break; + } + throw new bindings.MojoCodecError( + 'Header size doesn\'t correspond to known version size.'); + } + } + } else if (mainDataHeader.size < kVersions.last.size) { + throw new bindings.MojoCodecError( + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); + } + if (mainDataHeader.version >= 0) { + result.x = decoder0.decodeInt32(8); + } + if (mainDataHeader.version >= 0) { + result.y = decoder0.decodeInt32(12); + } + if (mainDataHeader.version >= 0) { + result.width = decoder0.decodeInt32(16); + } + if (mainDataHeader.version >= 0) { + result.height = decoder0.decodeInt32(20); + } + if (mainDataHeader.version >= 0) { + result.topLeftRadiusX = decoder0.decodeInt32(24); + } + if (mainDataHeader.version >= 0) { + result.topLeftRadiusY = decoder0.decodeInt32(28); + } + if (mainDataHeader.version >= 0) { + result.topRightRadiusX = decoder0.decodeInt32(32); + } + if (mainDataHeader.version >= 0) { + result.topRightRadiusY = decoder0.decodeInt32(36); + } + if (mainDataHeader.version >= 0) { + result.bottomLeftRadiusX = decoder0.decodeInt32(40); + } + if (mainDataHeader.version >= 0) { + result.bottomLeftRadiusY = decoder0.decodeInt32(44); + } + if (mainDataHeader.version >= 0) { + result.bottomRightRadiusX = decoder0.decodeInt32(48); + } + if (mainDataHeader.version >= 0) { + result.bottomRightRadiusY = decoder0.decodeInt32(52); + } + return result; + } + + void encode(bindings.Encoder encoder) { + var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); + + encoder0.encodeInt32(x, 8); + + encoder0.encodeInt32(y, 12); + + encoder0.encodeInt32(width, 16); + + encoder0.encodeInt32(height, 20); + + encoder0.encodeInt32(topLeftRadiusX, 24); + + encoder0.encodeInt32(topLeftRadiusY, 28); + + encoder0.encodeInt32(topRightRadiusX, 32); + + encoder0.encodeInt32(topRightRadiusY, 36); + + encoder0.encodeInt32(bottomLeftRadiusX, 40); + + encoder0.encodeInt32(bottomLeftRadiusY, 44); + + encoder0.encodeInt32(bottomRightRadiusX, 48); + + encoder0.encodeInt32(bottomRightRadiusY, 52); + } + + String toString() { + return "RRect(" + "x: $x" + ", " + "y: $y" + ", " + "width: $width" + ", " + "height: $height" + ", " + "topLeftRadiusX: $topLeftRadiusX" + ", " + "topLeftRadiusY: $topLeftRadiusY" + ", " + "topRightRadiusX: $topRightRadiusX" + ", " + "topRightRadiusY: $topRightRadiusY" + ", " + "bottomLeftRadiusX: $bottomLeftRadiusX" + ", " + "bottomLeftRadiusY: $bottomLeftRadiusY" + ", " + "bottomRightRadiusX: $bottomRightRadiusX" + ", " + "bottomRightRadiusY: $bottomRightRadiusY" + ")"; + } + + Map toJson() { + Map map = new Map(); + map["x"] = x; + map["y"] = y; + map["width"] = width; + map["height"] = height; + map["topLeftRadiusX"] = topLeftRadiusX; + map["topLeftRadiusY"] = topLeftRadiusY; + map["topRightRadiusX"] = topRightRadiusX; + map["topRightRadiusY"] = topRightRadiusY; + map["bottomLeftRadiusX"] = bottomLeftRadiusX; + map["bottomLeftRadiusY"] = bottomLeftRadiusY; + map["bottomRightRadiusX"] = bottomRightRadiusX; + map["bottomRightRadiusY"] = bottomRightRadiusY; + return map; + } +} class Transform extends bindings.Struct { static const List<bindings.StructDataHeader> kVersions = const [ @@ -465,25 +623,26 @@ } } else if (mainDataHeader.size < kVersions.last.size) { throw new bindings.MojoCodecError( - 'Message newer than the last known version cannot be shorter than ' - 'required by the last known version.'); + 'Message newer than the last known version cannot be shorter than ' + 'required by the last known version.'); } if (mainDataHeader.version >= 0) { - - result.matrix = decoder0.decodeFloatArray(8, bindings.kNothingNullable, 16); + result.matrix = + decoder0.decodeFloatArray(8, bindings.kNothingNullable, 16); } return result; } void encode(bindings.Encoder encoder) { var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last); - + encoder0.encodeFloatArray(matrix, 8, bindings.kNothingNullable, 16); } String toString() { return "Transform(" - "matrix: $matrix" ")"; + "matrix: $matrix" + ")"; } Map toJson() { @@ -492,5 +651,3 @@ return map; } } - -
diff --git a/mojo/services/geometry/cpp/BUILD.gn b/mojo/services/geometry/cpp/BUILD.gn index 2a42aa0..9225ce4 100644 --- a/mojo/services/geometry/cpp/BUILD.gn +++ b/mojo/services/geometry/cpp/BUILD.gn
@@ -9,6 +9,9 @@ restrict_external_deps = false public_configs = [ "../../public/build/config:mojo_services" ] sources = [ + "formatting.cc", + "formatting.h", + "geometry_util.cc", "geometry_util.h", ]
diff --git a/mojo/services/geometry/cpp/formatting.cc b/mojo/services/geometry/cpp/formatting.cc new file mode 100644 index 0000000..76162d7 --- /dev/null +++ b/mojo/services/geometry/cpp/formatting.cc
@@ -0,0 +1,58 @@ +// Copyright 2015 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. + +#include "mojo/services/geometry/cpp/formatting.h" + +#include <ostream> + +namespace mojo { + +std::ostream& operator<<(std::ostream& os, const mojo::Point& value) { + return os << "{x=" << value.x << ", y=" << value.y << "}"; +} + +std::ostream& operator<<(std::ostream& os, const mojo::Size& value) { + return os << "{width=" << value.width << ", height=" << value.height << "}"; +} + +std::ostream& operator<<(std::ostream& os, const mojo::Rect& value) { + return os << "{x=" << value.x << ", y=" << value.y + << ", width=" << value.width << ", height=" << value.height << "}"; +} + +std::ostream& operator<<(std::ostream& os, const mojo::RRect& value) { + return os << "{x=" << value.x << ", y=" << value.y + << ", width=" << value.width << ", height=" << value.height + << ", top_left_radius_x=" << value.top_left_radius_x + << ", top_left_radius_y=" << value.top_left_radius_y + << ", top_right_radius_x=" << value.top_right_radius_x + << ", top_right_radius_y=" << value.top_right_radius_y + << ", bottom_left_radius_x=" << value.bottom_left_radius_x + << ", bottom_left_radius_y=" << value.bottom_left_radius_y + << ", bottom_right_radius_x=" << value.bottom_right_radius_x + << ", bottom_right_radius_y=" << value.bottom_right_radius_y << "}"; +} + +std::ostream& operator<<(std::ostream& os, const mojo::Transform& value) { + if (value.matrix) { + os << "["; + for (size_t i = 0; i < 4; i++) { + if (i != 0) + os << ", "; + os << "["; + for (size_t j = 0; j < 4; j++) { + if (j != 0) + os << ", "; + os << value.matrix[i * 4 + j]; + } + os << "]"; + } + os << "]"; + } else { + os << "null"; + } + return os; +} + +} // namespace mojo
diff --git a/mojo/services/geometry/cpp/formatting.h b/mojo/services/geometry/cpp/formatting.h new file mode 100644 index 0000000..0942f2f --- /dev/null +++ b/mojo/services/geometry/cpp/formatting.h
@@ -0,0 +1,21 @@ +// Copyright 2015 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 MOJO_SERVICES_GEOMETRY_CPP_FORMATTING_H_ +#define MOJO_SERVICES_GEOMETRY_CPP_FORMATTING_H_ + +#include "mojo/public/cpp/bindings/formatting.h" +#include "mojo/services/geometry/interfaces/geometry.mojom.h" + +namespace mojo { + +std::ostream& operator<<(std::ostream& os, const mojo::Point& value); +std::ostream& operator<<(std::ostream& os, const mojo::Size& value); +std::ostream& operator<<(std::ostream& os, const mojo::Rect& value); +std::ostream& operator<<(std::ostream& os, const mojo::RRect& value); +std::ostream& operator<<(std::ostream& os, const mojo::Transform& value); + +} // namespace mojo + +#endif // MOJO_SERVICES_GEOMETRY_CPP_FORMATTING_H_
diff --git a/mojo/services/geometry/cpp/geometry_util.cc b/mojo/services/geometry/cpp/geometry_util.cc new file mode 100644 index 0000000..570f707 --- /dev/null +++ b/mojo/services/geometry/cpp/geometry_util.cc
@@ -0,0 +1,29 @@ +// Copyright 2014 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. + +#include "mojo/services/geometry/cpp/geometry_util.h" + +#include <string.h> + +namespace mojo { + +static const float kIdentityMatrix[]{ + 1.f, 0.f, 0.f, 0.f, // comments to prevent + 0.f, 1.f, 0.f, 0.f, // auto formatter reflow + 0.f, 0.f, 1.f, 0.f, // + 0.f, 0.f, 0.f, 1.f}; + +void SetIdentityTransform(Transform* transform) { + transform->matrix.resize(16u); + memcpy(transform->matrix.data(), kIdentityMatrix, sizeof(kIdentityMatrix)); +} + +void SetTranslationTransform(Transform* transform, float x, float y, float z) { + SetIdentityTransform(transform); + transform->matrix[3] = x; + transform->matrix[7] = y; + transform->matrix[11] = z; +} + +} // namespace mojo
diff --git a/mojo/services/geometry/cpp/geometry_util.h b/mojo/services/geometry/cpp/geometry_util.h index 3d4d35e..97271c9 100644 --- a/mojo/services/geometry/cpp/geometry_util.h +++ b/mojo/services/geometry/cpp/geometry_util.h
@@ -5,7 +5,7 @@ #ifndef MOJO_SERVICES_GEOMETRY_CPP_GEOMETRY_UTIL_H_ #define MOJO_SERVICES_GEOMETRY_CPP_GEOMETRY_UTIL_H_ -#include "geometry/interfaces/geometry.mojom.h" +#include "mojo/services/geometry/interfaces/geometry.mojom.h" namespace mojo { @@ -34,6 +34,9 @@ return !(lhs == rhs); } +void SetIdentityTransform(Transform* transform); +void SetTranslationTransform(Transform* transform, float x, float y, float z); + } // namespace mojo #endif // MOJO_SERVICES_GEOMETRY_CPP_GEOMETRY_UTIL_H_
diff --git a/mojo/services/geometry/interfaces/geometry.mojom b/mojo/services/geometry/interfaces/geometry.mojom index a6d2d4e..1f882b6 100644 --- a/mojo/services/geometry/interfaces/geometry.mojom +++ b/mojo/services/geometry/interfaces/geometry.mojom
@@ -34,6 +34,21 @@ float height; }; +struct RRect { + int32 x; + int32 y; + int32 width; + int32 height; + int32 top_left_radius_x; + int32 top_left_radius_y; + int32 top_right_radius_x; + int32 top_right_radius_y; + int32 bottom_left_radius_x; + int32 bottom_left_radius_y; + int32 bottom_right_radius_x; + int32 bottom_right_radius_y; +}; + struct Transform { // Row major order. array<float, 16> matrix;