Module: Postsvg::Visitors::PsVisitor::Font
- Included in:
- Postsvg::Visitors::PsVisitor
- Defined in:
- lib/postsvg/visitors/ps_visitor/font.rb
Overview
Font and text operator handlers. Each pops from the RUNTIME stack (not the AST) so chained font setup works:
/Helvetica findfont 18 scalefont setfont
pushes a FontRef after findfont, scales it after scalefont, installs it after setfont.
Defined Under Namespace
Classes: FontRef
Instance Method Summary collapse
- #visit_charpath(_op, _ctx) ⇒ Object
- #visit_findfont(op, _ctx) ⇒ Object
- #visit_scalefont(op, _ctx) ⇒ Object
- #visit_setfont(_op, _ctx) ⇒ Object
- #visit_show(_op, _ctx) ⇒ Object
- #visit_stringwidth(_op, _ctx) ⇒ Object
- #visit_xyshow(_op, _ctx) ⇒ Object
Instance Method Details
#visit_charpath(_op, _ctx) ⇒ Object
87 88 89 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 87 def visit_charpath(_op, _ctx) @builder.comment("charpath: requires font metrics") end |
#visit_findfont(op, _ctx) ⇒ Object
23 24 25 26 27 28 29 30 31 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 23 def visit_findfont(op, _ctx) name = case op.name when Model::Literals::Name then op.name.value when Model::Literals::StringLiteral then op.name.value else op.name.to_s end @stack << FontRef.new(name: name, size: nil) end |
#visit_scalefont(op, _ctx) ⇒ Object
33 34 35 36 37 38 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 33 def visit_scalefont(op, _ctx) size = op.size.to_i || op.size.to_f font = @stack.pop base = font.is_a?(FontRef) ? font : FontRef.new(name: "Helvetica", size: nil) @stack << FontRef.new(name: base.name, size: size.to_f) end |
#visit_setfont(_op, _ctx) ⇒ Object
40 41 42 43 44 45 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 40 def visit_setfont(_op, _ctx) font = @stack.pop ref = font.is_a?(FontRef) ? font : FontRef.new(name: "Helvetica", size: 12.0) @graphics.update(font_name: ref.name || "Helvetica", font_size: ref.size || 12.0) end |
#visit_show(_op, _ctx) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 47 def visit_show(_op, _ctx) text = @stack.pop text_str = case text when Model::Literals::StringLiteral then text.value when String then text else text.to_s end pos = @graphics.current.last_text_position return unless pos ctm = @graphics.current.ctm screen_pos = ctm.apply_point(pos[:x], pos[:y]) color = @graphics.current.fill_color # SVG y is inverted relative to PS — the Y-flip wrapper # group already flips the whole body, so we emit a # scale(1 -1) per <text> to undo the flip for text only. @builder.text( content: text_str, x: screen_pos[:x], y: -screen_pos[:y], font_family: @graphics.current.font_name, font_size: @graphics.current.font_size, color: color || Postsvg::Color::BLACK, transform: "scale(1 -1)", ) @path.reset @graphics.update(last_text_position: nil) end |
#visit_stringwidth(_op, _ctx) ⇒ Object
81 82 83 84 85 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 81 def visit_stringwidth(_op, _ctx) # Without real font metrics, push zero advance. @stack << 0 @stack << 0 end |
#visit_xyshow(_op, _ctx) ⇒ Object
77 78 79 |
# File 'lib/postsvg/visitors/ps_visitor/font.rb', line 77 def visit_xyshow(_op, _ctx) @builder.comment("xyshow: not yet implemented") end |