Class: Emfsvg::Translation::Context
- Inherits:
-
Object
- Object
- Emfsvg::Translation::Context
- Defined in:
- lib/emfsvg/translation/context.rb
Overview
Mutable translation state carried through the element tree walk.
Holds the GDI device context (pen/brush/font/transform), the 1-indexed object table, the SaveDC/RestoreDC stack, the coordinate scaler, and the output record list. All handlers receive a Context instance and operate on it functionally.
Context also carries a reference to the HandlerRegistry so that GroupHandler (and other container handlers) can recurse into their children uniformly.
Instance Attribute Summary collapse
-
#clip_path_registry ⇒ Object
readonly
Returns the value of attribute clip_path_registry.
-
#device_context ⇒ Object
readonly
Returns the value of attribute device_context.
-
#emitter ⇒ Object
readonly
Returns the value of attribute emitter.
-
#handler_registry ⇒ Object
readonly
Returns the value of attribute handler_registry.
-
#object_table ⇒ Object
readonly
Returns the value of attribute object_table.
-
#scaler ⇒ Object
readonly
Returns the value of attribute scaler.
-
#transform_stack ⇒ Object
readonly
Returns the value of attribute transform_stack.
Instance Method Summary collapse
-
#allocate_handle ⇒ Object
Allocate the next 1-indexed GDI object handle.
-
#dispatch(element) ⇒ Object
Dispatch an element through the registry.
- #emit(wire_class, **attrs) ⇒ Object
-
#initialize(handler_registry: EmfRenderer::DEFAULT_REGISTRY, clip_path_registry: nil, scaler: Scaler::Identity.new) ⇒ Context
constructor
A new instance of Context.
-
#point_l(x, y) ⇒ Object
---- Coordinate-scaled wire helpers (DRY: handlers route all coords through these so the scaler affects everything) ----.
- #records ⇒ Object
- #rect_l(left, top, right, bottom) ⇒ Object
- #size_l(cx, cy) ⇒ Object
-
#xform_wire_from(matrix) ⇒ Object
Convert a Matrix to its wire form, scaling the translation (dx/dy) by the scaler's factor.
Constructor Details
#initialize(handler_registry: EmfRenderer::DEFAULT_REGISTRY, clip_path_registry: nil, scaler: Scaler::Identity.new) ⇒ Context
Returns a new instance of Context.
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/emfsvg/translation/context.rb', line 21 def initialize(handler_registry: EmfRenderer::DEFAULT_REGISTRY, clip_path_registry: nil, scaler: Scaler::Identity.new) @device_context = DeviceContext.new @object_table = ObjectTable.new @transform_stack = TransformStack.new @emitter = RecordEmitter.new @handler_registry = handler_registry @clip_path_registry = clip_path_registry @scaler = scaler @next_handle = 1 end |
Instance Attribute Details
#clip_path_registry ⇒ Object (readonly)
Returns the value of attribute clip_path_registry.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def clip_path_registry @clip_path_registry end |
#device_context ⇒ Object (readonly)
Returns the value of attribute device_context.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def device_context @device_context end |
#emitter ⇒ Object (readonly)
Returns the value of attribute emitter.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def emitter @emitter end |
#handler_registry ⇒ Object (readonly)
Returns the value of attribute handler_registry.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def handler_registry @handler_registry end |
#object_table ⇒ Object (readonly)
Returns the value of attribute object_table.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def object_table @object_table end |
#scaler ⇒ Object (readonly)
Returns the value of attribute scaler.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def scaler @scaler end |
#transform_stack ⇒ Object (readonly)
Returns the value of attribute transform_stack.
18 19 20 |
# File 'lib/emfsvg/translation/context.rb', line 18 def transform_stack @transform_stack end |
Instance Method Details
#allocate_handle ⇒ Object
Allocate the next 1-indexed GDI object handle. Always increments — no reuse in v1 (see TODO.roadmap/09-coalescing-optimization.adoc).
36 37 38 39 40 |
# File 'lib/emfsvg/translation/context.rb', line 36 def allocate_handle handle = @next_handle @next_handle += 1 handle end |
#dispatch(element) ⇒ Object
Dispatch an element through the registry. Container handlers (e.g. GroupHandler) call this to recurse into their children.
52 53 54 55 |
# File 'lib/emfsvg/translation/context.rb', line 52 def dispatch(element) handler = @handler_registry.handler_for(element) handler&.call(element, self) end |
#emit(wire_class, **attrs) ⇒ Object
42 43 44 |
# File 'lib/emfsvg/translation/context.rb', line 42 def emit(wire_class, **attrs) @emitter.emit(wire_class, **attrs) end |
#point_l(x, y) ⇒ Object
---- Coordinate-scaled wire helpers (DRY: handlers route all coords through these so the scaler affects everything) ----
60 61 62 |
# File 'lib/emfsvg/translation/context.rb', line 60 def point_l(x, y) Emf::Binary::Types::PointL.new(x: scale_int(x), y: scale_int(y)) end |
#records ⇒ Object
46 47 48 |
# File 'lib/emfsvg/translation/context.rb', line 46 def records @emitter.records end |
#rect_l(left, top, right, bottom) ⇒ Object
64 65 66 67 68 69 |
# File 'lib/emfsvg/translation/context.rb', line 64 def rect_l(left, top, right, bottom) Emf::Binary::Types::RectL.new( left: scale_int(left), top: scale_int(top), right: scale_int(right), bottom: scale_int(bottom) ) end |
#size_l(cx, cy) ⇒ Object
71 72 73 |
# File 'lib/emfsvg/translation/context.rb', line 71 def size_l(cx, cy) Emf::Binary::Types::SizeL.new(cx: scale_int(cx), cy: scale_int(cy)) end |
#xform_wire_from(matrix) ⇒ Object
Convert a Matrix to its wire form, scaling the translation (dx/dy) by the scaler's factor. The 2x2 rotation/scale coefficients are NOT scaled — they're dimensionless ratios and survive any isometric map-mode change intact.
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/emfsvg/translation/context.rb', line 79 def xform_wire_from(matrix) factor = @scaler.factor return matrix.to_wire if factor == 1 scaled = Emf::Model::Geometry::Matrix.new( m11: matrix.m11, m12: matrix.m12, m21: matrix.m21, m22: matrix.m22, dx: matrix.dx * factor, dy: matrix.dy * factor ) scaled.to_wire end |