C++ image: add some docs

Note: Don't use cbindgen to generate `operator==` for public types.
Because it doesn't have docs and the documentation show warnings
otherwise
This commit is contained in:
Olivier Goffart 2023-03-20 15:04:14 +01:00 committed by Olivier Goffart
parent ef7fb6422a
commit c82bb1515e
4 changed files with 73 additions and 16 deletions

View file

@ -395,8 +395,20 @@ fn gen_corelib(
public_config.export.exclude = private_exported_types.into_iter().collect(); public_config.export.exclude = private_exported_types.into_iter().collect();
public_config.export.exclude.push("Point".into()); public_config.export.exclude.push("Point".into());
public_config.export.include = public_exported_types.into_iter().map(str::to_string).collect(); public_config.export.include = public_exported_types.into_iter().map(str::to_string).collect();
public_config.structure.derive_eq = true; public_config.export.body.insert(
public_config.structure.derive_neq = true; "StandardListViewItem".to_owned(),
"/// \\private\nfriend bool operator==(const StandardListViewItem&, const StandardListViewItem&) = default;".into(),
);
public_config.export.body.insert(
"Rgb8Pixel".to_owned(),
"/// \\private\nfriend bool operator==(const Rgb8Pixel&, const Rgb8Pixel&) = default;"
.into(),
);
public_config.export.body.insert(
"Rgba8Pixel".to_owned(),
"/// \\private\nfriend bool operator==(const Rgba8Pixel&, const Rgba8Pixel&) = default;"
.into(),
);
cbindgen::Builder::new() cbindgen::Builder::new()
.with_config(public_config) .with_config(public_config)

View file

@ -12,36 +12,37 @@
namespace slint { namespace slint {
/// SharedPixelBuffer is a container for storing image data as pixels. It is /// SharedPixelBuffer is a container for storing image data as pixels. It is
/// internally reference counted and cheap to clone. /// internally reference counted and cheap to copy.
/// ///
/// You can construct a new empty shared pixel buffer with its default constructor, /// You can construct a new empty shared pixel buffer with its default constructor,
/// or you can copy it from an existing contiguous buffer that you might already have, using that /// or you can copy it from an existing contiguous buffer that you might already have, using the
/// constructor /// range constructor.
/// ///
/// See the documentation for Image for examples how to use this type to integrate /// See the documentation for Image for examples how to use this type to integrate
/// Slint with external rendering functions. /// Slint with external rendering functions.
template<typename Pixel> template<typename Pixel>
struct SharedPixelBuffer struct SharedPixelBuffer
{ {
/// construct an empty SharedPixelBuffer /// Construct an empty SharedPixelBuffer.
SharedPixelBuffer() = default; SharedPixelBuffer() = default;
/// construct a SharedPixelBuffer with the given size /// Construct a SharedPixelBuffer with the given \a width and \a height. The pixels are default
/// initialized.
SharedPixelBuffer(uint32_t width, uint32_t height) SharedPixelBuffer(uint32_t width, uint32_t height)
: m_width(width), m_height(height), m_data(width * height) : m_width(width), m_height(height), m_data(width * height)
{ {
} }
/// Construct a SharedPixelBuffer by copying the data from the \a data array. /// Construct a SharedPixelBuffer by copying the data from the \a data array.
/// The array must be of size \a width * \a height /// The array must be of size \a width * \a height .
SharedPixelBuffer(uint32_t width, uint32_t height, const Pixel *data) SharedPixelBuffer(uint32_t width, uint32_t height, const Pixel *data)
: m_width(width), m_height(height), m_data(data, data + (width * height)) : m_width(width), m_height(height), m_data(data, data + (width * height))
{ {
} }
/// Return the width of the buffer in pixels /// Returns the width of the buffer in pixels.
uint32_t width() const { return m_width; } uint32_t width() const { return m_width; }
/// Return the height of the buffer in pixels /// Returns the height of the buffer in pixels.
uint32_t height() const { return m_height; } uint32_t height() const { return m_height; }
/// Returns a const pointer to the first pixel of this buffer. /// Returns a const pointer to the first pixel of this buffer.
@ -57,7 +58,7 @@ struct SharedPixelBuffer
/// Returns a const pointer past this buffer. /// Returns a const pointer past this buffer.
const Pixel *cend() const { return m_data.end(); } const Pixel *cend() const { return m_data.end(); }
/// Compare two SharedPixelBuffer. They are considered equal if all their pixels are equal /// Compare two SharedPixelBuffers. They are considered equal if all their pixels are equal.
bool operator==(const SharedPixelBuffer &other) const = default; bool operator==(const SharedPixelBuffer &other) const = default;
private: private:
@ -68,6 +69,43 @@ private:
}; };
/// An image type that can be displayed by the Image element /// An image type that can be displayed by the Image element
///
/// You can construct Image objects from a path to an image file on disk, using
/// Image::load_from_path().
///
/// Another typical use-case is to render the image content with C++ code.
/// For this its most efficient to create a new SharedPixelBuffer with the known dimensions and
/// pass the pixel pointer returned by begin() to your rendering function. Afterwards you can create
/// an Image using the constructor taking a SharedPixelBuffer.
///
/// The following example creates a 320x200 RGB pixel buffer and calls a function to draw a shape
/// into it:
/// ```c++
/// slint::SharedPixelBuffer::<slint::Rgb8Pixel> pixel_buffer(320, 200);
/// low_level_render(pixel_buffer.width(), pixel_buffer.height(),
/// static_cast<unsigned char *>(pixel_buffer.begin()));
/// slint::Image image(pixel_buffer);
/// ```
///
/// Another use-case is to import existing image data into Slint, by
/// creating a new Image through copying of the buffer:
///
/// ```cpp
/// slint::Image image(slint::SharedPixelBuffer<slint::Rgb8Pixel>(the_width, the_height,
/// static_cast<slint::Rgb8Pixel*>(the_data));
/// ```
///
/// This only works if the static_cast is valid and the underlying data has the same
/// memory layout as slint::Rgb8Pixel or slint::Rgba8Pixel. Otherwise, you will have to do a
/// pixel conversion as you copy the pixels:
///
/// ```cpp
/// slint::SharedPixelBuffer::<slint::Rgb8Pixel> pixel_buffer(the_width, the_height);
/// slint::Rgb8Pixel *raw_data = pixel_buffer.begin();
/// for (int i = 0; i < the_width * the_height; i++) {
/// raw_data[i] = { bgr_data[i * 3 + 2], bgr_data[i * 3 + 1], bgr_data[i * 3] };
/// }
/// ```
struct Image struct Image
{ {
public: public:
@ -81,7 +119,7 @@ public:
return img; return img;
} }
/// Construct an image from a SharedPixelBuffer of RGB pixel. /// Construct an image from a SharedPixelBuffer of RGB pixels.
Image(SharedPixelBuffer<Rgb8Pixel> buffer) Image(SharedPixelBuffer<Rgb8Pixel> buffer)
: data(Data::ImageInner_EmbeddedImage( : data(Data::ImageInner_EmbeddedImage(
cbindgen_private::types::ImageCacheKey::Invalid(), cbindgen_private::types::ImageCacheKey::Invalid(),
@ -93,7 +131,7 @@ public:
{ {
} }
/// Construct an image from a SharedPixelBuffer of RGB pixel. /// Construct an image from a SharedPixelBuffer of RGBA pixels.
Image(SharedPixelBuffer<Rgba8Pixel> buffer) Image(SharedPixelBuffer<Rgba8Pixel> buffer)
: data(Data::ImageInner_EmbeddedImage( : data(Data::ImageInner_EmbeddedImage(
cbindgen_private::types::ImageCacheKey::Invalid(), cbindgen_private::types::ImageCacheKey::Invalid(),

View file

@ -44,7 +44,7 @@ struct SharedVector
} }
} }
/// Creates a vector of a given size, with with copies of the value. /// Creates a vector of a given size, initialized with copies of the \a value.
explicit SharedVector(size_t size, const T &value) explicit SharedVector(size_t size, const T &value)
: SharedVector(SharedVector::with_capacity(size)) : SharedVector(SharedVector::with_capacity(size))
{ {

View file

@ -671,23 +671,30 @@ pub(crate) mod ffi {
use super::*; use super::*;
// Expand Rgb8Pixel so that cbindgen can see it. (is in fact rgb::RGB<u8>) // Expand Rgb8Pixel so that cbindgen can see it. (is in fact rgb::RGB<u8>)
/// Represents a RGB pixel /// Represents an RGB pixel.
#[cfg(cbindgen)] #[cfg(cbindgen)]
#[repr(C)] #[repr(C)]
struct Rgb8Pixel { struct Rgb8Pixel {
/// red value (between 0 and 255)
r: u8, r: u8,
/// green value (between 0 and 255)
g: u8, g: u8,
/// blue value (between 0 and 255)
b: u8, b: u8,
} }
// Expand Rgba8Pixel so that cbindgen can see it. (is in fact rgb::RGBA<u8>) // Expand Rgba8Pixel so that cbindgen can see it. (is in fact rgb::RGBA<u8>)
/// Represents a RGBA pixel /// Represents an RGBA pixel.
#[cfg(cbindgen)] #[cfg(cbindgen)]
#[repr(C)] #[repr(C)]
struct Rgba8Pixel { struct Rgba8Pixel {
/// red value (between 0 and 255)
r: u8, r: u8,
/// green value (between 0 and 255)
g: u8, g: u8,
/// blue value (between 0 and 255)
b: u8, b: u8,
/// alpha value (between 0 and 255)
a: u8, a: u8,
} }