From 2fb09abbf8c3704220ced9e6e3e1c2402c696bb2 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Mon, 3 Aug 2026 21:33:01 +0800 Subject: [PATCH] feat: use pdfrb 0.19.0 canvas.text_lines in TextFrameRenderer TextFrameRenderer batches all broken lines into a single canvas.text_lines call instead of N separate canvas.text calls. Reduces PDF content-stream size and improves rendering performance. TODO 65 documents remaining pdfrb 0.19.0 integration gaps: - glyph_width returns 0 for TTF (pdfrb bug) - FontResolver can't find .ttc files --- TODO.pdf/65-pdfrb-019-integration.md | 29 +++++++++++++++++++ .../render/renderers/text_frame_renderer.rb | 14 ++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 TODO.pdf/65-pdfrb-019-integration.md diff --git a/TODO.pdf/65-pdfrb-019-integration.md b/TODO.pdf/65-pdfrb-019-integration.md new file mode 100644 index 0000000..77ce661 --- /dev/null +++ b/TODO.pdf/65-pdfrb-019-integration.md @@ -0,0 +1,29 @@ +# TODO PDF 65: pdfrb 0.19.0 feature integration + +## Status: PARTIALLY DONE + +## What was implemented + +1. **Canvas#text_lines**: TextFrameRenderer uses `canvas.text_lines` + instead of N separate `canvas.text` calls per line. Single batch + call for all lines within a run. + +## What remains (pdfrb bugs) + +2. **glyph_width for TTF**: pdfrb 0.19.0 has `Fonts#glyph_width` but + returns 0 for TrueType fonts (bug: "undefined method glyph_id_for + for String"). Standard 14 Type1 fonts work correctly. Cannot + replace FontMetrics/Fontisan until this is fixed. + +3. **Pdfrb::FontResolver**: Returns nil for common fonts (Helvetica.ttc + on macOS). Cannot replace Fontisan-based resolver yet. + +4. **Font subsetting**: `Fonts#add` accepts `**opts` but `subset: true` + behavior unverified. Standard 14 fonts don't need FontFile embedding. + +## Acceptance criteria + +- [x] TextFrameRenderer uses canvas.text_lines +- [ ] FontMetrics replaced with pdfrb glyph_width (blocked by TTF bug) +- [ ] FontResolver replaced with Pdfrb::FontResolver (blocked by .ttc) +- [ ] Font subsetting verified diff --git a/lib/idml/render/renderers/text_frame_renderer.rb b/lib/idml/render/renderers/text_frame_renderer.rb index 6e15b9b..696b04d 100644 --- a/lib/idml/render/renderers/text_frame_renderer.rb +++ b/lib/idml/render/renderers/text_frame_renderer.rb @@ -95,15 +95,21 @@ def self.render_run_lines(canvas, run, context, box, font, baseline_y) glyphs: glyphs, frame_width: box[:width], ) + line_texts = [] lines.each do |line| break if baseline_y < box[:y] - line_text = line.glyphs.map { |g| [g.codepoint].pack("U") }.join - canvas.text(line_text, at: [box[:x], baseline_y], - font: context.font_ps_name, - size: size) + line_texts << line.glyphs.map { |g| [g.codepoint].pack("U") }.join baseline_y -= size * LEADING_FACTOR end + + if line_texts.any? + canvas.text_lines(line_texts, + font: context.font_ps_name, + size: size, + at: [box[:x], box[:y] + box[:height] - size], + leading: size * LEADING_FACTOR) + end baseline_y end private_class_method :render_run_lines