Skip to content

Improve QImage support #746

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

Merged
merged 22 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
3 changes: 3 additions & 0 deletions crates/cxx-qt-lib-headers/include/gui/qimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ QImage
qimageInitFromData(const rust::Slice<std::uint8_t const> data,
rust::Str format);

::std::int64_t
qimageCacheKey(const QImage& image);

} // namespace cxxqtlib1
} // namespace rust
#endif
1 change: 1 addition & 0 deletions crates/cxx-qt-lib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub use qstringlist::QStringList;
mod qt;
pub use qt::{
AspectRatioMode, CaseSensitivity, ConnectionType, DateFormat, SplitBehaviorFlags, TimeSpec,
TransformationMode,
};

mod qtime;
Expand Down
11 changes: 11 additions & 0 deletions crates/cxx-qt-lib/src/core/qt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ mod ffi {
TimeZone,
}

/// This enum type defines whether image transformations (e.g., scaling) should be smooth or not.
#[repr(i32)]
enum TransformationMode {
/// The transformation is performed quickly, with no smoothing.
FastTransformation,
/// The resulting image is transformed using bilinear filtering.
SmoothTransformation,
}

unsafe extern "C++" {
include!("cxx-qt-lib/qt.h");
type AspectRatioMode;
Expand All @@ -75,9 +84,11 @@ mod ffi {
type DateFormat;
type SplitBehaviorFlags;
type TimeSpec;
type TransformationMode;
}
}

pub use ffi::{
AspectRatioMode, CaseSensitivity, ConnectionType, DateFormat, SplitBehaviorFlags, TimeSpec,
TransformationMode,
};
5 changes: 5 additions & 0 deletions crates/cxx-qt-lib/src/gui/qimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ qimageInitFromData(const rust::Slice<std::uint8_t const> data, rust::Str format)
formatString.empty() ? nullptr : formatString.data());
}

::std::int64_t
qimageCacheKey(const QImage& image)
{
return static_cast<::std::int64_t>(image.cacheKey());
}
}
}

Expand Down
120 changes: 120 additions & 0 deletions crates/cxx-qt-lib/src/gui/qimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,127 @@ use std::mem::MaybeUninit;

#[cxx::bridge]
mod ffi {
#[namespace = "Qt"]
unsafe extern "C++" {
include!("cxx-qt-lib/qt.h");
type TransformationMode = crate::TransformationMode;
type AspectRatioMode = crate::AspectRatioMode;
}

unsafe extern "C++" {
include!("cxx-qt-lib/qimage.h");
type QImage = super::QImage;
include!("cxx-qt-lib/qsize.h");
type QSize = crate::QSize;
include!("cxx-qt-lib/qrect.h");
type QRect = crate::QRect;
include!("cxx-qt-lib/qcolor.h");
type QColor = crate::QColor;
include!("cxx-qt-lib/qpoint.h");
type QPoint = crate::QPoint;

/// Returns true if all the colors in the image are shades of gray
#[rust_name = "all_gray"]
fn allGray(self: &QImage) -> bool;

/// Returns a sub-area of the image as a new image.
fn copy(self: &QImage, rect: &QRect) -> QImage;

/// Returns the size of the color table for the image.
#[rust_name = "color_count"]
fn colorCount(self: &QImage) -> i32;

/// Returns the depth of the image.
fn depth(self: &QImage) -> i32;

/// Returns the number of pixels that fit horizontally in a physical meter.
#[rust_name = "dots_per_meterx"]
fn dotsPerMeterX(self: &QImage) -> i32;

/// Returns the number of pixels that fit vertically in a physical meter.
#[rust_name = "dots_per_metery"]
fn dotsPerMeterY(self: &QImage) -> i32;

/// Fills the entire image with the given color.
fn fill(self: &mut QImage, color: &QColor);

/// Whether the QImage is null.
///
/// This means that the QImage has all parameters set to zero and no allocated data.
#[rust_name = "is_null"]
fn isNull(self: &QImage) -> bool;

/// For 32-bit images, this function is equivalent to allGray().
/// For color indexed images, this function returns true if color(i) is QRgb(i, i, i)
/// for all indexes of the color table; otherwise returns false.
#[rust_name = "is_gray_scale"]
fn isGrayscale(self: &QImage) -> bool;

/// Returns true if the image has a format that respects the alpha channel, otherwise returns false.
#[rust_name = "has_alpha_channel"]
fn hasAlphaChannel(self: &QImage) -> bool;

/// Returns the height of the image.
fn height(self: &QImage) -> i32;

/// Returns the enclosing rectangle (0, 0, width(), height()) of the image.
fn rect(self: &QImage) -> QRect;

/// Returns a copy of the image scaled to a rectangle with the given width and height according to the given aspectRatioMode and transformMode.
fn scaled(
self: &QImage,
width: i32,
height: i32,
aspectRatioMode: AspectRatioMode,
transformMode: TransformationMode,
) -> QImage;

/// Returns a scaled copy of the image. The returned image is scaled to the given height using the specified transformation mode.
#[rust_name = "scaled_to_height"]
fn scaledToHeight(self: &QImage, width: i32, mode: TransformationMode) -> QImage;

/// Returns a scaled copy of the image. The returned image is scaled to the given width using the specified transformation mode.
#[rust_name = "scaled_to_width"]
fn scaledToWidth(self: &QImage, width: i32, mode: TransformationMode) -> QImage;

/// Resizes the color table to contain colorCount entries.
#[rust_name = "set_color_count"]
fn setColorCount(self: &mut QImage, colorCount: i32);

/// Sets the alpha channel of this image to the given alphaChannel.
#[rust_name = "set_alpha_channel"]
fn setAlphaChannel(self: &mut QImage, alphaChannel: &QImage);

/// Sets the number of pixels by which the image is intended to be offset by when positioning relative to other images, to offset.
#[rust_name = "set_offset"]
fn setOffset(self: &mut QImage, point: &QPoint);

/// Sets the pixel color at (x, y) to color.
#[rust_name = "set_pixel_color"]
fn setPixelColor(self: &mut QImage, x: i32, y: i32, color: &QColor);

/// Returns the size of the image.
fn size(self: &QImage) -> QSize;

/// Swaps image other with this image. This operation is very fast and never fails.
fn swap(self: &mut QImage, other: &mut QImage);

/// Returns the number of pixels by which the image is intended to be offset by when positioning relative to other images.
fn offset(self: &QImage) -> QPoint;

/// Returns the color of the pixel at coordinates (x, y) as a QColor.
#[rust_name = "pixel_color"]
fn pixelColor(self: &QImage, x: i32, y: i32) -> QColor;

/// Returns the pixel index at (x, y).
#[rust_name = "pixel_index"]
fn pixelIndex(self: &QImage, x: i32, y: i32) -> i32;

/// Returns true if pos is a valid coordinate pair within the image.
fn valid(self: &QImage, x: i32, y: i32) -> bool;

/// Returns the width of the image.
fn width(self: &QImage) -> i32;
}

#[namespace = "rust::cxxqtlib1"]
Expand All @@ -30,6 +142,10 @@ mod ffi {
#[doc(hidden)]
#[rust_name = "qimage_init_from_data"]
fn qimageInitFromData(data: &[u8], format: &str) -> QImage;

#[doc(hidden)]
#[rust_name = "qimage_cache_key"]
fn qimageCacheKey(image: &QImage) -> i64;
}
}

Expand Down Expand Up @@ -79,4 +195,8 @@ impl QImage {
None
}
}
/// Returns a number that identifies the contents of this QImage object.
pub fn cache_key(&self) -> i64 {
ffi::qimage_cache_key(self)
}
}