Commit Graph
15 Commits
Author SHA1 Message Date
Brandon Thomas 749656605c Merge PR #635 from NikitkaRa: Metafile: EMF+ Clear, and the EMF+ record coverage written down 2026-10-14 13:57:48 -04:00
Brandon Thomas 1360b283f3 Merge PR #633 from NikitkaRa: Metafile: EMF+ cardinal curves and region fills
# Conflicts:
#	crates/render/src/tests.rs
2026-10-14 13:57:48 -04:00
Brandon ThomasandClaude Opus 5.5 389c4dd5d0 Fix up merged PRs: #588's polygon clip and nested metafiles with clip regions
Move #588's clip.rs changes into cliprect.rs, carry main's per-item clip
region through the polygon clipper, and build nested-metafile items with the
region field main added (the nested picture's own regions are not carried
over; each item takes the canvas's current clip).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:56:56 -04:00
Brandon Thomas 4d7406be10 Merge PR #588 from NikitkaRa: Metafile: EMF+ arcs, convex clip paths, wrapped strings, nested metafiles
# Conflicts:
#	crates/metafile/src/canvas.rs
#	crates/metafile/src/clip.rs
#	crates/metafile/src/emfplus.rs
2026-10-14 13:56:02 -04:00
Brandon ThomasandClaude Opus 5.5 3450180f19 Fix up merged PRs: EMF+ clipping alongside GDI clip regions
main added its own clip.rs (GDI rectangle regions carried on every drawn
item); #582 added a clip.rs that cuts drawing geometrically to the EMF+ clip
rectangle. Keep main's module, move #582's to cliprect.rs, keep the EMF+
rectangle on the canvas as plus_clip, and carry the region field through the
geometric clipper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:55:38 -04:00
Brandon Thomas eab5686393 Merge PR #582 from NikitkaRa: Metafile: EMF+ images, text, gradient brushes and clipping
# Conflicts:
#	crates/metafile/src/canvas.rs
#	crates/metafile/src/clip.rs
2026-10-14 13:54:59 -04:00
Brandon Thomas 437153c8b5 Merge PR #574 from NikitkaRa: Metafile: draw EMF+ only pictures
# Conflicts:
#	crates/metafile/src/tests.rs
2026-10-14 13:08:55 -04:00
Nikita RakitinandCursor fea8c1498f Metafile: EMF+ Clear, and the EMF+ record coverage written down
EmfPlusClear paints the whole picture frame in its colour, ignoring the
world transform and clip, as GDI+ does; a transparent clear draws nothing.
With it every drawing record of MS-EMFPLUS 2.3.4 is played. The module docs
list what is deliberately ignored (rendering hints, rendering origin,
serializable image effects, terminal-server records, and StrokeFillPath,
which the specification names but gives no layout for), and the parity docs
no longer say EMF+ isn't drawn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 02:52:57 +03:00
Nikita RakitinandCursor 5fc8aaee7c Metafile: EMF+ cardinal curves and region fills
DrawCurve, DrawClosedCurve and FillClosedCurve (GDI+ cardinal splines, the
smoothed lines of charts and freehand shapes) draw as cubic Béziers with
the record's tension, offset and segment count; FillRegion fills the region
object's area. These records were skipped, so the shapes were missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 02:47:47 +03:00
Nikita RakitinandCursor 8f935a8697 Metafile: EMF+ arcs, convex clip paths, wrapped strings, nested metafiles
Arcs and pies; clip paths and regions clip to their convex outline instead
of the bounding rectangle; DrawString wraps to the layout width; glyph-index
driver strings in the Windows core fonts map back to text; metafile images
draw their nested picture.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 00:52:06 +03:00
Nikita RakitinandCursor 07d12ed8d9 Metafile: EMF+ images, text, gradient brushes and clipping
Builds on the EMF+ only reader: bitmap images (raw pixel formats and
compressed PNG/JPEG payloads) through DrawImage and DrawImagePoints,
DrawString and character-code DrawDriverString, hatch, texture, linear and
path gradient brushes, clip rectangles, paths and regions, and objects
split across several records.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 00:43:00 +03:00
Nikita RakitinandCursor 2c15fcc033 Metafile: draw EMF+ only pictures
EMF+ only files (no GDI fallback) used to render as empty pictures. Play
their vector records: solid brushes and pens, paths, rects, polygons,
lines, ellipses and Beziers under world/page transforms with save/restore
and containers. Dual files keep drawing their EMF records.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 00:32:30 +03:00
NikitaandCursor 4fee02636a Metafile: clip EMF and WMF drawing to rectangle regions
INTERSECTCLIPRECT, EXCLUDECLIPRECT and EXTSELECTCLIPRGN limit what later records paint, including a region made of several rectangles. A rotated map stores the bounds of the clip rectangle.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 17:57:34 +03:00
Brandon ThomasandClaude Opus 5.5 e28851d2f1 Pictures: WMF/EMF text, pattern and hatch brushes draw; ActiveX previews show (#336)
* ActiveX controls show their pictures

A slide's p:controls are read: each control with a p:pic (the image PowerPoint shows for it,
often a WMF) becomes a picture above the slide's shapes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Metafiles draw their text, pattern and hatch brushes

deckcraft-metafile (still kurbo + thiserror only, so it builds for wasm):
- Text: WMF EXTTEXTOUT/TEXTOUT and EMF EXTTEXTOUTW/EXTTEXTOUTA/SMALLTEXTOUT with the
  selected font (CREATEFONTINDIRECT, EXTCREATEFONTINDIRECTW: face, signed LOGFONT height,
  width, weight, italic, underline, strike-out, escapement, charset), text and background
  colour, background mode, TA_* alignment and TA_UPDATECP, the dx array (ETO_PDY pairs too),
  ETO_OPAQUE fills and ETO_CLIPPED clips. 8-bit strings decode through their charset
  (Windows-1252/1250/1251; symbol fonts keep their codes at U+F000; double-byte sets keep
  their advances). The neutral Item::Text carries a text-space-to-picture transform, so the
  mapping and escapement are folded in and glyphs are never mirrored.
- Brushes: WMF DIBCREATEPATTERNBRUSH, EMF CREATEDIBPATTERNBRUSHPT and CREATEMONOBRUSH, and
  BS_HATCHED, as Item::Pattern tiles in 96-dpi pixels; WMF PATBLT. The XOR / AND-pattern /
  XOR see-through shadow of old PowerPoint WMFs draws its pattern in the XOR colour.
- MFCOMMENT escapes with an embedded EMF are ignored: PowerPoint draws the WMF's records.
- Pattern pixels and text count against the byte budget; strings are capped.

deckcraft-render draws text through deckcraft-fonts with the face slide text would use
(document_face), symbol fonts mapped as bullets map them (deckcraft_text::symbol_char, now
public, with Webdings), per-character fallback, the file's advances, GDI cell metrics for
top/bottom alignment, underline/strike-out and synthetic bold/italic. Tiles below 1.5 output
pixels per cell are drawn as their average colour.

On the 24 corpus slides that show a metafile, mean abs diff against PowerPoint goes from
28.31 to 5.06 (with the OLE/ActiveX preview commits).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:40:56 -04:00
Brandon ThomasandClaude Opus 5.5 f8d54d7af4 Pictures: WMF and EMF draw, with the metafile reader ported from WordCraft (#317)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 18:27:19 -04:00