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 ); } }