From f33b26fa93ff4593e06fb381940686d23de93fab Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 1 Feb 2021 16:10:05 +0100 Subject: [PATCH] Make Brush compile for C++ A few changes were required: * `LinearGradient(LinearGradient)` as enum variant unfortunately won't compile because the cbindgen generated constructor function (`LinearGradient()`) will try to also instantiate the variant type inside (`LinearGradient`) and that won't find the type but the function itself and error out. So the inner type is now called `LinearGradientBrush`. * The same name dance was required for `Color`, where the enum variant instead is called `SolidColor` * `BrushInner` was removed in favor of just `Brush`. The nicer Rust API will be the public variant, and for cbindgen we can just put the generated enum into an internal namespace, like we do for Resource for example * A `NoBrush` variant was added. Maybe that name could be improved? --- api/sixtyfps-cpp/include/sixtyfps_brush.h | 32 ++++++++++++++++++++++ sixtyfps_runtime/corelib/graphics/brush.rs | 21 ++++++-------- tests/driver_lib/cbindgen.rs | 15 ++++++++-- 3 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 api/sixtyfps-cpp/include/sixtyfps_brush.h diff --git a/api/sixtyfps-cpp/include/sixtyfps_brush.h b/api/sixtyfps-cpp/include/sixtyfps_brush.h new file mode 100644 index 000000000..55fc6e7e4 --- /dev/null +++ b/api/sixtyfps-cpp/include/sixtyfps_brush.h @@ -0,0 +1,32 @@ +/* LICENSE BEGIN + This file is part of the SixtyFPS Project -- https://sixtyfps.io + Copyright (c) 2020 Olivier Goffart + Copyright (c) 2020 Simon Hausmann + + SPDX-License-Identifier: GPL-3.0-only + This file is also available under commercial licensing terms. + Please contact info@sixtyfps.io for more information. +LICENSE END */ +#pragma once +#include +#include "sixtyfps_color.h" +#include "sixtyfps_brush_internal.h" +#include "sixtyfps_string.h" + +namespace sixtyfps { + +struct Brush +{ +public: + Brush() : data(Inner::NoBrush()) { } + + friend bool operator==(const Brush &a, const Brush &b) { return a.data == b.data; } + friend bool operator!=(const Brush &a, const Brush &b) { return a.data != b.data; } + +private: + using Tag = cbindgen_private::types::Brush::Tag; + using Inner = cbindgen_private::types::Brush; + Inner data; +}; + +} diff --git a/sixtyfps_runtime/corelib/graphics/brush.rs b/sixtyfps_runtime/corelib/graphics/brush.rs index c555577c3..778a4474f 100644 --- a/sixtyfps_runtime/corelib/graphics/brush.rs +++ b/sixtyfps_runtime/corelib/graphics/brush.rs @@ -14,31 +14,28 @@ This module contains brush related types for the run-time library. use super::Color; use crate::SharedVector; -/// A brush is an opaque data structure that is used to describe how +/// A brush is a data structure that is used to describe how /// a shape, such as a rectangle, path or even text, shall be filled. /// A brush can also be applied to the outline of a shape, that means /// the fill of the outline itself. -#[repr(transparent)] -pub struct Brush(BrushInner); - -/// BrushInner is the variant for the `Brush` type that can be either -/// a color or a linear gradient. #[repr(C)] -pub enum BrushInner { +pub enum Brush { + /// The brush will not produce any fill. + NoBrush, /// The color variant of brush is a plain color that is to be used for the fill. - Color(Color), + SolidColor(Color), /// The linear gradient variant of a brush describes the gradient stops for a fill /// where all color stops are along a line that's rotated by the specified angle. - LinearGradient(LinearGradient), + LinearGradient(LinearGradientBrush), } -/// The LinearGradient describes a way of filling a shape with different colors, which +/// The LinearGradientBrush describes a way of filling a shape with different colors, which /// are interpolated between different stops. The colors are aligned with a line that's rotated /// by the LinearGradient's angle. #[repr(transparent)] -pub struct LinearGradient(SharedVector); +pub struct LinearGradientBrush(SharedVector); -impl LinearGradient { +impl LinearGradientBrush { /// Creates a new linear gradient, described by the specified angle and the provided color stops. pub fn new(angle: f32, stops: impl IntoIterator) -> Self { let stop_iter = stops.into_iter(); diff --git a/tests/driver_lib/cbindgen.rs b/tests/driver_lib/cbindgen.rs index d22c087a7..8f7b3ebd8 100644 --- a/tests/driver_lib/cbindgen.rs +++ b/tests/driver_lib/cbindgen.rs @@ -84,6 +84,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> { "Color", "PathData", "PathElement", + "Brush", "sixtyfps_new_path_elements", "sixtyfps_new_path_events", "Property", @@ -142,9 +143,9 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> { .context("Unable to generate bindings for sixtyfps_properties_internal.h")? .write_to_file(include_dir.join("sixtyfps_properties_internal.h")); - for (rust_types, internal_header) in [ - (vec!["Resource"], "sixtyfps_resource_internal.h"), - (vec!["Color"], "sixtyfps_color_internal.h"), + for (rust_types, extra_excluded_types, internal_header) in [ + (vec!["Resource"], vec![], "sixtyfps_resource_internal.h"), + (vec!["Color"], vec![], "sixtyfps_color_internal.h"), ( vec![ "PathData", @@ -152,8 +153,14 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> { "sixtyfps_new_path_elements", "sixtyfps_new_path_events", ], + vec![], "sixtyfps_pathdata_internal.h", ), + ( + vec!["Brush", "LinearGradient", "GradientStop"], + vec!["Color"], + "sixtyfps_brush_internal.h", + ), ] .iter() { @@ -176,6 +183,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> { ] .iter() .filter(|exclusion| rust_types.iter().find(|inclusion| inclusion == exclusion).is_none()) + .chain(extra_excluded_types.into_iter()) .map(|s| s.to_string()) .collect(); @@ -244,6 +252,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> { .with_include("sixtyfps_resource.h") .with_include("sixtyfps_color.h") .with_include("sixtyfps_pathdata.h") + .with_include("sixtyfps_brush.h") .with_after_include(format!( r" namespace sixtyfps {{