514 Commits
Author SHA1 Message Date
Caolán McNamara 37fd5b78b0 ofz#541854037 Timeout
the polygon point counts were checked against the space left in the
whole file, and a small record inside a large file could claim far
more points than it holds

so bound them by the size of the record instead

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I0770546d0d48f9b306461da5e9c0117977079483
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/12367
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 292bae6e2ee1d8749040b258cd7bf415cf6241b4)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211410
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-09-24 11:01:20 +02:00
Caolán McNamara c850b5eef5 wmf: initialize each palette entry and stop reading on stream failure
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I2f2449be83cd7d895726e2200cae15d276a0eccf
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/7869
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit c0a67cf1a5e07a28db14c9309e9fde70984ab1a2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208699
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-28 10:13:29 +02:00
Caolán McNamara 552712e5df ofz: emfio, remember where the first free object slot is
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Iadc79d94c1741167641781cdb0cc455d32385219
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/7858
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 0066c2a9ad09f6372fd9073aecba049ebce8dc7c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208698
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-28 10:13:24 +02:00
Caolán McNamara 1705455b10 ofz: emfio, return early for bogus comment counts
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Ib745f2126b090135db4739925c21b9335bd91ab3
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/7850
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 250b57ce97f121eb02044143c9f7a805be553655)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208697
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-28 10:13:19 +02:00
Caolán McNamara 6c9a60a12a ofz: emfio, return early for bogus Polygon nextpos
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I5c91676d924cd1e92baa359464c4147509a59832
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/7848
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 0021f4cfbbd204f824a3b2c0b3085c29c597831f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208696
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-28 10:13:15 +02:00
Caolán McNamara 881df727c1 ofz: emfio, return early if stream can't supply bitmap data
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Iaba0db498fe014c5dc7acb04f0de2da7f6bfe1f7
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/7846
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 5ac7255f58fd7ab737e74274372e9c8ca8868a0e)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208692
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-07-28 10:12:45 +02:00
Xisco Fauli dae32b5f57 CppunitTest_emfio_emf: fix test on Windows
gerrit_windows_wsl was configure to build with 'make build'
so this failure wasn't caught in time.
Now gerrit_windows_wsl builds with 'make build unitcheck slowcheck'
and it fails with
Test name: testExtTextOutScaleGM_COMPATIBLE::TestBody
double equality assertion failed
- Expected: 199
- Actual  : 201
- Delta   : 1
- In <>, attribute 'width' of '/primitive2D/metafile/transform/textsimpleportion[3]' incorrect value.

Change-Id: Ibce7398946ef52eea05438feacc7a1dcaa22d579
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208165
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-16 00:42:18 +02:00
Khaled Hosny ef3c39851d vcl: Rename Font::Set/GetAverageFontWidth to Set/GetFontWidth
It is a misnomer now, so return to the original name.

Also drop the redundant private Font::GetAverageFontSize().

Change-Id: I67495fa675091b459a4e90ac09665489cc61fdd9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207991
Tested-by: Jenkins
Reviewed-by: Khaled Hosny <khaled@libreoffice.org>
2026-07-14 00:16:59 +02:00
Khaled Hosny aa1e992c23 vcl: Scale stretched fonts relative to the height on Windows
The font width used to mean the average character width on Windows,
like GDI’s LOGFONT lfWidth. This complicates things cross-platform, and
also DirectWrite does not expose such info.

Drop the whole average character width nonsense and align Windows to
other platforms, keeping the already existing cross-platforms
workarounds for EMF/WMF that are now applied also to Windows.

Change-Id: I750d42ad090bb9d0f776e80609b7a67b8ac38aac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207990
Reviewed-by: Khaled Hosny <khaled@libreoffice.org>
Tested-by: Jenkins
2026-07-14 00:16:49 +02:00
Xisco Fauli 3e607e03a4 cid#1693963: Unintended sign extension
Change-Id: I246a3f8b18143a5e62806bde8b4152f9f62468ca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207950
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-07-12 17:47:58 +02:00
Caolán McNamara b5953116c4 ofz: skip checksum check when fuzzing
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I7404322dc9cd8b7e6e4595b3867a6bf42c83b056
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6115
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 5c1fa7bf1ff8c2a28fba70804b41fa02e5c59c82)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207657
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-06 13:56:37 +02:00
Caolán McNamara 4406da79b0 ofz: ignore an advance array shorter than the string
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I6ceec1ecbae58a714d2f45eb786e01b428e6d942
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6114
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 6ab602ca281f507f7e637183a49dd514ffb1376b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207656
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-07-06 13:13:59 +02:00
Andras Timar 0447d0cc95 emfio: null-check VectorGraphicData before dereferencing in MULTIFORMATS
ReadMultiformatsComment dereferenced aGraphic.getVectorGraphicData()
unconditionally to call setSizeHint, then a few lines later acquired
the same pointer into a local and checked it for null. Reorder so
the null check happens before the first use, and reuse the local
for getType() too.

vcl::ImportPDF always installs a non-null VectorGraphicData on
success today, so this is defensive against future changes (or
edge-case ImportPDF backends that succeed without producing one)
rather than a fix for a confirmed crash. The macOS dbgutil
tinderbox report for tdf#167641 was not reproducible on two
separate macOS boxes, so the underlying issue could not be
diagnosed; this guard is the conservative belt-and-braces change.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I2569f26b099f305dd98b94ef4e9ab5c9a20fef11
(cherry picked from commit 36b0369ad6205aa7383ff4e93214853ea1081d61)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206642
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-06-16 01:19:22 +02:00
Andras Timar c043f65f66 tdf#167641 emfio: render PDF in EMR_COMMENT_MULTIFORMATS with Version=0
MS Office writes the EmrFormat.Version field as 0 in the
EMR_COMMENT_MULTIFORMATS record carrying an embedded PDF. Per
[MS-EMF] 2.3.3.4.2 EmrFormat, Version MUST be 0x00000001 only when
Signature == EPS_SIGNATURE; for any other signature it MUST be
ignored. The reader rejected anything but 1, so the embedded PDF
was dropped on the floor.

Real-world files also use an empty OutputRect (0,0,0,0); per
[MS-EMF] 2.3.3.4.3 it is in logical coordinates, so fall back to
the EMF's logical bounds (mrclBounds) when it is degenerate, so
ResolveBitmapActions has somewhere to draw the PDF bitmap.

The new fixture is the existing pdf-in-emf.pptx EMF with the two
fields patched to reproduce the regression in 776 bytes.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I432f75a1cac11d84448db07c1a1815cd0be60744
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1904
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit a5d7b2935718bf7f1f6cc0352c8d8681e6713f4b)
Cherry-pick note: the test fails on macOS in CI
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205084
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-13 09:57:03 +02:00
Caolán McNamara db72fb12d7 ofz: Use-of-uninitialized-value
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I5def88bee741c3792af724d1ad41585ee560c535
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2352
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 8828bfc6c41a8e64121a69ec7b995be4a12961fc)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205115
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-13 00:59:28 +02:00
Andras Timar 783914b216 emfio: fill each EmfPlusFillRects rect independently
The handler accumulated every rect from one EmfPlusFillRects
record into a single B2DPolyPolygon and emitted a single
PolyPolygonColorPrimitive2D, which drawinglayer fills under the
even-odd rule. With overlapping rects, even-odd cancels pairwise
overlaps - three south-east-shifted gray squares rendered as
filled-then-hollow-then-filled stripes (the triple-overlap centre
came back as filled because three crossings is again odd).

Per MS-EMFPLUS each rect in EmfPlusFillRects fills its interior
independently; there is no fill-rule choice. Emit one fill
primitive per rect inside the loop and keep the polypolygon path
only for EmfPlusDrawRects, where stroking is independent of fill
rule so the existing single-call shape stays correct.

Tests: testEmfPlusFillRectsOverlap with three 300x300 squares
shifted south-east by 100px each (extracted from the tdf#107034
sample EMF) asserts three separate polypolygoncolor primitives
rather than one combined.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I567e6a06d103684a723f513297684c66f700587a
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2314
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 679c654a5b9a5f4a1cd787e5fa2d2380eb5574fb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205087
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-05-12 16:21:49 +02:00
Andras Timar f8084808c2 emfio: render EMF+ PathGradient brushes
Replace the previous SvgRadialGradientPrimitive2D approximation of
PathGradientBrush with a bitmap-textured polypolygongraphic fill,
where the bitmap content is computed by a per-triangle Gouraud
shading of the brush boundary.

The old approximation positioned the gradient centre via
Map(brush->firstPoint), which typically landed far outside the
polygon's unit-coordinate range because the brush's path lives in
its own coordinate space; with SpreadMethod::Pad the gradient then
degenerated into a flat boundary-colour fill - the "orange square
instead of tiled gradient circles" of tdf#143031.

The bitmap is allocated with the brush bbox's aspect ratio
(longest side 256 px) and anchored to aBrushBounds.getMinX/MinY in
raw EMF coords, so when maMapTransform sends it to world space it
lines up with the fill polygon. wrapMode != WrapModeClamp routes
it through the existing texture-tiling path so larger fill polygons
repeat the bitmap.

Per-pixel content (Gouraud sweep):
- Partition the brush boundary into N triangles formed by (centre,
  V_i, V_{i+1}) and Gouraud-shade each one with vertex colours
  (centerColor, surround[i], surround[(i+1) % nSurround]). Inside a
  triangle the pixel colour is the barycentric blend of the three
  vertex colours; this reproduces multi-surround-colour brushes
  (e.g. the libUEMF 5-pointed star with red/blue/red/blue/magenta
  outer points and green inner indents on a black centre) and
  collapses to a smooth radial gradient when all surround colours
  are equal.
- The brush's BlendFactors curve (sampleFactor) remaps the
  centre/edge parameter t before mixing centre and per-segment
  edge colour. PresetColors / ColorBlend (sampleColor), when
  present, override the centre/edge mix entirely with a sampled
  stop colour. Both fall back to a linear centre-to-edge mix when
  the brush carries no curve.

Rasterization is done per-triangle: Pass 1 walks each fan
triangle's pixel-space AABB (clipped to the bitmap) and writes
only the pixels that fall inside, so total work is O(sum of
triangle AABB areas) rather than O(bitmap area * triangle count).
Structurally this is what cairo's mesh-pattern rasterizer
(cairo-mesh-pattern-rasterizer.c) does for PDF type-7 shadings -
each patch paints into its own pixel range rather than every
pixel testing every patch. With N up to ~512 boundary segments
after Bezier flattening, that turns a 256x256-pixel bitmap from
a ~30M pixel-tests-triangle loop into ~50k AABB iterations
(per-pixel arithmetic is unchanged so the rendered colours match
bit-for-bit).

Boundary handling:
- BrushDataPath set: take the brush's path polygon and flatten
  Bezier segments via adaptiveSubdivideByDistance with bound =
  bbox/512 so the boundary closely follows the curve.
- BrushDataPath unset: use a new EMFPPath::GetRawPointsPolygon()
  helper that builds a polygon directly from the boundary points.
  GetPolygon() can't be used here because the trailing bytes of
  boundary-only brush data don't encode valid path-point types and
  produce a degenerate polygon.

Pixels outside every fan triangle (in the bitmap bbox but not in
the boundary) are handled per wrapMode in a second pass:
- Tile / TileFlipX / TileFlipY / TileFlipXY: left transparent so
  adjacent tiles in the fill polygon stay visually separate. Pass
  2 is skipped entirely for these wrap modes.
- Clamp: extended using the closest triangle's edge colour
  (smallest-negative-margin barycentric weights), eliminating
  sub-pixel transparent jaggies along smooth Bezier fill polygons
  that extend slightly past the flattened boundary.

Tests: testEmfPlusBrushPathGradientWithBlendColors expectations
updated to assert the new polypolygongraphic-with-bitmap structure
(single bitmap copy fills the polygon when bitmap and polygon bbox
coincide). New testEmfPlusBrushPathGradientMultiSurroundColor
with a hand-extracted libUEMF 5-pointed-star EMF exercises the
boundary-only / multi-surround-colour path. testEmfPlusBrushPath-
GradientTiled covers the texture-tiling case where the brush
gradient is repeated across a larger fill polygon.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I92aa6d90ef6d2106f1d8d1cad97a3bb83594bd23
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2209
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit fa76144b9cf130e232465c2480a5a7127bb282ed)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205086
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-05-12 16:21:43 +02:00
Andras Timar 05f4321345 emfio: honour Winding fill mode on EMF+ FillClosedCurve
The fill-mode bit (0x2000) of EMF+ FillClosedCurve records was
logged but ignored, so a self-intersecting closed curve drawn with
WINDING semantics rendered the same as ALTERNATE - the centre of a
pentagram fill came out as a hole instead of being filled. Convert
the polypolygon at parse time the same way the pre-existing
EMR_SETPOLYFILLMODE path does (solveCrossovers +
stripNeutralPolygons + mergeToSinglePolyPolygon for single self-
intersecting polygons, createNonzeroConform for nested poly-
polygons) so the resulting even-odd fill of primitive2d primitives
matches the intended winding-fill visual.

Add a unit test with a minimal EMF+ FillClosedCurve drawing a
self-intersecting pentagram in winding mode.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: Ic02048aae223527dca0f556f0171f117baf147c0
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2313
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit fd018f6203f61aaf0c8c781c11a93578bf1eaf6b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205085
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-12 16:21:36 +02:00
Andras Timar d271bc432b tdf#116623 emfio: apply RGN_COPY region data in EMR_EXTSELECTCLIPRGN
[MS-EMF] 2.3.2.2 says the RegionData field "MUST be ignored" when
iMode is RGN_COPY, but real EMFs include data with RGN_COPY and
expect the clip to be replaced with the given region (verified
against MS Word reference rendering of test files such as
TestCreatePen.emf and a chart EMF where the colored plot lines
were leaking outside the plot frame). Treat the record like the
Win32 ExtSelectClipRgn API: a non-NULL region with RGN_COPY
replaces the clip, a NULL region (cbRgnData == 0) with RGN_COPY
resets the clip to the default null region.

Add a minimal hand-crafted EMF (TestExtSelectClipRgnCopy.emf) that
draws a (0,0)-(200,200) rectangle through a (50,50)-(150,150)
RGN_COPY clip and asserts the imported metafile wraps the rectangle
in a clip-region mask matching the requested rectangle.

Update existing test expectations to reflect the new clip-region
group/mask wrappers that now appear in the metafile primitive tree
where RGN_COPY data is present (testCreatePen, testPolyPolygon,
testTextMapMode, testEmfPlusSetPageTransform,
testDrawImagePointsWithMetafile, testSine).

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: Id123157b64b75d817b4736443eac14804b04bb89
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2206
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 1c2ff94b6079451a7047a2afb45467d6fe31cb4f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205072
Tested-by: Jenkins
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
2026-05-12 07:40:42 +02:00
Andras Timar 6bfe01ec89 emfio: handle pattern brush in non-rectangular shape primitives
DrawPolygon and DrawRect already route Pattern fill style through
ImplEmitPatternFill, but DrawEllipse, DrawRoundRect, DrawPie,
DrawChord, and DrawPolyPolygon still emit their plain Meta*Action
which leaves the shape unfilled. Route Pattern fill through the
helper for those too, converting the shape to its polygon
equivalent and emitting the clipped MetaWallpaperAction.

Add a unit test that draws an ellipse with a DIB pattern brush and
asserts the wallpaper is emitted in the metafile dump. Without the
fix the ellipse renders as a hairline outline only.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I2d4e273029770ddc727bc24d9b3205fe079fafd6
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2205
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit e87013a0457d270d442841610f4a3430e82f1274)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205041
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-11 12:25:29 +02:00
Andras Timar 7ed015807a emfio: invalidate fill style cache on SETBKMODE for hatched brushes
UpdateFillStyle short-circuits when maLatestFillStyle == maFillStyle,
but for a hatched brush the emitted MetaFillColorAction depends on
mnBkMode (bk color when OPAQUE, transparent when TRANSPARENT). With
no brush change between two rectangles separated only by SETBKMODE,
the second rectangle inherits the previous OPAQUE bk color fill, so
the gaps between hatch lines stay opaque.

Make SetBkMode invalidate maLatestFillStyle.aFillColor (using the
same sentinel that ResetInternalState uses) when the mode actually
changes, forcing the next UpdateFillStyle to re-emit a fresh
MetaFillColorAction with the correct bk-mode-dependent fill.

Add a unit test with a minimal hand-crafted WMF that draws two
rectangles using the same hatched brush across a SETBKMODE flip
and asserts that both a #ff0000 (OPAQUE bk color) and a #000000
(TRANSPARENT) fillcolor are emitted in the metafile.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I34b8984989f3ce9108464ad5a8c379174a988b59
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2204
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 41ddf034e276a5493f4fd56be61702a8b28e9649)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205040
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-11 11:57:59 +02:00
Andras Timar acc568fd2a emfio: render WMF DIB pattern brushes as tiled bitmap fills
META_DIBCREATEPATTERNBRUSH with Style=BS_PATTERN was dropped on the
floor with a SAL_WARN, and BS_DIBPATTERN averaged the bitmap to a
solid color, so neither produced a real pattern fill. Read both
variants into a real Bitmap (DIB or, for BS_PATTERN, a 1bpp Bitmap16)
and store it as a Pattern WinMtfFillStyle. Real-world generators
emit a DIB even with Style=BS_PATTERN, so peek the leading DWORD to
decide between DIB and Bitmap16. The same Bitmap16 helper handles
the obsolete META_CREATEPATTERNBRUSH record (32-byte legacy BITMAP +
reserved padding per MS-WMF 2.3.4.4).

The Pattern fill type was only handled in DrawPolygon, and that path
emitted XPATHFILL_SEQ_BEGIN/END comments with no actual paint
primitives. wmfemfhelper does not consume those comments, so the
PNG/drawinglayer rendering path saw nothing. Replace the comment
emission with a clip-region wrapped MetaWallpaperAction (Tile style)
which is fully consumed downstream. Factor the emission into
ImplEmitPatternFill and call it from DrawRect too, where Pattern
was previously not handled at all.

WinMtfFillStyle::operator== did not compare aBmp, so successive
pattern brushes with different bitmaps but identical solid-fill
fields compared equal and UpdateFillStyle short-circuited, leaving
maLatestFillStyle pointing at the previous bitmap. Include aBmp in
the equality check.

Add a unit test with a minimal hand-crafted WMF that asserts the
expected wallpaper sequence in the metafile dump.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: Ia2662de9cac5fcf1a7153237f9974467b8f849de
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2203
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 66dcbef6b5ceec8d9ccd4542509d5f9d7fdce2c1)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205039
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-05-11 11:34:08 +02:00
Caolán McNamara c8f5c789e8 ofz: Use-of-uninitialized-value
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Ia4aca5af7e5de2e27492135e37a49540c62f09a1
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1940
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit d21827b4c295afcd9aef02b2a5b725d1dd2f9711)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204882
Tested-by: Jenkins
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
2026-05-09 12:47:00 +02:00
Andras Timar 60c4f98cee tdf#143056 EMF+: honor StringFormat tracking when drawing strings
The tracking field was parsed but ignored, so DrawString always
used the font's natural character advances. Now build a DX-array
by multiplying each cumulative width by tracking, and pass it to
the text primitive. Also use the stretched width for alignment
math so center/far positioning stays correct.

testDrawStringTracking loads an EMF+ with tracking == 1.5 and checks
that the resulting textsimpleportion carries a stretched DX-array.

testDrawStringAlign turned out to use a file with tracking == 1.03 and
its expected x positions were based on the old buggy behavior (tracking
silently ignored).  Update the centered/right-aligned expectations to
match the corrected text width.

Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: Ica93f6ba11d2d951688ee18230e5993d97a34db6
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1986
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 1a9cce32f7408aab06289295c63b3e24146472a0)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204839
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-05-06 09:36:55 +02:00
Caolán McNamara fa0d87b427 ofz#496751918 Out-of-memory
Change-Id: Ie0a3857669f8283a6d15460cbcd8453b6c3325b0
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1057
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit a7f72dd3b242e6390169bfe0131e7e31a87ceeec)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204400
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-04-27 16:04:31 +02:00
Caolán McNamara cc32ab7342 ofz#496349582 Integer-overflow
Change-Id: I537f96838f402f20b537440a5cf94967814a64ce
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1052
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 4c4f052a5f3700c332ede70bc71dda3529266ba5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204398
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-04-27 16:03:44 +02:00
Andras Timar 14be550da2 emfio: implement BS_HATCHED brushes and pens
Handle BS_HATCHED brush style in EMR_CREATEBRUSHINDIRECT,
W_META_CREATEBRUSHINDIRECT, and EMR_EXTCREATEPEN.

For brushes (hatch indices 0-5), map Windows hatch styles
(HS_HORIZONTAL..HS_DIAGCROSS) to VCL Hatch objects and emit
MetaHatchAction in all polygon/polypolygon fill paths.

For EMF-specific hatch indices 6-11, use the appropriate color
source per [MS-EMF] 2.1.17: brush color (6-7), text color (8-9),
or background color (10-11) as solid fills.

For wide geometric pens with BS_HATCHED (EMR_EXTCREATEPEN),
create stroke area geometry via createAreaGeometry and render
the hatch pattern inside the pen stroke area, replacing the
normal MetaPolyLineAction/MetaLineAction. This covers all
drawing paths including LineTo, DrawPolyLine, DrawPolygon,
DrawPolyPolygon, DrawRect, DrawRoundRect, DrawEllipse, DrawArc,
DrawPie, DrawChord, DrawPolyBezier, and StrokeAndFillPath.

Change-Id: Ie8482ac53b6d4d263793488ce10a97fa1716c68d
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/325
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 8808d550d12afb3e7abc4fe6a3145d80fc5bdde4)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204389
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-04-27 08:58:20 +02:00
Andras Timar 857fd268e8 emfio: implement EMR_SETPOLYFILLMODE and W_META_SETPOLYFILLMODE
The polygon fill mode (ALTERNATE vs WINDING) was ignored in both EMF
and WMF readers.  ALTERNATE (even-odd) is the default; WINDING
(non-zero winding) appears in 2541/6939 EMF files and 135/467 WMF
files that set the mode.  Self-intersecting polygons like pentagram
stars render differently under the two rules.

Store the fill mode state in MtfTools with save/restore in Push/Pop,
wire up the record handlers, and fix the hardcoded fillNonZero in
DrawPolygon pattern fills to respect the current mode.

Add a unit test with a pentagram star EMF using WINDING mode.

Change-Id: I1d9127b79cc6c3b67f39bebe2c82e806c9db4ce8
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/324
Tested-by: Andras Timar <andras.timar@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204388
Tested-by: Jenkins
2026-04-27 08:58:11 +02:00
Andras Timar d8f87cb61f emfio: implement EMR_GRADIENTFILL for rectangle modes
Read the TriVertex array and GradientRectangle indices, then emit
MetaGradientAction with a linear gradient for each rectangle pair.

- GRADIENT_FILL_RECT_H (0): horizontal, left-to-right
- GRADIENT_FILL_RECT_V (1): vertical, top-to-bottom
- GRADIENT_FILL_TRIANGLE (2): logged as TODO (Gouraud shading has
  no direct VCL primitive)

COLOR16 values are converted to 8-bit via >> 8; Alpha is ignored
per the [MS-EMF] spec.

Change-Id: I9bb525eb16fe63908b0160ff029c270765edda15
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/323
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit b13431518550e387318190b6827eaf10427aa745)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204387
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-04-27 08:58:03 +02:00
Andras Timar c80a393bc7 emfio: implement EMR_CREATEMONOBRUSH
same structure as CREATEDIBPATTERNBRUSHPT

Change-Id: Iaf8129c6150df4e5786eeb0676e7e19a9bb041d2
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/322
Tested-by: Andras Timar <andras.timar@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 838c5c042b817006b889b7ebd00a8ec2d14365fa)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204386
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-04-27 08:57:56 +02:00
Andras Timar 8e07fd830e emfio: remove implemented records from unsupported list in README
EMR_ANGLEARC, EMR_POLYDRAW and EMR_CREATECOLORSPACE are already
implemented in emfreader.cxx but were incorrectly listed as
unsupported in README.md.

Change-Id: I04e45cf544c2bf50a93a8436c335c34be7df632b
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/321
Tested-by: Andras Timar <andras.timar@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 1411d7bc9ec9cd327d9665bc499e69a0112cb9fc)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204248
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-04-27 01:03:51 +02:00
Andras Timar 2ac3353184 emfio: implement EMR_EXCLUDECLIPRECT
Wire up EMR_EXCLUDECLIPRECT (record type 29) in the EMF reader.
ExcludeClipRect() was already implemented in MtfTools and used by the
WMF reader, but missing from the EMF record dispatch. This record
subtracts a rectangle from the current clipping region, creating a
"hole" that prevents drawing in that area.

Present in 291 of 6,939 real-world EMF files (4.2%).

Change-Id: I7bff53473c19453605e5fd88fdeff101f213fd85
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/320
Tested-by: Andras Timar <andras.timar@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit 38e963b2b4b12471b2530e11208a543f403bf4f2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204247
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-04-27 01:03:44 +02:00
Andras Timar f7cc19ac92 emfio: rename EMR_ALPHADIBBLEND to EMR_SETLAYOUT and log non-zero values
Record 115 (0x73) was incorrectly named EMR_ALPHADIBBLEND, from a
pre-Windows 2000 draft of the EMF spec. The final [MS-EMF] spec defines
it as EMR_SETLAYOUT, which controls the DC layout direction (LTR/RTL).

For now just rename and log when a non-zero LayoutMode is encountered
(SAL_WARN), so we can observe real-world usage before deciding how to
implement the actual coordinate mirroring and text direction changes.

6939 EMF files from public bug trackers were analyzed, 2143 files
contained EMR_SETLAYOUT but none of them contain LayoutMode other
than 0.

Change-Id: Ic4116fcd4a079d09684deb792e2f0ddc646248eb
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/319
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit ab2b4437b178d5d397844cfeeeff43fd88b5cc9f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204246
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-04-27 01:03:37 +02:00
Andras Timar 5db6c203f3 tdf#168107 emfio: render ETO_GLYPH_INDEX text as glyph outlines
also tdf#137440 and tdf#102780

EMF files with pre-shaped text (e.g. Arabic) use ETO_GLYPH_INDEX in
EMR_EXTTEXTOUTW records. The string data in these records contains
font-specific glyph indices (16-bit IDs), not Unicode codepoints.

Previously, emfio read these glyph indices as Unicode text via
read_uInt16s_ToOUString, then passed them to DrawText which creates
a MetaTextArrayAction. On playback, VCL/HarfBuzz would shape these
fake "characters" again, producing double-shaped garbage output.

Fix this by detecting ETO_GLYPH_INDEX and rendering the pre-shaped
glyphs as filled polypolygon outlines, bypassing text shaping entirely.

Implementation:

- Add OutputDevice::GetGlyphOutlines() as a new VCL public API that
  takes raw glyph IDs and returns per-glyph B2DPolyPolygon outlines
  by calling LogicalFontInstance::GetGlyphOutline() directly. This is
  needed because LogicalFontInstance is in VCL's private headers and
  not accessible from emfio.

- Add MtfTools::DrawGlyphs() in emfio that mirrors the DrawText()
  setup (position/DX/DY mapping, font/color/alignment MetaActions)
  but instead of emitting MetaTextArrayAction, it obtains glyph
  outlines via GetGlyphOutlines() on a VirtualDevice, positions each
  glyph using the DX/DY array, and emits the combined result as a
  filled MetaPolyPolygonAction with the text color.

- Branch in emfreader.cxx: when ETO_GLYPH_INDEX is set on the Unicode
  variant (EMR_EXTTEXTOUTW), read glyph indices as sal_uInt16 values
  and call DrawGlyphs() instead of DrawText().

- Since glyph indices are font-specific, DrawGlyphs() checks font
  availability via IsFontAvailable() before rendering. If the required
  font is not installed, it returns false and the code falls back to
  the standard DrawText() path (same as before this change).

- Remove the stale SAL_WARN_IF for ETO_PDY|ETO_GLYPH_INDEX, since
  both flags are now handled.

Change-Id: Ib6e0a0b1accfe61ff871c391d02f4c529764438c
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/318
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit b260c2a6d8313c80720e34a366f01bcd0e429f47)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204245
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
2026-04-24 15:50:37 +02:00
Noel Grandin e77b23fa1c Fraction->double in MapMode
Change-Id: I865fe1c2b0377eebda6f9f19e163928cbe7c9056
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202631
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2026-03-26 13:23:37 +01:00
Bartosz Kosiorek 3407985249 tdf#103859 emfio: Update variable types to match EMF specification
This patch corrects several variable types across the EMF reader
to strictly align with the official Enhanced Metafile specification,
improving memory safety and fixing minor logging bugs.

Change-Id: I1cc1351248bcdb40220c33441e363aaa226f1ea1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202625
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-03-24 19:52:59 +01:00
Caolán McNamara d70bf770a8 ofz#494703925 Out-of-memory, etc
possibly since:

commit aad62f783b
Date:   Sun Feb 8 12:09:12 2026 +0100

    tdf#142226 emfio: implement EMR_SMALLTEXTOUT

Change-Id: Ic45575e9993a1f16e9221418c421a3f2500ded27
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202387
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
2026-03-23 10:04:13 +01:00
Andrea Gelmini c21f0a4a42 Fix typo
Change-Id: Ib019fb6e87f3da356a69a14729864f31b777c8bf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201196
Tested-by: Julien Nabet <serval2412@yahoo.fr>
Reviewed-by: Simon Chenery <simon_chenery@yahoo.com>
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
2026-03-19 09:51:46 +01:00
Bartosz Kosiorek f0a3081314 tdf119973 tdf160063 emfio: Reset GDI trackers on EMF+ GetDC record
When an EMF+ Dual Mode file switches back to GDI records via
EmfPlusRecordType::GetDC (0x4004), the GDI parser (MtfTools)
might have outdated information about the current state of the
VCL MetaFile, as EMF+ records could have modified it in the meantime.

By introducing ResetInternalState(), we invalidate the "latest"
trackers for fill style, line style, and text attributes. This
forces the parser to re-emit the necessary GDI actions (like
SetFillColor) for the subsequent GDI records, preventing issues
like incorrect colors (e.g., black shapes instead of white).

Change-Id: I1665daba2d9a2105f135e2b638af48d2b14150eb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201720
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-03-15 17:46:51 +01:00
Bartosz Kosiorek c1fb4c337d tdf59814 tdf168886 EMF+ Use Frame size and DPI instead Bound
Previously, nested EMF images were sized based on rclBounds, which
only encompasses the drawn objects. This caused incorrect scaling
and offsets when the drawing did not fill the entire logical canvas.

Changes:
- Switched from rclBounds to rclFrame for logical canvas dimensions.
- Implemented DPI calculation using szlDevice and szlMillimeters
  from the EMF header.
- Correctly mapped rclFrame (0.01mm units) to image pixel
  coordinates (x, y, width, height).

Change-Id: I32f6679bedb26e86b069abd6b4d270a385ca7e89
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201586
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Tested-by: Jenkins
2026-03-13 11:44:54 +01:00
Noel Grandin 8459f0be51 XmlWriter::attribute(double) should actually write a double value
And not truncate it to an integer value.

Add additional overload for attribute that takes an enumerated type, otherwise
the compiler will complain about ambiguous conversion because it cannot
choose between the attribute that takes a integral value and the one that
takes a double value.

Change-Id: I9eae22817ec3b26da7b9468d1c8b5e6f3e900538
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201193
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Jenkins
2026-03-10 15:49:17 +01:00
Xisco Fauli 6709dd178f CppunitTest_emfio_emf: fix build on Windows
Change-Id: Iffc791557eea3e38b02262f81c26c5dece6c343b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201136
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-03-07 09:19:56 +01:00
Bartosz Kosiorek 4dccec254c tdf166084 tdf138087 tdf59814 EMF+ Fix scale and trans DrawImagePoints Metafile
This commit fixes the incorrect positioning and scaling of Metafiles
rendered via EMF+ DrawImagePoints.

Key changes:
- Implemented a normalization matrix for Metafiles to properly map
  source coordinates (SrcRect) to the destination.
- Updated EMFPImage to parse and store bounds from nested EMF headers,
  ensuring correct dimensions (x, y, width, height) are available.

Change-Id: I07b4d99c334611a10e7faff42b76699f04fa1520
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201084
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-03-06 22:13:37 +01:00
Bartosz Kosiorek 6c05a6339c tdf#129342 tdf#170985 EMF+ Implement BrushTypeTextureFill for bitmaps
This patch implements the missing TextureFill brush support for EMF+
records. Previously, texture fills were ignored, resulting in missing
backgrounds or shapes.

Change-Id: I61f80a9851f3929651f54b68d6d4d21e65720aa6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200547
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-02-28 08:04:39 +01:00
Andrea Gelmini 6cdefb0806 Fix typo
Change-Id: Ibf6a768e07ee7892b74264732a261e364e13cfac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199966
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Jenkins
2026-02-26 18:26:23 +01:00
Caolán McNamara 3dfbc9df7d ofz: Use-of-uninitialized-value
there's a switch off this value before the mpInputStream->good() guard

Change-Id: I8ac7ce45336d9edbfae2308af39632c9322b2526
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199992
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
2026-02-22 20:42:22 +01:00
Gabor Kelemen eb087d25b3 tdf#146619 Use more forward declarations in include/drawinglayer
Change-Id: I5911dfb1cfc2bfd291758334b69123cfbce559a5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199387
Reviewed-by: Gabor Kelemen <gabor.kelemen@collabora.com>
Tested-by: Jenkins
2026-02-22 12:08:33 +01:00
Bartosz Kosiorek b6857c1f16 tdf#138087 tdf#142548 EMF Fix font scaling and orientation in GM_COMPATIBLE
When importing EMF files, certain records (like EXTTEXTOUTW) in
GM_COMPATIBLE mode were not respecting non-proportional scaling
or single-axis mirroring. This resulted in text that was too wide/narrow
or rotated in the wrong direction.

Key changes:
- Added font width scaling based on the ratio between fXScale and fYScale.
- Handled 180-degree rotation when both axes are negative.
- Corrected font orientation for single-axis mirroring by inverting the
  angle (3600 - orientation) to compensate for the reversed chirality
  of the coordinate system.

Change-Id: Ib1126c192a80b973f343f25bf20ec119d94d71a8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199770
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-02-21 08:30:48 +01:00
Xisco Fauli ba3fb9026c merge UnoApiText and UnoApiXmlTest
in preparation for a follow-up commit

Change-Id: I3449c031696fe3ab13d4832e2671da08eb483cdb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199552
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2026-02-18 21:17:13 +01:00
Bartosz Kosiorek 8b002437fb tdf#168227 EMF+ Fix implementation of SetPageTransform
The implementation of SetPageTransform was incorrectly overwriting mnMmX and mnMmY
with calculated pixel values.

These variables represent the Reference Device size from the EMF+ header and should
remain constant. Overwriting them causes mappingChanged() to calculate an incorrect
transformation matrix, as it relies on the original ratio between reference
millimeters and pixels. This led to incorrect scaling and cumulative errors
if multiple SetPageTransform records were present in the document.

This patch ensures that header constants are preserved and the Page Scale
is applied as a separate step in the transformation pipeline.

Change-Id: I7a957f57894cc079292e8f93c119dd0fdb456fb4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199380
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
2026-02-15 12:21:53 +01:00