emf 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +224 -19
- data/exe/emf +12 -0
- data/lib/emf/backend.rb +60 -0
- data/lib/emf/binary/class_field_accessors.rb +49 -0
- data/lib/emf/binary/float32_le.rb +54 -0
- data/lib/emf/binary/types.rb +40 -6
- data/lib/emf/conformance/context.rb +36 -0
- data/lib/emf/conformance/diagnostic.rb +18 -0
- data/lib/emf/conformance/manifest/emf_bitmap_misc.yml +622 -0
- data/lib/emf/conformance/manifest/emf_control_buffers.yml +61 -0
- data/lib/emf/conformance/manifest/emf_core.yml +117 -0
- data/lib/emf/conformance/manifest/emf_corpus_rules.yml +21 -0
- data/lib/emf/conformance/manifest/emf_objects_geometry.yml +229 -0
- data/lib/emf/conformance/manifest/emf_plus.yml +357 -0
- data/lib/emf/conformance/manifest/emf_plus_core.yml +33 -0
- data/lib/emf/conformance/manifest/emf_state_path.yml +403 -0
- data/lib/emf/conformance/manifest/emf_text.yml +97 -0
- data/lib/emf/conformance/manifest/wmf.yml +874 -0
- data/lib/emf/conformance/manifest.rb +79 -0
- data/lib/emf/conformance/profile.rb +35 -0
- data/lib/emf/conformance/record_types.rb +24 -0
- data/lib/emf/conformance/registry.rb +76 -0
- data/lib/emf/conformance/report.rb +83 -0
- data/lib/emf/conformance/rule.rb +16 -0
- data/lib/emf/conformance/rules/emf_bitmap.rb +357 -0
- data/lib/emf/conformance/rules/emf_comment_escape.rb +309 -0
- data/lib/emf/conformance/rules/emf_control_buffers.rb +137 -0
- data/lib/emf/conformance/rules/emf_corpus_named.rb +83 -0
- data/lib/emf/conformance/rules/emf_framing.rb +94 -0
- data/lib/emf/conformance/rules/emf_geometry.rb +282 -0
- data/lib/emf/conformance/rules/emf_header.rb +114 -0
- data/lib/emf/conformance/rules/emf_objects.rb +291 -0
- data/lib/emf/conformance/rules/emf_parse_recovery.rb +97 -0
- data/lib/emf/conformance/rules/emf_path_clip.rb +165 -0
- data/lib/emf/conformance/rules/emf_plus.rb +75 -0
- data/lib/emf/conformance/rules/emf_plus_common.rb +58 -0
- data/lib/emf/conformance/rules/emf_plus_drawing.rb +78 -0
- data/lib/emf/conformance/rules/emf_plus_effects.rb +104 -0
- data/lib/emf/conformance/rules/emf_plus_fields.rb +169 -0
- data/lib/emf/conformance/rules/emf_plus_fields_b.rb +102 -0
- data/lib/emf/conformance/rules/emf_plus_framing.rb +172 -0
- data/lib/emf/conformance/rules/emf_plus_objects.rb +97 -0
- data/lib/emf/conformance/rules/emf_plus_payloads.rb +320 -0
- data/lib/emf/conformance/rules/emf_plus_properties.rb +96 -0
- data/lib/emf/conformance/rules/emf_plus_state.rb +77 -0
- data/lib/emf/conformance/rules/emf_state.rb +244 -0
- data/lib/emf/conformance/rules/emf_text.rb +221 -0
- data/lib/emf/conformance/rules/emf_transform.rb +85 -0
- data/lib/emf/conformance/rules/wmf_buffers.rb +259 -0
- data/lib/emf/conformance/rules/wmf_framing.rb +146 -0
- data/lib/emf/conformance/rules/wmf_layout_records.rb +112 -0
- data/lib/emf/conformance/rules/wmf_objects.rb +168 -0
- data/lib/emf/conformance/rules/wmf_records.rb +191 -0
- data/lib/emf/conformance/rules/wmf_rejections.rb +184 -0
- data/lib/emf/conformance/runner.rb +61 -0
- data/lib/emf/conformance/ternary_raster_operations.rb +52 -0
- data/lib/emf/conformance.rb +31 -0
- data/lib/emf/emf_plus/effects/blur.rb +24 -0
- data/lib/emf/emf_plus/effects/brightness_contrast.rb +22 -0
- data/lib/emf/emf_plus/effects/color_balance.rb +24 -0
- data/lib/emf/emf_plus/effects/color_curve.rb +24 -0
- data/lib/emf/emf_plus/effects/color_lookup_table.rb +26 -0
- data/lib/emf/emf_plus/effects/color_matrix.rb +23 -0
- data/lib/emf/emf_plus/effects/effect.rb +50 -0
- data/lib/emf/emf_plus/effects/hue_saturation_lightness.rb +24 -0
- data/lib/emf/emf_plus/effects/levels.rb +24 -0
- data/lib/emf/emf_plus/effects/opaque.rb +19 -0
- data/lib/emf/emf_plus/effects/red_eye_correction.rb +35 -0
- data/lib/emf/emf_plus/effects/sharpen.rb +24 -0
- data/lib/emf/emf_plus/effects/tint.rb +22 -0
- data/lib/emf/emf_plus/effects.rb +45 -0
- data/lib/emf/emf_plus/frame.rb +41 -0
- data/lib/emf/emf_plus/links/effect_link.rb +16 -0
- data/lib/emf/emf_plus/links/get_dc_span.rb +18 -0
- data/lib/emf/emf_plus/links/link_error.rb +15 -0
- data/lib/emf/emf_plus/links.rb +77 -0
- data/lib/emf/emf_plus/object_chain.rb +108 -0
- data/lib/emf/emf_plus/object_table.rb +182 -0
- data/lib/emf/emf_plus/objects/brush.rb +296 -0
- data/lib/emf/emf_plus/objects/custom_line_cap.rb +106 -0
- data/lib/emf/emf_plus/objects/font.rb +47 -0
- data/lib/emf/emf_plus/objects/image.rb +68 -0
- data/lib/emf/emf_plus/objects/image_attributes.rb +28 -0
- data/lib/emf/emf_plus/objects/opaque.rb +19 -0
- data/lib/emf/emf_plus/objects/parts.rb +103 -0
- data/lib/emf/emf_plus/objects/path.rb +21 -0
- data/lib/emf/emf_plus/objects/pen.rb +132 -0
- data/lib/emf/emf_plus/objects/region.rb +39 -0
- data/lib/emf/emf_plus/objects/string_format.rb +55 -0
- data/lib/emf/emf_plus/objects/typed.rb +50 -0
- data/lib/emf/emf_plus/objects.rb +46 -0
- data/lib/emf/emf_plus/parser.rb +64 -2
- data/lib/emf/emf_plus/records/base.rb +107 -0
- data/lib/emf/emf_plus/records/begin_container.rb +31 -0
- data/lib/emf/emf_plus/records/begin_container_no_params.rb +20 -0
- data/lib/emf/emf_plus/records/body.rb +16 -0
- data/lib/emf/emf_plus/records/clear.rb +22 -0
- data/lib/emf/emf_plus/records/clip_transform_flags.rb +26 -0
- data/lib/emf/emf_plus/records/comment.rb +21 -0
- data/lib/emf/emf_plus/records/draw_arc.rb +33 -0
- data/lib/emf/emf_plus/records/draw_beziers.rb +31 -0
- data/lib/emf/emf_plus/records/draw_closed_curve.rb +34 -0
- data/lib/emf/emf_plus/records/draw_curve.rb +38 -0
- data/lib/emf/emf_plus/records/draw_driver_string.rb +61 -0
- data/lib/emf/emf_plus/records/draw_ellipse.rb +28 -0
- data/lib/emf/emf_plus/records/draw_image.rb +42 -0
- data/lib/emf/emf_plus/records/draw_image_points.rb +62 -0
- data/lib/emf/emf_plus/records/draw_lines.rb +34 -0
- data/lib/emf/emf_plus/records/draw_path.rb +23 -0
- data/lib/emf/emf_plus/records/draw_pie.rb +33 -0
- data/lib/emf/emf_plus/records/draw_rects.rb +30 -0
- data/lib/emf/emf_plus/records/draw_string.rb +41 -0
- data/lib/emf/emf_plus/records/end_container.rb +20 -0
- data/lib/emf/emf_plus/records/end_of_file.rb +17 -0
- data/lib/emf/emf_plus/records/fill_brush.rb +21 -0
- data/lib/emf/emf_plus/records/fill_closed_curve.rb +38 -0
- data/lib/emf/emf_plus/records/fill_ellipse.rb +29 -0
- data/lib/emf/emf_plus/records/fill_path.rb +23 -0
- data/lib/emf/emf_plus/records/fill_pie.rb +34 -0
- data/lib/emf/emf_plus/records/fill_polygon.rb +32 -0
- data/lib/emf/emf_plus/records/fill_rects.rb +31 -0
- data/lib/emf/emf_plus/records/fill_region.rb +23 -0
- data/lib/emf/emf_plus/records/get_dc.rb +18 -0
- data/lib/emf/emf_plus/records/header.rb +35 -0
- data/lib/emf/emf_plus/records/multiply_world_transform.rb +24 -0
- data/lib/emf/emf_plus/records/object.rb +32 -0
- data/lib/emf/emf_plus/records/offset_clip.rb +24 -0
- data/lib/emf/emf_plus/records/primitives/argb.rb +20 -0
- data/lib/emf/emf_plus/records/primitives/bitmap.rb +32 -0
- data/lib/emf/emf_plus/records/primitives/bitmap_data.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/blend_colors.rb +22 -0
- data/lib/emf/emf_plus/records/primitives/blend_factors.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/bounded_array.rb +38 -0
- data/lib/emf/emf_plus/records/primitives/byte_reader.rb +25 -0
- data/lib/emf/emf_plus/records/primitives/character_range.rb +20 -0
- data/lib/emf/emf_plus/records/primitives/compressed_image.rb +17 -0
- data/lib/emf/emf_plus/records/primitives/focus_scale_data.rb +20 -0
- data/lib/emf/emf_plus/records/primitives/graphics_version.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/language_identifier.rb +22 -0
- data/lib/emf/emf_plus/records/primitives/metafile.rb +19 -0
- data/lib/emf/emf_plus/records/primitives/palette.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/path.rb +89 -0
- data/lib/emf/emf_plus/records/primitives/path_point_type.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/path_point_type_rle.rb +23 -0
- data/lib/emf/emf_plus/records/primitives/point.rb +18 -0
- data/lib/emf/emf_plus/records/primitives/point_array.rb +42 -0
- data/lib/emf/emf_plus/records/primitives/point_f.rb +19 -0
- data/lib/emf/emf_plus/records/primitives/point_r.rb +19 -0
- data/lib/emf/emf_plus/records/primitives/rect.rb +20 -0
- data/lib/emf/emf_plus/records/primitives/rect_array.rb +24 -0
- data/lib/emf/emf_plus/records/primitives/rect_f.rb +21 -0
- data/lib/emf/emf_plus/records/primitives/region_node.rb +68 -0
- data/lib/emf/emf_plus/records/primitives/region_node_child_nodes.rb +22 -0
- data/lib/emf/emf_plus/records/primitives/region_node_path.rb +37 -0
- data/lib/emf/emf_plus/records/primitives/relative_coordinate.rb +32 -0
- data/lib/emf/emf_plus/records/primitives/string_format_data.rb +23 -0
- data/lib/emf/emf_plus/records/primitives/transform_matrix.rb +23 -0
- data/lib/emf/emf_plus/records/primitives.rb +41 -0
- data/lib/emf/emf_plus/records/reset_clip.rb +17 -0
- data/lib/emf/emf_plus/records/reset_world_transform.rb +17 -0
- data/lib/emf/emf_plus/records/restore.rb +20 -0
- data/lib/emf/emf_plus/records/rotate_world_transform.rb +24 -0
- data/lib/emf/emf_plus/records/save.rb +20 -0
- data/lib/emf/emf_plus/records/scale_world_transform.rb +26 -0
- data/lib/emf/emf_plus/records/serializable_object.rb +32 -0
- data/lib/emf/emf_plus/records/set_anti_alias_mode.rb +25 -0
- data/lib/emf/emf_plus/records/set_clip_path.rb +20 -0
- data/lib/emf/emf_plus/records/set_clip_rect.rb +24 -0
- data/lib/emf/emf_plus/records/set_clip_region.rb +20 -0
- data/lib/emf/emf_plus/records/set_compositing_mode.rb +21 -0
- data/lib/emf/emf_plus/records/set_compositing_quality.rb +21 -0
- data/lib/emf/emf_plus/records/set_interpolation_mode.rb +21 -0
- data/lib/emf/emf_plus/records/set_page_transform.rb +25 -0
- data/lib/emf/emf_plus/records/set_pixel_offset_mode.rb +21 -0
- data/lib/emf/emf_plus/records/set_rendering_origin.rb +22 -0
- data/lib/emf/emf_plus/records/set_text_contrast.rb +24 -0
- data/lib/emf/emf_plus/records/set_text_rendering_hint.rb +21 -0
- data/lib/emf/emf_plus/records/set_ts_clip.rb +40 -0
- data/lib/emf/emf_plus/records/set_ts_graphics.rb +88 -0
- data/lib/emf/emf_plus/records/set_world_transform.rb +22 -0
- data/lib/emf/emf_plus/records/shape_flags.rb +23 -0
- data/lib/emf/emf_plus/records/translate_world_transform.rb +26 -0
- data/lib/emf/emf_plus/records/unknown.rb +20 -0
- data/lib/emf/emf_plus/records.rb +107 -0
- data/lib/emf/emf_plus/serializer.rb +9 -2
- data/lib/emf/emf_plus/stream/conformance.rb +68 -0
- data/lib/emf/emf_plus/stream/editor.rb +21 -0
- data/lib/emf/emf_plus/stream/emf_gap.rb +20 -0
- data/lib/emf/emf_plus/stream/link_index.rb +30 -0
- data/lib/emf/emf_plus/stream/rebuild.rb +47 -0
- data/lib/emf/emf_plus/stream/record_handle.rb +26 -0
- data/lib/emf/emf_plus/stream/segment.rb +70 -0
- data/lib/emf/emf_plus/stream.rb +153 -0
- data/lib/emf/emf_plus.rb +9 -0
- data/lib/emf/emr/binary/dib_header.rb +142 -0
- data/lib/emf/emr/binary/ext_text_out_fields.rb +43 -0
- data/lib/emf/emr/binary/extended_pen_buffers.rb +23 -0
- data/lib/emf/emr/binary/fast_fill.rb +1164 -0
- data/lib/emf/emr/binary/font.rb +159 -0
- data/lib/emf/emr/binary/lazy_utf16_array.rb +82 -0
- data/lib/emf/emr/binary/pack_plan.rb +144 -0
- data/lib/emf/emr/binary/pack_plan_check.rb +75 -0
- data/lib/emf/emr/binary/pack_plan_exact.rb +130 -0
- data/lib/emf/emr/binary/pack_plan_generate.rb +116 -0
- data/lib/emf/emr/binary/pack_plan_values.rb +92 -0
- data/lib/emf/emr/binary/palette_body.rb +19 -0
- data/lib/emf/emr/binary/palette_entry.rb +18 -0
- data/lib/emf/emr/binary/record.rb +33 -0
- data/lib/emf/emr/binary/records/alpha_blend.rb +43 -0
- data/lib/emf/emr/binary/records/angle_arc.rb +2 -2
- data/lib/emf/emr/binary/records/bit_blt.rb +14 -0
- data/lib/emf/emr/binary/records/color_correct_palette.rb +55 -1
- data/lib/emf/emr/binary/records/colormatch_to_target_w.rb +76 -1
- data/lib/emf/emr/binary/records/create_colorspace.rb +67 -1
- data/lib/emf/emr/binary/records/create_colorspace_w.rb +90 -1
- data/lib/emf/emr/binary/records/create_dib_pattern_brush_pt.rb +14 -0
- data/lib/emf/emr/binary/records/create_font_indirect_w.rb +6 -2
- data/lib/emf/emr/binary/records/create_mono_brush.rb +14 -0
- data/lib/emf/emr/binary/records/create_palette.rb +19 -1
- data/lib/emf/emr/binary/records/delete_colorspace.rb +22 -1
- data/lib/emf/emr/binary/records/draw_escape.rb +45 -1
- data/lib/emf/emr/binary/records/ellipse.rb +1 -1
- data/lib/emf/emr/binary/records/eof.rb +9 -0
- data/lib/emf/emr/binary/records/ext_create_pen.rb +80 -1
- data/lib/emf/emr/binary/records/ext_escape.rb +45 -1
- data/lib/emf/emr/binary/records/ext_flood_fill.rb +9 -2
- data/lib/emf/emr/binary/records/ext_select_clip_rgn.rb +9 -1
- data/lib/emf/emr/binary/records/ext_text_out_a.rb +16 -3
- data/lib/emf/emr/binary/records/ext_text_out_w.rb +14 -3
- data/lib/emf/emr/binary/records/fill_rgn.rb +11 -2
- data/lib/emf/emr/binary/records/force_ufi_mapping.rb +38 -1
- data/lib/emf/emr/binary/records/frame_rgn.rb +12 -2
- data/lib/emf/emr/binary/records/gls_bounded_record.rb +61 -1
- data/lib/emf/emr/binary/records/gls_record.rb +42 -1
- data/lib/emf/emr/binary/records/gradient_fill.rb +7 -0
- data/lib/emf/emr/binary/records/invert_rgn.rb +11 -3
- data/lib/emf/emr/binary/records/mask_blt.rb +66 -0
- data/lib/emf/emr/binary/records/named_escape.rb +78 -1
- data/lib/emf/emr/binary/records/paint_rgn.rb +11 -3
- data/lib/emf/emr/binary/records/pixel_format.rb +76 -1
- data/lib/emf/emr/binary/records/plg_blt.rb +66 -0
- data/lib/emf/emr/binary/records/poly_textout_a.rb +128 -1
- data/lib/emf/emr/binary/records/poly_textout_w.rb +128 -1
- data/lib/emf/emr/binary/records/raw.rb +3 -0
- data/lib/emf/emr/binary/records/realize_palette.rb +1 -0
- data/lib/emf/emr/binary/records/rectangle.rb +1 -1
- data/lib/emf/emr/binary/records/resize_palette.rb +16 -2
- data/lib/emf/emr/binary/records/round_rect.rb +2 -2
- data/lib/emf/emr/binary/records/select_palette.rb +1 -0
- data/lib/emf/emr/binary/records/set_color_adjustment.rb +136 -0
- data/lib/emf/emr/binary/records/set_colorspace.rb +22 -1
- data/lib/emf/emr/binary/records/set_dibits_to_device.rb +43 -0
- data/lib/emf/emr/binary/records/set_icm_profile_a.rb +71 -1
- data/lib/emf/emr/binary/records/set_icm_profile_w.rb +71 -1
- data/lib/emf/emr/binary/records/set_linked_ufis.rb +49 -1
- data/lib/emf/emr/binary/records/set_miter_limit.rb +1 -1
- data/lib/emf/emr/binary/records/set_palette_entries.rb +20 -2
- data/lib/emf/emr/binary/records/set_text_justification.rb +8 -2
- data/lib/emf/emr/binary/records/small_text_out.rb +55 -4
- data/lib/emf/emr/binary/records/stretch_blt.rb +14 -0
- data/lib/emf/emr/binary/records/stretch_dibits.rb +14 -0
- data/lib/emf/emr/binary/records/transparent_blt.rb +43 -0
- data/lib/emf/emr/binary/records.rb +4 -2
- data/lib/emf/emr/binary/region_data.rb +33 -0
- data/lib/emf/emr/binary/state_record_body.rb +33 -0
- data/lib/emf/emr/binary/thin_shell.rb +226 -0
- data/lib/emf/emr/binary/value_view/layout.rb +101 -0
- data/lib/emf/emr/binary/value_view/reader_source.rb +88 -0
- data/lib/emf/emr/binary/value_view.rb +173 -0
- data/lib/emf/emr/binary/variable_buffers.rb +87 -0
- data/lib/emf/emr/binary.rb +4 -0
- data/lib/emf/emr/filled_record.rb +77 -0
- data/lib/emf/emr/parser.rb +239 -50
- data/lib/emf/emr/serializer.rb +4 -5
- data/lib/emf/emr.rb +1 -0
- data/lib/emf/error.rb +24 -1
- data/lib/emf/model/diagnostic.rb +41 -0
- data/lib/emf/model/emr/header.rb +40 -1
- data/lib/emf/model/emr/records.rb +142 -6
- data/lib/emf/model/emr/wire_values.rb +43 -0
- data/lib/emf/model/emr.rb +1 -0
- data/lib/emf/model/geometry/color.rb +19 -1
- data/lib/emf/model/metafile.rb +22 -2
- data/lib/emf/model/wmf/bitmap_records.rb +155 -0
- data/lib/emf/model/wmf/brush_records.rb +45 -0
- data/lib/emf/model/wmf/dc_escape_records.rb +67 -0
- data/lib/emf/model/wmf/font_record.rb +40 -0
- data/lib/emf/model/wmf/geometry_records.rb +107 -0
- data/lib/emf/model/wmf/header.rb +36 -0
- data/lib/emf/model/wmf/object_records.rb +71 -0
- data/lib/emf/model/wmf/palette_records.rb +68 -0
- data/lib/emf/model/wmf/records.rb +247 -0
- data/lib/emf/model/wmf/region_records.rb +112 -0
- data/lib/emf/model/wmf/state_records.rb +188 -0
- data/lib/emf/model/wmf/text_records.rb +36 -0
- data/lib/emf/model/wmf.rb +11 -0
- data/lib/emf/model.rb +2 -0
- data/lib/emf/native/bitmap_fields.rb +58 -0
- data/lib/emf/native/diagnostic_contract.rb +39 -0
- data/lib/emf/native/diagnostics.rb +81 -0
- data/lib/emf/native/emf_plus_loader.rb +35 -0
- data/lib/emf/native/emf_plus_snapshot.rb +96 -0
- data/lib/emf/native/emf_plus_source.rb +20 -0
- data/lib/emf/native/emf_plus_stream.rb +150 -0
- data/lib/emf/native/fields.rb +369 -0
- data/lib/emf/native/font_fields.rb +87 -0
- data/lib/emf/native/gradient_fields.rb +23 -0
- data/lib/emf/native/header.rb +35 -0
- data/lib/emf/native/header_errors.rb +30 -0
- data/lib/emf/native/hydrator.rb +151 -0
- data/lib/emf/native/lazy_wire.rb +100 -0
- data/lib/emf/native/legacy_state_fields.rb +22 -0
- data/lib/emf/native/library_path.rb +68 -0
- data/lib/emf/native/loader.rb +120 -0
- data/lib/emf/native/palette_fields.rb +45 -0
- data/lib/emf/native/poly_text_fields.rb +116 -0
- data/lib/emf/native/resource_failure.rb +28 -0
- data/lib/emf/native/small_text_fields.rb +27 -0
- data/lib/emf/native/snapshot.rb +102 -0
- data/lib/emf/native/wmf_bitmap_fields.rb +58 -0
- data/lib/emf/native/wmf_brush_fields.rb +62 -0
- data/lib/emf/native/wmf_fields.rb +117 -0
- data/lib/emf/native/wmf_hydrator.rb +143 -0
- data/lib/emf/native/wmf_loading.rb +49 -0
- data/lib/emf/native/wmf_palette_fields.rb +60 -0
- data/lib/emf/native/wmf_region_fields.rb +92 -0
- data/lib/emf/native/wmf_rejection.rb +84 -0
- data/lib/emf/native/wmf_remaining_fields.rb +70 -0
- data/lib/emf/native/wmf_snapshot.rb +51 -0
- data/lib/emf/native/wmf_text_fields.rb +56 -0
- data/lib/emf/native.rb +61 -0
- data/lib/emf/parse_evidence.rb +57 -0
- data/lib/emf/resource_budget/bitmap.rb +66 -0
- data/lib/emf/resource_budget/gradient.rb +30 -0
- data/lib/emf/resource_budget/poly_text.rb +85 -0
- data/lib/emf/resource_budget.rb +382 -0
- data/lib/emf/resource_limits/emf_records.rb +130 -0
- data/lib/emf/resource_limits.rb +58 -0
- data/lib/emf/version.rb +1 -1
- data/lib/emf/visitors/dump.rb +4 -0
- data/lib/emf/visitors/stats.rb +6 -5
- data/lib/emf/wmf/binary.rb +150 -1
- data/lib/emf/wmf/bitmap_codec.rb +118 -0
- data/lib/emf/wmf/brush_codec.rb +102 -0
- data/lib/emf/wmf/dc_escape_codec.rb +75 -0
- data/lib/emf/wmf/dib.rb +187 -0
- data/lib/emf/wmf/embedded_emf.rb +137 -0
- data/lib/emf/wmf/escape_views.rb +89 -0
- data/lib/emf/wmf/evidence.rb +255 -0
- data/lib/emf/wmf/geometry_codec.rb +49 -0
- data/lib/emf/wmf/palette_codec.rb +85 -0
- data/lib/emf/wmf/parser.rb +147 -2
- data/lib/emf/wmf/recovery.rb +95 -0
- data/lib/emf/wmf/region_codec.rb +151 -0
- data/lib/emf/wmf/serializer.rb +164 -2
- data/lib/emf/wmf/text_codec.rb +123 -0
- data/lib/emf/wmf.rb +7 -0
- data/lib/emf.rb +13 -9
- metadata +287 -10
|
@@ -13,16 +13,142 @@ module Emf
|
|
|
13
13
|
# `offset` is the byte offset within the source stream (for diagnostics).
|
|
14
14
|
class WireAdapter < Emf::Model::Record
|
|
15
15
|
Emf::Model::Visitor.register_visit(:visit_emr_wire_record, self)
|
|
16
|
+
include Emf::Model::Emr::WireValues
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
# Internal native construction path; the source owns copied Ruby data only.
|
|
19
|
+
# One per parsed record, so it skips keyword construction; the suffix
|
|
20
|
+
# is the source's once the wire is made.
|
|
21
|
+
def self.lazy(source:, offset: nil)
|
|
22
|
+
allocate.__send__(:init_lazy, source, offset)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Opt-in construction of a wire record from keyword attributes, with
|
|
26
|
+
# n_size set to the record's size, as `klass.new(**attrs)` followed by
|
|
27
|
+
# `n_size = num_bytes`. For a class with a PackPlan and attributes it
|
|
28
|
+
# accepts (values BinData stores unchanged), the adapter holds only the
|
|
29
|
+
# finished bytes; `to_binary_s` serves them until `#wire` is called,
|
|
30
|
+
# after which the adapter serializes that wire like any other. Any
|
|
31
|
+
# other class or attribute shape, or an error while packing, takes the
|
|
32
|
+
# BinData path unchanged, so the result and the errors are those of
|
|
33
|
+
# `klass.new`.
|
|
34
|
+
def self.build(klass, **attrs)
|
|
35
|
+
filler = Emf::Emr::Binary::FastFill.for_class(klass)
|
|
36
|
+
bytes = filler && packed_bytes(filler, attrs)
|
|
37
|
+
return allocate.__send__(:init_lazy, BuiltBytes.new(klass, filler, bytes), nil) if bytes
|
|
38
|
+
|
|
39
|
+
wire = klass.new(**attrs)
|
|
40
|
+
wire.n_size = wire.num_bytes
|
|
41
|
+
new(wire: wire)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.packed_bytes(filler, attrs)
|
|
45
|
+
filler.pack_plan&.pack(attrs)
|
|
46
|
+
rescue StandardError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
private_class_method :packed_bytes
|
|
50
|
+
|
|
51
|
+
# The lazy source of a record built by `build`: its bytes, and a
|
|
52
|
+
# wire read back from them when one is asked for.
|
|
53
|
+
class BuiltBytes
|
|
54
|
+
def initialize(klass, filler, bytes)
|
|
55
|
+
@klass = klass
|
|
56
|
+
@filler = filler
|
|
57
|
+
@bytes = (bytes.encoding == Encoding::BINARY ? bytes : bytes.b).freeze
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def type_id
|
|
61
|
+
@bytes.unpack1("V")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def wire_class
|
|
65
|
+
@klass
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def value_source
|
|
69
|
+
[@bytes, 0, true]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_binary_s
|
|
73
|
+
@bytes.dup
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def append_to(out)
|
|
77
|
+
out << @bytes
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def materialize
|
|
81
|
+
@filler.call_at(@bytes, 0, @bytes.bytesize)&.first || @klass.read(@bytes)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def suffix(_wire)
|
|
85
|
+
EMPTY_SUFFIX
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Bytes of a record that follow its typed layout (declared nSize larger
|
|
90
|
+
# than the layout consumes). Kept verbatim beside the wire.
|
|
91
|
+
EMPTY_SUFFIX = "".b.freeze
|
|
92
|
+
private_constant :EMPTY_SUFFIX
|
|
93
|
+
|
|
94
|
+
def self.suffix_of(record_bytes, wire)
|
|
95
|
+
extra = record_bytes.bytesize - wire.num_bytes
|
|
96
|
+
return EMPTY_SUFFIX unless extra.positive?
|
|
97
|
+
|
|
98
|
+
record_bytes.byteslice(-extra, extra).b.freeze
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def initialize(wire:, offset: nil, suffix: EMPTY_SUFFIX)
|
|
18
102
|
@wire = wire
|
|
19
103
|
@offset = offset
|
|
104
|
+
@suffix = suffix
|
|
20
105
|
end
|
|
21
106
|
|
|
22
|
-
attr_reader :
|
|
107
|
+
attr_reader :offset
|
|
108
|
+
|
|
109
|
+
def wire
|
|
110
|
+
return @wire if @wire
|
|
111
|
+
|
|
112
|
+
@wire = @wire_source.materialize
|
|
113
|
+
@suffix = @wire_source.suffix(@wire)
|
|
114
|
+
@wire_source = nil
|
|
115
|
+
@wire
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def suffix
|
|
119
|
+
wire
|
|
120
|
+
@suffix
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def to_binary_s
|
|
124
|
+
return @wire_source.to_binary_s unless @wire
|
|
125
|
+
|
|
126
|
+
bytes = @wire.to_binary_s
|
|
127
|
+
return bytes if @suffix.empty?
|
|
128
|
+
|
|
129
|
+
bytes[4, 4] = [bytes.bytesize + @suffix.bytesize].pack("V")
|
|
130
|
+
bytes + @suffix
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Appends this record's wire bytes to `out` (a binary String). A record
|
|
134
|
+
# still held as bytes appends them without a copy; once `#wire` has
|
|
135
|
+
# been made the wire is the truth and is packed, so an edit is never
|
|
136
|
+
# served from stale bytes.
|
|
137
|
+
def append_to(out)
|
|
138
|
+
return @wire_source.append_to(out) unless @wire
|
|
139
|
+
|
|
140
|
+
return out if @suffix.empty? && @wire.append_built_to?(out)
|
|
141
|
+
|
|
142
|
+
out << to_binary_s
|
|
143
|
+
end
|
|
23
144
|
|
|
24
145
|
def type_id
|
|
25
|
-
@wire.i_type
|
|
146
|
+
@wire ? @wire.i_type : @wire_source.type_id
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# The wire class of the record, without making the wire.
|
|
150
|
+
def wire_class
|
|
151
|
+
@wire ? @wire.class : @wire_source.wire_class
|
|
26
152
|
end
|
|
27
153
|
|
|
28
154
|
def accept(visitor)
|
|
@@ -30,16 +156,26 @@ module Emf
|
|
|
30
156
|
end
|
|
31
157
|
|
|
32
158
|
def ==(other)
|
|
33
|
-
other.is_a?(self.class) &&
|
|
159
|
+
other.is_a?(self.class) && to_binary_s == other.to_binary_s
|
|
34
160
|
end
|
|
35
161
|
alias eql? ==
|
|
36
162
|
|
|
37
163
|
def hash
|
|
38
|
-
[self.class,
|
|
164
|
+
[self.class, to_binary_s].hash
|
|
39
165
|
end
|
|
40
166
|
|
|
41
167
|
def inspect
|
|
42
|
-
"#<#{self.class.name} type_id=#{type_id} (#{(
|
|
168
|
+
"#<#{self.class.name} type_id=#{type_id} (#{(wire.class.name || '').split('::').last})>"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
private
|
|
172
|
+
|
|
173
|
+
def init_lazy(source, offset)
|
|
174
|
+
@wire = nil
|
|
175
|
+
@offset = offset
|
|
176
|
+
@suffix = EMPTY_SUFFIX
|
|
177
|
+
@wire_source = source
|
|
178
|
+
self
|
|
43
179
|
end
|
|
44
180
|
end
|
|
45
181
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module Model
|
|
5
|
+
module Emr
|
|
6
|
+
# `WireAdapter#values`: the record's field values as plain frozen Ruby
|
|
7
|
+
# objects, without making BinData field objects. See
|
|
8
|
+
# Emf::Emr::Binary::ValueView for the shape.
|
|
9
|
+
module WireValues
|
|
10
|
+
# The field values the record holds now, or nil when its wire class
|
|
11
|
+
# has no value view (variable-layout records such as ExtTextOut,
|
|
12
|
+
# strings, bitmaps and Raw): use `wire` for those.
|
|
13
|
+
#
|
|
14
|
+
# A field of the wire not made yet is still the record's bytes, so
|
|
15
|
+
# the values are unpacked from them (one String#unpack; kept and
|
|
16
|
+
# returned again while no field has been made). A field made through
|
|
17
|
+
# `wire` may have been edited, so it is read from the wire and the
|
|
18
|
+
# rest from the bytes. An edit through `wire` is always reflected.
|
|
19
|
+
# Equal on the Ruby and native backends.
|
|
20
|
+
def values
|
|
21
|
+
view = Emf::Emr::Binary::ValueView.for_class(@wire ? @wire.class : @wire_source.wire_class)
|
|
22
|
+
return unless view
|
|
23
|
+
|
|
24
|
+
data, base, untouched = byte_source
|
|
25
|
+
if data
|
|
26
|
+
found = untouched ? (@values ||= view.from_bytes(data, base)) : view.from_mixed(data, base, @wire)
|
|
27
|
+
return found if found
|
|
28
|
+
end
|
|
29
|
+
view.from_wire(wire)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# [data, offset, untouched] of the bytes the record is filled from.
|
|
35
|
+
def byte_source
|
|
36
|
+
return @wire_source.value_source unless @wire
|
|
37
|
+
|
|
38
|
+
@wire.lazy_source if @wire.respond_to?(:lazy_source)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/emf/model/emr.rb
CHANGED
|
@@ -4,6 +4,20 @@ module Emf
|
|
|
4
4
|
module Model
|
|
5
5
|
module Geometry
|
|
6
6
|
class Color
|
|
7
|
+
# One instantiated ColorRef and its field slots, built on first use.
|
|
8
|
+
module WireTemplate
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def get
|
|
12
|
+
@get ||= begin
|
|
13
|
+
sample = Binary::Types::ColorRef.new
|
|
14
|
+
sample.field_names.each { |name| sample.public_send(name) }
|
|
15
|
+
[sample, Emf::Emr::Binary::WireCopy.slots(sample)].freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
private_constant :WireTemplate
|
|
20
|
+
|
|
7
21
|
def initialize(red:, green:, blue:, alpha: 255)
|
|
8
22
|
@red = coerce(red)
|
|
9
23
|
@green = coerce(green)
|
|
@@ -17,8 +31,12 @@ module Emf
|
|
|
17
31
|
new(red: wire.red, green: wire.green, blue: wire.blue, alpha: wire.reserved.zero? ? 255 : wire.reserved)
|
|
18
32
|
end
|
|
19
33
|
|
|
34
|
+
# Same ColorRef as `ColorRef.new(red:, green:, blue:, reserved:)`,
|
|
35
|
+
# built from a copy of one instantiated ColorRef instead of BinData's
|
|
36
|
+
# lazy construction (the record builders call this once per color).
|
|
20
37
|
def to_wire
|
|
21
|
-
|
|
38
|
+
template, slots = WireTemplate.get
|
|
39
|
+
Emf::Emr::Binary::WireCopy.build(template, slots, { red: red, green: green, blue: blue, reserved: alpha })
|
|
22
40
|
end
|
|
23
41
|
|
|
24
42
|
def to_hex
|
data/lib/emf/model/metafile.rb
CHANGED
|
@@ -5,16 +5,25 @@ module Emf
|
|
|
5
5
|
class Metafile
|
|
6
6
|
include Enumerable
|
|
7
7
|
|
|
8
|
-
def initialize(format:, header:, records:, errors: [], emf_plus: nil, trailing: "")
|
|
8
|
+
def initialize(format:, header:, records:, errors: [], emf_plus: nil, trailing: "", emf_plus_source: nil, diagnostics: [])
|
|
9
9
|
@format = format
|
|
10
10
|
@header = header
|
|
11
11
|
@records = records.freeze
|
|
12
12
|
@errors = errors.freeze
|
|
13
|
+
@diagnostics = diagnostics.dup.freeze
|
|
13
14
|
@emf_plus = emf_plus
|
|
14
15
|
@trailing = trailing.freeze
|
|
16
|
+
@emf_plus_source = emf_plus_source
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
attr_reader :format, :header, :records, :errors, :emf_plus, :trailing
|
|
19
|
+
attr_reader :format, :header, :records, :errors, :emf_plus, :trailing, :diagnostics
|
|
20
|
+
|
|
21
|
+
# Return a new view while retaining backend-specific lazy sources.
|
|
22
|
+
def with_diagnostics(diagnostics)
|
|
23
|
+
copy = dup
|
|
24
|
+
copy.instance_variable_set(:@diagnostics, diagnostics.dup.freeze)
|
|
25
|
+
copy
|
|
26
|
+
end
|
|
18
27
|
|
|
19
28
|
def each(&block)
|
|
20
29
|
return to_enum unless block
|
|
@@ -22,6 +31,17 @@ module Emf
|
|
|
22
31
|
@records.each(&block)
|
|
23
32
|
end
|
|
24
33
|
|
|
34
|
+
# Typed EMF+ view; nil unless this is an EMF+ metafile. Memoised because
|
|
35
|
+
# the metafile is immutable; `reload: true` rebuilds it from the current comment bytes.
|
|
36
|
+
# A backend may supply `emf_plus_source` (called with the metafile and `reload`);
|
|
37
|
+
# a nil result falls back to the Ruby stream.
|
|
38
|
+
def emf_plus_stream(reload: false)
|
|
39
|
+
return unless format == :emf_plus
|
|
40
|
+
|
|
41
|
+
@emf_plus_stream = nil if reload
|
|
42
|
+
@emf_plus_stream ||= @emf_plus_source&.call(self, reload) || Emf::EmfPlus::Stream.from_metafile(self)
|
|
43
|
+
end
|
|
44
|
+
|
|
25
45
|
def errors?
|
|
26
46
|
!@errors.empty?
|
|
27
47
|
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module Model
|
|
5
|
+
module Wmf
|
|
6
|
+
module Records
|
|
7
|
+
# Typed bitmap interior (Emf::Wmf::BitmapImage.of); raw `bitmap` stays authoritative.
|
|
8
|
+
module TypedImage
|
|
9
|
+
def typed_image = Emf::Wmf::BitmapImage.of(self)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class BitBlt < Record
|
|
13
|
+
include TypedImage
|
|
14
|
+
|
|
15
|
+
def initialize(raster_operation:, source_y:, source_x:, height:, width:, destination_y:, destination_x:, bitmap: nil,
|
|
16
|
+
reserved: 0, suffix: "".b, offset: nil, type_id: 0x0922)
|
|
17
|
+
super(type_id: type_id, offset: offset)
|
|
18
|
+
@raster_operation = raster_operation
|
|
19
|
+
@source_y = source_y
|
|
20
|
+
@source_x = source_x
|
|
21
|
+
@height = height
|
|
22
|
+
@width = width
|
|
23
|
+
@destination_y = destination_y
|
|
24
|
+
@destination_x = destination_x
|
|
25
|
+
@bitmap = bitmap
|
|
26
|
+
@reserved = reserved
|
|
27
|
+
@suffix = suffix
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_accessor :raster_operation, :source_y, :source_x, :height, :width, :destination_y, :destination_x, :bitmap, :reserved,
|
|
31
|
+
:suffix
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class DibBitBlt < Record
|
|
35
|
+
include TypedImage
|
|
36
|
+
|
|
37
|
+
def initialize(raster_operation:, source_y:, source_x:, height:, width:, destination_y:, destination_x:, bitmap: nil,
|
|
38
|
+
reserved: 0, suffix: "".b, offset: nil, type_id: 0x0940)
|
|
39
|
+
super(type_id: type_id, offset: offset)
|
|
40
|
+
@raster_operation = raster_operation
|
|
41
|
+
@source_y = source_y
|
|
42
|
+
@source_x = source_x
|
|
43
|
+
@height = height
|
|
44
|
+
@width = width
|
|
45
|
+
@destination_y = destination_y
|
|
46
|
+
@destination_x = destination_x
|
|
47
|
+
@bitmap = bitmap
|
|
48
|
+
@reserved = reserved
|
|
49
|
+
@suffix = suffix
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
attr_accessor :raster_operation, :source_y, :source_x, :height, :width, :destination_y, :destination_x, :bitmap, :reserved,
|
|
53
|
+
:suffix
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class StretchBlt < Record
|
|
57
|
+
include TypedImage
|
|
58
|
+
|
|
59
|
+
def initialize(raster_operation:, source_height:, source_width:, source_y:, source_x:, destination_height:,
|
|
60
|
+
destination_width:, destination_y:, destination_x:, bitmap: nil, reserved: 0, suffix: "".b, offset: nil,
|
|
61
|
+
type_id: 0x0B23)
|
|
62
|
+
super(type_id: type_id, offset: offset)
|
|
63
|
+
@raster_operation = raster_operation
|
|
64
|
+
@source_height = source_height
|
|
65
|
+
@source_width = source_width
|
|
66
|
+
@source_y = source_y
|
|
67
|
+
@source_x = source_x
|
|
68
|
+
@destination_height = destination_height
|
|
69
|
+
@destination_width = destination_width
|
|
70
|
+
@destination_y = destination_y
|
|
71
|
+
@destination_x = destination_x
|
|
72
|
+
@bitmap = bitmap
|
|
73
|
+
@reserved = reserved
|
|
74
|
+
@suffix = suffix
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
attr_accessor :raster_operation, :source_height, :source_width, :source_y, :source_x, :destination_height, :destination_width,
|
|
78
|
+
:destination_y, :destination_x, :bitmap, :reserved, :suffix
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class DibStretchBlt < Record
|
|
82
|
+
include TypedImage
|
|
83
|
+
|
|
84
|
+
def initialize(raster_operation:, source_height:, source_width:, source_y:, source_x:, destination_height:,
|
|
85
|
+
destination_width:, destination_y:, destination_x:, bitmap: nil, reserved: 0, suffix: "".b, offset: nil,
|
|
86
|
+
type_id: 0x0B41)
|
|
87
|
+
super(type_id: type_id, offset: offset)
|
|
88
|
+
@raster_operation = raster_operation
|
|
89
|
+
@source_height = source_height
|
|
90
|
+
@source_width = source_width
|
|
91
|
+
@source_y = source_y
|
|
92
|
+
@source_x = source_x
|
|
93
|
+
@destination_height = destination_height
|
|
94
|
+
@destination_width = destination_width
|
|
95
|
+
@destination_y = destination_y
|
|
96
|
+
@destination_x = destination_x
|
|
97
|
+
@bitmap = bitmap
|
|
98
|
+
@reserved = reserved
|
|
99
|
+
@suffix = suffix
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
attr_accessor :raster_operation, :source_height, :source_width, :source_y, :source_x, :destination_height, :destination_width,
|
|
103
|
+
:destination_y, :destination_x, :bitmap, :reserved, :suffix
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class SetDibToDev < Record
|
|
107
|
+
include TypedImage
|
|
108
|
+
|
|
109
|
+
def initialize(color_usage:, scan_count:, start_scan:, source_y:, source_x:, height:, width:, destination_y:,
|
|
110
|
+
destination_x:, bitmap:, suffix: "".b, offset: nil, type_id: 0x0D33)
|
|
111
|
+
super(type_id: type_id, offset: offset)
|
|
112
|
+
@color_usage = color_usage
|
|
113
|
+
@scan_count = scan_count
|
|
114
|
+
@start_scan = start_scan
|
|
115
|
+
@source_y = source_y
|
|
116
|
+
@source_x = source_x
|
|
117
|
+
@height = height
|
|
118
|
+
@width = width
|
|
119
|
+
@destination_y = destination_y
|
|
120
|
+
@destination_x = destination_x
|
|
121
|
+
@bitmap = bitmap
|
|
122
|
+
@suffix = suffix
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
attr_accessor :color_usage, :scan_count, :start_scan, :source_y, :source_x, :height, :width, :destination_y, :destination_x,
|
|
126
|
+
:bitmap, :suffix
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class StretchDib < Record
|
|
130
|
+
include TypedImage
|
|
131
|
+
|
|
132
|
+
def initialize(raster_operation:, color_usage:, source_height:, source_width:, source_y:, source_x:, destination_height:,
|
|
133
|
+
destination_width:, destination_y:, destination_x:, bitmap:, suffix: "".b, offset: nil, type_id: 0x0F43)
|
|
134
|
+
super(type_id: type_id, offset: offset)
|
|
135
|
+
@raster_operation = raster_operation
|
|
136
|
+
@color_usage = color_usage
|
|
137
|
+
@source_height = source_height
|
|
138
|
+
@source_width = source_width
|
|
139
|
+
@source_y = source_y
|
|
140
|
+
@source_x = source_x
|
|
141
|
+
@destination_height = destination_height
|
|
142
|
+
@destination_width = destination_width
|
|
143
|
+
@destination_y = destination_y
|
|
144
|
+
@destination_x = destination_x
|
|
145
|
+
@bitmap = bitmap
|
|
146
|
+
@suffix = suffix
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
attr_accessor :raster_operation, :color_usage, :source_height, :source_width, :source_y, :source_x, :destination_height,
|
|
150
|
+
:destination_width, :destination_y, :destination_x, :bitmap, :suffix
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module Model
|
|
5
|
+
module Wmf
|
|
6
|
+
module Records
|
|
7
|
+
class CreatePatternBrush < Record
|
|
8
|
+
def initialize(bitmap_type:, width:, height:, width_bytes:, planes:, bits_pixel:, bits:, reserved:, pattern:,
|
|
9
|
+
offset: nil, suffix: "".b, type_id: 0x01F9)
|
|
10
|
+
super(type_id: type_id, offset: offset)
|
|
11
|
+
@bitmap_type = bitmap_type
|
|
12
|
+
@width = width
|
|
13
|
+
@height = height
|
|
14
|
+
@width_bytes = width_bytes
|
|
15
|
+
@planes = planes
|
|
16
|
+
@bits_pixel = bits_pixel
|
|
17
|
+
@bits = bits
|
|
18
|
+
@reserved = reserved
|
|
19
|
+
@pattern = pattern
|
|
20
|
+
@suffix = suffix
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attr_accessor :bitmap_type, :width, :height, :width_bytes, :planes, :bits_pixel, :bits, :reserved, :pattern, :suffix
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class DibCreatePatternBrush < Record
|
|
27
|
+
def initialize(style:, color_usage:, target:, offset: nil, type_id: 0x0142)
|
|
28
|
+
super(type_id: type_id, offset: offset)
|
|
29
|
+
@style = style
|
|
30
|
+
@color_usage = color_usage
|
|
31
|
+
@target = target
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
attr_accessor :style, :color_usage, :target
|
|
35
|
+
|
|
36
|
+
# BS_PATTERN (style 3) ignores the stored color usage and always uses RGB colors.
|
|
37
|
+
def effective_color_usage = style == 3 ? 0 : color_usage
|
|
38
|
+
|
|
39
|
+
# Packed DIB view of the raw target (Emf::Wmf::Dib::Image), or nil if unsupported.
|
|
40
|
+
def target_dib = Emf::Wmf::Dib.parse(target, effective_color_usage)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module Model
|
|
5
|
+
module Wmf
|
|
6
|
+
module Records
|
|
7
|
+
class SaveDc < StateRecord
|
|
8
|
+
WIRE_FIELDS = [].freeze
|
|
9
|
+
WIRE_TYPES = [].freeze
|
|
10
|
+
WIRE_FORMAT = ""
|
|
11
|
+
PAYLOAD_BYTES = 0
|
|
12
|
+
|
|
13
|
+
def initialize(offset: nil, suffix: "".b, type_id: 0x001E)
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class RestoreDc < StateRecord
|
|
19
|
+
WIRE_FIELDS = %i[saved_dc].freeze
|
|
20
|
+
WIRE_TYPES = %i[int16].freeze
|
|
21
|
+
WIRE_FORMAT = "s<"
|
|
22
|
+
PAYLOAD_BYTES = 2
|
|
23
|
+
|
|
24
|
+
def initialize(saved_dc:, offset: nil, suffix: "".b, type_id: 0x0127)
|
|
25
|
+
super(type_id: type_id, offset: offset, suffix: suffix)
|
|
26
|
+
@saved_dc = saved_dc
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
attr_accessor :saved_dc
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Reserved record: every body byte belongs to the preserved suffix.
|
|
33
|
+
class SetRelAbs < StateRecord
|
|
34
|
+
WIRE_FIELDS = [].freeze
|
|
35
|
+
WIRE_TYPES = [].freeze
|
|
36
|
+
WIRE_FORMAT = ""
|
|
37
|
+
PAYLOAD_BYTES = 0
|
|
38
|
+
|
|
39
|
+
def initialize(offset: nil, suffix: "".b, type_id: 0x0105)
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Escape data stays inert, including recognized driver subfunctions.
|
|
45
|
+
class Escape < Record
|
|
46
|
+
def initialize(escape_function:, data:, padding: nil, offset: nil, suffix: "".b, type_id: 0x0626)
|
|
47
|
+
super(type_id: type_id, offset: offset)
|
|
48
|
+
@escape_function = escape_function
|
|
49
|
+
@data = data
|
|
50
|
+
@padding = padding
|
|
51
|
+
@suffix = suffix
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
attr_accessor :escape_function, :data, :padding, :suffix
|
|
55
|
+
|
|
56
|
+
# Read-only typed views; each returns nil when the subtype or layout does not match.
|
|
57
|
+
def typed_payload = Emf::Wmf::EscapeViews.typed_payload(self)
|
|
58
|
+
def typed_counted_payload = Emf::Wmf::EscapeViews.typed_counted_payload(self)
|
|
59
|
+
def typed_special_passthrough2_payload = Emf::Wmf::EscapeViews.typed_special_passthrough2_payload(self)
|
|
60
|
+
|
|
61
|
+
# Validated 0x000F segment; raises Emf::Wmf::EmbeddedEmf::Invalid with a reason.
|
|
62
|
+
def embedded_emf_segment = Emf::Wmf::EmbeddedEmf.segment(self)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module Model
|
|
5
|
+
module Wmf
|
|
6
|
+
module Records
|
|
7
|
+
class CreateFontIndirect < ObjectRecord
|
|
8
|
+
SIGNED_FIELDS = %i[height width escapement orientation weight].freeze
|
|
9
|
+
BYTE_FIELDS = %i[italic underline strike_out char_set out_precision clip_precision quality pitch_and_family].freeze
|
|
10
|
+
WIRE_FIELDS = (SIGNED_FIELDS + BYTE_FIELDS + [:face_name]).freeze
|
|
11
|
+
WIRE_FORMAT = "s<5C8a32"
|
|
12
|
+
PAYLOAD_BYTES = 50
|
|
13
|
+
|
|
14
|
+
def initialize(height:, width:, escapement:, orientation:, weight:, italic:, underline:, strike_out:,
|
|
15
|
+
char_set:, out_precision:, clip_precision:, quality:, pitch_and_family:, face_name:,
|
|
16
|
+
offset: nil, type_id: 0x02FB, suffix: "")
|
|
17
|
+
super(type_id: type_id, offset: offset)
|
|
18
|
+
@height = height
|
|
19
|
+
@width = width
|
|
20
|
+
@escapement = escapement
|
|
21
|
+
@orientation = orientation
|
|
22
|
+
@weight = weight
|
|
23
|
+
@italic = italic
|
|
24
|
+
@underline = underline
|
|
25
|
+
@strike_out = strike_out
|
|
26
|
+
@char_set = char_set
|
|
27
|
+
@out_precision = out_precision
|
|
28
|
+
@clip_precision = clip_precision
|
|
29
|
+
@quality = quality
|
|
30
|
+
@pitch_and_family = pitch_and_family
|
|
31
|
+
@face_name = face_name
|
|
32
|
+
@suffix = suffix
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
attr_accessor(*WIRE_FIELDS, :suffix)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|