From 926e377a53f0f4855524d11ed54a19d3fe4eef95 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 15 Oct 2014 17:18:22 -0700 Subject: [PATCH] Add support for linear gradients --- src/azure-c.cpp | 45 ++++++++++++++--- src/azure-c.h | 60 ++++++++++++++--------- src/azure.rs | 41 +++++++++++++++- src/azure_hl.rs | 126 +++++++++++++++++++++++++++++++++++++++++++----- src/lib.rs | 4 +- 5 files changed, 229 insertions(+), 47 deletions(-) diff --git a/src/azure-c.cpp b/src/azure-c.cpp index 3282390..999118a 100644 --- a/src/azure-c.cpp +++ b/src/azure-c.cpp @@ -145,12 +145,6 @@ AzCreateColorPattern(AzColor *aColor) { return gfxColorPattern; } -extern "C" void -AzReleaseColorPattern(AzColorPatternRef aColorPattern) { - gfx::ColorPattern *gfxColorPattern = static_cast(aColorPattern); - delete gfxColorPattern; -} - extern "C" AzSkiaSharedGLContextRef AzCreateSkiaSharedGLContext(AzGLNativeContextRef aNativeContext, AzIntSize *aSize) { GrGLNativeContext* nativeContext = reinterpret_cast(aNativeContext); @@ -400,6 +394,20 @@ AzDrawTargetCreateSourceSurfaceFromData(AzDrawTargetRef aDrawTarget, return gfxSourceSurface; } +extern "C" AzGradientStopsRef +AzDrawTargetCreateGradientStops(AzDrawTargetRef aDrawTarget, + AzGradientStop *aStops, + uint32_t aNumStops, + AzExtendMode aExtendMode) { + gfx::DrawTarget *gfxDrawTarget = static_cast(aDrawTarget); + gfx::GradientStop *gfxStops = reinterpret_cast(aStops); + gfx::ExtendMode gfxExtendMode = static_cast(aExtendMode); + RefPtr gfxGradientStops = + gfxDrawTarget->CreateGradientStops(gfxStops, aNumStops, gfxExtendMode); + gfxGradientStops->AddRef(); + return gfxGradientStops; +} + extern "C" void AzReleaseSourceSurface(AzSourceSurfaceRef aSurface) { gfx::SourceSurface *gfxSourceSurface = static_cast(aSurface); @@ -553,3 +561,28 @@ AzReleasePath(AzPathRef aPath) { gfx::Path *gfxPath = static_cast(aPath); gfxPath->Release(); } + +extern "C" AzLinearGradientPatternRef +AzCreateLinearGradientPattern(const AzPoint *aBegin, + const AzPoint *aEnd, + AzGradientStopsRef aStops, + const AzMatrix *aMatrix) { + const gfx::Point *gfxBegin = reinterpret_cast(aBegin); + const gfx::Point *gfxEnd = reinterpret_cast(aEnd); + gfx::GradientStops *gfxStops = reinterpret_cast(aStops); + const gfx::Matrix *gfxMatrix = reinterpret_cast(aMatrix); + gfx::LinearGradientPattern* gfxLinearGradientPattern = new + gfx::LinearGradientPattern(*gfxBegin, *gfxEnd, gfxStops, *gfxMatrix); + return gfxLinearGradientPattern; +} + +void AzReleasePattern(AzPatternRef aPattern) { + gfx::Pattern *gfxPattern = reinterpret_cast(aPattern); + delete gfxPattern; +} + +void AzReleaseGradientStops(AzGradientStopsRef aStops) { + gfx::GradientStops *gfxStops = reinterpret_cast(aStops); + gfxStops->Release(); +} + diff --git a/src/azure-c.h b/src/azure-c.h index cdca7a9..6841d1a 100644 --- a/src/azure-c.h +++ b/src/azure-c.h @@ -22,6 +22,24 @@ void AzSanityCheck(); // FIXME: This stuff is copy pasted from the azure headers +typedef void* AzGradientStopsRef; +typedef void* AzSkiaSharedGLContextRef; +typedef void* AzSkiaSharedGrGLContextRef; +typedef void* AzSkiaGrContextRef; +typedef void* AzSkiaGrGLSharedSurfaceRef; +typedef void* AzSkiaGrGLSharedContextRef; +typedef void* AzDrawTargetRef; +typedef void* AzPatternRef; +typedef void* AzColorPatternRef; +typedef void* AzScaledFontRef; +typedef void* AzGlyphRenderingOptionsRef; +typedef void* AzSourceSurfaceRef; +typedef void* AzDrawSurfaceOptionsRef; +typedef void* AzDataSourceSurfaceRef; +typedef void* AzGLContextMetadataRef; +typedef void* AzPathBuilderRef; +typedef void* AzPathRef; +typedef void* AzLinearGradientPatternRef; /* Types.h */ @@ -281,29 +299,10 @@ typedef struct _AzNativeFont { void *mFont; } AzNativeFont; -typedef void* AzGradientStopsRef; -typedef void* AzSkiaSharedGLContextRef; -typedef void* AzSkiaSharedGrGLContextRef; -typedef void* AzSkiaGrContextRef; -typedef void* AzSkiaGrGLSharedSurfaceRef; -typedef void* AzSkiaGrGLSharedContextRef; -typedef void* AzDrawTargetRef; -typedef void* AzPatternRef; -typedef void* AzColorPatternRef; -typedef void* AzScaledFontRef; -typedef void* AzGlyphRenderingOptionsRef; -typedef void* AzSourceSurfaceRef; -typedef void* AzDrawSurfaceOptionsRef; -typedef void* AzDataSourceSurfaceRef; -typedef void* AzGLContextMetadataRef; -typedef void* AzPathBuilderRef; -typedef void* AzPathRef; - typedef GrGLSharedContext AzGLContext; typedef GrGLNativeContext* AzGLNativeContextRef; AzColorPatternRef AzCreateColorPattern(AzColor *aColor); -void AzReleaseColorPattern(AzColorPatternRef aColorPattern); AzSkiaSharedGLContextRef AzCreateSkiaSharedGLContext(AzGLNativeContextRef aNativeContext, AzIntSize *aSize); @@ -343,11 +342,11 @@ void AzDrawTargetStrokeRect(AzDrawTargetRef aDrawTarget, AzStrokeOptions *aStrokeOptions, AzDrawOptions *aDrawOptions); void AzDrawTargetStrokeLine(AzDrawTargetRef aDrawTarget, - AzPoint *aStart, - AzPoint *aEnd, - AzPatternRef aPattern, - AzStrokeOptions *aStrokeOptions, - AzDrawOptions *aDrawOptions); + AzPoint *aStart, + AzPoint *aEnd, + AzPatternRef aPattern, + AzStrokeOptions *aStrokeOptions, + AzDrawOptions *aDrawOptions); void AzDrawTargetFillGlyphs(AzDrawTargetRef aDrawTarget, AzScaledFontRef aFont, AzGlyphBuffer *aGlyphBuffer, @@ -366,6 +365,11 @@ AzSourceSurfaceRef AzDrawTargetCreateSourceSurfaceFromData(AzDrawTargetRef aDraw AzIntSize *aSize, int32_t aStride, AzSurfaceFormat aFormat); +AzGradientStopsRef AzDrawTargetCreateGradientStops(AzDrawTargetRef aDrawTarget, + AzGradientStop *aStops, + uint32_t aNumStops, + AzExtendMode aExtendMode); + void AzReleaseSourceSurface(AzSourceSurfaceRef aSurface); AzIntSize AzSourceSurfaceGetSize(AzSourceSurfaceRef aSurface); AzSurfaceFormat AzSourceSurfaceGetFormat(AzSourceSurfaceRef aSurface); @@ -385,6 +389,14 @@ void AzPathBuilderArc(AzPathBuilderRef aPathBuilder, bool aAntiClockwise); AzPathRef AzPathBuilderFinish(AzPathBuilderRef aPathBuilder); +AzLinearGradientPatternRef AzCreateLinearGradientPattern(const AzPoint *aBegin, + const AzPoint *aEnd, + AzGradientStopsRef aStops, + const AzMatrix *aMatrix); +void AzReleasePattern(AzPatternRef aPattern); + +void AzReleaseGradientStops(AzGradientStopsRef aStops); + /* Factory.h */ void AzReleaseScaledFont(AzScaledFontRef aFont); diff --git a/src/azure.rs b/src/azure.rs index c31cf47..0b77920 100644 --- a/src/azure.rs +++ b/src/azure.rs @@ -4,7 +4,7 @@ /* automatically generated by rust-bindgen */ -#![allow(non_uppercase_statics, non_camel_case_types)] +#![allow(non_uppercase_statics, non_camel_case_types, non_snake_case)] use libc::*; @@ -147,6 +147,8 @@ pub static AZ_eSideRight: u32 = 1_u32; pub static AZ_eSideBottom: u32 = 2_u32; pub static AZ_eSideLeft: u32 = 3_u32; +#[repr(C)] +#[deriving(Clone)] pub struct struct__AzColor { pub r: AzFloat, pub g: AzFloat, @@ -156,11 +158,13 @@ pub struct struct__AzColor { pub type AzColor = struct__AzColor; +#[repr(C)] pub struct struct__AzGradientStop { pub offset: AzFloat, pub color: AzColor, } +#[repr(C)] pub type AzGradientStop = struct__AzGradientStop; pub struct struct__AzIntRect { @@ -172,6 +176,7 @@ pub struct struct__AzIntRect { pub type AzIntRect = struct__AzIntRect; +#[repr(C)] pub struct struct__AzRect { pub x: AzFloat, pub y: AzFloat, @@ -188,6 +193,7 @@ pub struct struct__AzIntPoint { pub type AzIntPoint = struct__AzIntPoint; +#[repr(C)] pub struct struct__AzPoint { pub x: AzFloat, pub y: AzFloat, @@ -195,6 +201,7 @@ pub struct struct__AzPoint { pub type AzPoint = struct__AzPoint; +#[repr(C)] pub struct struct__AzIntSize { pub width: int32_t, pub height: int32_t, @@ -202,6 +209,7 @@ pub struct struct__AzIntSize { pub type AzIntSize = struct__AzIntSize; +#[repr(C)] pub struct struct__AzSize { pub width: AzFloat, pub height: AzFloat, @@ -209,6 +217,7 @@ pub struct struct__AzSize { pub type AzSize = struct__AzSize; +#[repr(C)] pub struct struct__AzMatrix { _11: AzFloat, _12: AzFloat, @@ -220,6 +229,7 @@ pub struct struct__AzMatrix { pub type AzMatrix = struct__AzMatrix; +#[repr(C)] pub struct struct__AzDrawOptions { pub mAlpha: AzFloat, pub fields: uint16_t, @@ -227,6 +237,7 @@ pub struct struct__AzDrawOptions { pub type AzDrawOptions = struct__AzDrawOptions; +#[repr(C)] pub struct struct__AzStrokeOptions { pub mLineWidth: AzFloat, pub mMiterLimit: AzFloat, @@ -238,26 +249,33 @@ pub struct struct__AzStrokeOptions { pub type AzStrokeOptions = struct__AzStrokeOptions; +#[repr(C)] pub struct struct__AzDrawSurfaceOptions { pub fields: uint32_t, } +#[repr(C)] pub type AzDrawSurfaceOptions = struct__AzDrawSurfaceOptions; +#[repr(C)] pub struct struct__AzGlyph { pub mIndex: uint32_t, pub mPosition: AzPoint, } +#[repr(C)] pub type AzGlyph = struct__AzGlyph; +#[repr(C)] pub struct struct__AzGlyphBuffer { pub mGlyphs: *mut AzGlyph, pub mNumGlyphs: uint32_t, } +#[repr(C)] pub type AzGlyphBuffer = struct__AzGlyphBuffer; +#[repr(C)] pub struct struct__AzNativeFont { pub mType: enum_AzNativeFontType, pub mFont: *mut c_void, @@ -281,6 +299,8 @@ pub type AzPatternRef = *mut c_void; pub type AzColorPatternRef = *mut c_void; +pub type AzLinearGradientPatternRef = *mut c_void; + pub type AzScaledFontRef = *mut c_void; pub type AzGlyphRenderingOptionsRef = *mut c_void; @@ -289,6 +309,7 @@ pub type AzSourceSurfaceRef = *mut c_void; pub type AzDataSourceSurfaceRef = *mut c_void; +#[repr(C)] pub type AzDrawSurfaceOptionsRef = *mut AzDrawSurfaceOptions; pub type AzGLContext = *mut c_void; @@ -303,6 +324,8 @@ pub type AzPathRef = *mut c_void; pub type AzPathBuilderRef = *mut c_void; +pub type AzExtendMode = i32; + #[link(name = "azure")] extern { @@ -310,7 +333,7 @@ pub fn AzSanityCheck(/* FIXME: variadic function */); pub fn AzCreateColorPattern(aColor: *mut AzColor) -> AzColorPatternRef; -pub fn AzReleaseColorPattern(aColorPattern: AzColorPatternRef); +pub fn AzReleasePattern(aPattern: AzPatternRef); pub fn AzCreateSkiaSharedGLContext(aNativeContext: AzGLNativeContextRef, aSize: *mut AzIntSize) -> AzSkiaSharedGLContextRef; @@ -368,6 +391,18 @@ pub fn AzDrawTargetGetSnapshot(aDrawTarget: AzDrawTargetRef) -> AzSourceSurfaceR pub fn AzDrawTargetCreateSourceSurfaceFromData(aDrawTarget: AzDrawTargetRef, aData: *const u8, aSize: *mut AzIntSize, aStride: i32, aFormat: AzSurfaceFormat) -> AzSourceSurfaceRef; +pub fn AzDrawTargetCreateGradientStops(aDrawTarget: AzDrawTargetRef, + aStops: *const AzGradientStop, + aNumStops: u32, + aExtendMode: AzExtendMode) + -> AzGradientStopsRef; + +pub fn AzCreateLinearGradientPattern(aBegin: *const AzPoint, + aEnd: *const AzPoint, + aStops: AzGradientStopsRef, + aMatrix: *const AzMatrix) + -> AzLinearGradientPatternRef; + pub fn AzReleaseSourceSurface(aSurface: AzSourceSurfaceRef); pub fn AzSourceSurfaceGetSize(aSurface: AzSourceSurfaceRef) -> AzIntSize; @@ -413,4 +448,6 @@ pub fn AzPathBuilderFinish(aPathBuilder: AzPathBuilderRef) -> AzPathRef; pub fn AzReleasePath(aPath: AzPathRef); +pub fn AzReleaseGradientStops(aFont: AzScaledFontRef); + } diff --git a/src/azure_hl.rs b/src/azure_hl.rs index 8d6da94..3c7a455 100644 --- a/src/azure_hl.rs +++ b/src/azure_hl.rs @@ -5,10 +5,10 @@ //! High-level bindings to Azure. use azure::{AZ_CAP_BUTT, AZ_JOIN_MITER_OR_BEVEL}; -use azure::{AzPoint, AzRect, AzFloat, AzIntSize, AzColor, AzColorPatternRef}; +use azure::{AzPoint, AzRect, AzFloat, AzIntSize, AzColor, AzColorPatternRef, AzGradientStopsRef}; use azure::{AzStrokeOptions, AzDrawOptions, AzSurfaceFormat, AzFilter, AzDrawSurfaceOptions}; use azure::{AzBackendType, AzDrawTargetRef, AzSourceSurfaceRef, AzDataSourceSurfaceRef}; -use azure::{AzScaledFontRef, AzGlyphRenderingOptionsRef}; +use azure::{AzScaledFontRef, AzGlyphRenderingOptionsRef, AzExtendMode, AzGradientStop}; use azure::{struct__AzColor, struct__AzGlyphBuffer}; use azure::{struct__AzDrawOptions, struct__AzDrawSurfaceOptions, struct__AzIntSize}; use azure::{struct__AzPoint, struct__AzRect, struct__AzStrokeOptions}; @@ -21,7 +21,8 @@ use azure::{AzReleaseSkiaSharedGLContext, AzRetainSkiaSharedGLContext}; use azure::{AzDrawTargetDrawSurface, AzDrawTargetFillRect, AzDrawTargetFlush}; use azure::{AzDrawTargetGetSize, AzDrawTargetGetSnapshot, AzDrawTargetSetTransform}; use azure::{AzDrawTargetStrokeLine, AzDrawTargetStrokeRect, AzDrawTargetFillGlyphs}; -use azure::{AzReleaseColorPattern, AzReleaseDrawTarget}; +use azure::{AzDrawTargetCreateGradientStops}; +use azure::{AzReleaseDrawTarget, AzReleasePattern, AzReleaseGradientStops}; use azure::{AzReleaseSourceSurface, AzRetainDrawTarget}; use azure::{AzSourceSurfaceGetDataSurface, AzSourceSurfaceGetFormat}; use azure::{AzSourceSurfaceGetSize, AzCreateSkiaDrawTargetForFBO, AzSkiaGetCurrentGLContext}; @@ -30,7 +31,8 @@ use azure::{AzSkiaSharedGLContextFlush, AzSkiaGrGLSharedSurfaceRef}; use azure::{AzCreatePathBuilder, AzPathBuilderRef, AzPathBuilderMoveTo, AzPathBuilderLineTo}; use azure::{AzPathBuilderArc, AzPathBuilderFinish, AzReleasePathBuilder}; use azure::{AzDrawTargetFill, AzPathRef, AzReleasePath, AzDrawTargetPushClip, AzDrawTargetPopClip}; -use azure::AzGLNativeContextRef; +use azure::{AzGLNativeContextRef, AzLinearGradientPatternRef, AzMatrix, AzPatternRef}; +use azure::{AzCreateLinearGradientPattern}; use sync::Arc; use geom::matrix2d::Matrix2D; @@ -115,7 +117,7 @@ pub struct ColorPattern { impl Drop for ColorPattern { fn drop(&mut self) { unsafe { - AzReleaseColorPattern(self.azure_color_pattern); + AzReleasePattern(self.azure_color_pattern); } } } @@ -481,7 +483,7 @@ impl DrawTarget { pub fn fill_rect(&self, rect: &Rect, - pattern: &ColorPattern, + pattern: PatternRef, draw_options: Option<&DrawOptions>) { let mut draw_options = draw_options.map(|draw_options| { draw_options.as_azure_draw_options() @@ -493,7 +495,7 @@ impl DrawTarget { unsafe { AzDrawTargetFillRect(self.azure_draw_target, &mut rect.as_azure_rect(), - pattern.azure_color_pattern, + pattern.as_azure_pattern(), draw_options); } } @@ -552,11 +554,11 @@ impl DrawTarget { } pub fn create_source_surface_from_data(&self, - data: &[u8], - size: Size2D, - stride: i32, - format: SurfaceFormat) - -> SourceSurface { + data: &[u8], + size: Size2D, + stride: i32, + format: SurfaceFormat) + -> SourceSurface { assert!(data.len() as i32 == stride * size.height); unsafe { let azure_surface = AzDrawTargetCreateSourceSurfaceFromData( @@ -569,6 +571,19 @@ impl DrawTarget { } } + pub fn create_gradient_stops(&self, + gradient_stops: &[GradientStop], + extend_mode: ExtendMode) + -> GradientStops { + unsafe { + GradientStops::new(AzDrawTargetCreateGradientStops( + self.azure_draw_target, + mem::transmute::<_,*const AzGradientStop>(&gradient_stops[0]), + gradient_stops.len() as u32, + extend_mode.as_azure_extend_mode())) + } + } + pub fn set_transform(&self, matrix: &Matrix2D) { unsafe { AzDrawTargetSetTransform(self.azure_draw_target, mem::transmute(matrix)); @@ -638,6 +653,47 @@ impl SourceSurface { } } +pub struct GradientStops { + pub azure_gradient_stops: AzGradientStopsRef, +} + +impl Drop for GradientStops { + fn drop(&mut self) { + unsafe { + AzReleaseGradientStops(self.azure_gradient_stops); + } + } +} + +impl GradientStops { + pub fn new(azure_gradient_stops: AzGradientStopsRef) -> GradientStops { + GradientStops { + azure_gradient_stops: azure_gradient_stops, + } + } +} + +#[repr(C)] +#[deriving(Clone)] +pub struct GradientStop { + pub offset: AzFloat, + pub color: Color, +} + +#[repr(i32)] +#[deriving(Clone, PartialEq)] +pub enum ExtendMode { + ExtendClamp = 0, + ExtendRepeat = 1, + ExtendReflect = 2, +} + +impl ExtendMode { + fn as_azure_extend_mode(self) -> AzExtendMode { + self as AzExtendMode + } +} + // FIXME Rust #8753 no fixed stack segment for default methods unsafe fn AzSourceSurfaceGetSize_(aSurface: AzSourceSurfaceRef) -> AzIntSize { AzSourceSurfaceGetSize(aSurface) @@ -784,6 +840,52 @@ impl Drop for PathBuilder { } } +pub struct LinearGradientPattern { + pub azure_linear_gradient_pattern: AzLinearGradientPatternRef, +} + +impl Drop for LinearGradientPattern { + fn drop(&mut self) { + unsafe { + AzReleasePattern(self.azure_linear_gradient_pattern); + } + } +} + +impl LinearGradientPattern { + pub fn new(begin: &Point2D, + end: &Point2D, + stops: GradientStops, + matrix: &Matrix2D) + -> LinearGradientPattern { + unsafe { + LinearGradientPattern { + azure_linear_gradient_pattern: + AzCreateLinearGradientPattern(mem::transmute::<_,*const AzPoint>(begin), + mem::transmute::<_,*const AzPoint>(end), + stops.azure_gradient_stops, + mem::transmute::<_,*const AzMatrix>(matrix)), + } + } + } +} + +pub enum PatternRef<'a> { + ColorPatternRef(&'a ColorPattern), + LinearGradientPatternRef(&'a LinearGradientPattern), +} + +impl<'a> PatternRef<'a> { + fn as_azure_pattern(&self) -> AzPatternRef { + match *self { + ColorPatternRef(color_pattern) => color_pattern.azure_color_pattern, + LinearGradientPatternRef(linear_gradient_pattern) => { + linear_gradient_pattern.azure_linear_gradient_pattern + } + } + } +} + pub fn current_gl_context() -> AzGLContext { unsafe { AzSkiaGetCurrentGLContext() diff --git a/src/lib.rs b/src/lib.rs index e8acf3b..8784e5c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,6 @@ #![feature(globs)] -#![allow(non_snake_case_functions)] - extern crate libc; extern crate sync; extern crate geom; @@ -71,7 +69,7 @@ pub use azure::{AzFontOptions, AzFloat, enum_AzSurfaceType, AZ_SURFACE_DATA, AzGlyphRenderingOptionsRef, AzSourceSurfaceRef, AzDataSourceSurfaceRef, AzDrawSurfaceOptionsRef, AzGLContext, AzSkiaGrGLSharedContextRef, AzGLContextMetadataRef, AzGLNativeContextRef, AzPathRef, AzPathBuilderRef, AzSanityCheck, AzCreateColorPattern, - AzReleaseColorPattern, AzCreateSkiaSharedGLContext, AzRetainSkiaSharedGLContext, AzReleaseSkiaSharedGLContext, + AzCreateSkiaSharedGLContext, AzRetainSkiaSharedGLContext, AzReleaseSkiaSharedGLContext, AzSkiaSharedGLContextGetFBOID, AzSkiaSharedGLContextStealSurface, AzSkiaSharedGLContextGetGrContext, AzSkiaSharedGLContextMakeCurrent, AzSkiaSharedGLContextFlush, AzCreateDrawTarget, AzCreateDrawTargetForData, AzCreateSkiaDrawTargetForFBO, AzRetainDrawTarget, AzReleaseDrawTarget, AzDrawTargetGetSize, AzDrawTargetFlush,