mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
fix leaky pdf text stroke (#3580)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
parent
2bc3c96bc9
commit
d927974bb1
@ -4,7 +4,7 @@ use std::num::NonZeroUsize;
|
|||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use pdf_writer::types::{
|
use pdf_writer::types::{
|
||||||
ActionType, AnnotationFlags, AnnotationType, ColorSpaceOperand, LineCapStyle,
|
ActionType, AnnotationFlags, AnnotationType, ColorSpaceOperand, LineCapStyle,
|
||||||
LineJoinStyle, NumberingStyle,
|
LineJoinStyle, NumberingStyle, TextRenderingMode,
|
||||||
};
|
};
|
||||||
use pdf_writer::writers::{PageLabel, Resources};
|
use pdf_writer::writers::{PageLabel, Resources};
|
||||||
use pdf_writer::{Content, Filter, Finish, Name, Rect, Ref, Str, TextStr};
|
use pdf_writer::{Content, Filter, Finish, Name, Rect, Ref, Str, TextStr};
|
||||||
@ -456,6 +456,7 @@ struct State {
|
|||||||
external_graphics_state: Option<ExtGState>,
|
external_graphics_state: Option<ExtGState>,
|
||||||
stroke: Option<FixedStroke>,
|
stroke: Option<FixedStroke>,
|
||||||
stroke_space: Option<Name<'static>>,
|
stroke_space: Option<Name<'static>>,
|
||||||
|
text_rendering_mode: TextRenderingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@ -471,6 +472,7 @@ impl State {
|
|||||||
external_graphics_state: None,
|
external_graphics_state: None,
|
||||||
stroke: None,
|
stroke: None,
|
||||||
stroke_space: None,
|
stroke_space: None,
|
||||||
|
text_rendering_mode: TextRenderingMode::Fill,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +655,13 @@ impl PageContext<'_, '_> {
|
|||||||
pub fn reset_stroke_color_space(&mut self) {
|
pub fn reset_stroke_color_space(&mut self) {
|
||||||
self.state.stroke_space = None;
|
self.state.stroke_space = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_text_rendering_mode(&mut self, mode: TextRenderingMode) {
|
||||||
|
if self.state.text_rendering_mode != mode {
|
||||||
|
self.content.set_text_rendering_mode(mode);
|
||||||
|
self.state.text_rendering_mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode a frame into the content stream.
|
/// Encode a frame into the content stream.
|
||||||
@ -714,13 +723,25 @@ fn write_text(ctx: &mut PageContext, pos: Point, text: &TextItem) {
|
|||||||
let segment = &text.text[g.range()];
|
let segment = &text.text[g.range()];
|
||||||
glyph_set.entry(g.id).or_insert_with(|| segment.into());
|
glyph_set.entry(g.id).or_insert_with(|| segment.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let fill_transform = ctx.state.transforms(Size::zero(), pos);
|
let fill_transform = ctx.state.transforms(Size::zero(), pos);
|
||||||
ctx.set_fill(&text.fill, true, fill_transform);
|
ctx.set_fill(&text.fill, true, fill_transform);
|
||||||
if let Some(stroke) = &text.stroke {
|
|
||||||
ctx.set_stroke(stroke, true, fill_transform);
|
let stroke = text.stroke.as_ref().and_then(|stroke| {
|
||||||
ctx.content
|
if stroke.thickness.to_f32() > 0.0 {
|
||||||
.set_text_rendering_mode(pdf_writer::types::TextRenderingMode::FillStroke);
|
Some(stroke)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(stroke) = stroke {
|
||||||
|
ctx.set_stroke(stroke, true, fill_transform);
|
||||||
|
ctx.set_text_rendering_mode(TextRenderingMode::FillStroke);
|
||||||
|
} else {
|
||||||
|
ctx.set_text_rendering_mode(TextRenderingMode::Fill);
|
||||||
|
}
|
||||||
|
|
||||||
ctx.set_font(&text.font, text.size);
|
ctx.set_font(&text.font, text.size);
|
||||||
ctx.set_opacities(text.stroke.as_ref(), Some(&text.fill));
|
ctx.set_opacities(text.stroke.as_ref(), Some(&text.fill));
|
||||||
ctx.content.begin_text();
|
ctx.content.begin_text();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user