diff options
| author | Martin Haug <mhaug@live.de> | 2022-02-08 21:12:09 +0100 |
|---|---|---|
| committer | Martin Haug <mhaug@live.de> | 2022-02-08 21:12:09 +0100 |
| commit | fe70db1f4ce078f7b41c163a1c0ead31fd04850a (patch) | |
| tree | 0f85390a89a05dc763cbc2eb6c611c48877c08cd /src/export | |
| parent | 62cf2a19d7207118f115c05c8f7c453d6db77a0a (diff) | |
New color stuff
- CMYK function
- More default colors
- Interpret RGB values as sRGB
Diffstat (limited to 'src/export')
| -rw-r--r-- | src/export/pdf.rs | 44 | ||||
| -rw-r--r-- | src/export/render.rs | 8 |
2 files changed, 36 insertions, 16 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs index 19134f99..18bb5385 100644 --- a/src/export/pdf.rs +++ b/src/export/pdf.rs @@ -7,8 +7,10 @@ use std::sync::Arc; use image::{DynamicImage, GenericImageView, ImageFormat, ImageResult, Rgba}; use pdf_writer::types::{ - ActionType, AnnotationType, CidFontType, FontFlags, SystemInfo, UnicodeCmap, + ActionType, AnnotationType, CidFontType, ColorSpaceOperand, FontFlags, SystemInfo, + UnicodeCmap, }; +use pdf_writer::writers::ColorSpace; use pdf_writer::{Content, Filter, Finish, Name, PdfWriter, Rect, Ref, Str, TextStr}; use ttf_parser::{name_id, GlyphId, Tag}; @@ -30,6 +32,9 @@ pub fn pdf(ctx: &Context, frames: &[Arc<Frame>]) -> Vec<u8> { PdfExporter::new(ctx).export(frames) } +/// Identifies the sRGB color space definition. +pub const SRGB: Name<'static> = Name(b"sRGB"); + /// An exporter for a whole PDF document. struct PdfExporter<'a> { fonts: &'a FontStore, @@ -316,6 +321,8 @@ impl<'a> PdfExporter<'a> { pages.count(page_refs.len() as i32).kids(page_refs); let mut resources = pages.resources(); + resources.color_spaces().insert(SRGB).start::<ColorSpace>().srgb(); + let mut fonts = resources.fonts(); for (font_ref, f) in self.face_map.pdf_indices(&self.face_refs) { let name = format_eco!("F{}", f); @@ -390,6 +397,8 @@ impl<'a> PageExporter<'a> { // Make the coordinate system start at the top-left. self.bottom = frame.size.y.to_f32(); self.content.transform([1.0, 0.0, 0.0, -1.0, 0.0, self.bottom]); + self.content.set_fill_color_space(ColorSpaceOperand::Named(SRGB)); + self.content.set_stroke_color_space(ColorSpaceOperand::Named(SRGB)); self.write_frame(frame); Page { size: frame.size, @@ -624,23 +633,32 @@ impl<'a> PageExporter<'a> { fn set_fill(&mut self, fill: Paint) { if self.state.fill != Some(fill) { - let Paint::Solid(Color::Rgba(c)) = fill; - self.content.set_fill_rgb( - c.r as f32 / 255.0, - c.g as f32 / 255.0, - c.b as f32 / 255.0, - ); + let f = |c| c as f32 / 255.0; + let Paint::Solid(color) = fill; + match color { + Color::Rgba(c) => { + self.content.set_fill_color([f(c.r), f(c.g), f(c.b)]); + } + Color::Cmyk(c) => { + self.content.set_fill_cmyk(f(c.c), f(c.m), f(c.y), f(c.k)); + } + } } } fn set_stroke(&mut self, stroke: Stroke) { if self.state.stroke != Some(stroke) { - let Paint::Solid(Color::Rgba(c)) = stroke.paint; - self.content.set_stroke_rgb( - c.r as f32 / 255.0, - c.g as f32 / 255.0, - c.b as f32 / 255.0, - ); + let f = |c| c as f32 / 255.0; + let Paint::Solid(color) = stroke.paint; + match color { + Color::Rgba(c) => { + self.content.set_stroke_color([f(c.r), f(c.g), f(c.b)]); + } + Color::Cmyk(c) => { + self.content.set_stroke_cmyk(f(c.c), f(c.m), f(c.y), f(c.k)); + } + } + self.content.set_line_width(stroke.thickness.to_f32()); } } diff --git a/src/export/render.rs b/src/export/render.rs index c41bcbf2..8b7aa46d 100644 --- a/src/export/render.rs +++ b/src/export/render.rs @@ -10,7 +10,7 @@ use usvg::FitTo; use crate::font::{Face, FaceId}; use crate::frame::{Element, Frame, Geometry, Group, Shape, Stroke, Text}; -use crate::geom::{self, Color, Length, Paint, PathElement, Size, Transform}; +use crate::geom::{self, Length, Paint, PathElement, Size, Transform}; use crate::image::{Image, RasterImage, Svg}; use crate::Context; @@ -279,7 +279,8 @@ fn render_outline_glyph( let bottom = top + mh; // Premultiply the text color. - let Paint::Solid(Color::Rgba(c)) = text.fill; + let Paint::Solid(color) = text.fill; + let c = color.to_rgba(); let color = sk::ColorU8::from_rgba(c.r, c.g, c.b, 255).premultiply().get(); // Blend the glyph bitmap with the existing pixels on the canvas. @@ -453,7 +454,8 @@ impl From<Transform> for sk::Transform { impl From<Paint> for sk::Paint<'static> { fn from(paint: Paint) -> Self { let mut sk_paint = sk::Paint::default(); - let Paint::Solid(Color::Rgba(c)) = paint; + let Paint::Solid(color) = paint; + let c = color.to_rgba(); sk_paint.set_color_rgba8(c.r, c.g, c.b, c.a); sk_paint.anti_alias = true; sk_paint |
