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
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/binary/float32_le"
|
|
5
|
+
require "emf/emf_plus/records/primitives/bounded_array"
|
|
6
|
+
|
|
7
|
+
module Emf
|
|
8
|
+
module EmfPlus
|
|
9
|
+
module Records
|
|
10
|
+
module Primitives
|
|
11
|
+
# EmfPlusBlendFactors (2.2.2.5).
|
|
12
|
+
class BlendFactors < Body
|
|
13
|
+
endian :little
|
|
14
|
+
uint32 :position_count
|
|
15
|
+
bounded_array :blend_positions, type: :float32_le, element_size: 4, initial_length: :position_count
|
|
16
|
+
bounded_array :blend_factors, type: :float32_le, element_size: 4, initial_length: :position_count
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# A BinData array whose untrusted `initial_length` is checked against
|
|
10
|
+
# the bytes left in the stream before any element is built. Each
|
|
11
|
+
# element takes at least `element_size` bytes, so a count that cannot
|
|
12
|
+
# fit raises EOFError (an IOError, the signal a short read already
|
|
13
|
+
# gives) instead of allocating count elements.
|
|
14
|
+
class BoundedArray < BinData::Array
|
|
15
|
+
# Extended onto each instance after the initial-length plugin, so
|
|
16
|
+
# its do_read runs first.
|
|
17
|
+
module Guard
|
|
18
|
+
def do_read(io)
|
|
19
|
+
count = eval_parameter(:initial_length)
|
|
20
|
+
needed = count * eval_parameter(:element_size)
|
|
21
|
+
left = io.num_bytes_remaining
|
|
22
|
+
raise EOFError, "#{count} elements need at least #{needed} bytes, #{left} left" if needed > left
|
|
23
|
+
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
mandatory_parameter :element_size
|
|
29
|
+
|
|
30
|
+
def initialize_shared_instance
|
|
31
|
+
super
|
|
32
|
+
extend Guard
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module EmfPlus
|
|
5
|
+
module Records
|
|
6
|
+
module Primitives
|
|
7
|
+
# Reads exact byte counts from a StringIO for the hand-parsed
|
|
8
|
+
# structures; a short read raises EOFError (an IOError), the same
|
|
9
|
+
# signal BinData gives, so callers map it to ParseError once.
|
|
10
|
+
module ByteReader
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def take(io, count, what)
|
|
14
|
+
bytes = io.read(count)
|
|
15
|
+
return bytes if bytes && bytes.bytesize == count
|
|
16
|
+
|
|
17
|
+
raise EOFError, "#{what} needs #{count} bytes, #{io.size - io.pos} left"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def remaining(io) = io.size - io.pos
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusCharacterRange (2.2.2.8).
|
|
10
|
+
# BinData reserves `first` and `length`, so the spec names First and
|
|
11
|
+
# Length are first_position and range_length here.
|
|
12
|
+
class CharacterRange < Body
|
|
13
|
+
endian :little
|
|
14
|
+
int32 :first_position
|
|
15
|
+
int32 :range_length
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusCompressedImage (2.2.2.10).
|
|
10
|
+
class CompressedImage < Body
|
|
11
|
+
endian :little
|
|
12
|
+
rest :compressed_image_data
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/binary/float32_le"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module EmfPlus
|
|
8
|
+
module Records
|
|
9
|
+
module Primitives
|
|
10
|
+
# EmfPlusFocusScaleData (2.2.2.18).
|
|
11
|
+
class FocusScaleData < Body
|
|
12
|
+
endian :little
|
|
13
|
+
uint32 :focus_scale_count
|
|
14
|
+
float32_le :focus_scale_x
|
|
15
|
+
float32_le :focus_scale_y
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusGraphicsVersion (2.2.2.19): 20-bit MetafileSignature (0xDBC01)
|
|
10
|
+
# above a 12-bit GraphicsVersion in one little-endian dword.
|
|
11
|
+
class GraphicsVersion < Body
|
|
12
|
+
endian :little
|
|
13
|
+
uint32 :raw
|
|
14
|
+
|
|
15
|
+
def metafile_signature = raw >> 12
|
|
16
|
+
def graphics_version = raw & 0xFFF
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusLanguageIdentifier (2.2.2.23): 6-bit SubLanguageId above a
|
|
10
|
+
# 10-bit PrimaryLanguageId. The containing objects reserve a full
|
|
11
|
+
# dword for it, so the whole dword is kept.
|
|
12
|
+
class LanguageIdentifier < Body
|
|
13
|
+
endian :little
|
|
14
|
+
uint32 :raw
|
|
15
|
+
|
|
16
|
+
def primary_language_id = raw & 0x3FF
|
|
17
|
+
def sub_language_id = (raw >> 10) & 0x3F
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusMetafile (2.2.2.27).
|
|
10
|
+
class Metafile < Body
|
|
11
|
+
endian :little
|
|
12
|
+
uint32 :metafile_type
|
|
13
|
+
uint32 :metafile_data_size
|
|
14
|
+
string :metafile_data, read_length: :metafile_data_size
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emf_plus/records/primitives/bounded_array"
|
|
5
|
+
require "emf/emf_plus/records/primitives/argb"
|
|
6
|
+
|
|
7
|
+
module Emf
|
|
8
|
+
module EmfPlus
|
|
9
|
+
module Records
|
|
10
|
+
module Primitives
|
|
11
|
+
# EmfPlusPalette (2.2.2.28).
|
|
12
|
+
class Palette < Body
|
|
13
|
+
endian :little
|
|
14
|
+
uint32 :palette_style_flags
|
|
15
|
+
uint32 :palette_count
|
|
16
|
+
bounded_array :palette_entries, type: :argb, element_size: 4, initial_length: :palette_count
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
require "emf/emf_plus/records/primitives/byte_reader"
|
|
5
|
+
require "emf/emf_plus/records/primitives/graphics_version"
|
|
6
|
+
require "emf/emf_plus/records/primitives/path_point_type"
|
|
7
|
+
require "emf/emf_plus/records/primitives/path_point_type_rle"
|
|
8
|
+
require "emf/emf_plus/records/primitives/point_array"
|
|
9
|
+
|
|
10
|
+
module Emf
|
|
11
|
+
module EmfPlus
|
|
12
|
+
module Records
|
|
13
|
+
module Primitives
|
|
14
|
+
# EmfPlusPath (2.2.1.6) without its AlignmentPadding, which the caller
|
|
15
|
+
# keeps. Same surface as a BinData record (`read`, `num_bytes`,
|
|
16
|
+
# `to_binary_s`); hand-parsed because the point and type encodings are
|
|
17
|
+
# chosen by the flags and the RLE run list has no stored length.
|
|
18
|
+
class Path
|
|
19
|
+
include ByteReader
|
|
20
|
+
|
|
21
|
+
RELATIVE_FLAG = 0x0800
|
|
22
|
+
COMPRESSED_FLAG = 0x4000
|
|
23
|
+
HEADER_SIZE = 12
|
|
24
|
+
MIN_POINT_SIZE = { relative: 2, compressed: 4, float: 8 }.freeze
|
|
25
|
+
private_constant :MIN_POINT_SIZE
|
|
26
|
+
|
|
27
|
+
attr_reader :version, :point_count, :flags, :points, :point_types
|
|
28
|
+
|
|
29
|
+
def read(source)
|
|
30
|
+
io = StringIO.new(source)
|
|
31
|
+
@version = GraphicsVersion.new.read(io)
|
|
32
|
+
@point_count, @flags = take(io, 8, "PathPointCount and PathPointFlags").unpack("VV")
|
|
33
|
+
require_room(io)
|
|
34
|
+
@points = PointArray.new(point_count: point_count, relative: relative?, compressed: compressed?).read(io)
|
|
35
|
+
@point_types = relative? ? read_runs(io) : read_types(io)
|
|
36
|
+
@size = io.pos
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def relative? = flags.anybits?(RELATIVE_FLAG)
|
|
41
|
+
# The C flag is undefined, and ignored, when R is set.
|
|
42
|
+
def compressed? = !relative? && flags.anybits?(COMPRESSED_FLAG)
|
|
43
|
+
def num_bytes = @size
|
|
44
|
+
|
|
45
|
+
def to_binary_s
|
|
46
|
+
version.to_binary_s + [point_count, flags].pack("VV") + points.to_binary_s +
|
|
47
|
+
point_types.map(&:to_binary_s).join
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def point_kind
|
|
53
|
+
if relative? then :relative
|
|
54
|
+
elsif compressed? then :compressed
|
|
55
|
+
else :float
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def require_room(io)
|
|
60
|
+
needed = (point_count * MIN_POINT_SIZE.fetch(point_kind)) + min_type_bytes
|
|
61
|
+
return if needed <= remaining(io)
|
|
62
|
+
|
|
63
|
+
raise EOFError, "#{point_count} path points need at least #{needed} bytes, #{remaining(io)} left"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def min_type_bytes
|
|
67
|
+
return point_count unless relative?
|
|
68
|
+
|
|
69
|
+
point_count.zero? ? 0 : PathPointTypeRLE.new.num_bytes
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def read_types(io)
|
|
73
|
+
Array.new(point_count) { PathPointType.new.read(io) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def read_runs(io)
|
|
77
|
+
covered = 0
|
|
78
|
+
runs = []
|
|
79
|
+
while covered < point_count
|
|
80
|
+
runs << PathPointTypeRLE.new.read(io)
|
|
81
|
+
covered += runs.last.run_count
|
|
82
|
+
end
|
|
83
|
+
runs
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusPathPointType (2.2.2.31): flags in the high nibble, the
|
|
10
|
+
# PathPointType enumeration in the low nibble.
|
|
11
|
+
class PathPointType < Body
|
|
12
|
+
endian :little
|
|
13
|
+
uint8 :raw
|
|
14
|
+
|
|
15
|
+
def flags = raw >> 4
|
|
16
|
+
def type = raw & 0x0F
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emf_plus/records/primitives/path_point_type"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module EmfPlus
|
|
8
|
+
module Records
|
|
9
|
+
module Primitives
|
|
10
|
+
# EmfPlusPathPointTypeRLE (2.2.2.32): a Bezier bit, a reserved bit and
|
|
11
|
+
# a 6-bit run count, then the type shared by that many points.
|
|
12
|
+
class PathPointTypeRLE < Body
|
|
13
|
+
endian :little
|
|
14
|
+
uint8 :header
|
|
15
|
+
path_point_type :point_type
|
|
16
|
+
|
|
17
|
+
def bezier? = header.anybits?(0x80)
|
|
18
|
+
def run_count = header & 0x3F
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusPoint (2.2.2.35): 16-bit signed, the "compressed" form.
|
|
10
|
+
class Point < Body
|
|
11
|
+
endian :little
|
|
12
|
+
int16 :x
|
|
13
|
+
int16 :y
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emf_plus/records/primitives/bounded_array"
|
|
5
|
+
require "emf/emf_plus/records/primitives/point"
|
|
6
|
+
require "emf/emf_plus/records/primitives/point_f"
|
|
7
|
+
require "emf/emf_plus/records/primitives/point_r"
|
|
8
|
+
|
|
9
|
+
module Emf
|
|
10
|
+
module EmfPlus
|
|
11
|
+
module Records
|
|
12
|
+
module Primitives
|
|
13
|
+
# `point_count` points in the form the record flags select: relative
|
|
14
|
+
# (PointR) wins over compressed (Point); otherwise PointF.
|
|
15
|
+
class PointArray < Body
|
|
16
|
+
endian :little
|
|
17
|
+
mandatory_parameter :point_count, :relative, :compressed
|
|
18
|
+
bounded_array :relative_points, type: PointR, element_size: 2, initial_length: :point_count, onlyif: -> { relative }
|
|
19
|
+
bounded_array :compressed_points, type: Point, element_size: 4, initial_length: :point_count, onlyif: lambda {
|
|
20
|
+
!relative && compressed
|
|
21
|
+
}
|
|
22
|
+
bounded_array :float_points, type: PointF, element_size: 8, initial_length: :point_count, onlyif: -> { !relative && !compressed }
|
|
23
|
+
|
|
24
|
+
def points
|
|
25
|
+
if relative
|
|
26
|
+
relative_points
|
|
27
|
+
elsif compressed
|
|
28
|
+
compressed_points
|
|
29
|
+
else
|
|
30
|
+
float_points
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def relative = eval_parameter(:relative)
|
|
37
|
+
def compressed = eval_parameter(:compressed)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/binary/float32_le"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module EmfPlus
|
|
8
|
+
module Records
|
|
9
|
+
module Primitives
|
|
10
|
+
# EmfPlusPointF (2.2.2.36): 32-bit floats.
|
|
11
|
+
class PointF < Body
|
|
12
|
+
endian :little
|
|
13
|
+
float32_le :x
|
|
14
|
+
float32_le :y
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emf_plus/records/primitives/relative_coordinate"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module EmfPlus
|
|
8
|
+
module Records
|
|
9
|
+
module Primitives
|
|
10
|
+
# EmfPlusPointR (2.2.2.37): relative location, each axis 7 or 15 bits.
|
|
11
|
+
class PointR < Body
|
|
12
|
+
endian :little
|
|
13
|
+
relative_coordinate :x
|
|
14
|
+
relative_coordinate :y
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
|
|
5
|
+
module Emf
|
|
6
|
+
module EmfPlus
|
|
7
|
+
module Records
|
|
8
|
+
module Primitives
|
|
9
|
+
# EmfPlusRect (2.2.2.39): 16-bit signed, the "compressed" form.
|
|
10
|
+
class Rect < Body
|
|
11
|
+
endian :little
|
|
12
|
+
int16 :x
|
|
13
|
+
int16 :y
|
|
14
|
+
int16 :width
|
|
15
|
+
int16 :height
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emf_plus/records/primitives/bounded_array"
|
|
5
|
+
require "emf/emf_plus/records/primitives/rect"
|
|
6
|
+
require "emf/emf_plus/records/primitives/rect_f"
|
|
7
|
+
|
|
8
|
+
module Emf
|
|
9
|
+
module EmfPlus
|
|
10
|
+
module Records
|
|
11
|
+
module Primitives
|
|
12
|
+
# `rect_count` rectangles, Rect when compressed and RectF otherwise.
|
|
13
|
+
class RectArray < Body
|
|
14
|
+
endian :little
|
|
15
|
+
mandatory_parameter :rect_count, :compressed
|
|
16
|
+
bounded_array :compressed_rects, type: Rect, element_size: 8, initial_length: :rect_count, onlyif: -> { compressed }
|
|
17
|
+
bounded_array :float_rects, type: RectF, element_size: 16, initial_length: :rect_count, onlyif: -> { !compressed }
|
|
18
|
+
|
|
19
|
+
def rects = eval_parameter(:compressed) ? compressed_rects : float_rects
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/binary/float32_le"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module EmfPlus
|
|
8
|
+
module Records
|
|
9
|
+
module Primitives
|
|
10
|
+
# EmfPlusRectF (2.2.2.40): 32-bit floats.
|
|
11
|
+
class RectF < Body
|
|
12
|
+
endian :little
|
|
13
|
+
float32_le :x
|
|
14
|
+
float32_le :y
|
|
15
|
+
float32_le :width
|
|
16
|
+
float32_le :height
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
require "bindata"
|
|
5
|
+
require "emf/emf_plus/records/primitives/byte_reader"
|
|
6
|
+
require "emf/emf_plus/records/primitives/rect_f"
|
|
7
|
+
require "emf/emf_plus/records/primitives/region_node_child_nodes"
|
|
8
|
+
require "emf/emf_plus/records/primitives/region_node_path"
|
|
9
|
+
|
|
10
|
+
module Emf
|
|
11
|
+
module EmfPlus
|
|
12
|
+
module Records
|
|
13
|
+
module Primitives
|
|
14
|
+
# EmfPlusRegionNode (2.2.2.40): a RegionNodeDataType, then data chosen
|
|
15
|
+
# by it: two child nodes (And/Or/Xor/Exclude/Complement), a RectF, a
|
|
16
|
+
# RegionNodePath, or nothing (Empty/Infinite).
|
|
17
|
+
class RegionNode
|
|
18
|
+
include ByteReader
|
|
19
|
+
|
|
20
|
+
COMBINING = [0x1, 0x2, 0x3, 0x4, 0x5].freeze
|
|
21
|
+
RECT = 0x10000000
|
|
22
|
+
PATH = 0x10000001
|
|
23
|
+
EMPTY = 0x10000002
|
|
24
|
+
INFINITE = 0x10000003
|
|
25
|
+
MAX_DEPTH = 256
|
|
26
|
+
|
|
27
|
+
attr_reader :type, :data
|
|
28
|
+
|
|
29
|
+
def initialize(depth = 0)
|
|
30
|
+
@depth = depth
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def read(io)
|
|
34
|
+
raise BinData::ValidityError, "region nodes nested deeper than #{MAX_DEPTH} levels" if @depth > MAX_DEPTH
|
|
35
|
+
|
|
36
|
+
@type = take(io, 4, "RegionNode Type").unpack1("V")
|
|
37
|
+
@data = read_data(io)
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def combining? = COMBINING.include?(type)
|
|
42
|
+
def to_binary_s = [type].pack("V") + (data ? data.to_binary_s : "".b)
|
|
43
|
+
|
|
44
|
+
# Nodes in this subtree, itself included.
|
|
45
|
+
def node_count = 1 + (combining? ? data.left.node_count + data.right.node_count : 0)
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def read_data(io)
|
|
50
|
+
case type
|
|
51
|
+
when *COMBINING then read_children(io)
|
|
52
|
+
when RECT then RectF.new.read(io)
|
|
53
|
+
when PATH then RegionNodePath.new.read(io)
|
|
54
|
+
when EMPTY, INFINITE then nil
|
|
55
|
+
else raise BinData::ValidityError, "unknown RegionNodeDataType 0x#{type.to_s(16)}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def read_children(io)
|
|
60
|
+
RegionNodeChildNodes.new(child(io), child(io))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def child(io) = self.class.new(@depth + 1).read(io)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emf
|
|
4
|
+
module EmfPlus
|
|
5
|
+
module Records
|
|
6
|
+
module Primitives
|
|
7
|
+
# EmfPlusRegionNodeChildNodes (2.2.2.41): the two subtrees of a
|
|
8
|
+
# combining node. RegionNode builds it, since the subtrees are nodes.
|
|
9
|
+
class RegionNodeChildNodes
|
|
10
|
+
attr_reader :left, :right
|
|
11
|
+
|
|
12
|
+
def initialize(left, right)
|
|
13
|
+
@left = left
|
|
14
|
+
@right = right
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_binary_s = left.to_binary_s + right.to_binary_s
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
require "emf/emf_plus/records/primitives/byte_reader"
|
|
5
|
+
require "emf/emf_plus/records/primitives/path"
|
|
6
|
+
|
|
7
|
+
module Emf
|
|
8
|
+
module EmfPlus
|
|
9
|
+
module Records
|
|
10
|
+
module Primitives
|
|
11
|
+
# EmfPlusRegionNodePath (2.2.2.42): a byte length, then an EmfPlusPath
|
|
12
|
+
# filling it. Bytes of the length the path does not use (its
|
|
13
|
+
# alignment padding) stay in `padding`.
|
|
14
|
+
class RegionNodePath
|
|
15
|
+
include ByteReader
|
|
16
|
+
|
|
17
|
+
attr_reader :path, :padding
|
|
18
|
+
|
|
19
|
+
def read(io)
|
|
20
|
+
length = take(io, 4, "RegionNodePathLength").unpack1("l<")
|
|
21
|
+
raise BinData::ValidityError, "negative RegionNodePathLength #{length}" if length.negative?
|
|
22
|
+
|
|
23
|
+
bytes = take(io, length, "RegionNodePath of #{length} bytes")
|
|
24
|
+
@path = Path.new.read(bytes)
|
|
25
|
+
@padding = bytes.byteslice(path.num_bytes..)
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_binary_s
|
|
30
|
+
body = path.to_binary_s + padding
|
|
31
|
+
[body.bytesize].pack("V") + body
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|