fix(render): Type 3 text ignores rendering modes other than invisible (vendored hayro-interpret patch 27) (fixes #1469) (#1478)
This commit is contained in:
parent
c6128c039a
commit
0d300c6a41
|
|
@ -5885,4 +5885,46 @@ trailer << /Root 1 0 R >>
|
|||
assert!([(5, 5), (50, 50), (95, 95)].iter().all(|(x, y)| px(&p, *x, *y) == red), "{content}: no stray clip");
|
||||
}
|
||||
}
|
||||
|
||||
/// ISO 32000-1 §9.3.6: only text rendering mode 3 has any effect on a Type 3 font (vendored
|
||||
/// hayro-interpret patch in `show_glyph`). Print-stream PDFs set `2 Tr` for Type 3 bitmap
|
||||
/// fonts, and the glyph procedure ran twice (fill, then stroke), so its anti-aliased edges
|
||||
/// doubled up and the text looked bold; under `1 Tr` an uncoloured glyph took the stroking
|
||||
/// colour, and under `7 Tr` it disappeared. Both glyph kinds have edges between pixels.
|
||||
#[test]
|
||||
fn text_rendering_modes_other_than_invisible_draw_type3_glyphs_as_filled() {
|
||||
let render = |glyph: &str, mode: u8| {
|
||||
let content = format!("BT 1 0 0 RG 6 w 0 g /F1 20 Tf {mode} Tr 10.3 10.3 Td (A) Tj ET");
|
||||
let pdf = format!(
|
||||
"%PDF-1.7
|
||||
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
|
||||
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj
|
||||
3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 40 40] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >> endobj
|
||||
4 0 obj << /Length {} >> stream
|
||||
{content}
|
||||
endstream endobj
|
||||
5 0 obj << /Type /Font /Subtype /Type3 /FontBBox [0 0 1 1] /FontMatrix [1 0 0 1 0 0] /FirstChar 65 /LastChar 65 /Widths [1]
|
||||
/Encoding << /Differences [65 /a] >> /CharProcs << /a 6 0 R >> >> endobj
|
||||
6 0 obj << /Length {} >> stream
|
||||
{glyph}
|
||||
endstream endobj
|
||||
trailer << /Root 1 0 R >>
|
||||
%%EOF",
|
||||
content.len(),
|
||||
glyph.len()
|
||||
);
|
||||
let mut r = PageRenderer::new(Arc::new(pdf.into_bytes()), RenderConfig::default());
|
||||
let p = r.render(RenderRequest { page: 0, kind: RequestKind::Pixels, tile: None, scale: 1.0, tag: 0, ..Default::default() });
|
||||
assert!(p.error.is_none(), "{glyph} {mode} Tr: {:?}", p.error);
|
||||
p.rgba
|
||||
};
|
||||
for glyph in ["1 0 0 0 1 1 d1 0.12 0.12 0.71 0.71 re f", "1 0 d0 0.12 0.12 0.71 0.71 re f"] {
|
||||
let filled = render(glyph, 0);
|
||||
assert!(filled.as_chunks::<4>().0.iter().any(|p| p[0] < 128), "{glyph}: the glyph paints");
|
||||
for mode in [1, 2, 4, 5, 6, 7] {
|
||||
assert!(render(glyph, mode) == filled, "{glyph}: {mode} Tr draws as 0 Tr");
|
||||
}
|
||||
assert!(render(glyph, 3).as_chunks::<4>().0.iter().all(|p| p[..3] == [255, 255, 255]), "{glyph}: 3 Tr hides the glyph");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -69,7 +69,16 @@ pub(crate) fn show_glyph<'a>(
|
|||
device.set_blend_mode(ctx.get().graphics_state.blend_mode);
|
||||
let stroke_props = ctx.stroke_props();
|
||||
|
||||
match ctx.get().text_state.render_mode {
|
||||
// PdfCraft patch: only mode 3 has any effect on text in a Type 3 font (ISO 32000-1
|
||||
// 9.3.6). Stroking ran the glyph procedure a second time, so `2 Tr` made bitmap fonts
|
||||
// look bold, and the clip modes have no outline to clip with.
|
||||
let render_mode = match (glyph, ctx.get().text_state.render_mode) {
|
||||
(Glyph::Type3(_), TextRenderingMode::Invisible) => TextRenderingMode::Invisible,
|
||||
(Glyph::Type3(_), _) => TextRenderingMode::Fill,
|
||||
(_, mode) => mode,
|
||||
};
|
||||
|
||||
match render_mode {
|
||||
TextRenderingMode::Fill => {
|
||||
device.draw_glyph(
|
||||
glyph,
|
||||
|
|
|
|||
Loading…
Reference in New Issue