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?
This commit is contained in:
Simon Hausmann 2021-02-01 16:10:05 +01:00
parent 69508575ec
commit f33b26fa93
3 changed files with 53 additions and 15 deletions

View file

@ -0,0 +1,32 @@
/* LICENSE BEGIN
This file is part of the SixtyFPS Project -- https://sixtyfps.io
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
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 <string_view>
#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;
};
}

View file

@ -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<GradientStop>);
pub struct LinearGradientBrush(SharedVector<GradientStop>);
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<Item = GradientStop>) -> Self {
let stop_iter = stops.into_iter();

View file

@ -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 {{