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>
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
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>
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>
[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>
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>
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>
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>
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
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
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>
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>
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
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
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>
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>
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>
Commit be9d6e414e4b forced all PS_COSMETIC pen widths to 1 in both
EMR_CREATEPEN and EMR_EXTCREATEPEN handlers. Since PS_COSMETIC is
0x00000000 (same value as PS_SOLID), the check
"if (nPenStyle == PS_COSMETIC)" matched every simple PS_SOLID pen,
causing all line widths to be lost. This made all lines render as
hairlines regardless of the actual width specified in the EMF file.
The style sanitization check for invalid PS_STYLE_MASK values is
retained, but the width forcing is removed. Pen widths from the
file are now used as-is: width=0 produces a hairline, width>=1
produces a scaled line. This effectively reverts to the behavior
established by tdf#140271 (commit 8932c8906ff3), which recognized
that real-world EMF producers use EMR_CREATEPEN with widths > 1
and expect them to be honored.
Change-Id: I9a3acf83ce03b4e646e9b95fe0db54f8ce403a49
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198904
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Jenkins
when BkMode is TRANSPARENT
In DrawText, the font's fill color was unconditionally set to maBkColor
before checking the background mode. When BkMode is TRANSPARENT, VCL's
underline rendering uses the font's fill color directly, ignoring the
transparency flag, causing an unwanted opaque background behind
underlined text.
Set COL_TRANSPARENT as the fill color when BkMode is TRANSPARENT, and
only use maBkColor when OPAQUE.
Change-Id: I0e94d2a1beae8ce2feecb0f7c0f8e03b36d2d80a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198889
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Jenkins
Found after running bin/find-unneeded-includes --headersfwd include/vcl/[d-g]*
This shaves off about 150M input
Change-Id: I2b15257451d4b392dca3e5d07f4a443ee653b04c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196395
Tested-by: Jenkins
Reviewed-by: Gabor Kelemen <gabor.kelemen@collabora.com>
which simplifies O[U]String expressions like
A = A + foo
into
A += foo
mostly because then they get spotted by other string plugins.
Change-Id: I2b81b701144acdf18743b52cb0befa7f90fd9528
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194191
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
After EMF_ROUNDRECT rendering comparison of Office 365 and
Libreoffice, it appears that radius of corners in LO is twice too large.
EMF_ROUNDRECT implementation has to be aligned and
conversion from ellipse width and height to ellipse vertical
and horizontal radius have been applied (values was divided by 2).
After apply this patch the ROUNDRECT looks identical as in Office.
The issue is also visible in previous version of LO (24.2.7).
Change-Id: I861fcd0e8d8a39d946215cc08ecc95403cd23fad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190391
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Tested-by: Jenkins
now that Bitmap supports transparency
Disable part of the redaction test. I have
verified that the visual result of auto-image redaction
is the same before and after this change, but we
seem to end up with more rectangles than before.
Probably something weird inside the EMF/WMF machinery.
(see the fixMetaFile function).
Change-Id: I85f308ae66ddf7592e41fde1ab9e49f9c882146e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190338
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>