Skip to content

Commit

Permalink
C++: make the PhysicalRegion::rectangles non-overlapping
Browse files Browse the repository at this point in the history
  • Loading branch information
ogoffart committed Jul 10, 2024
1 parent 256ff1a commit 42d7661
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
30 changes: 22 additions & 8 deletions api/cpp/include/slint-platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ class SoftwareRenderer : public AbstractRenderer
}

/// Returns a view on all the rectangles in this region.
/// The rectangles do not overlap.
/// The returned type is a C++ view over PhysicalRegion::Rect structs.
///
/// It can be used like so:
Expand All @@ -600,14 +601,27 @@ class SoftwareRenderer : public AbstractRenderer
/// ```
auto rectangles() const
{
return std::views::counted(inner.rectangles, inner.count)
| std::views::transform([](const auto &box) {
return Rect {
.origin = PhysicalPosition({ .x = box.min.x, .y = box.min.y }),
.size = PhysicalSize({ .width = uint32_t(box.max.x - box.min.x),
.height = uint32_t(box.max.y - box.min.y) })
};
});
SharedVector<cbindgen_private::IntRect> rectangles;
slint_software_renderer_region_to_rects(&inner, &rectangles);
# if __cpp_lib_ranges >= 202110L // DR20 P2415R2
using std::ranges::owning_view;
# else
struct owning_view : std::ranges::view_interface<owning_view>
{
SharedVector<cbindgen_private::IntRect> rectangles;
owning_view(SharedVector<cbindgen_private::IntRect> &&rectangles)
: rectangles(rectangles)
{
}
auto begin() const { return rectangles.begin(); }
auto end() const { return rectangles.end(); }
};
# endif
return owning_view(std::move(rectangles)) | std::views::transform([](const auto &r) {
return Rect { .origin = PhysicalPosition({ .x = r.x, .y = r.y }),
.size = PhysicalSize({ .width = uint32_t(r.width),
.height = uint32_t(r.height) }) };
});
}

/// A Rectangle defined with an origin and a size.
Expand Down
14 changes: 13 additions & 1 deletion api/cpp/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,11 @@ pub unsafe extern "C" fn slint_platform_task_run(event: PlatformTaskOpaque) {
mod software_renderer {
use super::*;
type SoftwareRendererOpaque = *const c_void;
use i_slint_core::graphics::Rgb8Pixel;
use i_slint_core::graphics::{IntRect, Rgb8Pixel};
use i_slint_core::software_renderer::{
PhysicalRegion, RepaintBufferType, Rgb565Pixel, SoftwareRenderer,
};
use i_slint_core::SharedVector;

#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_new(
Expand Down Expand Up @@ -505,6 +506,17 @@ mod software_renderer {
let r = (r as *const SoftwareRenderer) as *const dyn Renderer;
core::mem::transmute(r)
}

#[no_mangle]
pub extern "C" fn slint_software_renderer_region_to_rects(
region: &PhysicalRegion,
out: &mut SharedVector<IntRect>,
) {
*out = region
.iter()
.map(|r| euclid::rect(r.0.x, r.0.y, r.1.width as i32, r.1.height as i32))
.collect();
}
}

#[cfg(all(feature = "i-slint-renderer-skia", feature = "raw-window-handle"))]
Expand Down
2 changes: 1 addition & 1 deletion api/cpp/tests/datastructures.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

#include <ranges>
#include <chrono>
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"

#include <slint.h>
#include <slint_image.h>

SCENARIO("SharedString API")
{
Expand Down
7 changes: 3 additions & 4 deletions examples/printerdemo_mcu/zephyr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@

1. Unlike the Espressif integration, we don't provide the platform integration as part of the Slint C++ API. In part, this is due to the way Zephyr OS handles device hardware. Zephyr uses the Device Tree to describe the hardware to the device driver model. In order to register an input event call back we need a pointer to a device obtained from a device tree node, and we also need to know how the driver behaves in order to write our callback function. The existing implementation is generic enough to cover the simulator and display shield drivers. A more general solution could be investigated in the future;
2. Double buffering is not supported as neither the simulator or the hardware used for testing reported it as supported;
3. In the simulator, we convert dirty regions to big-endian. However, where regions overlap, the intersections get converted more than once resulting in incorrect colors on the display. This is a general issue caused by overlapping dirty regions, and should be tackled separately as it also affects the Espressif demo;
4. If there are active animations, we need to make sure to sleep for a fixed period of time, otherwise the event loop runs forever, never re-rendering and never getting to a state where there are no active animations;
5. The example doesn't use the full screen on the hardware;
3. If there are active animations, we need to make sure to sleep for a fixed period of time, otherwise the event loop runs forever, never re-rendering and never getting to a state where there are no active animations;
4. The example doesn't use the full screen on the hardware;

## Prerequisites

Expand Down Expand Up @@ -50,7 +49,7 @@ Before you can run this example, make sure you have done the following:
west init -l --mf examples/printerdemo_mcu/zephyr/west.yaml ./slint

# If you do not have Slint source yet (this checks out Slint and Zephyr source into slint-zephyr):
west init -m https://github.com/0x6e/slint --mr zephyr --mf examples/printerdemo_mcu/zephyr/west.yaml slint-zephyr
west init -m https://github.com/slint-ui/slint --mr zephyr --mf examples/printerdemo_mcu/zephyr/west.yaml slint-zephyr
cd slint-zephyr

# Checkout the repositories:
Expand Down

0 comments on commit 42d7661

Please sign in to comment.