Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the Layer::getLayersUnderPoint and Layer::hitTestPoint methods, and add related unit test cases. #282

Merged
merged 36 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
088552c
Implement the Layer::getLayersUnderPoint method to obtain all layers …
shlzxjp Oct 24, 2024
d3e706c
Added unit test case for Layer::getLayersUnderPoint method
shlzxjp Oct 24, 2024
2e4e717
Simplify the implementation of Layer::getLayersUnderPoint to make it …
shlzxjp Oct 25, 2024
453abd3
Implement a pixel-level accurate hitTest method.
shlzxjp Oct 28, 2024
baa2c42
Implement the Layer::getLayersUnderPoint method to obtain all layers …
shlzxjp Oct 24, 2024
bfbd536
Added unit test case for Layer::getLayersUnderPoint method
shlzxjp Oct 24, 2024
17f86db
Simplify the implementation of Layer::getLayersUnderPoint to make it …
shlzxjp Oct 25, 2024
2f75e5f
Implement a pixel-level accurate hitTest method.
shlzxjp Oct 28, 2024
35064d2
Merge branch 'feature/xjp_get_layers_under_point' of github.com:Tence…
shlzxjp Oct 28, 2024
1a8a7e0
Add Layer::getLayersUnderPoint and Layer::hitTestPoint test cases
shlzxjp Oct 28, 2024
7a7ad52
Fix the compilation issues caused by code formatting errors.
shlzxjp Oct 28, 2024
3e48b5c
Use codeformat.sh to format the code.
shlzxjp Oct 28, 2024
e122232
Fix the Path.cpp compilation issues caused by code formatting errors.
shlzxjp Oct 28, 2024
960cb38
Replace Layer::getBounds with LayerContent::getBounds.
shlzxjp Oct 29, 2024
8ad1d39
将Layer::hitTestByBounds和Layer::hitTestByPixel方法迁移到LayerContent上,并修改PR…
shlzxjp Oct 29, 2024
cd9e2d4
Add the judgment of ScrollRect and Mask in the Layer::getLayersUnderP…
shlzxjp Oct 29, 2024
60deac7
Merge branch 'main' into feature/xjp_get_layers_under_point
shlzxjp Oct 29, 2024
223a736
Modify the Layer::getLayersUnderPointInternal method to use the local…
shlzxjp Oct 30, 2024
9d767fa
Implement the hitTestPoint method for LayerContent and its subclasses…
shlzxjp Oct 31, 2024
a47a757
Merge branch 'main' into feature/xjp_get_layers_under_point
shlzxjp Oct 31, 2024
8f3182f
Add additional unit test cases for Layer::hitTestPoint.
shlzxjp Oct 31, 2024
ee1f27c
Fix compilation errors caused by code formatting issues
shlzxjp Oct 31, 2024
49fd59e
Remove -Wunused-parameter warning suppression.
shlzxjp Oct 31, 2024
b5e777b
Change the parameters of the Layer::getLayersUnderPoint and Layer::hi…
shlzxjp Oct 31, 2024
eb05993
Delete test cases and resolve conflicts.
shlzxjp Oct 31, 2024
d4f3fc8
Merge main branch code and resolve conflicts.
shlzxjp Oct 31, 2024
af4c70e
Optimize the implementation of pixel-precise hit testing in TextConte…
shlzxjp Oct 31, 2024
2b83b13
Merge branch 'main' into feature/xjp_get_layers_under_point
shlzxjp Oct 31, 2024
1172876
Merge branch 'main' into feature/xjp_get_layers_under_point
shlzxjp Oct 31, 2024
f717cd5
Format code and resolve pipeline code checking errors.
shlzxjp Oct 31, 2024
1c6e140
Rollback invalid configuration in misc.xml
shlzxjp Oct 31, 2024
48517c8
Modify code comments and optimize the performance of TextContent::hit…
shlzxjp Oct 31, 2024
d3663ad
Delete empty line breaks to resolve pipeline compilation check errors
shlzxjp Oct 31, 2024
9c84117
Update include/tgfx/core/TextBlob.h
domchen Oct 31, 2024
7f61ea0
Modify the internal implementation of TextContent::hitTestPointIntern…
shlzxjp Oct 31, 2024
6fb168f
Merge branch 'feature/xjp_get_layers_under_point' of github.com:Tence…
shlzxjp Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Layer::getLayersUnderPoint and Layer::hitTestPoint test cases
  • Loading branch information
shlzxjp committed Oct 28, 2024
commit 1a8a7e0b416751b8ea78fa8c68a09d643441cdb8
2 changes: 1 addition & 1 deletion include/tgfx/layers/ShapeLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class ShapeLayer : public Layer {
ShapeLayer() = default;

std::unique_ptr<LayerContent> onUpdateContent() override;
··

bool hitTestByPixel(float x, float y) override;

private:
Expand Down
166 changes: 166 additions & 0 deletions test/src/LayerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,4 +871,170 @@ TGFX_TEST(LayerTest, getLayersUnderPoint) {
Baseline::Compare(surface, "LayerTest/getLayersUnderPoint");
device->unlock();
}

/**
* The schematic diagram is as follows(Visit geogebra online vector map to view pixel details):
* https://www.geogebra.org/classic/krbzbz6m
* https://codesign-1252678369.cos.ap-guangzhou.myqcloud.com/hitTestPoint.png
* https://codesign-1252678369.cos.ap-guangzhou.myqcloud.com/Layer_hitTestPoint.png
*/
TGFX_TEST(LayerTest, hitTestPoint) {
auto device = DevicePool::Make();
ASSERT_TRUE(device != nullptr);
auto context = device->lockContext();
auto surface = Surface::Make(context, 800, 800);
auto canvas = surface->getCanvas();
auto displayList = std::make_unique<DisplayList>();

auto rootLayer = Layer::Make();
rootLayer->setName("root_layer");
displayList->root()->addChild(rootLayer);

auto shaperLayer1 = ShapeLayer::Make();
shaperLayer1->setName("shaper_layer1");
Path path1 = {};
path1.moveTo(100, 50);
path1.lineTo(150, 125);
path1.lineTo(50, 125);
path1.close();
shaperLayer1->setPath(path1);
auto fillStyle1 = SolidColor::Make(Color::FromRGBA(255, 0, 0, 127));
shaperLayer1->setFillStyle(fillStyle1);
shaperLayer1->setMatrix(Matrix::MakeTrans(100.0f, 50.0f));
rootLayer->addChild(shaperLayer1);
auto shaperLayer1Bounds = shaperLayer1->getBounds();
shaperLayer1->getGlobalMatrix().mapRect(&shaperLayer1Bounds);
printf("shaperLayer1Bounds: (%f, %f, %f, %f)\n", shaperLayer1Bounds.left, shaperLayer1Bounds.top,
shaperLayer1Bounds.right, shaperLayer1Bounds.bottom);

auto shaperLayer2 = ShapeLayer::Make();
shaperLayer2->setName("shaper_layer2");
Rect rect = Rect::MakeLTRB(220, 100, 370, 250);
Path path2 = {};
path2.addOval(rect);
path2.close();
shaperLayer2->setPath(path2);
auto fillStyle2 = SolidColor::Make(Color::FromRGBA(127, 255, 0, 127));
shaperLayer2->setFillStyle(fillStyle2);
rootLayer->addChild(shaperLayer2);
auto shaperLayer2Bounds = shaperLayer2->getBounds();
shaperLayer2->getGlobalMatrix().mapRect(&shaperLayer2Bounds);
printf("shaperLayer2Bounds: (%f, %f, %f, %f)\n", shaperLayer2Bounds.left, shaperLayer2Bounds.top,
shaperLayer2Bounds.right, shaperLayer2Bounds.bottom);

auto rootLayerBounds = rootLayer->getBounds();
rootLayerBounds.roundOut();
printf("rootLayerBounds: (%f, %f, %f, %f)\n", rootLayerBounds.left, rootLayerBounds.top, rootLayerBounds.right,
rootLayerBounds.bottom);

displayList->render(surface.get());

auto paint = Paint();
paint.setColor(Color::Red());
paint.setStyle(PaintStyle::Stroke);
paint.setStrokeWidth(1.0f);
canvas->drawRect(rootLayerBounds, paint);

// P1(160, 120)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p1 = {160.0f, 120.0f};
canvas->drawCircle(p1.x, p1.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p1.x, p1.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(p1.x, p1.y, true));

// P2(186.66668f, 120.0f)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p2 = {186.66668f, 120.0f};
canvas->drawCircle(p2.x, p2.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p2.x, p2.y));
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p2.x, p2.y, true));

// P3(172.0774145878251, 140)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p3 = {172.0774145878251f, 140.0f};
canvas->drawCircle(p3.x, p3.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p3.x, p3.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(p3.x, p3.y, true));

// P4(200, 150)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p4 = {200.0f, 150.0f};
canvas->drawCircle(p4.x, p4.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p4.x, p4.y));
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p4.x, p4.y, true));

// P5(225, 120)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p5 = {225.0f, 120.0f};
canvas->drawCircle(p5.x, p5.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(p5.x, p5.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(p5.x, p5.y, true));

// P6(200, 180)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point p6 = {200.0f, 180.0f};
canvas->drawCircle(p6.x, p6.y, 1.0f, paint);
EXPECT_EQ(false, shaperLayer1->hitTestPoint(p6.x, p6.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(p6.x, p6.y, true));

// Q1(227.79885, -141.69835)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point q1 = {227.79885f, 141.69835f};
canvas->drawCircle(q1.x, q1.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(q1.x, q1.y));
EXPECT_EQ(true, shaperLayer1->hitTestPoint(q1.x, q1.y, true));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q1.x, q1.y));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q1.x, q1.y, true));

// Q2(230.0, 160.0)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point q2 = {230.0f, 160.0f};
canvas->drawCircle(q2.x, q2.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(q2.x, q2.y));
EXPECT_EQ(true, shaperLayer1->hitTestPoint(q2.x, q2.y, true));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q2.x, q2.y));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q2.x, q2.y, true));

// Q3(270.0, 190.0)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point q3 = {270.0f, 190.0f};
canvas->drawCircle(q3.x, q3.y, 1.0f, paint);
EXPECT_EQ(false, shaperLayer1->hitTestPoint(q3.x, q3.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(q3.x, q3.y, true));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q3.x, q3.y));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q3.x, q3.y, true));

// Q4(336.0, 239.0)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point q4 = {336.0f, 239.0f};
canvas->drawCircle(q4.x, q4.y, 1.0f, paint);
EXPECT_EQ(false, shaperLayer1->hitTestPoint(q4.x, q4.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(q4.x, q4.y, true));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q4.x, q4.y));
EXPECT_EQ(false, shaperLayer2->hitTestPoint(q4.x, q4.y, true));

// Q5(240.0, 150.0)
paint.setColor(Color::Blue());
paint.setStyle(PaintStyle::Fill);
Point q5 = {240.0f, 150.0f};
canvas->drawCircle(q5.x, q5.y, 1.0f, paint);
EXPECT_EQ(true, shaperLayer1->hitTestPoint(q5.x, q5.y));
EXPECT_EQ(false, shaperLayer1->hitTestPoint(q5.x, q5.y, true));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q5.x, q5.y));
EXPECT_EQ(true, shaperLayer2->hitTestPoint(q5.x, q5.y, true));

context->submit();
Baseline::Compare(surface, "LayerTest/Layer_hitTestPoint");
device->unlock();
}
} // namespace tgfx
Loading