basegfx/source/curve/b2dcubicbezier.cxx                      |   24 +--
 canvas/source/directx/dx_textlayout_drawhelper.cxx           |    4 
 canvas/source/opengl/ogl_canvashelper.cxx                    |    2 
 canvas/source/tools/surface.cxx                              |    9 -
 canvas/source/vcl/canvasfont.cxx                             |    2 
 canvas/source/vcl/canvashelper.cxx                           |    4 
 canvas/source/vcl/canvashelper_texturefill.cxx               |   36 ++---
 canvas/source/vcl/impltools.cxx                              |    8 -
 chart2/source/controller/main/SelectionHelper.cxx            |    2 
 cppcanvas/source/mtfrenderer/transparencygroupaction.cxx     |    4 
 cui/source/dialogs/cuigrfflt.cxx                             |    8 -
 cui/source/tabpages/transfrm.cxx                             |    4 
 drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx |    2 
 drawinglayer/source/primitive2d/textlayoutdevice.cxx         |   67 +++++++---
 drawinglayer/source/processor2d/helperwrongspellrenderer.cxx |    6 
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx   |   16 +-
 drawinglayer/source/processor2d/vclprocessor2d.cxx           |   49 +++++--
 drawinglayer/source/tools/converters.cxx                     |    2 
 drawinglayer/source/tools/emfphelperdata.cxx                 |   34 ++---
 drawinglayer/source/tools/emfphelperdata.hxx                 |   10 +
 editeng/source/editeng/impedit3.cxx                          |    6 
 editeng/source/items/svxfont.cxx                             |    2 
 editeng/source/outliner/outliner.cxx                         |    4 
 emfio/qa/cppunit/emf/EmfImportTest.cxx                       |    4 
 emfio/source/reader/mtftools.cxx                             |    6 
 filter/source/msfilter/escherex.cxx                          |    2 
 filter/source/msfilter/eschesdo.cxx                          |   15 +-
 filter/source/svg/svgfilter.cxx                              |    2 
 filter/source/svg/svgwriter.cxx                              |   24 +--
 hwpfilter/source/drawing.h                                   |    1 
 include/basegfx/numeric/ftools.hxx                           |   20 +--
 include/drawinglayer/primitive2d/textlayoutdevice.hxx        |    2 
 include/svx/svdtrans.hxx                                     |   12 -
 include/svx/transfrmhelper.hxx                               |    8 -
 include/tools/helpers.hxx                                    |    8 -
 include/vcl/bitmap.hxx                                       |    8 +
 include/vcl/outdev.hxx                                       |   16 ++
 include/vcl/vcllayout.hxx                                    |    5 
 sc/qa/uitest/chart/chartLegend.py                            |    4 
 sc/source/core/data/drwlayer.cxx                             |   12 -
 sc/source/ui/miscdlgs/autofmt.cxx                            |    8 -
 sc/source/ui/view/drawview.cxx                               |    4 
 sd/qa/unit/layout-tests.cxx                                  |    4 
 sd/qa/unit/tiledrendering/LOKitSearchTest.cxx                |    6 
 sd/source/core/sdpage.cxx                                    |   16 +-
 sd/source/filter/html/htmlex.cxx                             |    3 
 sd/source/ui/app/optsitem.cxx                                |    4 
 sd/source/ui/dlg/vectdlg.cxx                                 |    6 
 sd/source/ui/func/fuoaprms.cxx                               |    3 
 sd/source/ui/view/drviews8.cxx                               |    4 
 sfx2/source/doc/objcont.cxx                                  |    4 
 slideshow/source/engine/shapes/drawinglayeranimation.cxx     |    6 
 slideshow/source/engine/slideview.cxx                        |    4 
 svgio/qa/cppunit/SvgImportTest.cxx                           |    9 +
 svgio/source/svgreader/svgcharacternode.cxx                  |   18 +-
 svx/qa/unit/customshapes.cxx                                 |   10 -
 svx/source/customshapes/EnhancedCustomShape2d.cxx            |    4 
 svx/source/customshapes/EnhancedCustomShape3d.cxx            |    2 
 svx/source/dialog/_contdlg.cxx                               |    4 
 svx/source/dialog/frmsel.cxx                                 |   12 -
 svx/source/engine3d/obj3d.cxx                                |    2 
 svx/source/engine3d/view3d.cxx                               |    6 
 svx/source/gallery2/galobj.cxx                               |    4 
 svx/source/svdraw/gradtrns.cxx                               |   24 +--
 svx/source/svdraw/sdrpagewindow.cxx                          |    7 -
 svx/source/svdraw/svdcrtv.cxx                                |    4 
 svx/source/svdraw/svddrgmt.cxx                               |   16 +-
 svx/source/svdraw/svddrgv.cxx                                |   16 +-
 svx/source/svdraw/svdedtv1.cxx                               |    4 
 svx/source/svdraw/svdedxv.cxx                                |    8 -
 svx/source/svdraw/svdfmtf.cxx                                |   15 +-
 svx/source/svdraw/svdhdl.cxx                                 |   12 +
 svx/source/svdraw/svdmrkv.cxx                                |   12 -
 svx/source/svdraw/svdoashp.cxx                               |   18 +-
 svx/source/svdraw/svdobj.cxx                                 |    6 
 svx/source/svdraw/svdocapt.cxx                               |    6 
 svx/source/svdraw/svdocirc.cxx                               |   11 +
 svx/source/svdraw/svdoedge.cxx                               |   16 +-
 svx/source/svdraw/svdograf.cxx                               |   18 +-
 svx/source/svdraw/svdomeas.cxx                               |   22 +--
 svx/source/svdraw/svdopath.cxx                               |   37 +++--
 svx/source/svdraw/svdorect.cxx                               |    2 
 svx/source/svdraw/svdotext.cxx                               |   10 -
 svx/source/svdraw/svdotextdecomposition.cxx                  |   12 -
 svx/source/svdraw/svdpdf.cxx                                 |   20 +--
 svx/source/svdraw/svdpoev.cxx                                |    9 -
 svx/source/svdraw/svdtrans.cxx                               |   24 +--
 svx/source/unodraw/UnoGraphicExporter.cxx                    |    8 -
 svx/source/unodraw/unoshape.cxx                              |    8 -
 svx/source/xoutdev/_xpoly.cxx                                |    7 -
 sw/qa/extras/layout/layout.cxx                               |    6 
 sw/qa/extras/ww8export/data/empty_group.docx                 |binary
 sw/qa/extras/ww8export/ww8export4.cxx                        |   24 +++
 sw/source/core/draw/dflyobj.cxx                              |   32 ++--
 sw/source/core/graphic/ndgrf.cxx                             |    3 
 sw/source/core/layout/fly.cxx                                |    2 
 sw/source/core/layout/wsfrm.cxx                              |   28 ++--
 sw/source/ui/table/autoformatpreview.cxx                     |   15 +-
 toolkit/source/awt/vclxfont.cxx                              |    2 
 tools/CppunitTest_tools_test.mk                              |    1 
 tools/qa/cppunit/test_fround.cxx                             |   62 ---------
 tools/source/generic/color.cxx                               |    7 -
 tools/source/generic/line.cxx                                |    7 -
 tools/source/generic/poly.cxx                                |   37 +++--
 vcl/inc/font/LogicalFontInstance.hxx                         |    5 
 vcl/inc/impfontcache.hxx                                     |    8 -
 vcl/inc/impglyphitem.hxx                                     |    6 
 vcl/inc/pdf/pdfbuildin_fonts.hxx                             |    2 
 vcl/inc/qt5/QtFont.hxx                                       |    1 
 vcl/inc/quartz/salgdi.h                                      |    2 
 vcl/inc/unx/freetype_glyphcache.hxx                          |    2 
 vcl/inc/unx/glyphcache.hxx                                   |    1 
 vcl/inc/win/DWriteTextRenderer.hxx                           |   15 --
 vcl/inc/win/winlayout.hxx                                    |    4 
 vcl/osx/salframeview.mm                                      |    3 
 vcl/qa/cppunit/cjktext.cxx                                   |    2 
 vcl/qa/cppunit/complextext.cxx                               |    2 
 vcl/qa/cppunit/fontmocks.hxx                                 |    3 
 vcl/qa/cppunit/logicalfontinstance.cxx                       |   67 ++++++++--
 vcl/qt5/QtFont.cxx                                           |    7 -
 vcl/quartz/ctfonts.cxx                                       |   21 ---
 vcl/skia/gdiimpl.cxx                                         |   17 +-
 vcl/skia/salbmp.cxx                                          |    3 
 vcl/skia/win/gdiimpl.cxx                                     |   33 ++---
 vcl/skia/x11/textrender.cxx                                  |   10 -
 vcl/source/animate/AnimationRenderer.cxx                     |    8 -
 vcl/source/bitmap/BitmapEmbossGreyFilter.cxx                 |    6 
 vcl/source/bitmap/BitmapEx.cxx                               |    2 
 vcl/source/bitmap/BitmapFastScaleFilter.cxx                  |    4 
 vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx           |    4 
 vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx           |    8 -
 vcl/source/bitmap/BitmapScaleSuperFilter.cxx                 |    4 
 vcl/source/bitmap/BitmapTools.cxx                            |   16 +-
 vcl/source/bitmap/bitmap.cxx                                 |   52 ++++----
 vcl/source/bitmap/impvect.cxx                                |    6 
 vcl/source/filter/eps/eps.cxx                                |    4 
 vcl/source/filter/wmf/emfwr.cxx                              |    8 -
 vcl/source/filter/wmf/wmfwr.cxx                              |    6 
 vcl/source/font/LogicalFontInstance.cxx                      |   36 ++++-
 vcl/source/font/fontcache.cxx                                |    4 
 vcl/source/gdi/CommonSalLayout.cxx                           |    6 
 vcl/source/gdi/gdimetafiletools.cxx                          |    8 -
 vcl/source/gdi/gdimtf.cxx                                    |   28 ++--
 vcl/source/gdi/impgraph.cxx                                  |    6 
 vcl/source/gdi/metaact.cxx                                   |   30 ++--
 vcl/source/gdi/pdfbuildin_fonts.cxx                          |    5 
 vcl/source/gdi/pdfwriter_impl.cxx                            |   37 ++++-
 vcl/source/gdi/pdfwriter_impl2.cxx                           |    8 -
 vcl/source/gdi/print.cxx                                     |   10 -
 vcl/source/gdi/regband.cxx                                   |    7 -
 vcl/source/gdi/region.cxx                                    |    4 
 vcl/source/gdi/regionband.cxx                                |    4 
 vcl/source/gdi/sallayout.cxx                                 |   40 ++++--
 vcl/source/gdi/textlayout.cxx                                |    2 
 vcl/source/graphic/GraphicObject.cxx                         |   24 +--
 vcl/source/helper/canvastools.cxx                            |    4 
 vcl/source/outdev/bitmapex.cxx                               |   18 +-
 vcl/source/outdev/font.cxx                                   |    6 
 vcl/source/outdev/hatch.cxx                                  |   19 +-
 vcl/source/outdev/map.cxx                                    |   37 +++++
 vcl/source/outdev/rect.cxx                                   |   16 +-
 vcl/source/outdev/text.cxx                                   |   71 ++++++++---
 vcl/source/outdev/textline.cxx                               |    4 
 vcl/source/outdev/transparent.cxx                            |    2 
 vcl/source/window/printdlg.cxx                               |    4 
 vcl/source/window/window2.cxx                                |    6 
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx               |   38 -----
 vcl/unx/generic/glyphs/glyphcache.cxx                        |    8 -
 vcl/unx/gtk3/gtkinst.cxx                                     |    3 
 vcl/win/gdi/DWriteTextRenderer.cxx                           |   39 ++++--
 vcl/win/gdi/gdiimpl.cxx                                      |    4 
 vcl/win/gdi/salfont.cxx                                      |   53 --------
 vcl/win/gdi/winlayout.cxx                                    |   18 --
 vcl/workben/listglyphs.cxx                                   |    2 
 xmloff/source/draw/shapeexport.cxx                           |   17 +-
 175 files changed, 1134 insertions(+), 1011 deletions(-)

New commits:
commit 76342214ed36a02342dbc43a081fa0e64a0262c4
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Apr 23 05:25:34 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    Fix a thinko in 8a97f1ba8d9ccb65b2c89106de20666311d90c30
    
    Change-Id: I07bb67e9384470269d1fd3df087acee377cce729
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166490
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 31120279a732..a9b78c599042 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -188,7 +188,7 @@ void TextLayouterDevice::setFontAttribute(const 
attribute::FontAttribute& rFontA
     }
     else
     {
-        mnFontScalingFixX = mnFontScalingFixY = 0;
+        mnFontScalingFixX = mnFontScalingFixY = 1.0;
     }
 }
 
commit 44e8c255d6e072e12f3e178b5080ad0f6b87b173
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Mon Apr 22 14:45:37 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    tdf#160773: handle 0-size font height
    
    Regression from commit cc3663bbaed4f65d64154e5f9abb51a5f622f710
    (tdf#160702: improve text positioning, 2024-04-20), where I didn't
    know yet that this was possible :-)
    
    Change-Id: I1316db48b8acbacd077eeb4a8989c3dbf7e4a7b5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166425
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 5bc82301b794..31120279a732 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -179,8 +179,17 @@ void TextLayouterDevice::setFontAttribute(const 
attribute::FontAttribute& rFontA
         = getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, 
fFontScaleY, 0.0, rLocale);
     setFont(aFont);
     Size aFontSize = aFont.GetFontSize();
-    mnFontScalingFixY = fFontScaleY / aFontSize.Height();
-    mnFontScalingFixX = fFontScaleX / (aFontSize.Width() ? aFontSize.Width() : 
aFontSize.Height());
+    if (aFontSize.Height())
+    {
+        mnFontScalingFixY = fFontScaleY / aFontSize.Height();
+        // aFontSize.Width() is 0 for uninformly scaled fonts: see 
getVclFontFromFontAttribute
+        mnFontScalingFixX
+            = fFontScaleX / (aFontSize.Width() ? aFontSize.Width() : 
aFontSize.Height());
+    }
+    else
+    {
+        mnFontScalingFixX = mnFontScalingFixY = 0;
+    }
 }
 
 double TextLayouterDevice::getOverlineOffset() const
commit 6e179e68bcfa6fadd503327699d907966f6fa3d8
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Apr 16 10:48:06 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    tdf#160702: improve text positioning
    
    Opening an SVG with text in different elements (e.g., tspans) in the
    same text element performs calculations to position the parts properly
    (i.e., the next part will start where the previous part ended, unless
    the position in overridden explicitly). These calculations require to
    know the text widths. The first problem leas here: the text width was
    calculated for a typically small text size (numerically equal to the
    pixel size defined in the SVG), but these calculations aren't truly
    linear, because font rendering may change depending on font height.
    Additionally, the rounding gives much higher error in smaller sizes
    than in larger. There was already a workaround for a similar problem
    in ViewRedirector::createRedirectedPrimitive2DSequence, where a large
    font (with 100 times greater height) was used to increase correctness.
    This was also used here, with the same large height (50000) used as a
    reference.
    
    Then, at the time of wrawing the text at different zoom levels, the
    code in VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D
    creates a font of a calculated size, and uses it to output the text.
    But the font is always created with an integral height, which means,
    that for a wanted height of 2.5 (in a zoomed out view), the really
    used height will be 3, which is 20% larger; or for wanted height of
    2.4, the actual height will be 2 (20% smaller). This resulted in odd
    jumps of the text widths, when the text may overlap the following
    part, or conversely, create a big gap before the next gap. To try to
    mitigate that, the function now takes the difference between the
    wanted and the actual font size into account, and adjusts the MapMode
    accordingly. This doesn't fix the jumping completely (e.g., because
    of the mentioned special handling of small font sizes in the fonts
    thenselves, like hinting), but still makes the calculations much more
    stable, decreasing the amount of jumping. Similar changes are made in
    TextLayouterDevice.
    
    Use of the functions that return text size as a double, not rounded
    value, should additionally help improving stability.
    
    Change-Id: I455845d8ca43ee9c06a0fc980947f35d8a25797a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166238
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index e36abffe2e64..5bc82301b794 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -22,6 +22,8 @@
 #include <algorithm>
 
 #include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <drawinglayer/attribute/fontattribute.hxx>
 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
 #include <comphelper/processfactory.hxx>
@@ -162,56 +164,69 @@ TextLayouterDevice::TextLayouterDevice()
 
 TextLayouterDevice::~TextLayouterDevice() COVERITY_NOEXCEPT_FALSE { 
releaseGlobalVirtualDevice(); }
 
-void TextLayouterDevice::setFont(const vcl::Font& rFont) { 
mrDevice.SetFont(rFont); }
+void TextLayouterDevice::setFont(const vcl::Font& rFont)
+{
+    mrDevice.SetFont(rFont);
+    mnFontScalingFixX = 1.0;
+    mnFontScalingFixY = 1.0;
+}
 
 void TextLayouterDevice::setFontAttribute(const attribute::FontAttribute& 
rFontAttribute,
                                           double fFontScaleX, double 
fFontScaleY,
                                           const css::lang::Locale& rLocale)
 {
-    setFont(getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, 
fFontScaleY, 0.0, rLocale));
+    vcl::Font aFont
+        = getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, 
fFontScaleY, 0.0, rLocale);
+    setFont(aFont);
+    Size aFontSize = aFont.GetFontSize();
+    mnFontScalingFixY = fFontScaleY / aFontSize.Height();
+    mnFontScalingFixX = fFontScaleX / (aFontSize.Width() ? aFontSize.Width() : 
aFontSize.Height());
 }
 
 double TextLayouterDevice::getOverlineOffset() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
     double fRet = (rMetric.GetInternalLeading() / 2.0) - rMetric.GetAscent();
-    return fRet;
+    return fRet * mnFontScalingFixY;
 }
 
 double TextLayouterDevice::getUnderlineOffset() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
     double fRet = rMetric.GetDescent() / 2.0;
-    return fRet;
+    return fRet * mnFontScalingFixY;
 }
 
 double TextLayouterDevice::getStrikeoutOffset() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
     double fRet = (rMetric.GetAscent() - rMetric.GetInternalLeading()) / 3.0;
-    return fRet;
+    return fRet * mnFontScalingFixY;
 }
 
 double TextLayouterDevice::getOverlineHeight() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
     double fRet = rMetric.GetInternalLeading() / 2.5;
-    return fRet;
+    return fRet * mnFontScalingFixY;
 }
 
 double TextLayouterDevice::getUnderlineHeight() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
     double fRet = rMetric.GetDescent() / 4.0;
-    return fRet;
+    return fRet * mnFontScalingFixY;
 }
 
-double TextLayouterDevice::getTextHeight() const { return 
mrDevice.GetTextHeight(); }
+double TextLayouterDevice::getTextHeight() const
+{
+    return mrDevice.GetTextHeightDouble() * mnFontScalingFixY;
+}
 
 double TextLayouterDevice::getTextWidth(const OUString& rText, sal_uInt32 
nIndex,
                                         sal_uInt32 nLength) const
 {
-    return mrDevice.GetTextWidth(rText, nIndex, nLength);
+    return mrDevice.GetTextWidthDouble(rText, nIndex, nLength) * 
mnFontScalingFixX;
 }
 
 void TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& 
rB2DPolyPolyVector,
@@ -245,6 +260,13 @@ void 
TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPoly
     {
         mrDevice.GetTextOutlines(rB2DPolyPolyVector, rText, nIndex, nIndex, 
nLength);
     }
+    if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0)
+        || !rtl_math_approxEqual(mnFontScalingFixX, 1.0))
+    {
+        auto scale = 
basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, mnFontScalingFixY);
+        for (auto& poly : rB2DPolyPolyVector)
+            poly.transform(scale);
+    }
 }
 
 basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, 
sal_uInt32 nIndex,
@@ -262,6 +284,12 @@ basegfx::B2DRange 
TextLayouterDevice::getTextBoundRect(const OUString& rText, sa
     {
         basegfx::B2DRange aRect;
         mrDevice.GetTextBoundRect(aRect, rText, nIndex, nIndex, nLength);
+        if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0)
+            || !rtl_math_approxEqual(mnFontScalingFixX, 1.0))
+        {
+            aRect.transform(
+                basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, 
mnFontScalingFixY));
+        }
         return aRect;
     }
 
@@ -271,13 +299,13 @@ basegfx::B2DRange 
TextLayouterDevice::getTextBoundRect(const OUString& rText, sa
 double TextLayouterDevice::getFontAscent() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
-    return rMetric.GetAscent();
+    return rMetric.GetAscent() * mnFontScalingFixY;
 }
 
 double TextLayouterDevice::getFontDescent() const
 {
     const ::FontMetric& rMetric = mrDevice.GetFontMetric();
-    return rMetric.GetDescent();
+    return rMetric.GetDescent() * mnFontScalingFixY;
 }
 
 void TextLayouterDevice::addTextRectActions(const ::tools::Rectangle& 
rRectangle,
@@ -305,7 +333,7 @@ std::vector<double> TextLayouterDevice::getTextArray(const 
OUString& rText, sal_
         mrDevice.GetTextArray(rText, &aArray, nIndex, nTextLength);
         aRetval.reserve(aArray.size());
         for (size_t i = 0, nEnd = aArray.size(); i < nEnd; ++i)
-            aRetval.push_back(aArray[i]);
+            aRetval.push_back(aArray[i] * mnFontScalingFixX);
     }
 
     return aRetval;
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 6a1073fa9d5b..f8e5d0457583 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -180,7 +180,8 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
             }
 
             // Don't draw fonts without height
-            if (aFont.GetFontHeight() <= 0)
+            Size aResultFontSize = aFont.GetFontSize();
+            if (aResultFontSize.Height() <= 0)
                 return;
 
             // set FillColor Attribute
@@ -397,8 +398,31 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
             else
             {
                 const basegfx::B2DPoint aPoint(aLocalTransform * 
basegfx::B2DPoint(0.0, 0.0));
-                aStartPoint = 
Point(basegfx::fround<tools::Long>(aPoint.getX()),
-                                    
basegfx::fround<tools::Long>(aPoint.getY()));
+                double aPointX = aPoint.getX(), aPointY = aPoint.getY();
+
+                // aFont has an integer size; we must scale a bit for precision
+                double nFontScalingFixY = aFontScaling.getY() / 
aResultFontSize.Height();
+                double nFontScalingFixX = aFontScaling.getX()
+                                          / (aResultFontSize.Width() ? 
aResultFontSize.Width()
+                                                                     : 
aResultFontSize.Height());
+
+                if (!rtl_math_approxEqual(nFontScalingFixY, 1.0)
+                    || !rtl_math_approxEqual(nFontScalingFixX, 1.0))
+                {
+                    MapMode aMapMode = mpOutputDevice->GetMapMode();
+                    aMapMode.SetScaleX(aMapMode.GetScaleX() * 
nFontScalingFixX);
+                    aMapMode.SetScaleY(aMapMode.GetScaleY() * 
nFontScalingFixY);
+
+                    mpOutputDevice->Push(vcl::PushFlags::MAPMODE);
+                    mpOutputDevice->SetRelativeMapMode(aMapMode);
+                    bChangeMapMode = true;
+
+                    aPointX /= nFontScalingFixX;
+                    aPointY /= nFontScalingFixY;
+                }
+
+                aStartPoint = Point(basegfx::fround<tools::Long>(aPointX),
+                                    basegfx::fround<tools::Long>(aPointY));
             }
 
             // tdf#152990 set the font after the MapMode is (potentially) set 
so canvas uses the desired
diff --git a/include/drawinglayer/primitive2d/textlayoutdevice.hxx 
b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
index 6348de0ddd25..a2e45f1bd8b5 100644
--- a/include/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -63,6 +63,8 @@ class DRAWINGLAYER_DLLPUBLIC TextLayouterDevice
     /// internally used VirtualDevice
     SolarMutexGuard maSolarGuard;
     VirtualDevice& mrDevice;
+    double mnFontScalingFixX = 1.0;
+    double mnFontScalingFixY = 1.0;
 
 public:
     /// constructor/destructor
diff --git a/svgio/source/svgreader/svgcharacternode.cxx 
b/svgio/source/svgreader/svgcharacternode.cxx
index 4ffc46a483db..d83c8b645202 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -257,9 +257,12 @@ namespace svgio::svgreader
                 // prepare locale
                 css::lang::Locale aLocale;
 
-                // prepare TextLayouterDevice
+                // prepare TextLayouterDevice; use a larger font size for more 
linear size
+                // calculations. Similar to nTextSizeFactor in 
sd/source/ui/view/sdview.cxx
+                // (ViewRedirector::createRedirectedPrimitive2DSequence).
+                const double sizeFactor = fFontHeight < 50000 ? 50000 / 
fFontHeight : 1.0;
                 TextLayouterDevice aTextLayouterDevice;
-                aTextLayouterDevice.setFontAttribute(aFontAttribute, 
fFontWidth, fFontHeight, aLocale);
+                aTextLayouterDevice.setFontAttribute(aFontAttribute, 
fFontWidth * sizeFactor, fFontHeight * sizeFactor, aLocale);
 
                 // prepare TextArray
                 ::std::vector< double > aTextArray(rSvgTextPosition.getX());
@@ -293,7 +296,7 @@ namespace svgio::svgreader
 
                 // get current TextPosition and TextWidth in units
                 basegfx::B2DPoint aPosition(rSvgTextPosition.getPosition());
-                double fTextWidth(aTextLayouterDevice.getTextWidth(getText(), 
nIndex, nLength));
+                double fTextWidth(aTextLayouterDevice.getTextWidth(getText(), 
nIndex, nLength) / sizeFactor);
 
                 // check for user-given TextLength
                 if(0.0 != rSvgTextPosition.getTextLength()
@@ -306,7 +309,10 @@ namespace svgio::svgreader
                         // spacing, need to create and expand TextArray
                         if(aTextArray.empty())
                         {
-                            aTextArray = 
aTextLayouterDevice.getTextArray(getText(), nIndex, nLength);
+                            auto 
aExtendArray(aTextLayouterDevice.getTextArray(getText(), nIndex, nLength));
+                            aTextArray.reserve(aExtendArray.size());
+                            for (auto n : aExtendArray)
+                                aTextArray.push_back(n / sizeFactor);
                         }
 
                         for(auto &a : aTextArray)
@@ -384,12 +390,12 @@ namespace svgio::svgreader
                 {
                     case BaselineShift::Sub:
                     {
-                        aPosition.setY(aPosition.getY() + 
aTextLayouterDevice.getUnderlineOffset());
+                        aPosition.setY(aPosition.getY() + 
aTextLayouterDevice.getUnderlineOffset() / sizeFactor);
                         break;
                     }
                     case BaselineShift::Super:
                     {
-                        aPosition.setY(aPosition.getY() + 
aTextLayouterDevice.getOverlineOffset());
+                        aPosition.setY(aPosition.getY() + 
aTextLayouterDevice.getOverlineOffset() / sizeFactor);
                         break;
                     }
                     case BaselineShift::Percentage:
commit c92e08d54033ffeb010c7460f1c25b31cb4c0f37
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Apr 18 13:18:37 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    Return double from OutputDevice::GetTextArray
    
    And introduce GetTextWidth / GetTextHeight variants returning double.
    It allows to avoid premature rounding.
    
    At least in one case - testTdf145111_anchor_in_Fontwork - it allowed
    to make the test DPI-independent (at least in my testing on Windows,
    using 125, 150, and 175% UI scaling).
    
    Change-Id: I973d2c729ec6bb7114b4f99b9027f1ead7c1d061
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166237
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 13025b27d8a2..6a1073fa9d5b 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -340,8 +340,8 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
             {
                 tools::Long nWidthToFill = rTextCandidate.getWidthToFill();
 
-                tools::Long nWidth
-                    = mpOutputDevice->GetTextArray(rTextCandidate.getText(), 
&aDXArray, 0, 1);
+                tools::Long nWidth = basegfx::fround<tools::Long>(
+                    mpOutputDevice->GetTextArray(rTextCandidate.getText(), 
&aDXArray, 0, 1));
                 sal_Int32 nChars = 2;
                 if (nWidth)
                     nChars = nWidthToFill / nWidth;
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx
index b484a645a7f6..306b378fc133 100644
--- a/editeng/source/items/svxfont.cxx
+++ b/editeng/source/items/svxfont.cxx
@@ -37,7 +37,7 @@ static tools::Long GetTextArray( const OutputDevice* pOut, 
const OUString& rStr,
 
 {
     const SalLayoutGlyphs* layoutGlyphs = 
SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen);
-    return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, true, nullptr, 
layoutGlyphs);
+    return basegfx::fround<tools::Long>(pOut->GetTextArray( rStr, pDXAry, 
nIndex, nLen, true, nullptr, layoutGlyphs));
 }
 
 SvxFont::SvxFont()
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx 
b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 1e03cc15dc20..627423117b37 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -1343,7 +1343,7 @@ void Test::TestExtTextOutOpaqueAndClipWMF()
     assertXPath(pDocument, aXPathPrefix + 
"mask/group[3]/mask/group/polypolygoncolor", "color",
                 "#ff8000");
     assertXPath(pDocument, aXPathPrefix + 
"mask/group[3]/mask/group/polypolygoncolor/polypolygon",
-                "path", "m1067 1067h1270v473h-1270z");
+                "path", "m1067 1067h1317v473h-1317z");
     assertXPath(pDocument, aXPathPrefix + 
"mask/group[3]/mask/group/textsimpleportion", "text",
                 "OOOO");
     assertXPath(pDocument, aXPathPrefix + 
"mask/group[3]/mask/group/textsimpleportion", "fontcolor",
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index ff444a6ce284..aa83250f53b6 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -2690,7 +2690,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, 
const OUString& rText,
     }
     else
     {
-        aNormSize = Size( mpVDev->GetTextArray( rText, &aTmpArray ), 0 );
+        aNormSize = 
Size(basegfx::fround<tools::Long>(mpVDev->GetTextArray(rText, &aTmpArray)), 0);
     }
 
     // if text is rotated, set transform matrix at new g element
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 8bcf883c8fc9..098a5ccc5ef0 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1033,12 +1033,16 @@ public:
     tools::Long                        GetTextWidth( const OUString& rStr, 
sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
                                   vcl::text::TextLayoutCache const* = nullptr,
                                   SalLayoutGlyphs const*const pLayoutCache = 
nullptr) const;
+    double GetTextWidthDouble(const OUString& rStr, sal_Int32 nIndex = 0, 
sal_Int32 nLen = -1,
+                              vcl::text::TextLayoutCache const* = nullptr,
+                              SalLayoutGlyphs const* const pLayoutCache = 
nullptr) const;
 
     /** Height where any character of the current font fits; in logic 
coordinates.
 
         See also GetTextBoundRect() for more explanation + code examples.
     */
     tools::Long                        GetTextHeight() const;
+    double GetTextHeightDouble() const;
     float                       approximate_digit_width() const;
 
     void                        DrawTextArray( const Point& rStartPt, const 
OUString& rStr,
@@ -1048,7 +1052,7 @@ public:
                                                sal_Int32 nLen,
                                                SalLayoutFlags flags = 
SalLayoutFlags::NONE,
                                                const SalLayoutGlyphs* 
pLayoutCache = nullptr);
-    tools::Long                        GetTextArray( const OUString& rStr, 
KernArray* pDXAry,
+    double                      GetTextArray( const OUString& rStr, KernArray* 
pDXAry,
                                               sal_Int32 nIndex = 0, sal_Int32 
nLen = -1, bool bCaret = false,
                                               vcl::text::TextLayoutCache 
const* = nullptr,
                                               SalLayoutGlyphs const*const 
pLayoutCache = nullptr) const;
@@ -1841,6 +1845,9 @@ private:
      */
     SAL_DLLPRIVATE tools::Long         ImplLogicYToDevicePixel( tools::Long nY 
) const;
 
+    SAL_DLLPRIVATE double ImplDevicePixelToLogicWidthDouble(double nWidth) 
const;
+    SAL_DLLPRIVATE double ImplDevicePixelToLogicHeightDouble(double nHeight) 
const;
+
     /** @name Native Widget Rendering functions
 
         These all just call through to the private mpGraphics functions of the 
same name.
diff --git a/sc/qa/uitest/chart/chartLegend.py 
b/sc/qa/uitest/chart/chartLegend.py
index 45938e23017d..fe0525a0746d 100644
--- a/sc/qa/uitest/chart/chartLegend.py
+++ b/sc/qa/uitest/chart/chartLegend.py
@@ -88,7 +88,7 @@ class chartLegend(UITestCase):
       xLegends.executeAction("SELECT", tuple())
 
       with self.ui_test.execute_dialog_through_action(xLegends, "COMMAND", 
mkPropertyValues({"COMMAND": "TransformDialog"})) as xDialog:
-        self.assertEqual("4.61", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value'])
+        self.assertEqual("4.59", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value'])
         self.assertEqual("1.54", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_Y"))['Value'])
 
       xChartMain.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"}))
@@ -96,7 +96,7 @@ class chartLegend(UITestCase):
 
       # Check the position has changed after moving the label using the arrows 
keys
       with self.ui_test.execute_dialog_through_action(xLegends, "COMMAND", 
mkPropertyValues({"COMMAND": "TransformDialog"})) as xDialog:
-        self.assertEqual("4.51", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value'])
+        self.assertEqual("4.49", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value'])
         self.assertEqual("1.44", 
get_state_as_dict(xDialog.getChild("MTR_FLD_POS_Y"))['Value'])
 
    def test_Tdf147394(self):
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index 1c4429f62aec..681f137f4dbb 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -103,7 +103,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf128212)
     xmlDocUniquePtr pXmlDoc = load("pptx/tdf128212.pptx");
 
     // Without the fix in place, this test would have failed with
-    // - Expected: 7793
+    // - Expected: 7795
     // - Actual  : 12068
     assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "x", "4525");
     assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "y", "7797");
@@ -310,7 +310,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, 
testFitToFrameTextFitting)
     assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "y", "406");
     assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", 
"first", "114");
 #ifndef _WIN32 // Windows seems to differ in text layouting, so ignore for now
-    assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", 
"last", "7010");
+    assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", 
"last", "6984");
 #endif
 }
 
diff --git a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx 
b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx
index f3beb12b3ce1..1468f130cf11 100644
--- a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx
+++ b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx
@@ -655,8 +655,7 @@ void LOKitSearchTest::testSearchIn2MixedObjects()
     CPPUNIT_ASSERT_EQUAL(size_t(1), 
mpCallbackRecorder->m_aSearchResultSelection.size());
     CPPUNIT_ASSERT_EQUAL(size_t(1), 
mpCallbackRecorder->m_aSearchResultPart.size());
 
-    CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"),
-                         mpCallbackRecorder->m_aSearchResultSelection[0]);
+    CPPUNIT_ASSERT_EQUAL("3545, 3174, 740, 402", 
mpCallbackRecorder->m_aSearchResultSelection[0]);
 
     // Search next
 
@@ -681,8 +680,7 @@ void LOKitSearchTest::testSearchIn2MixedObjects()
     CPPUNIT_ASSERT_EQUAL(size_t(1), 
mpCallbackRecorder->m_aSearchResultSelection.size());
     CPPUNIT_ASSERT_EQUAL(size_t(1), 
mpCallbackRecorder->m_aSearchResultPart.size());
 
-    CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"),
-                         mpCallbackRecorder->m_aSearchResultSelection[0]);
+    CPPUNIT_ASSERT_EQUAL("3545, 3174, 740, 402", 
mpCallbackRecorder->m_aSearchResultSelection[0]);
 }
 
 // Test searching in document with mixed objects. We have 6 objects.
diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx
index efe322d54e76..86bae7d50447 100644
--- a/svx/qa/unit/customshapes.cxx
+++ b/svx/qa/unit/customshapes.cxx
@@ -406,10 +406,6 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, 
testTdf145111_Fontwork_rendering_font_siz
 
 CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145111_anchor_in_Fontwork)
 {
-    // The tested positions depend on dpi.
-    if (!IsDefaultDPI())
-        return;
-
     // tdf#145004 In case ScaleX is true in property TextPath, 
SDRTEXTVERTADJUST is
     // evaluated and should shift the Fontwork text. That did not work for
     // 'Top-Left' and 'Bottom-Left'.
@@ -423,8 +419,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, 
testTdf145111_anchor_in_Fontwork)
         SdrObjCustomShape& rSdrCustomShape(
             
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape)));
 
-        // Without the fix in place top was 2295, but should be 2916 for 96dpi.
-        // Was 2184, should be 2886 for 120dpi.
+        // Without the fix in place top was 2295, but should be 2900.
         tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
         CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(2916), aBoundRect.Top(), 5);
     }
@@ -434,8 +429,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, 
testTdf145111_anchor_in_Fontwork)
         SdrObjCustomShape& rSdrCustomShape(
             
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape)));
 
-        // Without the fix in place top was 10294, but should be 9519 for 
96dpi.
-        // Was 10184, should be 9481 for 120dpi.
+        // Without the fix in place top was 10294, but should be 9500.
         tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
         CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(9519), aBoundRect.Top(), 5);
     }
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 0ffdb543fbd9..65b31c5909c6 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -3673,7 +3673,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf106234)
                 "type", "PortionType::Margin");
     // This was a justified line, without width
     assertXPath(pXmlDoc, 
"/root/page/body/txt[2]/SwParaPortion/SwLineLayout[1]/SwGluePortion",
-                "width", "7881");
+                "width", "7882");
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287b)
@@ -3686,7 +3686,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287b)
     assertXPath(
         pXmlDoc,
         
"/root/page/body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabRight']",
-        "width", "17");
+        "width", "19");
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287c)
@@ -3819,7 +3819,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf122607)
     assertXPath(pXmlDoc,
                 
"/root/page[1]/anchored/fly/txt[1]/anchored/fly/tab/row[2]/cell/txt[7]/anchored/"
                 "fly/txt/SwParaPortion/SwLineLayout/child::*[1]",
-                "width", "428");
+                "width", "427");
     assertXPath(pXmlDoc,
                 
"/root/page[1]/anchored/fly/txt[1]/anchored/fly/tab/row[2]/cell/txt[7]/anchored/"
                 "fly/txt/SwParaPortion/SwLineLayout/child::*[1]",
diff --git a/toolkit/source/awt/vclxfont.cxx b/toolkit/source/awt/vclxfont.cxx
index 866a362e710f..f7338e79cfd0 100644
--- a/toolkit/source/awt/vclxfont.cxx
+++ b/toolkit/source/awt/vclxfont.cxx
@@ -156,7 +156,7 @@ sal_Int32 VCLXFont::getStringWidthArray( const OUString& 
str, css::uno::Sequence
         vcl::Font aOldFont = pOutDev->GetFont();
         pOutDev->SetFont( maFont );
         KernArray aDXA;
-        nRet = pOutDev->GetTextArray( str, &aDXA );
+        nRet = basegfx::fround(pOutDev->GetTextArray(str, &aDXA));
         rDXArray.realloc(aDXA.size());
         sal_Int32* pArray = rDXArray.getArray();
         for (size_t i = 0, nLen = aDXA.size(); i < nLen; ++i)
diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index daf70a1c589d..cfe5d2213d7d 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -79,7 +79,7 @@ void VclComplexTextTest::testArabic()
     std::vector<sal_Int32> aRefCharWidths {6,  9,  16, 16, 22, 22, 26, 29, 32, 
32,
                                       36, 40, 49, 53, 56, 63, 63, 66, 72, 72};
     KernArray aCharWidths;
-    tools::Long nTextWidth = pOutDev->GetTextArray(aOneTwoThree, &aCharWidths);
+    tools::Long nTextWidth = 
basegfx::fround<tools::Long>(pOutDev->GetTextArray(aOneTwoThree, &aCharWidths));
 
     CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
     // this sporadically returns 75 or 74 on some of the windows tinderboxes 
eg. tb73
diff --git a/vcl/source/filter/wmf/emfwr.cxx b/vcl/source/filter/wmf/emfwr.cxx
index 45a1a7ce4e27..dfdc3156f838 100644
--- a/vcl/source/filter/wmf/emfwr.cxx
+++ b/vcl/source/filter/wmf/emfwr.cxx
@@ -880,7 +880,7 @@ void EMFWriter::ImplWriteTextRecord( const Point& rPos, 
const OUString& rText, K
     }
     else
     {
-        nNormWidth = maVDev->GetTextArray( rText, &aOwnArray );
+        nNormWidth = basegfx::fround<sal_uInt32>(maVDev->GetTextArray(rText, 
&aOwnArray));
         pDX = aOwnArray;
     }
 
diff --git a/vcl/source/filter/wmf/wmfwr.cxx b/vcl/source/filter/wmf/wmfwr.cxx
index 335773728b60..c35d7236c9d9 100644
--- a/vcl/source/filter/wmf/wmfwr.cxx
+++ b/vcl/source/filter/wmf/wmfwr.cxx
@@ -1198,7 +1198,7 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
                 pVirDev->SetFont( aSrcFont );
                 const sal_Int32 nLen = aTemp.getLength();
                 KernArray aDXAry;
-                const sal_Int32 nNormSize = pVirDev->GetTextArray( aTemp, nLen 
? &aDXAry : nullptr );
+                const sal_Int32 nNormSize = 
basegfx::fround(pVirDev->GetTextArray( aTemp, nLen ? &aDXAry : nullptr ));
                 if (nLen && nNormSize == 0)
                 {
                     OSL_FAIL("Impossible div by 0 action: 
MetaStretchTextAction!");
diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx
index 0ee1c9ba5faf..ce681a2e9eea 100644
--- a/vcl/source/gdi/textlayout.cxx
+++ b/vcl/source/gdi/textlayout.cxx
@@ -166,7 +166,7 @@ namespace vcl
             return 0;
 
         // retrieve the character widths from the reference device
-        tools::Long nTextWidth = m_rReferenceDevice.GetTextArray( _rText, 
_pDXAry, _nStartIndex, _nLength );
+        tools::Long nTextWidth = 
basegfx::fround<tools::Long>(m_rReferenceDevice.GetTextArray( _rText, _pDXAry, 
_nStartIndex, _nLength ));
 #if OSL_DEBUG_LEVEL > 1
         if ( _pDXAry )
         {
diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx
index d7ddaf3ccd86..3359cc70c210 100644
--- a/vcl/source/outdev/map.cxx
+++ b/vcl/source/outdev/map.cxx
@@ -272,6 +272,19 @@ static tools::Long ImplPixelToLogic(tools::Long n, 
tools::Long nDPI, tools::Long
     return n;
 }
 
+static double ImplPixelToLogicDouble(double n, tools::Long nDPI, tools::Long 
nMapNum,
+                                     tools::Long nMapDenom)
+{
+    assert(nDPI > 0);
+    if (nMapNum == 0)
+        return 0;
+
+    n *= nMapDenom;
+    n /= nDPI;
+    n /= nMapNum;
+    return n;
+}
+
 tools::Long OutputDevice::ImplLogicXToDevicePixel( tools::Long nX ) const
 {
     if ( !mbMap )
@@ -314,6 +327,14 @@ tools::Long OutputDevice::ImplDevicePixelToLogicWidth( 
tools::Long nWidth ) cons
     return ImplPixelToLogic(nWidth, mnDPIX, maMapRes.mnMapScNumX, 
maMapRes.mnMapScDenomX);
 }
 
+SAL_DLLPRIVATE double OutputDevice::ImplDevicePixelToLogicWidthDouble(double 
nWidth) const
+{
+    if (!mbMap)
+        return nWidth;
+
+    return ImplPixelToLogicDouble(nWidth, mnDPIX, maMapRes.mnMapScNumX, 
maMapRes.mnMapScDenomX);
+}
+
 tools::Long OutputDevice::ImplDevicePixelToLogicHeight( tools::Long nHeight ) 
const
 {
     if ( !mbMap )
@@ -322,6 +343,14 @@ tools::Long OutputDevice::ImplDevicePixelToLogicHeight( 
tools::Long nHeight ) co
     return ImplPixelToLogic(nHeight, mnDPIY, maMapRes.mnMapScNumY, 
maMapRes.mnMapScDenomY);
 }
 
+double OutputDevice::ImplDevicePixelToLogicHeightDouble(double nHeight) const
+{
+    if (!mbMap)
+        return nHeight;
+
+    return ImplPixelToLogicDouble(nHeight, mnDPIY, maMapRes.mnMapScNumY, 
maMapRes.mnMapScDenomY);
+}
+
 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
 {
     if ( !mbMap )
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index bbbb63f2326d..0ff3ac91f177 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -892,11 +892,15 @@ tools::Long OutputDevice::GetTextWidth( const OUString& 
rStr, sal_Int32 nIndex,
      vcl::text::TextLayoutCache const*const pLayoutCache,
      SalLayoutGlyphs const*const pSalLayoutCache) const
 {
+    double nWidth = GetTextWidthDouble(rStr, nIndex, nLen, pLayoutCache, 
pSalLayoutCache);
+    return basegfx::fround<tools::Long>(nWidth);
+}
 
-    tools::Long nWidth = GetTextArray( rStr, nullptr, nIndex,
-            nLen, false, pLayoutCache, pSalLayoutCache );
-
-    return nWidth;
+double OutputDevice::GetTextWidthDouble(const OUString& rStr, sal_Int32 
nIndex, sal_Int32 nLen,
+                                        vcl::text::TextLayoutCache const* 
const pLayoutCache,
+                                        SalLayoutGlyphs const* const 
pSalLayoutCache) const
+{
+    return GetTextArray(rStr, nullptr, nIndex, nLen, false, pLayoutCache, 
pSalLayoutCache);
 }
 
 tools::Long OutputDevice::GetTextHeight() const
@@ -912,6 +916,16 @@ tools::Long OutputDevice::GetTextHeight() const
     return nHeight;
 }
 
+double OutputDevice::GetTextHeightDouble() const
+{
+    if (!InitFont())
+        return 0;
+
+    tools::Long nHeight = mpFontInstance->mnLineHeight + mnEmphasisAscent + 
mnEmphasisDescent;
+
+    return ImplDevicePixelToLogicHeightDouble(nHeight);
+}
+
 float OutputDevice::approximate_char_width() const
 {
     //note pango uses "The quick brown fox jumps over the lazy dog." for 
english
@@ -960,7 +974,7 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, 
const OUString& rStr,
         mpAlphaVDev->DrawTextArray( rStartPt, rStr, pDXAry, pKashidaAry, 
nIndex, nLen, flags );
 }
 
-tools::Long OutputDevice::GetTextArray( const OUString& rStr, KernArray* 
pKernArray,
+double OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernArray,
                                  sal_Int32 nIndex, sal_Int32 nLen, bool bCaret,
                                  vcl::text::TextLayoutCache const*const 
pLayoutCache,
                                  SalLayoutGlyphs const*const pSalLayoutCache) 
const
@@ -1048,7 +1062,7 @@ tools::Long OutputDevice::GetTextArray( const OUString& 
rStr, KernArray* pKernAr
         if (mbMap)
         {
             for (int i = 0; i < nLen; ++i)
-                (*pDXAry)[i] = ImplDevicePixelToLogicWidth( (*pDXAry)[i] * 
nSubPixelFactor );
+                (*pDXAry)[i] = ImplDevicePixelToLogicWidthDouble((*pDXAry)[i] 
* nSubPixelFactor);
         }
         else if (nSubPixelFactor)
         {
@@ -1057,10 +1071,7 @@ tools::Long OutputDevice::GetTextArray( const OUString& 
rStr, KernArray* pKernAr
         }
     }
 
-    if (mbMap)
-        nWidth = ImplDevicePixelToLogicWidth( nWidth );
-
-    return basegfx::fround<tools::Long>(nWidth);
+    return ImplDevicePixelToLogicWidthDouble(nWidth);
 #endif /* VCL_FLOAT_DEVICE_PIXEL */
 }
 
commit 9059240ea11f8c16c3fb9d40a85650d187ad19db
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Apr 10 12:15:55 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    tdf#160622: Let SalLayout::GetBoundRect return basegfx::B2DRectangle
    
    This avoids premature rounding in TextLayouterDevice::getTextBoundRect.
    The box in D2DWriteTextOutRenderer::performRender needs to be expanded
    to allow room for the line width (which now will be guaranteed on all
    sides; previously, the rounding could happen to give no room on some
    side, even prior to commit 8962141a12c966b2d891829925e6203bf8d51852).
    Fixes some lines partially cut off in smaller text (or zoomed out).
    
    Change-Id: I07335136021f894cf045363b4d736bfab06c64d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166236
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index ea9fed02a20f..e36abffe2e64 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -260,15 +260,9 @@ basegfx::B2DRange 
TextLayouterDevice::getTextBoundRect(const OUString& rText, sa
 
     if (nTextLength)
     {
-        ::tools::Rectangle aRect;
-
+        basegfx::B2DRange aRect;
         mrDevice.GetTextBoundRect(aRect, rText, nIndex, nIndex, nLength);
-
-        // #i104432#, #i102556# take empty results into account
-        if (!aRect.IsEmpty())
-        {
-            return vcl::unotools::b2DRectangleFromRectangle(aRect);
-        }
+        return aRect;
     }
 
     return basegfx::B2DRange();
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 6b864213a66d..8bcf883c8fc9 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -54,6 +54,7 @@
 #include <vcl/settings.hxx>
 #include <vcl/vclreferencebase.hxx>
 
+#include <basegfx/range/b2drectangle.hxx>
 #include <basegfx/numeric/ftools.hxx>
 #include <basegfx/vector/b2enums.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
@@ -960,6 +961,11 @@ public:
                                                   sal_uLong nLayoutWidth = 0, 
KernArraySpan aDXArray = KernArraySpan(),
                                                   o3tl::span<const sal_Bool> 
pKashidaArray = {},
                                                   const SalLayoutGlyphs* 
pGlyphs = nullptr ) const;
+    bool                        GetTextBoundRect( basegfx::B2DRectangle& rRect,
+                                                  const OUString& rStr, 
sal_Int32 nBase = 0, sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
+                                                  sal_uLong nLayoutWidth = 0, 
KernArraySpan aDXArray = KernArraySpan(),
+                                                  o3tl::span<const sal_Bool> 
pKashidaArray = {},
+                                                  const SalLayoutGlyphs* 
pGlyphs = nullptr ) const;
 
     tools::Rectangle            ImplGetTextBoundRect( const SalLayout& ) const;
 
@@ -1627,6 +1633,7 @@ public:
     SAL_WARN_UNUSED_RESULT tools::Polygon PixelToLogic(const tools::Polygon& 
rDevicePoly) const;
     SAL_WARN_UNUSED_RESULT tools::PolyPolygon PixelToLogic(const 
tools::PolyPolygon& rDevicePolyPoly) const;
     SAL_WARN_UNUSED_RESULT basegfx::B2DPolyPolygon PixelToLogic(const 
basegfx::B2DPolyPolygon& rDevicePolyPoly) const;
+    SAL_WARN_UNUSED_RESULT basegfx::B2DRectangle PixelToLogic(const 
basegfx::B2DRectangle& rDeviceRect) const;
     SAL_WARN_UNUSED_RESULT vcl::Region PixelToLogic(const vcl::Region& 
rDeviceRegion) const;
     SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point& rDevicePt, const 
MapMode& rMapMode) const;
     SAL_WARN_UNUSED_RESULT Size PixelToLogic(const Size& rDeviceSize, const 
MapMode& rMapMode) const;
diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx
index 4705a44d9b92..887480ce3ee9 100644
--- a/include/vcl/vcllayout.hxx
+++ b/include/vcl/vcllayout.hxx
@@ -20,6 +20,7 @@
 #pragma once
 
 #include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/range/b2drectangle.hxx>
 #include <i18nlangtag/languagetag.hxx>
 #include <tools/gen.hxx>
 #include <tools/degree.hxx>
@@ -103,7 +104,9 @@ public:
     virtual bool    GetNextGlyph(const GlyphItem** pGlyph, DevicePoint& rPos, 
int& nStart,
                                  const LogicalFontInstance** ppGlyphFont = 
nullptr) const = 0;
     virtual bool GetOutline(basegfx::B2DPolyPolygonVector&) const;
-    bool GetBoundRect(tools::Rectangle&) const;
+    bool GetBoundRect(basegfx::B2DRectangle&) const;
+
+    static tools::Rectangle BoundRect2Rectangle(basegfx::B2DRectangle&);
 
     virtual SalLayoutGlyphs GetGlyphs() const;
 
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx 
b/svgio/qa/cppunit/SvgImportTest.cxx
index d61c5c761f79..7a8706556129 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -41,6 +41,8 @@ protected:
     void checkRectPrimitive(Primitive2DSequence const & rPrimitive);
 
     Primitive2DSequence parseSvg(std::u16string_view aSource);
+    void assertXPathDouble(const xmlDocUniquePtr& pXmlDoc, const OString& 
rXPath,
+                           const OString& rAttribute, double nExpectedValue, 
double delta);
 };
 
 Primitive2DSequence Test::parseSvg(std::u16string_view aSource)
@@ -82,6 +84,13 @@ void Test::checkRectPrimitive(Primitive2DSequence const & 
rPrimitive)
 
 }
 
+void Test::assertXPathDouble(const xmlDocUniquePtr& pXmlDoc, const OString& 
rXPath,
+                             const OString& rAttribute, double nExpectedValue, 
double delta)
+{
+    auto sVal = getXPath(pXmlDoc, rXPath, rAttribute);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(nExpectedValue, sVal.toDouble(), delta);
+}
+
 bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const 
Primitive2DSequence& rB)
 {
     return std::equal(rA.begin(), rA.end(), rB.begin(), rB.end(),
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 84b625115648..c40a010173a7 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -2131,7 +2131,7 @@ void SkiaSalGraphicsImpl::drawGenericLayout(const 
GenericSalLayout& layout, Colo
 
     preDraw();
     auto getBoundRect = [&layout]() {
-        tools::Rectangle rect;
+        basegfx::B2DRectangle rect;
         layout.GetBoundRect(rect);
         return rect;
     };
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index c8c2d6ca1093..e801ac3057ca 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -221,11 +221,10 @@ static double trimInsignificant(double n)
     return std::abs(n) >= 0x1p53 ? n : std::round(n * 1e5) / 1e5;
 }
 
-bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const
+bool SalLayout::GetBoundRect(basegfx::B2DRectangle& rRect) const
 {
     bool bRet = false;
-
-    basegfx::B2DRectangle aUnion;
+    rRect.reset();
     basegfx::B2DRectangle aRectangle;
 
     DevicePoint aPos;
@@ -241,28 +240,28 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) 
const
             {
                 
aRectangle.transform(basegfx::utils::createTranslateB2DHomMatrix(aPos));
                 // merge rectangle
-                aUnion.expand(aRectangle);
+                rRect.expand(aRectangle);
             }
             bRet = true;
         }
     }
-    if (aUnion.isEmpty())
-    {
-        rRect = {};
-    }
-    else
-    {
-        double l = rtl::math::approxFloor(trimInsignificant(aUnion.getMinX())),
-               t = rtl::math::approxFloor(trimInsignificant(aUnion.getMinY())),
-               r = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxX())),
-               b = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxY()));
-        assert(std::isfinite(l) && std::isfinite(t) && std::isfinite(r) && 
std::isfinite(b));
-        rRect = tools::Rectangle(l, t, r, b);
-    }
 
     return bRet;
 }
 
+tools::Rectangle SalLayout::BoundRect2Rectangle(basegfx::B2DRectangle& rRect)
+{
+    if (rRect.isEmpty())
+        return {};
+
+    double l = rtl::math::approxFloor(trimInsignificant(rRect.getMinX())),
+           t = rtl::math::approxFloor(trimInsignificant(rRect.getMinY())),
+           r = rtl::math::approxCeil(trimInsignificant(rRect.getMaxX())),
+           b = rtl::math::approxCeil(trimInsignificant(rRect.getMaxY()));
+    assert(std::isfinite(l) && std::isfinite(t) && std::isfinite(r) && 
std::isfinite(b));
+    return tools::Rectangle(l, t, r, b);
+}
+
 SalLayoutGlyphs SalLayout::GetGlyphs() const
 {
     return SalLayoutGlyphs(); // invalid
diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx
index 67414cb2976c..d7ddaf3ccd86 100644
--- a/vcl/source/outdev/map.cxx
+++ b/vcl/source/outdev/map.cxx
@@ -1230,6 +1230,14 @@ basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( 
const basegfx::B2DPolyPolygo
     return aTransformedPoly;
 }
 
+basegfx::B2DRectangle OutputDevice::PixelToLogic(const basegfx::B2DRectangle& 
rDeviceRect) const
+{
+    basegfx::B2DRectangle aTransformedRect = rDeviceRect;
+    const basegfx::B2DHomMatrix& rTransformationMatrix = 
GetInverseViewTransformation();
+    aTransformedRect.transform(rTransformationMatrix);
+    return aTransformedRect;
+}
+
 vcl::Region OutputDevice::PixelToLogic( const vcl::Region& rDeviceRegion ) 
const
 {
 
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 9e93a5775857..bbbb63f2326d 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -23,6 +23,7 @@
 #include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
 #include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <comphelper/processfactory.hxx>
 #include <tools/lineend.hxx>
 #include <tools/debug.hxx>
@@ -233,7 +234,11 @@ bool OutputDevice::ImplDrawRotateText( SalLayout& 
rSalLayout )
     tools::Rectangle aBoundRect;
     rSalLayout.DrawBase() = DevicePoint( 0, 0 );
     rSalLayout.DrawOffset() = Point( 0, 0 );
-    if (!rSalLayout.GetBoundRect(aBoundRect))
+    if (basegfx::B2DRectangle r; rSalLayout.GetBoundRect(r))
+    {
+        aBoundRect = SalLayout::BoundRect2Rectangle(r);
+    }
+    else
     {
         // guess vertical text extents if GetBoundRect failed
         tools::Long nRight = rSalLayout.GetTextWidth();
@@ -2326,9 +2331,22 @@ bool OutputDevice::GetTextBoundRect( tools::Rectangle& 
rRect,
                                          sal_uLong nLayoutWidth, KernArraySpan 
pDXAry,
                                          o3tl::span<const sal_Bool> 
pKashidaAry,
                                          const SalLayoutGlyphs* pGlyphs ) const
+{
+    basegfx::B2DRectangle aRect;
+    bool bRet = GetTextBoundRect(aRect, rStr, nBase, nIndex, nLen, 
nLayoutWidth, pDXAry,
+                                 pKashidaAry, pGlyphs);
+    rRect = SalLayout::BoundRect2Rectangle(aRect);
+    return bRet;
+}
+
+bool OutputDevice::GetTextBoundRect(basegfx::B2DRectangle& rRect, const 
OUString& rStr,
+                                    sal_Int32 nBase, sal_Int32 nIndex, 
sal_Int32 nLen,
+                                    sal_uLong nLayoutWidth, KernArraySpan 
pDXAry,
+                                    o3tl::span<const sal_Bool> pKashidaAry,
+                                    const SalLayoutGlyphs* pGlyphs) const
 {
     bool bRet = false;
-    rRect.SetEmpty();
+    rRect.reset();
 
     std::unique_ptr<SalLayout> pSalLayout;
     const Point aPoint;
@@ -2352,18 +2370,22 @@ bool OutputDevice::GetTextBoundRect( tools::Rectangle& 
rRect,
                             nullptr, pGlyphs);
     if( pSalLayout )
     {
-        tools::Rectangle aPixelRect;
+        basegfx::B2DRectangle aPixelRect;
         bRet = pSalLayout->GetBoundRect(aPixelRect);
 
         if( bRet )
         {
-            Point aRotatedOfs( mnTextOffX, mnTextOffY );
-            DevicePoint aPos = 
pSalLayout->GetDrawPosition(DevicePoint(nXOffset, 0));
-            aRotatedOfs -= Point(aPos.getX(), aPos.getY());
-            aPixelRect += aRotatedOfs;
+            basegfx::B2DPoint aPos = 
pSalLayout->GetDrawPosition(basegfx::B2DPoint(nXOffset, 0));
+            auto m = basegfx::utils::createTranslateB2DHomMatrix(mnTextOffX - 
aPos.getX(),
+                                                                 mnTextOffY - 
aPos.getY());
+            aPixelRect.transform(m);
             rRect = PixelToLogic( aPixelRect );
-            if( mbMap )
-                rRect += Point( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
+            if (mbMap)
+            {
+                m = 
basegfx::utils::createTranslateB2DHomMatrix(maMapRes.mnMapOfsX,
+                                                                
maMapRes.mnMapOfsY);
+                rRect.transform(m);
+            }
         }
     }
 
diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx 
b/vcl/win/gdi/DWriteTextRenderer.cxx
index 321587db8137..fb96cfa68659 100644
--- a/vcl/win/gdi/DWriteTextRenderer.cxx
+++ b/vcl/win/gdi/DWriteTextRenderer.cxx
@@ -238,8 +238,15 @@ bool 
D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
     if (!pFontFace)
         return false;
 
-    tools::Rectangle bounds;
-    bool succeeded = rLayout.GetBoundRect(bounds);
+    auto [succeeded, bounds] = [&rLayout]()
+    {
+        basegfx::B2DRectangle r;
+        bool result = rLayout.GetBoundRect(r);
+        if (result)
+            r.grow(1); // plus 1 pixel to the tight range
+        return std::make_pair(result, SalLayout::BoundRect2Rectangle(r));
+    }();
+
     if (succeeded)
     {
         hr = BindDC(hDC, bounds);   // Update the bounding rect.
commit ddd6d8bd2ed2b37492d7660df1769618cea17105
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Apr 19 10:31:39 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    Add a unit test for commit 3f0220f18a66630e06e3c128980f21a5722f49ca
    
    (Handle empty range properly, 2024-04-18)
    
    Change-Id: Ifea60ace8ff864ef092e6a62177d5926ceb60de3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166278
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/ww8export/data/empty_group.docx 
b/sw/qa/extras/ww8export/data/empty_group.docx
new file mode 100644
index 000000000000..a3454746c5e0
Binary files /dev/null and b/sw/qa/extras/ww8export/data/empty_group.docx differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx 
b/sw/qa/extras/ww8export/ww8export4.cxx
index efb198ebae00..b4116ff2bbac 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -19,8 +19,11 @@
 
 #include <comphelper/sequenceashashmap.hxx>
 #include <o3tl/string_view.hxx>
+#include <svx/svdpage.hxx>
 
 #include <docsh.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentDrawModelAccess.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <unotxdoc.hxx>
 
@@ -78,6 +81,27 @@ DECLARE_WW8EXPORT_TEST(testTdf104704_mangledFooter, 
"tdf104704_mangledFooter.odt
     CPPUNIT_ASSERT_EQUAL(2, getPages());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testEmptyGroup)
+{
+    // Given a document with an empty group
+    createSwDoc("empty_group.docx");
+
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    CPPUNIT_ASSERT_EQUAL(1, getShapes());
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+    SdrPage* pPage = 
pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
+    SdrObject* pObject = pPage->GetObj(0);
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Empty group"), pObject->GetName());
+    CPPUNIT_ASSERT(pObject->IsGroupObject());
+    CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetSubList()->GetObjCount());
+
+    // it must not assert/crash on save
+    saveAndReload(OUString::createFromAscii(mpFilter));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit b2509d82c0b63d001f0f7a946e0d4c926158f6e2
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Apr 17 21:16:23 2024 +0100
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:52 2024 +0500

    Handle empty range properly
    
    Since commit 690526f95e3ee4fd25bb2c987e093543e4bc435b
    (Generalize basegfx::fround for templated return type, 2024-04-14),
    an assertion could fail for certain case, like
    
    include/o3tl/unit_conversion.hxx:75: sal_Int64 o3tl::detail::MulDiv(I,
    sal_Int64, sal_Int64) [I = long]: Assertion `isBetween(n,
    (SAL_MIN_INT64 + d / 2) / m, (SAL_MAX_INT64 - d / 2) / m)'
    
    The problem was unchecked case of empty B2DRange.
    
    Change-Id: Ice9125ea557b73a7fabf64bc1ad9368f503ad525
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166101
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/filter/source/msfilter/eschesdo.cxx 
b/filter/source/msfilter/eschesdo.cxx
index ca0dc8a4a14d..2f8f84bb9dc4 100644
--- a/filter/source/msfilter/eschesdo.cxx
+++ b/filter/source/msfilter/eschesdo.cxx
@@ -1151,10 +1151,19 @@ void ImplEESdrObject::Init()
     {
         // if it's a group, the unrotated range is needed for that group
         const basegfx::B2DRange 
aUnrotatedRange(getUnrotatedGroupBoundRange(mXShape));
-        const Point 
aNewP(basegfx::fround<tools::Long>(aUnrotatedRange.getMinX()), 
basegfx::fround<tools::Long>(aUnrotatedRange.getMinY()));
-        const Size 
aNewS(basegfx::fround<tools::Long>(aUnrotatedRange.getWidth()), 
basegfx::fround<tools::Long>(aUnrotatedRange.getHeight()));
+        if (aUnrotatedRange.isEmpty())
+        {
+            SetRect(tools::Rectangle());
+        }
+        else
+        {
+            const Point 
aNewP(basegfx::fround<tools::Long>(aUnrotatedRange.getMinX()),
+                              
basegfx::fround<tools::Long>(aUnrotatedRange.getMinY()));
+            const Size 
aNewS(basegfx::fround<tools::Long>(aUnrotatedRange.getWidth()),
+                             
basegfx::fround<tools::Long>(aUnrotatedRange.getHeight()));
 
-        SetRect(ImplEESdrWriter::ImplMapPoint(aNewP), 
ImplEESdrWriter::ImplMapSize(aNewS));
+            SetRect(ImplEESdrWriter::ImplMapPoint(aNewP), 
ImplEESdrWriter::ImplMapSize(aNewS));
+        }
     }
     else
     {
commit 02f22e016e0e7bda4c2f3c910ce3026e6672a117
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Apr 16 23:10:45 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Apr 29 10:02:51 2024 +0500

    Drop FRound, and use generalized basegfx::fround
    
    Change-Id: I7447e649dc3ef4e51242f69c7486a3e84e103d2e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166159
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx
index c67ee92d141c..0ffb50342936 100644
--- a/cui/source/dialogs/cuigrfflt.cxx
+++ b/cui/source/dialogs/cuigrfflt.cxx
@@ -192,8 +192,8 @@ Graphic GraphicFilterMosaic::GetFilteredGraphic( const 
Graphic& rGraphic,
     Graphic         aRet;
     tools::Long            nTileWidth = 
static_cast<tools::Long>(mxMtrWidth->get_value(FieldUnit::PIXEL));
     tools::Long            nTileHeight = 
static_cast<tools::Long>(mxMtrHeight->get_value(FieldUnit::PIXEL));
-    const Size      aSize( std::max( FRound( nTileWidth * fScaleX ), 
tools::Long(1) ),
-                           std::max( FRound( nTileHeight * fScaleY ), 
tools::Long(1) ) );
+    const Size      aSize( std::max( basegfx::fround<tools::Long>( nTileWidth 
* fScaleX ), tools::Long(1) ),
+                           std::max( basegfx::fround<tools::Long>( nTileHeight 
* fScaleY ), tools::Long(1) ) );
 
     if( rGraphic.IsAnimated() )
     {
@@ -270,7 +270,7 @@ GraphicFilterSolarize::GraphicFilterSolarize(weld::Window* 
pParent, const Graphi
     , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", 
FieldUnit::PERCENT))
     , mxCbxInvert(m_xBuilder->weld_check_button("invert"))
 {
-    mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), 
FieldUnit::PERCENT);
+    mxMtrThreshold->set_value(basegfx::fround(cGreyThreshold / 2.55), 
FieldUnit::PERCENT);
     mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, 
EditModifyHdl));
 
     mxCbxInvert->set_active(bInvert);
@@ -290,7 +290,7 @@ IMPL_LINK_NOARG(GraphicFilterSolarize, EditModifyHdl, 
weld::MetricSpinButton&, v
 Graphic GraphicFilterSolarize::GetFilteredGraphic( const Graphic& rGraphic, 
double, double )
 {
     Graphic         aRet;
-    sal_uInt8       nGreyThreshold = 
static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 
2.55));
+    sal_uInt8       nGreyThreshold = 
basegfx::fround<sal_uInt8>(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 
2.55);
 
     if( rGraphic.IsAnimated() )
     {
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index e4420dc27e71..ff444a6ce284 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -2184,7 +2184,7 @@ void SVGActionWriter::ImplWriteShape( const 
SVGShapeDescriptor& rShape )
 
         for( size_t k = 0; k < rShape.maDashArray.size(); ++k )
         {
-            const sal_Int32 nDash = ImplMap( FRound( rShape.maDashArray[ k ] ) 
);
+            const sal_Int32 nDash = 
ImplMap(basegfx::fround(rShape.maDashArray[k]));
 
             if( k )
                 aDashArrayStr.append(",");
@@ -2546,8 +2546,8 @@ void SVGActionWriter::ImplWriteMask(GDIMetaFile& rMtf, 
const Point& rDestPt, con
     if (fScaleX != 1.0 || fScaleY != 1.0)
     {
         rMtf.Scale(fScaleX, fScaleY);
-        aSrcPt.setX(FRound(aSrcPt.X() * fScaleX));
-        aSrcPt.setY(FRound(aSrcPt.Y() * fScaleY));
+        aSrcPt.setX(basegfx::fround<tools::Long>(aSrcPt.X() * fScaleX));
+        aSrcPt.setY(basegfx::fround<tools::Long>(aSrcPt.Y() * fScaleY));
     }
 
     nMoveX = rDestPt.X() - aSrcPt.X();
@@ -2747,7 +2747,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, 
const OUString& rText,
                 const double fFactor = static_cast<double>(nWidth) / 
aNormSize.Width();
 
                 for( i = 0; i < ( nLen - 1 ); i++ )
-                    aTmpArray.set(i, FRound(aTmpArray[i] * fFactor));
+                    aTmpArray.set(i, basegfx::fround(aTmpArray[i] * fFactor));
             }
             else
             {
@@ -2811,11 +2811,11 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, 
const OUString& rText,
         return;
 
     tools::Polygon aPoly( 4 );
-    const tools::Long  nLineHeight = std::max<tools::Long>( FRound( 
aMetric.GetLineHeight() * 0.05 ), 1 );
+    const tools::Long  nLineHeight = std::max<tools::Long>( 
basegfx::fround<tools::Long>( aMetric.GetLineHeight() * 0.05 ), 1 );
 
     if( rFont.GetStrikeout() )
     {
-        const tools::Long nYLinePos = aBaseLinePos.Y() - FRound( 
aMetric.GetAscent() * 0.26 );
+        const tools::Long nYLinePos = aBaseLinePos.Y() - 
basegfx::fround<tools::Long>( aMetric.GetAscent() * 0.26 );
 
         aPoly[ 0 ].setX( aBaseLinePos.X() ); aPoly[ 0 ].setY( nYLinePos - ( 
nLineHeight >> 1 ) );
         aPoly[ 1 ].setX( aBaseLinePos.X() + aNormSize.Width() - 1 ); aPoly[ 1 
].setY( aPoly[ 0 ].Y() );
@@ -3323,8 +3323,8 @@ void SVGActionWriter::ImplWriteActions( const 
GDIMetaFile& rMtf,
                         // i.e. invisible line, because it makes it visible,
                         // resulting an extra line behind the normal shape line
                         if ( aNewLineColor.GetAlpha() > 0 )
-                            aNewLineColor.SetAlpha( 255 - 
sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) );
-                        aNewFillColor.SetAlpha( 255 - 
sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) );
+                            aNewLineColor.SetAlpha( 255 - 
basegfx::fround<sal_uInt8>( pA->GetTransparence() * 2.55 ) );
+                        aNewFillColor.SetAlpha( 255 - 
basegfx::fround<sal_uInt8>( pA->GetTransparence() * 2.55 ) );
 
                         maAttributeWriter.AddPaintAttr( aNewLineColor, 
aNewFillColor );
                         ImplWritePolyPolygon( rPolyPoly, false );
@@ -3435,7 +3435,7 @@ void SVGActionWriter::ImplWriteActions( const 
GDIMetaFile& rMtf,
 
                             mapCurShape->maShapePolyPoly = aShapePolyPoly;
                             mapCurShape->maShapeFillColor = 
aFill.getFillColor();
-                            mapCurShape->maShapeFillColor.SetAlpha( 255 - 
static_cast<sal_uInt8>(FRound( 255.0 * aFill.getTransparency() )) );
+                            mapCurShape->maShapeFillColor.SetAlpha( 255 - 
basegfx::fround<sal_uInt8>( 255.0 * aFill.getTransparency() ) );
 
                             if( bGradient )
                             {
@@ -3525,8 +3525,8 @@ void SVGActionWriter::ImplWriteActions( const 
GDIMetaFile& rMtf,
                     }
 
                     mapCurShape->maShapeLineColor = mpVDev->GetLineColor();
-                    mapCurShape->maShapeLineColor.SetAlpha( 255 - 
static_cast<sal_uInt8>(FRound( aStroke.getTransparency() * 255.0 )) );
-                    mapCurShape->mnStrokeWidth = FRound( 
aStroke.getStrokeWidth() );
+                    mapCurShape->maShapeLineColor.SetAlpha( 255 - 
basegfx::fround<sal_uInt8>( aStroke.getTransparency() * 255.0 ) );
+                    mapCurShape->mnStrokeWidth = 
basegfx::fround(aStroke.getStrokeWidth());
                     aStroke.getDashArray( mapCurShape->maDashArray );
 
                     // added support for LineJoin
diff --git a/include/basegfx/numeric/ftools.hxx 
b/include/basegfx/numeric/ftools.hxx
index 28efe2770b74..b286c847968c 100644
--- a/include/basegfx/numeric/ftools.hxx
+++ b/include/basegfx/numeric/ftools.hxx
@@ -35,41 +35,25 @@ namespace basegfx
 
         @return the nearest integer
     */
-    inline sal_Int32 fround32( double fVal )
+    template <class Int = sal_Int32>
+    inline std::enable_if_t<std::is_integral_v<Int>, Int> fround(double fVal)
     {
         if (fVal >= 0.0)
         {
-            if (fVal >= std::numeric_limits<sal_Int32>::max() - .5)
-                return std::numeric_limits<sal_Int32>::max();
-            return static_cast<sal_Int32>(fVal + .5);
+            if (fVal >= static_cast<double>(std::numeric_limits<Int>::max()) - 
0.5)
+                return std::numeric_limits<Int>::max();
+            return static_cast<Int>(fVal + .5);
         }
-        if (fVal <= std::numeric_limits<sal_Int32>::min() + .5)
-            return std::numeric_limits<sal_Int32>::min();
-        return static_cast<sal_Int32>(fVal - .5);
+        if (fVal <= static_cast<double>(std::numeric_limits<Int>::min()) + 0.5)
+            return std::numeric_limits<Int>::min();
+        return static_cast<Int>(fVal - .5);
     }
 
     /** Round double to nearest integer
 
         @return the nearest 64 bit integer
     */
-    inline sal_Int64 fround64( double fVal )
-    {
-        return fVal > 0.0 ? static_cast<sal_Int64>( fVal + .5 ) : 
-static_cast<sal_Int64>( -fVal + .5 );
-    }
-
-    /** Round double to nearest integer
-
-        @return the nearest integer
-    */
-    template <class Int = sal_Int32>
-    inline std::enable_if_t<std::is_integral_v<Int> && std::is_signed_v<Int>, 
Int>
-    fround(double fVal)
-    {
-        if constexpr (sizeof(Int) == sizeof(sal_Int64))
-            return fround64(fVal);
-        else
-            return fround32(fVal);
-    }
+    inline sal_Int64 fround64(double fVal) { return fround<sal_Int64>(fVal); }
 
     /** Prune a small epsilon range around zero.
 
diff --git a/include/svx/svdtrans.hxx b/include/svx/svdtrans.hxx
index 0087f5407f81..88bbfc6fa1ed 100644
--- a/include/svx/svdtrans.hxx
+++ b/include/svx/svdtrans.hxx
@@ -94,27 +94,27 @@ inline void ResizePoint(Point& rPnt, const Point& rRef, 
const Fraction& xFract,
 {
     double nxFract = xFract.IsValid() ? static_cast<double>(xFract) : 1.0;
     double nyFract = yFract.IsValid() ? static_cast<double>(yFract) : 1.0;
-    rPnt.setX(rRef.X() + FRound( (rPnt.X() - rRef.X()) * nxFract ));
-    rPnt.setY(rRef.Y() + FRound( (rPnt.Y() - rRef.Y()) * nyFract ));
+    rPnt.setX(rRef.X() + basegfx::fround<tools::Long>((rPnt.X() - rRef.X()) * 
nxFract));
+    rPnt.setY(rRef.Y() + basegfx::fround<tools::Long>((rPnt.Y() - rRef.Y()) * 
nyFract));
 }
 
 inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
 {
     tools::Long dx=rPnt.X()-rRef.X();
     tools::Long dy=rPnt.Y()-rRef.Y();
-    rPnt.setX(FRound(rRef.X()+dx*cs+dy*sn));
-    rPnt.setY(FRound(rRef.Y()+dy*cs-dx*sn));
+    rPnt.setX(basegfx::fround<tools::Long>(rRef.X() + dx * cs + dy * sn));
+    rPnt.setY(basegfx::fround<tools::Long>(rRef.Y() + dy * cs - dx * sn));
 }
 
 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
 {
     if (!bVShear) { // Horizontal
         if (rPnt.Y()!=rRef.Y()) { // else not needed
-            rPnt.AdjustX(-FRound((rPnt.Y()-rRef.Y())*tn));
+            rPnt.AdjustX(basegfx::fround<tools::Long>((rRef.Y() - rPnt.Y()) * 
tn));
         }
     } else { // or else vertical
         if (rPnt.X()!=rRef.X()) { // else not needed
-            rPnt.AdjustY(-FRound((rPnt.X()-rRef.X())*tn));
+            rPnt.AdjustY(basegfx::fround<tools::Long>((rRef.X() - rPnt.X()) * 
tn));
         }
     }
 }
diff --git a/include/tools/helpers.hxx b/include/tools/helpers.hxx
index 5f61ba80836c..d0fb08f70e5b 100644
--- a/include/tools/helpers.hxx
+++ b/include/tools/helpers.hxx
@@ -71,14 +71,6 @@ inline sal_uInt32 AlignedWidth4Bytes(sal_uInt32 nWidthBits)
     return (nWidthBits >> 5) << 2;
 }
 
-inline tools::Long FRound( double fVal )
-{
-    return fVal > 0.0
-        ? fVal == double(std::numeric_limits<tools::Long>::max())
-            ? std::numeric_limits<tools::Long>::max() : 
static_cast<tools::Long>( fVal + 0.5 )
-        :  static_cast<tools::Long>( fVal - 0.5 );
-}
-
 //valid range:  (-180,180]
 template <typename T>
 [[nodiscard]] inline typename std::enable_if<std::is_signed<T>::value, T>::type
diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index 123b48fcd752..19dc78bc5d76 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -20,6 +20,9 @@
 #ifndef INCLUDED_VCL_BITMAP_HXX
 #define INCLUDED_VCL_BITMAP_HXX
 
+#include <sal/config.h>
+
+#include <basegfx/numeric/ftools.hxx>
 #include <tools/degree.hxx>
 #include <vcl/checksum.hxx>
 #include <vcl/dllapi.h>
@@ -32,7 +35,10 @@
 
 #include <memory>
 
-#define GAMMA( _def_cVal, _def_InvGamma )   
(static_cast<sal_uInt8>(MinMax(FRound(pow( 
_def_cVal/255.0,_def_InvGamma)*255.0),0,255)))
+inline sal_uInt8 GAMMA(double _def_cVal, double _def_InvGamma)
+{
+    return basegfx::fround<sal_uInt8>(pow(_def_cVal / 255.0, _def_InvGamma) * 
255.0);
+}
 
 class Color;
 
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 20da0fcac2bf..c4bd1b2f90b1 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -963,10 +963,10 @@ void ScDrawLayer::InitializeCellAnchoredObj(SdrObject* 
pObj, ScDrawObjData& rDat
                 
static_cast<SdrPathObj*>(pObj)->GetPathPoly().getB2DPolygon(0));
             const basegfx::B2DPoint aB2DPoint0(aPoly.getB2DPoint(0));
             const basegfx::B2DPoint aB2DPoint1(aPoly.getB2DPoint(1));
-            const Point aPointLT(FRound(std::min(aB2DPoint0.getX(), 
aB2DPoint1.getX())),
-                                 FRound(std::min(aB2DPoint0.getY(), 
aB2DPoint1.getY())));
-            const Point aPointRB(FRound(std::max(aB2DPoint0.getX(), 
aB2DPoint1.getX())),
-                                 FRound(std::max(aB2DPoint0.getY(), 
aB2DPoint1.getY())));
+            const Point 
aPointLT(basegfx::fround<tools::Long>(std::min(aB2DPoint0.getX(), 
aB2DPoint1.getX())),
+                                 
basegfx::fround<tools::Long>(std::min(aB2DPoint0.getY(), aB2DPoint1.getY())));
+            const Point 
aPointRB(basegfx::fround<tools::Long>(std::max(aB2DPoint0.getX(), 
aB2DPoint1.getX())),
+                                 
basegfx::fround<tools::Long>(std::max(aB2DPoint0.getY(), aB2DPoint1.getY())));
             const tools::Rectangle aObjRect(aPointLT, aPointRB);
             GetCellAnchorFromPosition(aObjRect, rNoRotatedAnchor, *pDoc, nTab1,
                                       false /*bHiddenAsZero*/);
diff --git a/sd/source/filter/html/htmlex.cxx b/sd/source/filter/html/htmlex.cxx
index aed0312bc812..7f41e2966a4d 100644
--- a/sd/source/filter/html/htmlex.cxx
+++ b/sd/source/filter/html/htmlex.cxx
@@ -2774,7 +2774,8 @@ OUString HtmlExport::CreateHTMLPolygonArea( const 
::basegfx::B2DPolyPolygon& rPo
         for ( sal_uInt32 nPoint = 0; nPoint < nNoOfPoints; nPoint++ )
         {
             const ::basegfx::B2DPoint aB2DPoint(aPolygon.getB2DPoint(nPoint));
-            Point aPnt(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
+            Point aPnt(basegfx::fround<tools::Long>(aB2DPoint.getX()),
+                       basegfx::fround<tools::Long>(aB2DPoint.getY()));
             // coordinates are relative to the physical page origin, not the
             // origin of ordinates
             aPnt.Move(aShift.Width(), aShift.Height());
diff --git a/sd/source/ui/app/optsitem.cxx b/sd/source/ui/app/optsitem.cxx
index fb9aac86d491..1736a20e0c6c 100644
--- a/sd/source/ui/app/optsitem.cxx
+++ b/sd/source/ui/app/optsitem.cxx
@@ -1042,13 +1042,13 @@ bool SdOptionsGrid::ReadData( const Any* pValues )
 
     if( pValues[2].hasValue() )
     {
-        const sal_uInt32 nDivX = FRound( *o3tl::doAccess<double>(pValues[ 2 ]) 
);
+        const sal_uInt32 nDivX = 
basegfx::fround<sal_uInt32>(*o3tl::doAccess<double>(pValues[2]));
         SetFieldDivisionX( SvxOptionsGrid::GetFieldDrawX() / ( nDivX + 1 ) );
     }
 
     if( pValues[3].hasValue() )
     {
-        const sal_uInt32 nDivY = FRound( *o3tl::doAccess<double>(pValues[ 3 ]) 
);
+        const sal_uInt32 nDivY = 
basegfx::fround<sal_uInt32>(*o3tl::doAccess<double>(pValues[3]));
         SetFieldDivisionY( SvxOptionsGrid::GetFieldDrawY() / ( nDivY + 1 ) );
     }
 
diff --git a/sd/source/ui/dlg/vectdlg.cxx b/sd/source/ui/dlg/vectdlg.cxx
index 4069aa225f44..ee407b7eb8ca 100644
--- a/sd/source/ui/dlg/vectdlg.cxx
+++ b/sd/source/ui/dlg/vectdlg.cxx
@@ -221,9 +221,9 @@ void SdVectorizeDlg::AddTile( BitmapReadAccess const * 
pRAcc, GDIMetaFile& rMtf,
         }
     }
 
-    const Color aColor( static_cast<sal_uInt8>(FRound( nSumR * fMult )),
-                        static_cast<sal_uInt8>(FRound( nSumG * fMult )),
-                        static_cast<sal_uInt8>(FRound( nSumB * fMult )) );
+    const Color aColor( basegfx::fround<sal_uInt8>( nSumR * fMult ),
+                        basegfx::fround<sal_uInt8>( nSumG * fMult ),
+                        basegfx::fround<sal_uInt8>( nSumB * fMult ) );
 
     ::tools::Rectangle   aRect( Point( nPosX, nPosY ), Size( nWidth + 1, 
nHeight + 1 ) );
     const Size& rMaxSize = rMtf.GetPrefSize();
diff --git a/sd/source/ui/func/fuoaprms.cxx b/sd/source/ui/func/fuoaprms.cxx
index 0feaabfb4736..893f833fcdf1 100644
--- a/sd/source/ui/func/fuoaprms.cxx
+++ b/sd/source/ui/func/fuoaprms.cxx
@@ -662,7 +662,8 @@ void FuObjectAnimationParameters::DoExecute( SfxRequest& 
rReq )
             const ::basegfx::B2DPolygon& 
aPolygon(rPolyPolygon.getB2DPolygon(nNoOfPolygons - 1));
             sal_uInt32 nPoints(aPolygon.count());
             const ::basegfx::B2DPoint 
aNewB2DCenter(aPolygon.getB2DPoint(nPoints - 1));
-            const Point aNewCenter(FRound(aNewB2DCenter.getX()), 
FRound(aNewB2DCenter.getY()));
+            const Point 
aNewCenter(basegfx::fround<::tools::Long>(aNewB2DCenter.getX()),
+                                   
basegfx::fround<::tools::Long>(aNewB2DCenter.getY()));
             Size aDistance(aNewCenter.X() - aCurCenter.X(), aNewCenter.Y() - 
aCurCenter.Y());
             pRunningObj->Move(aDistance);
 
diff --git a/sd/source/ui/view/drviews8.cxx b/sd/source/ui/view/drviews8.cxx
index 0f2907d424ba..15be1d1c95d0 100644
--- a/sd/source/ui/view/drviews8.cxx
+++ b/sd/source/ui/view/drviews8.cxx
@@ -74,13 +74,13 @@ void DrawViewShell::ScannerEvent()
 
                         if( fGrfWH < fWinWH )
                         {
-                            aBmpSize.setWidth( FRound( aPageSize.Height() * 
fGrfWH ) );
+                            aBmpSize.setWidth( basegfx::fround<::tools::Long>( 
aPageSize.Height() * fGrfWH ) );
                             aBmpSize.setHeight( aPageSize.Height() );
                         }
                         else if( fGrfWH > 0.F )
                         {
                             aBmpSize.setWidth( aPageSize.Width() );
-                            aBmpSize.setHeight( FRound( aPageSize.Width() / 
fGrfWH ) );
+                            aBmpSize.setHeight( 
basegfx::fround<::tools::Long>( aPageSize.Width() / fGrfWH ) );
                         }
                     }
 
diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx
index a3b5226917d3..847d44d00820 100644
--- a/sfx2/source/doc/objcont.cxx
+++ b/sfx2/source/doc/objcont.cxx
@@ -171,13 +171,13 @@ bool SfxObjectShell::CreatePreview_Impl( bool 
bFullContent, VirtualDevice* pDevi
             double      fWH = static_cast< double >( aSizePix.Width() ) / 
aSizePix.Height();
             if ( fWH <= 1.0 )
             {
-                aSizePix.setWidth( FRound( nMaximumExtent * fWH ) );
+                aSizePix.setWidth(basegfx::fround<tools::Long>(nMaximumExtent 
* fWH));
                 aSizePix.setHeight( nMaximumExtent );
             }
             else
             {
                 aSizePix.setWidth( nMaximumExtent );
-                aSizePix.setHeight( FRound(  nMaximumExtent / fWH ) );
+                aSizePix.setHeight(basegfx::fround<tools::Long>(nMaximumExtent 
/ fWH));
             }
         }
         // do it 4x larger to be able to scale it down & get beautiful 
antialias
diff --git a/slideshow/source/engine/shapes/drawinglayeranimation.cxx 
b/slideshow/source/engine/shapes/drawinglayeranimation.cxx
index d0d3acb66369..ea765eea9649 100644
--- a/slideshow/source/engine/shapes/drawinglayeranimation.cxx
+++ b/slideshow/source/engine/shapes/drawinglayeranimation.cxx
@@ -422,7 +422,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes()
 
         const double fNumberSteps =
             (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
-        nLoopTime = FRound(fNumberSteps * mnFrequency);
+        nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency);
 
         // init loop
         ScrollTextAnimNode aInitNode(
@@ -451,7 +451,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes()
 
         const double fNumberSteps =
             (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
-        nLoopTime = FRound(fNumberSteps * mnFrequency);
+        nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency);
 
         if(0 == mnRepeat)
         {
@@ -501,7 +501,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes()
 
     const double fNumberSteps =
         (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic();
-    nLoopTime = FRound(fNumberSteps * mnFrequency);
+    nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency);
 
     // exit loop
     ScrollTextAnimNode aExitNode(
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx 
b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index d93dbee142a3..4c5214bf8674 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -1171,9 +1171,9 @@ bool EnhancedCustomShape2d::GetHandlePosition( const 
sal_uInt32 nIndex, Point& r
                 double fY =-dx * sin( a );
                 rReturnPosition =
                     Point(
-                        FRound( fX + aReferencePoint.X() ),
+                        basegfx::fround<tools::Long>( fX + aReferencePoint.X() 
),
                         basegfx::fTools::equalZero(fXScale) ? 
aReferencePoint.Y() :
-                        FRound( ( fY * fYScale ) / fXScale + 
aReferencePoint.Y() ) );
+                        basegfx::fround<tools::Long>( ( fY * fYScale ) / 
fXScale + aReferencePoint.Y() ) );
             }
             else
             {
diff --git a/svx/source/dialog/_contdlg.cxx b/svx/source/dialog/_contdlg.cxx
index 3ae8cba852e0..02608859b380 100644
--- a/svx/source/dialog/_contdlg.cxx
+++ b/svx/source/dialog/_contdlg.cxx
@@ -135,12 +135,12 @@ tools::PolyPolygon SvxContourDlg::CreateAutoContour( 
const Graphic& rGraphic,
             if( fWH <= 1.0 )
             {
                 aSizePix.setHeight(512);
-                aSizePix.setWidth( FRound( ( aSizePix.Height() ) * fWH ) );
+                
aSizePix.setWidth(basegfx::fround<tools::Long>(aSizePix.Height() * fWH));
             }
             else
             {
                 aSizePix.setWidth(512);
-                aSizePix.setHeight( FRound( ( aSizePix.Width() ) / fWH ) );
+                
aSizePix.setHeight(basegfx::fround<tools::Long>(aSizePix.Width() / fWH));
             }
         }
 
diff --git a/svx/source/gallery2/galobj.cxx b/svx/source/gallery2/galobj.cxx
index 44362b9a78ec..80d49228e750 100644
--- a/svx/source/gallery2/galobj.cxx
+++ b/svx/source/gallery2/galobj.cxx
@@ -118,9 +118,9 @@ bool SgaObject::CreateThumb( const Graphic& rGraphic )
                     double  fFactorPix = static_cast< double >( 
aBmpSize.Width() ) / aBmpSize.Height();
 
                     if( fFactorPix > fFactorLog )
-                        aBmpSize.setWidth( FRound( aBmpSize.Height() * 
fFactorLog ) );
+                        aBmpSize.setWidth( basegfx::fround<tools::Long>( 
aBmpSize.Height() * fFactorLog ) );
                     else
-                        aBmpSize.setHeight( FRound( aBmpSize.Width() / 
fFactorLog ) );
+                        aBmpSize.setHeight( basegfx::fround<tools::Long>( 
aBmpSize.Width() / fFactorLog ) );
 
                     aBmpEx.Scale(aBmpSize, BmpScaleFlag::BestQuality);
                 }
diff --git a/svx/source/svdraw/gradtrns.cxx b/svx/source/svdraw/gradtrns.cxx
index d665cd48ce16..34c547bba8ed 100644
--- a/svx/source/svdraw/gradtrns.cxx
+++ b/svx/source/svdraw/gradtrns.cxx
@@ -235,7 +235,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 }
 
                 // to int and set
-                Degree10 nNewAngle( FRound(fNewFullAngle));
+                Degree10 nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle));
 
                 if(nNewAngle != rGOld.aGradient.GetAngle())
                 {
@@ -252,7 +252,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 const double fFullLen(aFullVec.getLength());
                 const double fOldLen(aOldVec.getLength());
                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
-                sal_Int32 nNewBorder(100 - FRound(fNewBorder));
+                sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder));
 
                 // clip
                 if(nNewBorder < 0)
@@ -283,7 +283,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 const double fFullLen(aFullVec.getLength());
                 const double fOldLen(aOldVec.getLength());
                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
-                sal_Int32 nNewBorder = 100 - FRound(fNewBorder);
+                sal_Int32 nNewBorder = 100 - basegfx::fround(fNewBorder);
 
                 // clip
                 if(nNewBorder < 0)
@@ -319,7 +319,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 }
 
                 // to int and set
-                const Degree10 nNewAngle(FRound(fNewFullAngle));
+                const Degree10 
nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle));
 
                 if(nNewAngle != rGOld.aGradient.GetAngle())
                 {
@@ -336,8 +336,8 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
             {
                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), 
aRange.getMinY());
                 const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
-                sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / 
aRange.getWidth()));
-                sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / 
aRange.getHeight()));
+                sal_Int32 nNewXOffset(basegfx::fround(aOffset.getX() * 100.0 / 
aRange.getWidth()));
+                sal_Int32 nNewYOffset(basegfx::fround(aOffset.getY() * 100.0 / 
aRange.getHeight()));
 
                 // clip
                 if(nNewXOffset < 0)
@@ -376,7 +376,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 const double fFullLen(aFullVec.getLength());
                 const double fOldLen(aOldVec.getLength());
                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
-                sal_Int32 nNewBorder(100 - FRound(fNewBorder));
+                sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder));
 
                 // clip
                 if(nNewBorder < 0)
@@ -414,7 +414,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 }
 
                 // to int and set
-                const Degree10 nNewAngle(FRound(fNewFullAngle));
+                const Degree10 
nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle));
 
                 if(nNewAngle != rGOld.aGradient.GetAngle())
                 {
@@ -431,8 +431,8 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
             {
                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), 
aRange.getMinY());
                 const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
-                sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / 
aRange.getWidth()));
-                sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / 
aRange.getHeight()));
+                sal_Int32 nNewXOffset(basegfx::fround(aOffset.getX() * 100.0 / 
aRange.getWidth()));
+                sal_Int32 nNewYOffset(basegfx::fround(aOffset.getY() * 100.0 / 
aRange.getHeight()));
 
                 // clip
                 if(nNewXOffset < 0)
@@ -471,7 +471,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 const double fFullLen(aFullVec.getLength());
                 const double fOldLen(aOldVec.getLength());
                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
-                sal_Int32 nNewBorder(100 - FRound(fNewBorder));
+                sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder));
 
                 // clip
                 if(nNewBorder < 0)
@@ -509,7 +509,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, 
GradTransGradient& r
                 }
 
                 // to int and set
-                const Degree10 nNewAngle(FRound(fNewFullAngle));
+                const Degree10 
nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle));
 
                 if(nNewAngle != rGOld.aGradient.GetAngle())
                 {
diff --git a/svx/source/svdraw/sdrpagewindow.cxx 
b/svx/source/svdraw/sdrpagewindow.cxx
index 01be77135674..86fbe967ccbc 100644
--- a/svx/source/svdraw/sdrpagewindow.cxx
+++ b/svx/source/svdraw/sdrpagewindow.cxx
@@ -231,6 +231,7 @@ void SdrPageWindow::PrepareRedraw(const vcl::Region& rReg)
 // clip test
 #ifdef CLIPPER_TEST
 #include <svx/svdopath.hxx>
+#include <basegfx/numeric/ftools.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <tools/helpers.hxx>
 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
@@ -262,8 +263,10 @@ namespace
             {
                 const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
                 const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % 
aCandidate.count()));
-                const Point aStart(FRound(aBStart.getX()), 
FRound(aBStart.getY()));
-                const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY()));
+                const Point 
aStart(basegfx::fround<tools::Long>(aBStart.getX()),
+                                   
basegfx::fround<tools::Long>(aBStart.getY()));
+                const Point aEnd(basegfx::fround<tools::Long>(aBEnd.getX()),
+                                 basegfx::fround<tools::Long>(aBEnd.getY()));
                 rOutDev.DrawLine(aStart, aEnd);
             }
         }
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index 2e4d218a3aee..7d40c4f211f8 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -559,7 +559,7 @@ void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& 
rRef, const Point& rRa
     aCtr1 -= aCtr0;
 
     if(bRotOk)
-        pO->Rotate(aCtr0, Degree100(FRound(basegfx::rad2deg<100>(nAngle))), 
nSin, nCos);
+        pO->Rotate(aCtr0, 
Degree100(basegfx::fround(basegfx::rad2deg<100>(nAngle))), nSin, nCos);
 
     pO->Move(Size(aCtr1.X(),aCtr1.Y()));
 }
@@ -1675,7 +1675,7 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& 
rAttr, bool addPageMargin
                     double nNew = tan(toRadians(nNewShearAngle));
                     nNew-=nOld;
                     nNew = basegfx::rad2deg<100>(atan(nNew));
-                    nShearAngle=Degree100(FRound(nNew));
+                    nShearAngle = Degree100(basegfx::fround(nNew));
                 } else {
                     nShearAngle=nNewShearAngle-nOldShearAngle;
                 }
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index f27413d4700c..54760e0f6e18 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -394,7 +394,7 @@ void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* 
pObj, bool bForceTextAttr
     if(bText && mbFntDirty)
     {
         vcl::Font aFnt(mpVD->GetFont());
-        const sal_uInt32 nHeight(FRound(aFnt.GetFontSize().Height() * 
mfScaleY));
+        const sal_uInt32 nHeight(basegfx::fround(aFnt.GetFontSize().Height() * 
mfScaleY));
 
         mpTextAttr->Put( SvxFontItem( aFnt.GetFamilyType(), 
aFnt.GetFamilyName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), 
EE_CHAR_FONTINFO ) );
         mpTextAttr->Put( SvxFontItem( aFnt.GetFamilyType(), 
aFnt.GetFamilyName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), 
EE_CHAR_FONTINFO_CJK ) );
@@ -1002,11 +1002,12 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& 
rPos, const OUString& rSt
     sal_Int32 nTextWidth = static_cast<sal_Int32>( mpVD->GetTextWidth( rStr ) 
* mfScaleX );
     sal_Int32 nTextHeight = static_cast<sal_Int32>( mpVD->GetTextHeight() * 
mfScaleY );
 
-    Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * 
mfScaleY + maOfs.Y()) );
+    Point aPos(basegfx::fround<tools::Long>(rPos.X() * mfScaleX + maOfs.X()),
+               basegfx::fround<tools::Long>(rPos.Y() * mfScaleY + maOfs.Y()));
     Size aSize( nTextWidth, nTextHeight );
 
     if ( eAlg == ALIGN_BASELINE )
-        aPos.AdjustY( -(FRound(aFontMetric.GetAscent() * mfScaleY)) );
+        aPos.AdjustY(basegfx::fround<tools::Long>(aFontMetric.GetAscent() * 
-mfScaleY));
     else if ( eAlg == ALIGN_BOTTOM )
         aPos.AdjustY( -nTextHeight );
 
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
index 379b3ed3f73e..75d6ae0c873f 100644
--- a/svx/source/svdraw/svdhdl.cxx
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -1420,16 +1420,20 @@ void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, 
bool bSetItemOnObject, bool
     // back transformation, set values on pIAOHandle
     GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, _pObj);
 
-    SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), 
FRound(aGradTransVector.maPositionA.getY())));
-    Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), 
FRound(aGradTransVector.maPositionB.getY())));
+    SetPos({ basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()),
+             basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY()) 
});
+    Set2ndPos({ 
basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()),
+                
basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY()) });
     if(pColHdl1)
     {
-        pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), 
FRound(aGradTransVector.maPositionA.getY())));
+        pColHdl1->SetPos({ 
basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()),
+                             
basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY()) });
         pColHdl1->SetColor(aGradTransVector.aCol1);
     }
     if(pColHdl2)
     {
-        pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), 
FRound(aGradTransVector.maPositionB.getY())));
+        pColHdl2->SetPos({ 
basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()),
+                             
basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY()) });
         pColHdl2->SetColor(aGradTransVector.aCol2);
     }
 }
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 44ecb8fefded..fd0c43f851f1 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -3033,7 +3033,8 @@ void SdrObjCustomShape::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix,
     }
 
     // scale
-    Size aSize(FRound(fabs(aScale.getX())), FRound(fabs(aScale.getY())));
+    Size aSize(basegfx::fround<tools::Long>(fabs(aScale.getX())),
+               basegfx::fround<tools::Long>(fabs(aScale.getY())));
     // fdo#47434 We need a valid rectangle here
     if( !aSize.Height() ) aSize.setHeight( 1 );
     if( !aSize.Width() ) aSize.setWidth( 1 );
@@ -3053,7 +3054,7 @@ void SdrObjCustomShape::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix,
         // #i123181# The fix for #121932# here was wrong, the trunk version 
does not correct the
         // mirrored shear values, neither at the object level, nor on the API 
or XML level. Taking
         // back the mirroring of the shear angle
-        aGeoStat.nShearAngle = 
Degree100(FRound(basegfx::rad2deg<100>(atan(fShearX))));
+        aGeoStat.nShearAngle = 
Degree100(basegfx::fround(basegfx::rad2deg<100>(atan(fShearX))));
         aGeoStat.RecalcTan();
         Shear(Point(), aGeoStat.nShearAngle, aGeoStat.mfTanShearAngle, false);
     }
@@ -3066,7 +3067,7 @@ void SdrObjCustomShape::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix,
         // #i78696#
         // fRotate is mathematically correct, but aGeoStat.nRotationAngle is
         // mirrored -> mirror value here
-        aGeoStat.nRotationAngle = 
NormAngle36000(Degree100(FRound(-basegfx::rad2deg<100>(fRotate))));
+        aGeoStat.nRotationAngle = 
NormAngle36000(Degree100(basegfx::fround(-basegfx::rad2deg<100>(fRotate))));
         aGeoStat.RecalcSinCos();
         Rotate(Point(), aGeoStat.nRotationAngle, aGeoStat.mfSinRotationAngle, 
aGeoStat.mfCosRotationAngle);
     }
@@ -3074,7 +3075,8 @@ void SdrObjCustomShape::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix,
     // translate?
     if(!aTranslate.equalZero())
     {
-        Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
+        Move(Size(basegfx::fround<tools::Long>(aTranslate.getX()),
+                  basegfx::fround<tools::Long>(aTranslate.getY())));
     }
 
     // Apply flipping from enhanced geometry at center of the shape.
@@ -3095,11 +3097,11 @@ void SdrObjCustomShape::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix,
     double fCenterX = aCenter.getX();
     double fCenterY = aCenter.getY();
     if (bIsMirroredX) // vertical axis
-        Mirror(Point(FRound(fCenterX),FRound(fCenterY)),
-            Point(FRound(fCenterX), FRound(fCenterY + 1000.0)));
+        Mirror(Point(basegfx::fround<tools::Long>(fCenterX), 
basegfx::fround<tools::Long>(fCenterY)),
+            Point(basegfx::fround<tools::Long>(fCenterX), 
basegfx::fround<tools::Long>(fCenterY + 1000.0)));
     if (bIsMirroredY) // horizontal axis
-        Mirror(Point(FRound(fCenterX),FRound(fCenterY)),
-            Point(FRound(fCenterX + 1000.0), FRound(fCenterY)));
+        Mirror(Point(basegfx::fround<tools::Long>(fCenterX), 
basegfx::fround<tools::Long>(fCenterY)),
+            Point(basegfx::fround<tools::Long>(fCenterX + 1000.0), 
basegfx::fround<tools::Long>(fCenterY)));
 }
 
 // taking fObjectRotation instead of aGeo.nAngle
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 4bcd7c386270..a817ad295a9b 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -3036,8 +3036,10 @@ void SdrObject::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix, const ba
     }
 
     // build BaseRect
-    Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
-    tools::Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), 
FRound(aScale.getY())));
+    Point aPoint(basegfx::fround<tools::Long>(aTranslate.getX()),
+                 basegfx::fround<tools::Long>(aTranslate.getY()));
+    tools::Rectangle aBaseRect(aPoint, 
Size(basegfx::fround<tools::Long>(aScale.getX()),
+                                            
basegfx::fround<tools::Long>(aScale.getY())));
 
     // set BaseRect
     SetSnapRect(aBaseRect);
diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx
index 6a886272bad1..0287b2391a5b 100644
--- a/svx/source/svdraw/svdocapt.cxx
+++ b/svx/source/svdraw/svdocapt.cxx
@@ -737,8 +737,10 @@ void SdrCaptionObj::TRSetBaseGeometry(const 
basegfx::B2DHomMatrix& rMatrix, cons
     }
 
     // build BaseRect
-    Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
-    tools::Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), 
FRound(aScale.getY())));
+    Point aPoint(basegfx::fround<tools::Long>(aTranslate.getX()),
+                 basegfx::fround<tools::Long>(aTranslate.getY()));
+    tools::Rectangle aBaseRect(aPoint, 
Size(basegfx::fround<tools::Long>(aScale.getX()),
+                                            
basegfx::fround<tools::Long>(aScale.getY())));
 
     // set BaseRect, but rescue TailPos over this call
     const Point aTailPoint = GetTailPos();
diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx
index 1207548114bf..270eda407493 100644
--- a/svx/source/svdraw/svdocirc.cxx
+++ b/svx/source/svdraw/svdocirc.cxx
@@ -57,7 +57,8 @@ static Point GetAnglePnt(const tools::Rectangle& rR, 
Degree100 nAngle)
     tools::Long nHgt=rR.Bottom()-rR.Top();
     tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
     double a = toRadians(nAngle);
-    Point aRetval(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
+    Point aRetval(basegfx::fround<tools::Long>(cos(a) * nMaxRad),
+                  basegfx::fround<tools::Long>(-sin(a) * nMaxRad));
     if (nWdt==0) aRetval.setX(0 );
     if (nHgt==0) aRetval.setY(0 );
     if (nWdt!=nHgt) {
@@ -886,13 +887,15 @@ void SdrCircObj::NbcMirror(const Point& rRef1, const 
Point& rRef2)
         tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2;
         // starting point
         double a = toRadians(nStartAngle);
-        aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
+        aTmpPt1 = Point(basegfx::fround<tools::Long>(cos(a) * nMaxRad),
+                        basegfx::fround<tools::Long>(-sin(a) * nMaxRad));
         if (nWdt==0) aTmpPt1.setX(0 );
         if (nHgt==0) aTmpPt1.setY(0 );
         aTmpPt1+=aCenter;
         // finishing point
         a = toRadians(nEndAngle);
-        aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad));
+        aTmpPt2 = Point(basegfx::fround<tools::Long>(cos(a) * nMaxRad),
+                        basegfx::fround<tools::Long>(-sin(a) * nMaxRad));
         if (nWdt==0) aTmpPt2.setX(0 );
         if (nHgt==0) aTmpPt2.setY(0 );
         aTmpPt2+=aCenter;
@@ -1011,7 +1014,7 @@ void SdrCircObj::TakeUnrotatedSnapRect(tools::Rectangle& 
rRect) const
     if (maGeo.nShearAngle==0_deg100)
         return;
 
-    tools::Long nDst = FRound((rRect.Bottom() - rRect.Top()) * 
maGeo.mfTanShearAngle);
+    tools::Long nDst = basegfx::fround<tools::Long>((rRect.Bottom() - 
rRect.Top()) * maGeo.mfTanShearAngle);
     if (maGeo.nShearAngle > 0_deg100)
     {
         Point aRef(rRect.TopLeft());
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index a4b2060956dc..49fb0666af82 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -1051,7 +1051,7 @@ void SdrGrafObj::ImpSetAttrToGrafInfo()
     aGrafInfo.SetChannelG( rSet.Get( SDRATTR_GRAFGREEN ).GetValue() );
     aGrafInfo.SetChannelB( rSet.Get( SDRATTR_GRAFBLUE ).GetValue() );
-e 
... etc. - the rest is truncated

Reply via email to