parent
0bf0f58fa4
commit
2b69ff778f
|
@ -24,6 +24,7 @@ use std::mem;
|
||||||
pub struct Gradient {
|
pub struct Gradient {
|
||||||
pub geometry: GradientGeometry,
|
pub geometry: GradientGeometry,
|
||||||
stops: Vec<ColorStop>,
|
stops: Vec<ColorStop>,
|
||||||
|
pub wrap: GradientWrap,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
@ -49,6 +50,12 @@ pub enum GradientGeometry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub enum GradientWrap {
|
||||||
|
Clamp,
|
||||||
|
Repeat,
|
||||||
|
}
|
||||||
|
|
||||||
impl Eq for Gradient {}
|
impl Eq for Gradient {}
|
||||||
|
|
||||||
impl Hash for Gradient {
|
impl Hash for Gradient {
|
||||||
|
@ -90,7 +97,11 @@ impl Hash for ColorStop {
|
||||||
impl Gradient {
|
impl Gradient {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn linear(line: LineSegment2F) -> Gradient {
|
pub fn linear(line: LineSegment2F) -> Gradient {
|
||||||
Gradient { geometry: GradientGeometry::Linear(line), stops: Vec::new() }
|
Gradient {
|
||||||
|
geometry: GradientGeometry::Linear(line),
|
||||||
|
stops: Vec::new(),
|
||||||
|
wrap: GradientWrap::Clamp,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -104,6 +115,7 @@ impl Gradient {
|
||||||
Gradient {
|
Gradient {
|
||||||
geometry: GradientGeometry::Radial { line: line.to_line(), radii, transform },
|
geometry: GradientGeometry::Radial { line: line.to_line(), radii, transform },
|
||||||
stops: Vec::new(),
|
stops: Vec::new(),
|
||||||
|
wrap: GradientWrap::Clamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use crate::allocator::{AllocationMode, TextureAllocator};
|
use crate::allocator::{AllocationMode, TextureAllocator};
|
||||||
use crate::gpu_data::{ColorCombineMode, RenderCommand, TextureLocation, TextureMetadataEntry, TexturePageDescriptor};
|
use crate::gpu_data::{ColorCombineMode, RenderCommand, TextureLocation, TextureMetadataEntry};
|
||||||
use crate::gpu_data::{TexturePageId, TileBatchTexture};
|
use crate::gpu_data::{TexturePageDescriptor, TexturePageId, TileBatchTexture};
|
||||||
use crate::scene::{RenderTarget, SceneId};
|
use crate::scene::{RenderTarget, SceneId};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_content::effects::{BlendMode, Filter, PatternFilter};
|
use pathfinder_content::effects::{BlendMode, Filter, PatternFilter};
|
||||||
use pathfinder_content::gradient::{Gradient, GradientGeometry};
|
use pathfinder_content::gradient::{Gradient, GradientGeometry, GradientWrap};
|
||||||
use pathfinder_content::pattern::{Pattern, PatternSource};
|
use pathfinder_content::pattern::{Pattern, PatternSource};
|
||||||
use pathfinder_content::render_target::RenderTargetId;
|
use pathfinder_content::render_target::RenderTargetId;
|
||||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||||
|
@ -368,12 +368,20 @@ impl Palette {
|
||||||
let color_texture_metadata = paint.overlay.as_ref().map(|overlay| {
|
let color_texture_metadata = paint.overlay.as_ref().map(|overlay| {
|
||||||
match overlay.contents {
|
match overlay.contents {
|
||||||
PaintContents::Gradient(ref gradient) => {
|
PaintContents::Gradient(ref gradient) => {
|
||||||
|
let mut sampling_flags = TextureSamplingFlags::empty();
|
||||||
|
match gradient.wrap {
|
||||||
|
GradientWrap::Repeat => {
|
||||||
|
sampling_flags.insert(TextureSamplingFlags::REPEAT_U);
|
||||||
|
}
|
||||||
|
GradientWrap::Clamp => {}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME(pcwalton): The gradient size might not be big enough. Detect this.
|
// FIXME(pcwalton): The gradient size might not be big enough. Detect this.
|
||||||
let location = gradient_tile_builder.allocate(allocator, gradient);
|
let location = gradient_tile_builder.allocate(allocator, gradient);
|
||||||
PaintColorTextureMetadata {
|
PaintColorTextureMetadata {
|
||||||
location,
|
location,
|
||||||
page_scale: allocator.page_scale(location.page),
|
page_scale: allocator.page_scale(location.page),
|
||||||
sampling_flags: TextureSamplingFlags::empty(),
|
sampling_flags,
|
||||||
filter: match gradient.geometry {
|
filter: match gradient.geometry {
|
||||||
GradientGeometry::Linear(_) => PaintFilter::None,
|
GradientGeometry::Linear(_) => PaintFilter::None,
|
||||||
GradientGeometry::Radial { line, radii, .. } => {
|
GradientGeometry::Radial { line, radii, .. } => {
|
||||||
|
|
|
@ -17,7 +17,7 @@ use hashbrown::HashMap;
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_content::dash::OutlineDash;
|
use pathfinder_content::dash::OutlineDash;
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::gradient::{ColorStop, Gradient};
|
use pathfinder_content::gradient::{ColorStop, Gradient, GradientWrap};
|
||||||
use pathfinder_content::outline::Outline;
|
use pathfinder_content::outline::Outline;
|
||||||
use pathfinder_content::segment::{Segment, SegmentFlags};
|
use pathfinder_content::segment::{Segment, SegmentFlags};
|
||||||
use pathfinder_content::stroke::{LineCap, LineJoin, OutlineStrokeToFill, StrokeStyle};
|
use pathfinder_content::stroke::{LineCap, LineJoin, OutlineStrokeToFill, StrokeStyle};
|
||||||
|
@ -56,7 +56,6 @@ bitflags! {
|
||||||
const UNSUPPORTED_LINK_PAINT = 0x0020;
|
const UNSUPPORTED_LINK_PAINT = 0x0020;
|
||||||
const UNSUPPORTED_FILTER_ATTR = 0x0040;
|
const UNSUPPORTED_FILTER_ATTR = 0x0040;
|
||||||
const UNSUPPORTED_MASK_ATTR = 0x0080;
|
const UNSUPPORTED_MASK_ATTR = 0x0080;
|
||||||
const UNSUPPORTED_GRADIENT_SPREAD_METHOD = 0x0100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,11 +236,27 @@ impl SVGScene {
|
||||||
id: String,
|
id: String,
|
||||||
usvg_base_gradient: &BaseGradient) {
|
usvg_base_gradient: &BaseGradient) {
|
||||||
for stop in &usvg_base_gradient.stops {
|
for stop in &usvg_base_gradient.stops {
|
||||||
gradient.add(ColorStop::from_usvg_stop(stop));
|
let mut stop = ColorStop::from_usvg_stop(stop);
|
||||||
|
if usvg_base_gradient.spread_method == SpreadMethod::Reflect {
|
||||||
|
stop.offset *= 0.5;
|
||||||
|
}
|
||||||
|
gradient.add(stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if usvg_base_gradient.spread_method != SpreadMethod::Pad {
|
// Reflect gradient if necessary.
|
||||||
self.result_flags.insert(BuildResultFlags::UNSUPPORTED_GRADIENT_SPREAD_METHOD);
|
if usvg_base_gradient.spread_method == SpreadMethod::Reflect {
|
||||||
|
for stop in &usvg_base_gradient.stops {
|
||||||
|
let mut stop = ColorStop::from_usvg_stop(stop);
|
||||||
|
if usvg_base_gradient.spread_method == SpreadMethod::Reflect {
|
||||||
|
stop.offset = 1.0 - stop.offset * 0.5;
|
||||||
|
}
|
||||||
|
gradient.add(stop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match usvg_base_gradient.spread_method {
|
||||||
|
SpreadMethod::Pad => {}
|
||||||
|
SpreadMethod::Reflect | SpreadMethod::Repeat => gradient.wrap = GradientWrap::Repeat,
|
||||||
}
|
}
|
||||||
|
|
||||||
let transform = usvg_transform_to_transform_2d(&usvg_base_gradient.transform);
|
let transform = usvg_transform_to_transform_2d(&usvg_base_gradient.transform);
|
||||||
|
@ -304,7 +319,6 @@ impl Display for BuildResultFlags {
|
||||||
"non-color paint",
|
"non-color paint",
|
||||||
"filter attribute",
|
"filter attribute",
|
||||||
"mask attribute",
|
"mask attribute",
|
||||||
"gradient spread method",
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue