/* * This source file is part of RmlUi, the HTML/CSS Interface Middleware * * For the latest information, see http://github.com/mikke89/RmlUi * * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd * Copyright (c) 2019-2024 The RmlUi Team, and contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ #include "../Common/TestsInterface.h" #include "../Common/TestsShell.h" #include #include #include #include #include #include using namespace Rml; static String GenerateRowsRml(int num_rows, String row_rml) { String rml; rml.reserve(num_rows * row_rml.size()); for (int i = 0; i < num_rows; i++) rml += row_rml; return rml; } static const String document_basic_rml = R"( Demo
)"; TEST_CASE("ElementBackgroundBorder.render_stats") { Context* context = TestsShell::GetContext(); REQUIRE(context); ElementDocument* document = context->LoadDocumentFromMemory(document_basic_rml); REQUIRE(document); document->Show(); constexpr int num_rows = 10; const String row_rml = "
"; const String inner_rml = GenerateRowsRml(num_rows, row_rml); Element* wrapper = document->GetElementById("wrapper"); REQUIRE(wrapper); wrapper->SetInnerRML(inner_rml); context->Update(); context->Render(); TestsShell::RenderLoop(); TestsRenderInterface* render_interface = TestsShell::GetTestsRenderInterface(); if (!render_interface) return; MESSAGE(TestsShell::GetRenderStats()); render_interface->Reset(); for (int i = 1; i < 50; i++) { wrapper->SetScrollTop(1.3333f * float(i)); context->Update(); context->Render(); } wrapper->SetScrollTop(FLT_MAX); context->Update(); context->Render(); // Ensure that we have no unnecessary compile geometry commands. The geometry for the background-border should not // change in size as long as scrolling occurs in integer increments. CHECK(render_interface->GetCounters().compile_geometry == 0); document->Close(); TestsShell::ShutdownShell(); } static const String document_relative_offset_rml = R"( Demo
)"; TEST_CASE("ElementBackgroundBorder.background_edges_line_up_with_relative_offset") { Context* context = TestsShell::GetContext(); REQUIRE(context); ElementDocument* document = context->LoadDocumentFromMemory(document_relative_offset_rml); REQUIRE(document); document->Show(); constexpr int num_children = 10; const String row_rml = "
"; const String inner_rml = GenerateRowsRml(num_children, row_rml); Element* wrapper = document->GetElementById("wrapper"); REQUIRE(wrapper); wrapper->SetInnerRML(inner_rml); context->Update(); context->Render(); TestsShell::RenderLoop(); TestsRenderInterface* render_interface = TestsShell::GetTestsRenderInterface(); if (!render_interface) return; MESSAGE(TestsShell::GetRenderStats()); render_interface->Reset(); for (int i = 1; i < 100; i++) { for (int child_index = 0; child_index < num_children; child_index++) { Element* child = wrapper->GetChild(child_index); child->SetProperty(PropertyId::Top, Property(1.3333f * float(i), Unit::PX)); } context->Update(); context->Render(); for (int child_index = 0; child_index < num_children - 1; child_index++) { Element* current_child = wrapper->GetChild(child_index); Element* next_child = wrapper->GetChild(child_index + 1); Vector2f current_bottom_right = current_child->GetAbsoluteOffset(BoxArea::Border).Round() + current_child->GetRenderBox().GetFillSize(); Vector2f next_top_left = next_child->GetAbsoluteOffset(BoxArea::Border).Round(); CHECK(current_bottom_right.y == next_top_left.y); } } // When changing the position using fractional increments we expect the size of the backgrounds to change, resulting // in new geometry. This is done to ensure that the top and bottom of each background lines up with the one for the // next element, thereby avoiding any gaps. CHECK(render_interface->GetCounters().compile_geometry > 0); MESSAGE("Compile geometry after movement: ", render_interface->GetCounters().compile_geometry); document->Close(); TestsShell::ShutdownShell(); }