summaryrefslogtreecommitdiff
path: root/crates/typst-pdf
diff options
context:
space:
mode:
authorWenzhuo Liu <mgt@oi-wiki.org>2023-12-19 17:36:18 +0800
committerGitHub <noreply@github.com>2023-12-19 10:36:18 +0100
commit81ff34d80dac76c345c54e36b7bd203efa3be710 (patch)
treeba7baf4e08b0b3b5aac89c5ba3e90ab649453000 /crates/typst-pdf
parent111a69f6aaf0dd470dd2319f8cff29194aa0da08 (diff)
Add stroke for text (#2970)
Diffstat (limited to 'crates/typst-pdf')
-rw-r--r--crates/typst-pdf/src/color.rs17
-rw-r--r--crates/typst-pdf/src/gradient.rs9
-rw-r--r--crates/typst-pdf/src/page.rs28
-rw-r--r--crates/typst-pdf/src/pattern.rs9
4 files changed, 46 insertions, 17 deletions
diff --git a/crates/typst-pdf/src/color.rs b/crates/typst-pdf/src/color.rs
index 3d90926f..f0d483cf 100644
--- a/crates/typst-pdf/src/color.rs
+++ b/crates/typst-pdf/src/color.rs
@@ -205,7 +205,7 @@ pub(super) trait PaintEncode {
fn set_as_fill(&self, ctx: &mut PageContext, on_text: bool, transforms: Transforms);
/// Set the paint as the stroke color.
- fn set_as_stroke(&self, ctx: &mut PageContext, transforms: Transforms);
+ fn set_as_stroke(&self, ctx: &mut PageContext, on_text: bool, transforms: Transforms);
}
impl PaintEncode for Paint {
@@ -217,11 +217,16 @@ impl PaintEncode for Paint {
}
}
- fn set_as_stroke(&self, ctx: &mut PageContext, transforms: Transforms) {
+ fn set_as_stroke(
+ &self,
+ ctx: &mut PageContext,
+ on_text: bool,
+ transforms: Transforms,
+ ) {
match self {
- Self::Solid(c) => c.set_as_stroke(ctx, transforms),
- Self::Gradient(gradient) => gradient.set_as_stroke(ctx, transforms),
- Self::Pattern(pattern) => pattern.set_as_stroke(ctx, transforms),
+ Self::Solid(c) => c.set_as_stroke(ctx, on_text, transforms),
+ Self::Gradient(gradient) => gradient.set_as_stroke(ctx, on_text, transforms),
+ Self::Pattern(pattern) => pattern.set_as_stroke(ctx, on_text, transforms),
}
}
}
@@ -267,7 +272,7 @@ impl PaintEncode for Color {
}
}
- fn set_as_stroke(&self, ctx: &mut PageContext, _: Transforms) {
+ fn set_as_stroke(&self, ctx: &mut PageContext, _: bool, _: Transforms) {
match self {
Color::Luma(_) => {
ctx.parent.colors.d65_gray(&mut ctx.parent.alloc);
diff --git a/crates/typst-pdf/src/gradient.rs b/crates/typst-pdf/src/gradient.rs
index 0882a70e..523d67b9 100644
--- a/crates/typst-pdf/src/gradient.rs
+++ b/crates/typst-pdf/src/gradient.rs
@@ -225,10 +225,15 @@ impl PaintEncode for Gradient {
.insert(PageResource::new(ResourceKind::Gradient, id), index);
}
- fn set_as_stroke(&self, ctx: &mut PageContext, transforms: Transforms) {
+ fn set_as_stroke(
+ &self,
+ ctx: &mut PageContext,
+ on_text: bool,
+ transforms: Transforms,
+ ) {
ctx.reset_stroke_color_space();
- let index = register_gradient(ctx, self, false, transforms);
+ let index = register_gradient(ctx, self, on_text, transforms);
let id = eco_format!("Gr{index}");
let name = Name(id.as_bytes());
diff --git a/crates/typst-pdf/src/page.rs b/crates/typst-pdf/src/page.rs
index 05501d2c..56d3fd83 100644
--- a/crates/typst-pdf/src/page.rs
+++ b/crates/typst-pdf/src/page.rs
@@ -504,7 +504,12 @@ impl PageContext<'_, '_> {
self.state.fill_space = None;
}
- fn set_stroke(&mut self, stroke: &FixedStroke, transforms: Transforms) {
+ fn set_stroke(
+ &mut self,
+ stroke: &FixedStroke,
+ on_text: bool,
+ transforms: Transforms,
+ ) {
if self.state.stroke.as_ref() != Some(stroke)
|| matches!(
self.state.stroke.as_ref().map(|s| &s.paint),
@@ -520,7 +525,7 @@ impl PageContext<'_, '_> {
miter_limit,
} = stroke;
- paint.set_as_stroke(self, transforms);
+ paint.set_as_stroke(self, on_text, transforms);
self.content.set_line_width(thickness.to_f32());
if self.state.stroke.as_ref().map(|s| &s.line_cap) != Some(line_cap) {
@@ -620,13 +625,18 @@ fn write_text(ctx: &mut PageContext, pos: Point, text: &TextItem) {
let segment = &text.text[g.range()];
glyph_set.entry(g.id).or_insert_with(|| segment.into());
}
-
- ctx.set_fill(&text.fill, true, ctx.state.transforms(Size::zero(), pos));
+ let fill_transform = ctx.state.transforms(Size::zero(), pos);
+ ctx.set_fill(&text.fill, true, fill_transform);
+ if let Some(stroke) = &text.stroke {
+ ctx.set_stroke(stroke, true, fill_transform);
+ ctx.content
+ .set_text_rendering_mode(pdf_writer::types::TextRenderingMode::FillStroke);
+ }
ctx.set_font(&text.font, text.size);
- ctx.set_opacities(None, Some(&text.fill));
+ ctx.set_opacities(text.stroke.as_ref(), Some(&text.fill));
ctx.content.begin_text();
- // Positiosn the text.
+ // Position the text.
ctx.content.set_text_matrix([1.0, 0.0, 0.0, -1.0, x, y]);
let mut positioned = ctx.content.show_positioned();
@@ -690,7 +700,11 @@ fn write_shape(ctx: &mut PageContext, pos: Point, shape: &Shape) {
}
if let Some(stroke) = stroke {
- ctx.set_stroke(stroke, ctx.state.transforms(shape.geometry.bbox_size(), pos));
+ ctx.set_stroke(
+ stroke,
+ false,
+ ctx.state.transforms(shape.geometry.bbox_size(), pos),
+ );
}
ctx.set_opacities(stroke, shape.fill.as_ref());
diff --git a/crates/typst-pdf/src/pattern.rs b/crates/typst-pdf/src/pattern.rs
index ea7d48e0..0829ef32 100644
--- a/crates/typst-pdf/src/pattern.rs
+++ b/crates/typst-pdf/src/pattern.rs
@@ -140,10 +140,15 @@ impl PaintEncode for Pattern {
.insert(PageResource::new(ResourceKind::Pattern, id), index);
}
- fn set_as_stroke(&self, ctx: &mut PageContext, transforms: Transforms) {
+ fn set_as_stroke(
+ &self,
+ ctx: &mut PageContext,
+ on_text: bool,
+ transforms: Transforms,
+ ) {
ctx.reset_stroke_color_space();
- let index = register_pattern(ctx, self, false, transforms);
+ let index = register_pattern(ctx, self, on_text, transforms);
let id = eco_format!("P{index}");
let name = Name(id.as_bytes());