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.
Files changed (360) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +224 -19
  3. data/exe/emf +12 -0
  4. data/lib/emf/backend.rb +60 -0
  5. data/lib/emf/binary/class_field_accessors.rb +49 -0
  6. data/lib/emf/binary/float32_le.rb +54 -0
  7. data/lib/emf/binary/types.rb +40 -6
  8. data/lib/emf/conformance/context.rb +36 -0
  9. data/lib/emf/conformance/diagnostic.rb +18 -0
  10. data/lib/emf/conformance/manifest/emf_bitmap_misc.yml +622 -0
  11. data/lib/emf/conformance/manifest/emf_control_buffers.yml +61 -0
  12. data/lib/emf/conformance/manifest/emf_core.yml +117 -0
  13. data/lib/emf/conformance/manifest/emf_corpus_rules.yml +21 -0
  14. data/lib/emf/conformance/manifest/emf_objects_geometry.yml +229 -0
  15. data/lib/emf/conformance/manifest/emf_plus.yml +357 -0
  16. data/lib/emf/conformance/manifest/emf_plus_core.yml +33 -0
  17. data/lib/emf/conformance/manifest/emf_state_path.yml +403 -0
  18. data/lib/emf/conformance/manifest/emf_text.yml +97 -0
  19. data/lib/emf/conformance/manifest/wmf.yml +874 -0
  20. data/lib/emf/conformance/manifest.rb +79 -0
  21. data/lib/emf/conformance/profile.rb +35 -0
  22. data/lib/emf/conformance/record_types.rb +24 -0
  23. data/lib/emf/conformance/registry.rb +76 -0
  24. data/lib/emf/conformance/report.rb +83 -0
  25. data/lib/emf/conformance/rule.rb +16 -0
  26. data/lib/emf/conformance/rules/emf_bitmap.rb +357 -0
  27. data/lib/emf/conformance/rules/emf_comment_escape.rb +309 -0
  28. data/lib/emf/conformance/rules/emf_control_buffers.rb +137 -0
  29. data/lib/emf/conformance/rules/emf_corpus_named.rb +83 -0
  30. data/lib/emf/conformance/rules/emf_framing.rb +94 -0
  31. data/lib/emf/conformance/rules/emf_geometry.rb +282 -0
  32. data/lib/emf/conformance/rules/emf_header.rb +114 -0
  33. data/lib/emf/conformance/rules/emf_objects.rb +291 -0
  34. data/lib/emf/conformance/rules/emf_parse_recovery.rb +97 -0
  35. data/lib/emf/conformance/rules/emf_path_clip.rb +165 -0
  36. data/lib/emf/conformance/rules/emf_plus.rb +75 -0
  37. data/lib/emf/conformance/rules/emf_plus_common.rb +58 -0
  38. data/lib/emf/conformance/rules/emf_plus_drawing.rb +78 -0
  39. data/lib/emf/conformance/rules/emf_plus_effects.rb +104 -0
  40. data/lib/emf/conformance/rules/emf_plus_fields.rb +169 -0
  41. data/lib/emf/conformance/rules/emf_plus_fields_b.rb +102 -0
  42. data/lib/emf/conformance/rules/emf_plus_framing.rb +172 -0
  43. data/lib/emf/conformance/rules/emf_plus_objects.rb +97 -0
  44. data/lib/emf/conformance/rules/emf_plus_payloads.rb +320 -0
  45. data/lib/emf/conformance/rules/emf_plus_properties.rb +96 -0
  46. data/lib/emf/conformance/rules/emf_plus_state.rb +77 -0
  47. data/lib/emf/conformance/rules/emf_state.rb +244 -0
  48. data/lib/emf/conformance/rules/emf_text.rb +221 -0
  49. data/lib/emf/conformance/rules/emf_transform.rb +85 -0
  50. data/lib/emf/conformance/rules/wmf_buffers.rb +259 -0
  51. data/lib/emf/conformance/rules/wmf_framing.rb +146 -0
  52. data/lib/emf/conformance/rules/wmf_layout_records.rb +112 -0
  53. data/lib/emf/conformance/rules/wmf_objects.rb +168 -0
  54. data/lib/emf/conformance/rules/wmf_records.rb +191 -0
  55. data/lib/emf/conformance/rules/wmf_rejections.rb +184 -0
  56. data/lib/emf/conformance/runner.rb +61 -0
  57. data/lib/emf/conformance/ternary_raster_operations.rb +52 -0
  58. data/lib/emf/conformance.rb +31 -0
  59. data/lib/emf/emf_plus/effects/blur.rb +24 -0
  60. data/lib/emf/emf_plus/effects/brightness_contrast.rb +22 -0
  61. data/lib/emf/emf_plus/effects/color_balance.rb +24 -0
  62. data/lib/emf/emf_plus/effects/color_curve.rb +24 -0
  63. data/lib/emf/emf_plus/effects/color_lookup_table.rb +26 -0
  64. data/lib/emf/emf_plus/effects/color_matrix.rb +23 -0
  65. data/lib/emf/emf_plus/effects/effect.rb +50 -0
  66. data/lib/emf/emf_plus/effects/hue_saturation_lightness.rb +24 -0
  67. data/lib/emf/emf_plus/effects/levels.rb +24 -0
  68. data/lib/emf/emf_plus/effects/opaque.rb +19 -0
  69. data/lib/emf/emf_plus/effects/red_eye_correction.rb +35 -0
  70. data/lib/emf/emf_plus/effects/sharpen.rb +24 -0
  71. data/lib/emf/emf_plus/effects/tint.rb +22 -0
  72. data/lib/emf/emf_plus/effects.rb +45 -0
  73. data/lib/emf/emf_plus/frame.rb +41 -0
  74. data/lib/emf/emf_plus/links/effect_link.rb +16 -0
  75. data/lib/emf/emf_plus/links/get_dc_span.rb +18 -0
  76. data/lib/emf/emf_plus/links/link_error.rb +15 -0
  77. data/lib/emf/emf_plus/links.rb +77 -0
  78. data/lib/emf/emf_plus/object_chain.rb +108 -0
  79. data/lib/emf/emf_plus/object_table.rb +182 -0
  80. data/lib/emf/emf_plus/objects/brush.rb +296 -0
  81. data/lib/emf/emf_plus/objects/custom_line_cap.rb +106 -0
  82. data/lib/emf/emf_plus/objects/font.rb +47 -0
  83. data/lib/emf/emf_plus/objects/image.rb +68 -0
  84. data/lib/emf/emf_plus/objects/image_attributes.rb +28 -0
  85. data/lib/emf/emf_plus/objects/opaque.rb +19 -0
  86. data/lib/emf/emf_plus/objects/parts.rb +103 -0
  87. data/lib/emf/emf_plus/objects/path.rb +21 -0
  88. data/lib/emf/emf_plus/objects/pen.rb +132 -0
  89. data/lib/emf/emf_plus/objects/region.rb +39 -0
  90. data/lib/emf/emf_plus/objects/string_format.rb +55 -0
  91. data/lib/emf/emf_plus/objects/typed.rb +50 -0
  92. data/lib/emf/emf_plus/objects.rb +46 -0
  93. data/lib/emf/emf_plus/parser.rb +64 -2
  94. data/lib/emf/emf_plus/records/base.rb +107 -0
  95. data/lib/emf/emf_plus/records/begin_container.rb +31 -0
  96. data/lib/emf/emf_plus/records/begin_container_no_params.rb +20 -0
  97. data/lib/emf/emf_plus/records/body.rb +16 -0
  98. data/lib/emf/emf_plus/records/clear.rb +22 -0
  99. data/lib/emf/emf_plus/records/clip_transform_flags.rb +26 -0
  100. data/lib/emf/emf_plus/records/comment.rb +21 -0
  101. data/lib/emf/emf_plus/records/draw_arc.rb +33 -0
  102. data/lib/emf/emf_plus/records/draw_beziers.rb +31 -0
  103. data/lib/emf/emf_plus/records/draw_closed_curve.rb +34 -0
  104. data/lib/emf/emf_plus/records/draw_curve.rb +38 -0
  105. data/lib/emf/emf_plus/records/draw_driver_string.rb +61 -0
  106. data/lib/emf/emf_plus/records/draw_ellipse.rb +28 -0
  107. data/lib/emf/emf_plus/records/draw_image.rb +42 -0
  108. data/lib/emf/emf_plus/records/draw_image_points.rb +62 -0
  109. data/lib/emf/emf_plus/records/draw_lines.rb +34 -0
  110. data/lib/emf/emf_plus/records/draw_path.rb +23 -0
  111. data/lib/emf/emf_plus/records/draw_pie.rb +33 -0
  112. data/lib/emf/emf_plus/records/draw_rects.rb +30 -0
  113. data/lib/emf/emf_plus/records/draw_string.rb +41 -0
  114. data/lib/emf/emf_plus/records/end_container.rb +20 -0
  115. data/lib/emf/emf_plus/records/end_of_file.rb +17 -0
  116. data/lib/emf/emf_plus/records/fill_brush.rb +21 -0
  117. data/lib/emf/emf_plus/records/fill_closed_curve.rb +38 -0
  118. data/lib/emf/emf_plus/records/fill_ellipse.rb +29 -0
  119. data/lib/emf/emf_plus/records/fill_path.rb +23 -0
  120. data/lib/emf/emf_plus/records/fill_pie.rb +34 -0
  121. data/lib/emf/emf_plus/records/fill_polygon.rb +32 -0
  122. data/lib/emf/emf_plus/records/fill_rects.rb +31 -0
  123. data/lib/emf/emf_plus/records/fill_region.rb +23 -0
  124. data/lib/emf/emf_plus/records/get_dc.rb +18 -0
  125. data/lib/emf/emf_plus/records/header.rb +35 -0
  126. data/lib/emf/emf_plus/records/multiply_world_transform.rb +24 -0
  127. data/lib/emf/emf_plus/records/object.rb +32 -0
  128. data/lib/emf/emf_plus/records/offset_clip.rb +24 -0
  129. data/lib/emf/emf_plus/records/primitives/argb.rb +20 -0
  130. data/lib/emf/emf_plus/records/primitives/bitmap.rb +32 -0
  131. data/lib/emf/emf_plus/records/primitives/bitmap_data.rb +21 -0
  132. data/lib/emf/emf_plus/records/primitives/blend_colors.rb +22 -0
  133. data/lib/emf/emf_plus/records/primitives/blend_factors.rb +21 -0
  134. data/lib/emf/emf_plus/records/primitives/bounded_array.rb +38 -0
  135. data/lib/emf/emf_plus/records/primitives/byte_reader.rb +25 -0
  136. data/lib/emf/emf_plus/records/primitives/character_range.rb +20 -0
  137. data/lib/emf/emf_plus/records/primitives/compressed_image.rb +17 -0
  138. data/lib/emf/emf_plus/records/primitives/focus_scale_data.rb +20 -0
  139. data/lib/emf/emf_plus/records/primitives/graphics_version.rb +21 -0
  140. data/lib/emf/emf_plus/records/primitives/language_identifier.rb +22 -0
  141. data/lib/emf/emf_plus/records/primitives/metafile.rb +19 -0
  142. data/lib/emf/emf_plus/records/primitives/palette.rb +21 -0
  143. data/lib/emf/emf_plus/records/primitives/path.rb +89 -0
  144. data/lib/emf/emf_plus/records/primitives/path_point_type.rb +21 -0
  145. data/lib/emf/emf_plus/records/primitives/path_point_type_rle.rb +23 -0
  146. data/lib/emf/emf_plus/records/primitives/point.rb +18 -0
  147. data/lib/emf/emf_plus/records/primitives/point_array.rb +42 -0
  148. data/lib/emf/emf_plus/records/primitives/point_f.rb +19 -0
  149. data/lib/emf/emf_plus/records/primitives/point_r.rb +19 -0
  150. data/lib/emf/emf_plus/records/primitives/rect.rb +20 -0
  151. data/lib/emf/emf_plus/records/primitives/rect_array.rb +24 -0
  152. data/lib/emf/emf_plus/records/primitives/rect_f.rb +21 -0
  153. data/lib/emf/emf_plus/records/primitives/region_node.rb +68 -0
  154. data/lib/emf/emf_plus/records/primitives/region_node_child_nodes.rb +22 -0
  155. data/lib/emf/emf_plus/records/primitives/region_node_path.rb +37 -0
  156. data/lib/emf/emf_plus/records/primitives/relative_coordinate.rb +32 -0
  157. data/lib/emf/emf_plus/records/primitives/string_format_data.rb +23 -0
  158. data/lib/emf/emf_plus/records/primitives/transform_matrix.rb +23 -0
  159. data/lib/emf/emf_plus/records/primitives.rb +41 -0
  160. data/lib/emf/emf_plus/records/reset_clip.rb +17 -0
  161. data/lib/emf/emf_plus/records/reset_world_transform.rb +17 -0
  162. data/lib/emf/emf_plus/records/restore.rb +20 -0
  163. data/lib/emf/emf_plus/records/rotate_world_transform.rb +24 -0
  164. data/lib/emf/emf_plus/records/save.rb +20 -0
  165. data/lib/emf/emf_plus/records/scale_world_transform.rb +26 -0
  166. data/lib/emf/emf_plus/records/serializable_object.rb +32 -0
  167. data/lib/emf/emf_plus/records/set_anti_alias_mode.rb +25 -0
  168. data/lib/emf/emf_plus/records/set_clip_path.rb +20 -0
  169. data/lib/emf/emf_plus/records/set_clip_rect.rb +24 -0
  170. data/lib/emf/emf_plus/records/set_clip_region.rb +20 -0
  171. data/lib/emf/emf_plus/records/set_compositing_mode.rb +21 -0
  172. data/lib/emf/emf_plus/records/set_compositing_quality.rb +21 -0
  173. data/lib/emf/emf_plus/records/set_interpolation_mode.rb +21 -0
  174. data/lib/emf/emf_plus/records/set_page_transform.rb +25 -0
  175. data/lib/emf/emf_plus/records/set_pixel_offset_mode.rb +21 -0
  176. data/lib/emf/emf_plus/records/set_rendering_origin.rb +22 -0
  177. data/lib/emf/emf_plus/records/set_text_contrast.rb +24 -0
  178. data/lib/emf/emf_plus/records/set_text_rendering_hint.rb +21 -0
  179. data/lib/emf/emf_plus/records/set_ts_clip.rb +40 -0
  180. data/lib/emf/emf_plus/records/set_ts_graphics.rb +88 -0
  181. data/lib/emf/emf_plus/records/set_world_transform.rb +22 -0
  182. data/lib/emf/emf_plus/records/shape_flags.rb +23 -0
  183. data/lib/emf/emf_plus/records/translate_world_transform.rb +26 -0
  184. data/lib/emf/emf_plus/records/unknown.rb +20 -0
  185. data/lib/emf/emf_plus/records.rb +107 -0
  186. data/lib/emf/emf_plus/serializer.rb +9 -2
  187. data/lib/emf/emf_plus/stream/conformance.rb +68 -0
  188. data/lib/emf/emf_plus/stream/editor.rb +21 -0
  189. data/lib/emf/emf_plus/stream/emf_gap.rb +20 -0
  190. data/lib/emf/emf_plus/stream/link_index.rb +30 -0
  191. data/lib/emf/emf_plus/stream/rebuild.rb +47 -0
  192. data/lib/emf/emf_plus/stream/record_handle.rb +26 -0
  193. data/lib/emf/emf_plus/stream/segment.rb +70 -0
  194. data/lib/emf/emf_plus/stream.rb +153 -0
  195. data/lib/emf/emf_plus.rb +9 -0
  196. data/lib/emf/emr/binary/dib_header.rb +142 -0
  197. data/lib/emf/emr/binary/ext_text_out_fields.rb +43 -0
  198. data/lib/emf/emr/binary/extended_pen_buffers.rb +23 -0
  199. data/lib/emf/emr/binary/fast_fill.rb +1164 -0
  200. data/lib/emf/emr/binary/font.rb +159 -0
  201. data/lib/emf/emr/binary/lazy_utf16_array.rb +82 -0
  202. data/lib/emf/emr/binary/pack_plan.rb +144 -0
  203. data/lib/emf/emr/binary/pack_plan_check.rb +75 -0
  204. data/lib/emf/emr/binary/pack_plan_exact.rb +130 -0
  205. data/lib/emf/emr/binary/pack_plan_generate.rb +116 -0
  206. data/lib/emf/emr/binary/pack_plan_values.rb +92 -0
  207. data/lib/emf/emr/binary/palette_body.rb +19 -0
  208. data/lib/emf/emr/binary/palette_entry.rb +18 -0
  209. data/lib/emf/emr/binary/record.rb +33 -0
  210. data/lib/emf/emr/binary/records/alpha_blend.rb +43 -0
  211. data/lib/emf/emr/binary/records/angle_arc.rb +2 -2
  212. data/lib/emf/emr/binary/records/bit_blt.rb +14 -0
  213. data/lib/emf/emr/binary/records/color_correct_palette.rb +55 -1
  214. data/lib/emf/emr/binary/records/colormatch_to_target_w.rb +76 -1
  215. data/lib/emf/emr/binary/records/create_colorspace.rb +67 -1
  216. data/lib/emf/emr/binary/records/create_colorspace_w.rb +90 -1
  217. data/lib/emf/emr/binary/records/create_dib_pattern_brush_pt.rb +14 -0
  218. data/lib/emf/emr/binary/records/create_font_indirect_w.rb +6 -2
  219. data/lib/emf/emr/binary/records/create_mono_brush.rb +14 -0
  220. data/lib/emf/emr/binary/records/create_palette.rb +19 -1
  221. data/lib/emf/emr/binary/records/delete_colorspace.rb +22 -1
  222. data/lib/emf/emr/binary/records/draw_escape.rb +45 -1
  223. data/lib/emf/emr/binary/records/ellipse.rb +1 -1
  224. data/lib/emf/emr/binary/records/eof.rb +9 -0
  225. data/lib/emf/emr/binary/records/ext_create_pen.rb +80 -1
  226. data/lib/emf/emr/binary/records/ext_escape.rb +45 -1
  227. data/lib/emf/emr/binary/records/ext_flood_fill.rb +9 -2
  228. data/lib/emf/emr/binary/records/ext_select_clip_rgn.rb +9 -1
  229. data/lib/emf/emr/binary/records/ext_text_out_a.rb +16 -3
  230. data/lib/emf/emr/binary/records/ext_text_out_w.rb +14 -3
  231. data/lib/emf/emr/binary/records/fill_rgn.rb +11 -2
  232. data/lib/emf/emr/binary/records/force_ufi_mapping.rb +38 -1
  233. data/lib/emf/emr/binary/records/frame_rgn.rb +12 -2
  234. data/lib/emf/emr/binary/records/gls_bounded_record.rb +61 -1
  235. data/lib/emf/emr/binary/records/gls_record.rb +42 -1
  236. data/lib/emf/emr/binary/records/gradient_fill.rb +7 -0
  237. data/lib/emf/emr/binary/records/invert_rgn.rb +11 -3
  238. data/lib/emf/emr/binary/records/mask_blt.rb +66 -0
  239. data/lib/emf/emr/binary/records/named_escape.rb +78 -1
  240. data/lib/emf/emr/binary/records/paint_rgn.rb +11 -3
  241. data/lib/emf/emr/binary/records/pixel_format.rb +76 -1
  242. data/lib/emf/emr/binary/records/plg_blt.rb +66 -0
  243. data/lib/emf/emr/binary/records/poly_textout_a.rb +128 -1
  244. data/lib/emf/emr/binary/records/poly_textout_w.rb +128 -1
  245. data/lib/emf/emr/binary/records/raw.rb +3 -0
  246. data/lib/emf/emr/binary/records/realize_palette.rb +1 -0
  247. data/lib/emf/emr/binary/records/rectangle.rb +1 -1
  248. data/lib/emf/emr/binary/records/resize_palette.rb +16 -2
  249. data/lib/emf/emr/binary/records/round_rect.rb +2 -2
  250. data/lib/emf/emr/binary/records/select_palette.rb +1 -0
  251. data/lib/emf/emr/binary/records/set_color_adjustment.rb +136 -0
  252. data/lib/emf/emr/binary/records/set_colorspace.rb +22 -1
  253. data/lib/emf/emr/binary/records/set_dibits_to_device.rb +43 -0
  254. data/lib/emf/emr/binary/records/set_icm_profile_a.rb +71 -1
  255. data/lib/emf/emr/binary/records/set_icm_profile_w.rb +71 -1
  256. data/lib/emf/emr/binary/records/set_linked_ufis.rb +49 -1
  257. data/lib/emf/emr/binary/records/set_miter_limit.rb +1 -1
  258. data/lib/emf/emr/binary/records/set_palette_entries.rb +20 -2
  259. data/lib/emf/emr/binary/records/set_text_justification.rb +8 -2
  260. data/lib/emf/emr/binary/records/small_text_out.rb +55 -4
  261. data/lib/emf/emr/binary/records/stretch_blt.rb +14 -0
  262. data/lib/emf/emr/binary/records/stretch_dibits.rb +14 -0
  263. data/lib/emf/emr/binary/records/transparent_blt.rb +43 -0
  264. data/lib/emf/emr/binary/records.rb +4 -2
  265. data/lib/emf/emr/binary/region_data.rb +33 -0
  266. data/lib/emf/emr/binary/state_record_body.rb +33 -0
  267. data/lib/emf/emr/binary/thin_shell.rb +226 -0
  268. data/lib/emf/emr/binary/value_view/layout.rb +101 -0
  269. data/lib/emf/emr/binary/value_view/reader_source.rb +88 -0
  270. data/lib/emf/emr/binary/value_view.rb +173 -0
  271. data/lib/emf/emr/binary/variable_buffers.rb +87 -0
  272. data/lib/emf/emr/binary.rb +4 -0
  273. data/lib/emf/emr/filled_record.rb +77 -0
  274. data/lib/emf/emr/parser.rb +239 -50
  275. data/lib/emf/emr/serializer.rb +4 -5
  276. data/lib/emf/emr.rb +1 -0
  277. data/lib/emf/error.rb +24 -1
  278. data/lib/emf/model/diagnostic.rb +41 -0
  279. data/lib/emf/model/emr/header.rb +40 -1
  280. data/lib/emf/model/emr/records.rb +142 -6
  281. data/lib/emf/model/emr/wire_values.rb +43 -0
  282. data/lib/emf/model/emr.rb +1 -0
  283. data/lib/emf/model/geometry/color.rb +19 -1
  284. data/lib/emf/model/metafile.rb +22 -2
  285. data/lib/emf/model/wmf/bitmap_records.rb +155 -0
  286. data/lib/emf/model/wmf/brush_records.rb +45 -0
  287. data/lib/emf/model/wmf/dc_escape_records.rb +67 -0
  288. data/lib/emf/model/wmf/font_record.rb +40 -0
  289. data/lib/emf/model/wmf/geometry_records.rb +107 -0
  290. data/lib/emf/model/wmf/header.rb +36 -0
  291. data/lib/emf/model/wmf/object_records.rb +71 -0
  292. data/lib/emf/model/wmf/palette_records.rb +68 -0
  293. data/lib/emf/model/wmf/records.rb +247 -0
  294. data/lib/emf/model/wmf/region_records.rb +112 -0
  295. data/lib/emf/model/wmf/state_records.rb +188 -0
  296. data/lib/emf/model/wmf/text_records.rb +36 -0
  297. data/lib/emf/model/wmf.rb +11 -0
  298. data/lib/emf/model.rb +2 -0
  299. data/lib/emf/native/bitmap_fields.rb +58 -0
  300. data/lib/emf/native/diagnostic_contract.rb +39 -0
  301. data/lib/emf/native/diagnostics.rb +81 -0
  302. data/lib/emf/native/emf_plus_loader.rb +35 -0
  303. data/lib/emf/native/emf_plus_snapshot.rb +96 -0
  304. data/lib/emf/native/emf_plus_source.rb +20 -0
  305. data/lib/emf/native/emf_plus_stream.rb +150 -0
  306. data/lib/emf/native/fields.rb +369 -0
  307. data/lib/emf/native/font_fields.rb +87 -0
  308. data/lib/emf/native/gradient_fields.rb +23 -0
  309. data/lib/emf/native/header.rb +35 -0
  310. data/lib/emf/native/header_errors.rb +30 -0
  311. data/lib/emf/native/hydrator.rb +151 -0
  312. data/lib/emf/native/lazy_wire.rb +100 -0
  313. data/lib/emf/native/legacy_state_fields.rb +22 -0
  314. data/lib/emf/native/library_path.rb +68 -0
  315. data/lib/emf/native/loader.rb +120 -0
  316. data/lib/emf/native/palette_fields.rb +45 -0
  317. data/lib/emf/native/poly_text_fields.rb +116 -0
  318. data/lib/emf/native/resource_failure.rb +28 -0
  319. data/lib/emf/native/small_text_fields.rb +27 -0
  320. data/lib/emf/native/snapshot.rb +102 -0
  321. data/lib/emf/native/wmf_bitmap_fields.rb +58 -0
  322. data/lib/emf/native/wmf_brush_fields.rb +62 -0
  323. data/lib/emf/native/wmf_fields.rb +117 -0
  324. data/lib/emf/native/wmf_hydrator.rb +143 -0
  325. data/lib/emf/native/wmf_loading.rb +49 -0
  326. data/lib/emf/native/wmf_palette_fields.rb +60 -0
  327. data/lib/emf/native/wmf_region_fields.rb +92 -0
  328. data/lib/emf/native/wmf_rejection.rb +84 -0
  329. data/lib/emf/native/wmf_remaining_fields.rb +70 -0
  330. data/lib/emf/native/wmf_snapshot.rb +51 -0
  331. data/lib/emf/native/wmf_text_fields.rb +56 -0
  332. data/lib/emf/native.rb +61 -0
  333. data/lib/emf/parse_evidence.rb +57 -0
  334. data/lib/emf/resource_budget/bitmap.rb +66 -0
  335. data/lib/emf/resource_budget/gradient.rb +30 -0
  336. data/lib/emf/resource_budget/poly_text.rb +85 -0
  337. data/lib/emf/resource_budget.rb +382 -0
  338. data/lib/emf/resource_limits/emf_records.rb +130 -0
  339. data/lib/emf/resource_limits.rb +58 -0
  340. data/lib/emf/version.rb +1 -1
  341. data/lib/emf/visitors/dump.rb +4 -0
  342. data/lib/emf/visitors/stats.rb +6 -5
  343. data/lib/emf/wmf/binary.rb +150 -1
  344. data/lib/emf/wmf/bitmap_codec.rb +118 -0
  345. data/lib/emf/wmf/brush_codec.rb +102 -0
  346. data/lib/emf/wmf/dc_escape_codec.rb +75 -0
  347. data/lib/emf/wmf/dib.rb +187 -0
  348. data/lib/emf/wmf/embedded_emf.rb +137 -0
  349. data/lib/emf/wmf/escape_views.rb +89 -0
  350. data/lib/emf/wmf/evidence.rb +255 -0
  351. data/lib/emf/wmf/geometry_codec.rb +49 -0
  352. data/lib/emf/wmf/palette_codec.rb +85 -0
  353. data/lib/emf/wmf/parser.rb +147 -2
  354. data/lib/emf/wmf/recovery.rb +95 -0
  355. data/lib/emf/wmf/region_codec.rb +151 -0
  356. data/lib/emf/wmf/serializer.rb +164 -2
  357. data/lib/emf/wmf/text_codec.rb +123 -0
  358. data/lib/emf/wmf.rb +7 -0
  359. data/lib/emf.rb +13 -9
  360. metadata +287 -10
@@ -7,9 +7,98 @@ 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.
10
+ # Logical color space fields retain their original fixed-width wire bytes.
11
11
  class CreateColorspaceW < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ [
15
+ [:ih_cs, 0, "V", 4],
16
+ [:lcs_signature, 4, "V", 592],
17
+ [:lcs_version, 8, "V", 592],
18
+ [:lcs_size, 12, "V", 592],
19
+ [:color_space_type, 16, "l<", 592],
20
+ [:intent, 20, "l<", 592],
21
+ [:gamma_red, 60, "V", 592],
22
+ [:gamma_green, 64, "V", 592],
23
+ [:gamma_blue, 68, "V", 592],
24
+ [:dw_flags, 592, "V", 600]
25
+ ].each do |name, offset, format, required|
26
+ define_method(name) do
27
+ colorspace_body(required).byteslice(offset, 4).unpack1(format)
28
+ end
29
+
30
+ define_method("#{name}=") do |value|
31
+ write_colorspace_value(offset, value, format, required)
32
+ end
33
+ end
34
+
35
+ def endpoints_bytes
36
+ colorspace_body(592).byteslice(24, 36).b
37
+ end
38
+
39
+ def endpoints_bytes=(value)
40
+ replace_colorspace_bytes(24, 36, value, 592)
41
+ end
42
+
43
+ def filename_bytes
44
+ colorspace_body(592).byteslice(72, 520).b
45
+ end
46
+
47
+ def filename_bytes=(value)
48
+ replace_colorspace_bytes(72, 520, value, 592)
49
+ end
50
+
51
+ def cb_data
52
+ colorspace_body(600).byteslice(596, 4).unpack1("V")
53
+ end
54
+
55
+ def profile_bytes
56
+ bytes, length = profile_span
57
+ bytes.byteslice(600, length).b
58
+ end
59
+
60
+ def profile_bytes=(value)
61
+ _bytes, length = profile_span
62
+ replace_colorspace_bytes(600, length, value, 600)
63
+ end
64
+
65
+ private
66
+
67
+ def colorspace_body(required)
68
+ bytes = body.to_s
69
+ raise ArgumentError, "truncated logical color space body" if bytes.bytesize < required
70
+
71
+ bytes
72
+ end
73
+
74
+ def write_colorspace_value(offset, value, format, required)
75
+ colorspace_body(required)
76
+ raise ArgumentError, "color space value must be an Integer" unless value.is_a?(Integer)
77
+
78
+ range = format == "l<" ? (-0x80000000..0x7fffffff) : (0..0xffffffff)
79
+ raise RangeError, "color space value must fit its 32-bit field" unless range.cover?(value)
80
+
81
+ replace_colorspace_bytes(offset, 4, [value].pack(format), required)
82
+ end
83
+
84
+ def replace_colorspace_bytes(offset, length, value, required)
85
+ bytes = colorspace_body(required)
86
+ unless value.is_a?(String) && value.bytesize == length
87
+ raise ArgumentError, "color space value must be a String of #{length} bytes"
88
+ end
89
+
90
+ replacement = bytes.b
91
+ replacement[offset, length] = value.b
92
+ self.body = replacement
93
+ end
94
+
95
+ def profile_span
96
+ bytes = colorspace_body(600)
97
+ length = bytes.byteslice(596, 4).unpack1("V")
98
+ raise ArgumentError, "truncated color profile data" if length > bytes.bytesize - 600
99
+
100
+ [bytes, length]
101
+ end
13
102
  end
14
103
  end
15
104
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
+ require "emf/emr/binary/variable_buffers"
5
+ require "emf/emr/binary/dib_header"
4
6
  require "emf/emr/binary/record"
5
7
 
6
8
  module Emf
@@ -11,6 +13,12 @@ module Emf
11
13
  # Layout: emr, ihBrush, iUsage, offBmi, cbBmi, offBits, cbBits,
12
14
  # then trailing BMI/bitmap data.
13
15
  class CreateDibPatternBrushPt < Emf::Emr::Binary::Record
16
+ include Emf::Emr::Binary::VariableBuffers
17
+
18
+ fixed_layout 32
19
+ variable_buffer :bmi_bytes, offset: :off_bmi, length: :cb_bmi
20
+ variable_buffer :bits_bytes, offset: :off_bits, length: :cb_bits
21
+
14
22
  uint32 :ih_brush
15
23
  uint32 :i_usage
16
24
  uint32 :off_bmi
@@ -18,6 +26,12 @@ module Emf
18
26
  uint32 :off_bits
19
27
  uint32 :cb_bits
20
28
  rest :body
29
+
30
+ # Read-only; computed from the current fields on each call.
31
+ def dib_header_view
32
+ DibHeader.view(off_bmi, cb_bmi, 32, body,
33
+ bits_offset: off_bits, bits_size: cb_bits)
34
+ end
21
35
  end
22
36
  end
23
37
  end
@@ -2,15 +2,19 @@
2
2
 
3
3
  require "bindata"
4
4
  require "emf/emr/binary/record"
5
+ require "emf/emr/binary/font"
5
6
 
6
7
  module Emf
7
8
  module Emr
8
9
  module Binary
9
10
  module Records
10
- # Stub: ihObject + body bytes; full LOGFONT_PANOSE layout in TODO 10.
11
11
  class CreateFontIndirectW < Emf::Emr::Binary::Record
12
12
  uint32 :ih_object
13
- rest :body
13
+ font_body :body, byte_length: -> { n_size - 12 }
14
+
15
+ def elw
16
+ body.font
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
+ require "emf/emr/binary/variable_buffers"
5
+ require "emf/emr/binary/dib_header"
4
6
  require "emf/emr/binary/record"
5
7
 
6
8
  module Emf
@@ -11,6 +13,12 @@ module Emf
11
13
  # Layout: emr, ihBrush, iUsage, offBmi, cbBmi, offBits, cbBits,
12
14
  # then trailing BMI/bitmap data.
13
15
  class CreateMonoBrush < Emf::Emr::Binary::Record
16
+ include Emf::Emr::Binary::VariableBuffers
17
+
18
+ fixed_layout 32
19
+ variable_buffer :bmi_bytes, offset: :off_bmi, length: :cb_bmi
20
+ variable_buffer :bits_bytes, offset: :off_bits, length: :cb_bits
21
+
14
22
  uint32 :ih_brush
15
23
  uint32 :i_usage
16
24
  uint32 :off_bmi
@@ -18,6 +26,12 @@ module Emf
18
26
  uint32 :off_bits
19
27
  uint32 :cb_bits
20
28
  rest :body
29
+
30
+ # Read-only; computed from the current fields on each call.
31
+ def dib_header_view
32
+ DibHeader.view(off_bmi, cb_bmi, 32, body,
33
+ bits_offset: off_bits, bits_size: cb_bits)
34
+ end
21
35
  end
22
36
  end
23
37
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "bindata"
4
4
  require "emf/emr/binary/record"
5
+ require "emf/emr/binary/palette_body"
6
+ require "emf/emr/binary/palette_entry"
5
7
 
6
8
  module Emf
7
9
  module Emr
@@ -9,7 +11,23 @@ module Emf
9
11
  module Records
10
12
  class CreatePalette < Emf::Emr::Binary::Record
11
13
  uint32 :ih_pal
12
- rest :body
14
+ uint16 :version
15
+ uint16 :entry_count
16
+ array :palette_entries, type: :emr_palette_entry, initial_length: :entry_count
17
+ rest :trailing
18
+
19
+ def body
20
+ PaletteBody.new(self, to_binary_s.byteslice(12..))
21
+ end
22
+
23
+ def body=(value)
24
+ bytes = value.to_s
25
+ count = bytes.byteslice(2, 2)&.unpack1("v")
26
+ raise ArgumentError, "invalid palette body entry count" unless count && bytes.bytesize >= 4 + (count * 4)
27
+
28
+ replacement = self.class.read(to_binary_s.byteslice(0, 12) + bytes)
29
+ assign(replacement.snapshot)
30
+ end
13
31
  end
14
32
  end
15
33
  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 DeleteColorspace < 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
@@ -7,9 +7,53 @@ 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.
10
+ # Body-backed fields retain driver-specific bytes and trailing padding.
11
11
  class DrawEscape < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ def i_escape
15
+ escape_body.byteslice(0, 4).unpack1("V")
16
+ end
17
+
18
+ def i_escape=(value)
19
+ bytes = escape_body
20
+ valid = value.is_a?(Integer) && value.between?(0, 0xFFFFFFFF)
21
+ raise ArgumentError, "i_escape must be an unsigned 32-bit Integer" unless valid
22
+
23
+ bytes[0, 4] = [value].pack("V")
24
+ self.body = bytes
25
+ end
26
+
27
+ def cj_in
28
+ escape_body.byteslice(4, 4).unpack1("V")
29
+ end
30
+
31
+ def data_bytes
32
+ bytes = escape_body
33
+ length = bytes.byteslice(4, 4).unpack1("V")
34
+ raise ArgumentError, "truncated escape data" if length > bytes.bytesize - 8
35
+
36
+ bytes.byteslice(8, length).b
37
+ end
38
+
39
+ def data_bytes=(value)
40
+ length = data_bytes.bytesize
41
+ valid = value.is_a?(String) && value.bytesize == length
42
+ raise ArgumentError, "escape data must be a String of #{length} bytes" unless valid
43
+
44
+ bytes = escape_body
45
+ bytes[8, length] = value.b
46
+ self.body = bytes
47
+ end
48
+
49
+ private
50
+
51
+ def escape_body
52
+ bytes = body.to_s.b
53
+ raise ArgumentError, "truncated escape record prefix" if bytes.bytesize < 8
54
+
55
+ bytes
56
+ end
13
57
  end
14
58
  end
15
59
  end
@@ -10,7 +10,7 @@ module Emf
10
10
  # EMR_ELLIPSE: emr + rclBox per MS-EMF 2.3.5.
11
11
  # No rclBounds.
12
12
  class Ellipse < Emf::Emr::Binary::Record
13
- rectl :rcl_box
13
+ rectl :rcl_box
14
14
  end
15
15
  end
16
16
  end
@@ -14,6 +14,15 @@ module Emf
14
14
  uint32 :off_pal_entries
15
15
  uint32 :n_size_last
16
16
  rest :body
17
+
18
+ # Raw palette bytes (nPalEntries * 4 at offPalEntries from record start),
19
+ # or nil when there are no entries or the range leaves the record.
20
+ def palette_bytes
21
+ return unless n_pal_entries.positive? && off_pal_entries.positive?
22
+
23
+ bytes = to_binary_s
24
+ bytes.byteslice(off_pal_entries, n_pal_entries * 4) if off_pal_entries + (n_pal_entries * 4) <= bytes.bytesize
25
+ end
17
26
  end
18
27
  end
19
28
  end
@@ -1,15 +1,94 @@
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"
6
+ require "emf/emr/binary/extended_pen_buffers"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
12
  class ExtCreatePen < Emf::Emr::Binary::Record
13
+ include Emf::Emr::Binary::VariableBuffers
14
+
15
+ fixed_layout -> { 52 + (num_style_entries * 4) }
16
+ variable_buffer :bmi_bytes, offset: :off_bmi, length: :cb_bmi
17
+ variable_buffer :bits_bytes, offset: :off_bits, length: :cb_bits
18
+
19
+ class Body < String
20
+ def initialize(record, bytes)
21
+ @record = record
22
+ super(bytes)
23
+ end
24
+
25
+ def assign(bytes)
26
+ @record.body = bytes
27
+ replace(@record.body)
28
+ end
29
+ end
30
+
11
31
  uint32 :ih_pen
12
- rest :body
32
+ uint32 :off_bmi
33
+ uint32 :cb_bmi
34
+ uint32 :off_bits
35
+ uint32 :cb_bits
36
+ uint32 :pen_style
37
+ uint32 :width
38
+ uint32 :brush_style
39
+ color_ref :color
40
+ uint32 :brush_hatch
41
+ uint32 :num_style_entries
42
+ array :style_entries, type: :uint32, initial_length: :num_style_entries
43
+ extended_pen_buffers :buffers,
44
+ fixed_size: -> { 52 + (num_style_entries * 4) },
45
+ first_offset: -> { bits_first? ? off_bits : off_bmi },
46
+ first_length: -> { bits_first? ? cb_bits : cb_bmi },
47
+ second_offset: -> { bits_first? ? off_bmi : off_bits },
48
+ second_length: -> { bits_first? ? cb_bmi : cb_bits }
49
+
50
+ def bits_first?
51
+ off_bits.positive? && (off_bmi.zero? || off_bits < off_bmi || (off_bits == off_bmi && cb_bits.zero?))
52
+ end
53
+
54
+ def bitmap_info
55
+ return if off_bmi.zero?
56
+
57
+ bits_first? ? buffers.second_bitmap : buffers.first_bitmap
58
+ end
59
+
60
+ def bitmap_bits
61
+ return if off_bits.zero?
62
+
63
+ bits_first? ? buffers.first_bitmap : buffers.second_bitmap
64
+ end
65
+
66
+ def info_padding
67
+ bits_first? ? buffers.second_padding : buffers.first_padding
68
+ end
69
+
70
+ def bits_padding
71
+ bits_first? ? buffers.first_padding : buffers.second_padding
72
+ end
73
+
74
+ def trailing
75
+ buffers.trailing
76
+ end
77
+
78
+ # Sizes, counts and offsets are explicit, as in the text wire records.
79
+ # Update them when changing the lengths of styles or bitmap buffers.
80
+ def body
81
+ Body.new(self, to_binary_s.byteslice(12..))
82
+ end
83
+
84
+ def body=(value)
85
+ bytes = value.to_s
86
+ count = bytes.byteslice(36, 4)&.unpack1("V")
87
+ raise ArgumentError, "invalid extended pen body style count" unless count && bytes.bytesize >= 40 + (count * 4)
88
+
89
+ replacement = self.class.read(to_binary_s.byteslice(0, 12) + bytes)
90
+ assign(replacement.snapshot)
91
+ end
13
92
  end
14
93
  end
15
94
  end
@@ -7,9 +7,53 @@ 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.
10
+ # Body-backed fields retain driver-specific bytes and trailing padding.
11
11
  class ExtEscape < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ def i_escape
15
+ escape_body.byteslice(0, 4).unpack1("V")
16
+ end
17
+
18
+ def i_escape=(value)
19
+ bytes = escape_body
20
+ valid = value.is_a?(Integer) && value.between?(0, 0xFFFFFFFF)
21
+ raise ArgumentError, "i_escape must be an unsigned 32-bit Integer" unless valid
22
+
23
+ bytes[0, 4] = [value].pack("V")
24
+ self.body = bytes
25
+ end
26
+
27
+ def cj_in
28
+ escape_body.byteslice(4, 4).unpack1("V")
29
+ end
30
+
31
+ def data_bytes
32
+ bytes = escape_body
33
+ length = bytes.byteslice(4, 4).unpack1("V")
34
+ raise ArgumentError, "truncated escape data" if length > bytes.bytesize - 8
35
+
36
+ bytes.byteslice(8, length).b
37
+ end
38
+
39
+ def data_bytes=(value)
40
+ length = data_bytes.bytesize
41
+ valid = value.is_a?(String) && value.bytesize == length
42
+ raise ArgumentError, "escape data must be a String of #{length} bytes" unless valid
43
+
44
+ bytes = escape_body
45
+ bytes[8, length] = value.b
46
+ self.body = bytes
47
+ end
48
+
49
+ private
50
+
51
+ def escape_body
52
+ bytes = body.to_s.b
53
+ raise ArgumentError, "truncated escape record prefix" if bytes.bytesize < 8
54
+
55
+ bytes
56
+ end
13
57
  end
14
58
  end
15
59
  end
@@ -2,14 +2,21 @@
2
2
 
3
3
  require "bindata"
4
4
  require "emf/emr/binary/record"
5
+ require "emf/emr/binary/state_record_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 ExtFloodFill < Emf::Emr::Binary::Record
12
- rest :body
12
+ include StateRecordBody
13
+
14
+ BODY_SIZE = 16
15
+
16
+ point_l :start
17
+ color_ref :color
18
+ uint32 :flood_fill_mode
19
+ rest :trailing
13
20
  end
14
21
  end
15
22
  end
@@ -1,7 +1,9 @@
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"
6
+ require "emf/emr/binary/region_data"
5
7
 
6
8
  module Emf
7
9
  module Emr
@@ -9,9 +11,15 @@ module Emf
9
11
  module Records
10
12
  # EMR_EXTSELECTCLIPRGN: emr + cbRgnData + dwMode + RgnData[cbRgnData].
11
13
  class ExtSelectClipRgn < Emf::Emr::Binary::Record
14
+ include Emf::Emr::Binary::VariableBuffers
15
+
16
+ fixed_layout 16
17
+ variable_buffer :region_bytes, offset: 16, length: :cb_rgn_data
18
+
12
19
  uint32 :cb_rgn_data
13
20
  uint32 :dw_mode
14
- rest :rgn_data
21
+ region_data :rgn_data, byte_length: :cb_rgn_data, onlyif: -> { cb_rgn_data.positive? }
22
+ rest :body
15
23
  end
16
24
  end
17
25
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bindata"
4
4
  require "emf/emr/binary/with_bounds"
5
+ require "emf/emr/binary/ext_text_out_fields"
5
6
 
6
7
  module Emf
7
8
  module Emr
@@ -11,15 +12,27 @@ module Emf
11
12
  # ExtTextOutW except the string is 8-bit ANSI.
12
13
  class ExtTextOutA < Emf::Emr::Binary::WithBounds
13
14
  uint32 :i_graphics_mode
14
- float :ex_scale
15
- float :ey_scale
15
+ float32_le :ex_scale
16
+ float32_le :ey_scale
16
17
  point_l :ptl_reference
17
18
  uint32 :n_chars
18
19
  uint32 :off_string
19
20
  uint32 :f_options
20
- rectl :rcl
21
+ rectl :rcl, onlyif: -> { f_options.nobits?(0x100) }
21
22
  uint32 :off_dx
22
23
  rest :trailing
24
+
25
+ include Emf::Emr::Binary::ExtTextOutFields
26
+
27
+ private
28
+
29
+ def char_size = 1
30
+
31
+ # ANSI bytes read as Windows-1252; the real code page is the selected
32
+ # font's charset, which this record does not carry.
33
+ def decode_text(bytes)
34
+ bytes.dup.force_encoding(Encoding::Windows_1252).encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
35
+ end
23
36
  end
24
37
  end
25
38
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bindata"
4
4
  require "emf/emr/binary/with_bounds"
5
+ require "emf/emr/binary/ext_text_out_fields"
5
6
 
6
7
  module Emf
7
8
  module Emr
@@ -25,15 +26,25 @@ module Emf
25
26
  # ...Dx array (uint32 per char)...
26
27
  class ExtTextOutW < Emf::Emr::Binary::WithBounds
27
28
  uint32 :i_graphics_mode
28
- float :ex_scale
29
- float :ey_scale
29
+ float32_le :ex_scale
30
+ float32_le :ey_scale
30
31
  point_l :ptl_reference
31
32
  uint32 :n_chars
32
33
  uint32 :off_string
33
34
  uint32 :f_options
34
- rectl :rcl
35
+ rectl :rcl, onlyif: -> { f_options.nobits?(0x100) }
35
36
  uint32 :off_dx
36
37
  rest :trailing
38
+
39
+ include Emf::Emr::Binary::ExtTextOutFields
40
+
41
+ private
42
+
43
+ def char_size = 2
44
+
45
+ def decode_text(bytes)
46
+ bytes.dup.force_encoding(Encoding::UTF_16LE).encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
47
+ end
37
48
  end
38
49
  end
39
50
  end
@@ -1,14 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
- require "emf/emr/binary/record"
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 FillRgn < Emf::Emr::Binary::Record
12
+ class FillRgn < Emf::Emr::Binary::WithBounds
13
+ include Emf::Emr::Binary::VariableBuffers
14
+
15
+ fixed_layout 32
16
+ variable_buffer :region_bytes, offset: 32, length: :cb_rgn_data
17
+
18
+ uint32 :cb_rgn_data
11
19
  uint32 :ih_brush
20
+ region_data :rgn_data, byte_length: :cb_rgn_data
12
21
  rest :body
13
22
  end
14
23
  end