Auto merge of #396 - pcwalton:docs-content, r=pcwalton
Document `pathfinder_content` more
This commit is contained in:
commit
38252f8314
|
@ -8,6 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Clips polygons.
|
||||
|
||||
#![allow(deprecated)]
|
||||
|
||||
use crate::outline::{Contour, ContourIterFlags, PointFlags, PushSegmentFlags};
|
||||
use crate::segment::{CubicSegment, Segment};
|
||||
use arrayvec::ArrayVec;
|
||||
|
@ -310,16 +314,25 @@ enum EdgeRelativeLocation {
|
|||
|
||||
// 3D quad clipping
|
||||
|
||||
/// Clips polygons in 3D homogeneous coordinates against the (-1, 1) normalized device coordinate
|
||||
/// cube.
|
||||
#[deprecated]
|
||||
pub struct PolygonClipper3D {
|
||||
subject: Vec<Vector4F>,
|
||||
}
|
||||
|
||||
impl PolygonClipper3D {
|
||||
/// Creates a new polygon clipper with the vertices of the given polygon-to-be-clipped, in 3D
|
||||
/// homogeneous coordinates.
|
||||
#[deprecated]
|
||||
#[inline]
|
||||
pub fn new(subject: Vec<Vector4F>) -> PolygonClipper3D {
|
||||
PolygonClipper3D { subject }
|
||||
}
|
||||
|
||||
/// Clips the subject polygon against the (-1, 1) normalized device coordinate cube and returns
|
||||
/// the resulting vertices, in 3D homogeneous coordinates.
|
||||
#[deprecated]
|
||||
pub fn clip(mut self) -> Vec<Vector4F> {
|
||||
// TODO(pcwalton): Fast path for completely contained polygon?
|
||||
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Line dashing support.
|
||||
//! Transforms a stroke into a dashed stroke.
|
||||
|
||||
use crate::outline::{Contour, ContourIterFlags, Outline, PushSegmentFlags};
|
||||
use std::mem;
|
||||
|
||||
const EPSILON: f32 = 0.0001;
|
||||
|
||||
/// Transforms a stroke into a dashed stroke.
|
||||
pub struct OutlineDash<'a> {
|
||||
input: &'a Outline,
|
||||
output: Outline,
|
||||
|
@ -22,17 +23,34 @@ pub struct OutlineDash<'a> {
|
|||
}
|
||||
|
||||
impl<'a> OutlineDash<'a> {
|
||||
/// Creates a new outline dasher for the given stroke.
|
||||
///
|
||||
/// Arguments:
|
||||
///
|
||||
/// * `input`: The input stroke to be dashed. This must not yet been converted to a fill; i.e.
|
||||
/// it is assumed that the stroke-to-fill conversion happens *after* this dashing process.
|
||||
///
|
||||
/// * `dashes`: The list of dashes, specified as alternating pixel lengths of lines and gaps
|
||||
/// that describe the pattern. See
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash.
|
||||
///
|
||||
/// * `offset`: The line dash offset, or "phase". See
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset.
|
||||
#[inline]
|
||||
pub fn new(input: &'a Outline, dashes: &'a [f32], offset: f32) -> OutlineDash<'a> {
|
||||
OutlineDash { input, output: Outline::new(), state: DashState::new(dashes, offset) }
|
||||
}
|
||||
|
||||
/// Performs the dashing operation.
|
||||
///
|
||||
/// The results can be retrieved with the `into_outline()` method.
|
||||
pub fn dash(&mut self) {
|
||||
for contour in &self.input.contours {
|
||||
ContourDash::new(contour, &mut self.output, &mut self.state).dash()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the resulting dashed outline.
|
||||
pub fn into_outline(mut self) -> Outline {
|
||||
if self.state.is_on() {
|
||||
self.output.push_contour(self.state.output);
|
||||
|
|
|
@ -15,20 +15,28 @@ use pathfinder_geometry::line_segment::LineSegment2F;
|
|||
use pathfinder_geometry::vector::Vector2F;
|
||||
use pathfinder_simd::default::F32x2;
|
||||
|
||||
/// This intentionally does not precisely match what Core Graphics does (a
|
||||
/// Lanczos function), because we don't want any ringing artefacts.
|
||||
/// A defringing kernel for LCD screens that approximates the macOS/iOS look.
|
||||
///
|
||||
/// This intentionally does not precisely match what Core Graphics does (a Lanczos function),
|
||||
/// because we don't want any ringing artefacts.
|
||||
pub static DEFRINGING_KERNEL_CORE_GRAPHICS: DefringingKernel =
|
||||
DefringingKernel([0.033165660, 0.102074051, 0.221434336, 0.286651906]);
|
||||
|
||||
/// A defringing kernel for LCD screens that approximates the FreeType look.
|
||||
pub static DEFRINGING_KERNEL_FREETYPE: DefringingKernel =
|
||||
DefringingKernel([0.0, 0.031372549, 0.301960784, 0.337254902]);
|
||||
|
||||
/// Stem darkening factors that approximate the macOS look.
|
||||
///
|
||||
/// Should match macOS 10.13 High Sierra.
|
||||
pub static STEM_DARKENING_FACTORS: [f32; 2] = [0.0121, 0.0121 * 1.25];
|
||||
|
||||
/// The maximum number of pixels we are willing to expand outlines by to match the macOS look.
|
||||
///
|
||||
/// Should match macOS 10.13 High Sierra.
|
||||
pub const MAX_STEM_DARKENING_AMOUNT: [f32; 2] = [0.3, 0.3];
|
||||
|
||||
/// This value is a subjective cutoff. Above this ppem value, no stem darkening is performed.
|
||||
/// A subjective cutoff. Above this ppem value, no stem darkening is performed.
|
||||
pub const MAX_STEM_DARKENING_PIXELS_PER_EM: f32 = 72.0;
|
||||
|
||||
/// The shader that should be used when compositing this layer onto its destination.
|
||||
|
|
|
@ -8,10 +8,16 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Fill rules.
|
||||
//! The fill rule, which determines how self-intersecting paths are filled.
|
||||
|
||||
/// The fill rule, which determines how self-intersecting paths are filled.
|
||||
///
|
||||
/// Paths that don't intersect themselves (and have no holes) are unaffected by the choice of fill
|
||||
/// rule.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum FillRule {
|
||||
/// The nonzero rule: https://en.wikipedia.org/wiki/Nonzero-rule
|
||||
Winding,
|
||||
/// The even-odd rule: https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
|
||||
EvenOdd,
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Gradient effects that paths can be filled with.
|
||||
|
||||
use crate::util;
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||
|
|
|
@ -33,6 +33,7 @@ pub struct Pattern {
|
|||
flags: PatternFlags,
|
||||
}
|
||||
|
||||
/// Where a raster image pattern comes from.
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum PatternSource {
|
||||
Image(Image),
|
||||
|
@ -42,9 +43,10 @@ pub enum PatternSource {
|
|||
}
|
||||
}
|
||||
|
||||
/// RGBA, non-premultiplied.
|
||||
/// A raster image, in 32-bit RGBA (8 bits per channel), non-premultiplied form.
|
||||
// FIXME(pcwalton): Hash the pixel contents so that we don't have to compare every pixel!
|
||||
// TODO(pcwalton): Should the pixels be premultiplied?
|
||||
// TODO(pcwalton): Color spaces.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Image {
|
||||
size: Vector2I,
|
||||
|
@ -58,9 +60,15 @@ pub struct Image {
|
|||
pub struct ImageHash(pub u64);
|
||||
|
||||
bitflags! {
|
||||
/// Various flags that determine behavior of a pattern.
|
||||
pub struct PatternFlags: u8 {
|
||||
/// If set, the pattern repeats in the X direction. If unset, the base color is used.
|
||||
const REPEAT_X = 0x01;
|
||||
/// If set, the pattern repeats in the Y direction. If unset, the base color is used.
|
||||
const REPEAT_Y = 0x02;
|
||||
/// If set, nearest-neighbor interpolation is used when compositing this pattern (i.e. the
|
||||
/// image will be pixelated). If unset, bilinear interpolation is used when compositing
|
||||
/// this pattern (i.e. the image will be smooth).
|
||||
const NO_SMOOTHING = 0x04;
|
||||
}
|
||||
}
|
||||
|
@ -76,26 +84,37 @@ impl Pattern {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new pattern from the given image.
|
||||
///
|
||||
/// The transform is initialized to the identity transform. There is no filter.
|
||||
#[inline]
|
||||
pub fn from_image(image: Image) -> Pattern {
|
||||
Pattern::from_source(PatternSource::Image(image))
|
||||
}
|
||||
|
||||
/// Creates a new pattern from the given render target with the given size.
|
||||
///
|
||||
/// The transform is initialized to the identity transform. There is no filter.
|
||||
#[inline]
|
||||
pub fn from_render_target(id: RenderTargetId, size: Vector2I) -> Pattern {
|
||||
Pattern::from_source(PatternSource::RenderTarget { id, size })
|
||||
}
|
||||
|
||||
/// Returns the affine transform applied to this pattern.
|
||||
#[inline]
|
||||
pub fn transform(&self) -> Transform2F {
|
||||
self.transform
|
||||
}
|
||||
|
||||
/// Applies the given transform to this pattern.
|
||||
///
|
||||
/// The transform is applied after any existing transform.
|
||||
#[inline]
|
||||
pub fn apply_transform(&mut self, transform: Transform2F) {
|
||||
self.transform = transform * self.transform;
|
||||
}
|
||||
|
||||
/// Returns the underlying pixel size of this pattern, not taking transforms into account.
|
||||
#[inline]
|
||||
pub fn size(&self) -> Vector2I {
|
||||
match self.source {
|
||||
|
@ -104,51 +123,72 @@ impl Pattern {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the filter attached to this pattern, if any.
|
||||
#[inline]
|
||||
pub fn filter(&self) -> Option<PatternFilter> {
|
||||
self.filter
|
||||
}
|
||||
|
||||
/// Applies a filter to this pattern, replacing any previous filter if any.
|
||||
#[inline]
|
||||
pub fn set_filter(&mut self, filter: Option<PatternFilter>) {
|
||||
self.filter = filter;
|
||||
}
|
||||
|
||||
/// Returns true if this pattern repeats in the X direction or false if the base color will be
|
||||
/// used when sampling beyond the coordinates of the image.
|
||||
#[inline]
|
||||
pub fn repeat_x(&self) -> bool {
|
||||
self.flags.contains(PatternFlags::REPEAT_X)
|
||||
}
|
||||
|
||||
/// Set to true if the pattern should repeat in the X direction or false if the base color
|
||||
/// should be used when sampling beyond the coordinates of the image.
|
||||
#[inline]
|
||||
pub fn set_repeat_x(&mut self, repeat_x: bool) {
|
||||
self.flags.set(PatternFlags::REPEAT_X, repeat_x);
|
||||
}
|
||||
|
||||
/// Returns true if this pattern repeats in the Y direction or false if the base color will be
|
||||
/// used when sampling beyond the coordinates of the image.
|
||||
#[inline]
|
||||
pub fn repeat_y(&self) -> bool {
|
||||
self.flags.contains(PatternFlags::REPEAT_Y)
|
||||
}
|
||||
|
||||
/// Set to true if the pattern should repeat in the Y direction or false if the base color
|
||||
/// should be used when sampling beyond the coordinates of the image.
|
||||
#[inline]
|
||||
pub fn set_repeat_y(&mut self, repeat_y: bool) {
|
||||
self.flags.set(PatternFlags::REPEAT_Y, repeat_y);
|
||||
}
|
||||
|
||||
/// Returns true if this pattern should use bilinear interpolation (i.e. the image will be
|
||||
/// smooth) when scaled or false if this pattern should use nearest-neighbor interpolation
|
||||
/// (i.e. the image will be pixelated).
|
||||
#[inline]
|
||||
pub fn smoothing_enabled(&self) -> bool {
|
||||
!self.flags.contains(PatternFlags::NO_SMOOTHING)
|
||||
}
|
||||
|
||||
/// Set to true if the pattern should use bilinear interpolation (i.e. should be smooth) when
|
||||
/// scaled or false if this pattern should use nearest-neighbor interpolation (i.e. should be
|
||||
/// pixelated).
|
||||
#[inline]
|
||||
pub fn set_smoothing_enabled(&mut self, enable: bool) {
|
||||
self.flags.set(PatternFlags::NO_SMOOTHING, !enable);
|
||||
}
|
||||
|
||||
/// Returns true if this pattern is obviously fully opaque.
|
||||
///
|
||||
/// This is a best-effort quick check, so it might return false even if the image is actually
|
||||
/// opaque.
|
||||
#[inline]
|
||||
pub fn is_opaque(&self) -> bool {
|
||||
self.source.is_opaque()
|
||||
}
|
||||
|
||||
/// Returns the underlying source of the pattern.
|
||||
#[inline]
|
||||
pub fn source(&self) -> &PatternSource {
|
||||
&self.source
|
||||
|
@ -156,6 +196,8 @@ impl Pattern {
|
|||
}
|
||||
|
||||
impl Image {
|
||||
/// Creates a new image with the given device pixel size and pixel store, as 32-bit RGBA (8
|
||||
/// bits per channel), RGBA, linear color space, nonpremultiplied.
|
||||
#[inline]
|
||||
pub fn new(size: Vector2I, pixels: Arc<Vec<ColorU>>) -> Image {
|
||||
assert_eq!(size.x() as usize * size.y() as usize, pixels.len());
|
||||
|
@ -168,6 +210,7 @@ impl Image {
|
|||
Image { size, pixels, pixels_hash, is_opaque }
|
||||
}
|
||||
|
||||
/// A convenience function to create a new image with the given image from the `image` crate.
|
||||
#[cfg(feature = "pf-image")]
|
||||
pub fn from_image_buffer(image_buffer: RgbaImage) -> Image {
|
||||
let (width, height) = image_buffer.dimensions();
|
||||
|
@ -175,21 +218,29 @@ impl Image {
|
|||
Image::new(vec2i(width as i32, height as i32), Arc::new(pixels))
|
||||
}
|
||||
|
||||
/// Returns the device pixel size of the image.
|
||||
#[inline]
|
||||
pub fn size(&self) -> Vector2I {
|
||||
self.size
|
||||
}
|
||||
|
||||
/// Returns the pixel buffer of this image as 32-bit RGBA (8 bits per channel), RGBA, linear
|
||||
/// color space, nonpremultiplied.
|
||||
#[inline]
|
||||
pub fn pixels(&self) -> &Arc<Vec<ColorU>> {
|
||||
&self.pixels
|
||||
}
|
||||
|
||||
/// Returns true if this image is obviously opaque.
|
||||
///
|
||||
/// This is a best-guess quick check, and as such it might return false even if the image is
|
||||
/// fully opaque.
|
||||
#[inline]
|
||||
pub fn is_opaque(&self) -> bool {
|
||||
self.is_opaque
|
||||
}
|
||||
|
||||
/// Returns a non-cryptographic hash of the image, which should be globally unique.
|
||||
#[inline]
|
||||
pub fn get_hash(&self) -> ImageHash {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
|
@ -199,6 +250,10 @@ impl Image {
|
|||
}
|
||||
|
||||
impl PatternSource {
|
||||
/// Returns true if this pattern is obviously opaque.
|
||||
///
|
||||
/// This is a best-guess quick check, and as such it might return false even if the pattern is
|
||||
/// fully opaque.
|
||||
#[inline]
|
||||
pub fn is_opaque(&self) -> bool {
|
||||
match *self {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Line or curve segments, optimized with SIMD.
|
||||
//! Single line or Bézier curve segments, optimized with SIMD.
|
||||
|
||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
|
@ -17,15 +17,26 @@ use pathfinder_geometry::vector::{Vector2F, vec2f};
|
|||
use pathfinder_simd::default::F32x4;
|
||||
use std::f32::consts::SQRT_2;
|
||||
|
||||
/// A single line or Bézier curve segment, with explicit start and end points.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Segment {
|
||||
/// The start and end points of the curve.
|
||||
pub baseline: LineSegment2F,
|
||||
/// The control point or points.
|
||||
///
|
||||
/// If this is a line (which can be determined by examining the segment kind), this field is
|
||||
/// ignored. If this is a quadratic Bézier curve, the start point of this line represents the
|
||||
/// control point, and the endpoint of this line is ignored. Otherwise, if this is a cubic
|
||||
/// Bézier curve, both the start and endpoints are used.
|
||||
pub ctrl: LineSegment2F,
|
||||
/// The type of segment this is: invalid, line, quadratic, or cubic Bézier curve.
|
||||
pub kind: SegmentKind,
|
||||
/// Various flags that describe information about this segment in a path.
|
||||
pub flags: SegmentFlags,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
/// Returns an invalid segment.
|
||||
#[inline]
|
||||
pub fn none() -> Segment {
|
||||
Segment {
|
||||
|
@ -36,6 +47,7 @@ impl Segment {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a segment representing a straight line.
|
||||
#[inline]
|
||||
pub fn line(line: LineSegment2F) -> Segment {
|
||||
Segment {
|
||||
|
@ -226,12 +238,17 @@ impl Segment {
|
|||
}
|
||||
}
|
||||
|
||||
/// The type of line segment this is.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum SegmentKind {
|
||||
/// An invalid segment.
|
||||
None,
|
||||
/// A line segment.
|
||||
Line,
|
||||
/// A quadratic Bézier curve.
|
||||
Quadratic,
|
||||
/// A cubic Bézier curve.
|
||||
Cubic,
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ use pathfinder_geometry::rect::RectF;
|
|||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
use pathfinder_geometry::transform3d::Perspective;
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector4F};
|
||||
|
||||
#[allow(deprecated)]
|
||||
use pathfinder_content::clip::PolygonClipper3D;
|
||||
|
||||
/// A sink for the render commands that scenes build.
|
||||
|
@ -85,6 +87,7 @@ impl Default for RenderTransform {
|
|||
}
|
||||
|
||||
impl RenderTransform {
|
||||
#[allow(deprecated)]
|
||||
fn prepare(&self, bounds: RectF) -> PreparedRenderTransform {
|
||||
let perspective = match self {
|
||||
RenderTransform::Transform2D(ref transform) => {
|
||||
|
|
Loading…
Reference in New Issue