include/vcl/outdev.hxx                  |    2 
 include/vcl/vcllayout.hxx               |    6 +-
 vcl/inc/ImplLayoutArgs.hxx              |    4 -
 vcl/inc/font/FontMetricData.hxx         |    6 +-
 vcl/inc/font/LogicalFontInstance.hxx    |    2 
 vcl/inc/impglyphitem.hxx                |   33 ++++++++-------
 vcl/inc/quartz/salgdi.h                 |    4 -
 vcl/inc/sallayout.hxx                   |   16 +++----
 vcl/inc/skia/osx/gdiimpl.hxx            |    3 -
 vcl/qa/cppunit/complextext.cxx          |    2 
 vcl/quartz/salgdi.cxx                   |    6 +-
 vcl/skia/osx/gdiimpl.cxx                |    4 -
 vcl/source/font/LogicalFontInstance.cxx |    2 
 vcl/source/gdi/CommonSalLayout.cxx      |   16 +++----
 vcl/source/gdi/pdfwriter_impl.cxx       |    2 
 vcl/source/gdi/sallayout.cxx            |   70 +++++++++++++++-----------------
 vcl/source/outdev/text.cxx              |   64 +++++++++--------------------
 vcl/source/text/ImplLayoutArgs.cxx      |    2 
 18 files changed, 109 insertions(+), 135 deletions(-)

New commits:
commit c46f8c356d812230c3a43cd08fb79674be88d9a8
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Mon Jul 17 12:16:58 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Sun Jul 23 06:01:31 2023 +0200

    vcl: Simplify AquaGraphics*::drawTextLayout() calling
    
    Take TextRenderModeForResolutionIndependentLayout() from the SalLayout
    argument instead of passing it separately.
    
    Change-Id: I155ea645e401618ad884fdc36c4c1aeab69980ee
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154516
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 01826c5c93e0..026f5e066382 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -292,7 +292,7 @@ public:
                                    const tools::Rectangle &rControlRegion,
                                    ControlState nState,
                                    const ImplControlValue &aValue) = 0;
-    virtual void drawTextLayout(const GenericSalLayout& layout, bool 
bTextRenderModeForResolutionIndependentLayout) = 0;
+    virtual void drawTextLayout(const GenericSalLayout& layout) = 0;
     virtual void Flush() {}
     virtual void Flush( const tools::Rectangle& ) {}
     virtual void WindowBackingPropertiesChanged() {};
@@ -445,7 +445,7 @@ public:
                                    ControlState nState,
                                    const ImplControlValue &aValue) override;
 
-    virtual void drawTextLayout(const GenericSalLayout& layout, bool 
bTextRenderModeForResolutionIndependentLayout) override;
+    virtual void drawTextLayout(const GenericSalLayout& layout) override;
 
     bool supportsOperation(OutDevSupportType eType) const override;
 };
diff --git a/vcl/inc/skia/osx/gdiimpl.hxx b/vcl/inc/skia/osx/gdiimpl.hxx
index b90b576a873f..b97245e86e11 100644
--- a/vcl/inc/skia/osx/gdiimpl.hxx
+++ b/vcl/inc/skia/osx/gdiimpl.hxx
@@ -38,8 +38,7 @@ public:
                                    const tools::Rectangle& rControlRegion, 
ControlState nState,
                                    const ImplControlValue& aValue) override;
 
-    virtual void drawTextLayout(const GenericSalLayout& layout,
-                                bool 
bTextRenderModeForResolutionIndependentLayout) override;
+    virtual void drawTextLayout(const GenericSalLayout& layout) override;
 
     virtual void Flush() override;
     virtual void Flush(const tools::Rectangle&) override;
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 4af4b28ffa2c..b06e0d41bdbd 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -306,10 +306,10 @@ bool 
AquaSalGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection*,
 
 void AquaSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
 {
-    mpBackend->drawTextLayout(rLayout, 
rLayout.GetTextRenderModeForResolutionIndependentLayout());
+    mpBackend->drawTextLayout(rLayout);
 }
 
-void AquaGraphicsBackend::drawTextLayout(const GenericSalLayout& rLayout, bool 
bTextRenderModeForResolutionIndependentLayout)
+void AquaGraphicsBackend::drawTextLayout(const GenericSalLayout& rLayout)
 {
 #ifdef IOS
     if (!mrShared.checkContext())
@@ -397,7 +397,7 @@ void AquaGraphicsBackend::drawTextLayout(const 
GenericSalLayout& rLayout, bool b
         CGContextSetTextDrawingMode(mrShared.maContextHolder.get(), 
kCGTextFillStroke);
     }
 
-    if (bTextRenderModeForResolutionIndependentLayout)
+    if (rLayout.GetTextRenderModeForResolutionIndependentLayout())
     {
         
CGContextSetAllowsFontSubpixelQuantization(mrShared.maContextHolder.get(), 
false);
         
CGContextSetShouldSubpixelQuantizeFonts(mrShared.maContextHolder.get(), false);
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx
index fd0bdca04333..e392587c8836 100644
--- a/vcl/skia/osx/gdiimpl.cxx
+++ b/vcl/skia/osx/gdiimpl.cxx
@@ -294,9 +294,9 @@ bool AquaSkiaSalGraphicsImpl::drawNativeControl(ControlType 
nType, ControlPart n
     return bOK;
 }
 
-void AquaSkiaSalGraphicsImpl::drawTextLayout(const GenericSalLayout& rLayout,
-                                             bool bSubpixelPositioning)
+void AquaSkiaSalGraphicsImpl::drawTextLayout(const GenericSalLayout& rLayout)
 {
+    const bool bSubpixelPositioning = 
rLayout.GetTextRenderModeForResolutionIndependentLayout();
     const CoreTextFont& rFont = *static_cast<const 
CoreTextFont*>(&rLayout.GetFont());
     const vcl::font::FontSelectPattern& rFontSelect = 
rFont.GetFontSelectPattern();
     int nHeight = rFontSelect.mnHeight;
commit 172b500ccbc8dac0496cc2936a9bcca793c0b594
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Sun Jul 16 21:11:40 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Sun Jul 23 06:01:23 2023 +0200

    vcl: Use more doubles for text measurements
    
    Change-Id: I5695d9ab51eb09929b4c290ceaf7ae2be46f5989
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154504
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index cfa423759202..f898f4f13902 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1232,7 +1232,7 @@ public:
                                             const SalLayoutGlyphs* pGlyphs = 
nullptr) const;
 
     SAL_DLLPRIVATE vcl::text::ImplLayoutArgs ImplPrepareLayoutArgs( OUString&, 
const sal_Int32 nIndex, const sal_Int32 nLen,
-                                                         DeviceCoordinate 
nPixelWidth,
+                                                         double nPixelWidth,
                                                          SalLayoutFlags flags 
= SalLayoutFlags::NONE,
                                                          
vcl::text::TextLayoutCache const* = nullptr) const;
     SAL_DLLPRIVATE std::unique_ptr<SalLayout>
diff --git a/vcl/inc/ImplLayoutArgs.hxx b/vcl/inc/ImplLayoutArgs.hxx
index d7100d71fd8b..1802ce19decd 100644
--- a/vcl/inc/ImplLayoutArgs.hxx
+++ b/vcl/inc/ImplLayoutArgs.hxx
@@ -37,7 +37,7 @@ public:
     // positioning related inputs
     const double* mpDXArray; // in floating point pixel units
     const sal_Bool* mpKashidaArray;
-    DeviceCoordinate mnLayoutWidth; // in pixel units
+    double mnLayoutWidth; // in pixel units
     Degree10 mnOrientation; // in 0-3600 system
 
     // data for bidi and glyph+script fallback
@@ -47,7 +47,7 @@ public:
     ImplLayoutArgs(OUString const& rStr, int nMinCharPos, int nEndCharPos, 
SalLayoutFlags nFlags,
                    LanguageTag aLanguageTag, vcl::text::TextLayoutCache const* 
pLayoutCache);
 
-    void SetLayoutWidth(DeviceCoordinate nWidth);
+    void SetLayoutWidth(double nWidth);
     void SetDXArray(const double* pDXArray);
     void SetKashidaArray(const sal_Bool* pKashidaArray);
     void SetOrientation(Degree10 nOrientation);
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 51f62d9b0057..274de68a0400 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -141,7 +141,7 @@ private:
                     GenericSalLayout& operator=( const GenericSalLayout& ) = 
delete;
 
     void            ApplyDXArray(const double*, const sal_Bool*);
-    void            Justify(DeviceCoordinate nNewWidth);
+    void            Justify(double nNewWidth);
     void            ApplyAsianKerning(std::u16string_view rStr);
 
     void            GetCharWidths(std::vector<double>& rCharWidths,
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index da70859f4c53..ba2f1e050dca 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -276,9 +276,9 @@ double GenericSalLayout::GetTextWidth() const
     return nWidth;
 }
 
-void GenericSalLayout::Justify( DeviceCoordinate nNewWidth )
+void GenericSalLayout::Justify(double nNewWidth)
 {
-    DeviceCoordinate nOldWidth = GetTextWidth();
+    double nOldWidth = GetTextWidth();
     if( !nOldWidth || nNewWidth==nOldWidth )
         return;
 
@@ -292,7 +292,7 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth )
     std::vector<GlyphItem>::iterator pGlyphIter;
     // count stretchable glyphs
     int nStretchable = 0;
-    int nMaxGlyphWidth = 0;
+    double nMaxGlyphWidth = 0;
     for(pGlyphIter = m_GlyphItems.begin(); pGlyphIter != pGlyphIterRight; 
++pGlyphIter)
     {
         if( !pGlyphIter->IsInCluster() )
@@ -311,7 +311,7 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth )
     pGlyphIterRight->setLinearPosX( nNewWidth );
 
     // justify glyph widths and positions
-    int nDiffWidth = nNewWidth - nOldWidth;
+    double nDiffWidth = nNewWidth - nOldWidth;
     if( nDiffWidth >= 0) // expanded case
     {
         // expand width by distributing space between glyphs evenly
@@ -326,7 +326,7 @@ void GenericSalLayout::Justify( DeviceCoordinate nNewWidth )
                 continue;
 
             // distribute extra space equally to stretchable glyphs
-            int nDeltaWidth = nDiffWidth / nStretchable--;
+            double nDeltaWidth = nDiffWidth / nStretchable--;
             nDiffWidth     -= nDeltaWidth;
             pGlyphIter->addNewWidth(nDeltaWidth);
             nDeltaSum      += nDeltaWidth;
@@ -335,13 +335,13 @@ void GenericSalLayout::Justify( DeviceCoordinate 
nNewWidth )
     else // condensed case
     {
         // squeeze width by moving glyphs proportionally
-        double fSqueeze = static_cast<double>(nNewWidth) / nOldWidth;
+        double fSqueeze = nNewWidth / nOldWidth;
         if(m_GlyphItems.size() > 1)
         {
             for( pGlyphIter = m_GlyphItems.begin(); ++pGlyphIter != 
pGlyphIterRight;)
             {
-                int nX = pGlyphIter->linearPos().getX();
-                nX = static_cast<int>(nX * fSqueeze);
+                double nX = pGlyphIter->linearPos().getX();
+                nX = nX * fSqueeze;
                 pGlyphIter->setLinearPosX( nX );
             }
         }
@@ -423,7 +423,7 @@ void 
GenericSalLayout::ApplyAsianKerning(std::u16string_view rStr)
                 continue;
 
             // apply punctuation compression to logical glyph widths
-            DeviceCoordinate nDelta = (nKernCurrent < nKernNext) ? 
nKernCurrent : nKernNext;
+            double nDelta = (nKernCurrent < nKernNext) ? nKernCurrent : 
nKernNext;
             if (nDelta < 0)
             {
                 nDelta = (nDelta * pGlyphIter->origWidth() + 2) / 4;
@@ -640,7 +640,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
     {
         // for stretched text in a MultiSalLayout the target width needs to be
         // distributed by individually adjusting its virtual character widths
-        DeviceCoordinate nTargetWidth = aMultiArgs.mnLayoutWidth;
+        double nTargetWidth = aMultiArgs.mnLayoutWidth;
         aMultiArgs.mnLayoutWidth = 0;
 
         // we need to get the original unmodified layouts ready
@@ -652,7 +652,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
         // #i17359# multilayout is not simplified yet, so calculating the
         // unjustified width needs handholding; also count the number of
         // stretchable virtual char widths
-        DeviceCoordinate nOrigWidth = 0;
+        double nOrigWidth = 0;
         int nStretchable = 0;
         for( int i = 0; i < nCharCount; ++i )
         {
@@ -665,14 +665,14 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
         // now we are able to distribute the extra width over the virtual char 
widths
         if( nOrigWidth && (nTargetWidth != nOrigWidth) )
         {
-            DeviceCoordinate nDiffWidth = nTargetWidth - nOrigWidth;
-            DeviceCoordinate nWidthSum = 0;
+            double nDiffWidth = nTargetWidth - nOrigWidth;
+            double nWidthSum = 0;
             for( int i = 0; i < nCharCount; ++i )
             {
-                DeviceCoordinate nJustWidth = aJustificationArray[i];
+                double nJustWidth = aJustificationArray[i];
                 if( (nJustWidth > 0) && (nStretchable > 0) )
                 {
-                    DeviceCoordinate nDeltaWidth = nDiffWidth / nStretchable;
+                    double nDeltaWidth = nDiffWidth / nStretchable;
                     nJustWidth += nDeltaWidth;
                     nDiffWidth -= nDeltaWidth;
                     --nStretchable;
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 81f4aa095840..6e35beccfec0 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -1115,7 +1115,7 @@ void OutputDevice::DrawStretchText( const Point& 
rStartPt, sal_Int32 nWidth,
 
 vcl::text::ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
                                                     const sal_Int32 nMinIndex, 
const sal_Int32 nLen,
-                                                    DeviceCoordinate 
nPixelWidth,
+                                                    double nPixelWidth,
                                                     SalLayoutFlags 
nLayoutFlags,
          vcl::text::TextLayoutCache const*const pLayoutCache) const
 {
@@ -1328,17 +1328,17 @@ std::unique_ptr<SalLayout> 
OutputDevice::ImplLayout(const OUString& rOrigStr,
         pGlyphs = nullptr;
     }
 
-    DeviceCoordinate nPixelWidth = 
static_cast<DeviceCoordinate>(nLogicalWidth);
+    double nPixelWidth = nLogicalWidth;
     if( nLogicalWidth && mbMap )
     {
         // convert from logical units to physical units
-        nPixelWidth = LogicWidthToDeviceCoordinate( nLogicalWidth );
+        nPixelWidth = ImplLogicWidthToDeviceSubPixel(nLogicalWidth);
     }
 
     vcl::text::ImplLayoutArgs aLayoutArgs = ImplPrepareLayoutArgs( aStr, 
nMinIndex, nLen,
             nPixelWidth, flags, pLayoutCache);
 
-    DeviceCoordinate nEndGlyphCoord(0);
+    double nEndGlyphCoord(0);
     std::unique_ptr<double[]> xDXPixelArray;
     if( !pDXArray.empty() )
     {
@@ -1405,7 +1405,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const 
OUString& rOrigStr,
     // adjust to right alignment if necessary
     if( aLayoutArgs.mnFlags & SalLayoutFlags::RightAlign )
     {
-        DeviceCoordinate nRTLOffset;
+        double nRTLOffset;
         if (!pDXArray.empty())
             nRTLOffset = nEndGlyphCoord;
         else if( nPixelWidth )
diff --git a/vcl/source/text/ImplLayoutArgs.cxx 
b/vcl/source/text/ImplLayoutArgs.cxx
index 80aec6b5f42c..826d288bba6f 100644
--- a/vcl/source/text/ImplLayoutArgs.cxx
+++ b/vcl/source/text/ImplLayoutArgs.cxx
@@ -88,7 +88,7 @@ ImplLayoutArgs::ImplLayoutArgs(const OUString& rStr, int 
nMinCharPos, int nEndCh
     maRuns.ResetPos();
 }
 
-void ImplLayoutArgs::SetLayoutWidth(DeviceCoordinate nWidth) { mnLayoutWidth = 
nWidth; }
+void ImplLayoutArgs::SetLayoutWidth(double nWidth) { mnLayoutWidth = nWidth; }
 
 void ImplLayoutArgs::SetDXArray(double const* pDXArray) { mpDXArray = 
pDXArray; }
 
commit 507a8745870e9a755be3a72f59c6e9a9d811fdcf
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Sun Jul 16 16:06:59 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Sun Jul 23 06:01:17 2023 +0200

    vcl: Use doubles for glyph item coordinates
    
    Change how glyph coordinates are represented inside VCL to use floating
    point instead of integers. Should make no functional difference because
    we are still rounding them.
    
    Change-Id: I5480ee3dec3afab50194954095fd6829ebaa4a22
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154499
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx
index 4705a44d9b92..4acfb9b4ab04 100644
--- a/include/vcl/vcllayout.hxx
+++ b/include/vcl/vcllayout.hxx
@@ -93,9 +93,9 @@ public:
     }
 
     // methods using string indexing
-    virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, 
DeviceCoordinate nCharExtra, int nFactor) const = 0;
-    virtual DeviceCoordinate FillDXArray( std::vector<DeviceCoordinate>* 
pDXArray, const OUString& rStr ) const = 0;
-    virtual DeviceCoordinate GetTextWidth() const { return FillDXArray( 
nullptr, {} ); }
+    virtual sal_Int32 GetTextBreak(double nMaxWidth, double nCharExtra, int 
nFactor) const = 0;
+    virtual double  FillDXArray( std::vector<double>* pDXArray, const 
OUString& rStr ) const = 0;
+    virtual double  GetTextWidth() const { return FillDXArray( nullptr, {} ); }
     virtual void    GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray 
) const = 0;
     virtual bool    IsKashidaPosValid ( int /*nCharPos*/, int /*nNextCharPos*/ 
) const = 0; // i60594
 
diff --git a/vcl/inc/font/FontMetricData.hxx b/vcl/inc/font/FontMetricData.hxx
index 000a5a250bbd..bd552562ff9a 100644
--- a/vcl/inc/font/FontMetricData.hxx
+++ b/vcl/inc/font/FontMetricData.hxx
@@ -56,11 +56,11 @@ public:
     tools::Long            GetInternalLeading() const                          
            { return mnIntLeading; }
     tools::Long            GetExternalLeading() const                          
            { return mnExtLeading; }
     int             GetSlant() const                                           
     { return mnSlant; }
-    tools::Long            GetMinKashida() const                               
            { return mnMinKashida; }
+    double                 GetMinKashida() const                               
            { return mnMinKashida; }
     tools::Long            GetHangingBaseline() const                          
            { return mnHangingBaseline; }
 
     void            SetSlant(int nSlant)                                       
     { mnSlant=nSlant; }
-    void            SetMinKashida( tools::Long nMinKashida )                   
            { mnMinKashida=nMinKashida; }
+    void            SetMinKashida(double nMinKashida )                         
            { mnMinKashida=nMinKashida; }
 
     // font attributes queried from the font instance
     bool            IsFullstopCentered() const                                 
     { return mbFullstopCentered; }
@@ -117,7 +117,7 @@ private:
     tools::Long            mnIntLeading;               // Internal Leading
     tools::Long            mnExtLeading;               // External Leading
     int             mnSlant;                    // Slant (Italic/Oblique)
-    tools::Long            mnMinKashida;               // Minimal width of 
kashida (Arabic)
+    double                 mnMinKashida;               // Minimal width of 
kashida (Arabic)
     tools::Long            mnHangingBaseline;          // Offset of hanging 
baseline to Romn baseline
 
     // font attributes queried from the font instance
diff --git a/vcl/inc/font/LogicalFontInstance.hxx 
b/vcl/inc/font/LogicalFontInstance.hxx
index e85d25b41f10..43b23d9cd0e9 100644
--- a/vcl/inc/font/LogicalFontInstance.hxx
+++ b/vcl/inc/font/LogicalFontInstance.hxx
@@ -109,7 +109,7 @@ public: // TODO: make data members private
 
     double GetGlyphWidth(sal_GlyphId, bool = false, bool = true) const;
 
-    int GetKashidaWidth() const;
+    double GetKashidaWidth() const;
 
     void GetScale(double* nXScale, double* nYScale) const;
 
diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx
index 87f966bd1676..c729d0cc9b7e 100644
--- a/vcl/inc/impglyphitem.hxx
+++ b/vcl/inc/impglyphitem.hxx
@@ -24,6 +24,7 @@
 #include <tools/gen.hxx>
 #include <vcl/dllapi.h>
 #include <vcl/outdev.hxx>
+#include <rtl/math.hxx>
 #include <vector>
 
 #include "font/LogicalFontInstance.hxx"
@@ -51,18 +52,18 @@ template <> struct typed_flags<GlyphItemFlags> : 
is_typed_flags<GlyphItemFlags,
 class VCL_DLLPUBLIC GlyphItem
 {
     DevicePoint m_aLinearPos; // absolute position of non rotated string
-    DeviceCoordinate m_nOrigWidth; // original glyph width
+    double m_nOrigWidth; // original glyph width
     sal_Int32 m_nCharPos; // index in string
-    sal_Int32 m_nXOffset;
-    sal_Int32 m_nYOffset;
-    DeviceCoordinate m_nNewWidth; // width after adjustments
+    double m_nXOffset;
+    double m_nYOffset;
+    double m_nNewWidth; // width after adjustments
     sal_GlyphId m_aGlyphId;
     GlyphItemFlags m_nFlags;
     sal_Int8 m_nCharCount; // number of characters making up this glyph
 
 public:
     GlyphItem(int nCharPos, int nCharCount, sal_GlyphId aGlyphId, const 
DevicePoint& rLinearPos,
-              GlyphItemFlags nFlags, DeviceCoordinate nOrigWidth, int 
nXOffset, int nYOffset)
+              GlyphItemFlags nFlags, double nOrigWidth, double nXOffset, 
double nYOffset)
         : m_aLinearPos(rLinearPos)
         , m_nOrigWidth(nOrigWidth)
         , m_nCharPos(nCharPos)
@@ -93,24 +94,26 @@ public:
 
     sal_GlyphId glyphId() const { return m_aGlyphId; }
     int charCount() const { return m_nCharCount; }
-    DeviceCoordinate origWidth() const { return m_nOrigWidth; }
+    double origWidth() const { return m_nOrigWidth; }
     int charPos() const { return m_nCharPos; }
-    int xOffset() const { return m_nXOffset; }
-    int yOffset() const { return m_nYOffset; }
-    DeviceCoordinate newWidth() const { return m_nNewWidth; }
+    double xOffset() const { return m_nXOffset; }
+    double yOffset() const { return m_nYOffset; }
+    double newWidth() const { return m_nNewWidth; }
     const DevicePoint& linearPos() const { return m_aLinearPos; }
 
-    void setNewWidth(DeviceCoordinate width) { m_nNewWidth = width; }
-    void addNewWidth(DeviceCoordinate width) { m_nNewWidth += width; }
+    void setNewWidth(double width) { m_nNewWidth = width; }
+    void addNewWidth(double width) { m_nNewWidth += width; }
     void setLinearPos(const DevicePoint& point) { m_aLinearPos = point; }
     void setLinearPosX(double x) { m_aLinearPos.setX(x); }
     void adjustLinearPosX(double diff) { m_aLinearPos.adjustX(diff); }
     bool isLayoutEquivalent(const GlyphItem& other) const
     {
-        return m_aLinearPos == other.m_aLinearPos && m_nOrigWidth == 
other.m_nOrigWidth
-               && m_nCharPos == other.m_nCharPos && m_nXOffset == 
other.m_nXOffset
-               && m_nYOffset == other.m_nYOffset && m_nNewWidth == 
other.m_nNewWidth
-               && m_aGlyphId == other.m_aGlyphId && m_nCharCount == 
other.m_nCharCount
+        return rtl::math::approxEqual(m_aLinearPos.getX(), 
other.m_aLinearPos.getX(), 8)
+               && rtl::math::approxEqual(m_aLinearPos.getY(), 
other.m_aLinearPos.getY(), 8)
+               && m_nOrigWidth == other.m_nOrigWidth && m_nCharPos == 
other.m_nCharPos
+               && m_nXOffset == other.m_nXOffset && m_nYOffset == 
other.m_nYOffset
+               && m_nNewWidth == other.m_nNewWidth && m_aGlyphId == 
other.m_aGlyphId
+               && m_nCharCount == other.m_nCharCount
                && (m_nFlags & ~GlyphItemFlags::IS_UNSAFE_TO_BREAK)
                       == (other.m_nFlags & 
~GlyphItemFlags::IS_UNSAFE_TO_BREAK);
     }
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index d48edaaf67f2..51f62d9b0057 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -61,9 +61,9 @@ class MultiSalLayout final : public SalLayout
 {
 public:
     void            DrawText(SalGraphics&) const override;
-    sal_Int32       GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate 
nCharExtra, int nFactor) const override;
-    DeviceCoordinate GetTextWidth() const final override;
-    DeviceCoordinate FillDXArray(std::vector<DeviceCoordinate>* pDXArray, 
const OUString& rStr) const override;
+    sal_Int32       GetTextBreak(double nMaxWidth, double nCharExtra, int 
nFactor) const override;
+    double          GetTextWidth() const final override;
+    double          FillDXArray(std::vector<double>* pDXArray, const OUString& 
rStr) const override;
     void            GetCaretPositions(int nArraySize, sal_Int32* pCaretXArray) 
const override;
     bool            GetNextGlyph(const GlyphItem** pGlyph, DevicePoint& rPos, 
int& nStart,
                                  const LogicalFontInstance** ppGlyphFont = 
nullptr) const override;
@@ -117,9 +117,9 @@ public:
     bool            IsKashidaPosValid(int nCharPos, int nNextCharPos) const 
final override;
 
     // used by upper layers
-    DeviceCoordinate GetTextWidth() const final override;
-    DeviceCoordinate FillDXArray(std::vector<DeviceCoordinate>* pDXArray, 
const OUString& rStr) const final override;
-    sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate 
nCharExtra, int nFactor) const final override;
+    double          GetTextWidth() const final override;
+    double          FillDXArray(std::vector<double>* pDXArray, const OUString& 
rStr) const final override;
+    sal_Int32       GetTextBreak(double nMaxWidth, double nCharExtra, int 
nFactor) const final override;
     void            GetCaretPositions(int nArraySize, sal_Int32* pCaretXArray) 
const final override;
 
     // used by display layers
@@ -144,7 +144,7 @@ private:
     void            Justify(DeviceCoordinate nNewWidth);
     void            ApplyAsianKerning(std::u16string_view rStr);
 
-    void            GetCharWidths(std::vector<DeviceCoordinate>& rCharWidths,
+    void            GetCharWidths(std::vector<double>& rCharWidths,
                                   const OUString& rStr) const;
 
     void            SetNeedFallback(vcl::text::ImplLayoutArgs&, sal_Int32, 
bool);
diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index db8593e48fbb..6c2491a27010 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -424,7 +424,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048)
     // Without the fix this fails with:
     // - Expected: 393
     // - Actual  : 511
-    CPPUNIT_ASSERT_EQUAL(DeviceCoordinate(nRefTextWidth + nKashida), 
pLayout->GetTextWidth());
+    CPPUNIT_ASSERT_EQUAL(double(nRefTextWidth + nKashida), 
pLayout->GetTextWidth());
 #endif
 }
 
diff --git a/vcl/source/font/LogicalFontInstance.cxx 
b/vcl/source/font/LogicalFontInstance.cxx
index 766dd2514120..965fc91591c1 100644
--- a/vcl/source/font/LogicalFontInstance.cxx
+++ b/vcl/source/font/LogicalFontInstance.cxx
@@ -102,7 +102,7 @@ hb_font_t* LogicalFontInstance::GetHbFontUntransformed() 
const
     return pHbFont;
 }
 
-int LogicalFontInstance::GetKashidaWidth() const
+double LogicalFontInstance::GetKashidaWidth() const
 {
     sal_GlyphId nGlyph = GetGlyphIndex(0x0640);
     if (nGlyph)
diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index f46f4d875210..ca34b098c8cb 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -239,12 +239,12 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
     // horizontal text. That is the offset from original baseline to
     // the center of EM box. Maybe we can use OpenType base table to improve 
this
     // in the future.
-    DeviceCoordinate nBaseOffset = 0;
+    double nBaseOffset = 0;
     if (rArgs.mnFlags & SalLayoutFlags::Vertical)
     {
         hb_font_extents_t extents;
         if (hb_font_get_h_extents(pHbFont, &extents))
-            nBaseOffset = ( extents.ascender + extents.descender ) / 2;
+            nBaseOffset = ( extents.ascender + extents.descender ) / 2.0;
     }
 
     hb_buffer_t* pHbBuffer = hb_buffer_create();
@@ -505,7 +505,7 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
                 if (hb_glyph_info_get_glyph_flags(&pHbGlyphInfos[i]) & 
HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL)
                     nGlyphFlags |= GlyphItemFlags::IS_SAFE_TO_INSERT_KASHIDA;
 
-                DeviceCoordinate nAdvance, nXOffset, nYOffset;
+                double nAdvance, nXOffset, nYOffset;
                 if (aSubRun.maDirection == HB_DIRECTION_TTB)
                 {
                     nGlyphFlags |= GlyphItemFlags::IS_VERTICAL;
@@ -523,7 +523,7 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
                         GetFont().GetGlyphBoundRect(nGlyphIndex, aRect, true);
 
                         nXOffset = -(aRect.Top() / nXScale  + ( 
pHbPositions[i].y_advance
-                                    + ( aRect.GetHeight() / nXScale ) ) / 2 );
+                                    + ( aRect.GetHeight() / nXScale ) ) / 2.0 
);
                     }
 
                 }
@@ -557,7 +557,7 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
     return true;
 }
 
-void GenericSalLayout::GetCharWidths(std::vector<DeviceCoordinate>& 
rCharWidths, const OUString& rStr) const
+void GenericSalLayout::GetCharWidths(std::vector<double>& rCharWidths, const 
OUString& rStr) const
 {
     const int nCharCount = mnEndCharPos - mnMinCharPos;
 
@@ -595,7 +595,7 @@ void 
GenericSalLayout::GetCharWidths(std::vector<DeviceCoordinate>& rCharWidths,
         {
             // More than one grapheme cluster, we want to distribute the glyph
             // width over them.
-            std::vector<DeviceCoordinate> aWidths(nGraphemeCount);
+            std::vector<double> aWidths(nGraphemeCount);
 
             // Check if the glyph has ligature caret positions.
             unsigned int nCarets = nGraphemeCount;
@@ -662,7 +662,7 @@ void 
GenericSalLayout::GetCharWidths(std::vector<DeviceCoordinate>& rCharWidths,
 void GenericSalLayout::ApplyDXArray(const double* pDXArray, const sal_Bool* 
pKashidaArray)
 {
     int nCharCount = mnEndCharPos - mnMinCharPos;
-    std::vector<DeviceCoordinate> aOldCharWidths;
+    std::vector<double> aOldCharWidths;
     std::unique_ptr<double[]> const pNewCharWidths(new double[nCharCount]);
 
     // Get the natural character widths (i.e. before applying DX adjustments).
@@ -679,7 +679,7 @@ void GenericSalLayout::ApplyDXArray(const double* pDXArray, 
const sal_Bool* pKas
 
     // Map of Kashida insertion points (in the glyph items vector) and the
     // requested width.
-    std::map<size_t, std::pair<DeviceCoordinate, DeviceCoordinate>> pKashidas;
+    std::map<size_t, std::pair<double, double>> pKashidas;
 
     // The accumulated difference in X position.
     double nDelta = 0;
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 42f85d42bb76..533fd62f2ae6 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6983,7 +6983,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const 
OUString& rText, bool
         if( m_aCurrentPDFState.m_aFont.IsWordLineMode() )
         {
             DevicePoint aStartPt;
-            DeviceCoordinate nWidth = 0;
+            double nWidth = 0;
             nIndex = 0;
             while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex))
             {
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index be3506bf4e3c..da70859f4c53 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -255,7 +255,7 @@ SalLayoutGlyphs SalLayout::GetGlyphs() const
     return SalLayoutGlyphs(); // invalid
 }
 
-DeviceCoordinate GenericSalLayout::FillDXArray( std::vector<DeviceCoordinate>* 
pCharWidths, const OUString& rStr ) const
+double GenericSalLayout::FillDXArray( std::vector<double>* pCharWidths, const 
OUString& rStr ) const
 {
     if (pCharWidths)
         GetCharWidths(*pCharWidths, rStr);
@@ -264,12 +264,12 @@ DeviceCoordinate GenericSalLayout::FillDXArray( 
std::vector<DeviceCoordinate>* p
 }
 
 // the text width is the maximum logical extent of all glyphs
-DeviceCoordinate GenericSalLayout::GetTextWidth() const
+double GenericSalLayout::GetTextWidth() const
 {
     if (!m_GlyphItems.IsValid())
         return 0;
 
-    DeviceCoordinate nWidth = 0;
+    double nWidth = 0;
     for (auto const& aGlyphItem : m_GlyphItems)
         nWidth += aGlyphItem.newWidth();
 
@@ -470,15 +470,15 @@ void GenericSalLayout::GetCaretPositions( int nMaxIndex, 
sal_Int32* pCaretXArray
     }
 }
 
-sal_Int32 GenericSalLayout::GetTextBreak( DeviceCoordinate nMaxWidth, 
DeviceCoordinate nCharExtra, int nFactor ) const
+sal_Int32 GenericSalLayout::GetTextBreak(double nMaxWidth, double nCharExtra, 
int nFactor) const
 {
-    std::vector<DeviceCoordinate> aCharWidths;
+    std::vector<double> aCharWidths;
     GetCharWidths(aCharWidths, {});
 
-    DeviceCoordinate nWidth = 0;
+    double nWidth = 0;
     for( int i = mnMinCharPos; i < mnEndCharPos; ++i )
     {
-        DeviceCoordinate nDelta =  aCharWidths[ i - mnMinCharPos ] * nFactor;
+        double nDelta =  aCharWidths[ i - mnMinCharPos ] * nFactor;
 
         if (nDelta != 0)
         {
@@ -634,8 +634,7 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
 {
     SalLayout::AdjustLayout( rArgs );
     vcl::text::ImplLayoutArgs aMultiArgs = rArgs;
-    std::vector<DeviceCoordinate> aJustificationArray;
-    std::vector<double> aNaturalJustificationArray;
+    std::vector<double> aJustificationArray;
 
     if( !rArgs.HasDXArray() && rArgs.mnLayoutWidth )
     {
@@ -684,11 +683,8 @@ void MultiSalLayout::AdjustLayout( 
vcl::text::ImplLayoutArgs& rArgs )
             if( nWidthSum != nTargetWidth )
                 aJustificationArray[ nCharCount-1 ] = nTargetWidth;
 
-            aNaturalJustificationArray.reserve(aJustificationArray.size());
-            for (DeviceCoordinate a : aJustificationArray)
-                aNaturalJustificationArray.push_back(a);
             // change the DXArray temporarily (just for the justification)
-            aMultiArgs.mpDXArray = aNaturalJustificationArray.data();
+            aMultiArgs.mpDXArray = aJustificationArray.data();
         }
     }
 
@@ -976,7 +972,7 @@ void MultiSalLayout::DrawText( SalGraphics& rGraphics ) 
const
     // NOTE: now the baselevel font is active again
 }
 
-sal_Int32 MultiSalLayout::GetTextBreak( DeviceCoordinate nMaxWidth, 
DeviceCoordinate nCharExtra, int nFactor ) const
+sal_Int32 MultiSalLayout::GetTextBreak(double nMaxWidth, double nCharExtra, 
int nFactor) const
 {
     if( mnLevel <= 0 )
         return -1;
@@ -984,8 +980,8 @@ sal_Int32 MultiSalLayout::GetTextBreak( DeviceCoordinate 
nMaxWidth, DeviceCoordi
         return mpLayouts[0]->GetTextBreak( nMaxWidth, nCharExtra, nFactor );
 
     int nCharCount = mnEndCharPos - mnMinCharPos;
-    std::vector<DeviceCoordinate> aCharWidths;
-    std::vector<DeviceCoordinate> aFallbackCharWidths;
+    std::vector<double> aCharWidths;
+    std::vector<double> aFallbackCharWidths;
     mpLayouts[0]->FillDXArray( &aCharWidths, {} );
 
     for( int n = 1; n < mnLevel; ++n )
@@ -997,7 +993,7 @@ sal_Int32 MultiSalLayout::GetTextBreak( DeviceCoordinate 
nMaxWidth, DeviceCoordi
                 aCharWidths[i] = aFallbackCharWidths[i];
     }
 
-    DeviceCoordinate nWidth = 0;
+    double nWidth = 0;
     for( int i = 0; i < nCharCount; ++i )
     {
         nWidth += aCharWidths[ i ] * nFactor;
@@ -1009,7 +1005,7 @@ sal_Int32 MultiSalLayout::GetTextBreak( DeviceCoordinate 
nMaxWidth, DeviceCoordi
     return -1;
 }
 
-DeviceCoordinate MultiSalLayout::GetTextWidth() const
+double MultiSalLayout::GetTextWidth() const
 {
     // Measure text width. There might be holes in each SalLayout due to
     // missing chars, so we use GetNextGlyph() to get the glyphs across all
@@ -1018,19 +1014,19 @@ DeviceCoordinate MultiSalLayout::GetTextWidth() const
     DevicePoint aPos;
     const GlyphItem* pGlyphItem;
 
-    DeviceCoordinate nWidth = 0;
+    double nWidth = 0;
     while (GetNextGlyph(&pGlyphItem, aPos, nStart))
         nWidth += pGlyphItem->newWidth();
 
     return nWidth;
 }
 
-DeviceCoordinate MultiSalLayout::FillDXArray( std::vector<DeviceCoordinate>* 
pCharWidths, const OUString& rStr ) const
+double MultiSalLayout::FillDXArray( std::vector<double>* pCharWidths, const 
OUString& rStr ) const
 {
     if (pCharWidths)
     {
         // prepare merging of fallback levels
-        std::vector<DeviceCoordinate> aTempWidths;
+        std::vector<double> aTempWidths;
         const int nCharCount = mnEndCharPos - mnMinCharPos;
         pCharWidths->clear();
         pCharWidths->resize(nCharCount, 0);
@@ -1047,7 +1043,7 @@ DeviceCoordinate MultiSalLayout::FillDXArray( 
std::vector<DeviceCoordinate>* pCh
                 // one char cannot be resolved from different fallbacks
                 if ((*pCharWidths)[i] != 0)
                     continue;
-                DeviceCoordinate nCharWidth = aTempWidths[i];
+                double nCharWidth = aTempWidths[i];
                 if (!nCharWidth)
                     continue;
                 (*pCharWidths)[i] = nCharWidth;
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 61d965a28b68..81f4aa095840 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -989,14 +989,13 @@ tools::Long OutputDevice::GetTextArray( const OUString& 
rStr, KernArray* pKernAr
         return 0;
     }
 
-#if VCL_FLOAT_DEVICE_PIXEL
-    std::unique_ptr<std::vector<DeviceCoordinate>> xDXPixelArray;
+    std::unique_ptr<std::vector<double>> xDXPixelArray;
     if(pDXAry)
     {
-        xDXPixelArray.reset(new std::vector<DeviceCoordinate>(nLen));
+        xDXPixelArray.reset(new std::vector<double>(nLen));
     }
-    std::vector<DeviceCoordinate>* pDXPixelArray = xDXPixelArray.get();
-    DeviceCoordinate nWidth = pSalLayout->FillDXArray(pDXPixelArray, bCaret ? 
rStr : OUString());
+    std::vector<double>* pDXPixelArray = xDXPixelArray.get();
+    double nWidth = pSalLayout->FillDXArray(pDXPixelArray, bCaret ? rStr : 
OUString());
 
     // convert virtual char widths to virtual absolute positions
     if( pDXPixelArray )
@@ -1006,57 +1005,34 @@ tools::Long OutputDevice::GetTextArray( const OUString& 
rStr, KernArray* pKernAr
             (*pDXPixelArray)[i] += (*pDXPixelArray)[i - 1];
         }
     }
-    if( mbMap )
-    {
-        if( pDXPixelArray )
-        {
-            for( int i = 0; i < nLen; ++i )
-            {
-                (*pDXPixelArray)[i] = 
ImplDevicePixelToLogicWidth((*pDXPixelArray)[i]);
-            }
-        }
-        nWidth = ImplDevicePixelToLogicWidth( nWidth );
-    }
-    if(pDXAry)
-    {
-        pDXAry->resize(nLen);
-        for( int i = 0; i < nLen; ++i )
-        {
-            (*pDXAry)[i] = basegfx::fround((*pDXPixelArray)[i]);
-        }
-    }
-    return basegfx::fround(nWidth);
-
-#else /* ! VCL_FLOAT_DEVICE_PIXEL */
-
-    tools::Long nWidth = pSalLayout->FillDXArray( pDXAry, bCaret ? rStr : 
OUString() );
-
-    // convert virtual char widths to virtual absolute positions
-    if( pDXAry )
-        for( int i = 1; i < nLen; ++i )
-            (*pDXAry)[ i ] += (*pDXAry)[ i-1 ];
 
     // convert from font units to logical units
-    if (pDXAry)
+    if (pDXPixelArray)
     {
         int nSubPixelFactor = pKernArray->get_factor();
         if (mbMap)
         {
             for (int i = 0; i < nLen; ++i)
-                (*pDXAry)[i] = ImplDevicePixelToLogicWidth( (*pDXAry)[i] * 
nSubPixelFactor );
+                (*pDXPixelArray)[i] = 
ImplDevicePixelToLogicWidth((*pDXPixelArray)[i] * nSubPixelFactor);
         }
         else if (nSubPixelFactor)
         {
             for (int i = 0; i < nLen; ++i)
-                (*pDXAry)[i] *= nSubPixelFactor;
+                (*pDXPixelArray)[i] *= nSubPixelFactor;
         }
     }
 
+    if (pDXAry)
+    {
+        pDXAry->resize(nLen);
+        for (int i = 0; i < nLen; ++i)
+            (*pDXAry)[i] = basegfx::fround((*pDXPixelArray)[i]);
+    }
+
     if (mbMap)
         nWidth = ImplDevicePixelToLogicWidth( nWidth );
 
-    return nWidth;
-#endif /* VCL_FLOAT_DEVICE_PIXEL */
+    return basegfx::fround(nWidth);
 }
 
 void OutputDevice::GetCaretPositions( const OUString& rStr, sal_Int32* 
pCaretXArray,

Reply via email to