This commit continues the cleanup of map.cxx by refactoring the
Polygon overload of OutputDevice::LogicToPixel to use the new
explicit ImplMapRes wrappers.
Key changes:
- Replaced the nested ViewToWindowUnits(LogicUnitsToViewUnits(...))
calls with the much cleaner LogicToWindowUnitsX/Y(..., aMapRes)
master wrappers.
- Removed legacy C-style pointer arithmetic (GetConstPointAry) in
favor of directly accessing and assigning to the polygon via the
overloaded operator[].
- Eliminated the temporary Point allocation and sequential setX/setY
calls, replacing them with a direct inline Point constructor.
- This dramatically improves the readability of the loop while
maintaining identical coordinate transformation behavior.
Change-Id: I25252b99f5fc8e1b7097d766cd74ac6e7e8f3e80
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203669
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit improves the encapsulation of custom MapMode conversions
by adding ImplMapRes overloads to the LogicToWindowUnits master
wrappers in CoordinateMapper.
Previously, when OutputDevice::LogicToPixel was called with an
explicit custom MapMode, it had to bypass the standard wrappers and
manually chain the LogicUnitsToViewUnits and ViewToWindowUnits
pipeline stages inline. This resulted in highly verbose and difficult-
to-read rectangle initialization.
Key changes:
- Added LogicToWindowUnitsX(nX, rRes) and LogicToWindowUnitsY to
CoordinateMapper to safely encapsulate custom resolution scaling
while still applying the correct internal window offsets.
- Refactored OutputDevice::LogicToPixel(Rectangle, MapMode) in
map.cxx to use these new wrappers, drastically improving the
readability of the coordinate mapping logic.
Change-Id: Ib3af5314ad11653395b08c2ca722d66360baeb99
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203668
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit replaces manual coordinate arithmetic in map.cxx with the
newly introduced CoordinateMapper pipeline stages and master wrappers,
improving encapsulation and fixing a subtle offset bug.
Key changes:
- OutputDevice::LogicToDeviceSubPixel: Replaced nested pipeline calls
and manual device origin additions with the LogicToDeviceSubPixel
master wrapper. This completely hides the math from map.cxx and
ensures the absolute logical offset (mnOutOffLogic) is correctly
applied before any DPI/MapMode scaling occurs.
- OutputDevice::ImplPixelToDevicePixel: Fixed an early-exit bug. The
legacy code only checked if the screen origin (mnOutOff) was zero
before returning early, completely ignoring whether the window had an
internal VCL pixel offset (mnOutOffOrig). By piping `0` through
ViewToWindowUnits and WindowToDeviceUnits, we now calculate the
exact combined spatial delta to check for the early exit and move
the region safely.
Change-Id: I697a0a7aa2bc4c03e55654305432b0805cee9c66
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203667
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Updates the OutputDevice::LogicToPixel variant that accepts an
explicit MapMode to utilize CoordinateMapper pipeline stages.
Previously, this method manually composed the transformation by
adding ImplMapRes offsets, calling LogicToViewDistance, and then
adding the internal VCL pixel offset (mnOutOffOrigX/Y).
By refactoring this to use LogicUnitsToViewUnitsX/Y(nX, aMapRes)
nested within ViewToWindowUnitsX/Y, we maintain architectural
consistency with the rest of the mapper refactor. This ensures
that even when using a temporary resolution context, the coordinate
journey follows the standardized Logic -> View -> Window path
without exposing raw arithmetic in OutputDevice.
Change-Id: Ie39cf7d67d6461f418c942528abbbffbf7f9a7bc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203663
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Introduces LogicToWindowUnitsX and LogicToWindowUnitsY to the
CoordinateMapper API. These master wrappers chain the first two
stages of the forward transformation pipeline (LogicUnits -> View
-> Window), cleanly stopping before the final physical screen
offset is applied.
This addition is immediately put to use in map.cxx to refactor
OutputDevice::LogicToPixel for both Rectangles and Polygons.
It successfully collapses complex, nested inline arithmetic—such
as the manual scaling of logical offsets and the explicit addition
of internal VCL pixel offsets (mnOutOffOrigX/Y)—into single,
highly semantic API calls.
OutputDevice is now further isolated from the underlying mechanics
of the coordinate mapping math, continuing the encapsulation
goals of the mapper refactor.
Change-Id: Ifbc49b3c8ba5a84d864fe9a6626dcf587039241d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203662
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Updates OutputDevice::LogicToPixel(const Point&) to utilize the
newly established CoordinateMapper forward pipeline.
This replaces the manual inline composition of logical offsets,
distance scaling, and pixel offsets with a clean, chained
pipeline sequence: LogicUnitsToViewUnits -> ViewToWindowUnits.
By adopting this structure, we completely encapsulate the internal
VCL pixel offset (mnOutOffOrigX/Y) within the mapper, eliminating
the need for OutputDevice to manually fetch and add GetPixelXOffset().
This abstracts the coordinate math out of OutputDevice and enforces
the strict stage-by-stage geometric transition.
Change-Id: I4c29403e3c0f8afcde24927f3bc687b02c6e1479
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203661
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Introduces DevicePixelToLogicX and DevicePixelToLogicY to the
CoordinateMapper API, completing the "un-projection" side of the
transformation pipeline.
These master wrappers correctly chain the inverse pipeline stages
(Device -> Window -> View -> LogicUnits) and seamlessly handle the
MapMode bypass logic internally.
This allows us to strip out the massive, complex inline arithmetic
found in OutputDevice::ImplDevicePixelToLogic (inside map.cxx)
and replace it with clean, semantic function calls.
OutputDevice is now completely abstracted away from the underlying
geometric offset and scaling math, achieving the core encapsulation
goal of the coordinate mapper refactor.
Change-Id: I9a15041abede8ffdb4b7f71478b5b992fe2d062d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203660
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Updates OutputDevice::ImplDevicePixelToLogic to use the newly
established CoordinateMapper transformation pipeline when MapMode
is disabled.
Previously, this block manually subtracted GetDeviceOriginX/Y
from the given rectangle to convert absolute device pixels into
window-relative coordinates. This replaces the raw arithmetic
with explicit DeviceToWindowUnitsX/Y calls.
This change encapsulates the offset logic entirely within
CoordinateMapper and ensures the coordinate space transition
is explicitly documented by the API nomenclature.
Change-Id: Ica26ebd9b3c04eba2816dac26e2e8bca2a403776
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203659
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit finalizes the CoordinateMapper refactor by resolving naming
collisions and establishing a strict semantic separation between
physical units and logical distances.
To avoid ambiguity with the word "Pixel" and to clearly distinguish
between pure mathematical scaling and coordinate space translations,
the API has been standardized:
1. Distance Scaling:
Renamed the pure multiplication methods from LogicToViewX/Y to
LogicToViewDistanceX/Y. This frees up the namespace and clarifies
that these methods handle scaling without applying mapping offsets.
2. Physical Pipeline Stages (*Units):
Implemented the definitive space-to-space transformation ladder using
the 'Units' suffix for physical stages and 'LogicUnits' for the
document stage:
- DeviceToWindowUnits / WindowToDeviceUnits
- WindowToViewUnits / ViewToWindowUnits
- ViewToLogicUnits / LogicUnitsToViewUnits
3. Legacy Cleanup:
Purged the orphaned LogicToViewPixelX/Y declarations and
implementations left over from earlier refactoring attempts. Updated
the legacy ImplCalcDevicePixelX/Y helpers to utilize the new
LogicUnitsToViewUnitsX/Y pipeline stage.
4. map.cxx Alignment:
Updated all OutputDevice translation sites in map.cxx that previously
relied on the overloaded LogicToViewX/Y to explicitly call the correct
LogicToViewDistanceX/Y variants, restoring a clean build.
Change-Id: I621ed8741055a29bf65963d75b763ca3e4a7bd0f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203658
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Simplifies OutputDevice::ImplLogicToDevicePixel for B2DPolygons by
delegating coordinate transformation to the CoordinateMapper. By using
LogicToDevicePixelX and LogicToDevicePixelY, we eliminate redundant
if/else branching and ensure that window and pixel offsets are
consistently applied across both axes.
This refactoring also addresses systemic X/Y scaling mix-ups where the
horizontal scaler was being used for vertical coordinates, a bug
identified through failures in PDF export integration tests.
Changes:
* Simplified B2DPolygon transformation loop in map.cxx.
* Removed private visibility (SAL_DLLPRIVATE) from the B2DPolyPolygon
overload of LogicToPixel to allow for external unit testing.
* Added a new unit test fixture 'testB2DPolygonAsymmetricDPI' in
vclmaptest.cxx to verify scaling accuracy on asymmetric displays
(e.g., 100x200 DPI) and prevent future axis-specific regressions.
Change-Id: I718df9af8e5d8b2a446be74223047bdaa20ed148
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207555
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
The newly refactored CoordinateMapper::Logic[X|Y]ToDevicePixel()
methods act as the primary, state-aware public API for scalar
coordinate transformation.
Because these mapper methods already handle the IsMapModeEnabled()
state check internally, we can safely remove the manual branching
from the higher-level OutputDevice conversion methods. This
drastically simplifies the code, replacing massive blocks of inline
mathematical boilerplate with clean, 1-to-1 delegation calls.
- Simplified LogicToDevicePixel(const Point&) to delegate directly
to the mapper.
- Removed redundant MapMode branching that is now safely handled
by CoordinateMapper.
Change-Id: Ie7e3696f9cb2ec7098a3b8e6f5e500a366f8e72f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203653
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Identify a font by its typographic family (name ID 16) and subfamily
(name ID 17), falling back to legacy names (name ID 1 and 2), so we can
interoperate with systems that use legacy names, while using typographic
names internally.
Change-Id: Ie51c8c14fe91e7e314d9a4b4808485ea4483b524
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207546
Tested-by: Khaled Hosny <khaled@libreoffice.org>
Reviewed-by: Khaled Hosny <khaled@libreoffice.org>
Replaces the manual addition of mapping offsets (GetMapping[X|Y]Offset)
with the encapsulated LogicToOffsetLogic[X|Y] helpers introduced
recently in CoordinateMapper.
This continues the ongoing architectural cleanup by standardizing how
absolute logical coordinates are transitioned into view-relative
logical space before being scaled to device pixels.
- Updated LogicToDevicePixel overloads (Point, Rectangle, Polygon,
B2DPolygon).
- Updated LogicToPixel overloads (Point, Rectangle, Polygon).
- Updated LogicToDeviceSubPixel.
Change-Id: Ie0a6fc40ada9127860a244f3f93e02d9cc658f72
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203652
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Following the migration of the device origin state into
CoordinateMapper, this commit updates the complex coordinate
transformation methods in map.cxx to query the origin directly
from the mapper.
Bypassing the OutputDevice wrappers (GetDeviceOriginX/Y) makes it
explicitly clear that the mapper owns this physical window offset.
This reduces internal reliance on the OutputDevice god-class API
and sets the stage to potentially remove these wrappers entirely.
- Updated LogicToDevicePixel overloads (Point, Rectangle).
- Updated ImplLogicToDevicePixel overloads (Polygon, B2DPolygon,
PolyPolygon).
- Updated ImplDevicePixelToLogic (Rectangle) and
ImplPixelToDevicePixel (Region).
Change-Id: I1b5915f27bf6117a0fd303c7f30603a67ca181a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203651
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit finalizes the migration of the core scalar coordinate
transformations by moving the logic out of OutputDevice and entirely
into CoordinateMapper.
To clearly separate the public API (which handles MapMode state
branching) from the internal math engine (which unconditionally
applies offsets and scaling), the mapping operations have been
explicitly split.
- Removed ImplLogicXToDevicePixel() and ImplLogicYToDevicePixel()
from OutputDevice.
- Added LogicToDevicePixelX() and LogicToDevicePixelY() to
CoordinateMapper to act as the primary state-checking API.
- Added ImplCalcDevicePixelX() and ImplCalcDevicePixelY() to
CoordinateMapper to isolate the raw transformation math.
- Updated all scalar call sites across vcl (bitmap, map, mask,
outdev, pixel, rect) to route their math through the mpMapper
instance.
Change-Id: Ibb23aec54dd6eab6e3a753c2a61f8e023aa03883
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203650
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
vcl/source/outdev/ImplMapRes.cxx:115:70: runtime error: signed integer overflow: -9223372036854775808 + -57089 cannot be represented in type 'long long'
#0 0x592c9880de2d in operator() vcl/source/outdev/ImplMapRes.cxx:115:70
#1 0x592c9880de2d in ImplMapRes::CalcMapResolution(MapMode const&, long, long) vcl/source/outdev/ImplMapRes.cxx:119:9
#2 0x592c9819827c in OutputDevice::SetMapMode(MapMode const&) vcl/source/outdev/map.cxx:519:18
#3 0x592c9830750e in GDIMetaFile::Play(OutputDevice&, unsigned long) vcl/source/gdi/gdimtf.cxx:365:26
#4 0x592c978beda6 in TestImportSVM vcl/source/filter/svm/SvmConverter.cxx:1281:22
This seems to have appeared since:
commit 64c6a8c44b7730d1f703f260e7359642e8af9288
Date: Sun Mar 22 15:09:35 2026 +0200
Fraction->double in MapMode
Clamp the divided value to sal_Int32 range to explicitly restore the
limits that BigInt path incidentally.
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I3c8061a72e447e4bdcad07ace3075076d09285be
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1891
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
(cherry picked from commit b1dd07307b7a00e73996975616efa113940fdf37)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207723
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Completes the logical-to-device transformation pipeline by moving
the final physical offset calculations into CoordinateMapper.
OutputDevice no longer needs to manually assemble the view pixels,
device origins, and pixel offsets.
- Added LogicToDevicePixelX() and LogicToDevicePixelY() to
CoordinateMapper to handle the final transformation from view
space to physical device space.
- Simplified ImplLogicXToDevicePixel() and ImplLogicYToDevicePixel()
in map.cxx to directly delegate to these new mapper methods.
- Added comments in CoordinateMapper to clearly delineate the
Viewport (view space) and Physical window (device space) methods.
- Updated the unmapped branches in map.cxx to fetch the device
origin directly from mpMapper.
Change-Id: If7dbcf3fe9ed70fabc6c24d3b4a426cdde7d438c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203649
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
These functions are declared as file-local static helpers in map.cxx,
so they should follow the standard lcl_ naming convention rather
than the Impl prefix, which is generally reserved for private
class methods.
- Renamed ImplLogicToSubPixel() to lcl_logicToSubPixel().
- Renamed ImplSubPixelToLogic() to lcl_subPixelToLogic().
- Updated all call sites in SubPixelToLogic(), LogicWidthToDeviceSubPixel(),
LogicHeightToDeviceSubPixel(), and LogicToDeviceSubPixel().
Change-Id: I01e64f41b153526c13f15856e1182d3bea6802f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203648
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Continues the encapsulation of coordinate mapping logic by moving
the intermediate logical-to-pixel calculation into CoordinateMapper.
This removes the need for OutputDevice to query the mapper for
individual scaling and DPI components just to do the math itself.
- Added LogicToViewPixelX() and LogicToViewPixelY() to CoordinateMapper
to handle the multiplication of the offset logical coordinate, map
resolution scale, and DPI.
- Simplified OutputDevice::ImplLogic[X|Y]ToDevicePixel() to delegate
directly to these new helpers instead of relying on lcl_logicToPixel.
- Included minor formatting cleanup in LogicToLogic.
Change-Id: Iabf90dd129e3f51102c05e27fe11af1bb6d946a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203647
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Completes the deprecation of legacy coordinate subsystem naming by
renaming GetOutOffYPixel() and SetOutOffYPixel() to
GetDeviceOriginY() and SetDeviceOriginY() across OutputDevice,
Window, and CoordinateMapper.
This unifies axis naming conventions following previous X-axis
refactoring passes, clarifying that these fields represent the
physical origin offsets of the device rendering canvas.
This patch also moves view transformation logic inline from outdev/map
to CoordinateMapper, and wraps sprawling multi-line logic formulas
across mapping routines to clean up formatting boundaries.
Key changes:
* include/vcl/outdev.hxx / window.hxx: Updated public declarations
to replace GetOutOffYPixel with GetDeviceOriginY.
* vcl/inc/CoordinateMapper.hxx: Migrated view transformation cache State
members and mapping calculation methods into the mapper object.
* Global adjustments: Patched all related coordinate offset reads
and tracking writes throughout desktop, editeng, sc, svx, and vcl.
Change-Id: I28fec54a7f3312cc41ada2de38b26351c0a65527
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203646
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Rename GetOutOffXPixel() and SetOutOffXPixel() to GetDeviceOriginX()
and SetDeviceOriginX() across OutputDevice, Window, and CoordinateMapper.
The legacy "OutOff" naming convention obscured the difference between
system-level window positioning offsets and internal content scrolling
(SetPixelOffset). The new nomenclature explicitly communicates that
these metrics strictly govern the device coordinate space origin.
This patch focuses strictly on the X-axis coordinate reads and cleans
up duplicated formatting signatures inside the CoordinateMapper header.
Impacted modules:
* include/vcl: Update public declarations in outdev.hxx and window.hxx.
* vcl/inc: Clean up CoordinateMapper.hxx whitespace and scaling hooks.
* Global: Patch dependent pixel coordinate reads across desktop, editeng,
sc, sfx2, svx, and vcl.
Change-Id: I546e1d255887e3b280ff15caca2e27ef10de52d7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206509
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Refactors the CoordinateMapper::SetLogicalOffset implementation to
match standard const reference placement style (Size const& rOffset)
and positions it lower in the source file to align with structural
member grouping conventions.
Additionally, this patch cleans up long line-wrapping indentation
artifacts inside the polygon processing block of
OutputDevice::PixelToLogic to maintain clean, standardized VCL
formatting guidelines.
Key changes:
* vcl/source/outdev/CoordinateMapper.cxx: Repositioned
SetLogicalOffset and adjusted the parameter signature to match
consistent layout declarations.
* vcl/source/outdev/map.cxx: Re-wrapped aPt calculation blocks in
PixelToLogic to improve localized readability.
Change-Id: I297bc4abc627c6b60b0015fd01fd8e72108ae44c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203644
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Refactor OutputDevice by shifting tracking of coordinate mapping state,
including map mode status, map mode properties, map resolutions, and
pixel/logical offsets, entirely into the CoordinateMapper helper class.
This cleanup unloads redundant member variables from OutputDevice (such
as mbMap, mnOutOffOrigX/Y, mnOutOffLogicX/Y, and maMapRes) and replaces
direct flag manipulation with accessors through mpMapper.
Additionally, this change fixes a latent bug where toggling MapMode
visibility via EnableMapMode() failed to properly invalidate and restore
coordinate transformations. A unit test has been added to guard against
regressions for MapMode invalidation.
Change-Id: Iec61ceb5244d2086215e8a54aa1462eec05882c3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196505
Tested-by: Dan Williams <dcbw@libreoffice.org>
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
OutputDevice doesn't need to be doing coordinate mapping. I am gradually
moving functionality from OutputDevice into CoordinateMapper, leaving
wrapper functions behind.
Change-Id: Iffbf308c99aee7fcab06683437013b7e34ecddde
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196475
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Jenkins
Replaced the anonymous namespace in vcl/source/outdev/map.cxx with
explicit static declarations for translation-unit local functions.
- Renamed getCorrectedUnit() to lcl_getCorrectedUnit() to match the
standard lcl_ prefix convention for local functions.
- Explicitly marked lcl_getCorrectedUnit() and lcl_calcConversionMapRes()
as static.
- Updated all corresponding call sites to reflect the renamed function.
Change-Id: I6a489a50f3f12d2797ecfb4c46dfed8dede70b1b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203269
Tested-by: Jenkins
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Moved the declaration of the sal_uInt16 i loop counter directly into
the for loop initializers across several polygon conversion methods
in vcl/source/outdev/map.cxx. This reduces the scope of the variables
to the loops themselves, cleaning up the code and following modern C++
practices.
Affected functions include:
- ImplLogicToDevicePixel()
- LogicToPixel() (both overloads)
- PixelToLogic() (both overloads)
Change-Id: I5f7f46d786c2e7e34c8277acee689820c5f74305
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196481
Reviewed-by: Julien Nabet <serval2412@yahoo.fr>
Tested-by: Julien Nabet <serval2412@yahoo.fr>
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
Refactored multiple functions in vcl/source/outdev/map.cxx to utilize
early returns. This flattens the code structure, reduces nesting levels,
and improves overall readability without altering the underlying logic.
Affected functions include:
- ImplLogicToDevicePixel()
- SetMapMode()
- GetViewTransformation()
- GetInverseViewTransformation()
- lcl_resolveMapRes()
- lcl_convertLogicValue()
- LogicToLogic() (Point, Size, and B2DHomMatrix overloads)
Added a mapping relative scaling unit test.
Change-Id: I7b0bc6a33cb655080cbf2699e9adc0345b15ca92
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203268
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Renamed the following methods in OutputDevice to remove the "Impl"
prefix, standardizing the naming convention to match the existing
LogicWidthToDevicePixel() method:
- ImplLogicHeightToDevicePixel() -> LogicHeightToDevicePixel()
- ImplLogicHeightToDeviceSubPixel() -> LogicHeightToDeviceSubPixel()
- ImplDevicePixelToLogicWidth() -> DevicePixelToLogicWidth()
- ImplDevicePixelToLogicHeight() -> DevicePixelToLogicHeight()
Updated all corresponding call sites across the vcl module to reflect
the new method names.
Change-Id: I780373600c0ba64e14e1a5ee1389d6733e1ffc69
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203267
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This promotes several coordinate conversion methods from protected/private
Impl functions to public OutputDevice members, as they are widely
used across the VCL codebase (including by Window, VirtualDevice, and
various outdev components).
Changes:
- Renamed and exposed ImplLogicToDevicePixel(Point/Rectangle) as
LogicToDevicePixel().
- Renamed and exposed ImplLogicToDeviceSubPixel(Point) as
LogicToDeviceSubPixel().
- Renamed and exposed ImplLogicWidthToDevicePixel(Long) as
LogicWidthToDevicePixel().
- Renamed and exposed ImplLogicWidthToDeviceSubPixel(Long) as
LogicWidthToDeviceSubPixel().
- Updated all call sites across VCL to use the newly public API.
- Updated TestVirtualDevice in vclmaptest.cxx to reflect the
promoted method names.
Change-Id: I4063d77d76e8889dea06c2aab53d6ec2be3aee8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203262
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
The function ENTER4 in vcl/source/outdev/map.cxx has a name that gives
no indication of its purpose, making the code difficult to read.
This function calculates the map resolutions for a source and destination
MapMode using a standardized 72 DPI, which is necessary for logical unit
conversions.
Rename it to lcl_calcConversionMapRes to clearly reflect its purpose
and improve maintainability.
Change-Id: I2cc265c07c4108a3a3a37356a148ae9ea37a3b9b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196467
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
The ENTER1 macro in vcl/source/outdev/map.cxx hid the logic for
resolving the source and destination MapModes and implicitly handled
early returns. This made the code difficult to follow, debug, and
maintain.
This change replaces the macro with a new static helper function,
lcl_resolveMapRes(), which encapsulates the logic for determining the
effective MapResolution. The fallback logic and early returns are now
handled explicitly at the beginning of each LogicToLogic() overload,
making the control flow much clearer.
Add a unit test.
Change-Id: I1a68f3a168be3f9ea2c4d06354b7091e03964688
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196466
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Renames several file-local static functions in map.cxx to use the
standard 'lcl_' (local) prefix rather than 'Impl' or no prefix.
In VCL, the 'Impl' prefix is generally reserved for private member
functions of a class. Since these are free static helper functions
restricted to this translation unit, updating them to the 'lcl_'
prefix improves readability and aligns with LibreOffice naming
conventions.
Functions renamed:
- ImplCalcMapResolution -> lcl_calcMapResolution
- ImplLogicToPixel -> lcl_logicToPixel
- ImplPixelToLogic -> lcl_pixelToLogic
- ImplPixelToLogicDouble -> lcl_pixelToLogicDouble
- setMapRes -> lcl_setMapRes
Change-Id: I984a7a8da7dd1a2d2c996b4524f9f1def1874dea
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196465
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>