canvas/source/directx/dx_textlayout_drawhelper.cxx    |    7 -
 canvas/source/opengl/ogl_canvashelper.cxx             |    7 -
 canvas/source/vcl/textlayout.cxx                      |    2 
 chart2/qa/extras/xshape/data/reference/tdf90839-2.xml |   16 +--
 chart2/qa/extras/xshape/data/reference/tdf90839-3.xml |   32 +++---
 chart2/qa/extras/xshape/data/reference/tdf90839-4.xml |    8 -
 cppcanvas/qa/unit/test.cxx                            |    4 
 cppcanvas/source/mtfrenderer/implrenderer.cxx         |   15 --
 desktop/qa/desktop_lib/test_desktop_lib.cxx           |    4 
 drawinglayer/source/primitive2d/textlayoutdevice.cxx  |   12 --
 drawinglayer/source/primitive2d/textprimitive2d.cxx   |   12 --
 drawinglayer/source/processor2d/vclprocessor2d.cxx    |    2 
 editeng/inc/EditLine.hxx                              |   10 -
 editeng/inc/TextPortion.hxx                           |    6 -
 editeng/inc/outleeng.hxx                              |    2 
 editeng/qa/unit/core-test.cxx                         |    8 -
 editeng/source/editeng/editeng.cxx                    |    2 
 editeng/source/editeng/impedit.hxx                    |    2 
 editeng/source/editeng/impedit2.cxx                   |    2 
 editeng/source/editeng/impedit3.cxx                   |   36 ++----
 editeng/source/items/svxfont.cxx                      |   37 +++----
 editeng/source/outliner/outleeng.cxx                  |    2 
 editeng/source/outliner/outliner.cxx                  |    5 
 emfio/qa/cppunit/emf/EmfImportTest.cxx                |    2 
 emfio/source/reader/emfreader.cxx                     |    4 
 emfio/source/reader/mtftools.cxx                      |    2 
 emfio/source/reader/wmfreader.cxx                     |    4 
 filter/source/svg/svgwriter.cxx                       |    4 
 include/drawinglayer/primitive2d/textlayoutdevice.hxx |    2 
 include/editeng/editeng.hxx                           |    3 
 include/editeng/outliner.hxx                          |    6 -
 include/editeng/svxfont.hxx                           |    6 -
 include/vcl/kernarray.hxx                             |   93 ------------------
 sc/source/ui/view/output2.cxx                         |    2 
 sd/qa/unit/layout-tests.cxx                           |    6 -
 svx/source/svdraw/svdotextdecomposition.cxx           |    8 -
 sw/qa/core/text/text.cxx                              |    4 
 sw/qa/core/txtnode/justify.cxx                        |    4 
 sw/qa/extras/layout/layout3.cxx                       |    6 -
 sw/qa/extras/tiledrendering/tiledrendering.cxx        |    2 
 sw/source/core/text/porlay.cxx                        |   12 +-
 sw/source/core/txtnode/fntcache.cxx                   |   16 +--
 sw/source/core/txtnode/justify.cxx                    |   20 +--
 vcl/qa/cppunit/complextext.cxx                        |   80 ++++++++-------
 vcl/qa/cppunit/pdfexport/pdfexport.cxx                |   14 +-
 vcl/qa/cppunit/svm/svmtest.cxx                        |    8 -
 vcl/qa/cppunit/text.cxx                               |   16 +--
 vcl/source/filter/svm/SvmConverter.cxx                |    6 -
 vcl/source/filter/wmf/emfwr.cxx                       |    4 
 vcl/source/filter/wmf/wmfwr.cxx                       |    3 
 vcl/source/gdi/metaact.cxx                            |    6 -
 vcl/source/outdev/text.cxx                            |   32 +-----
 52 files changed, 236 insertions(+), 372 deletions(-)

New commits:
commit 11b15571475414ef853e21a6c96afa2ac81f848f
Author:     Noel Grandin <[email protected]>
AuthorDate: Wed Oct 30 09:51:26 2024 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Thu Oct 31 12:10:52 2024 +0100

    convert KernArray from sal_Int32 to double
    
    which allows us to eliminate a bunch of rounding at various layers, and
    consequently maintain a lot more precision
    
    Change-Id: I911dedd7c041c1d67396c082e5695346ea689acb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175814
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/canvas/source/directx/dx_textlayout_drawhelper.cxx 
b/canvas/source/directx/dx_textlayout_drawhelper.cxx
index efdf8bf03cfb..cc72436ccf50 100644
--- a/canvas/source/directx/dx_textlayout_drawhelper.cxx
+++ b/canvas/source/directx/dx_textlayout_drawhelper.cxx
@@ -208,12 +208,7 @@ namespace dxcanvas
             if( rLogicalAdvancements.getLength() )
             {
                 // create the DXArray
-                const sal_Int32 nLen( rLogicalAdvancements.getLength() );
-                KernArray DXArray;
-                DXArray.reserve(nLen);
-                for( sal_Int32 i=0; i<nLen; ++i )
-                    
DXArray.push_back(basegfx::fround(rLogicalAdvancements[i]));
-
+                KernArraySpan DXArray( rLogicalAdvancements.getConstArray(), 
rLogicalAdvancements.getLength() );
                 std::span<const sal_Bool> 
aKashidaArray(rKashidaPositions.getConstArray(), rKashidaPositions.getLength());
 
                 // draw the String
diff --git a/canvas/source/opengl/ogl_canvashelper.cxx 
b/canvas/source/opengl/ogl_canvashelper.cxx
index df85d1ab428f..a4ab0738e65d 100644
--- a/canvas/source/opengl/ogl_canvashelper.cxx
+++ b/canvas/source/opengl/ogl_canvashelper.cxx
@@ -728,12 +728,7 @@ namespace oglcanvas
                 uno::Sequence<double> 
aLogicalAdvancements=xLayoutetText->queryLogicalAdvancements();
                 if( aLogicalAdvancements.hasElements() )
                 {
-                    // create the DXArray
-                    const sal_Int32 nLen( aLogicalAdvancements.getLength() );
-                    KernArray aDXArray;
-                    aDXArray.resize(nLen);
-                    for( sal_Int32 i=0; i<nLen; ++i )
-                        aDXArray.set(i, 
basegfx::fround(aLogicalAdvancements[i]));
+                    KernArraySpan 
aDXArray(aLogicalAdvancements.getConstArray(), 
aLogicalAdvancements.getLength());
 
                     uno::Sequence<sal_Bool> 
aKashidaPositions=xLayoutetText->queryKashidaPositions();
                     std::span<const sal_Bool> 
aKashidaArray(aKashidaPositions.getConstArray(), aKashidaPositions.getLength());
diff --git a/canvas/source/vcl/textlayout.cxx b/canvas/source/vcl/textlayout.cxx
index 23c450e66149..b08288c70127 100644
--- a/canvas/source/vcl/textlayout.cxx
+++ b/canvas/source/vcl/textlayout.cxx
@@ -169,8 +169,6 @@ namespace vclcanvas
             uno::Sequence<double>(4),
             rendering::CompositeOperation::SOURCE);
 
-        KernArray aOffsets(setupTextOffsets(maLogicalAdvancements, aViewState, 
aRenderState));
-
         std::vector< ::tools::Rectangle > aMetricVector;
         uno::Sequence<geometry::RealRectangle2D> aBoundingBoxes;
         if (pVDev->GetGlyphBoundRects(
diff --git a/chart2/qa/extras/xshape/data/reference/tdf90839-2.xml 
b/chart2/qa/extras/xshape/data/reference/tdf90839-2.xml
index 9daee4752d08..91fcee4428c6 100644
--- a/chart2/qa/extras/xshape/data/reference/tdf90839-2.xml
+++ b/chart2/qa/extras/xshape/data/reference/tdf90839-2.xml
@@ -204,9 +204,9 @@
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
            </XShape>
-           <XShape positionX="5957" positionY="12784" sizeX="5792" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=1">
+           <XShape positionX="5958" positionY="12784" sizeX="5791" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=1">
             <XShapes>
-             <XShape positionX="5957" positionY="12784" sizeX="5792" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="Black - The color of 
night and coffee&#10;28%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="RIGHT" textVerticalAdjust="TOP" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
+             <XShape positionX="5958" positionY="12784" sizeX="5791" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="Black - The color of 
night and coffee&#10;28%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="RIGHT" textVerticalAdjust="TOP" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
               <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillGradient style="LINEAR" startColor="000000" 
endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillHatch style="SINGLE" color="3465a4" distance="20" 
angle="0"/>
@@ -215,14 +215,14 @@
               <LineStart/>
               <LineEnd/>
               <Transformation>
-               <Line1 column1="5793.000000" column2="0.000000" 
column3="5957.000000"/>
+               <Line1 column1="5792.000000" column2="0.000000" 
column3="5958.000000"/>
                <Line2 column1="0.000000" column2="1748.000000" 
column3="12784.000000"/>
                <Line3 column1="0.000000" column2="0.000000" 
column3="1.000000"/>
               </Transformation>
              </XShape>
             </XShapes>
             <Transformation>
-             <Line1 column1="5793.000000" column2="0.000000" 
column3="5957.000000"/>
+             <Line1 column1="5792.000000" column2="0.000000" 
column3="5958.000000"/>
              <Line2 column1="0.000000" column2="1748.000000" 
column3="12784.000000"/>
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
@@ -273,9 +273,9 @@
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
            </XShape>
-           <XShape positionX="16335" positionY="2226" sizeX="5692" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=4">
+           <XShape positionX="16335" positionY="2226" sizeX="5691" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=4">
             <XShapes>
-             <XShape positionX="16335" positionY="2226" sizeX="5692" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="White - The color of 
milk and purity&#10;14%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="LEFT" textVerticalAdjust="BOTTOM" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
+             <XShape positionX="16335" positionY="2226" sizeX="5691" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="White - The color of 
milk and purity&#10;14%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="LEFT" textVerticalAdjust="BOTTOM" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
               <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillGradient style="LINEAR" startColor="000000" 
endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillHatch style="SINGLE" color="3465a4" distance="20" 
angle="0"/>
@@ -284,14 +284,14 @@
               <LineStart/>
               <LineEnd/>
               <Transformation>
-               <Line1 column1="5693.000000" column2="0.000000" 
column3="16335.000000"/>
+               <Line1 column1="5692.000000" column2="0.000000" 
column3="16335.000000"/>
                <Line2 column1="0.000000" column2="1748.000000" 
column3="2226.000000"/>
                <Line3 column1="0.000000" column2="0.000000" 
column3="1.000000"/>
               </Transformation>
              </XShape>
             </XShapes>
             <Transformation>
-             <Line1 column1="5693.000000" column2="0.000000" 
column3="16335.000000"/>
+             <Line1 column1="5692.000000" column2="0.000000" 
column3="16335.000000"/>
              <Line2 column1="0.000000" column2="1748.000000" 
column3="2226.000000"/>
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
diff --git a/chart2/qa/extras/xshape/data/reference/tdf90839-3.xml 
b/chart2/qa/extras/xshape/data/reference/tdf90839-3.xml
index d19a18c1980d..631bd3e18e8b 100644
--- a/chart2/qa/extras/xshape/data/reference/tdf90839-3.xml
+++ b/chart2/qa/extras/xshape/data/reference/tdf90839-3.xml
@@ -14,7 +14,7 @@
    <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
   </Transformation>
  </XShape>
- <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.GroupShape" name="CID/D=0">
+ <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.GroupShape" name="CID/D=0">
   <XShapes>
    <XShape positionX="9761" positionY="3821" sizeX="9721" sizeY="9721" 
type="com.sun.star.drawing.RectangleShape" name="MarkHandles" 
fontHeight="12.000000" fontColor="ffffffff" textAutoGrowHeight="true" 
textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" 
textHorizontalAdjust="CENTER" textVerticalAdjust="CENTER" textLeftDistance="0" 
textRightDistance="0" textUpperDistance="0" textLowerDistance="0" 
textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" 
textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" 
textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" 
textAnimationStartInside="false" textAnimationStopInside="false" 
textWritingMode="LR_TB" fillStyle="NONE" fillColor="729fcf" 
fillTransparence="0" fillTransparenceGradientName="">
     <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
@@ -30,7 +30,7 @@
      <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
     </Transformation>
    </XShape>
-   <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.RectangleShape" name="PlotAreaIncludingAxes" 
fontHeight="12.000000" fontColor="ffffffff" textAutoGrowHeight="true" 
textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" 
textHorizontalAdjust="CENTER" textVerticalAdjust="CENTER" textLeftDistance="0" 
textRightDistance="0" textUpperDistance="0" textLowerDistance="0" 
textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" 
textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" 
textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" 
textAnimationStartInside="false" textAnimationStopInside="false" 
textWritingMode="LR_TB" fillStyle="NONE" fillColor="729fcf" 
fillTransparence="0" fillTransparenceGradientName="">
+   <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.RectangleShape" name="PlotAreaIncludingAxes" 
fontHeight="12.000000" fontColor="ffffffff" textAutoGrowHeight="true" 
textAutoGrowWidth="false" textContourFrame="false" textFitToSize="NONE" 
textHorizontalAdjust="CENTER" textVerticalAdjust="CENTER" textLeftDistance="0" 
textRightDistance="0" textUpperDistance="0" textLowerDistance="0" 
textMaximumFrameHeight="0" textMaximumFrameWidth="0" textMinimumFrameHeight="0" 
textMinimumFrameWidth="0" textAnimationAmount="0" textAnimationCount="0" 
textAnimationDelay="0" textAnimationDirection="LEFT" textAnimationKind="NONE" 
textAnimationStartInside="false" textAnimationStopInside="false" 
textWritingMode="LR_TB" fillStyle="NONE" fillColor="729fcf" 
fillTransparence="0" fillTransparenceGradientName="">
     <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
     <FillGradient style="LINEAR" startColor="000000" endColor="ffffff" 
angle="0" border="0" xOffset="50" yOffset="50" startIntensity="100" 
endIntensity="100" stepCount="0"/>
     <FillHatch style="SINGLE" color="3465a4" distance="20" angle="0"/>
@@ -39,12 +39,12 @@
     <LineStart/>
     <LineEnd/>
     <Transformation>
-     <Line1 column1="22660.000000" column2="0.000000" column3="2509.000000"/>
+     <Line1 column1="22659.000000" column2="0.000000" column3="2509.000000"/>
      <Line2 column1="0.000000" column2="11142.000000" column3="2808.000000"/>
      <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
     </Transformation>
    </XShape>
-   <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
+   <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
     <XShapes>
      <XShape positionX="9761" positionY="3819" sizeX="9721" sizeY="9723" 
type="com.sun.star.drawing.GroupShape">
       <XShapes>
@@ -175,15 +175,15 @@
        <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
       </Transformation>
      </XShape>
-     <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
+     <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
       <XShapes>
-       <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
+       <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.GroupShape">
         <XShapes>
-         <XShape positionX="2509" positionY="2808" sizeX="22659" sizeY="11141" 
type="com.sun.star.drawing.GroupShape" 
name="CID/D=0:CS=0:CT=0:Series=0:DataLabels=">
+         <XShape positionX="2509" positionY="2808" sizeX="22658" sizeY="11141" 
type="com.sun.star.drawing.GroupShape" 
name="CID/D=0:CS=0:CT=0:Series=0:DataLabels=">
           <XShapes>
-           <XShape positionX="19461" positionY="9977" sizeX="5707" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=0">
+           <XShape positionX="19461" positionY="9977" sizeX="5706" 
sizeY="1747" type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=0">
             <XShapes>
-             <XShape positionX="19461" positionY="9977" sizeX="5707" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="Yellow - The color of 
sun and honey&#10;33%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="LEFT" textVerticalAdjust="TOP" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
+             <XShape positionX="19461" positionY="9977" sizeX="5706" 
sizeY="1747" type="com.sun.star.drawing.TextShape" text="Yellow - The color of 
sun and honey&#10;33%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="LEFT" textVerticalAdjust="TOP" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5929" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
               <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillGradient style="LINEAR" startColor="000000" 
endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillHatch style="SINGLE" color="3465a4" distance="20" 
angle="0"/>
@@ -192,14 +192,14 @@
               <LineStart/>
               <LineEnd/>
               <Transformation>
-               <Line1 column1="5708.000000" column2="0.000000" 
column3="19461.000000"/>
+               <Line1 column1="5707.000000" column2="0.000000" 
column3="19461.000000"/>
                <Line2 column1="0.000000" column2="1748.000000" 
column3="9977.000000"/>
                <Line3 column1="0.000000" column2="0.000000" 
column3="1.000000"/>
               </Transformation>
              </XShape>
             </XShapes>
             <Transformation>
-             <Line1 column1="5708.000000" column2="0.000000" 
column3="19461.000000"/>
+             <Line1 column1="5707.000000" column2="0.000000" 
column3="19461.000000"/>
              <Line2 column1="0.000000" column2="1748.000000" 
column3="9977.000000"/>
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
@@ -298,35 +298,35 @@
            </XShape>
           </XShapes>
           <Transformation>
-           <Line1 column1="22660.000000" column2="0.000000" 
column3="2509.000000"/>
+           <Line1 column1="22659.000000" column2="0.000000" 
column3="2509.000000"/>
            <Line2 column1="0.000000" column2="11142.000000" 
column3="2808.000000"/>
            <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
           </Transformation>
          </XShape>
         </XShapes>
         <Transformation>
-         <Line1 column1="22660.000000" column2="0.000000" 
column3="2509.000000"/>
+         <Line1 column1="22659.000000" column2="0.000000" 
column3="2509.000000"/>
          <Line2 column1="0.000000" column2="11142.000000" 
column3="2808.000000"/>
          <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
         </Transformation>
        </XShape>
       </XShapes>
       <Transformation>
-       <Line1 column1="22660.000000" column2="0.000000" column3="2509.000000"/>
+       <Line1 column1="22659.000000" column2="0.000000" column3="2509.000000"/>
        <Line2 column1="0.000000" column2="11142.000000" column3="2808.000000"/>
        <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
       </Transformation>
      </XShape>
     </XShapes>
     <Transformation>
-     <Line1 column1="22660.000000" column2="0.000000" column3="2509.000000"/>
+     <Line1 column1="22659.000000" column2="0.000000" column3="2509.000000"/>
      <Line2 column1="0.000000" column2="11142.000000" column3="2808.000000"/>
      <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
     </Transformation>
    </XShape>
   </XShapes>
   <Transformation>
-   <Line1 column1="22660.000000" column2="0.000000" column3="2509.000000"/>
+   <Line1 column1="22659.000000" column2="0.000000" column3="2509.000000"/>
    <Line2 column1="0.000000" column2="11142.000000" column3="2808.000000"/>
    <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
   </Transformation>
diff --git a/chart2/qa/extras/xshape/data/reference/tdf90839-4.xml 
b/chart2/qa/extras/xshape/data/reference/tdf90839-4.xml
index 79bd4392962e..198cf985e29b 100644
--- a/chart2/qa/extras/xshape/data/reference/tdf90839-4.xml
+++ b/chart2/qa/extras/xshape/data/reference/tdf90839-4.xml
@@ -250,9 +250,9 @@
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
            </XShape>
-           <XShape positionX="5188" positionY="2570" sizeX="4461" sizeY="2329" 
type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=3">
+           <XShape positionX="5189" positionY="2570" sizeX="4460" sizeY="2329" 
type="com.sun.star.drawing.GroupShape" 
name="CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=3">
             <XShapes>
-             <XShape positionX="5188" positionY="2570" sizeX="4461" 
sizeY="2329" type="com.sun.star.drawing.TextShape" text="Red - The color of 
rose and passion&#10;70&#10;19%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="RIGHT" textVerticalAdjust="BOTTOM" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5199" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
+             <XShape positionX="5189" positionY="2570" sizeX="4460" 
sizeY="2329" type="com.sun.star.drawing.TextShape" text="Red - The color of 
rose and passion&#10;70&#10;19%" fontHeight="12.000000" fontColor="595959" 
textAutoGrowHeight="true" textAutoGrowWidth="true" textContourFrame="false" 
textFitToSize="NONE" textHorizontalAdjust="RIGHT" textVerticalAdjust="BOTTOM" 
textLeftDistance="0" textRightDistance="0" textUpperDistance="0" 
textLowerDistance="0" textMaximumFrameHeight="0" textMaximumFrameWidth="5199" 
textMinimumFrameHeight="1" textMinimumFrameWidth="1" textAnimationAmount="0" 
textAnimationCount="0" textAnimationDelay="0" textAnimationDirection="LEFT" 
textAnimationKind="NONE" textAnimationStartInside="false" 
textAnimationStopInside="false" textWritingMode="LR_TB" fillStyle="NONE" 
fillColor="ffffff" fillTransparence="0" fillTransparenceGradientName="">
               <FillTransparenceGradient style="LINEAR" startColor="000000" 
endColor="000000" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillGradient style="LINEAR" startColor="000000" 
endColor="ffffff" angle="0" border="0" xOffset="50" yOffset="50" 
startIntensity="100" endIntensity="100" stepCount="0"/>
               <FillHatch style="SINGLE" color="3465a4" distance="20" 
angle="0"/>
@@ -261,14 +261,14 @@
               <LineStart/>
               <LineEnd/>
               <Transformation>
-               <Line1 column1="4462.000000" column2="0.000000" 
column3="5188.000000"/>
+               <Line1 column1="4461.000000" column2="0.000000" 
column3="5189.000000"/>
                <Line2 column1="0.000000" column2="2330.000000" 
column3="2570.000000"/>
                <Line3 column1="0.000000" column2="0.000000" 
column3="1.000000"/>
               </Transformation>
              </XShape>
             </XShapes>
             <Transformation>
-             <Line1 column1="4462.000000" column2="0.000000" 
column3="5188.000000"/>
+             <Line1 column1="4461.000000" column2="0.000000" 
column3="5189.000000"/>
              <Line2 column1="0.000000" column2="2330.000000" 
column3="2570.000000"/>
              <Line3 column1="0.000000" column2="0.000000" column3="1.000000"/>
             </Transformation>
diff --git a/cppcanvas/qa/unit/test.cxx b/cppcanvas/qa/unit/test.cxx
index ad278f10834b..8a2d6af2365b 100644
--- a/cppcanvas/qa/unit/test.cxx
+++ b/cppcanvas/qa/unit/test.cxx
@@ -129,8 +129,8 @@ CPPUNIT_TEST_FIXTURE(CanvasTest, testTdf155810)
         pDev->GetTextArray(aText, &aDXArray);
 
         auto nKashida = 200;
-        aDXArray.set(0, aDXArray[0] + nKashida);
-        aDXArray.set(2, aDXArray[2] + nKashida);
+        aDXArray[0] += nKashida;
+        aDXArray[2] += nKashida;
         aKashidaArray = { true, false, true, false };
 
         pDev->DrawTextArray(Point(0, 0), aText, aDXArray, aKashidaArray, 0, 
-1);
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx 
b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index e9f3bb56e7bc..4a81fb325682 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -991,15 +991,8 @@ namespace cppcanvas::internal
                     nStrikeoutWidth += nInterval;
                     KernArray aStrikeoutCharWidths;
 
-                    for ( int i = 0;i<nLen; i++)
-                    {
-                        aStrikeoutCharWidths.push_back(nStrikeoutWidth);
-                    }
-
-                    for ( int i = 1;i< nLen; i++ )
-                    {
-                        aStrikeoutCharWidths.adjust(i, aStrikeoutCharWidths[i 
- 1]);
-                    }
+                    for ( int i = 0;i< nLen; i++ )
+                        aStrikeoutCharWidths.push_back(nStrikeoutWidth * (i + 
1));
 
                     pStrikeoutTextAction =
                         TextActionFactory::createTextAction(
@@ -2566,7 +2559,7 @@ namespace cppcanvas::internal
                         rVDev.GetTextArray( pAct->GetText(), &aDXArray,
                                             pAct->GetIndex(), pAct->GetLen() );
 
-                        const sal_Int32 nWidthDifference( pAct->GetWidth() - 
aDXArray[ nLen-1 ] );
+                        const double nWidthDifferencePerDx = ( 
pAct->GetWidth() - aDXArray[ nLen-1 ] ) / nLen;
 
                         // Last entry of pDXArray contains total width of the 
text
                         for (sal_Int32 i = 1; i <= nLen; ++i)
@@ -2577,7 +2570,7 @@ namespace cppcanvas::internal
                             // entry represents the 'end' position of
                             // the corresponding character, thus, we
                             // let i run from 1 to nLen.
-                            aDXArray.adjust(i - 1, i * nWidthDifference / 
nLen);
+                            aDXArray[i - 1] += i * nWidthDifferencePerDx;
                         }
 
                         createTextAction(
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 3a1074fdc303..1594e2fd6e00 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2982,7 +2982,7 @@ void DesktopLOKTest::testTextSelectionHandles()
     CPPUNIT_ASSERT_EQUAL(aText, OString(pText));
     free(pText);
     CPPUNIT_ASSERT_EQUAL("1418, 1418, 0, 275"_ostr, m_aTextSelectionStart);
-    CPPUNIT_ASSERT_EQUAL("1898, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
+    CPPUNIT_ASSERT_EQUAL("1897, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
 
     // deselect & check
     m_aTextSelectionStart = ""_ostr;
@@ -3003,7 +3003,7 @@ void DesktopLOKTest::testTextSelectionHandles()
     CPPUNIT_ASSERT_EQUAL(aText, OString(pText));
     free(pText);
     CPPUNIT_ASSERT_EQUAL("1418, 1418, 0, 275"_ostr, m_aTextSelectionStart);
-    CPPUNIT_ASSERT_EQUAL("1898, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
+    CPPUNIT_ASSERT_EQUAL("1897, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
 }
 
 void DesktopLOKTest::testDialogPaste()
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx 
b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
index 67f1311a8010..ac51f8a9e458 100644
--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -274,13 +274,8 @@ void 
TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPoly
         OSL_ENSURE(nDXArrayCount == nTextLength,
                    "DXArray size does not correspond to text portion size 
(!)");
 
-        KernArray aIntegerDXArray;
-        aIntegerDXArray.reserve(nDXArrayCount);
-        for (sal_uInt32 a(0); a < nDXArrayCount; a++)
-            aIntegerDXArray.push_back(basegfx::fround(rDXArray[a]));
-
-        mrDevice.GetTextOutlines(rB2DPolyPolyVector, rText, nIndex, nIndex, 
nLength, 0,
-                                 aIntegerDXArray, rKashidaArray);
+        mrDevice.GetTextOutlines(rB2DPolyPolyVector, rText, nIndex, nIndex, 
nLength, 0, rDXArray,
+                                 rKashidaArray);
     }
     else
     {
@@ -374,8 +369,7 @@ TextLayouterDevice::getSalLayout(const OUString& rText, 
sal_uInt32 nIndex, sal_u
         SalLayoutGlyphsCache::self()->GetLayoutGlyphs(&mrDevice, rText, 
nIndex, nLength));
     const Point aStartPoint(basegfx::fround<tools::Long>(rStartPoint.getX()),
                             basegfx::fround<tools::Long>(rStartPoint.getY()));
-    KernArraySpan aKernArraySpan(rDXArray);
-    return mrDevice.ImplLayout(rText, nIndex, nLength, aStartPoint, 0, 
aKernArraySpan, pKashidaAry,
+    return mrDevice.ImplLayout(rText, nIndex, nLength, aStartPoint, 0, 
rDXArray, pKashidaAry,
                                SalLayoutFlags::NONE, nullptr, pGlyphs);
 }
 
diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textprimitive2d.cxx
index db9a6359ccf2..d08f729e3abf 100644
--- a/drawinglayer/source/primitive2d/textprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -353,22 +353,14 @@ void 
TextSimplePortionPrimitive2D::createTextLayouter(TextLayouterDevice& rTextL
 std::unique_ptr<SalLayout>
 TextSimplePortionPrimitive2D::createSalLayout(TextLayouterDevice& 
rTextLayouter) const
 {
-    // create integer DXArray. As mentioned above we can act in the
+    // As mentioned above we can act in the
     // Text's local coordinate system without transformation at all
     const ::std::vector<double>& rDXArray(getDXArray());
-    KernArray aDXArray;
-
-    if (!rDXArray.empty())
-    {
-        aDXArray.reserve(rDXArray.size());
-        for (auto const& elem : rDXArray)
-            aDXArray.push_back(basegfx::fround(elem));
-    }
 
     // create SalLayout. No need for a position, as mentioned text can work
     // without transformations, so start point is always 0,0
     return rTextLayouter.getSalLayout(getText(), getTextPosition(), 
getTextLength(),
-                                      basegfx::B2DPoint(0.0, 0.0), aDXArray, 
getKashidaArray());
+                                      basegfx::B2DPoint(0.0, 0.0), rDXArray, 
getKashidaArray());
 }
 
 // provide unique ID
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 2e3a7c08f7cf..73e3d8adbac9 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -309,7 +309,7 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
 
                 aDXArray.reserve(rTextCandidate.getDXArray().size());
                 for (auto const& elem : rTextCandidate.getDXArray())
-                    aDXArray.push_back(basegfx::fround(elem * 
fPixelVectorFactor));
+                    aDXArray.push_back(elem * fPixelVectorFactor);
             }
 
             // set parameters and paint text snippet
diff --git a/editeng/inc/EditLine.hxx b/editeng/inc/EditLine.hxx
index 46a2379853e6..38625bc246da 100644
--- a/editeng/inc/EditLine.hxx
+++ b/editeng/inc/EditLine.hxx
@@ -22,16 +22,14 @@
 #include <vector>
 #include <sal/types.h>
 #include <tools/gen.hxx>
+#include <vcl/kernarray.hxx>
 
 class ParaPortion;
 
 class EditLine
 {
-public:
-    typedef std::vector<sal_Int32> CharPosArrayType;
-
 private:
-    CharPosArrayType maPositions;
+    KernArray maPositions;
     std::vector<sal_Bool> maKashidaPositions;
     sal_Int32 mnTextWidth = 0;
     sal_Int32 mnStartPosX = 0;
@@ -111,8 +109,8 @@ public:
 
     bool IsEmpty() const { return mnEnd <= mnStart; }
 
-    CharPosArrayType& GetCharPosArray() { return maPositions; }
-    const CharPosArrayType& GetCharPosArray() const { return maPositions; }
+    KernArray& GetCharPosArray() { return maPositions; }
+    const KernArray& GetCharPosArray() const { return maPositions; }
 
     std::vector<sal_Bool>& GetKashidaArray() { return maKashidaPositions; }
     const std::vector<sal_Bool>& GetKashidaArray() const { return 
maKashidaPositions; }
diff --git a/editeng/inc/TextPortion.hxx b/editeng/inc/TextPortion.hxx
index e5560f260326..5458eaa9cf23 100644
--- a/editeng/inc/TextPortion.hxx
+++ b/editeng/inc/TextPortion.hxx
@@ -71,14 +71,14 @@ struct ExtraPortionInfo
     bool bFirstCharIsRightPunktuation = false;
     bool bCompressed = false;
 
-    std::unique_ptr<sal_Int32[]> pOrgDXArray;
+    std::unique_ptr<double[]> pOrgDXArray;
     std::vector<sal_Int32> lineBreaksList;
 
-    void SaveOrgDXArray(const sal_Int32* pDXArray, sal_Int32 nLen)
+    void SaveOrgDXArray(const double* pDXArray, sal_Int32 nLen)
     {
         if (pDXArray)
         {
-            pOrgDXArray.reset(new sal_Int32[nLen]);
+            pOrgDXArray.reset(new double[nLen]);
             memcpy(pOrgDXArray.get(), pDXArray, nLen * sizeof(sal_Int32));
         }
         else
diff --git a/editeng/inc/outleeng.hxx b/editeng/inc/outleeng.hxx
index c40837dc5f8f..56f7aa62485e 100644
--- a/editeng/inc/outleeng.hxx
+++ b/editeng/inc/outleeng.hxx
@@ -46,7 +46,7 @@ public:
     virtual void        ParagraphConnected( sal_Int32 nLeftParagraph, 
sal_Int32 nRightParagraph ) override;
 
     virtual void DrawingText( const Point& rStartPos, const OUString& rText, 
sal_Int32 nTextStart,
-                              sal_Int32 nTextLen, std::span<const sal_Int32> 
pDXArray,
+                              sal_Int32 nTextLen, KernArraySpan pDXArray,
                               std::span<const sal_Bool> pKashidaArray, const 
SvxFont& rFont,
                               sal_Int32 nPara, sal_uInt8 nRightToLeft,
                               const EEngineData::WrongSpellVector* 
pWrongSpellVector,
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 41b01c381250..4918ffb3aeb8 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -2140,12 +2140,12 @@ void Test::testCreateLines()
         CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rLine.GetStart());
         CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rLine.GetEnd());
 
-        std::vector<sal_Int32> const& rArray = rLine.GetCharPosArray();
+        KernArray const& rArray = rLine.GetCharPosArray();
         CPPUNIT_ASSERT_EQUAL(size_t(3), rArray.size());
 
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(173), rArray[0]);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(333), rArray[1]);
-        CPPUNIT_ASSERT_EQUAL(sal_Int32(493), rArray[2]);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(173), sal_Int32(rArray[0]));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(333), sal_Int32(rArray[1]));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(493), sal_Int32(rArray[2]));
     }
 
     {
diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index fec2c8cd3c99..bdb33166d00b 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1582,7 +1582,7 @@ EditEngine::CreateTransferable(const ESelection& 
rSelection)
 // ======================    Virtual Methods    ========================
 
 void EditEngine::DrawingText( const Point&, const OUString&, sal_Int32, 
sal_Int32,
-                              std::span<const sal_Int32>, std::span<const 
sal_Bool>,
+                              KernArraySpan, std::span<const sal_Bool>,
                               const SvxFont&, sal_Int32 /*nPara*/, sal_uInt8 
/*nRightToLeft*/,
                               const EEngineData::WrongSpellVector*, const 
SvxFieldData*, bool, bool,
                               const css::lang::Locale*, const Color&, const 
Color&)
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index 3387607c4c5b..856a53b792fe 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -758,7 +758,7 @@ private:
     bool                HasScriptType( sal_Int32 nPara, sal_uInt16 nType ) 
const;
 
     bool                ImplCalcAsianCompression( ContentNode* pNode, 
TextPortion* pTextPortion, sal_Int32 nStartPos,
-                                                sal_Int32* pDXArray, 
sal_uInt16 n100thPercentFromMax, bool bManipulateDXArray );
+                                                double* pDXArray, sal_uInt16 
n100thPercentFromMax, bool bManipulateDXArray );
     void                ImplExpandCompressedPortions(EditLine& rLine, 
ParaPortion& rParaPortion, tools::Long nRemainingWidth);
 
     void                ImplInitLayoutMode(OutputDevice& rOutDev, sal_Int32 
nPara, sal_Int32 nIndex);
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 2e4ac3102ae7..b59c40ca42f4 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -4439,7 +4439,7 @@ tools::Long ImpEditEngine::GetXPos(ParaPortion const& 
rParaPortion, EditLine con
                         if ( nType == AsianCompressionFlags::PunctuationRight 
&& !rLine.GetCharPosArray().empty() )
                         {
                             sal_Int32 n = nIndex - nTextPortionStart;
-                            const sal_Int32* pDXArray = 
rLine.GetCharPosArray().data() + (nTextPortionStart - rLine.GetStart());
+                            const double* pDXArray = 
rLine.GetCharPosArray().data() + (nTextPortionStart - rLine.GetStart());
                             sal_Int32 nCharWidth = ( ( (n+1) < 
rPortion.GetLen() ) ? pDXArray[n] : rPortion.GetSize().Width() )
                                                             - ( n ? 
pDXArray[n-1] : 0 );
                             if ( (n+1) < rPortion.GetLen() )
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index eeb6d3a0a175..ddbdb2176407 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -153,7 +153,7 @@ static void lcl_DrawRedLines( OutputDevice& rOutDev,
                               const Point& rPoint,
                               size_t nIndex,
                               size_t nMaxEnd,
-                              std::span<const sal_Int32> pDXArray,
+                              KernArraySpan pDXArray,
                               WrongList const * pWrongs,
                               Degree10 nOrientation,
                               const Point& rOrigin,
@@ -1051,7 +1051,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                             bEOL = true;
                             bBrokenLine = true;
                         }
-                        EditLine::CharPosArrayType& rArray = 
pLine->GetCharPosArray();
+                        KernArray& rArray = pLine->GetCharPosArray();
                         size_t nPos = nTmpPos - pLine->GetStart();
                         rArray.insert(rArray.begin()+nPos, 
pPortion->GetSize().Width());
                         bCompressedChars = false;
@@ -1065,7 +1065,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                         bLineBreak = true;
                         pPortion->SetKind( PortionKind::LINEBREAK );
                         bCompressedChars = false;
-                        EditLine::CharPosArrayType& rArray = 
pLine->GetCharPosArray();
+                        KernArray& rArray = pLine->GetCharPosArray();
                         size_t nPos = nTmpPos - pLine->GetStart();
                         rArray.insert(rArray.begin()+nPos, 
pPortion->GetSize().Width());
                     }
@@ -1179,7 +1179,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                             }
                         }
                         nTmpWidth += pPortion->GetSize().Width();
-                        EditLine::CharPosArrayType& rArray = 
pLine->GetCharPosArray();
+                        KernArray& rArray = pLine->GetCharPosArray();
                         size_t nPos = nTmpPos - pLine->GetStart();
                         rArray.insert(rArray.begin()+nPos, 
pPortion->GetSize().Width());
                         pPortion->SetKind(PortionKind::FIELD);
@@ -1233,15 +1233,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 // The array is  generally flattened at the beginning
                 // => Always simply quick inserts.
                 size_t nPos = nTmpPos - pLine->GetStart();
-                EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
-                assert(aCharPositionArray.get_factor() == 1);
-                std::vector<sal_Int32>& rKernArray = 
aCharPositionArray.get_subunit_array();
-                rArray.insert( rArray.begin() + nPos, rKernArray.data(), 
rKernArray.data() + nPortionLen);
+                KernArray& rArray = pLine->GetCharPosArray();
+                rArray.insert( rArray.begin() + nPos, 
aCharPositionArray.data(), aCharPositionArray.data() + nPortionLen);
 
                 // And now check for Compression:
                 if ( !bContinueLastPortion && nPortionLen && 
GetAsianCompressionMode() != CharCompressType::NONE )
                 {
-                    sal_Int32* pDXArray = rArray.data() + nTmpPos - 
pLine->GetStart();
+                    double* pDXArray = rArray.data() + nTmpPos - 
pLine->GetStart();
                     bCompressedChars |= ImplCalcAsianCompression(
                         pNode, pPortion, nTmpPos, pDXArray, 10000, false);
                 }
@@ -1435,7 +1433,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             if ( bCompressedChars && pPortion && ( pPortion->GetLen() > 1 ) && 
pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
             {
                 // I need the manipulated DXArray for determining the break 
position...
-                sal_Int32* pDXArray = pLine->GetCharPosArray().data() + 
(nPortionStart - pLine->GetStart());
+                double* pDXArray = pLine->GetCharPosArray().data() + 
(nPortionStart - pLine->GetStart());
                 ImplCalcAsianCompression(
                     pNode, pPortion, nPortionStart, pDXArray, 10000, true);
             }
@@ -1648,7 +1646,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
 
         // If a portion was wrapped there may be far too many positions in
         // CharPosArray:
-        EditLine::CharPosArrayType& rArray = pLine->GetCharPosArray();
+        KernArray& rArray = pLine->GetCharPosArray();
         size_t nLen = pLine->GetLen();
         if (rArray.size() > nLen)
             rArray.erase(rArray.begin()+nLen, rArray.end());
@@ -3477,7 +3475,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                 OUString aText;
                                 sal_Int32 nTextStart = 0;
                                 sal_Int32 nTextLen = 0;
-                                std::span<const sal_Int32> pDXArray;
+                                KernArraySpan pDXArray;
                                 std::span<const sal_Bool> pKashidaArray;
                                 KernArray aTmpDXArray;
 
@@ -3486,7 +3484,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                     aText = 
rParaPortion.GetNode()->GetString();
                                     nTextStart = nIndex;
                                     nTextLen = rTextPortion.GetLen();
-                                    pDXArray = 
std::span(pLine->GetCharPosArray().data() + (nIndex - pLine->GetStart()),
+                                    pDXArray = 
KernArraySpan(pLine->GetCharPosArray().data() + (nIndex - pLine->GetStart()),
                                                     
pLine->GetCharPosArray().size() - (nIndex - pLine->GetStart()));
 
                                     if (!pLine->GetKashidaArray().empty())
@@ -3647,9 +3645,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                     aTmpFont.SetPhysFont(*GetRefDevice());
                                     aTmpFont.QuickGetTextSize( GetRefDevice(), 
aText, nTextStart, nTextLen,
                                         &aTmpDXArray );
-                                    assert(aTmpDXArray.get_factor() == 1);
-                                    std::vector<sal_Int32>& rKernArray = 
aTmpDXArray.get_subunit_array();
-                                    pDXArray = rKernArray;
+                                    pDXArray = KernArraySpan(aTmpDXArray);
 
                                     // add a meta file comment if we record to 
a metafile
                                     if( bMetafileValid )
@@ -3676,9 +3672,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                     aTmpFont.SetPhysFont(*GetRefDevice());
                                     aTmpFont.QuickGetTextSize( GetRefDevice(), 
aText, 0, aText.getLength(),
                                         &aTmpDXArray );
-                                    assert(aTmpDXArray.get_factor() == 1);
-                                    std::vector<sal_Int32>& rKernArray = 
aTmpDXArray.get_subunit_array();
-                                    pDXArray = rKernArray;
+                                    pDXArray = aTmpDXArray;
                                 }
 
                                 tools::Long nTxtWidth = 
rTextPortion.GetSize().Width();
@@ -4792,7 +4786,7 @@ Color ImpEditEngine::GetAutoColor() const
 
 bool ImpEditEngine::ImplCalcAsianCompression(ContentNode* pNode,
                                              TextPortion* pTextPortion, 
sal_Int32 nStartPos,
-                                             sal_Int32* pDXArray, sal_uInt16 
n100thPercentFromMax,
+                                             double* pDXArray, sal_uInt16 
n100thPercentFromMax,
                                              bool bManipulateDXArray)
 {
     DBG_ASSERT( GetAsianCompressionMode() != CharCompressType::NONE, 
"ImplCalcAsianCompression - Why?" );
@@ -4960,7 +4954,7 @@ void 
ImpEditEngine::ImplExpandCompressedPortions(EditLine& rLine, ParaPortion& r
             sal_Int32 nTxtPortion = rParaPortion.GetTextPortions().GetPos( pTP 
);
             sal_Int32 nTxtPortionStart = 
rParaPortion.GetTextPortions().GetStartPos( nTxtPortion );
             DBG_ASSERT( nTxtPortionStart >= rLine.GetStart(), "Portion doesn't 
belong to the line!!!" );
-            sal_Int32* pDXArray = rLine.GetCharPosArray().data() + 
(nTxtPortionStart - rLine.GetStart());
+            double* pDXArray = rLine.GetCharPosArray().data() + 
(nTxtPortionStart - rLine.GetStart());
             if ( pTP->GetExtraInfos()->pOrgDXArray )
                 memcpy( pDXArray, pTP->GetExtraInfos()->pOrgDXArray.get(), 
(pTP->GetLen()-1)*sizeof(sal_Int32) );
             ImplCalcAsianCompression( rParaPortion.GetNode(), pTP, 
nTxtPortionStart, pDXArray, static_cast<sal_uInt16>(nCompressPercent), true );
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx
index 3bd2c8086c07..ea8c6523f703 100644
--- a/editeng/source/items/svxfont.cxx
+++ b/editeng/source/items/svxfont.cxx
@@ -480,10 +480,10 @@ Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, 
const OUString &rTxt,
 
     if( IsFixKerning() && ( nLen > 1 ) && !bStacked)
     {
-        auto nKern = GetFixKerning();
-        tools::Long nOldValue = (*pDXArray)[0];
+        short nKern = GetFixKerning();
+        double nOldValue = (*pDXArray)[0];
         tools::Long nSpaceSum = nKern;
-        pDXArray->adjust(0, nSpaceSum);
+        (*pDXArray)[0] += nSpaceSum;
 
         for ( sal_Int32 i = 1; i < nLen; i++ )
         {
@@ -492,14 +492,14 @@ Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, 
const OUString &rTxt,
                 nOldValue = (*pDXArray)[i];
                 nSpaceSum += nKern;
             }
-            pDXArray->adjust(i, nSpaceSum);
+            (*pDXArray)[i] += nSpaceSum;
         }
 
         // The last one is a nKern too big:
         nOldValue = (*pDXArray)[nLen - 1];
-        tools::Long nNewValue = nOldValue - nKern;
+        double nNewValue = nOldValue - nKern;
         for ( sal_Int32 i = nLen - 1; i >= 0 && (*pDXArray)[i] == nOldValue; 
--i)
-            pDXArray->set(i, nNewValue);
+            (*pDXArray)[i] = nNewValue;
 
         aTxtSize.AdjustWidth(nSpaceSum - nKern);
     }
@@ -525,7 +525,7 @@ Size SvxFont::GetTextSize(const OutputDevice& rOut, const 
OUString &rTxt,
 }
 
 static void DrawTextArray( OutputDevice* pOut, const Point& rStartPt, const 
OUString& rStr,
-                           std::span<const sal_Int32> pDXAry,
+                           KernArraySpan pDXAry,
                            std::span<const sal_Bool> pKashidaAry,
                            sal_Int32 nIndex, sal_Int32 nLen )
 {
@@ -536,7 +536,7 @@ static void DrawTextArray( OutputDevice* pOut, const Point& 
rStartPt, const OUSt
 void SvxFont::QuickDrawText( OutputDevice *pOut,
     const Point &rPos, const OUString &rTxt,
     const sal_Int32 nIdx, const sal_Int32 nLen,
-    std::span<const sal_Int32> pDXArray,
+    KernArraySpan pDXArray,
     std::span<const sal_Bool> pKashidaArray) const
 {
 
@@ -728,14 +728,11 @@ void SvxDoGetCapitalSize::Do( const OUString &_rTxt, 
const sal_Int32 _nIdx,
         KernArray aKernArray;
         aPartSize.setWidth(basegfx::fround<tools::Long>(
             pOut->GetTextArray(_rTxt, &aKernArray, _nIdx, _nLen).nWidth));
-        assert(pDXAry->get_factor() == aKernArray.get_factor());
-        auto& dest = pDXAry->get_subunit_array();
-        sal_Int32 nStart = dest.empty() ? 0 : dest.back();
+        double nStart = pDXAry->empty() ? 0 : pDXAry->back();
         size_t nSrcLen = aKernArray.size();
-        dest.reserve(dest.size() + nSrcLen);
-        const auto& src = aKernArray.get_subunit_array();
+        pDXAry->reserve(pDXAry->size() + nSrcLen);
         for (size_t i = 0; i < nSrcLen; ++i)
-            dest.push_back(src[i] + nStart);
+            (*pDXAry).push_back(aKernArray[i] + nStart);
     }
     else
     {
@@ -782,11 +779,11 @@ protected:
     Point aPos;
     Point aSpacePos;
     short nKern;
-    std::span<const sal_Int32> pDXArray;
+    KernArraySpan pDXArray;
     std::span<const sal_Bool> pKashidaArray;
 public:
     SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString 
&_rTxt,
-                      std::span<const sal_Int32> _pDXArray,
+                      KernArraySpan _pDXArray,
                       std::span<const sal_Bool> _pKashidaArray,
                       const sal_Int32 _nIdx, const sal_Int32 _nLen,
                       const Point &rPos, const short nKrn )
@@ -872,10 +869,10 @@ void SvxDoDrawCapital::Do( const OUString &_rTxt, const 
sal_Int32 nSpanIdx,
 
         Point aStartPos(aPos.X() + nStartX, aPos.Y());
 
-        std::vector<sal_Int32> aDXArray;
-        aDXArray.reserve(nSpanLen);
+        KernArray aDXArray;
+        aDXArray.resize(nSpanLen);
         for (sal_Int32 i = 0; i < nSpanLen; ++i)
-            aDXArray.push_back(pDXArray[nStartOffset + i] - nStartX);
+            aDXArray[i] = pDXArray[nStartOffset + i] - nStartX;
 
         auto aKashidaArray = !pKashidaArray.empty() ?
             std::span<const sal_Bool>(pKashidaArray.data() + nStartOffset, 
nSpanLen) :
@@ -901,7 +898,7 @@ void SvxDoDrawCapital::Do( const OUString &_rTxt, const 
sal_Int32 nSpanIdx,
 
 void SvxFont::DrawCapital( OutputDevice *pOut,
                const Point &rPos, const OUString &rTxt,
-               std::span<const sal_Int32> pDXArray,
+               KernArraySpan pDXArray,
                std::span<const sal_Bool> pKashidaArray,
                const sal_Int32 nIdx, const sal_Int32 nLen ) const
 {
diff --git a/editeng/source/outliner/outleeng.cxx 
b/editeng/source/outliner/outleeng.cxx
index 6ad8d267ed19..67fcd0c4bd93 100644
--- a/editeng/source/outliner/outleeng.cxx
+++ b/editeng/source/outliner/outleeng.cxx
@@ -151,7 +151,7 @@ OUString OutlinerEditEng::GetUndoComment( sal_uInt16 
nUndoId ) const
 }
 
 void OutlinerEditEng::DrawingText( const Point& rStartPos, const OUString& 
rText, sal_Int32 nTextStart, sal_Int32 nTextLen,
-                                   std::span<const sal_Int32> pDXArray, 
std::span<const sal_Bool> pKashidaArray,
+                                   KernArraySpan pDXArray, std::span<const 
sal_Bool> pKashidaArray,
                                    const SvxFont& rFont, sal_Int32 nPara, 
sal_uInt8 nRightToLeft,
                                    const EEngineData::WrongSpellVector* 
pWrongSpellVector,
                                    const SvxFieldData* pFieldData,
diff --git a/editeng/source/outliner/outliner.cxx 
b/editeng/source/outliner/outliner.cxx
index 718e7f42aea8..1a5ad1e0cbdd 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -967,8 +967,7 @@ void Outliner::PaintBullet(sal_Int32 nPara, const Point& 
rStartPos, const Point&
                     aTextPos.AdjustY( -(aMetric.GetDescent()) );
                 }
 
-                assert(aBuf.get_factor() == 1);
-                DrawingText(aTextPos, pPara->GetText(), 0, 
pPara->GetText().getLength(), aBuf.get_subunit_array(), {},
+                DrawingText(aTextPos, pPara->GetText(), 0, 
pPara->GetText().getLength(), aBuf, {},
                     aSvxFont, nPara, bRightToLeftPara ? 1 : 0, nullptr, 
nullptr, false, false, true, nullptr, Color(), Color());
             }
             else
@@ -1644,7 +1643,7 @@ void Outliner::StripPortions()
 }
 
 void Outliner::DrawingText( const Point& rStartPos, const OUString& rText, 
sal_Int32 nTextStart,
-                            sal_Int32 nTextLen, std::span<const sal_Int32> 
pDXArray,
+                            sal_Int32 nTextLen, std::span<const double> 
pDXArray,
                             std::span<const sal_Bool> pKashidaArray, const 
SvxFont& rFont,
                             sal_Int32 nPara, sal_uInt8 nRightToLeft,
                             const EEngineData::WrongSpellVector* 
pWrongSpellVector,
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx 
b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 30955bdb8973..1c4378c7bc42 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -1399,7 +1399,7 @@ CPPUNIT_TEST_FIXTURE(Test, testExtTextOutOpaqueAndClipWMF)
 
     assertXPath(pDocument, aPrefix + "group[3]/mask/group/polypolygoncolor", 
"color", u"#ff8000");
     assertXPath(pDocument, aPrefix + 
"group[3]/mask/group/polypolygoncolor/polypolygon", "path",
-                u"m1067 1067h1317v473h-1317z");
+                u"m1067 1067h1317.12890625v473h-1317.12890625z");
     assertXPath(pDocument, aPrefix + "group[3]/mask/group/textsimpleportion", 
"text", u"OOOO");
     assertXPath(pDocument, aPrefix + "group[3]/mask/group/textsimpleportion", 
"fontcolor",
                 u"#000000");
diff --git a/emfio/source/reader/emfreader.cxx 
b/emfio/source/reader/emfreader.cxx
index ff179d7ed2a0..9cdbeedda898 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -1962,7 +1962,7 @@ namespace emfio
                                             }
                                         }
 
-                                        aDXAry.set(i, 0);
+                                        aDXAry[i] = 0;
                                         if (nOptions & ETO_PDY)
                                         {
                                             pDYAry[i] = 0;
@@ -1972,7 +1972,7 @@ namespace emfio
                                         {
                                             sal_Int32 nDxTmp = 0;
                                             mpInputStream->ReadInt32(nDxTmp);
-                                            aDXAry.set(i, 
o3tl::saturating_add(aDXAry[i], nDxTmp));
+                                            aDXAry[i] += nDxTmp;
                                             if (nOptions & ETO_PDY)
                                             {
                                                 sal_Int32 nDyTmp = 0;
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index f12e6e92b17d..7ce4cd0fd559 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -1681,7 +1681,7 @@ namespace emfio
                 // #i121382# Map DXArray using WorldTransform
                 const Size aSizeX(ImplMap(Size(nSumX, 0)));
                 const basegfx::B2DVector aVectorX(aSizeX.Width(), 
aSizeX.Height());
-                pDXArry->set(i, basegfx::fround(aVectorX.getLength()) * (nSumX 
>= 0 ? 1 : -1));
+                (*pDXArry)[i] = aVectorX.getLength() * (nSumX >= 0 ? 1 : -1);
 
                 if (pDYArry)
                 {
diff --git a/emfio/source/reader/wmfreader.cxx 
b/emfio/source/reader/wmfreader.cxx
index 414218c717bb..5c16df6e42b2 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -805,7 +805,7 @@ namespace emfio
                                     }
                                 }
 
-                                aDXAry.set(i, nDx);
+                                aDXAry[i] = nDx;
                                 if ( nOptions & ETO_PDY )
                                 {
                                     pDYAry[i] = nDy;
@@ -1303,7 +1303,7 @@ namespace emfio
                                                     {
                                                         sal_Int32 val;
                                                         
aMemoryStream.ReadInt32(val);
-                                                        aDXAry.set(i, val);
+                                                        aDXAry[i] = val;
                                                     }
                                                     
aMemoryStream.ReadUInt32(mnSkipActions);
                                                     DrawText(aPt, aString,
diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index c3aa21599512..3b58d330e001 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -2724,7 +2724,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, 
const OUString& rText,
     if( !pDXArray.empty() )
     {
         aNormSize = Size( mpVDev->GetTextWidth( rText ), 0 );
-        aTmpArray.assign(pDXArray);
+        aTmpArray.assign(pDXArray.begin(), pDXArray.end());
     }
     else
     {
@@ -2786,7 +2786,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, basegfx::fround(aTmpArray[i] * fFactor));
+                    aTmpArray[i] *= fFactor;
             }
             else
             {
diff --git a/include/drawinglayer/primitive2d/textlayoutdevice.hxx 
b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
index 5eb70003d0d4..7aacceeef7fd 100644
--- a/include/drawinglayer/primitive2d/textlayoutdevice.hxx
+++ b/include/drawinglayer/primitive2d/textlayoutdevice.hxx
@@ -25,6 +25,7 @@
 #include <drawinglayer/primitive2d/textenumsprimitive2d.hxx>
 #include <vector>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/kernarray.hxx>
 #include <vcl/svapp.hxx>
 #include <tools/fontenum.hxx>
 #include <span>
@@ -34,7 +35,6 @@ class VirtualDevice;
 class GDIMetaFile;
 enum class DrawTextFlags;
 class SalLayout;
-class KernArray;
 namespace vcl
 {
 class Font;
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index c981c332a855..1fa3d17409cd 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -47,6 +47,7 @@
 #include <editeng/eedata.hxx>
 #include <o3tl/typed_flags_set.hxx>
 #include <svl/languageoptions.hxx>
+#include <vcl/kernarray.hxx>
 #include <comphelper/errcode.hxx>
 #include <functional>
 
@@ -498,7 +499,7 @@ public:
 
     virtual void DrawingText( const Point& rStartPos, const OUString& rText,
                               sal_Int32 nTextStart, sal_Int32 nTextLen,
-                              std::span<const sal_Int32> pDXArray,
+                              KernArraySpan pDXArray,
                               std::span<const sal_Bool> pKashidaArray,
                               const SvxFont& rFont,
                               sal_Int32 nPara, sal_uInt8 nRightToLeft,
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 8c217b22247b..8c69eaf77719 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -407,7 +407,7 @@ public:
     sal_Int32           mnTextLen;
     sal_Int32           mnPara;
     const SvxFont&      mrFont;
-    std::span<const sal_Int32> mpDXArray;
+    KernArraySpan mpDXArray;
     std::span<const sal_Bool> mpKashidaArray;
 
     const EEngineData::WrongSpellVector*  mpWrongSpellVector;
@@ -431,7 +431,7 @@ public:
         sal_Int32 nTxtLen,
         const SvxFont& rFnt,
         sal_Int32 nPar,
-        std::span<const sal_Int32> pDXArr,
+        KernArraySpan pDXArr,
         std::span<const sal_Bool> pKashidaArr,
         const EEngineData::WrongSpellVector* pWrongSpellVector,
         const SvxFieldData* pFieldData,
@@ -824,7 +824,7 @@ public:
 
     SAL_DLLPRIVATE void DrawingText( const Point& rStartPos, const OUString& 
rText,
                               sal_Int32 nTextStart, sal_Int32 nTextLen,
-                              std::span<const sal_Int32> pDXArray,
+                              KernArraySpan pDXArray,
                               std::span<const sal_Bool> pKashidaArray,
                               const SvxFont& rFont,
                               sal_Int32 nPara, sal_uInt8 nRightToLeft,
diff --git a/include/editeng/svxfont.hxx b/include/editeng/svxfont.hxx
index 9061ffe398d2..a696e6c78084 100644
--- a/include/editeng/svxfont.hxx
+++ b/include/editeng/svxfont.hxx
@@ -26,6 +26,7 @@
 #include <editeng/svxenum.hxx>
 #include <tools/long.hxx>
 #include <vcl/font.hxx>
+#include <vcl/kernarray.hxx>
 #include <editeng/editengdllapi.h>
 #include <tools/poly.hxx>
 
@@ -33,7 +34,6 @@
 // See i#1526# for full explanation
 #define SMALL_CAPS_PERCENTAGE 80
 
-class KernArray;
 class SvxDoCapitals;
 class OutputDevice;
 class Printer;
@@ -82,7 +82,7 @@ public:
     Size GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, 
KernArray* pDXAry,
                           const sal_Int32 nIdx, const sal_Int32 nLen) const;
     void DrawCapital( OutputDevice *pOut, const Point &rPos, const OUString 
&rTxt,
-                      std::span<const sal_Int32> pDXArray,
+                      KernArraySpan pDXArray,
                       std::span<const sal_Bool> pKashidaArray,
                       const sal_Int32 nIdx, const sal_Int32 nLen ) const;
 
@@ -96,7 +96,7 @@ public:
 
     void QuickDrawText( OutputDevice *pOut, const Point &rPos, const OUString 
&rTxt,
                         const sal_Int32 nIdx = 0, const sal_Int32 nLen = 
SAL_MAX_INT32,
-                        std::span<const sal_Int32> pDXArray = {},
+                        KernArraySpan pDXArray = {},
                         std::span<const sal_Bool> pKashidaArray = {} ) const;
 
     Size QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt,
diff --git a/include/vcl/kernarray.hxx b/include/vcl/kernarray.hxx
index e9e5462faf95..43b6647524b7 100644
--- a/include/vcl/kernarray.hxx
+++ b/include/vcl/kernarray.hxx
@@ -10,99 +10,10 @@
 
 #include <sal/config.h>
 
-#include <sal/types.h>
-#include <cmath>
 #include <span>
 #include <vector>
 
-class KernArraySpan final
-{
-private:
-    int m_nSubUnitFactor;
-    std::span<const sal_Int32> m_DXArray;
-
-public:
-    KernArraySpan()
-        : m_nSubUnitFactor(1)
-    {
-    }
-
-    KernArraySpan(std::span<const sal_Int32> DXArray, int nSubUnitFactor = 1)
-        : m_nSubUnitFactor(nSubUnitFactor)
-        , m_DXArray(DXArray)
-    {
-    }
-    size_t size() const { return m_DXArray.size(); }
-    bool empty() const { return m_DXArray.empty(); }
-    sal_Int32 operator[](size_t nIndex) const { return get(nIndex); }
-    sal_Int32 get(size_t nIndex) const
-    {
-        return std::round(static_cast<double>(m_DXArray[nIndex]) / 
m_nSubUnitFactor);
-    }
-
-    int get_factor() const { return m_nSubUnitFactor; }
-    sal_Int32 get_subunit(size_t nIndex) const { return m_DXArray[nIndex]; }
-};
-
-class KernArray final
-{
-private:
-    int m_nSubUnitFactor;
-    std::vector<sal_Int32> m_aDXArray;
-
-public:
-    KernArray(int nSubUnitFactor = 1)
-        : m_nSubUnitFactor(nSubUnitFactor)
-    {
-    }
-
-    sal_Int32 operator[](size_t nIndex) const { return get(nIndex); }
-    sal_Int32 get(size_t nIndex) const
-    {
-        return std::round(static_cast<double>(m_aDXArray[nIndex]) / 
m_nSubUnitFactor);
-    }
-
-    int get_factor() const { return m_nSubUnitFactor; }
-    sal_Int32 get_subunit(size_t nIndex) const { return m_aDXArray[nIndex]; }
-
-    void set_subunit(size_t nIndex, sal_Int32 nValue) { m_aDXArray[nIndex] = 
nValue; }
-    std::vector<sal_Int32>& get_subunit_array() { return m_aDXArray; }
-
-    void adjust(size_t nIndex, sal_Int32 nDiff) { m_aDXArray[nIndex] += nDiff 
* m_nSubUnitFactor; }
-    void set(size_t nIndex, sal_Int32 nValue) { m_aDXArray[nIndex] = nValue * 
m_nSubUnitFactor; }
-    void push_back(sal_Int32 nUnit) { m_aDXArray.push_back(nUnit * 
m_nSubUnitFactor); }
-    sal_Int32 back() const { return m_aDXArray.back() * m_nSubUnitFactor; }
-    size_t size() const { return m_aDXArray.size(); }
-    bool empty() const { return m_aDXArray.empty(); }
-    void clear() { m_aDXArray.clear(); }
-    void assign(KernArraySpan other)
-    {
-        m_nSubUnitFactor = other.get_factor();
-        m_aDXArray.clear();
-        size_t nLen = other.size();
-        m_aDXArray.reserve(nLen);
-        for (size_t i = 0; i < nLen; ++i)
-            m_aDXArray.push_back(other.get_subunit(i));
-    }
-    void resize(size_t nSize) { m_aDXArray.resize(nSize); }
-    void resize(size_t nSize, sal_Int32 nDefault)
-    {
-        m_aDXArray.resize(nSize, nDefault * m_nSubUnitFactor);
-    }
-    void reserve(size_t nCapacity) { m_aDXArray.reserve(nCapacity); }
-
-    bool operator==(const KernArray& rOther) const
-    {
-        size_t nSize = size();
-        if (nSize != rOther.size())
-            return false;
-        for (size_t i = 0; i < nSize; ++i)
-            if (m_aDXArray[i] != rOther.m_aDXArray[i])
-                return false;
-        return true;
-    }
-
-    operator KernArraySpan() const { return KernArraySpan(m_aDXArray, 
m_nSubUnitFactor); }
-};
+using KernArraySpan = std::span<const double>;
+using KernArray = std::vector<double>;
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index ee0709594caf..0f6302b5ba3b 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -2193,7 +2193,7 @@ void ScOutputData::LayoutStrings(bool bPixelToLogic)
                                 {
                                     double fMul = GetStretch();
                                     for (size_t i = 0; i < nLen; ++i)
-                                        aDX.set(i, 
static_cast<sal_Int32>(aDX[i] / fMul + 0.5));
+                                        aDX[i] /= fMul;
                                 }
 
                                 mpDev->DrawTextArray(aDrawTextPos, aShort, 
aDX, {}, 0, nLen);
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index f26876ab8d4d..8e3e19cdb3a2 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -393,9 +393,9 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, 
testTdf152906_AdjustToContour)
 
     // index, length, x, y
     const std::tuple<int, int, int, int> strings[] = {
-        { 0, 6, 9599, 8647 }, //                        Lorem
+        { 0, 6, 9600, 8647 }, //                        Lorem
         { 6, 22, 7570, 9358 }, //               ipsum dolor sit amet,
-        { 28, 29, 6775, 10069 }, //         consectetur adipiscing elit.
+        { 28, 29, 6776, 10069 }, //         consectetur adipiscing elit.
         { 57, 29, 6299, 10780 }, //         Vestibulum consequat mi quis
         { 86, 37, 5453, 11491 }, //     pretium semper. Proin luctus orci ac
         { 123, 36, 5134, 12202 }, //     neque venenatis, quis commodo dolor
@@ -404,7 +404,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, 
testTdf152906_AdjustToContour)
         { 243, 40, 4975, 14335 }, //   nec pellentesque eros molestie eget. In
         { 283, 42, 4552, 15046 }, //  consectetur aliquam hendrerit. Sed cursus
         { 325, 38, 5363, 15757 }, //    mauris vitae ligula pellentesque, non
-        { 363, 42, 4692, 16468 }, //  pellentesque urna aliquet. Fusce placerat
+        { 363, 42, 4693, 16468 }, //  pellentesque urna aliquet. Fusce placerat
         { 405, 37, 5047, 17179 }, //    mauris enim, nec rutrum purus semper
         { 442, 33, 5963, 17890 }, //      vel. Praesent tincidunt neque eu
         { 475, 29, 6387, 18601 }, //        pellentesque pharetra. Fusce
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx 
b/svx/source/svdraw/svdotextdecomposition.cxx
index e228471b3433..2c04df143f8e 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -191,14 +191,14 @@ namespace
             }
 
             sal_Int32 nStartOffset = nSpanIdx - nIdx;
-            sal_Int32 nStartX = nStartOffset ? m_rInfo.mpDXArray[nStartOffset 
- 1] : 0;
+            double nStartX = nStartOffset ? m_rInfo.mpDXArray[nStartOffset - 
1] : 0;
 
             Point aStartPos(m_rInfo.mrStartPos.X() + nStartX, 
m_rInfo.mrStartPos.Y());
 
-            std::vector<sal_Int32> aDXArray;
-            aDXArray.reserve(nSpanLen);
+            KernArray aDXArray;
+            aDXArray.resize(nSpanLen);
             for (sal_Int32 i = 0; i < nSpanLen; ++i)
-                aDXArray.push_back(m_rInfo.mpDXArray[nStartOffset + i] - 
nStartX);
+                aDXArray[i] = m_rInfo.mpDXArray[nStartOffset + i] - nStartX;
 
             auto aKashidaArray = !m_rInfo.mpKashidaArray.empty() ?
                 std::span<const sal_Bool>(m_rInfo.mpKashidaArray.data() + 
nStartOffset, nSpanLen) :
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 40bdcca07b5f..6dc3e933a2dc 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -1623,9 +1623,9 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf129810)
             CPPUNIT_ASSERT_EQUAL(size_t(14), pDXArray.size());
 
             // Assert we are using the expected width for uncompressed chars
-            CPPUNIT_ASSERT_EQUAL(sal_Int32(720), pDXArray[0]);
+            CPPUNIT_ASSERT_EQUAL(sal_Int32(720), sal_Int32(pDXArray[0]));
             // Assert we are using the expected width for compressed chars
-            CPPUNIT_ASSERT_EQUAL(sal_Int32(500), pDXArray[6] - pDXArray[5]);
+            CPPUNIT_ASSERT_EQUAL(sal_Int32(500), sal_Int32(pDXArray[6] - 
pDXArray[5]));
             break;
         }
     }
diff --git a/sw/qa/core/txtnode/justify.cxx b/sw/qa/core/txtnode/justify.cxx
index 98b81babd8ff..495c3037a062 100644
--- a/sw/qa/core/txtnode/justify.cxx
+++ b/sw/qa/core/txtnode/justify.cxx
@@ -56,13 +56,13 @@ std::ostream& operator<<(std::ostream& rStrm, const 
CharWidthArray& rCharWidthAr
 void CharWidthArray::ConvertToKernArray()
 {
     for (std::size_t i = 1; i < maArray.size(); ++i)
-        maArray.adjust(i, maArray[i - 1]);
+        maArray[i] += maArray[i - 1];
 }
 
 void CharWidthArray::ConvertToCharWidths()
 {
     for (sal_Int32 i = maArray.size() - 1; i > 0; --i)
-        maArray.adjust(i, -maArray[i - 1]);
+        maArray[i] -= maArray[i - 1];
 }
 
 /// Convert maArray to kern array values, then invoke the function, and 
convert it back.
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index 7fd080b043e2..ebec9da48e4f 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -446,7 +446,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf161810)
 
             // Assert we are using the expected position for the last char
             // This was 9369, now 9165, according to the fixed space shrinking
-            CPPUNIT_ASSERT_LESS(sal_Int32(9300), pDXArray[72]);
+            CPPUNIT_ASSERT_LESS(sal_Int32(9300), sal_Int32(pDXArray[72]));
             break;
         }
     }
@@ -491,7 +491,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf163149)
 
             // Assert we are using the expected position for the last char
             // This was 4673, now 4163, according to the fixed space shrinking
-            CPPUNIT_ASSERT_LESS(sal_Int32(4200), pDXArray[45]);
+            CPPUNIT_ASSERT_LESS(sal_Int32(4200), sal_Int32(pDXArray[45]));
             break;
         }
     }
@@ -920,7 +920,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 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", u"428");
+                "width", u"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/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index eb7502025b15..fec4a17c269e 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -3389,7 +3389,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testDropDownFormFieldButton)
         CPPUNIT_ASSERT_EQUAL("drop-down"_ostr, sType);
 
         OString sTextArea( 
aTree.get_child("textArea").get_value<std::string>() );
-        CPPUNIT_ASSERT_EQUAL("1538, 1418, 1026, 275"_ostr, sTextArea);
+        CPPUNIT_ASSERT_EQUAL("1538, 1418, 1025, 275"_ostr, sTextArea);
 
         boost::property_tree::ptree aItems = 
aTree.get_child("params").get_child("items");
         CPPUNIT_ASSERT_EQUAL(size_t(6), aItems.size());
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 9f0fd502114f..99e00aa071df 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -2141,8 +2141,8 @@ tools::Long SwScriptInfo::Compress(KernArray& rKernArray, 
TextFrameIndex nIdx, T
                 nSub -= nLast;
                 nLast = rKernArray[ nI ];
                 if( nI && nMove )
-                    rKernArray.adjust(nI - 1, nMove);
-                rKernArray.adjust(nI, -nSub);
+                    rKernArray[nI - 1] += nMove;
+                rKernArray[nI] += -nSub;
                 ++nI;
                 ++nIdx;
             }
@@ -2163,7 +2163,7 @@ tools::Long SwScriptInfo::Compress(KernArray& rKernArray, 
TextFrameIndex nIdx, T
         while( nIdx < nTmpChg )
         {
             nLast = rKernArray[ nI ];
-            rKernArray.adjust(nI, -nSub);
+            rKernArray[nI] += -nSub;
             ++nI;
             ++nIdx;
         }
@@ -2251,7 +2251,7 @@ sal_Int32 SwScriptInfo::KashidaJustify( KernArray* 
pKernArray,
 
             while ( nArrayPos < nArrayEnd )
             {
-                pKernArray->adjust(sal_Int32(nArrayPos), nKashAdd);
+                (*pKernArray)[sal_Int32(nArrayPos)] += nKashAdd;
                 ++nArrayPos;
             }
             nKashAdd += nSpaceAdd;
@@ -2496,7 +2496,7 @@ TextFrameIndex SwScriptInfo::ThaiJustify( 
std::u16string_view aText, KernArray*
         }
 
         if (pKernArray)
-            pKernArray->adjust(nI, nSpaceSum);
+            (*pKernArray)[nI] += nSpaceSum;
     }
 
     return nCnt;
@@ -2877,7 +2877,7 @@ void SwScriptInfo::CJKJustify( const OUString& rText, 
KernArray& rKernArray,
             if (nNext < sal_Int32(nStt + nLen) || !bIsSpaceStop)
                 nSpaceSum += nSpaceAdd;
         }
-        rKernArray.adjust(nI, nSpaceSum);
+        rKernArray[nI] += nSpaceSum;
     }
 }
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/fntcache.cxx 
b/sw/source/core/txtnode/fntcache.cxx
index 3ae9456e62d8..9d8b678b9681 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -1108,7 +1108,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                 tools::Long nSum = nDiff;
                 for( sal_Int32 i = 0; i < nZwi; )
                 {
-                    aKernArray.adjust(i, nSum);
+                    aKernArray[i] += nSum;
                     if( ++i == nRest )
                         nDiff += nAdd;
                     nSum += nDiff;
@@ -1202,7 +1202,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                 {
                     if (CH_BLANK == rInf.GetText()[sal_Int32(rInf.GetIdx()) + 
i])
                         nKernSum += nSpaceAdd;
-                    aKernArray.adjust(i, nKernSum);
+                    aKernArray[i] += nKernSum;
                 }
 
                 // In case of underlined/strike-through justified text
@@ -1213,14 +1213,14 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                     // If it is a single underlined space, output 2 spaces:
                     if (TextFrameIndex(1) == rInf.GetLen())
                     {
-                        aKernArray.set(0, rInf.GetWidth() + nSpaceAdd);
+                        aKernArray[0] = rInf.GetWidth() + nSpaceAdd;
                         rInf.GetOut().DrawTextArray( aTextOriginPos, 
rInf.GetText(),
                              aKernArray, aKashidaArray, 
sal_Int32(rInf.GetIdx()), 1 );
                     }
                     else
                     {
                         sal_Int32 nIndex(sal_Int32(rInf.GetLen()) - 2);
-                        aKernArray.adjust(nIndex, nSpaceAdd);
+                        aKernArray[nIndex] += nSpaceAdd;
                         DrawTextArray(rInf.GetOut(), aTextOriginPos, 
rInf.GetText(), aKernArray,
                                       aKashidaArray, sal_Int32{ rInf.GetIdx() 
},
                                       sal_Int32{ rInf.GetLen() }, 
rInf.GetLayoutContext());
@@ -1455,9 +1455,9 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
         // have to output 2 spaces:
         if ((nCnt == TextFrameIndex(1)) && rInf.GetSpace() && (cChPrev == 
CH_BLANK))
         {
-            aKernArray.set(0, rInf.GetWidth() +
+            aKernArray[0] = rInf.GetWidth() +
                             rInf.GetKern() +
-                           (rInf.GetSpace() / SPACING_PRECISION_FACTOR));
+                           (rInf.GetSpace() / SPACING_PRECISION_FACTOR);
 
             if ( bSwitchL2R )
                 rInf.GetFrame()->SwitchLTRtoRTL( aTextOriginPos );
@@ -1615,9 +1615,9 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
                         for( sal_Int32 i = 1 ; i < nLen ; ++i )
                         {
                             if ( aBulletOverlay[ i ] == CH_BULLET )
-                                aKernArray.adjust(i - 1, nShift);
+                                aKernArray[i - 1] += nShift;
                             if ( nAdd )
-                                aKernArray.adjust(i - 1, -nAdd);
+                                aKernArray[i - 1] += -nAdd;
                         }
                     }
                     rInf.GetOut().DrawTextArray( aTextOriginPos, 
aBulletOverlay, aKernArray,
diff --git a/sw/source/core/txtnode/justify.cxx 
b/sw/source/core/txtnode/justify.cxx
index 16a141a5b284..e1ea949b5613 100644
--- a/sw/source/core/txtnode/justify.cxx
+++ b/sw/source/core/txtnode/justify.cxx
@@ -152,23 +152,23 @@ void SpaceDistribution(KernArray& rKernArray, 
std::u16string_view aText, sal_Int
         }
 
         cChPrev = nCh;
-        rKernArray.adjust(nPrevIdx, nKernSum + nSpaceSum);
+        rKernArray[nPrevIdx] += nKernSum + nSpaceSum;
         // In word line mode and for Arabic, we disabled the half space trick. 
If a portion
         // ends with a blank, the full nSpaceAdd value has been added to the 
character in
         // front of the blank. This leads to painting artifacts, therefore we 
remove the
         // nSpaceAdd value again:
         if (bNoHalfSpace && i + 1 == nLen && nCh == CH_BLANK)
-            rKernArray.adjust(nPrevIdx, -nSpaceAdd);
+            rKernArray[nPrevIdx] += -nSpaceAdd;
 
         // Advance nPrevIdx and assign kern values to previous cluster.
         for (tools::Long nValue = rKernArray[nPrevIdx++]; nPrevIdx < i; 
++nPrevIdx)
-            rKernArray.set(nPrevIdx, nValue);
+            rKernArray[nPrevIdx] = nValue;
     }
 
     // the layout engine requires the total width of the output
     while (nPrevIdx < nLen)
     {
-        rKernArray.adjust(nPrevIdx, nKernSum + nSpaceSum);
+        rKernArray[nPrevIdx] += nKernSum + nSpaceSum;
         ++nPrevIdx;
     }
 }
@@ -199,14 +199,14 @@ tools::Long SnapToGrid(KernArray& rKernArray, 
std::u16string_view aText, sal_Int
 
         while (nLast < i)
         {
-            rKernArray.set(nLast, nX);
+            rKernArray[nLast] = nX;
             ++nLast;
         }
     }
 
     while (nLast < nLen)
     {
-        rKernArray.set(nLast, nEdge);
+        rKernArray[nLast] = nEdge;
         ++nLast;
     }
 
@@ -238,7 +238,7 @@ void lcl_MsoCompatSnapToGridEdge(KernArray& rKernArray, 
sal_Int32 nLen, tools::L
         tools::Long nMinWidth = lcl_MsoGridWidth(nGridWidth, nBaseFontSize, 
nCharWidth + nKern);
         while (nLast < i)
         {
-            rKernArray.set(nLast, nEdge);
+            rKernArray[nLast] = nEdge;
             ++nLast;
         }
 
@@ -247,7 +247,7 @@ void lcl_MsoCompatSnapToGridEdge(KernArray& rKernArray, 
sal_Int32 nLen, tools::L
 
     while (nLast < nLen)
     {
-        rKernArray.set(nLast, nEdge);
+        rKernArray[nLast] = nEdge;
         ++nLast;
     }
 }
@@ -279,7 +279,7 @@ void SnapToGridEdge(KernArray& rKernArray, sal_Int32 nLen, 
tools::Long nGridWidt
         tools::Long nMinWidth = lcl_MinGridWidth(nGridWidth, nCharWidth + 
nKern);
         while (nLast < i)
         {
-            rKernArray.set(nLast, nEdge);
+            rKernArray[nLast] = nEdge;
             ++nLast;
         }
 
@@ -288,7 +288,7 @@ void SnapToGridEdge(KernArray& rKernArray, sal_Int32 nLen, 
tools::Long nGridWidt
 
     while (nLast < nLen)
     {
-        rKernArray.set(nLast, nEdge);
+        rKernArray[nLast] = nEdge;
         ++nLast;
     }
 }
diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx
index a3d033e7adba..693cde25b206 100644
--- a/vcl/qa/cppunit/complextext.cxx
+++ b/vcl/qa/cppunit/complextext.cxx
@@ -18,6 +18,7 @@
 #if HAVE_MORE_FONTS
 // must be declared before inclusion of test/bootstrapfixture.hxx
 static std::ostream& operator<<(std::ostream& rStream, const 
std::vector<sal_Int32>& rVec);
+static std::ostream& operator<<(std::ostream& rStream, const 
std::vector<double>& rVec);
 #endif
 #include <test/bootstrapfixture.hxx>
 
@@ -40,6 +41,15 @@ static std::ostream& operator<<(std::ostream& rStream, const 
std::vector<sal_Int
     rStream << " }";
     return rStream;
 }
+static std::ostream& operator<<(std::ostream& rStream, const 
std::vector<double>& rVec)
+{
+    rStream << "{ ";
+    for (size_t i = 0; i < rVec.size() - 1; i++)
+        rStream << rVec[i] << ", ";
+    rStream << rVec.back();
+    rStream << " }";
+    return rStream;
+}
 #endif
 
 class VclComplexTextTest : public test::BootstrapFixture
@@ -82,17 +92,17 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testArabic)
 
     // absolute character widths AKA text array.
     tools::Long nRefTextWidth = 12595;
-    std::vector<sal_Int32> aRefCharWidths = { 989, 1558, 2824, 2824, 3899,
+    KernArray aRefCharWidths = { 989, 1558, 2824, 2824, 3899,
         3899, 4550, 5119, 5689, 5689, 6307, 6925, 8484, 9135, 9705, 10927,
         10927, 11497, 12595, 12595 };
     KernArray aCharWidths;
     tools::Long nTextWidth
         = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aOneTwoThree, 
&aCharWidths).nWidth);
 
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     // this sporadically returns 75 or 74 on some of the windows tinderboxes 
eg. tb73
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // text advance width and line height
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, pOutDev->GetTextWidth(aOneTwoThree));
@@ -258,7 +268,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
 
     OUString aText;
     KernArray aCharWidths;
-    std::vector<sal_Int32> aRefCharWidths;
+    KernArray aRefCharWidths;
     tools::Long nTextWidth, nTextWidth2, nRefTextWidth;
 
     // A. RTL text
@@ -270,18 +280,18 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     aRefCharWidths = { 1168, 1168, 1819, 2389, 3611, 3611 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 584, 1168, 1819, 2389, 3000, 3611 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 3) caret placement with combining marks, they should not add to ligature
     // component count.
@@ -293,10 +303,10 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[8], aCharWidths[9]);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(nTextWidth, nTextWidth2);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // B. LTR text
     aText = u"fi fl ffi ffl"_ustr;
@@ -307,18 +317,18 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testCaret)
     aRefCharWidths = { 1290, 1290, 1941, 3231, 3231, 3882, 5862, 5862, 5862, 
6513, 8493, 8493, 8493 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 645, 1290, 1941, 2586, 3231, 3882, 4542, 5202, 5862, 
6513, 7173, 7833, 8493 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 #endif
 }
 
@@ -332,7 +342,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     vcl::Font aFont;
     OUString aText;
     KernArray aCharWidths;
-    std::vector<sal_Int32> aRefCharWidths;
+    KernArray aRefCharWidths;
     tools::Long nTextWidth, nTextWidth2, nRefTextWidth;
 
     // A. RTL text
@@ -348,18 +358,18 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     aRefCharWidths= { 582, 582, 842, 1111, 1710, 1710 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
     aRefCharWidths = { 291, 582, 842, 1111, 1410, 1710 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 3) caret placement with combining marks, they should not add to ligature
     // component count.
@@ -371,10 +381,10 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
     CPPUNIT_ASSERT_EQUAL(aCharWidths[2], aCharWidths[3]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[6], aCharWidths[7]);
     CPPUNIT_ASSERT_EQUAL(aCharWidths[8], aCharWidths[9]);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth2);
     CPPUNIT_ASSERT_EQUAL(nTextWidth, nTextWidth2);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // B. LTR text
     // Set font size to its UPEM to decrease rounding issues
@@ -390,9 +400,9 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
                        3544, 3544, 3544, 3836, 4634, 4634, 4926, 5996, 5996, 
5996 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
false).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // 2) Caret placement DX array, ligature width is distributed over its
     // components.
@@ -400,9 +410,9 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testGdefCaret)
                        3004, 3278, 3544, 3836, 4138, 4634, 4926, 5199, 5494, 
5996 };
     nTextWidth = basegfx::fround<tools::Long>(
         pOutDev->GetTextArray(aText, &aCharWidths, 0, -1, /*bCaret*/ 
true).nWidth);
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 #endif
 }
 
@@ -417,25 +427,25 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048)
     pOutDev->SetFont(aFont);
 
     // get an compare the default text array
-    std::vector<sal_Int32> aRefCharWidths{ 934, 2341, 2341, 3689, 4647, 5495 };
+    KernArray aRefCharWidths{ 934, 2341, 2341, 3689, 4647, 5495 };
     tools::Long nRefTextWidth(5495);
 
     KernArray aCharWidths;
     tools::Long nTextWidth
         = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aText, 
&aCharWidths).nWidth);
 
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // Simulate Kashida insertion using Kashida array and extending text array
     // to have room for Kashida.
     std::vector<sal_Bool> aKashidaArray{ false, false, false, true, false, 
false };
     auto nKashida = 4000;
 
-    aCharWidths.set(3, aCharWidths[3] + nKashida);
-    aCharWidths.set(4, aCharWidths[4] + nKashida);
-    aCharWidths.set(5, aCharWidths[5] + nKashida);
+    aCharWidths[3] += nKashida;
+    aCharWidths[4] += nKashida;
+    aCharWidths[5] += nKashida;
     auto pLayout = pOutDev->ImplLayout(aText, 0, -1, Point(0, 0), 0, 
aCharWidths, aKashidaArray);
 
     // Without the fix this fails with:
@@ -463,7 +473,7 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, testTdf152048_2)
     // Without the fix this fails with:
     // - Expected: 158
     // - Actual  : 118
-    CPPUNIT_ASSERT_EQUAL(aCharWidths.back(), sal_Int32(nTextWidth));
+    CPPUNIT_ASSERT_EQUAL(tools::Long(aCharWidths.back()), nTextWidth);
 #endif
 }
 
@@ -525,14 +535,14 @@ CPPUNIT_TEST_FIXTURE(VclComplexTextTest, 
testMixedCJKLatinScript_glyph_advanceme
 
     // absolute character widths AKA text array.
     tools::Long nRefTextWidth = 704;
-    std::vector<sal_Int32> aRefCharWidths = { 72, 144, 190, 236, 259, 305, 
333, 379, 425, 474, 523, 551, 567, 612, 658, 704 };
+    KernArray aRefCharWidths = { 72, 144, 190, 236, 259, 305, 333, 379, 425, 
474, 523, 551, 567, 612, 658, 704 };
     KernArray aCharWidths;
     tools::Long nTextWidth
         = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aTestScript, 
&aCharWidths).nWidth);
 
-    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array());
+    CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths);
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, nTextWidth);
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(nTextWidth), aCharWidths.back());
+    CPPUNIT_ASSERT_EQUAL(nTextWidth, tools::Long(aCharWidths.back()));
 
     // text advance width and line height
     CPPUNIT_ASSERT_EQUAL(nRefTextWidth, pOutDev->GetTextWidth(aTestScript));
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 765e4a0aaa4f..453b36f7bb84 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2246,7 +2246,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816)
                 const auto* pNumR = 
dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
                 CPPUNIT_ASSERT(pNumR);
                 // this changed to the end of the text, not the start of the 
fly
-                CPPUNIT_ASSERT_DOUBLES_EQUAL(187.207, pNumR->GetValue(), 1e-3);
+                CPPUNIT_ASSERT_DOUBLES_EQUAL(187.157, pNumR->GetValue(), 1e-3);
                 const auto* pNumB = 
dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
                 CPPUNIT_ASSERT(pNumB);
                 CPPUNIT_ASSERT_DOUBLES_EQUAL(688.389, pNumB->GetValue(), 1e-3);
@@ -2312,7 +2312,7 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816)
                 CPPUNIT_ASSERT_DOUBLES_EQUAL(660.789, pNumT->GetValue(), 1e-3);
                 const auto* pNumR = 
dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
                 CPPUNIT_ASSERT(pNumR);
-                CPPUNIT_ASSERT_DOUBLES_EQUAL(146.157, pNumR->GetValue(), 1e-3);
+                CPPUNIT_ASSERT_DOUBLES_EQUAL(146.107, pNumR->GetValue(), 1e-3);
                 const auto* pNumB = 
dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
                 CPPUNIT_ASSERT(pNumB);
                 CPPUNIT_ASSERT_DOUBLES_EQUAL(674.589, pNumB->GetValue(), 1e-3);
@@ -2372,13 +2372,13 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816)
                 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
                 const auto* pNumL = 
dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
                 CPPUNIT_ASSERT(pNumL);
-                CPPUNIT_ASSERT_DOUBLES_EQUAL(146.093, pNumL->GetValue(), 1e-3);
+                CPPUNIT_ASSERT_DOUBLES_EQUAL(146.043, pNumL->GetValue(), 1e-3);
-e 
... etc. - the rest is truncated

Reply via email to