include/vcl/outdev.hxx            |    1 
 include/vcl/vcllayout.hxx         |    6 +--
 vcl/source/gdi/pdfwriter_impl.cxx |    4 +-
 vcl/source/gdi/sallayout.cxx      |    6 +--
 vcl/source/outdev/font.cxx        |    2 -
 vcl/source/outdev/map.cxx         |   13 +++++++-
 vcl/source/outdev/text.cxx        |   59 ++++++++++++++++++++++----------------
 vcl/source/outdev/textline.cxx    |   12 +++----
 8 files changed, 63 insertions(+), 40 deletions(-)

New commits:
commit dab0d4e1f36faace21145a51733bd3a946992624
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sat Jan 15 21:47:02 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sun Jan 16 12:23:29 2022 +0100

    tdf#146439 retain precise base start pos when using 
ResolutionIndependentLayout
    
    Change-Id: I16a585abf4805d87a2eeb4e3e9d9bd9f2697b838
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128472
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 0282ea8458b5..4b9d1e7e626a 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1713,6 +1713,7 @@ public:
      @returns Device's X pixel coordinate
      */
     SAL_DLLPRIVATE tools::Long         ImplLogicXToDevicePixel( tools::Long nX 
) const;
+    SAL_DLLPRIVATE double LogicXToDeviceFontCoordinate( tools::Long nWidth ) 
const;
 
     /** Convert a logical Y coordinate to a device pixel's Y coordinate.
 
diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx
index 957d18cebd95..b766a0b4ccd6 100644
--- a/include/vcl/vcllayout.hxx
+++ b/include/vcl/vcllayout.hxx
@@ -68,8 +68,8 @@ class VCL_DLLPUBLIC SalLayout
 public:
     virtual         ~SalLayout();
     // used by upper layers
-    Point&          DrawBase()                              { return 
maDrawBase; }
-    const Point&    DrawBase() const                        { return 
maDrawBase; }
+    DevicePoint&    DrawBase()                              { return 
maDrawBase; }
+    const DevicePoint& DrawBase() const                     { return 
maDrawBase; }
     Point&          DrawOffset()                            { return 
maDrawOffset; }
     const Point&    DrawOffset() const                      { return 
maDrawOffset; }
     DevicePoint     GetDrawPosition( const DevicePoint& rRelative = 
DevicePoint(0,0) ) const;
@@ -114,7 +114,7 @@ protected:
     Degree10        mnOrientation;
 
     mutable Point   maDrawOffset;
-    Point           maDrawBase;
+    DevicePoint     maDrawBase;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index b85592e8fa51..0af6cc78f221 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -5804,9 +5804,9 @@ void PDFWriterImpl::drawShadow( SalLayout& rLayout, const 
OUString& rText, bool
     tools::Long nOff = 1 + ((GetFontInstance()->mnLineHeight-24)/24);
     if( rFont.IsOutline() )
         nOff++;
-    rLayout.DrawBase() += Point( nOff, nOff );
+    rLayout.DrawBase() += DevicePoint(nOff, nOff);
     drawLayout( rLayout, rText, bTextLines );
-    rLayout.DrawBase() -= Point( nOff, nOff );
+    rLayout.DrawBase() -= DevicePoint(nOff, nOff);
 
     setFont( aSaveFont );
     setTextLineColor( aSaveTextLineColor );
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 8c7542a3b79f..64b1d22480e5 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -150,7 +150,7 @@ void SalLayout::AdjustLayout( vcl::text::ImplLayoutArgs& 
rArgs )
 
 DevicePoint SalLayout::GetDrawPosition(const DevicePoint& rRelative) const
 {
-    DevicePoint aPos(maDrawBase.X(), maDrawBase.Y());
+    DevicePoint aPos(maDrawBase);
     DevicePoint aOfs(rRelative.getX() + maDrawOffset.X(),
                      rRelative.getY() + maDrawOffset.Y());
 
@@ -1124,8 +1124,8 @@ bool MultiSalLayout::GetNextGlyph(const GlyphItem** 
pGlyph,
             nStart |= nFontTag;
             if (pFallbackFont)
                 *pFallbackFont = pFontFace;
-            rPos.adjustX(maDrawBase.X() + maDrawOffset.X());
-            rPos.adjustY(maDrawBase.Y() + maDrawOffset.Y());
+            rPos.adjustX(maDrawBase.getX() + maDrawOffset.X());
+            rPos.adjustY(maDrawBase.getY() + maDrawOffset.Y());
             return true;
         }
     }
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 1182ac96a6b9..71e4091e754e 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -1138,7 +1138,7 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& 
rSalLayout )
             }
             aOutPoint.adjustX(aAdjPoint.X() - nEmphasisWidth2);
             aOutPoint.adjustY(aAdjPoint.Y() - nEmphasisHeight2);
-            ImplDrawEmphasisMark( rSalLayout.DrawBase().X(),
+            ImplDrawEmphasisMark( rSalLayout.DrawBase().getX(),
                                   aOutPoint.getX(), aOutPoint.getY(),
                                   aPolyPoly, bPolyLine, aRect1, aRect2 );
         }
diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx
index f98ff3057b6f..5144f0f89f9f 100644
--- a/vcl/source/outdev/map.cxx
+++ b/vcl/source/outdev/map.cxx
@@ -1835,7 +1835,18 @@ double 
OutputDevice::LogicWidthToDeviceFontCoordinate(tools::Long nWidth) const
     if (!mbMap)
         return nWidth;
 
-    return ImplLogicToPixel(static_cast<double>(nWidth), mnDPIX, 
maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
+    return ImplLogicToPixel(static_cast<double>(nWidth), mnDPIX,
+                            maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
+}
+
+double OutputDevice::LogicXToDeviceFontCoordinate(tools::Long nX) const
+{
+    if (!mbMap)
+        return nX + mnOutOffX;
+
+    return ImplLogicToPixel(static_cast<double>(nX + maMapRes.mnMapOfsX), 
mnDPIX,
+                            maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX)
+                            + mnOutOffX + mnOutOffOrigX;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index de196499a81f..f9f0fd54b673 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -168,9 +168,9 @@ void OutputDevice::ImplDrawTextRect( tools::Long nBaseX, 
tools::Long nBaseY,
 void OutputDevice::ImplDrawTextBackground( const SalLayout& rSalLayout )
 {
     const tools::Long nWidth = rSalLayout.GetTextWidth() / 
rSalLayout.GetUnitsPerPixel();
-    const Point aBase = rSalLayout.DrawBase();
-    const tools::Long nX = aBase.X();
-    const tools::Long nY = aBase.Y();
+    const DevicePoint aBase = rSalLayout.DrawBase();
+    const tools::Long nX = aBase.getX();
+    const tools::Long nY = aBase.getY();
 
     if ( mbLineColor || mbInitLineColor )
     {
@@ -225,11 +225,11 @@ tools::Rectangle OutputDevice::ImplGetTextBoundRect( 
const SalLayout& rSalLayout
 
 bool OutputDevice::ImplDrawRotateText( SalLayout& rSalLayout )
 {
-    tools::Long nX = rSalLayout.DrawBase().X();
-    tools::Long nY = rSalLayout.DrawBase().Y();
+    tools::Long nX = rSalLayout.DrawBase().getX();
+    tools::Long nY = rSalLayout.DrawBase().getY();
 
     tools::Rectangle aBoundRect;
-    rSalLayout.DrawBase() = Point( 0, 0 );
+    rSalLayout.DrawBase() = DevicePoint( 0, 0 );
     rSalLayout.DrawOffset() = Point( 0, 0 );
     if (!rSalLayout.GetBoundRect(aBoundRect))
     {
@@ -261,7 +261,8 @@ bool OutputDevice::ImplDrawRotateText( SalLayout& 
rSalLayout )
     pVDev->ImplInitTextColor();
 
     // draw text into upper left corner
-    rSalLayout.DrawBase() -= aBoundRect.TopLeft();
+    rSalLayout.DrawBase().adjustX(-aBoundRect.Left());
+    rSalLayout.DrawBase().adjustY(-aBoundRect.Top());
     rSalLayout.DrawText( *pVDev->mpGraphics );
 
     Bitmap aBmp = pVDev->GetBitmap( Point(), aBoundRect.GetSize() );
@@ -302,18 +303,18 @@ void OutputDevice::ImplDrawTextDirect( SalLayout& 
rSalLayout,
         if( ImplDrawRotateText( rSalLayout ) )
             return;
 
-    tools::Long nOldX = rSalLayout.DrawBase().X();
+    auto nOldX = rSalLayout.DrawBase().getX();
     if( HasMirroredGraphics() )
     {
         tools::Long w = IsVirtual() ? mnOutWidth : 
mpGraphics->GetGraphicsWidth();
-        tools::Long x = rSalLayout.DrawBase().X();
+        auto x = rSalLayout.DrawBase().getX();
         rSalLayout.DrawBase().setX( w - 1 - x );
         if( !IsRTLEnabled() )
         {
             OutputDevice *pOutDevRef = this;
             // mirror this window back
             tools::Long devX = w-pOutDevRef->mnOutWidth-pOutDevRef->mnOutOffX; 
  // re-mirrored mnOutOffX
-            rSalLayout.DrawBase().setX( devX + ( pOutDevRef->mnOutWidth - 1 - 
(rSalLayout.DrawBase().X() - devX) ) ) ;
+            rSalLayout.DrawBase().setX( devX + ( pOutDevRef->mnOutWidth - 1 - 
(rSalLayout.DrawBase().getX() - devX) ) ) ;
         }
     }
     else if( IsRTLEnabled() )
@@ -322,7 +323,7 @@ void OutputDevice::ImplDrawTextDirect( SalLayout& 
rSalLayout,
 
         // mirror this window back
         tools::Long devX = pOutDevRef->mnOutOffX;   // re-mirrored mnOutOffX
-        rSalLayout.DrawBase().setX( pOutDevRef->mnOutWidth - 1 - 
(rSalLayout.DrawBase().X() - devX) + devX );
+        rSalLayout.DrawBase().setX( pOutDevRef->mnOutWidth - 1 - 
(rSalLayout.DrawBase().getX() - devX) + devX );
     }
 
     rSalLayout.DrawText( *mpGraphics );
@@ -345,7 +346,7 @@ void OutputDevice::ImplDrawSpecialText( SalLayout& 
rSalLayout )
     Color       aOldOverlineColor   = GetOverlineColor();
     FontRelief  eRelief             = maFont.GetRelief();
 
-    Point aOrigPos = rSalLayout.DrawBase();
+    DevicePoint aOrigPos = rSalLayout.DrawBase();
     if ( eRelief != FontRelief::NONE )
     {
         Color   aReliefColor( COL_LIGHTGRAY );
@@ -413,9 +414,9 @@ void OutputDevice::ImplDrawSpecialText( SalLayout& 
rSalLayout )
             else
                 SetTextColor( COL_BLACK );
             ImplInitTextColor();
-            rSalLayout.DrawBase() += Point( nOff, nOff );
+            rSalLayout.DrawBase() += DevicePoint( nOff, nOff );
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() -= Point( nOff, nOff );
+            rSalLayout.DrawBase() -= DevicePoint( nOff, nOff );
             SetTextColor( aOldColor );
             SetTextLineColor( aOldTextLineColor );
             SetOverlineColor( aOldOverlineColor );
@@ -427,21 +428,21 @@ void OutputDevice::ImplDrawSpecialText( SalLayout& 
rSalLayout )
 
         if ( maFont.IsOutline() )
         {
-            rSalLayout.DrawBase() = aOrigPos + Point(-1,-1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(-1,-1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(+1,+1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(+1,+1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(-1,+0);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(-1,+0);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(-1,+1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(-1,+1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(+0,+1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(+0,+1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(+0,-1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(+0,-1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(+1,-1);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(+1,-1);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
-            rSalLayout.DrawBase() = aOrigPos + Point(+1,+0);
+            rSalLayout.DrawBase() = aOrigPos + DevicePoint(+1,+0);
             ImplDrawTextDirect( rSalLayout, mbTextLines );
             rSalLayout.DrawBase() = aOrigPos;
 
@@ -468,7 +469,7 @@ void OutputDevice::ImplDrawText( SalLayout& rSalLayout )
     if( mbInitTextColor )
         ImplInitTextColor();
 
-    rSalLayout.DrawBase() += Point( mnTextOffX, mnTextOffY );
+    rSalLayout.DrawBase() += DevicePoint(mnTextOffX, mnTextOffY);
 
     if( IsTextFillColor() )
         ImplDrawTextBackground( rSalLayout );
@@ -1341,6 +1342,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const 
OUString& rOrigStr,
     vcl::text::ImplLayoutArgs aLayoutArgs = ImplPrepareLayoutArgs( aStr, 
nMinIndex, nLen,
             nPixelWidth, flags, pLayoutCache);
 
+    bool bTextRenderModeForResolutionIndependentLayout(false);
     DeviceCoordinate nEndGlyphCoord(0);
     std::unique_ptr<DeviceCoordinate[]> xDXPixelArray;
     std::unique_ptr<double[]> xNaturalDXPixelArray;
@@ -1351,6 +1353,8 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const 
OUString& rOrigStr,
         {
             if (GetTextRenderModeForResolutionIndependentLayout())
             {
+                bTextRenderModeForResolutionIndependentLayout = true;
+
                 // convert from logical units to font units using a temporary 
array
                 xNaturalDXPixelArray.reset(new double[nLen]);
 
@@ -1419,7 +1423,14 @@ std::unique_ptr<SalLayout> 
OutputDevice::ImplLayout(const OUString& rOrigStr,
 
     // position, justify, etc. the layout
     pSalLayout->AdjustLayout( aLayoutArgs );
-    pSalLayout->DrawBase() = ImplLogicToDevicePixel( rLogicalPos );
+
+    Point aDevicePos = ImplLogicToDevicePixel(rLogicalPos);
+    if (bTextRenderModeForResolutionIndependentLayout)
+        
pSalLayout->DrawBase().setX(LogicXToDeviceFontCoordinate(rLogicalPos.X()));
+    else
+        pSalLayout->DrawBase().setX(aDevicePos.X());
+    pSalLayout->DrawBase().setY(aDevicePos.Y());
+
     // adjust to right alignment if necessary
     if( aLayoutArgs.mnFlags & SalLayoutFlags::RightAlign )
     {
diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx
index c950d345da00..7c8af3db9220 100644
--- a/vcl/source/outdev/textline.cxx
+++ b/vcl/source/outdev/textline.cxx
@@ -710,7 +710,7 @@ void OutputDevice::ImplDrawStrikeoutChar( tools::Long 
nBaseX, tools::Long nBaseY
     SetTextColor( aColor );
     ImplInitTextColor();
 
-    pLayout->DrawBase() = Point( nBaseX+mnTextOffX, nBaseY+mnTextOffY );
+    pLayout->DrawBase() = DevicePoint(nBaseX + mnTextOffX, nBaseY + 
mnTextOffY);
 
     tools::Rectangle aPixelRect;
     aPixelRect.SetLeft( nBaseX+mnTextOffX );
@@ -811,7 +811,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& 
rSalLayout, FontStrikeout eStri
     if( bWordLine )
     {
         // draw everything relative to the layout base point
-        const Point aStartPt = rSalLayout.DrawBase();
+        const DevicePoint aStartPt = rSalLayout.DrawBase();
 
         // calculate distance of each word from the base point
         DevicePoint aPos;
@@ -827,10 +827,10 @@ void OutputDevice::ImplDrawTextLines( SalLayout& 
rSalLayout, FontStrikeout eStri
                 if( !nWidth )
                 {
                     // get the distance to the base point (as projected to 
baseline)
-                    nDist = aPos.getX() - aStartPt.X();
+                    nDist = aPos.getX() - aStartPt.getX();
                     if( mpFontInstance->mnOrientation )
                     {
-                        const DeviceCoordinate nDY = aPos.getY() - 
aStartPt.Y();
+                        const DeviceCoordinate nDY = aPos.getY() - 
aStartPt.getY();
                         const double fRad = 
toRadians(mpFontInstance->mnOrientation);
                         nDist = FRound( nDist*cos(fRad) - nDY*sin(fRad) );
                     }
@@ -842,7 +842,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& 
rSalLayout, FontStrikeout eStri
             else if( nWidth > 0 )
             {
                 // draw the textline for each word
-                ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth,
+                ImplDrawTextLine( aStartPt.getX(), aStartPt.getY(), nDist, 
nWidth,
                                   eStrikeout, eUnderline, eOverline, 
bUnderlineAbove );
                 nWidth = 0;
             }
@@ -851,7 +851,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& 
rSalLayout, FontStrikeout eStri
         // draw textline for the last word
         if( nWidth > 0 )
         {
-            ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth,
+            ImplDrawTextLine( aStartPt.getX(), aStartPt.getY(), nDist, nWidth,
                               eStrikeout, eUnderline, eOverline, 
bUnderlineAbove );
         }
     }

Reply via email to