1487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk/* 2487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Copyright (C) 2015 The Android Open Source Project 3487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * 4487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Licensed under the Apache License, Version 2.0 (the "License"); 5487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * you may not use this file except in compliance with the License. 6487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * You may obtain a copy of the License at 7487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * 8487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * http://www.apache.org/licenses/LICENSE-2.0 9487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * 10487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Unless required by applicable law or agreed to in writing, software 11487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * distributed under the License is distributed on an "AS IS" BASIS, 12487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * See the License for the specific language governing permissions and 14487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * limitations under the License. 15487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk */ 16487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 17487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include <gtest/gtest.h> 18487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include <SkPath.h> 19487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include <SkRegion.h> 20487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 21487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "ClipArea.h" 22487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 23487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "Matrix.h" 24487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "Rect.h" 25487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "utils/LinearAllocator.h" 26487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 27487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuknamespace android { 28487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuknamespace uirenderer { 29487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 3069aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craikstatic Rect kViewportBounds(2048, 2048); 31487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 32487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukstatic ClipArea createClipArea() { 33487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk ClipArea area; 34487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk area.setViewportDimensions(kViewportBounds.getWidth(), kViewportBounds.getHeight()); 35487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return area; 36487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 37487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 38487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukTEST(TransformedRectangle, basics) { 39487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect r(0, 0, 100, 100); 40487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 minus90; 41487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk minus90.loadRotate(-90); 42487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk minus90.mapRect(r); 43487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect r2(20, 40, 120, 60); 44487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 45487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 m90; 46487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk m90.loadRotate(90); 47487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk TransformedRectangle tr(r, m90); 48487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_TRUE(tr.canSimplyIntersectWith(tr)); 49487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 50487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 m0; 51487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk TransformedRectangle tr0(r2, m0); 52487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(tr.canSimplyIntersectWith(tr0)); 53487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 54487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 m45; 55487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk m45.loadRotate(45); 56487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk TransformedRectangle tr2(r, m45); 57487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(tr2.canSimplyIntersectWith(tr)); 58487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 59487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 60487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukTEST(RectangleList, basics) { 61487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk RectangleList list; 62487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_TRUE(list.isEmpty()); 63487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 64487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect r(0, 0, 100, 100); 65487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 m45; 66487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk m45.loadRotate(45); 67487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk list.set(r, m45); 68487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(list.isEmpty()); 69487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 70487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect r2(20, 20, 200, 200); 71487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk list.intersectWith(r2, m45); 72487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(list.isEmpty()); 73487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_EQ(1, list.getTransformedRectanglesCount()); 74487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 75487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect r3(20, 20, 200, 200); 76487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Matrix4 m30; 77487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk m30.loadRotate(30); 78487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk list.intersectWith(r2, m30); 79487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(list.isEmpty()); 80487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_EQ(2, list.getTransformedRectanglesCount()); 81487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 82487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion clip; 83487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk clip.setRect(0, 0, 2000, 2000); 84487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion rgn(list.convertToRegion(clip)); 85487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(rgn.isEmpty()); 86487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 87487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 88487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukTEST(ClipArea, basics) { 89487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk ClipArea area(createClipArea()); 90487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(area.isEmpty()); 91487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 92487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 93487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukTEST(ClipArea, paths) { 94487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk ClipArea area(createClipArea()); 95487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkPath path; 96487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkScalar r = 100; 97487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk path.addCircle(r, r, r); 98386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik area.clipPathWithTransform(path, &Matrix4::identity(), SkRegion::kIntersect_Op); 99487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(area.isEmpty()); 100487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(area.isSimple()); 101487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_FALSE(area.isRectangleList()); 102b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 103487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect clipRect(area.getClipRect()); 104487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect expected(0, 0, r * 2, r * 2); 105487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_EQ(expected, clipRect); 106487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion clipRegion(area.getClipRegion()); 107487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk auto skRect(clipRegion.getBounds()); 108487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect regionBounds; 109487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk regionBounds.set(skRect); 110487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk EXPECT_EQ(expected, regionBounds); 111487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 1128ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik 1138ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris CraikTEST(ClipArea, replaceNegative) { 1148ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik ClipArea area(createClipArea()); 1158ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik area.setClip(0, 0, 100, 100); 1168ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik 1178ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik Rect expected(-50, -50, 50, 50); 118386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik area.clipRectWithTransform(expected, &Matrix4::identity(), SkRegion::kReplace_Op); 1198ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik EXPECT_EQ(expected, area.getClipRect()); 1208ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik} 121386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 122e4db79de127cfe961195f52907af8451026eaa20Chris CraikTEST(ClipArea, serializeClip) { 123e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipArea area(createClipArea()); 124e4db79de127cfe961195f52907af8451026eaa20Chris Craik LinearAllocator allocator; 125e4db79de127cfe961195f52907af8451026eaa20Chris Craik 126e4db79de127cfe961195f52907af8451026eaa20Chris Craik // unset clip 127e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, area.serializeClip(allocator)); 128e4db79de127cfe961195f52907af8451026eaa20Chris Craik 129e4db79de127cfe961195f52907af8451026eaa20Chris Craik // rect clip 130e4db79de127cfe961195f52907af8451026eaa20Chris Craik area.setClip(0, 0, 200, 200); 131e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 132e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto serializedClip = area.serializeClip(allocator); 133e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, serializedClip); 134e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode); 135bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; 13604d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik EXPECT_EQ(Rect(200, 200), serializedClip->rect); 137e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(serializedClip, area.serializeClip(allocator)) 138e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Requery of clip on unmodified ClipArea must return same pointer."; 139e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 140e4db79de127cfe961195f52907af8451026eaa20Chris Craik 141e4db79de127cfe961195f52907af8451026eaa20Chris Craik // rect list 142e4db79de127cfe961195f52907af8451026eaa20Chris Craik Matrix4 rotate; 14369aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik rotate.loadRotate(5.0f); 14469aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik area.clipRectWithTransform(Rect(50, 50, 150, 150), &rotate, SkRegion::kIntersect_Op); 145e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 146e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto serializedClip = area.serializeClip(allocator); 147e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, serializedClip); 148e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::RectangleList, serializedClip->mode); 149bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; 150e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto clipRectList = reinterpret_cast<const ClipRectList*>(serializedClip); 151b4f4f3e16d8fbb2905dfc168383213161e988f83Chris Craik EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount()); 15269aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik EXPECT_EQ(Rect(37, 54, 145, 163), clipRectList->rect); 153e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(serializedClip, area.serializeClip(allocator)) 154e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Requery of clip on unmodified ClipArea must return same pointer."; 155e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 156e4db79de127cfe961195f52907af8451026eaa20Chris Craik 157e4db79de127cfe961195f52907af8451026eaa20Chris Craik // region 158e4db79de127cfe961195f52907af8451026eaa20Chris Craik SkPath circlePath; 159e4db79de127cfe961195f52907af8451026eaa20Chris Craik circlePath.addCircle(100, 100, 100); 160e4db79de127cfe961195f52907af8451026eaa20Chris Craik area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kReplace_Op); 161e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 162e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto serializedClip = area.serializeClip(allocator); 163e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, serializedClip); 164e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::Region, serializedClip->mode); 165bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik ASSERT_TRUE(serializedClip->intersectWithRoot) << "Replace op, so expect intersectWithRoot"; 166e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto clipRegion = reinterpret_cast<const ClipRegion*>(serializedClip); 167b4f4f3e16d8fbb2905dfc168383213161e988f83Chris Craik EXPECT_EQ(SkIRect::MakeWH(200, 200), clipRegion->region.getBounds()) 168e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Clip region should be 200x200"; 169b4f4f3e16d8fbb2905dfc168383213161e988f83Chris Craik EXPECT_EQ(Rect(200, 200), clipRegion->rect); 170e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(serializedClip, area.serializeClip(allocator)) 171e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Requery of clip on unmodified ClipArea must return same pointer."; 172e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 173487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 174e4db79de127cfe961195f52907af8451026eaa20Chris Craik 175bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris CraikTEST(ClipArea, serializeClip_pathIntersectWithRoot) { 176bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik ClipArea area(createClipArea()); 177bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik LinearAllocator allocator; 178bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik SkPath circlePath; 179bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik circlePath.addCircle(100, 100, 100); 180bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kIntersect_Op); 181bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik 182bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik auto serializedClip = area.serializeClip(allocator); 183bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik ASSERT_NE(nullptr, serializedClip); 184bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik EXPECT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot"; 185bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik} 186bf27b995ae1bc36ee0b24effcaf41ec477e7fae3Chris Craik 187e4db79de127cfe961195f52907af8451026eaa20Chris CraikTEST(ClipArea, serializeIntersectedClip) { 188e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipArea area(createClipArea()); 189e4db79de127cfe961195f52907af8451026eaa20Chris Craik LinearAllocator allocator; 190e4db79de127cfe961195f52907af8451026eaa20Chris Craik 191e4db79de127cfe961195f52907af8451026eaa20Chris Craik // simple state; 192e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(nullptr, area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity())); 193e4db79de127cfe961195f52907af8451026eaa20Chris Craik area.setClip(0, 0, 200, 200); 194e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 195e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto origRectClip = area.serializeClip(allocator); 196e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, origRectClip); 197e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(origRectClip, area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity())); 198e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 199e4db79de127cfe961195f52907af8451026eaa20Chris Craik 200e4db79de127cfe961195f52907af8451026eaa20Chris Craik // rect 201e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 202e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipRect recordedClip(Rect(100, 100)); 203e4db79de127cfe961195f52907af8451026eaa20Chris Craik Matrix4 translateScale; 204e4db79de127cfe961195f52907af8451026eaa20Chris Craik translateScale.loadTranslate(100, 100, 0); 205e4db79de127cfe961195f52907af8451026eaa20Chris Craik translateScale.scale(2, 3, 1); 206e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale); 207e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, resolvedClip); 208e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::Rectangle, resolvedClip->mode); 20904d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik EXPECT_EQ(Rect(100, 100, 200, 200), resolvedClip->rect); 210e4db79de127cfe961195f52907af8451026eaa20Chris Craik 211e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(resolvedClip, area.serializeIntersectedClip(allocator, &recordedClip, translateScale)) 212e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Must return previous serialization, since input is same"; 213e4db79de127cfe961195f52907af8451026eaa20Chris Craik 214e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipRect recordedClip2(Rect(100, 100)); 215e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_NE(resolvedClip, area.serializeIntersectedClip(allocator, &recordedClip2, translateScale)) 216e4db79de127cfe961195f52907af8451026eaa20Chris Craik << "Shouldn't return previous serialization, since matrix location is different"; 217e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 218e4db79de127cfe961195f52907af8451026eaa20Chris Craik 219e4db79de127cfe961195f52907af8451026eaa20Chris Craik // rect list 220e4db79de127cfe961195f52907af8451026eaa20Chris Craik Matrix4 rotate; 221e4db79de127cfe961195f52907af8451026eaa20Chris Craik rotate.loadRotate(2.0f); 222e4db79de127cfe961195f52907af8451026eaa20Chris Craik area.clipRectWithTransform(Rect(200, 200), &rotate, SkRegion::kIntersect_Op); 223e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 224e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipRect recordedClip(Rect(100, 100)); 225e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, Matrix4::identity()); 226e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, resolvedClip); 227e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::RectangleList, resolvedClip->mode); 228e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto clipRectList = reinterpret_cast<const ClipRectList*>(resolvedClip); 229e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount()); 230e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 231e4db79de127cfe961195f52907af8451026eaa20Chris Craik 232e4db79de127cfe961195f52907af8451026eaa20Chris Craik // region 233e4db79de127cfe961195f52907af8451026eaa20Chris Craik SkPath circlePath; 234e4db79de127cfe961195f52907af8451026eaa20Chris Craik circlePath.addCircle(100, 100, 100); 235e4db79de127cfe961195f52907af8451026eaa20Chris Craik area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kReplace_Op); 236e4db79de127cfe961195f52907af8451026eaa20Chris Craik { 237e4db79de127cfe961195f52907af8451026eaa20Chris Craik SkPath ovalPath; 238e4db79de127cfe961195f52907af8451026eaa20Chris Craik ovalPath.addOval(SkRect::MakeLTRB(50, 0, 150, 200)); 239e4db79de127cfe961195f52907af8451026eaa20Chris Craik 240e4db79de127cfe961195f52907af8451026eaa20Chris Craik ClipRegion recordedClip; 241e4db79de127cfe961195f52907af8451026eaa20Chris Craik recordedClip.region.setPath(ovalPath, SkRegion(SkIRect::MakeWH(200, 200))); 242261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik recordedClip.rect = Rect(200, 200); 243e4db79de127cfe961195f52907af8451026eaa20Chris Craik 244e4db79de127cfe961195f52907af8451026eaa20Chris Craik Matrix4 translate10x20; 245e4db79de127cfe961195f52907af8451026eaa20Chris Craik translate10x20.loadTranslate(10, 20, 0); 246e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, 247e4db79de127cfe961195f52907af8451026eaa20Chris Craik translate10x20); // Note: only translate for now, others not handled correctly 248e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_NE(nullptr, resolvedClip); 249e4db79de127cfe961195f52907af8451026eaa20Chris Craik ASSERT_EQ(ClipMode::Region, resolvedClip->mode); 250e4db79de127cfe961195f52907af8451026eaa20Chris Craik auto clipRegion = reinterpret_cast<const ClipRegion*>(resolvedClip); 251e4db79de127cfe961195f52907af8451026eaa20Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(60, 20, 160, 200), clipRegion->region.getBounds()); 252e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 253487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} 254e4db79de127cfe961195f52907af8451026eaa20Chris Craik 25569aeabe6184bbbe6e731656205ffbef78b7b0f3fChris CraikTEST(ClipArea, serializeIntersectedClip_snap) { 25669aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik ClipArea area(createClipArea()); 25769aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik area.setClip(100.2, 100.4, 500.6, 500.8); 25869aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik LinearAllocator allocator; 25969aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik 26069aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik { 26169aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik // no recorded clip case 26269aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity()); 26369aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik EXPECT_EQ(Rect(100, 100, 501, 501), resolvedClip->rect); 26469aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik } 26569aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik { 26669aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik // recorded clip case 26769aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik ClipRect recordedClip(Rect(100.12, 100.74)); 26869aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik Matrix4 translateScale; 26969aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik translateScale.loadTranslate(100, 100, 0); 27069aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik translateScale.scale(2, 3, 1); // recorded clip will have non-int coords, even after transform 27169aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale); 27269aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik ASSERT_NE(nullptr, resolvedClip); 27369aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik EXPECT_EQ(ClipMode::Rectangle, resolvedClip->mode); 27469aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik EXPECT_EQ(Rect(100, 100, 300, 402), resolvedClip->rect); 27569aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik } 27669aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik} 27769aeabe6184bbbe6e731656205ffbef78b7b0f3fChris Craik 27882457c51176855b9be0b441010870093a6feb414Chris CraikTEST(ClipArea, serializeIntersectedClip_scale) { 27982457c51176855b9be0b441010870093a6feb414Chris Craik ClipArea area(createClipArea()); 28082457c51176855b9be0b441010870093a6feb414Chris Craik area.setClip(0, 0, 400, 400); 28182457c51176855b9be0b441010870093a6feb414Chris Craik LinearAllocator allocator; 28282457c51176855b9be0b441010870093a6feb414Chris Craik 28382457c51176855b9be0b441010870093a6feb414Chris Craik SkPath circlePath; 28482457c51176855b9be0b441010870093a6feb414Chris Craik circlePath.addCircle(50, 50, 50); 28582457c51176855b9be0b441010870093a6feb414Chris Craik 28682457c51176855b9be0b441010870093a6feb414Chris Craik ClipRegion recordedClip; 28782457c51176855b9be0b441010870093a6feb414Chris Craik recordedClip.region.setPath(circlePath, SkRegion(SkIRect::MakeWH(100, 100))); 28882457c51176855b9be0b441010870093a6feb414Chris Craik recordedClip.rect = Rect(100, 100); 28982457c51176855b9be0b441010870093a6feb414Chris Craik 29082457c51176855b9be0b441010870093a6feb414Chris Craik Matrix4 translateScale; 29182457c51176855b9be0b441010870093a6feb414Chris Craik translateScale.loadTranslate(100, 100, 0); 29282457c51176855b9be0b441010870093a6feb414Chris Craik translateScale.scale(2, 2, 1); 29382457c51176855b9be0b441010870093a6feb414Chris Craik auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale); 29482457c51176855b9be0b441010870093a6feb414Chris Craik 29582457c51176855b9be0b441010870093a6feb414Chris Craik ASSERT_NE(nullptr, resolvedClip); 29682457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(ClipMode::Region, resolvedClip->mode); 29782457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(Rect(100, 100, 300, 300), resolvedClip->rect); 29882457c51176855b9be0b441010870093a6feb414Chris Craik auto clipRegion = reinterpret_cast<const ClipRegion*>(resolvedClip); 29982457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(100, 100, 300, 300), clipRegion->region.getBounds()); 30082457c51176855b9be0b441010870093a6feb414Chris Craik} 30182457c51176855b9be0b441010870093a6feb414Chris Craik 30282457c51176855b9be0b441010870093a6feb414Chris CraikTEST(ClipArea, applyTransformToRegion_identity) { 30382457c51176855b9be0b441010870093a6feb414Chris Craik SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4)); 30482457c51176855b9be0b441010870093a6feb414Chris Craik ClipArea::applyTransformToRegion(Matrix4::identity(), ®ion); 30582457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_TRUE(region.isRect()); 30682457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(1, 2, 3, 4), region.getBounds()); 30782457c51176855b9be0b441010870093a6feb414Chris Craik} 30882457c51176855b9be0b441010870093a6feb414Chris Craik 30982457c51176855b9be0b441010870093a6feb414Chris CraikTEST(ClipArea, applyTransformToRegion_translate) { 31082457c51176855b9be0b441010870093a6feb414Chris Craik SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4)); 31182457c51176855b9be0b441010870093a6feb414Chris Craik Matrix4 transform; 31282457c51176855b9be0b441010870093a6feb414Chris Craik transform.loadTranslate(10, 20, 0); 31382457c51176855b9be0b441010870093a6feb414Chris Craik ClipArea::applyTransformToRegion(transform, ®ion); 31482457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_TRUE(region.isRect()); 31582457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(11, 22, 13, 24), region.getBounds()); 31682457c51176855b9be0b441010870093a6feb414Chris Craik} 31782457c51176855b9be0b441010870093a6feb414Chris Craik 31882457c51176855b9be0b441010870093a6feb414Chris CraikTEST(ClipArea, applyTransformToRegion_scale) { 31982457c51176855b9be0b441010870093a6feb414Chris Craik SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4)); 32082457c51176855b9be0b441010870093a6feb414Chris Craik Matrix4 transform; 32182457c51176855b9be0b441010870093a6feb414Chris Craik transform.loadScale(2, 3, 1); 32282457c51176855b9be0b441010870093a6feb414Chris Craik ClipArea::applyTransformToRegion(transform, ®ion); 32382457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_TRUE(region.isRect()); 32482457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(2, 6, 6, 12), region.getBounds()); 32582457c51176855b9be0b441010870093a6feb414Chris Craik} 32682457c51176855b9be0b441010870093a6feb414Chris Craik 32782457c51176855b9be0b441010870093a6feb414Chris CraikTEST(ClipArea, applyTransformToRegion_translateScale) { 32882457c51176855b9be0b441010870093a6feb414Chris Craik SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4)); 32982457c51176855b9be0b441010870093a6feb414Chris Craik Matrix4 transform; 33082457c51176855b9be0b441010870093a6feb414Chris Craik transform.translate(10, 20); 33182457c51176855b9be0b441010870093a6feb414Chris Craik transform.scale(2, 3, 1); 33282457c51176855b9be0b441010870093a6feb414Chris Craik ClipArea::applyTransformToRegion(transform, ®ion); 33382457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_TRUE(region.isRect()); 33482457c51176855b9be0b441010870093a6feb414Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(12, 26, 16, 32), region.getBounds()); 33582457c51176855b9be0b441010870093a6feb414Chris Craik} 33682457c51176855b9be0b441010870093a6feb414Chris Craik 3370658435096a26067c0183e0a977c9ae0af1cc006Chris CraikTEST(ClipArea, applyTransformToRegion_rotate90) { 3380658435096a26067c0183e0a977c9ae0af1cc006Chris Craik SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4)); 3390658435096a26067c0183e0a977c9ae0af1cc006Chris Craik Matrix4 transform; 3400658435096a26067c0183e0a977c9ae0af1cc006Chris Craik transform.loadRotate(90); 3410658435096a26067c0183e0a977c9ae0af1cc006Chris Craik ClipArea::applyTransformToRegion(transform, ®ion); 3420658435096a26067c0183e0a977c9ae0af1cc006Chris Craik EXPECT_TRUE(region.isRect()); 3430658435096a26067c0183e0a977c9ae0af1cc006Chris Craik EXPECT_EQ(SkIRect::MakeLTRB(-4, 1, -2, 3), region.getBounds()); 3440658435096a26067c0183e0a977c9ae0af1cc006Chris Craik} 3450658435096a26067c0183e0a977c9ae0af1cc006Chris Craik 346e4db79de127cfe961195f52907af8451026eaa20Chris Craik} // namespace uirenderer 347e4db79de127cfe961195f52907af8451026eaa20Chris Craik} // namespace android 348