// Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_ #include #include "flutter/fml/logging.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/embedder_engine.h" #include "flutter/testing/assertions.h" #include "gtest/gtest.h" #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkSize.h" //------------------------------------------------------------------------------ // Equality //------------------------------------------------------------------------------ inline bool operator==(const FlutterPoint& a, const FlutterPoint& b) { return flutter::testing::NumberNear(a.x, b.x) && flutter::testing::NumberNear(a.y, b.y); } inline bool operator==(const FlutterRect& a, const FlutterRect& b) { return flutter::testing::NumberNear(a.left, b.left) && flutter::testing::NumberNear(a.top, b.top) && flutter::testing::NumberNear(a.right, b.right) && flutter::testing::NumberNear(a.bottom, b.bottom); } inline bool operator==(const FlutterSize& a, const FlutterSize& b) { return flutter::testing::NumberNear(a.width, b.width) && flutter::testing::NumberNear(a.height, b.height); } inline bool operator==(const FlutterRoundedRect& a, const FlutterRoundedRect& b) { return a.rect == b.rect && a.upper_left_corner_radius == b.upper_left_corner_radius && a.upper_right_corner_radius == b.upper_right_corner_radius && a.lower_right_corner_radius == b.lower_right_corner_radius && a.lower_left_corner_radius == b.lower_left_corner_radius; } inline bool operator==(const FlutterTransformation& a, const FlutterTransformation& b) { return a.scaleX == b.scaleX && a.skewX == b.skewX && a.transX == b.transX && a.skewY == b.skewY && a.scaleY == b.scaleY && a.transY == b.transY && a.pers0 == b.pers0 && a.pers1 == b.pers1 && a.pers2 == b.pers2; } inline bool operator==(const FlutterOpenGLTexture& a, const FlutterOpenGLTexture& b) { return a.target == b.target && a.name == b.name && a.format == b.format && a.user_data == b.user_data && a.destruction_callback == b.destruction_callback; } inline bool operator==(const FlutterOpenGLFramebuffer& a, const FlutterOpenGLFramebuffer& b) { return a.target == b.target && a.name == b.name && a.user_data == b.user_data && a.destruction_callback == b.destruction_callback; } inline bool operator==(const FlutterOpenGLBackingStore& a, const FlutterOpenGLBackingStore& b) { if (!(a.type == b.type)) { return false; } switch (a.type) { case kFlutterOpenGLTargetTypeTexture: return a.texture == b.texture; case kFlutterOpenGLTargetTypeFramebuffer: return a.framebuffer == b.framebuffer; } return false; } inline bool operator==(const FlutterSoftwareBackingStore& a, const FlutterSoftwareBackingStore& b) { return a.allocation == b.allocation && a.row_bytes == b.row_bytes && a.height == b.height && a.user_data == b.user_data && a.destruction_callback == b.destruction_callback; } inline bool operator==(const FlutterBackingStore& a, const FlutterBackingStore& b) { if (!(a.struct_size == b.struct_size && a.user_data == b.user_data && a.type == b.type && a.did_update == b.did_update)) { return false; } switch (a.type) { case kFlutterBackingStoreTypeOpenGL: return a.open_gl == b.open_gl; case kFlutterBackingStoreTypeSoftware: return a.software == b.software; } return false; } inline bool operator==(const FlutterPlatformViewMutation& a, const FlutterPlatformViewMutation& b) { if (a.type != b.type) { return false; } switch (a.type) { case kFlutterPlatformViewMutationTypeOpacity: return flutter::testing::NumberNear(a.opacity, b.opacity); case kFlutterPlatformViewMutationTypeClipRect: return a.clip_rect == b.clip_rect; case kFlutterPlatformViewMutationTypeClipRoundedRect: return a.clip_rounded_rect == b.clip_rounded_rect; case kFlutterPlatformViewMutationTypeTransformation: return a.transformation == b.transformation; } return false; } inline bool operator==(const FlutterPlatformView& a, const FlutterPlatformView& b) { if (!(a.struct_size == b.struct_size && a.identifier == b.identifier && a.mutations_count == b.mutations_count)) { return false; } for (size_t i = 0; i < a.mutations_count; ++i) { if (!(*a.mutations[i] == *b.mutations[i])) { return false; } } return true; } inline bool operator==(const FlutterLayer& a, const FlutterLayer& b) { if (!(a.struct_size == b.struct_size && a.type == b.type && a.offset == b.offset && a.size == b.size)) { return false; } switch (a.type) { case kFlutterLayerContentTypeBackingStore: return *a.backing_store == *b.backing_store; case kFlutterLayerContentTypePlatformView: return *a.platform_view == *b.platform_view; } return false; } //------------------------------------------------------------------------------ // Printing //------------------------------------------------------------------------------ inline std::ostream& operator<<(std::ostream& out, const FlutterPoint& point) { return out << "(" << point.x << ", " << point.y << ")"; } inline std::ostream& operator<<(std::ostream& out, const FlutterRect& r) { return out << "LTRB (" << r.left << ", " << r.top << ", " << r.right << ", " << r.bottom << ")"; } inline std::ostream& operator<<(std::ostream& out, const FlutterSize& size) { return out << "(" << size.width << ", " << size.height << ")"; } inline std::ostream& operator<<(std::ostream& out, const FlutterRoundedRect& r) { out << "Rect: " << r.rect << ", "; out << "Upper Left Corner Radius: " << r.upper_left_corner_radius << ", "; out << "Upper Right Corner Radius: " << r.upper_right_corner_radius << ", "; out << "Lower Right Corner Radius: " << r.lower_right_corner_radius << ", "; out << "Lower Left Corner Radius: " << r.lower_left_corner_radius; return out; } inline std::ostream& operator<<(std::ostream& out, const FlutterTransformation& t) { out << "Scale X: " << t.scaleX << ", "; out << "Skew X: " << t.skewX << ", "; out << "Trans X: " << t.transX << ", "; out << "Skew Y: " << t.skewY << ", "; out << "Scale Y: " << t.scaleY << ", "; out << "Trans Y: " << t.transY << ", "; out << "Pers 0: " << t.pers0 << ", "; out << "Pers 1: " << t.pers1 << ", "; out << "Pers 2: " << t.pers2; return out; } inline std::string FlutterLayerContentTypeToString( FlutterLayerContentType type) { switch (type) { case kFlutterLayerContentTypeBackingStore: return "kFlutterLayerContentTypeBackingStore"; case kFlutterLayerContentTypePlatformView: return "kFlutterLayerContentTypePlatformView"; } return "Unknown"; } inline std::string FlutterBackingStoreTypeToString( FlutterBackingStoreType type) { switch (type) { case kFlutterBackingStoreTypeOpenGL: return "kFlutterBackingStoreTypeOpenGL"; case kFlutterBackingStoreTypeSoftware: return "kFlutterBackingStoreTypeSoftware"; } return "Unknown"; } inline std::ostream& operator<<(std::ostream& out, const FlutterOpenGLTexture& item) { return out << "(FlutterOpenGLTexture) Target: 0x" << std::hex << item.target << std::dec << " Name: " << item.name << " Format: " << item.format << " User Data: " << item.user_data << " Destruction Callback: " << reinterpret_cast(item.destruction_callback); } inline std::ostream& operator<<(std::ostream& out, const FlutterOpenGLFramebuffer& item) { return out << "(FlutterOpenGLFramebuffer) Target: 0x" << std::hex << item.target << std::dec << " Name: " << item.name << " User Data: " << item.user_data << " Destruction Callback: " << reinterpret_cast(item.destruction_callback); } inline std::string FlutterPlatformViewMutationTypeToString( FlutterPlatformViewMutationType type) { switch (type) { case kFlutterPlatformViewMutationTypeOpacity: return "kFlutterPlatformViewMutationTypeOpacity"; case kFlutterPlatformViewMutationTypeClipRect: return "kFlutterPlatformViewMutationTypeClipRect"; case kFlutterPlatformViewMutationTypeClipRoundedRect: return "kFlutterPlatformViewMutationTypeClipRoundedRect"; case kFlutterPlatformViewMutationTypeTransformation: return "kFlutterPlatformViewMutationTypeTransformation"; } return "Unknown"; } inline std::ostream& operator<<(std::ostream& out, const FlutterPlatformViewMutation& m) { out << "(FlutterPlatformViewMutation) Type: " << FlutterPlatformViewMutationTypeToString(m.type) << " "; switch (m.type) { case kFlutterPlatformViewMutationTypeOpacity: out << "Opacity: " << m.opacity; case kFlutterPlatformViewMutationTypeClipRect: out << "Clip Rect: " << m.clip_rect; case kFlutterPlatformViewMutationTypeClipRoundedRect: out << "Clip Rounded Rect: " << m.clip_rounded_rect; case kFlutterPlatformViewMutationTypeTransformation: out << "Transformation: " << m.transformation; } return out; } inline std::ostream& operator<<(std::ostream& out, const FlutterPlatformView& platform_view) { out << "[" << "(FlutterPlatformView) Struct Size: " << platform_view.struct_size << " Identifier: " << platform_view.identifier << " Mutations Count: " << platform_view.mutations_count; if (platform_view.mutations_count > 0) { out << std::endl; for (size_t i = 0; i < platform_view.mutations_count; i++) { out << "Mutation " << i << ": " << *platform_view.mutations[i] << std::endl; } } out << "]"; return out; } inline std::string FlutterOpenGLTargetTypeToString( FlutterOpenGLTargetType type) { switch (type) { case kFlutterOpenGLTargetTypeTexture: return "kFlutterOpenGLTargetTypeTexture"; case kFlutterOpenGLTargetTypeFramebuffer: return "kFlutterOpenGLTargetTypeFramebuffer"; } return "Unknown"; } inline std::ostream& operator<<(std::ostream& out, const FlutterOpenGLBackingStore& item) { out << "(FlutterOpenGLBackingStore) Type: " << FlutterOpenGLTargetTypeToString(item.type) << " "; switch (item.type) { case kFlutterOpenGLTargetTypeTexture: out << item.texture; break; case kFlutterOpenGLTargetTypeFramebuffer: out << item.framebuffer; break; } return out; } inline std::ostream& operator<<(std::ostream& out, const FlutterSoftwareBackingStore& item) { return out << "(FlutterSoftwareBackingStore) Allocation: " << item.allocation << " Row Bytes: " << item.row_bytes << " Height: " << item.height << " User Data: " << item.user_data << " Destruction Callback: " << reinterpret_cast(item.destruction_callback); } inline std::ostream& operator<<(std::ostream& out, const FlutterBackingStore& backing_store) { out << "(FlutterBackingStore) Struct size: " << backing_store.struct_size << " User Data: " << backing_store.user_data << " Type: " << FlutterBackingStoreTypeToString(backing_store.type) << " "; switch (backing_store.type) { case kFlutterBackingStoreTypeOpenGL: out << backing_store.open_gl; break; case kFlutterBackingStoreTypeSoftware: out << backing_store.software; break; } return out; } inline std::ostream& operator<<(std::ostream& out, const FlutterLayer& layer) { out << "(Flutter Layer) Struct size: " << layer.struct_size << " Type: " << FlutterLayerContentTypeToString(layer.type); switch (layer.type) { case kFlutterLayerContentTypeBackingStore: out << *layer.backing_store; break; case kFlutterLayerContentTypePlatformView: out << *layer.platform_view; break; } return out << " Offset: " << layer.offset << " Size: " << layer.size; } //------------------------------------------------------------------------------ // Factories and Casts //------------------------------------------------------------------------------ inline FlutterPoint FlutterPointMake(double x, double y) { FlutterPoint point = {}; point.x = x; point.y = y; return point; } inline FlutterSize FlutterSizeMake(double width, double height) { FlutterSize size = {}; size.width = width; size.height = height; return size; } inline FlutterSize FlutterSizeMake(const SkVector& vector) { FlutterSize size = {}; size.width = vector.x(); size.height = vector.y(); return size; } inline FlutterTransformation FlutterTransformationMake(const SkMatrix& matrix) { FlutterTransformation transformation = {}; transformation.scaleX = matrix[SkMatrix::kMScaleX]; transformation.skewX = matrix[SkMatrix::kMSkewX]; transformation.transX = matrix[SkMatrix::kMTransX]; transformation.skewY = matrix[SkMatrix::kMSkewY]; transformation.scaleY = matrix[SkMatrix::kMScaleY]; transformation.transY = matrix[SkMatrix::kMTransY]; transformation.pers0 = matrix[SkMatrix::kMPersp0]; transformation.pers1 = matrix[SkMatrix::kMPersp1]; transformation.pers2 = matrix[SkMatrix::kMPersp2]; return transformation; } inline SkMatrix SkMatrixMake(const FlutterTransformation& xformation) { return SkMatrix::MakeAll(xformation.scaleX, // xformation.skewX, // xformation.transX, // xformation.skewY, // xformation.scaleY, // xformation.transY, // xformation.pers0, // xformation.pers1, // xformation.pers2 // ); } inline flutter::EmbedderEngine* ToEmbedderEngine(const FlutterEngine& engine) { return reinterpret_cast(engine); } inline FlutterRect FlutterRectMake(const SkRect& rect) { FlutterRect r = {}; r.left = rect.left(); r.top = rect.top(); r.right = rect.right(); r.bottom = rect.bottom(); return r; } inline FlutterRect FlutterRectMakeLTRB(double l, double t, double r, double b) { FlutterRect rect = {}; rect.left = l; rect.top = t; rect.right = r; rect.bottom = b; return rect; } inline SkRect SkRectMake(const FlutterRect& rect) { return SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom); } inline FlutterRoundedRect FlutterRoundedRectMake(const SkRRect& rect) { FlutterRoundedRect r = {}; r.rect = FlutterRectMake(rect.rect()); r.upper_left_corner_radius = FlutterSizeMake(rect.radii(SkRRect::Corner::kUpperLeft_Corner)); r.upper_right_corner_radius = FlutterSizeMake(rect.radii(SkRRect::Corner::kUpperRight_Corner)); r.lower_right_corner_radius = FlutterSizeMake(rect.radii(SkRRect::Corner::kLowerRight_Corner)); r.lower_left_corner_radius = FlutterSizeMake(rect.radii(SkRRect::Corner::kLowerLeft_Corner)); return r; } #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_