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

Add QBrush support #862

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Support for further types: `QLine`, `QLineF`, `QImage`, `QPainter`, `QFont`, `QPen`, `QPolygon`, `QPolygonF`
- Support for further types: `QLine`, `QLineF`, `QImage`, `QPainter`, `QFont`, `QPen`, `QPolygon`, `QPolygonF`, `QBrush`
- `internal_pointer_mut()` function on `QModelIndex`
- `c_void` in CXX-Qt-lib for easy access to `void *`
- `CxxQtThread` is now marked as `Sync` so that it can be used by reference
Expand Down
22 changes: 22 additions & 0 deletions crates/cxx-qt-lib-headers/include/gui/qbrush.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// clang-format off
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
#pragma once

#include <QtGui/QBrush>

#include "rust/cxx.h"

// Define namespace otherwise we hit a GCC bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
namespace rust {

template<>
struct IsRelocatable<QBrush> : ::std::true_type
{
};

} // namespace rust
1 change: 1 addition & 0 deletions crates/cxx-qt-lib-headers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub fn build_opts() -> cxx_qt_build::CxxQtBuildersOpts {
"qmodelindex.h",
),
#[cfg(feature = "qt_gui")]
(include_str!("../include/gui/qbrush.h"), "qbrush.h"),
(include_str!("../include/gui/qpen.h"), "qpen.h"),
(
include_str!("../include/core/qpersistentmodelindex.h"),
Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ fn main() {
"core/qlist/qlist_qcolor",
"core/qvariant/qvariant_qcolor",
"core/qvector/qvector_qcolor",
"gui/qbrush",
"gui/qcolor",
"gui/qfont",
"gui/qguiapplication",
Expand Down Expand Up @@ -218,6 +219,7 @@ fn main() {

if feature_qt_gui_enabled {
cpp_files.extend([
"gui/qbrush",
"gui/qcolor",
"gui/qfont",
"gui/qguiapplication",
Expand Down
6 changes: 3 additions & 3 deletions crates/cxx-qt-lib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ pub use qstringlist::QStringList;

mod qt;
pub use qt::{
AspectRatioMode, BGMode, CaseSensitivity, ClipOperation, ConnectionType, DateFormat, FillRule,
LayoutDirection, PenCapStyle, PenJoinStyle, PenStyle, SplitBehaviorFlags, TimeSpec,
TransformationMode,
AspectRatioMode, BGMode, BrushStyle, CaseSensitivity, ClipOperation, ConnectionType,
DateFormat, FillRule, LayoutDirection, PenCapStyle, PenJoinStyle, PenStyle, SplitBehaviorFlags,
TimeSpec, TransformationMode,
};

mod qtime;
Expand Down
29 changes: 27 additions & 2 deletions crates/cxx-qt-lib/src/core/qt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,29 @@ mod ffi {
IntersectClip,
}

#[repr(i32)]
enum BrushStyle {
NoBrush,
SolidPattern,
Dense1Pattern,
Dense2Pattern,
Dense3Pattern,
Dense4Pattern,
Dense5Pattern,
Dense6Pattern,
Dense7Pattern,
HorPattern,
VerPattern,
CrossPattern,
BDiagPattern,
FDiagPattern,
DiagCrossPattern,
LinearGradientPattern,
RadialGradientPattern,
ConicalGradientPattern,
TexturePattern = 24,
}

unsafe extern "C++" {
include!("cxx-qt-lib/qt.h");
type AspectRatioMode;
Expand All @@ -149,12 +172,14 @@ mod ffi {
type LayoutDirection;
type BGMode;
type ClipOperation;
type BrushStyle;
}
}

pub use ffi::{
AspectRatioMode, BGMode, CaseSensitivity, ClipOperation, DateFormat, FillRule, LayoutDirection,
PenCapStyle, PenJoinStyle, PenStyle, SplitBehaviorFlags, TimeSpec, TransformationMode,
AspectRatioMode, BGMode, BrushStyle, CaseSensitivity, ClipOperation, DateFormat, FillRule,
LayoutDirection, PenCapStyle, PenJoinStyle, PenStyle, SplitBehaviorFlags, TimeSpec,
TransformationMode,
};

// Reexport ConnectionType from cxx-qt
Expand Down
3 changes: 3 additions & 0 deletions crates/cxx-qt-lib/src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ pub use qpainterpath::QPainterPath;

mod qpainter;
pub use qpainter::QPainter;

mod qbrush;
pub use qbrush::QBrush;
23 changes: 23 additions & 0 deletions crates/cxx-qt-lib/src/gui/qbrush.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// clang-format off
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// clang-format on
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0

#include "cxx-qt-lib/qbrush.h"

#include "../assertion_utils.h"

// https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/painting/qbrush.h?h=v5.15.6-lts-lgpl#n130
// https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/painting/qbrush.h?h=v6.2.4#n123
assert_alignment_and_size(QBrush,
alignof(::std::size_t),
sizeof(::std::size_t));

static_assert(!::std::is_trivially_copy_assignable<QBrush>::value);
static_assert(!::std::is_trivially_copy_constructible<QBrush>::value);

static_assert(!::std::is_trivially_destructible<QBrush>::value);

static_assert(QTypeInfo<QBrush>::isRelocatable);
102 changes: 102 additions & 0 deletions crates/cxx-qt-lib/src/gui/qbrush.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
// SPDX-FileContributor: Laurent Montel <[email protected]>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use cxx::{type_id, ExternType};
use std::mem::MaybeUninit;

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

unsafe extern "C++" {
include!("cxx-qt-lib/qbrush.h");
type QBrush = super::QBrush;
include!("cxx-qt-lib/qcolor.h");
type QColor = crate::QColor;
include!("cxx-qt-lib/qimage.h");
type QImage = crate::QImage;

/// Returns true if the brush is fully opaque otherwise false
#[rust_name = "is_opaque"]
fn isOpaque(self: &QBrush) -> bool;

/// Returns the brush color.
fn color(self: &QBrush) -> &QColor;

/// Sets the brush style to style.
#[rust_name = "set_style"]
fn setStyle(self: &mut QBrush, style: BrushStyle);

/// Sets the brush color to the given color.
#[rust_name = "set_color"]
fn setColor(self: &mut QBrush, color: &QColor);

/// Sets the brush image to image. The style is set to Qt::TexturePattern.
#[rust_name = "set_texture_image"]
fn setTextureImage(self: &mut QBrush, image: &QImage);

/// Returns the brush style.
fn style(self: &QBrush) -> BrushStyle;

/// Returns the custom brush pattern, or a null image if no custom brush pattern has been set.
#[rust_name = "texture_image"]
fn textureImage(self: &QBrush) -> QImage;
}

#[namespace = "rust::cxxqtlib1"]
unsafe extern "C++" {
include!("cxx-qt-lib/common.h");

#[doc(hidden)]
#[rust_name = "qbrush_init_default"]
fn construct() -> QBrush;

#[doc(hidden)]
#[rust_name = "qbrush_drop"]
fn drop(brush: &mut QBrush);

#[doc(hidden)]
#[rust_name = "qbrush_clone"]
fn construct(brush: &QBrush) -> QBrush;
}
}

#[repr(C)]
pub struct QBrush {
#[cfg(qt_version_major = "5")]
_cspec: MaybeUninit<[i32; 2]>,
#[cfg(qt_version_major = "6")]
_cspec: MaybeUninit<i32>,
}

impl Default for QBrush {
/// Constructs a default black brush with the style Qt::NoBrush (i.e. this brush will not fill shapes).
fn default() -> Self {
ffi::qbrush_init_default()
}
}

impl Drop for QBrush {
fn drop(&mut self) {
ffi::qbrush_drop(self);
}
}

impl Clone for QBrush {
fn clone(&self) -> Self {
ffi::qbrush_clone(self)
}
}

// Safety:
//
// Static checks on the C++ side to ensure the size is the same.
unsafe impl ExternType for QBrush {
type Id = type_id!("QBrush");
type Kind = cxx::kind::Trivial;
}
20 changes: 20 additions & 0 deletions crates/cxx-qt-lib/src/gui/qpainter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,19 @@ mod ffi {
type QPen = crate::QPen;
include!("cxx-qt-lib/qpolygon.h");
type QPolygon = crate::QPolygon;
include!("cxx-qt-lib/qbrush.h");
type QBrush = crate::QBrush;

/// Returns the current background brush.
fn background(self: &QPainter) -> &QBrush;

/// Returns the current background mode.
#[rust_name = "background_mode"]
fn backgroundMode(self: &QPainter) -> BGMode;

/// Returns the painter's current brush.
fn brush(self: &QPainter) -> &QBrush;

/// Returns the currently set brush origin.
#[rust_name = "brush_origin"]
fn brushOrigin(self: &QPainter) -> QPoint;
Expand Down Expand Up @@ -131,6 +139,10 @@ mod ffi {
#[rust_name = "erase_rect"]
fn eraseRect(self: Pin<&mut QPainter>, rectangle: &QRectF);

/// Fills the given path using the given brush. The outline is not drawn.
#[rust_name = "fill_path"]
fn fillPath(self: Pin<&mut QPainter>, path: &QPainterPath, brush: &QBrush);

/// Fills the given rectangle with the color specified.
#[rust_name = "fill_rect"]
fn fillRect(self: Pin<&mut QPainter>, rectangle: &QRectF, color: &QColor);
Expand Down Expand Up @@ -160,10 +172,18 @@ mod ffi {
/// A save() must be followed by a corresponding restore(); the end() function unwinds the stack.
fn save(self: Pin<&mut QPainter>);

/// Sets the background brush of the painter to the given brush.
#[rust_name = "set_background"]
fn setBackground(self: Pin<&mut QPainter>, brush: &QBrush);

/// Sets the background mode of the painter to the given mode
#[rust_name = "set_background_mode"]
fn setBackgroundMode(self: Pin<&mut QPainter>, mode: BGMode);

/// Sets the painter's brush to the given brush.
#[rust_name = "set_brush"]
fn setBrush(self: Pin<&mut QPainter>, brush: &QBrush);

/// Enables clipping if enable is true, or disables clipping if enable is false.
#[rust_name = "set_clipping"]
fn setClipping(self: Pin<&mut QPainter>, enable: bool);
Expand Down
9 changes: 9 additions & 0 deletions crates/cxx-qt-lib/src/gui/qpen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ mod ffi {
type QPen = super::QPen;
include!("cxx-qt-lib/qcolor.h");
type QColor = crate::QColor;
include!("cxx-qt-lib/qbrush.h");
type QBrush = crate::QBrush;

/// Returns the brush used to fill strokes generated with this pen.
fn brush(self: &QPen) -> QBrush;

/// Returns the pen's cap style.
#[rust_name = "cap_style"]
Expand Down Expand Up @@ -49,6 +54,10 @@ mod ffi {
#[rust_name = "miter_limit"]
fn miterLimit(self: &QPen) -> f64;

/// Sets the brush used to fill strokes generated with this pen to the given brush.
#[rust_name = "set_brush"]
fn setBrush(self: &mut QPen, brush: &QBrush);

/// Sets the pen's cap style to the given style. The default value is Qt::SquareCap.
#[rust_name = "set_cap_style"]
fn setCapStyle(self: &mut QPen, style: PenCapStyle);
Expand Down
Loading