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,136 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# Exposes option-dependent text buffers without changing the wire layout.
|
|
11
11
|
class PolyTextOutA < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
def c_strings
|
|
15
|
+
checked_body(32).byteslice(28, 4).unpack1("V")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def bounds
|
|
19
|
+
checked_body(16).byteslice(0, 16).b
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bounds=(value)
|
|
23
|
+
replace_body_bytes(0, 16, value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def text_bytes(index)
|
|
27
|
+
read_span(text_span(index))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def set_text_bytes(index, value)
|
|
31
|
+
replace_body_bytes(*text_span(index), value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dx_bytes(index)
|
|
35
|
+
span = dx_span(index)
|
|
36
|
+
read_span(span) if span
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def set_dx_bytes(index, value)
|
|
40
|
+
span = dx_span(index)
|
|
41
|
+
raise ArgumentError, "text entry has no spacing buffer" unless span
|
|
42
|
+
|
|
43
|
+
replace_body_bytes(*span, value)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def entry_bounds(index)
|
|
47
|
+
span = entry_bounds_span(index)
|
|
48
|
+
read_span(span) if span
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_entry_bounds(index, value)
|
|
52
|
+
span = entry_bounds_span(index)
|
|
53
|
+
raise ArgumentError, "text entry has no bounds rectangle" unless span
|
|
54
|
+
|
|
55
|
+
replace_body_bytes(*span, value)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def checked_body(required)
|
|
61
|
+
bytes = body.to_s
|
|
62
|
+
raise ArgumentError, "truncated poly text output body" if bytes.bytesize < required
|
|
63
|
+
|
|
64
|
+
bytes
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def entry_location(index)
|
|
68
|
+
bytes = checked_body(32)
|
|
69
|
+
count = bytes.byteslice(28, 4).unpack1("V")
|
|
70
|
+
raise ArgumentError, "invalid text entry index" unless index.is_a?(Integer) && index >= 0 && index < count
|
|
71
|
+
raise ArgumentError, "truncated text entry table" if count > (bytes.bytesize - 32) / 24
|
|
72
|
+
|
|
73
|
+
offset = 32
|
|
74
|
+
selected = nil
|
|
75
|
+
count.times do |position|
|
|
76
|
+
raise ArgumentError, "truncated text entry table" if bytes.bytesize - offset < 24
|
|
77
|
+
|
|
78
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
79
|
+
length = options.nobits?(0x100) ? 40 : 24
|
|
80
|
+
raise ArgumentError, "truncated text entry table" if bytes.bytesize - offset < length
|
|
81
|
+
|
|
82
|
+
selected = offset if position == index
|
|
83
|
+
offset += length
|
|
84
|
+
end
|
|
85
|
+
[bytes, selected, offset]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def text_span(index)
|
|
89
|
+
bytes, offset, table_end = entry_location(index)
|
|
90
|
+
count, pointer = bytes.byteslice(offset + 8, 8).unpack("V2")
|
|
91
|
+
buffer_span(bytes, pointer, count, table_end, 1)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def dx_span(index)
|
|
95
|
+
bytes, offset, table_end = entry_location(index)
|
|
96
|
+
count = bytes.byteslice(offset + 8, 4).unpack1("V")
|
|
97
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
98
|
+
pointer_at = options.nobits?(0x100) ? 36 : 20
|
|
99
|
+
pointer = bytes.byteslice(offset + pointer_at, 4).unpack1("V")
|
|
100
|
+
return nil if pointer.zero?
|
|
101
|
+
|
|
102
|
+
width = options.nobits?(0x2000) ? 4 : 8
|
|
103
|
+
buffer_span(bytes, pointer, count * width, table_end, 4)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def entry_bounds_span(index)
|
|
107
|
+
bytes, offset, = entry_location(index)
|
|
108
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
109
|
+
[offset + 20, 16] if options.nobits?(0x100)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def buffer_span(bytes, pointer, length, table_end, alignment)
|
|
113
|
+
return [0, 0] if length.zero?
|
|
114
|
+
|
|
115
|
+
raise ArgumentError, "misaligned text entry buffer" unless (pointer % alignment).zero?
|
|
116
|
+
|
|
117
|
+
offset = pointer - 8
|
|
118
|
+
if offset < table_end || offset > bytes.bytesize || length > bytes.bytesize - offset
|
|
119
|
+
raise ArgumentError, "invalid text entry buffer span"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
[offset, length]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def read_span(span)
|
|
126
|
+
offset, length = span
|
|
127
|
+
body.to_s.byteslice(offset, length).b
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def replace_body_bytes(offset, length, value)
|
|
131
|
+
bytes = checked_body(offset + length)
|
|
132
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
133
|
+
raise ArgumentError, "poly text output value must be a String of #{length} bytes"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
replacement = bytes.b
|
|
137
|
+
replacement[offset, length] = value.b
|
|
138
|
+
self.body = replacement
|
|
139
|
+
end
|
|
13
140
|
end
|
|
14
141
|
end
|
|
15
142
|
end
|
|
@@ -7,9 +7,136 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
#
|
|
10
|
+
# Exposes option-dependent text buffers without changing the wire layout.
|
|
11
11
|
class PolyTextOutW < Emf::Emr::Binary::Record
|
|
12
12
|
rest :body
|
|
13
|
+
|
|
14
|
+
def c_strings
|
|
15
|
+
checked_body(32).byteslice(28, 4).unpack1("V")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def bounds
|
|
19
|
+
checked_body(16).byteslice(0, 16).b
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bounds=(value)
|
|
23
|
+
replace_body_bytes(0, 16, value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def text_bytes(index)
|
|
27
|
+
read_span(text_span(index))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def set_text_bytes(index, value)
|
|
31
|
+
replace_body_bytes(*text_span(index), value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dx_bytes(index)
|
|
35
|
+
span = dx_span(index)
|
|
36
|
+
read_span(span) if span
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def set_dx_bytes(index, value)
|
|
40
|
+
span = dx_span(index)
|
|
41
|
+
raise ArgumentError, "text entry has no spacing buffer" unless span
|
|
42
|
+
|
|
43
|
+
replace_body_bytes(*span, value)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def entry_bounds(index)
|
|
47
|
+
span = entry_bounds_span(index)
|
|
48
|
+
read_span(span) if span
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def set_entry_bounds(index, value)
|
|
52
|
+
span = entry_bounds_span(index)
|
|
53
|
+
raise ArgumentError, "text entry has no bounds rectangle" unless span
|
|
54
|
+
|
|
55
|
+
replace_body_bytes(*span, value)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def checked_body(required)
|
|
61
|
+
bytes = body.to_s
|
|
62
|
+
raise ArgumentError, "truncated poly text output body" if bytes.bytesize < required
|
|
63
|
+
|
|
64
|
+
bytes
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def entry_location(index)
|
|
68
|
+
bytes = checked_body(32)
|
|
69
|
+
count = bytes.byteslice(28, 4).unpack1("V")
|
|
70
|
+
raise ArgumentError, "invalid text entry index" unless index.is_a?(Integer) && index >= 0 && index < count
|
|
71
|
+
raise ArgumentError, "truncated text entry table" if count > (bytes.bytesize - 32) / 24
|
|
72
|
+
|
|
73
|
+
offset = 32
|
|
74
|
+
selected = nil
|
|
75
|
+
count.times do |position|
|
|
76
|
+
raise ArgumentError, "truncated text entry table" if bytes.bytesize - offset < 24
|
|
77
|
+
|
|
78
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
79
|
+
length = options.nobits?(0x100) ? 40 : 24
|
|
80
|
+
raise ArgumentError, "truncated text entry table" if bytes.bytesize - offset < length
|
|
81
|
+
|
|
82
|
+
selected = offset if position == index
|
|
83
|
+
offset += length
|
|
84
|
+
end
|
|
85
|
+
[bytes, selected, offset]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def text_span(index)
|
|
89
|
+
bytes, offset, table_end = entry_location(index)
|
|
90
|
+
count, pointer = bytes.byteslice(offset + 8, 8).unpack("V2")
|
|
91
|
+
buffer_span(bytes, pointer, count * 2, table_end, 2)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def dx_span(index)
|
|
95
|
+
bytes, offset, table_end = entry_location(index)
|
|
96
|
+
count = bytes.byteslice(offset + 8, 4).unpack1("V")
|
|
97
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
98
|
+
pointer_at = options.nobits?(0x100) ? 36 : 20
|
|
99
|
+
pointer = bytes.byteslice(offset + pointer_at, 4).unpack1("V")
|
|
100
|
+
return nil if pointer.zero?
|
|
101
|
+
|
|
102
|
+
width = options.nobits?(0x2000) ? 4 : 8
|
|
103
|
+
buffer_span(bytes, pointer, count * width, table_end, 4)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def entry_bounds_span(index)
|
|
107
|
+
bytes, offset, = entry_location(index)
|
|
108
|
+
options = bytes.byteslice(offset + 16, 4).unpack1("V")
|
|
109
|
+
[offset + 20, 16] if options.nobits?(0x100)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def buffer_span(bytes, pointer, length, table_end, alignment)
|
|
113
|
+
return [0, 0] if length.zero?
|
|
114
|
+
|
|
115
|
+
raise ArgumentError, "misaligned text entry buffer" unless (pointer % alignment).zero?
|
|
116
|
+
|
|
117
|
+
offset = pointer - 8
|
|
118
|
+
if offset < table_end || offset > bytes.bytesize || length > bytes.bytesize - offset
|
|
119
|
+
raise ArgumentError, "invalid text entry buffer span"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
[offset, length]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def read_span(span)
|
|
126
|
+
offset, length = span
|
|
127
|
+
body.to_s.byteslice(offset, length).b
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def replace_body_bytes(offset, length, value)
|
|
131
|
+
bytes = checked_body(offset + length)
|
|
132
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
133
|
+
raise ArgumentError, "poly text output value must be a String of #{length} bytes"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
replacement = bytes.b
|
|
137
|
+
replacement[offset, length] = value.b
|
|
138
|
+
self.body = replacement
|
|
139
|
+
end
|
|
13
140
|
end
|
|
14
141
|
end
|
|
15
142
|
end
|
|
@@ -2,14 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
require "bindata"
|
|
4
4
|
require "emf/emr/binary/record"
|
|
5
|
+
require "emf/emr/binary/palette_body"
|
|
5
6
|
|
|
6
7
|
module Emf
|
|
7
8
|
module Emr
|
|
8
9
|
module Binary
|
|
9
10
|
module Records
|
|
10
|
-
# Stub: preserves full body bytes. Full layout lands with TODO 10.
|
|
11
11
|
class ResizePalette < Emf::Emr::Binary::Record
|
|
12
|
-
|
|
12
|
+
uint32 :ih_pal
|
|
13
|
+
uint32 :entry_count
|
|
14
|
+
rest :trailing
|
|
15
|
+
|
|
16
|
+
def body
|
|
17
|
+
PaletteBody.new(self, to_binary_s.byteslice(8..))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def body=(value)
|
|
21
|
+
bytes = value.to_s
|
|
22
|
+
raise ArgumentError, "invalid palette body length" if bytes.bytesize < 8
|
|
23
|
+
|
|
24
|
+
replacement = self.class.read(to_binary_s.byteslice(0, 8) + bytes)
|
|
25
|
+
assign(replacement.snapshot)
|
|
26
|
+
end
|
|
13
27
|
end
|
|
14
28
|
end
|
|
15
29
|
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bindata"
|
|
4
|
+
require "emf/emr/binary/record"
|
|
5
|
+
|
|
6
|
+
module Emf
|
|
7
|
+
module Emr
|
|
8
|
+
module Binary
|
|
9
|
+
module Records
|
|
10
|
+
class SetColorAdjustment < Emf::Emr::Binary::Record
|
|
11
|
+
rest :body
|
|
12
|
+
|
|
13
|
+
def adjustment_size
|
|
14
|
+
read_adjustment_value(0, "v")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def adjustment_size=(value)
|
|
18
|
+
write_adjustment_value(0, value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def values
|
|
22
|
+
read_adjustment_value(2, "v")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def values=(value)
|
|
26
|
+
write_adjustment_value(2, value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def illuminant_index
|
|
30
|
+
read_adjustment_value(4, "v")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def illuminant_index=(value)
|
|
34
|
+
write_adjustment_value(4, value)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def red_gamma
|
|
38
|
+
read_adjustment_value(6, "v")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def red_gamma=(value)
|
|
42
|
+
write_adjustment_value(6, value)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def green_gamma
|
|
46
|
+
read_adjustment_value(8, "v")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def green_gamma=(value)
|
|
50
|
+
write_adjustment_value(8, value)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def blue_gamma
|
|
54
|
+
read_adjustment_value(10, "v")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def blue_gamma=(value)
|
|
58
|
+
write_adjustment_value(10, value)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def reference_black
|
|
62
|
+
read_adjustment_value(12, "v")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def reference_black=(value)
|
|
66
|
+
write_adjustment_value(12, value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def reference_white
|
|
70
|
+
read_adjustment_value(14, "v")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def reference_white=(value)
|
|
74
|
+
write_adjustment_value(14, value)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def contrast
|
|
78
|
+
read_adjustment_value(16, "s<")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def contrast=(value)
|
|
82
|
+
write_adjustment_value(16, value, signed: true)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def brightness
|
|
86
|
+
read_adjustment_value(18, "s<")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def brightness=(value)
|
|
90
|
+
write_adjustment_value(18, value, signed: true)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def colorfulness
|
|
94
|
+
read_adjustment_value(20, "s<")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def colorfulness=(value)
|
|
98
|
+
write_adjustment_value(20, value, signed: true)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def red_green_tint
|
|
102
|
+
read_adjustment_value(22, "s<")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def red_green_tint=(value)
|
|
106
|
+
write_adjustment_value(22, value, signed: true)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def adjustment_body
|
|
112
|
+
bytes = body.to_s
|
|
113
|
+
raise ArgumentError, "invalid color adjustment body length" if bytes.bytesize < 24
|
|
114
|
+
|
|
115
|
+
bytes
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def read_adjustment_value(offset, format)
|
|
119
|
+
adjustment_body.byteslice(offset, 2).unpack1(format)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def write_adjustment_value(offset, value, signed: false)
|
|
123
|
+
bytes = adjustment_body.dup
|
|
124
|
+
raise ArgumentError, "color adjustment value must be an Integer" unless value.is_a?(Integer)
|
|
125
|
+
|
|
126
|
+
bounds = signed ? (-32_768..32_767) : (0..65_535)
|
|
127
|
+
raise RangeError, "color adjustment value must fit its 16-bit integer field" unless bounds.cover?(value)
|
|
128
|
+
|
|
129
|
+
bytes[offset, 2] = [value].pack(signed ? "s<" : "v")
|
|
130
|
+
self.body = bytes
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -7,9 +7,30 @@ module Emf
|
|
|
7
7
|
module Emr
|
|
8
8
|
module Binary
|
|
9
9
|
module Records
|
|
10
|
-
# Stub: preserves full body bytes. Full layout lands with TODO 10.
|
|
11
10
|
class SetColorspace < Emf::Emr::Binary::Record
|
|
12
11
|
rest :body
|
|
12
|
+
|
|
13
|
+
def ih_cs
|
|
14
|
+
colorspace_body.byteslice(0, 4).unpack1("V")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ih_cs=(value)
|
|
18
|
+
bytes = colorspace_body.dup
|
|
19
|
+
raise ArgumentError, "colorspace handle must be an Integer" unless value.is_a?(Integer)
|
|
20
|
+
raise RangeError, "colorspace handle must fit an unsigned 32-bit integer" unless (0..0xffffffff).cover?(value)
|
|
21
|
+
|
|
22
|
+
bytes[0, 4] = [value].pack("V")
|
|
23
|
+
self.body = bytes
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def colorspace_body
|
|
29
|
+
bytes = body.to_s
|
|
30
|
+
raise ArgumentError, "invalid colorspace body length" if bytes.bytesize < 4
|
|
31
|
+
|
|
32
|
+
bytes
|
|
33
|
+
end
|
|
13
34
|
end
|
|
14
35
|
end
|
|
15
36
|
end
|
|
@@ -1,15 +1,58 @@
|
|
|
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 76 bytes including the EMR header; the bitmap
|
|
14
|
+
# pointers are read from body without declaring fields.
|
|
11
15
|
class SetDibitsToDevice < Emf::Emr::Binary::WithBounds
|
|
16
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
17
|
+
|
|
18
|
+
fixed_layout 76
|
|
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
|
+
|
|
12
22
|
rest :body
|
|
23
|
+
|
|
24
|
+
# Read-only accessors computed from body on each call; body starts at
|
|
25
|
+
# record offset 24, so a record offset maps to (offset - 24) in body.
|
|
26
|
+
def off_bmi_src
|
|
27
|
+
pointers(24)[0]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cb_bmi_src
|
|
31
|
+
pointers(24)[1]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def off_bits_src
|
|
35
|
+
pointers(24)[2]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cb_bits_src
|
|
39
|
+
pointers(24)[3]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def dib_header_view
|
|
43
|
+
DibHeader.view(off_bmi_src, cb_bmi_src, 76, after_fixed,
|
|
44
|
+
bits_offset: off_bits_src, bits_size: cb_bits_src)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def after_fixed
|
|
50
|
+
body.to_s.byteslice(52..).to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def pointers(offset)
|
|
54
|
+
body.to_s.byteslice(offset, 16).to_s.unpack("V4").map(&:to_i)
|
|
55
|
+
end
|
|
13
56
|
end
|
|
14
57
|
end
|
|
15
58
|
end
|
|
@@ -1,15 +1,85 @@
|
|
|
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/record"
|
|
5
6
|
|
|
6
7
|
module Emf
|
|
7
8
|
module Emr
|
|
8
9
|
module Binary
|
|
9
10
|
module Records
|
|
10
|
-
#
|
|
11
|
+
# MS-EMF 2.3.11.15: name and profile lengths are byte counts.
|
|
11
12
|
class SetIcmProfileA < Emf::Emr::Binary::Record
|
|
13
|
+
include Emf::Emr::Binary::VariableBuffers
|
|
14
|
+
|
|
15
|
+
fixed_layout 20
|
|
16
|
+
variable_buffer :icm_name_bytes, offset: 20, length: -> { u32_at(12) }
|
|
17
|
+
variable_buffer :icm_profile_bytes, offset: -> { 20 + u32_at(12) }, length: -> { u32_at(16) }
|
|
18
|
+
|
|
19
|
+
# Byte counts and opaque spans retain the original body layout.
|
|
12
20
|
rest :body
|
|
21
|
+
|
|
22
|
+
def dw_flags
|
|
23
|
+
profile_prefix.unpack1("V")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def dw_flags=(value)
|
|
27
|
+
raise ArgumentError, "color profile flags must be an Integer" unless value.is_a?(Integer)
|
|
28
|
+
raise RangeError, "color profile flags must fit an unsigned 32-bit integer" unless (0..0xFFFFFFFF).cover?(value)
|
|
29
|
+
|
|
30
|
+
write_profile_bytes(0, 4, [value].pack("V"))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def cb_name
|
|
34
|
+
profile_prefix.byteslice(4, 4).unpack1("V")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def cb_data
|
|
38
|
+
profile_prefix.byteslice(8, 4).unpack1("V")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def name_bytes
|
|
42
|
+
read_profile_bytes(12, cb_name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def name_bytes=(value)
|
|
46
|
+
write_profile_bytes(12, cb_name, value)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def profile_bytes
|
|
50
|
+
read_profile_bytes(12 + cb_name, cb_data)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def profile_bytes=(value)
|
|
54
|
+
write_profile_bytes(12 + cb_name, cb_data, value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def profile_prefix
|
|
60
|
+
bytes = body.to_s
|
|
61
|
+
raise ArgumentError, "truncated color profile prefix" if bytes.bytesize < 12
|
|
62
|
+
|
|
63
|
+
bytes
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def read_profile_bytes(offset, length)
|
|
67
|
+
bytes = profile_prefix
|
|
68
|
+
raise ArgumentError, "truncated color profile span" if offset + length > bytes.bytesize
|
|
69
|
+
|
|
70
|
+
bytes.byteslice(offset, length).b
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def write_profile_bytes(offset, length, value)
|
|
74
|
+
read_profile_bytes(offset, length)
|
|
75
|
+
unless value.is_a?(String) && value.bytesize == length
|
|
76
|
+
raise ArgumentError, "color profile value must be a String of #{length} bytes"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
bytes = body.to_s.b
|
|
80
|
+
bytes[offset, length] = value.b
|
|
81
|
+
self.body = bytes
|
|
82
|
+
end
|
|
13
83
|
end
|
|
14
84
|
end
|
|
15
85
|
end
|