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
|
@@ -7,9 +7,46 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# Universal font identifiers retain their original byte representation.
|
|
11
11
|
class ForceUfiMapping < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
[[:ufi_checksum, 0], [:ufi_index, 4]].each do |name, offset|
|
|
15
|
+
define_method(name) { ufi_body.byteslice(offset, 4).unpack1("V") }
|
|
16
|
+
define_method("#{name}=") do |value|
|
|
17
|
+
ufi_body
|
|
18
|
+
raise ArgumentError, "UFI value must be an Integer" unless value.is_a?(Integer)
|
|
19
|
+
raise RangeError, "UFI value must fit an unsigned 32-bit integer" unless (0..0xFFFFFFFF).cover?(value)
|
|
20
|
+
|
|
21
|
+
replace_ufi_bytes(offset, 4, [value].pack("V"))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def ufi_bytes
|
|
26
|
+
ufi_body.byteslice(0, 8).b
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def ufi_bytes=(value)
|
|
30
|
+
replace_ufi_bytes(0, 8, value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def ufi_body
|
|
36
|
+
bytes = body.to_s
|
|
37
|
+
raise ArgumentError, "truncated universal font identifier" if bytes.bytesize < 8
|
|
38
|
+
|
|
39
|
+
bytes
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def replace_ufi_bytes(offset, length, value)
|
|
43
|
+
bytes = ufi_body
|
|
44
|
+
raise ArgumentError, "UFI value must be a String of #{length} bytes" unless value.is_a?(String) && value.bytesize == length
|
|
45
|
+
|
|
46
|
+
replacement = bytes.b
|
|
47
|
+
replacement[offset, length] = value.b
|
|
48
|
+
self.body = replacement
|
|
49
|
+
end
|
|
13
50
|
end
|
|
14
51
|
end
|
|
15
52
|
end
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
-
require "emf/emr/binary/
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
5
|
+
require "emf/emr/binary/with_bounds"
|
|
6
|
+
require "emf/emr/binary/region_data"
|
|
5
7
|
|
|
6
8
|
module Emf
|
|
7
9
|
module Emr
|
|
8
10
|
module Binary
|
|
9
11
|
module Records
|
|
10
|
-
class FrameRgn < Emf::Emr::Binary::
|
|
12
|
+
class FrameRgn < Emf::Emr::Binary::WithBounds
|
|
13
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
14
|
+
|
|
15
|
+
fixed_layout 40
|
|
16
|
+
variable_buffer :region_bytes, offset: 40, length: :cb_rgn_data
|
|
17
|
+
|
|
18
|
+
uint32 :cb_rgn_data
|
|
11
19
|
uint32 :ih_brush
|
|
20
|
+
size_l :szl_stroke
|
|
21
|
+
region_data :rgn_data, byte_length: :cb_rgn_data
|
|
12
22
|
rest :body
|
|
13
23
|
end
|
|
14
24
|
end
|
|
@@ -7,9 +7,69 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# EMR_GLSBOUNDEDRECORD (MS-EMF 2.3.5.23).
|
|
11
11
|
class GlsBoundedRecord < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
def bounds
|
|
15
|
+
gls_body.byteslice(0, 16).b
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def bounds=(value)
|
|
19
|
+
write_gls_bytes(0, 16, value)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def cb_data
|
|
23
|
+
gls_body.byteslice(16, 4).unpack1("V")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def data_bytes
|
|
27
|
+
read_gls_data
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def data_bytes=(value)
|
|
31
|
+
write_gls_data(value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def gls_body
|
|
37
|
+
bytes = body.to_s
|
|
38
|
+
raise ArgumentError, "truncated bounded GLS record prefix" if bytes.bytesize < 20
|
|
39
|
+
|
|
40
|
+
bytes
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def read_gls_data
|
|
44
|
+
bytes = gls_body
|
|
45
|
+
length = bytes.byteslice(16, 4).unpack1("V")
|
|
46
|
+
raise ArgumentError, "truncated bounded GLS record data" if 20 + length > bytes.bytesize
|
|
47
|
+
|
|
48
|
+
bytes.byteslice(20, length).b
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def write_gls_data(value)
|
|
52
|
+
read_gls_data
|
|
53
|
+
length = cb_data
|
|
54
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
55
|
+
raise ArgumentError, "bounded GLS data must be a String of #{length} bytes"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
bytes = body.to_s.b
|
|
59
|
+
bytes[20, length] = value.b
|
|
60
|
+
self.body = bytes
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def write_gls_bytes(offset, length, value)
|
|
64
|
+
gls_body
|
|
65
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
66
|
+
raise ArgumentError, "bounded GLS value must be a String of #{length} bytes"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
bytes = body.to_s.b
|
|
70
|
+
bytes[offset, length] = value.b
|
|
71
|
+
self.body = bytes
|
|
72
|
+
end
|
|
13
73
|
end
|
|
14
74
|
end
|
|
15
75
|
end
|
|
@@ -7,9 +7,50 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# EMR_GLSRECORD (MS-EMF 2.3.5.24).
|
|
11
11
|
class GlsRecord < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
def cb_data
|
|
15
|
+
gls_body(4).byteslice(0, 4).unpack1("V")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def data_bytes
|
|
19
|
+
read_gls_data(4)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def data_bytes=(value)
|
|
23
|
+
write_gls_data(4, value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def gls_body(prefix_length)
|
|
29
|
+
bytes = body.to_s
|
|
30
|
+
raise ArgumentError, "truncated GLS record prefix" if bytes.bytesize < prefix_length
|
|
31
|
+
|
|
32
|
+
bytes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def read_gls_data(prefix_length)
|
|
36
|
+
bytes = gls_body(prefix_length)
|
|
37
|
+
length = bytes.byteslice(0, 4).unpack1("V")
|
|
38
|
+
raise ArgumentError, "truncated GLS record data" if prefix_length + length > bytes.bytesize
|
|
39
|
+
|
|
40
|
+
bytes.byteslice(prefix_length, length).b
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def write_gls_data(prefix_length, value)
|
|
44
|
+
read_gls_data(prefix_length)
|
|
45
|
+
length = cb_data
|
|
46
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
47
|
+
raise ArgumentError, "GLS record data must be a String of #{length} bytes"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
bytes = body.to_s.b
|
|
51
|
+
bytes[prefix_length, length] = value.b
|
|
52
|
+
self.body = bytes
|
|
53
|
+
end
|
|
13
54
|
end
|
|
14
55
|
end
|
|
15
56
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
4
5
|
require "emf/emr/binary/with_bounds"
|
|
5
6
|
|
|
6
7
|
module Emf
|
|
@@ -8,6 +9,12 @@ module Emf
|
|
|
8
9
|
module Binary
|
|
9
10
|
module Records
|
|
10
11
|
class GradientFill < Emf::Emr::Binary::WithBounds
|
|
12
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
13
|
+
|
|
14
|
+
fixed_layout 36
|
|
15
|
+
variable_buffer :vertex_bytes, offset: 36, length: -> { n_ver * 16 }
|
|
16
|
+
variable_buffer :mesh_bytes, offset: -> { 36 + (n_ver * 16) }, length: -> { n_tri * (ul_mode == 2 ? 12 : 8) }
|
|
17
|
+
|
|
11
18
|
uint32 :n_ver
|
|
12
19
|
uint32 :n_tri
|
|
13
20
|
uint32 :ul_mode
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
-
require "emf/emr/binary/
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
5
|
+
require "emf/emr/binary/with_bounds"
|
|
6
|
+
require "emf/emr/binary/region_data"
|
|
5
7
|
|
|
6
8
|
module Emf
|
|
7
9
|
module Emr
|
|
8
10
|
module Binary
|
|
9
11
|
module Records
|
|
10
|
-
class InvertRgn < Emf::Emr::Binary::
|
|
11
|
-
|
|
12
|
+
class InvertRgn < Emf::Emr::Binary::WithBounds
|
|
13
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
14
|
+
|
|
15
|
+
fixed_layout 28
|
|
16
|
+
variable_buffer :region_bytes, offset: 28, length: :cb_rgn_data
|
|
17
|
+
|
|
18
|
+
uint32 :cb_rgn_data
|
|
19
|
+
region_data :rgn_data, byte_length: :cb_rgn_data
|
|
12
20
|
rest :body
|
|
13
21
|
end
|
|
14
22
|
end
|
|
@@ -1,15 +1,81 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
4
5
|
require "emf/emr/binary/with_bounds"
|
|
6
|
+
require "emf/emr/binary/dib_header"
|
|
5
7
|
|
|
6
8
|
module Emf
|
|
7
9
|
module Emr
|
|
8
10
|
module Binary
|
|
9
11
|
module Records
|
|
10
12
|
# Stub: leading fields per MS-EMF, body captures remaining bytes.
|
|
13
|
+
# The fixed part is 128 bytes including the EMR header; the bitmap
|
|
14
|
+
# pointers are read from body without declaring fields.
|
|
11
15
|
class MaskBlt < Emf::Emr::Binary::WithBounds
|
|
16
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
17
|
+
|
|
18
|
+
fixed_layout 128
|
|
19
|
+
variable_buffer :bmi_bytes, offset: :off_bmi_src, length: :cb_bmi_src
|
|
20
|
+
variable_buffer :bits_bytes, offset: :off_bits_src, length: :cb_bits_src
|
|
21
|
+
variable_buffer :mask_bmi_bytes, offset: :off_bmi_mask, length: :cb_bmi_mask
|
|
22
|
+
variable_buffer :mask_bits_bytes, offset: :off_bits_mask, length: :cb_bits_mask
|
|
23
|
+
|
|
12
24
|
rest :body
|
|
25
|
+
|
|
26
|
+
# Read-only accessors computed from body on each call; body starts at
|
|
27
|
+
# record offset 24, so a record offset maps to (offset - 24) in body.
|
|
28
|
+
def off_bmi_src
|
|
29
|
+
pointers(60)[0]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cb_bmi_src
|
|
33
|
+
pointers(60)[1]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def off_bits_src
|
|
37
|
+
pointers(60)[2]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def cb_bits_src
|
|
41
|
+
pointers(60)[3]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def off_bmi_mask
|
|
45
|
+
pointers(88)[0]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def cb_bmi_mask
|
|
49
|
+
pointers(88)[1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def off_bits_mask
|
|
53
|
+
pointers(88)[2]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def cb_bits_mask
|
|
57
|
+
pointers(88)[3]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def dib_header_view
|
|
61
|
+
DibHeader.view(off_bmi_src, cb_bmi_src, 128, after_fixed,
|
|
62
|
+
bits_offset: off_bits_src, bits_size: cb_bits_src)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def mask_dib_header_view
|
|
66
|
+
DibHeader.view(off_bmi_mask, cb_bmi_mask, 128, after_fixed,
|
|
67
|
+
bits_offset: off_bits_mask, bits_size: cb_bits_mask)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def after_fixed
|
|
73
|
+
body.to_s.byteslice(104..).to_s
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def pointers(offset)
|
|
77
|
+
body.to_s.byteslice(offset, 16).to_s.unpack("V4").map(&:to_i)
|
|
78
|
+
end
|
|
13
79
|
end
|
|
14
80
|
end
|
|
15
81
|
end
|
|
@@ -7,9 +7,86 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# Body-backed byte spans retain the driver's raw name, data and padding.
|
|
11
11
|
class NamedEscape < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
def i_escape
|
|
15
|
+
named_escape_body.byteslice(0, 4).unpack1("V")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def i_escape=(value)
|
|
19
|
+
bytes = named_escape_body
|
|
20
|
+
raise ArgumentError, "i_escape must be an Integer" unless value.is_a?(Integer)
|
|
21
|
+
raise RangeError, "i_escape must fit in an unsigned 32-bit field" unless value.between?(0, 0xFFFFFFFF)
|
|
22
|
+
|
|
23
|
+
bytes[0, 4] = [value].pack("V")
|
|
24
|
+
self.body = bytes
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def cj_driver
|
|
28
|
+
named_escape_body.byteslice(4, 4).unpack1("V")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def cj_in
|
|
32
|
+
named_escape_body.byteslice(8, 4).unpack1("V")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def driver_name_bytes
|
|
36
|
+
bytes = named_escape_body
|
|
37
|
+
length = bytes.byteslice(4, 4).unpack1("V")
|
|
38
|
+
validate_span!(bytes, 12, length, "driver name")
|
|
39
|
+
bytes.byteslice(12, length).b
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def driver_name_bytes=(value)
|
|
43
|
+
bytes = named_escape_body
|
|
44
|
+
length = bytes.byteslice(4, 4).unpack1("V")
|
|
45
|
+
validate_span!(bytes, 12, length, "driver name")
|
|
46
|
+
validate_bytes!(value, length, "driver name")
|
|
47
|
+
bytes[12, length] = value.b
|
|
48
|
+
self.body = bytes
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def data_bytes
|
|
52
|
+
bytes = named_escape_body
|
|
53
|
+
driver_length = bytes.byteslice(4, 4).unpack1("V")
|
|
54
|
+
data_length = bytes.byteslice(8, 4).unpack1("V")
|
|
55
|
+
data_offset = 12 + driver_length
|
|
56
|
+
validate_span!(bytes, 12, driver_length, "driver name")
|
|
57
|
+
validate_span!(bytes, data_offset, data_length, "data")
|
|
58
|
+
bytes.byteslice(data_offset, data_length).b
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def data_bytes=(value)
|
|
62
|
+
bytes = named_escape_body
|
|
63
|
+
driver_length = bytes.byteslice(4, 4).unpack1("V")
|
|
64
|
+
data_length = bytes.byteslice(8, 4).unpack1("V")
|
|
65
|
+
data_offset = 12 + driver_length
|
|
66
|
+
validate_span!(bytes, 12, driver_length, "driver name")
|
|
67
|
+
validate_span!(bytes, data_offset, data_length, "data")
|
|
68
|
+
validate_bytes!(value, data_length, "data")
|
|
69
|
+
bytes[data_offset, data_length] = value.b
|
|
70
|
+
self.body = bytes
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def named_escape_body
|
|
76
|
+
bytes = body.to_s.b
|
|
77
|
+
raise ArgumentError, "truncated named escape prefix" if bytes.bytesize < 12
|
|
78
|
+
|
|
79
|
+
bytes
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def validate_span!(bytes, offset, length, name)
|
|
83
|
+
raise ArgumentError, "truncated named escape #{name}" if length > bytes.bytesize - offset
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def validate_bytes!(value, length, name)
|
|
87
|
+
valid = value.is_a?(String) && value.bytesize == length
|
|
88
|
+
raise ArgumentError, "#{name} must be a String of #{length} bytes" unless valid
|
|
89
|
+
end
|
|
13
90
|
end
|
|
14
91
|
end
|
|
15
92
|
end
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
-
require "emf/emr/binary/
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
5
|
+
require "emf/emr/binary/with_bounds"
|
|
6
|
+
require "emf/emr/binary/region_data"
|
|
5
7
|
|
|
6
8
|
module Emf
|
|
7
9
|
module Emr
|
|
8
10
|
module Binary
|
|
9
11
|
module Records
|
|
10
|
-
class PaintRgn < Emf::Emr::Binary::
|
|
11
|
-
|
|
12
|
+
class PaintRgn < Emf::Emr::Binary::WithBounds
|
|
13
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
14
|
+
|
|
15
|
+
fixed_layout 28
|
|
16
|
+
variable_buffer :region_bytes, offset: 28, length: :cb_rgn_data
|
|
17
|
+
|
|
18
|
+
uint32 :cb_rgn_data
|
|
19
|
+
region_data :rgn_data, byte_length: :cb_rgn_data
|
|
12
20
|
rest :body
|
|
13
21
|
end
|
|
14
22
|
end
|
|
@@ -7,9 +7,84 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# Pixel format fields retain their original fixed-width descriptor bytes.
|
|
11
11
|
class PixelFormat < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
[
|
|
15
|
+
[:pfd_size, 0, "v", 2],
|
|
16
|
+
[:pfd_version, 2, "v", 2],
|
|
17
|
+
[:dw_flags, 4, "V", 4],
|
|
18
|
+
[:i_pixel_type, 8, "C", 1],
|
|
19
|
+
[:c_color_bits, 9, "C", 1],
|
|
20
|
+
[:c_red_bits, 10, "C", 1],
|
|
21
|
+
[:c_red_shift, 11, "C", 1],
|
|
22
|
+
[:c_green_bits, 12, "C", 1],
|
|
23
|
+
[:c_green_shift, 13, "C", 1],
|
|
24
|
+
[:c_blue_bits, 14, "C", 1],
|
|
25
|
+
[:c_blue_shift, 15, "C", 1],
|
|
26
|
+
[:c_alpha_bits, 16, "C", 1],
|
|
27
|
+
[:c_alpha_shift, 17, "C", 1],
|
|
28
|
+
[:c_accum_bits, 18, "C", 1],
|
|
29
|
+
[:c_accum_red_bits, 19, "C", 1],
|
|
30
|
+
[:c_accum_green_bits, 20, "C", 1],
|
|
31
|
+
[:c_accum_blue_bits, 21, "C", 1],
|
|
32
|
+
[:c_accum_alpha_bits, 22, "C", 1],
|
|
33
|
+
[:c_depth_bits, 23, "C", 1],
|
|
34
|
+
[:c_stencil_bits, 24, "C", 1],
|
|
35
|
+
[:c_aux_buffers, 25, "C", 1],
|
|
36
|
+
[:i_layer_type, 26, "C", 1],
|
|
37
|
+
[:b_reserved, 27, "C", 1],
|
|
38
|
+
[:dw_layer_mask, 28, "V", 4],
|
|
39
|
+
[:dw_visible_mask, 32, "V", 4],
|
|
40
|
+
[:dw_damage_mask, 36, "V", 4]
|
|
41
|
+
].each do |name, offset, format, width|
|
|
42
|
+
define_method(name) do
|
|
43
|
+
pixel_format_body.byteslice(offset, width).unpack1(format)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
define_method("#{name}=") do |value|
|
|
47
|
+
write_pixel_format_value(offset, value, format, width)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def pfd_bytes
|
|
52
|
+
pixel_format_body.byteslice(0, 40).b
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def pfd_bytes=(value)
|
|
56
|
+
replace_pixel_format_bytes(0, 40, value)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def pixel_format_body
|
|
62
|
+
bytes = body.to_s
|
|
63
|
+
raise ArgumentError, "truncated pixel format descriptor" if bytes.bytesize < 40
|
|
64
|
+
|
|
65
|
+
bytes
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def write_pixel_format_value(offset, value, format, width)
|
|
69
|
+
pixel_format_body
|
|
70
|
+
raise ArgumentError, "pixel format value must be an Integer" unless value.is_a?(Integer)
|
|
71
|
+
|
|
72
|
+
range = 0...(1 << (width * 8))
|
|
73
|
+
raise RangeError, "pixel format value must fit its #{width * 8}-bit field" unless range.cover?(value)
|
|
74
|
+
|
|
75
|
+
replace_pixel_format_bytes(offset, width, [value].pack(format))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def replace_pixel_format_bytes(offset, length, value)
|
|
79
|
+
bytes = pixel_format_body
|
|
80
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
81
|
+
raise ArgumentError, "pixel format value must be a String of #{length} bytes"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
replacement = bytes.b
|
|
85
|
+
replacement[offset, length] = value.b
|
|
86
|
+
self.body = replacement
|
|
87
|
+
end
|
|
13
88
|
end
|
|
14
89
|
end
|
|
15
90
|
end
|
|
@@ -1,15 +1,81 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
|
+
require "emf/emr/binary/variable_buffers"
|
|
4
5
|
require "emf/emr/binary/with_bounds"
|
|
6
|
+
require "emf/emr/binary/dib_header"
|
|
5
7
|
|
|
6
8
|
module Emf
|
|
7
9
|
module Emr
|
|
8
10
|
module Binary
|
|
9
11
|
module Records
|
|
10
12
|
# Stub: leading fields per MS-EMF, body captures remaining bytes.
|
|
13
|
+
# The fixed part is 140 bytes including the EMR header; the bitmap
|
|
14
|
+
# pointers are read from body without declaring fields.
|
|
11
15
|
class PlgBlt < Emf::Emr::Binary::WithBounds
|
|
16
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
17
|
+
|
|
18
|
+
fixed_layout 140
|
|
19
|
+
variable_buffer :bmi_bytes, offset: :off_bmi_src, length: :cb_bmi_src
|
|
20
|
+
variable_buffer :bits_bytes, offset: :off_bits_src, length: :cb_bits_src
|
|
21
|
+
variable_buffer :mask_bmi_bytes, offset: :off_bmi_mask, length: :cb_bmi_mask
|
|
22
|
+
variable_buffer :mask_bits_bytes, offset: :off_bits_mask, length: :cb_bits_mask
|
|
23
|
+
|
|
12
24
|
rest :body
|
|
25
|
+
|
|
26
|
+
# Read-only accessors computed from body on each call; body starts at
|
|
27
|
+
# record offset 24, so a record offset maps to (offset - 24) in body.
|
|
28
|
+
def off_bmi_src
|
|
29
|
+
pointers(72)[0]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cb_bmi_src
|
|
33
|
+
pointers(72)[1]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def off_bits_src
|
|
37
|
+
pointers(72)[2]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def cb_bits_src
|
|
41
|
+
pointers(72)[3]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def off_bmi_mask
|
|
45
|
+
pointers(100)[0]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def cb_bmi_mask
|
|
49
|
+
pointers(100)[1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def off_bits_mask
|
|
53
|
+
pointers(100)[2]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def cb_bits_mask
|
|
57
|
+
pointers(100)[3]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def dib_header_view
|
|
61
|
+
DibHeader.view(off_bmi_src, cb_bmi_src, 140, after_fixed,
|
|
62
|
+
bits_offset: off_bits_src, bits_size: cb_bits_src)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def mask_dib_header_view
|
|
66
|
+
DibHeader.view(off_bmi_mask, cb_bmi_mask, 140, after_fixed,
|
|
67
|
+
bits_offset: off_bits_mask, bits_size: cb_bits_mask)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def after_fixed
|
|
73
|
+
body.to_s.byteslice(116..).to_s
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def pointers(offset)
|
|
77
|
+
body.to_s.byteslice(offset, 16).to_s.unpack("V4").map(&:to_i)
|
|
78
|
+
end
|
|
13
79
|
end
|
|
14
80
|
end
|
|
15
81
|
end
|