diff options
197 files changed, 1436 insertions, 1061 deletions
diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx index d33cd82b194d..3929690b8921 100644 --- a/basegfx/source/curve/b2dcubicbezier.cxx +++ b/basegfx/source/curve/b2dcubicbezier.cxx @@ -1021,33 +1021,33 @@ namespace basegfx if(maControlPointA == maStartPoint) { maControlPointA = maStartPoint = basegfx::B2DPoint( - basegfx::fround(maStartPoint.getX()), - basegfx::fround(maStartPoint.getY())); + std::round(maStartPoint.getX()), + std::round(maStartPoint.getY())); } else { maStartPoint = basegfx::B2DPoint( - basegfx::fround(maStartPoint.getX()), - basegfx::fround(maStartPoint.getY())); + std::round(maStartPoint.getX()), + std::round(maStartPoint.getY())); maControlPointA = basegfx::B2DPoint( - basegfx::fround(maControlPointA.getX()), - basegfx::fround(maControlPointA.getY())); + std::round(maControlPointA.getX()), + std::round(maControlPointA.getY())); } if(maControlPointB == maEndPoint) { maControlPointB = maEndPoint = basegfx::B2DPoint( - basegfx::fround(maEndPoint.getX()), - basegfx::fround(maEndPoint.getY())); + std::round(maEndPoint.getX()), + std::round(maEndPoint.getY())); } else { maEndPoint = basegfx::B2DPoint( - basegfx::fround(maEndPoint.getX()), - basegfx::fround(maEndPoint.getY())); + std::round(maEndPoint.getX()), + std::round(maEndPoint.getY())); maControlPointB = basegfx::B2DPoint( - basegfx::fround(maControlPointB.getX()), - basegfx::fround(maControlPointB.getY())); + std::round(maControlPointB.getX()), + std::round(maControlPointB.getY())); } } } // end of namespace basegfx diff --git a/canvas/source/directx/dx_textlayout_drawhelper.cxx b/canvas/source/directx/dx_textlayout_drawhelper.cxx index 9a8771428d93..8ac3eb95d0f5 100644 --- a/canvas/source/directx/dx_textlayout_drawhelper.cxx +++ b/canvas/source/directx/dx_textlayout_drawhelper.cxx @@ -111,7 +111,7 @@ namespace dxcanvas vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); @@ -253,7 +253,7 @@ namespace dxcanvas vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); diff --git a/canvas/source/opengl/ogl_canvashelper.cxx b/canvas/source/opengl/ogl_canvashelper.cxx index 1b84879b005c..edce6bc5ab83 100644 --- a/canvas/source/opengl/ogl_canvashelper.cxx +++ b/canvas/source/opengl/ogl_canvashelper.cxx @@ -690,7 +690,7 @@ namespace oglcanvas vcl::Font aFont( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize))); + Size( 0, ::basegfx::fround<tools::Long>(rFontRequest.CellSize))); aFont.SetAlignment( ALIGN_BASELINE ); aFont.SetCharSet( (rFontRequest.FontDescription.IsSymbolFont==util::TriState_YES) ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE ); diff --git a/canvas/source/tools/surface.cxx b/canvas/source/tools/surface.cxx index 9dfb0f7c9d36..4e3111f1b1ca 100644 --- a/canvas/source/tools/surface.cxx +++ b/canvas/source/tools/surface.cxx @@ -117,8 +117,7 @@ namespace canvas basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix( maSourceOffset.getX(), maSourceOffset.getY())); aTransform = aTransform * rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* ###################################### @@ -237,8 +236,7 @@ namespace canvas // 3) translation to output position [rPos] basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(aPos1.getX(), aPos1.getY())); aTransform = aTransform * rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* @@ -333,8 +331,7 @@ namespace canvas // be calculated from the result, and this is why we need to use // integer coordinates here... basegfx::B2DHomMatrix aTransform = rTransform; - aTransform.translate(::basegfx::fround(rPos.getX()), - ::basegfx::fround(rPos.getY())); + aTransform.translate(rPos); /* ###################################### diff --git a/canvas/source/vcl/canvasfont.cxx b/canvas/source/vcl/canvasfont.cxx index 41b7da25016d..d028a9814d08 100644 --- a/canvas/source/vcl/canvasfont.cxx +++ b/canvas/source/vcl/canvasfont.cxx @@ -44,7 +44,7 @@ namespace vclcanvas CanvasFont_Base( m_aMutex ), maFont( vcl::Font( rFontRequest.FontDescription.FamilyName, rFontRequest.FontDescription.StyleName, - Size( 0, ::basegfx::fround(rFontRequest.CellSize) ) ) ), + Size( 0, ::basegfx::fround<::tools::Long>(rFontRequest.CellSize) ) ) ), maFontRequest( rFontRequest ), mpRefDevice( &rDevice ), mpOutDevProvider( rOutDevProvider ), diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx index cbbd18a376d9..4d1a4d0b20d6 100644 --- a/canvas/source/vcl/canvashelper.cxx +++ b/canvas/source/vcl/canvashelper.cxx @@ -830,8 +830,8 @@ namespace vclcanvas // output GraphicObject const ::Point aPt( vcl::unotools::pointFromB2DPoint( aOutputPos ) ); - const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width() ), - ::basegfx::fround( aScale.getY() * aBmpSize.Height() ) ); + const ::Size aSz( ::basegfx::fround<::tools::Long>( aScale.getX() * aBmpSize.Width() ), + ::basegfx::fround<::tools::Long>( aScale.getY() * aBmpSize.Height() ) ); pGrfObj->Draw(mpOutDevProvider->getOutDev(), aPt, diff --git a/canvas/source/vcl/canvashelper_texturefill.cxx b/canvas/source/vcl/canvashelper_texturefill.cxx index 468ef3921a80..2c3bc6a05d11 100644 --- a/canvas/source/vcl/canvashelper_texturefill.cxx +++ b/canvas/source/vcl/canvashelper_texturefill.cxx @@ -211,12 +211,12 @@ namespace vclcanvas // loop below, we set the _right_ edge here, which will be // readily copied into the left edge in the loop below const ::basegfx::B2DPoint& rPoint1( aLeftTop - 2.0*nDiagonalLength*aDirection ); - aTempPoly[1] = ::Point( ::basegfx::fround( rPoint1.getX() ), - ::basegfx::fround( rPoint1.getY() ) ); + aTempPoly[1] = ::Point( ::basegfx::fround<::tools::Long>( rPoint1.getX() ), + ::basegfx::fround<::tools::Long>( rPoint1.getY() ) ); const ::basegfx::B2DPoint& rPoint2( aLeftBottom - 2.0*nDiagonalLength*aDirection ); - aTempPoly[2] = ::Point( ::basegfx::fround( rPoint2.getX() ), - ::basegfx::fround( rPoint2.getY() ) ); + aTempPoly[2] = ::Point( ::basegfx::fround<::tools::Long>( rPoint2.getX() ), + ::basegfx::fround<::tools::Long>( rPoint2.getY() ) ); // iteratively render all other strips @@ -258,14 +258,14 @@ namespace vclcanvas const ::basegfx::B2DPoint& rPoint3( (nStepCount - i-1)/double(nStepCount)*aLeftTop + (i+1)/double(nStepCount)*aRightTop ); - aTempPoly[1] = ::Point( ::basegfx::fround( rPoint3.getX() ), - ::basegfx::fround( rPoint3.getY() ) ); + aTempPoly[1] = ::Point( ::basegfx::fround<::tools::Long>( rPoint3.getX() ), + ::basegfx::fround<::tools::Long>( rPoint3.getY() ) ); const ::basegfx::B2DPoint& rPoint4( (nStepCount - i-1)/double(nStepCount)*aLeftBottom + (i+1)/double(nStepCount)*aRightBottom ); - aTempPoly[2] = ::Point( ::basegfx::fround( rPoint4.getX() ), - ::basegfx::fround( rPoint4.getY() ) ); + aTempPoly[2] = ::Point( ::basegfx::fround<::tools::Long>( rPoint4.getX() ), + ::basegfx::fround<::tools::Long>( rPoint4.getY() ) ); rOutDev.DrawPolygon( aTempPoly ); } @@ -283,12 +283,12 @@ namespace vclcanvas // gradient rect two times the bound rect's diagonal to // the 'right'. const ::basegfx::B2DPoint& rPoint3( aRightTop + 2.0*nDiagonalLength*aDirection ); - aTempPoly[0] = aTempPoly[4] = ::Point( ::basegfx::fround( rPoint3.getX() ), - ::basegfx::fround( rPoint3.getY() ) ); + aTempPoly[0] = aTempPoly[4] = ::Point( ::basegfx::fround<::tools::Long>( rPoint3.getX() ), + ::basegfx::fround<::tools::Long>( rPoint3.getY() ) ); const ::basegfx::B2DPoint& rPoint4( aRightBottom + 2.0*nDiagonalLength*aDirection ); - aTempPoly[3] = ::Point( ::basegfx::fround( rPoint4.getX() ), - ::basegfx::fround( rPoint4.getY() ) ); + aTempPoly[3] = ::Point( ::basegfx::fround<::tools::Long>( rPoint4.getX() ), + ::basegfx::fround<::tools::Long>( rPoint4.getY() ) ); rOutDev.SetFillColor( rColors.back() ); @@ -418,8 +418,8 @@ namespace vclcanvas const ::basegfx::B2DPoint& rInnerPoint( aInnerPoly.getB2DPoint(p) ); aTempPoly[static_cast<sal_uInt16>(p)] = ::Point( - basegfx::fround( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), - basegfx::fround( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); + basegfx::fround<::tools::Long>( fT*rInnerPoint.getX() + (1-fT)*rOuterPoint.getX() ), + basegfx::fround<::tools::Long>( fT*rInnerPoint.getY() + (1-fT)*rOuterPoint.getY() ) ); } // close polygon explicitly @@ -898,15 +898,15 @@ namespace vclcanvas const ::Point aPtRepeat( vcl::unotools::pointFromB2DPoint( aSingleDeviceTextureRect.getMinimum() ) ); - const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width ), - ::basegfx::fround( aScale.getY() * aBmpSize.Height ) ); + const ::Size aSz( ::basegfx::fround<::tools::Long>( aScale.getX() * aBmpSize.Width ), + ::basegfx::fround<::tools::Long>( aScale.getY() * aBmpSize.Height ) ); const ::Size aIntegerNextTileX( vcl::unotools::sizeFromB2DSize(aNextTileX) ); const ::Size aIntegerNextTileY( vcl::unotools::sizeFromB2DSize(aNextTileY) ); const ::Point aPt( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? - ::basegfx::fround( aOutputPos.getX() ) : aPtRepeat.X(), + ::basegfx::fround<::tools::Long>( aOutputPos.getX() ) : aPtRepeat.X(), textures[0].RepeatModeY == rendering::TexturingMode::NONE ? - ::basegfx::fround( aOutputPos.getY() ) : aPtRepeat.Y() ); + ::basegfx::fround<::tools::Long>( aOutputPos.getY() ) : aPtRepeat.Y() ); const sal_Int32 nTilesX( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? 1 : nX2 - nX1 ); const sal_Int32 nTilesY( textures[0].RepeatModeX == rendering::TexturingMode::NONE ? diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx index 0a44f22096f0..cafc59a9b83f 100644 --- a/canvas/source/vcl/impltools.cxx +++ b/canvas/source/vcl/impltools.cxx @@ -123,14 +123,14 @@ namespace vclcanvas::tools if( !::rtl::math::approxEqual(aScale.getY(), 1.0) ) { const sal_Int32 nFontHeight( io_rVCLFont.GetFontHeight() ); - io_rVCLFont.SetFontHeight( ::basegfx::fround(nFontHeight * aScale.getY()) ); + io_rVCLFont.SetFontHeight( ::basegfx::fround<::tools::Long>(nFontHeight * aScale.getY()) ); } io_rVCLFont.SetOrientation( Degree10( ::basegfx::fround(-basegfx::rad2deg<10>(fmod(nRotate, 2*M_PI))) ) ); // TODO(F2): Missing functionality in VCL: shearing - o_rPoint.setX( ::basegfx::fround(aTranslate.getX()) ); - o_rPoint.setY( ::basegfx::fround(aTranslate.getY()) ); + o_rPoint.setX( ::basegfx::fround<::tools::Long>(aTranslate.getX()) ); + o_rPoint.setY( ::basegfx::fround<::tools::Long>(aTranslate.getY()) ); return true; } @@ -154,7 +154,7 @@ namespace vclcanvas::tools if (!::basegfx::fTools::equalZero(fDividend)) fStretch /= fDividend; - const ::tools::Long nNewWidth = ::basegfx::fround(aSize.Width() * fStretch); + const ::tools::Long nNewWidth = ::basegfx::fround<::tools::Long>(aSize.Width() * fStretch); rFont.SetAverageFontWidth(nNewWidth); diff --git a/chart2/source/controller/main/SelectionHelper.cxx b/chart2/source/controller/main/SelectionHelper.cxx index 46f648399980..f116d06bf7be 100644 --- a/chart2/source/controller/main/SelectionHelper.cxx +++ b/chart2/source/controller/main/SelectionHelper.cxx @@ -596,7 +596,7 @@ bool SelectionHelper::getMarkHandles( SdrHdlList& rHdlList ) for( sal_uInt32 nM = 0; nM < aPolygon.count(); nM++) { const ::basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(nM)); - rHdlList.AddHdl(std::make_unique<SdrHdl>(Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())), SdrHdlKind::Poly)); + rHdlList.AddHdl(std::make_unique<SdrHdl>(Point(basegfx::fround<tools::Long>(aPoint.getX()), basegfx::fround<tools::Long>(aPoint.getY())), SdrHdlKind::Poly)); } } return true; diff --git a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx index dd3077f94882..1061b63a60a2 100644 --- a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx +++ b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx @@ -246,8 +246,8 @@ namespace cppcanvas::internal } // output size of metafile - ::Size aOutputSizePixel( ::basegfx::fround( aScale.getX() * maDstSize.getWidth() ), - ::basegfx::fround( aScale.getY() * maDstSize.getHeight() ) ); + ::Size aOutputSizePixel( ::basegfx::fround<::tools::Long>( aScale.getX() * maDstSize.getWidth() ), + ::basegfx::fround<::tools::Long>( aScale.getY() * maDstSize.getHeight() ) ); sal_Int32 nBitmapExtra; if ( bHasTextActions ) diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx index c67ee92d141c..0ffb50342936 100644 --- a/cui/source/dialogs/cuigrfflt.cxx +++ b/cui/source/dialogs/cuigrfflt.cxx @@ -192,8 +192,8 @@ Graphic GraphicFilterMosaic::GetFilteredGraphic( const Graphic& rGraphic, Graphic aRet; tools::Long nTileWidth = static_cast<tools::Long>(mxMtrWidth->get_value(FieldUnit::PIXEL)); tools::Long nTileHeight = static_cast<tools::Long>(mxMtrHeight->get_value(FieldUnit::PIXEL)); - const Size aSize( std::max( FRound( nTileWidth * fScaleX ), tools::Long(1) ), - std::max( FRound( nTileHeight * fScaleY ), tools::Long(1) ) ); + const Size aSize( std::max( basegfx::fround<tools::Long>( nTileWidth * fScaleX ), tools::Long(1) ), + std::max( basegfx::fround<tools::Long>( nTileHeight * fScaleY ), tools::Long(1) ) ); if( rGraphic.IsAnimated() ) { @@ -270,7 +270,7 @@ GraphicFilterSolarize::GraphicFilterSolarize(weld::Window* pParent, const Graphi , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT)) , mxCbxInvert(m_xBuilder->weld_check_button("invert")) { - mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), FieldUnit::PERCENT); + mxMtrThreshold->set_value(basegfx::fround(cGreyThreshold / 2.55), FieldUnit::PERCENT); mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, EditModifyHdl)); mxCbxInvert->set_active(bInvert); @@ -290,7 +290,7 @@ IMPL_LINK_NOARG(GraphicFilterSolarize, EditModifyHdl, weld::MetricSpinButton&, v Graphic GraphicFilterSolarize::GetFilteredGraphic( const Graphic& rGraphic, double, double ) { Graphic aRet; - sal_uInt8 nGreyThreshold = static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55)); + sal_uInt8 nGreyThreshold = basegfx::fround<sal_uInt8>(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55); if( rGraphic.IsAnimated() ) { diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx index c9fd14095b9d..55b062d749df 100644 --- a/cui/source/tabpages/transfrm.cxx +++ b/cui/source/tabpages/transfrm.cxx @@ -1123,8 +1123,8 @@ DeactivateRC SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet ) GetTopLeftPosition(fX, fY, maRange); const ::tools::Rectangle aOutRectangle( - basegfx::fround(fX), basegfx::fround(fY), - basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight())); + basegfx::fround<tools::Long>(fX), basegfx::fround<tools::Long>(fY), + basegfx::fround<tools::Long>(fX + maRange.getWidth()), basegfx::fround<tools::Long>(fY + maRange.getHeight())); _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle)); _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS, m_xTsbPosProtect->get_state() == TRISTATE_TRUE )); diff --git a/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx index be58c77dd390..f9103cb5dcd2 100644 --- a/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx +++ b/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx @@ -146,7 +146,7 @@ namespace drawinglayer::unorenderer if(!aBitmapEx.IsEmpty()) { aBitmapEx.SetPrefMapMode(MapMode(MapUnit::Map100thMM)); - aBitmapEx.SetPrefSize(Size(basegfx::fround(fWidth), basegfx::fround(fHeight))); + aBitmapEx.SetPrefSize(Size(basegfx::fround<tools::Long>(fWidth), basegfx::fround<tools::Long>(fHeight))); XBitmap = vcl::unotools::xBitmapFromBitmapEx(aBitmapEx); } } diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx index ea9fed02a20f..a9b78c599042 100644 --- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx +++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx @@ -22,6 +22,8 @@ #include <algorithm> #include <com/sun/star/uno/XComponentContext.hpp> + +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include <drawinglayer/attribute/fontattribute.hxx> #include <drawinglayer/primitive2d/textlayoutdevice.hxx> #include <comphelper/processfactory.hxx> @@ -162,56 +164,78 @@ TextLayouterDevice::TextLayouterDevice() TextLayouterDevice::~TextLayouterDevice() COVERITY_NOEXCEPT_FALSE { releaseGlobalVirtualDevice(); } -void TextLayouterDevice::setFont(const vcl::Font& rFont) { mrDevice.SetFont(rFont); } +void TextLayouterDevice::setFont(const vcl::Font& rFont) +{ + mrDevice.SetFont(rFont); + mnFontScalingFixX = 1.0; + mnFontScalingFixY = 1.0; +} void TextLayouterDevice::setFontAttribute(const attribute::FontAttribute& rFontAttribute, double fFontScaleX, double fFontScaleY, const css::lang::Locale& rLocale) { - setFont(getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, fFontScaleY, 0.0, rLocale)); + vcl::Font aFont + = getVclFontFromFontAttribute(rFontAttribute, fFontScaleX, fFontScaleY, 0.0, rLocale); + setFont(aFont); + Size aFontSize = aFont.GetFontSize(); + if (aFontSize.Height()) + { + mnFontScalingFixY = fFontScaleY / aFontSize.Height(); + // aFontSize.Width() is 0 for uninformly scaled fonts: see getVclFontFromFontAttribute + mnFontScalingFixX + = fFontScaleX / (aFontSize.Width() ? aFontSize.Width() : aFontSize.Height()); + } + else + { + mnFontScalingFixX = mnFontScalingFixY = 1.0; + } } double TextLayouterDevice::getOverlineOffset() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); double fRet = (rMetric.GetInternalLeading() / 2.0) - rMetric.GetAscent(); - return fRet; + return fRet * mnFontScalingFixY; } double TextLayouterDevice::getUnderlineOffset() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); double fRet = rMetric.GetDescent() / 2.0; - return fRet; + return fRet * mnFontScalingFixY; } double TextLayouterDevice::getStrikeoutOffset() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); double fRet = (rMetric.GetAscent() - rMetric.GetInternalLeading()) / 3.0; - return fRet; + return fRet * mnFontScalingFixY; } double TextLayouterDevice::getOverlineHeight() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); double fRet = rMetric.GetInternalLeading() / 2.5; - return fRet; + return fRet * mnFontScalingFixY; } double TextLayouterDevice::getUnderlineHeight() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); double fRet = rMetric.GetDescent() / 4.0; - return fRet; + return fRet * mnFontScalingFixY; } -double TextLayouterDevice::getTextHeight() const { return mrDevice.GetTextHeight(); } +double TextLayouterDevice::getTextHeight() const +{ + return mrDevice.GetTextHeightDouble() * mnFontScalingFixY; +} double TextLayouterDevice::getTextWidth(const OUString& rText, sal_uInt32 nIndex, sal_uInt32 nLength) const { - return mrDevice.GetTextWidth(rText, nIndex, nLength); + return mrDevice.GetTextWidthDouble(rText, nIndex, nLength) * mnFontScalingFixX; } void TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector, @@ -245,6 +269,13 @@ void TextLayouterDevice::getTextOutlines(basegfx::B2DPolyPolygonVector& rB2DPoly { mrDevice.GetTextOutlines(rB2DPolyPolyVector, rText, nIndex, nIndex, nLength); } + if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0) + || !rtl_math_approxEqual(mnFontScalingFixX, 1.0)) + { + auto scale = basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, mnFontScalingFixY); + for (auto& poly : rB2DPolyPolyVector) + poly.transform(scale); + } } basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sal_uInt32 nIndex, @@ -260,15 +291,15 @@ basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sa if (nTextLength) { - ::tools::Rectangle aRect; - + basegfx::B2DRange aRect; mrDevice.GetTextBoundRect(aRect, rText, nIndex, nIndex, nLength); - - // #i104432#, #i102556# take empty results into account - if (!aRect.IsEmpty()) + if (!rtl_math_approxEqual(mnFontScalingFixY, 1.0) + || !rtl_math_approxEqual(mnFontScalingFixX, 1.0)) { - return vcl::unotools::b2DRectangleFromRectangle(aRect); + aRect.transform( + basegfx::utils::createScaleB2DHomMatrix(mnFontScalingFixX, mnFontScalingFixY)); } + return aRect; } return basegfx::B2DRange(); @@ -277,13 +308,13 @@ basegfx::B2DRange TextLayouterDevice::getTextBoundRect(const OUString& rText, sa double TextLayouterDevice::getFontAscent() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); - return rMetric.GetAscent(); + return rMetric.GetAscent() * mnFontScalingFixY; } double TextLayouterDevice::getFontDescent() const { const ::FontMetric& rMetric = mrDevice.GetFontMetric(); - return rMetric.GetDescent(); + return rMetric.GetDescent() * mnFontScalingFixY; } void TextLayouterDevice::addTextRectActions(const ::tools::Rectangle& rRectangle, @@ -311,7 +342,7 @@ std::vector<double> TextLayouterDevice::getTextArray(const OUString& rText, sal_ mrDevice.GetTextArray(rText, &aArray, nIndex, nTextLength); aRetval.reserve(aArray.size()); for (size_t i = 0, nEnd = aArray.size(); i < nEnd; ++i) - aRetval.push_back(aArray[i]); + aRetval.push_back(aArray[i] * mnFontScalingFixX); } return aRetval; diff --git a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx b/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx index 9f838a7e1b61..d4f14a13ce6c 100644 --- a/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx +++ b/drawinglayer/source/processor2d/helperwrongspellrenderer.cxx @@ -50,8 +50,10 @@ bool renderWrongSpellPrimitive2D(const primitive2d::WrongSpellPrimitive2D& rWron * basegfx::B2DPoint(rWrongSpellCandidate.getStart(), 0.0)); const basegfx::B2DPoint aStop(aLocalTransform * basegfx::B2DPoint(rWrongSpellCandidate.getStop(), 0.0)); - const Point aVclStart(basegfx::fround(aStart.getX()), basegfx::fround(aStart.getY())); - const Point aVclStop(basegfx::fround(aStop.getX()), basegfx::fround(aStop.getY())); + const Point aVclStart(basegfx::fround<tools::Long>(aStart.getX()), + basegfx::fround<tools::Long>(aStart.getY())); + const Point aVclStop(basegfx::fround<tools::Long>(aStop.getX()), + basegfx::fround<tools::Long>(aStop.getY())); // #i101075# draw it. Do not forget to use the evtl. offsetted origin of the target device, // e.g. when used with mask/transparence buffer device diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index e88a3e9802a5..ec3010cf8455 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -222,8 +222,10 @@ VclMetafileProcessor2D::impDumpToMetaFile(const primitive2d::Primitive2DContaine aPrimitiveRange.transform(maCurrentTransformation); const tools::Rectangle aPrimitiveRectangle( - basegfx::fround(aPrimitiveRange.getMinX()), basegfx::fround(aPrimitiveRange.getMinY()), - basegfx::fround(aPrimitiveRange.getMaxX()), basegfx::fround(aPrimitiveRange.getMaxY())); + basegfx::fround<tools::Long>(aPrimitiveRange.getMinX()), + basegfx::fround<tools::Long>(aPrimitiveRange.getMinY()), + basegfx::fround<tools::Long>(aPrimitiveRange.getMaxX()), + basegfx::fround<tools::Long>(aPrimitiveRange.getMaxY())); ScopedVclPtrInstance<VirtualDevice> aContentVDev; MapMode aNewMapMode(pLastOutputDevice->GetMapMode()); @@ -1662,7 +1664,7 @@ void VclMetafileProcessor2D::processPolygonStrokePrimitive2D( // use the transformed line width LineInfo aLineInfo(LineStyle::Solid, - basegfx::fround(getTransformedLineWidth(rLine.getWidth()))); + std::round(getTransformedLineWidth(rLine.getWidth()))); aLineInfo.SetLineJoin(rLine.getLineJoin()); aLineInfo.SetLineCap(rLine.getLineCap()); @@ -1992,7 +1994,7 @@ void VclMetafileProcessor2D::processPolyPolygonHatchPrimitive2D( aToolsPolyPolygon, Hatch(aHatchStyle, Color(maBColorModifierStack.getModifiedColor(rFillHatchAttribute.getColor())), - basegfx::fround(rFillHatchAttribute.getDistance()), + basegfx::fround<tools::Long>(rFillHatchAttribute.getDistance()), Degree10(basegfx::fround(basegfx::rad2deg<10>(rFillHatchAttribute.getAngle()))))); impEndSvtGraphicFill(pSvtGraphicFill.get()); @@ -2496,8 +2498,10 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D( { auto const range(rStructureTagCandidate.getB2DRange(getViewInformation2D())); tools::Rectangle const aLogicRect( - basegfx::fround(range.getMinX()), basegfx::fround(range.getMinY()), - basegfx::fround(range.getMaxX()), basegfx::fround(range.getMaxY())); + basegfx::fround<tools::Long>(range.getMinX()), + basegfx::fround<tools::Long>(range.getMinY()), + basegfx::fround<tools::Long>(range.getMaxX()), + basegfx::fround<tools::Long>(range.getMaxY())); mpPDFExtOutDevData->SetStructureBoundingBox(aLogicRect); break; } diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 393c4c64d8e8..109be5cd40f9 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -180,7 +180,8 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D( } // Don't draw fonts without height - if (aFont.GetFontHeight() <= 0) + Size aResultFontSize = aFont.GetFontSize(); + if (aResultFontSize.Height() <= 0) return; // set FillColor Attribute @@ -328,8 +329,6 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D( mpOutputDevice->SetLayoutMode(nRTLLayoutMode); } - mpOutputDevice->SetTextColor(Color(aRGBFontColor)); - OUString aText(rTextCandidate.getText()); sal_Int32 nPos = rTextCandidate.getTextPosition(); sal_Int32 nLen = rTextCandidate.getTextLength(); @@ -340,8 +339,8 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D( { tools::Long nWidthToFill = rTextCandidate.getWidthToFill(); - tools::Long nWidth - = mpOutputDevice->GetTextArray(rTextCandidate.getText(), &aDXArray, 0, 1); + tools::Long nWidth = basegfx::fround<tools::Long>( + mpOutputDevice->GetTextArray(rTextCandidate.getText(), &aDXArray, 0, 1)); sal_Int32 nChars = 2; if (nWidth) nChars = nWidthToFill / nWidth; @@ -375,15 +374,17 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D( fIgnoreShearX); const Point aOrigin( - basegfx::fround(aCurrentTranslate.getX() / aCurrentScaling.getX()), - basegfx::fround(aCurrentTranslate.getY() / aCurrentScaling.getY())); + basegfx::fround<tools::Long>(aCurrentTranslate.getX() / aCurrentScaling.getX()), + basegfx::fround<tools::Long>(aCurrentTranslate.getY() + / aCurrentScaling.getY())); MapMode aMapMode(mpOutputDevice->GetMapMode().GetMapUnit(), aOrigin, Fraction(aCurrentScaling.getX()), Fraction(aCurrentScaling.getY())); if (fCurrentRotate) aTextTranslate *= basegfx::utils::createRotateB2DHomMatrix(fCurrentRotate); - aStartPoint = Point(aTextTranslate.getX(), aTextTranslate.getY()); + aStartPoint = Point(basegfx::fround<tools::Long>(aTextTranslate.getX()), + basegfx::fround<tools::Long>(aTextTranslate.getY())); bChangeMapMode = aMapMode != mpOutputDevice->GetMapMode(); if (bChangeMapMode) @@ -395,12 +396,37 @@ void VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D( else { const basegfx::B2DPoint aPoint(aLocalTransform * basegfx::B2DPoint(0.0, 0.0)); - aStartPoint = Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())); + double aPointX = aPoint.getX(), aPointY = aPoint.getY(); + + // aFont has an integer size; we must scale a bit for precision + double nFontScalingFixY = aFontScaling.getY() / aResultFontSize.Height(); + double nFontScalingFixX = aFontScaling.getX() + / (aResultFontSize.Width() ? aResultFontSize.Width() + : aResultFontSize.Height()); + + if (!rtl_math_approxEqual(nFontScalingFixY, 1.0) + || !rtl_math_approxEqual(nFontScalingFixX, 1.0)) + { + MapMode aMapMode = mpOutputDevice->GetMapMode(); + aMapMode.SetScaleX(aMapMode.GetScaleX() * nFontScalingFixX); + aMapMode.SetScaleY(aMapMode.GetScaleY() * nFontScalingFixY); + + mpOutputDevice->Push(vcl::PushFlags::MAPMODE); + mpOutputDevice->SetRelativeMapMode(aMapMode); + bChangeMapMode = true; + + aPointX /= nFontScalingFixX; + aPointY /= nFontScalingFixY; + } + + aStartPoint = Point(basegfx::fround<tools::Long>(aPointX), + basegfx::fround<tools::Long>(aPointY)); } // tdf#152990 set the font after the MapMode is (potentially) set so canvas uses the desired // font size mpOutputDevice->SetFont(aFont); + mpOutputDevice->SetTextColor(Color(aRGBFontColor)); if (!aDXArray.empty()) { @@ -1049,8 +1075,8 @@ void VclProcessor2D::RenderMarkerArrayPrimitive2D( { const basegfx::B2DPoint aDiscreteTopLeft((maCurrentTransformation * pos) - aDiscreteHalfSize); - const Point aDiscretePoint(basegfx::fround(aDiscreteTopLeft.getX()), - basegfx::fround(aDiscreteTopLeft.getY())); + const Point aDiscretePoint(basegfx::fround<tools::Long>(aDiscreteTopLeft.getX()), + basegfx::fround<tools::Long>(aDiscreteTopLeft.getY())); mpOutputDevice->DrawBitmapEx(aDiscretePoint + aOrigin, rMarker); } @@ -1070,8 +1096,8 @@ void VclProcessor2D::RenderPointArrayPrimitive2D( for (auto const& pos : rPositions) { const basegfx::B2DPoint aViewPosition(maCurrentTransformation * pos); - const Point aPos(basegfx::fround(aViewPosition.getX()), - basegfx::fround(aViewPosition.getY())); + const Point aPos(basegfx::fround<tools::Long>(aViewPosition.getX()), + basegfx::fround<tools::Long>(aViewPosition.getY())); mpOutputDevice->DrawPixel(aPos, aVCLColor); } diff --git a/drawinglayer/source/tools/converters.cxx b/drawinglayer/source/tools/converters.cxx index 8167f8bf3f60..66a8fb52e2b2 100644 --- a/drawinglayer/source/tools/converters.cxx +++ b/drawinglayer/source/tools/converters.cxx @@ -338,7 +338,7 @@ BitmapEx convertPrimitive2DContainerToBitmapEx(primitive2d::Primitive2DContainer if (aBitmapEx.IsEmpty()) return BitmapEx(); aBitmapEx.SetPrefMapMode(MapMode(MapUnit::Map100thMM)); - aBitmapEx.SetPrefSize(Size(basegfx::fround(fWidth), basegfx::fround(fHeight))); + aBitmapEx.SetPrefSize(Size(basegfx::fround<tools::Long>(fWidth), basegfx::fround<tools::Long>(fHeight))); return aBitmapEx; } diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 94c4c32f026f..0a3cc2887c1d 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -228,33 +228,33 @@ namespace emfplushelper { } - float EmfPlusHelperData::getUnitToPixelMultiplier(const UnitType aUnitType, const sal_uInt32 aDPI) + double EmfPlusHelperData::unitToPixel(double n, sal_uInt32 aUnitType, Direction d) { - switch (aUnitType) + switch (static_cast<UnitType>(aUnitType)) { case UnitTypePixel: - return 1.0f; + return n; case UnitTypePoint: - return aDPI / 72.0; + return o3tl::convert(n, o3tl::Length::pt, o3tl::Length::in) * DPI(d); case UnitTypeInch: - return aDPI; + return n * DPI(d); case UnitTypeMillimeter: - return aDPI / 25.4; + return o3tl::convert(n, o3tl::Length::mm, o3tl::Length::in) * DPI(d); case UnitTypeDocument: - return aDPI / 300.0; + return n * DPI(d) / 300.0; case UnitTypeWorld: case UnitTypeDisplay: SAL_WARN("drawinglayer.emf", "EMF+\t Converting to World/Display."); - return 1.0f; + return n; default: SAL_WARN("drawinglayer.emf", "EMF+\tTODO Unimplemented support of Unit Type: 0x" << std::hex << aUnitType); - return 1.0f; + return n; } } @@ -280,7 +280,7 @@ namespace emfplushelper EMFPPen *pen = new EMFPPen(); maEMFPObjects[index].reset(pen); pen->Read(rObjectStream, *this); - pen->penWidth = pen->penWidth * getUnitToPixelMultiplier(static_cast<UnitType>(pen->penUnit), mnHDPI); + pen->penWidth = unitToPixel(pen->penWidth, pen->penUnit, Direction::horizontal); break; } case EmfPlusObjectTypePath: @@ -324,7 +324,7 @@ namespace emfplushelper font->fontFlags = 0; font->Read(rObjectStream); // tdf#113624 Convert unit to Pixels - font->emSize = font->emSize * getUnitToPixelMultiplier(static_cast<UnitType>(font->sizeUnit), mnHDPI); + font->emSize = unitToPixel(font->emSize, font->sizeUnit, Direction::horizontal); break; } @@ -1737,8 +1737,8 @@ namespace emfplushelper } else { - mnMmX *= mfPageScale * getUnitToPixelMultiplier(static_cast<UnitType>(flags), mnHDPI); - mnMmY *= mfPageScale * getUnitToPixelMultiplier(static_cast<UnitType>(flags), mnVDPI); + mnMmX = std::round(unitToPixel(static_cast<double>(mnMmX) * mfPageScale, flags, Direction::horizontal)); + mnMmY = std::round(unitToPixel(static_cast<double>(mnMmY) * mfPageScale, flags, Direction::vertical)); mappingChanged(); } break; @@ -1835,12 +1835,12 @@ namespace emfplushelper SAL_WARN("drawinglayer.emf", "EMF+\t file error. UnitTypeDisplay and UnitTypeWorld are not supported by BeginContainer in EMF+ specification."); break; } - const float aPageScaleX = getUnitToPixelMultiplier(static_cast<UnitType>(flags), mnHDPI); - const float aPageScaleY = getUnitToPixelMultiplier(static_cast<UnitType>(flags), mnVDPI); GraphicStatePush(mGSContainerStack, stackIndex); const basegfx::B2DHomMatrix transform = basegfx::utils::createScaleTranslateB2DHomMatrix( - aPageScaleX * ( dw / sw ), aPageScaleY * ( dh / sh ), - aPageScaleX * ( dx - sx ), aPageScaleY * ( dy - sy) ); + unitToPixel(static_cast<double>(dw) / sw, flags, Direction::horizontal), + unitToPixel(static_cast<double>(dh) / sh, flags, Direction::vertical), + unitToPixel(static_cast<double>(dx) - sx, flags, Direction::horizontal), + unitToPixel(static_cast<double>(dy) - sy, flags, Direction::vertical)); maWorldTransform *= transform; mappingChanged(); break; diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx index ef870f31e687..b8006210d2b9 100644 --- a/drawinglayer/source/tools/emfphelperdata.hxx +++ b/drawinglayer/source/tools/emfphelperdata.hxx @@ -244,6 +244,14 @@ namespace emfplushelper // helper functions Color EMFPGetBrushColorOrARGBColor(const sal_uInt16 flags, const sal_uInt32 brushIndexOrColor) const; + enum class Direction + { + horizontal, + vertical + }; + sal_uInt32 DPI(Direction d) { return d == Direction::horizontal ? mnHDPI : mnVDPI; } + double unitToPixel(double n, sal_uInt32 aUnitType, Direction d); + public: EmfPlusHelperData( SvMemoryStream& rMS, @@ -262,8 +270,6 @@ namespace emfplushelper static void ReadRectangle(SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false); static bool readXForm(SvStream& rIn, basegfx::B2DHomMatrix& rTarget); static ::basegfx::B2DPolyPolygon combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon); - - static float getUnitToPixelMultiplier(const UnitType aUnitType, const sal_uInt32 aDPI); }; } diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 3191b7a874e7..937413a0ac15 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -1051,7 +1051,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) tools::Long nCurPos = nTmpWidth+nStartX; // consider scaling if ( aStatus.DoStretch() && ( mnStretchX != 100.0 ) ) - nCurPos = basegfx::fround(double(nCurPos) * 100.0 / std::max(mnStretchX, 1.0)); + nCurPos = basegfx::fround<tools::Long>(double(nCurPos) * 100.0 / std::max(mnStretchX, 1.0)); short nAllSpaceBeforeText = static_cast< short >(rLRItem.GetTextLeft()/* + rLRItem.GetTextLeft()*/ + nSpaceBeforeAndMinLabelWidth); aCurrentTab.aTabStop = pNode->GetContentAttribs().FindTabStop( nCurPos - nAllSpaceBeforeText /*rLRItem.GetTextLeft()*/, aEditDoc.GetDefTab() ); @@ -2993,7 +2993,7 @@ void ImpEditEngine::SeekCursor( ContentNode* pNode, sal_Int32 nPos, SvxFont& rFo if (mnStretchY != 100.0) { double fNewHeight = (double(aRealSz.Height()) * mnStretchY) / 100.0; - aRealSz.setHeight(basegfx::fround(fNewHeight)); + aRealSz.setHeight(basegfx::fround<tools::Long>(fNewHeight)); } if (mnStretchX != 100.0) { @@ -3004,7 +3004,7 @@ void ImpEditEngine::SeekCursor( ContentNode* pNode, sal_Int32 nPos, SvxFont& rFo else { double fNewWidth = (double(aRealSz.Width()) * mnStretchX) / 100.0; - aRealSz.setWidth(basegfx::fround(fNewWidth)); + aRealSz.setWidth(basegfx::fround<tools::Long>(fNewWidth)); // Also the Kerning: (long due to handle Interim results) tools::Long nKerning = rFont.GetFixKerning(); diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx index b484a645a7f6..306b378fc133 100644 --- a/editeng/source/items/svxfont.cxx +++ b/editeng/source/items/svxfont.cxx @@ -37,7 +37,7 @@ static tools::Long GetTextArray( const OutputDevice* pOut, const OUString& rStr, { const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); - return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, true, nullptr, layoutGlyphs); + return basegfx::fround<tools::Long>(pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, true, nullptr, layoutGlyphs)); } SvxFont::SvxFont() diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx index 84097ae2a14b..1673560392e8 100644 --- a/editeng/source/outliner/outliner.cxx +++ b/editeng/source/outliner/outliner.cxx @@ -889,8 +889,8 @@ void Outliner::PaintBullet(sal_Int32 nPara, const Point& rStartPos, const Point& tools::Rectangle aBulletArea( ImpCalcBulletArea( nPara, true, false ) ); double nStretchX, nStretchY; GetGlobalCharStretching(nStretchX, nStretchY); - tools::Long nStretchBulletX = basegfx::fround(double(aBulletArea.Left()) * nStretchX / 100.0); - tools::Long nStretchBulletWidth = basegfx::fround(double(aBulletArea.GetWidth()) * nStretchX / 100.0); + tools::Long nStretchBulletX = basegfx::fround<tools::Long>(double(aBulletArea.Left()) * nStretchX / 100.0); + tools::Long nStretchBulletWidth = basegfx::fround<tools::Long>(double(aBulletArea.GetWidth()) * nStretchX / 100.0); aBulletArea = tools::Rectangle(Point(nStretchBulletX, aBulletArea.Top()), Size(nStretchBulletWidth, aBulletArea.GetHeight()) ); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 930e4f0961dc..627423117b37 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -425,7 +425,7 @@ void Test::TestDrawLine() assertXPath(pDocument, aXPathPrefix + "mask/unifiedtransparence/polypolygonstroke/line", "linecap", "BUTT"); assertXPath(pDocument, aXPathPrefix + "mask/unifiedtransparence/polypolygonstroke/polypolygon", - "path", "m55.5192348773662 403.573503917507 874.352660545936-345.821325648415"); + "path", "m89.1506452315894 403.573503917507 895.170581035125-345.821325648415"); } void Test::TestDrawLineWithCaps() @@ -1343,7 +1343,7 @@ void Test::TestExtTextOutOpaqueAndClipWMF() assertXPath(pDocument, aXPathPrefix + "mask/group[3]/mask/group/polypolygoncolor", "color", "#ff8000"); assertXPath(pDocument, aXPathPrefix + "mask/group[3]/mask/group/polypolygoncolor/polypolygon", - "path", "m1067 1067h1270v473h-1270z"); + "path", "m1067 1067h1317v473h-1317z"); assertXPath(pDocument, aXPathPrefix + "mask/group[3]/mask/group/textsimpleportion", "text", "OOOO"); assertXPath(pDocument, aXPathPrefix + "mask/group[3]/mask/group/textsimpleportion", "fontcolor", diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx index 17c679cc2a06..71687f09807c 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -588,7 +588,7 @@ namespace emfio fX2 -= mrclFrame.Left(); fY2 -= mrclFrame.Top(); } - return Point(basegfx::fround(fX2), basegfx::fround(fY2)); + return Point(basegfx::fround<tools::Long>(fX2), basegfx::fround<tools::Long>(fY2)); } else return Point(); @@ -677,7 +677,7 @@ namespace emfio break; } } - return Size(basegfx::fround(fWidth), basegfx::fround(fHeight)); + return Size(basegfx::fround<tools::Long>(fWidth), basegfx::fround<tools::Long>(fHeight)); } else return Size(); @@ -1670,7 +1670,7 @@ namespace emfio const Size aSizeY(ImplMap(Size(0, nSumY))); const basegfx::B2DVector aVectorY(aSizeY.Width(), aSizeY.Height()); // Reverse Y - pDYArry[i] = basegfx::fround(aVectorY.getLength()); + pDYArry[i] = basegfx::fround<tools::Long>(aVectorY.getLength()); pDYArry[i] *= (nSumY >= 0 ? -1 : 1); } } diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx index 8169a0fb0601..aafea4a53130 100644 --- a/filter/source/msfilter/escherex.cxx +++ b/filter/source/msfilter/escherex.cxx @@ -2864,7 +2864,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT if ( rrProp.Value >>= fExtrusionShininess ) { // ODF to MS Office conversion invers to msdffimp.cxx - fExtrusionShininess = basegfx::fround(fExtrusionShininess / 10.0); + fExtrusionShininess = std::round(fExtrusionShininess / 10.0); AddOpt( DFF_Prop_c3DShininess, static_cast<sal_Int32>(fExtrusionShininess) ); } } diff --git a/filter/source/msfilter/eschesdo.cxx b/filter/source/msfilter/eschesdo.cxx index fe16862df69a..2f8f84bb9dc4 100644 --- a/filter/source/msfilter/eschesdo.cxx +++ b/filter/source/msfilter/eschesdo.cxx @@ -1151,10 +1151,19 @@ void ImplEESdrObject::Init() { // if it's a group, the unrotated range is needed for that group const basegfx::B2DRange aUnrotatedRange(getUnrotatedGroupBoundRange(mXShape)); - const Point aNewP(basegfx::fround(aUnrotatedRange.getMinX()), basegfx::fround(aUnrotatedRange.getMinY())); - const Size aNewS(basegfx::fround(aUnrotatedRange.getWidth()), basegfx::fround(aUnrotatedRange.getHeight())); + if (aUnrotatedRange.isEmpty()) + { + SetRect(tools::Rectangle()); + } + else + { + const Point aNewP(basegfx::fround<tools::Long>(aUnrotatedRange.getMinX()), + basegfx::fround<tools::Long>(aUnrotatedRange.getMinY())); + const Size aNewS(basegfx::fround<tools::Long>(aUnrotatedRange.getWidth()), + basegfx::fround<tools::Long>(aUnrotatedRange.getHeight())); - SetRect(ImplEESdrWriter::ImplMapPoint(aNewP), ImplEESdrWriter::ImplMapSize(aNewS)); + SetRect(ImplEESdrWriter::ImplMapPoint(aNewP), ImplEESdrWriter::ImplMapSize(aNewS)); + } } else { diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx index 963a9ae2c4d4..ef351cc78495 100644 --- a/filter/source/svg/svgfilter.cxx +++ b/filter/source/svg/svgfilter.cxx @@ -327,7 +327,7 @@ bool SVGFilter::filterImpressOrDraw( const Sequence< PropertyValue >& rDescripto static_cast< double >(pTargetSdrPage->GetRightBorder()) / aPageSize.Width() + static_cast< double >(pTargetSdrPage->GetUpperBorder()) / aPageSize.Height() + static_cast< double >(pTargetSdrPage->GetLowerBorder()) / aPageSize.Height()) / 4.0); - const tools::Long nAllBorder(basegfx::fround((aGraphicSize.Width() + aGraphicSize.Height()) * fBorderRelation * 0.5)); + const tools::Long nAllBorder(basegfx::fround<tools::Long>((aGraphicSize.Width() + aGraphicSize.Height()) * fBorderRelation * 0.5)); // Adapt PageSize and Border stuff. To get all MasterPages and PresObjs // correctly adapted, do not just use diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index e4420dc27e71..aa83250f53b6 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -2184,7 +2184,7 @@ void SVGActionWriter::ImplWriteShape( const SVGShapeDescriptor& rShape ) for( size_t k = 0; k < rShape.maDashArray.size(); ++k ) { - const sal_Int32 nDash = ImplMap( FRound( rShape.maDashArray[ k ] ) ); + const sal_Int32 nDash = ImplMap(basegfx::fround(rShape.maDashArray[k])); if( k ) aDashArrayStr.append(","); @@ -2546,8 +2546,8 @@ void SVGActionWriter::ImplWriteMask(GDIMetaFile& rMtf, const Point& rDestPt, con if (fScaleX != 1.0 || fScaleY != 1.0) { rMtf.Scale(fScaleX, fScaleY); - aSrcPt.setX(FRound(aSrcPt.X() * fScaleX)); - aSrcPt.setY(FRound(aSrcPt.Y() * fScaleY)); + aSrcPt.setX(basegfx::fround<tools::Long>(aSrcPt.X() * fScaleX)); + aSrcPt.setY(basegfx::fround<tools::Long>(aSrcPt.Y() * fScaleY)); } nMoveX = rDestPt.X() - aSrcPt.X(); @@ -2690,7 +2690,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText, } else { - aNormSize = Size( mpVDev->GetTextArray( rText, &aTmpArray ), 0 ); + aNormSize = Size(basegfx::fround<tools::Long>(mpVDev->GetTextArray(rText, &aTmpArray)), 0); } // if text is rotated, set transform matrix at new g element @@ -2747,7 +2747,7 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText, const double fFactor = static_cast<double>(nWidth) / aNormSize.Width(); for( i = 0; i < ( nLen - 1 ); i++ ) - aTmpArray.set(i, FRound(aTmpArray[i] * fFactor)); + aTmpArray.set(i, basegfx::fround(aTmpArray[i] * fFactor)); } else { @@ -2811,11 +2811,11 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText, return; tools::Polygon aPoly( 4 ); - const tools::Long nLineHeight = std::max<tools::Long>( FRound( aMetric.GetLineHeight() * 0.05 ), 1 ); + const tools::Long nLineHeight = std::max<tools::Long>( basegfx::fround<tools::Long>( aMetric.GetLineHeight() * 0.05 ), 1 ); if( rFont.GetStrikeout() ) { - const tools::Long nYLinePos = aBaseLinePos.Y() - FRound( aMetric.GetAscent() * 0.26 ); + const tools::Long nYLinePos = aBaseLinePos.Y() - basegfx::fround<tools::Long>( aMetric.GetAscent() * 0.26 ); aPoly[ 0 ].setX( aBaseLinePos.X() ); aPoly[ 0 ].setY( nYLinePos - ( nLineHeight >> 1 ) ); aPoly[ 1 ].setX( aBaseLinePos.X() + aNormSize.Width() - 1 ); aPoly[ 1 ].setY( aPoly[ 0 ].Y() ); @@ -3323,8 +3323,8 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, // i.e. invisible line, because it makes it visible, // resulting an extra line behind the normal shape line if ( aNewLineColor.GetAlpha() > 0 ) - aNewLineColor.SetAlpha( 255 - sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) ); - aNewFillColor.SetAlpha( 255 - sal::static_int_cast<sal_uInt8>( FRound( pA->GetTransparence() * 2.55 ) ) ); + aNewLineColor.SetAlpha( 255 - basegfx::fround<sal_uInt8>( pA->GetTransparence() * 2.55 ) ); + aNewFillColor.SetAlpha( 255 - basegfx::fround<sal_uInt8>( pA->GetTransparence() * 2.55 ) ); maAttributeWriter.AddPaintAttr( aNewLineColor, aNewFillColor ); ImplWritePolyPolygon( rPolyPoly, false ); @@ -3435,7 +3435,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, mapCurShape->maShapePolyPoly = aShapePolyPoly; mapCurShape->maShapeFillColor = aFill.getFillColor(); - mapCurShape->maShapeFillColor.SetAlpha( 255 - static_cast<sal_uInt8>(FRound( 255.0 * aFill.getTransparency() )) ); + mapCurShape->maShapeFillColor.SetAlpha( 255 - basegfx::fround<sal_uInt8>( 255.0 * aFill.getTransparency() ) ); if( bGradient ) { @@ -3525,8 +3525,8 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, } mapCurShape->maShapeLineColor = mpVDev->GetLineColor(); - mapCurShape->maShapeLineColor.SetAlpha( 255 - static_cast<sal_uInt8>(FRound( aStroke.getTransparency() * 255.0 )) ); - mapCurShape->mnStrokeWidth = FRound( aStroke.getStrokeWidth() ); + mapCurShape->maShapeLineColor.SetAlpha( 255 - basegfx::fround<sal_uInt8>( aStroke.getTransparency() * 255.0 ) ); + mapCurShape->mnStrokeWidth = basegfx::fround(aStroke.getStrokeWidth()); aStroke.getDashArray( mapCurShape->maDashArray ); // added support for LineJoin diff --git a/hwpfilter/source/drawing.h b/hwpfilter/source/drawing.h index e3f2a512e7c7..e549896a5eed 100644 --- a/hwpfilter/source/drawing.h +++ b/hwpfilter/source/drawing.h @@ -491,7 +491,6 @@ int cmd, void * /*argp*/, int /*argv*/) return HWPDODefaultFunc(cmd); } -#define WTMM(x) ((double)(x) / 1800. * 25.4) static int HWPDOEllipse2Func(int /*type*/, HWPDrawingObject * hdo, int cmd, void * /*argp*/, int /*argv*/) diff --git a/include/basegfx/numeric/ftools.hxx b/include/basegfx/numeric/ftools.hxx index 1e7f0a34e71c..b286c847968c 100644 --- a/include/basegfx/numeric/ftools.hxx +++ b/include/basegfx/numeric/ftools.hxx @@ -35,27 +35,25 @@ namespace basegfx @return the nearest integer */ - inline sal_Int32 fround( double fVal ) + template <class Int = sal_Int32> + inline std::enable_if_t<std::is_integral_v<Int>, Int> fround(double fVal) { if (fVal >= 0.0) { - if (fVal >= std::numeric_limits<sal_Int32>::max() - .5) - return std::numeric_limits<sal_Int32>::max(); - return static_cast<sal_Int32>(fVal + .5); + if (fVal >= static_cast<double>(std::numeric_limits<Int>::max()) - 0.5) + return std::numeric_limits<Int>::max(); + return static_cast<Int>(fVal + .5); } - if (fVal <= std::numeric_limits<sal_Int32>::min() + .5) - return std::numeric_limits<sal_Int32>::min(); - return static_cast<sal_Int32>(fVal - .5); + if (fVal <= static_cast<double>(std::numeric_limits<Int>::min()) + 0.5) + return std::numeric_limits<Int>::min(); + return static_cast<Int>(fVal - .5); } /** Round double to nearest integer @return the nearest 64 bit integer */ - inline sal_Int64 fround64( double fVal ) - { - return fVal > 0.0 ? static_cast<sal_Int64>( fVal + .5 ) : -static_cast<sal_Int64>( -fVal + .5 ); - } + inline sal_Int64 fround64(double fVal) { return fround<sal_Int64>(fVal); } /** Prune a small epsilon range around zero. diff --git a/include/drawinglayer/primitive2d/textlayoutdevice.hxx b/include/drawinglayer/primitive2d/textlayoutdevice.hxx index 6348de0ddd25..a2e45f1bd8b5 100644 --- a/include/drawinglayer/primitive2d/textlayoutdevice.hxx +++ b/include/drawinglayer/primitive2d/textlayoutdevice.hxx @@ -63,6 +63,8 @@ class DRAWINGLAYER_DLLPUBLIC TextLayouterDevice /// internally used VirtualDevice SolarMutexGuard maSolarGuard; VirtualDevice& mrDevice; + double mnFontScalingFixX = 1.0; + double mnFontScalingFixY = 1.0; public: /// constructor/destructor diff --git a/include/svx/svdtrans.hxx b/include/svx/svdtrans.hxx index 0087f5407f81..88bbfc6fa1ed 100644 --- a/include/svx/svdtrans.hxx +++ b/include/svx/svdtrans.hxx @@ -94,27 +94,27 @@ inline void ResizePoint(Point& rPnt, const Point& rRef, const Fraction& xFract, { double nxFract = xFract.IsValid() ? static_cast<double>(xFract) : 1.0; double nyFract = yFract.IsValid() ? static_cast<double>(yFract) : 1.0; - rPnt.setX(rRef.X() + FRound( (rPnt.X() - rRef.X()) * nxFract )); - rPnt.setY(rRef.Y() + FRound( (rPnt.Y() - rRef.Y()) * nyFract )); + rPnt.setX(rRef.X() + basegfx::fround<tools::Long>((rPnt.X() - rRef.X()) * nxFract)); + rPnt.setY(rRef.Y() + basegfx::fround<tools::Long>((rPnt.Y() - rRef.Y()) * nyFract)); } inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs) { tools::Long dx=rPnt.X()-rRef.X(); tools::Long dy=rPnt.Y()-rRef.Y(); - rPnt.setX(FRound(rRef.X()+dx*cs+dy*sn)); - rPnt.setY(FRound(rRef.Y()+dy*cs-dx*sn)); + rPnt.setX(basegfx::fround<tools::Long>(rRef.X() + dx * cs + dy * sn)); + rPnt.setY(basegfx::fround<tools::Long>(rRef.Y() + dy * cs - dx * sn)); } inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear) { if (!bVShear) { // Horizontal if (rPnt.Y()!=rRef.Y()) { // else not needed - rPnt.AdjustX(-FRound((rPnt.Y()-rRef.Y())*tn)); + rPnt.AdjustX(basegfx::fround<tools::Long>((rRef.Y() - rPnt.Y()) * tn)); } } else { // or else vertical if (rPnt.X()!=rRef.X()) { // else not needed - rPnt.AdjustY(-FRound((rPnt.X()-rRef.X())*tn)); + rPnt.AdjustY(basegfx::fround<tools::Long>((rRef.X() - rPnt.X()) * tn)); } } } diff --git a/include/svx/transfrmhelper.hxx b/include/svx/transfrmhelper.hxx index 9e683d44522f..f544553d22a2 100644 --- a/include/svx/transfrmhelper.hxx +++ b/include/svx/transfrmhelper.hxx @@ -31,11 +31,11 @@ namespace TransfrmHelper inline void ConvertRect(basegfx::B2DRange& rRange, const sal_uInt16 nDigits, const MapUnit ePoolUnit, const FieldUnit eDlgUnit) { const basegfx::B2DPoint aTopLeft( - static_cast<double>(vcl::ConvertValue(basegfx::fround(rRange.getMinX()), nDigits, ePoolUnit, eDlgUnit)), - static_cast<double>(vcl::ConvertValue(basegfx::fround(rRange.getMinY()), nDigits, ePoolUnit, eDlgUnit))); + static_cast<double>(vcl::ConvertValue(basegfx::fround64(rRange.getMinX()), nDigits, ePoolUnit, eDlgUnit)), + static_cast<double>(vcl::ConvertValue(basegfx::fround64(rRange.getMinY()), nDigits, ePoolUnit, eDlgUnit))); const basegfx::B2DPoint aBottomRight( - static_cast<double>(vcl::ConvertValue(basegfx::fround(rRange.getMaxX()), nDigits, ePoolUnit, eDlgUnit)), - static_cast<double>(vcl::ConvertValue(basegfx::fround(rRange.getMaxY()), nDigits, ePoolUnit, eDlgUnit))); + static_cast<double>(vcl::ConvertValue(basegfx::fround64(rRange.getMaxX()), nDigits, ePoolUnit, eDlgUnit)), + static_cast<double>(vcl::ConvertValue(basegfx::fround64(rRange.getMaxY()), nDigits, ePoolUnit, eDlgUnit))); rRange = basegfx::B2DRange(aTopLeft, aBottomRight); } diff --git a/include/tools/helpers.hxx b/include/tools/helpers.hxx index 5f61ba80836c..d0fb08f70e5b 100644 --- a/include/tools/helpers.hxx +++ b/include/tools/helpers.hxx @@ -71,14 +71,6 @@ inline sal_uInt32 AlignedWidth4Bytes(sal_uInt32 nWidthBits) return (nWidthBits >> 5) << 2; } -inline tools::Long FRound( double fVal ) -{ - return fVal > 0.0 - ? fVal == double(std::numeric_limits<tools::Long>::max()) - ? std::numeric_limits<tools::Long>::max() : static_cast<tools::Long>( fVal + 0.5 ) - : static_cast<tools::Long>( fVal - 0.5 ); -} - //valid range: (-180,180] template <typename T> [[nodiscard]] inline typename std::enable_if<std::is_signed<T>::value, T>::type diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index 123b48fcd752..19dc78bc5d76 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -20,6 +20,9 @@ #ifndef INCLUDED_VCL_BITMAP_HXX #define INCLUDED_VCL_BITMAP_HXX +#include <sal/config.h> + +#include <basegfx/numeric/ftools.hxx> #include <tools/degree.hxx> #include <vcl/checksum.hxx> #include <vcl/dllapi.h> @@ -32,7 +35,10 @@ #include <memory> -#define GAMMA( _def_cVal, _def_InvGamma ) (static_cast<sal_uInt8>(MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0,255))) +inline sal_uInt8 GAMMA(double _def_cVal, double _def_InvGamma) +{ + return basegfx::fround<sal_uInt8>(pow(_def_cVal / 255.0, _def_InvGamma) * 255.0); +} class Color; diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 6b864213a66d..098a5ccc5ef0 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -54,6 +54,7 @@ #include <vcl/settings.hxx> #include <vcl/vclreferencebase.hxx> +#include <basegfx/range/b2drectangle.hxx> #include <basegfx/numeric/ftools.hxx> #include <basegfx/vector/b2enums.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> @@ -960,6 +961,11 @@ public: sal_uLong nLayoutWidth = 0, KernArraySpan aDXArray = KernArraySpan(), o3tl::span<const sal_Bool> pKashidaArray = {}, const SalLayoutGlyphs* pGlyphs = nullptr ) const; + bool GetTextBoundRect( basegfx::B2DRectangle& rRect, + const OUString& rStr, sal_Int32 nBase = 0, sal_Int32 nIndex = 0, sal_Int32 nLen = -1, + sal_uLong nLayoutWidth = 0, KernArraySpan aDXArray = KernArraySpan(), + o3tl::span<const sal_Bool> pKashidaArray = {}, + const SalLayoutGlyphs* pGlyphs = nullptr ) const; tools::Rectangle ImplGetTextBoundRect( const SalLayout& ) const; @@ -1027,12 +1033,16 @@ public: tools::Long GetTextWidth( const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1, vcl::text::TextLayoutCache const* = nullptr, SalLayoutGlyphs const*const pLayoutCache = nullptr) const; + double GetTextWidthDouble(const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1, + vcl::text::TextLayoutCache const* = nullptr, + SalLayoutGlyphs const* const pLayoutCache = nullptr) const; /** Height where any character of the current font fits; in logic coordinates. See also GetTextBoundRect() for more explanation + code examples. */ tools::Long GetTextHeight() const; + double GetTextHeightDouble() const; float approximate_digit_width() const; void DrawTextArray( const Point& rStartPt, const OUString& rStr, @@ -1042,7 +1052,7 @@ public: sal_Int32 nLen, SalLayoutFlags flags = SalLayoutFlags::NONE, const SalLayoutGlyphs* pLayoutCache = nullptr); - tools::Long GetTextArray( const OUString& rStr, KernArray* pDXAry, + double GetTextArray( const OUString& rStr, KernArray* pDXAry, sal_Int32 nIndex = 0, sal_Int32 nLen = -1, bool bCaret = false, vcl::text::TextLayoutCache const* = nullptr, SalLayoutGlyphs const*const pLayoutCache = nullptr) const; @@ -1627,6 +1637,7 @@ public: SAL_WARN_UNUSED_RESULT tools::Polygon PixelToLogic(const tools::Polygon& rDevicePoly) const; SAL_WARN_UNUSED_RESULT tools::PolyPolygon PixelToLogic(const tools::PolyPolygon& rDevicePolyPoly) const; SAL_WARN_UNUSED_RESULT basegfx::B2DPolyPolygon PixelToLogic(const basegfx::B2DPolyPolygon& rDevicePolyPoly) const; + SAL_WARN_UNUSED_RESULT basegfx::B2DRectangle PixelToLogic(const basegfx::B2DRectangle& rDeviceRect) const; SAL_WARN_UNUSED_RESULT vcl::Region PixelToLogic(const vcl::Region& rDeviceRegion) const; SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point& rDevicePt, const MapMode& rMapMode) const; SAL_WARN_UNUSED_RESULT Size PixelToLogic(const Size& rDeviceSize, const MapMode& rMapMode) const; @@ -1834,6 +1845,9 @@ private: */ SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel( tools::Long nY ) const; + SAL_DLLPRIVATE double ImplDevicePixelToLogicWidthDouble(double nWidth) const; + SAL_DLLPRIVATE double ImplDevicePixelToLogicHeightDouble(double nHeight) const; + /** @name Native Widget Rendering functions These all just call through to the private mpGraphics functions of the same name. diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx index 4705a44d9b92..887480ce3ee9 100644 --- a/include/vcl/vcllayout.hxx +++ b/include/vcl/vcllayout.hxx @@ -20,6 +20,7 @@ #pragma once #include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/b2drectangle.hxx> #include <i18nlangtag/languagetag.hxx> #include <tools/gen.hxx> #include <tools/degree.hxx> @@ -103,7 +104,9 @@ public: virtual bool GetNextGlyph(const GlyphItem** pGlyph, DevicePoint& rPos, int& nStart, const LogicalFontInstance** ppGlyphFont = nullptr) const = 0; virtual bool GetOutline(basegfx::B2DPolyPolygonVector&) const; - bool GetBoundRect(tools::Rectangle&) const; + bool GetBoundRect(basegfx::B2DRectangle&) const; + + static tools::Rectangle BoundRect2Rectangle(basegfx::B2DRectangle&); virtual SalLayoutGlyphs GetGlyphs() const; diff --git a/sc/qa/uitest/chart/chartLegend.py b/sc/qa/uitest/chart/chartLegend.py index 45938e23017d..fe0525a0746d 100644 --- a/sc/qa/uitest/chart/chartLegend.py +++ b/sc/qa/uitest/chart/chartLegend.py @@ -88,7 +88,7 @@ class chartLegend(UITestCase): xLegends.executeAction("SELECT", tuple()) with self.ui_test.execute_dialog_through_action(xLegends, "COMMAND", mkPropertyValues({"COMMAND": "TransformDialog"})) as xDialog: - self.assertEqual("4.61", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value']) + self.assertEqual("4.59", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value']) self.assertEqual("1.54", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_Y"))['Value']) xChartMain.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) @@ -96,7 +96,7 @@ class chartLegend(UITestCase): # Check the position has changed after moving the label using the arrows keys with self.ui_test.execute_dialog_through_action(xLegends, "COMMAND", mkPropertyValues({"COMMAND": "TransformDialog"})) as xDialog: - self.assertEqual("4.51", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value']) + self.assertEqual("4.49", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_X"))['Value']) self.assertEqual("1.44", get_state_as_dict(xDialog.getChild("MTR_FLD_POS_Y"))['Value']) def test_Tdf147394(self): diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 5627c8b889ec..c4bd1b2f90b1 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -899,8 +899,8 @@ void ScDrawLayer::ResizeLastRectFromAnchor(const SdrObject* pObj, ScDrawObjData& // apply to aRect aRect = tools::Rectangle( - basegfx::fround(aNewRange.getMinX()), basegfx::fround(aNewRange.getMinY()), - basegfx::fround(aNewRange.getMaxX()), basegfx::fround(aNewRange.getMaxY())); + basegfx::fround<tools::Long>(aNewRange.getMinX()), basegfx::fround<tools::Long>(aNewRange.getMinY()), + basegfx::fround<tools::Long>(aNewRange.getMaxX()), basegfx::fround<tools::Long>(aNewRange.getMaxY())); } } } @@ -963,10 +963,10 @@ void ScDrawLayer::InitializeCellAnchoredObj(SdrObject* pObj, ScDrawObjData& rDat static_cast<SdrPathObj*>(pObj)->GetPathPoly().getB2DPolygon(0)); const basegfx::B2DPoint aB2DPoint0(aPoly.getB2DPoint(0)); const basegfx::B2DPoint aB2DPoint1(aPoly.getB2DPoint(1)); - const Point aPointLT(FRound(std::min(aB2DPoint0.getX(), aB2DPoint1.getX())), - FRound(std::min(aB2DPoint0.getY(), aB2DPoint1.getY()))); - const Point aPointRB(FRound(std::max(aB2DPoint0.getX(), aB2DPoint1.getX())), - FRound(std::max(aB2DPoint0.getY(), aB2DPoint1.getY()))); + const Point aPointLT(basegfx::fround<tools::Long>(std::min(aB2DPoint0.getX(), aB2DPoint1.getX())), + basegfx::fround<tools::Long>(std::min(aB2DPoint0.getY(), aB2DPoint1.getY()))); + const Point aPointRB(basegfx::fround<tools::Long>(std::max(aB2DPoint0.getX(), aB2DPoint1.getX())), + basegfx::fround<tools::Long>(std::max(aB2DPoint0.getY(), aB2DPoint1.getY()))); const tools::Rectangle aObjRect(aPointLT, aPointRB); GetCellAnchorFromPosition(aObjRect, rNoRotatedAnchor, *pDoc, nTab1, false /*bHiddenAsZero*/); diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx index 877c412a5966..5707f8796526 100644 --- a/sc/source/ui/miscdlgs/autofmt.cxx +++ b/sc/source/ui/miscdlgs/autofmt.cxx @@ -249,7 +249,7 @@ void ScAutoFmtPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCo Size aStrSize; sal_uInt16 nFmtIndex = GetFormatIndex( nCol, nRow ); const basegfx::B2DRange cellRange(maArray.GetCellRange( nCol, nRow )); - Point aPos(basegfx::fround(cellRange.getMinX()), basegfx::fround(cellRange.getMinY())); + Point aPos(basegfx::fround<tools::Long>(cellRange.getMinX()), basegfx::fround<tools::Long>(cellRange.getMinY())); sal_uInt16 nRightX = 0; bool bJustify = pCurData->GetIncludeJustify(); SvxCellHorJustify eJustification; @@ -269,7 +269,7 @@ void ScAutoFmtPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCo MakeFonts(rRenderContext, nFmtIndex, aFont, aCJKFont, aCTLFont); - theMaxStrSize = Size(basegfx::fround(cellRange.getWidth()), basegfx::fround(cellRange.getHeight())); + theMaxStrSize = Size(basegfx::fround<tools::Long>(cellRange.getWidth()), basegfx::fround<tools::Long>(cellRange.getHeight())); theMaxStrSize.AdjustWidth( -(FRAME_OFFSET) ); theMaxStrSize.AdjustHeight( -(FRAME_OFFSET) ); @@ -375,8 +375,8 @@ void ScAutoFmtPreview::DrawBackground(vcl::RenderContext& rRenderContext) const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow )); rRenderContext.DrawRect( tools::Rectangle( - basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()), - basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()))); + basegfx::fround<tools::Long>(aCellRange.getMinX()), basegfx::fround<tools::Long>(aCellRange.getMinY()), + basegfx::fround<tools::Long>(aCellRange.getMaxX()), basegfx::fround<tools::Long>(aCellRange.getMaxY()))); rRenderContext.Pop(); } diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 24aec4aa5da2..073026840f0a 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -1077,8 +1077,8 @@ bool ScDrawView::calculateGridOffsetForB2DRange( // the object as we want to maintain page anchoring ) ScDrawObjData aAnchor; const tools::Rectangle aRectangle( - basegfx::fround(rB2DRange.getMinX()), basegfx::fround(rB2DRange.getMinY()), - basegfx::fround(rB2DRange.getMaxX()), basegfx::fround(rB2DRange.getMaxY())); + basegfx::fround<tools::Long>(rB2DRange.getMinX()), basegfx::fround<tools::Long>(rB2DRange.getMinY()), + basegfx::fround<tools::Long>(rB2DRange.getMaxX()), basegfx::fround<tools::Long>(rB2DRange.getMaxY())); ScDrawLayer::GetCellAnchorFromPosition( aRectangle, aAnchor, diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx index 36293f2dcfe2..681f137f4dbb 100644 --- a/sd/qa/unit/layout-tests.cxx +++ b/sd/qa/unit/layout-tests.cxx @@ -103,7 +103,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf128212) xmlDocUniquePtr pXmlDoc = load("pptx/tdf128212.pptx"); // Without the fix in place, this test would have failed with - // - Expected: 7797 + // - Expected: 7795 // - Actual : 12068 assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "x", "4525"); assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray", "y", "7797"); @@ -310,7 +310,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testFitToFrameTextFitting) assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]", "y", "406"); assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", "first", "114"); #ifndef _WIN32 // Windows seems to differ in text layouting, so ignore for now - assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", "last", "7010"); + assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[1]/dxarray", "last", "6984"); #endif } diff --git a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx index f3beb12b3ce1..1468f130cf11 100644 --- a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx +++ b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx @@ -655,8 +655,7 @@ void LOKitSearchTest::testSearchIn2MixedObjects() CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size()); CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size()); - CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"), - mpCallbackRecorder->m_aSearchResultSelection[0]); + CPPUNIT_ASSERT_EQUAL("3545, 3174, 740, 402", mpCallbackRecorder->m_aSearchResultSelection[0]); // Search next @@ -681,8 +680,7 @@ void LOKitSearchTest::testSearchIn2MixedObjects() CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size()); CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size()); - CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"), - mpCallbackRecorder->m_aSearchResultSelection[0]); + CPPUNIT_ASSERT_EQUAL("3545, 3174, 740, 402", mpCallbackRecorder->m_aSearchResultSelection[0]); } // Test searching in document with mixed objects. We have 6 objects. diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx index 0b1be5faadd0..cb773a0ca16f 100644 --- a/sd/source/core/sdpage.cxx +++ b/sd/source/core/sdpage.cxx @@ -1431,19 +1431,19 @@ static void CalcAutoLayoutRectangles( SdPage const & rPage,::tools::Rectangle* r if(count == 0) { Size aSize ( aTitleRect.GetSize() ); - aSize.setHeight( basegfx::fround(aSize.Height() * propvalue[0]) ); - aSize.setWidth( basegfx::fround(aSize.Width() * propvalue[1]) ); - Point aPos( basegfx::fround(aTitlePos.X() +(aSize.Width() * propvalue[2])), - basegfx::fround(aTitlePos.Y() + (aSize.Height() * propvalue[3])) ); + aSize.setHeight( basegfx::fround<::tools::Long>(aSize.Height() * propvalue[0]) ); + aSize.setWidth( basegfx::fround<::tools::Long>(aSize.Width() * propvalue[1]) ); + Point aPos( basegfx::fround<::tools::Long>(aTitlePos.X() +(aSize.Width() * propvalue[2])), + basegfx::fround<::tools::Long>(aTitlePos.Y() + (aSize.Height() * propvalue[3])) ); rRectangle[count] = ::tools::Rectangle(aPos, aSize); count = count+1; } else { - Size aSize( basegfx::fround(aLayoutSize.Width() * propvalue[1]), - basegfx::fround(aLayoutSize.Height() * propvalue[0]) ); - Point aPos( basegfx::fround(aLayoutPos.X() +(aSize.Width() * propvalue[2])), - basegfx::fround(aLayoutPos.Y() + (aSize.Height() * propvalue[3])) ); + Size aSize( basegfx::fround<::tools::Long>(aLayoutSize.Width() * propvalue[1]), + basegfx::fround<::tools::Long>(aLayoutSize.Height() * propvalue[0]) ); + Point aPos( basegfx::fround<::tools::Long>(aLayoutPos.X() +(aSize.Width() * propvalue[2])), + basegfx::fround<::tools::Long>(aLayoutPos.Y() + (aSize.Height() * propvalue[3])) ); rRectangle[count] = ::tools::Rectangle (aPos, aSize); count = count+1; } diff --git a/sd/source/filter/html/htmlex.cxx b/sd/source/filter/html/htmlex.cxx index aed0312bc812..7f41e2966a4d 100644 --- a/sd/source/filter/html/htmlex.cxx +++ b/sd/source/filter/html/htmlex.cxx @@ -2774,7 +2774,8 @@ OUString HtmlExport::CreateHTMLPolygonArea( const ::basegfx::B2DPolyPolygon& rPo for ( sal_uInt32 nPoint = 0; nPoint < nNoOfPoints; nPoint++ ) { const ::basegfx::B2DPoint aB2DPoint(aPolygon.getB2DPoint(nPoint)); - Point aPnt(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY())); + Point aPnt(basegfx::fround<tools::Long>(aB2DPoint.getX()), + basegfx::fround<tools::Long>(aB2DPoint.getY())); // coordinates are relative to the physical page origin, not the // origin of ordinates aPnt.Move(aShift.Width(), aShift.Height()); diff --git a/sd/source/ui/app/optsitem.cxx b/sd/source/ui/app/optsitem.cxx index fb9aac86d491..1736a20e0c6c 100644 --- a/sd/source/ui/app/optsitem.cxx +++ b/sd/source/ui/app/optsitem.cxx @@ -1042,13 +1042,13 @@ bool SdOptionsGrid::ReadData( const Any* pValues ) if( pValues[2].hasValue() ) { - const sal_uInt32 nDivX = FRound( *o3tl::doAccess<double>(pValues[ 2 ]) ); + const sal_uInt32 nDivX = basegfx::fround<sal_uInt32>(*o3tl::doAccess<double>(pValues[2])); SetFieldDivisionX( SvxOptionsGrid::GetFieldDrawX() / ( nDivX + 1 ) ); } if( pValues[3].hasValue() ) { - const sal_uInt32 nDivY = FRound( *o3tl::doAccess<double>(pValues[ 3 ]) ); + const sal_uInt32 nDivY = basegfx::fround<sal_uInt32>(*o3tl::doAccess<double>(pValues[3])); SetFieldDivisionY( SvxOptionsGrid::GetFieldDrawY() / ( nDivY + 1 ) ); } diff --git a/sd/source/ui/dlg/vectdlg.cxx b/sd/source/ui/dlg/vectdlg.cxx index 4069aa225f44..ee407b7eb8ca 100644 --- a/sd/source/ui/dlg/vectdlg.cxx +++ b/sd/source/ui/dlg/vectdlg.cxx @@ -221,9 +221,9 @@ void SdVectorizeDlg::AddTile( BitmapReadAccess const * pRAcc, GDIMetaFile& rMtf, } } - const Color aColor( static_cast<sal_uInt8>(FRound( nSumR * fMult )), - static_cast<sal_uInt8>(FRound( nSumG * fMult )), - static_cast<sal_uInt8>(FRound( nSumB * fMult )) ); + const Color aColor( basegfx::fround<sal_uInt8>( nSumR * fMult ), + basegfx::fround<sal_uInt8>( nSumG * fMult ), + basegfx::fround<sal_uInt8>( nSumB * fMult ) ); ::tools::Rectangle aRect( Point( nPosX, nPosY ), Size( nWidth + 1, nHeight + 1 ) ); const Size& rMaxSize = rMtf.GetPrefSize(); diff --git a/sd/source/ui/func/fuoaprms.cxx b/sd/source/ui/func/fuoaprms.cxx index 0feaabfb4736..893f833fcdf1 100644 --- a/sd/source/ui/func/fuoaprms.cxx +++ b/sd/source/ui/func/fuoaprms.cxx @@ -662,7 +662,8 @@ void FuObjectAnimationParameters::DoExecute( SfxRequest& rReq ) const ::basegfx::B2DPolygon& aPolygon(rPolyPolygon.getB2DPolygon(nNoOfPolygons - 1)); sal_uInt32 nPoints(aPolygon.count()); const ::basegfx::B2DPoint aNewB2DCenter(aPolygon.getB2DPoint(nPoints - 1)); - const Point aNewCenter(FRound(aNewB2DCenter.getX()), FRound(aNewB2DCenter.getY())); + const Point aNewCenter(basegfx::fround<::tools::Long>(aNewB2DCenter.getX()), + basegfx::fround<::tools::Long>(aNewB2DCenter.getY())); Size aDistance(aNewCenter.X() - aCurCenter.X(), aNewCenter.Y() - aCurCenter.Y()); pRunningObj->Move(aDistance); diff --git a/sd/source/ui/view/drviews8.cxx b/sd/source/ui/view/drviews8.cxx index 0f2907d424ba..15be1d1c95d0 100644 --- a/sd/source/ui/view/drviews8.cxx +++ b/sd/source/ui/view/drviews8.cxx @@ -74,13 +74,13 @@ void DrawViewShell::ScannerEvent() if( fGrfWH < fWinWH ) { - aBmpSize.setWidth( FRound( aPageSize.Height() * fGrfWH ) ); + aBmpSize.setWidth( basegfx::fround<::tools::Long>( aPageSize.Height() * fGrfWH ) ); aBmpSize.setHeight( aPageSize.Height() ); } else if( fGrfWH > 0.F ) { aBmpSize.setWidth( aPageSize.Width() ); - aBmpSize.setHeight( FRound( aPageSize.Width() / fGrfWH ) ); + aBmpSize.setHeight( basegfx::fround<::tools::Long>( aPageSize.Width() / fGrfWH ) ); } } diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx index a3b5226917d3..847d44d00820 100644 --- a/sfx2/source/doc/objcont.cxx +++ b/sfx2/source/doc/objcont.cxx @@ -171,13 +171,13 @@ bool SfxObjectShell::CreatePreview_Impl( bool bFullContent, VirtualDevice* pDevi double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height(); if ( fWH <= 1.0 ) { - aSizePix.setWidth( FRound( nMaximumExtent * fWH ) ); + aSizePix.setWidth(basegfx::fround<tools::Long>(nMaximumExtent * fWH)); aSizePix.setHeight( nMaximumExtent ); } else { aSizePix.setWidth( nMaximumExtent ); - aSizePix.setHeight( FRound( nMaximumExtent / fWH ) ); + aSizePix.setHeight(basegfx::fround<tools::Long>(nMaximumExtent / fWH)); } } // do it 4x larger to be able to scale it down & get beautiful antialias diff --git a/slideshow/source/engine/shapes/drawinglayeranimation.cxx b/slideshow/source/engine/shapes/drawinglayeranimation.cxx index d0d3acb66369..ea765eea9649 100644 --- a/slideshow/source/engine/shapes/drawinglayeranimation.cxx +++ b/slideshow/source/engine/shapes/drawinglayeranimation.cxx @@ -422,7 +422,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes() const double fNumberSteps = (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic(); - nLoopTime = FRound(fNumberSteps * mnFrequency); + nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency); // init loop ScrollTextAnimNode aInitNode( @@ -451,7 +451,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes() const double fNumberSteps = (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic(); - nLoopTime = FRound(fNumberSteps * mnFrequency); + nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency); if(0 == mnRepeat) { @@ -501,7 +501,7 @@ void ActivityImpl::ImpForceScrollTextAnimNodes() const double fNumberSteps = (fRelativeDistance * fDistanceLogic) / GetStepWidthLogic(); - nLoopTime = FRound(fNumberSteps * mnFrequency); + nLoopTime = basegfx::fround<sal_uInt32>(fNumberSteps * mnFrequency); // exit loop ScrollTextAnimNode aExitNode( diff --git a/slideshow/source/engine/slideview.cxx b/slideshow/source/engine/slideview.cxx index 26c4e0f971bb..70d5f33e7cd6 100644 --- a/slideshow/source/engine/slideview.cxx +++ b/slideshow/source/engine/slideview.cxx @@ -523,8 +523,8 @@ private: // translation when aTmpRect was not properly initialized. if ( ! aTmpRect.isEmpty()) { - aMatrix.translate( -basegfx::fround(aTmpRect.getMinX()), - -basegfx::fround(aTmpRect.getMinY()) ); + aMatrix.translate( -std::round(aTmpRect.getMinX()), + -std::round(aTmpRect.getMinY()) ); } return aMatrix; diff --git a/svgio/inc/SvgNumber.hxx b/svgio/inc/SvgNumber.hxx index fe4ab8e2683e..c62576c2b082 100644 --- a/svgio/inc/SvgNumber.hxx +++ b/svgio/inc/SvgNumber.hxx @@ -39,8 +39,8 @@ public: virtual basegfx::B2DRange getCurrentViewPort() const = 0; /// return font size of node, either set here or inherited from parents virtual double getCurrentFontSize() const = 0; - /// return xheight of node inherited from parents - virtual double getCurrentXHeightInherited() const = 0; + /// return xheight of node, either set here or inherited from parents + virtual double getCurrentXHeight() const = 0; }; enum class SvgUnit diff --git a/svgio/inc/svgnode.hxx b/svgio/inc/svgnode.hxx index 5d3a2453d727..d24cdecf3729 100644 --- a/svgio/inc/svgnode.hxx +++ b/svgio/inc/svgnode.hxx @@ -157,9 +157,7 @@ namespace svgio::svgreader /// InfoProvider support for %, em and ex values virtual basegfx::B2DRange getCurrentViewPort() const override; virtual double getCurrentFontSize() const override; - virtual double getCurrentXHeightInherited() const override; - - double getCurrentXHeight() const; + virtual double getCurrentXHeight() const override; /// Id access std::optional<OUString> const & getId() const { return mpId; } diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index 4d6f7568e2cd..7a8706556129 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -41,6 +41,8 @@ protected: void checkRectPrimitive(Primitive2DSequence const & rPrimitive); Primitive2DSequence parseSvg(std::u16string_view aSource); + void assertXPathDouble(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, + const OString& rAttribute, double nExpectedValue, double delta); }; Primitive2DSequence Test::parseSvg(std::u16string_view aSource) @@ -82,6 +84,13 @@ void Test::checkRectPrimitive(Primitive2DSequence const & rPrimitive) } +void Test::assertXPathDouble(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, + const OString& rAttribute, double nExpectedValue, double delta) +{ + auto sVal = getXPath(pXmlDoc, rXPath, rAttribute); + CPPUNIT_ASSERT_DOUBLES_EQUAL(nExpectedValue, sVal.toDouble(), delta); +} + bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB) { return std::equal(rA.begin(), rA.end(), rB.begin(), rB.end(), @@ -1148,7 +1157,7 @@ CPPUNIT_TEST_FIXTURE(Test, testDyInEms) CPPUNIT_TEST_FIXTURE(Test, testExs) { - // tdf#160594 given an SVG file with <tspan dy="3ex" style="font-size:1ex">: + // tdf#160594, tdf#160717 given an SVG file with <tspan dy="3ex" style="font-size:1ex">: std::u16string_view aPath = u"/svgio/qa/cppunit/data/dy_in_exs.svg"; Primitive2DSequence aSequence = parseSvg(aPath); drawinglayer::Primitive2dXmlDump aDumper; @@ -1156,6 +1165,7 @@ CPPUNIT_TEST_FIXTURE(Test, testExs) assertXPath(pDocument, "//textsimpleportion", 2); assertXPath(pDocument, "//textsimpleportion[1]", "height", "16"); + assertXPath(pDocument, "//textsimpleportion[1]", "y", "20"); sal_Int32 nSize = getXPath(pDocument, "//textsimpleportion[2]", "height").toInt32(); // Without the accompanying fix in place, this test would have failed with: @@ -1163,6 +1173,17 @@ CPPUNIT_TEST_FIXTURE(Test, testExs) // - Actual : 16 // i.e. the parent font-size was used, instead of its x-size. CPPUNIT_ASSERT_LESS(sal_Int32(16), nSize); + + sal_Int32 nYPos = getXPath(pDocument, "//textsimpleportion[2]", "y").toInt32(); + // Then make sure that the vertical offset is based on x-size of tspan, not of its parent. + // Given the tspan's font-size is nSize, its x-size is less than nSize, and the expected + // vertical offset is less than 3 * nSize, which means that the resulting y is expected + // to be strictly less than 20 + 3 * nSize. + // Without the accompanying fix in place, this test would have failed with: + // - Expected less than: 44 + // - Actual : 44 + // i.e. the parent x-size (or current font-size) was used, instead of current x-size. + CPPUNIT_ASSERT_LESS(sal_Int32(20 + 3 * nSize), nYPos); } } diff --git a/svgio/qa/cppunit/SvgNumberTest.cxx b/svgio/qa/cppunit/SvgNumberTest.cxx index 9b12e52bf956..49e1394bcef2 100644 --- a/svgio/qa/cppunit/SvgNumberTest.cxx +++ b/svgio/qa/cppunit/SvgNumberTest.cxx @@ -40,7 +40,7 @@ public: double getCurrentFontSize() const override { return 12.0; } - double getCurrentXHeightInherited() const override { return 5.0; } + double getCurrentXHeight() const override { return 5.0; } }; void TestNumber::testSetting() diff --git a/svgio/source/svgreader/SvgNumber.cxx b/svgio/source/svgreader/SvgNumber.cxx index 4a48ffbfb4e9..72a44dbdd032 100644 --- a/svgio/source/svgreader/SvgNumber.cxx +++ b/svgio/source/svgreader/SvgNumber.cxx @@ -39,7 +39,7 @@ double SvgNumber::solveNonPercentage(const InfoProvider& rInfoProvider) const case SvgUnit::em: return mfNumber * rInfoProvider.getCurrentFontSize(); case SvgUnit::ex: - return mfNumber * rInfoProvider.getCurrentXHeightInherited() * 0.5; + return mfNumber * rInfoProvider.getCurrentXHeight(); case SvgUnit::px: return mfNumber; case SvgUnit::pt: diff --git a/svgio/source/svgreader/svgcharacternode.cxx b/svgio/source/svgreader/svgcharacternode.cxx index 4ffc46a483db..d83c8b645202 100644 --- a/svgio/source/svgreader/svgcharacternode.cxx +++ b/svgio/source/svgreader/svgcharacternode.cxx @@ -257,9 +257,12 @@ namespace svgio::svgreader // prepare locale css::lang::Locale aLocale; - // prepare TextLayouterDevice + // prepare TextLayouterDevice; use a larger font size for more linear size + // calculations. Similar to nTextSizeFactor in sd/source/ui/view/sdview.cxx + // (ViewRedirector::createRedirectedPrimitive2DSequence). + const double sizeFactor = fFontHeight < 50000 ? 50000 / fFontHeight : 1.0; TextLayouterDevice aTextLayouterDevice; - aTextLayouterDevice.setFontAttribute(aFontAttribute, fFontWidth, fFontHeight, aLocale); + aTextLayouterDevice.setFontAttribute(aFontAttribute, fFontWidth * sizeFactor, fFontHeight * sizeFactor, aLocale); // prepare TextArray ::std::vector< double > aTextArray(rSvgTextPosition.getX()); @@ -293,7 +296,7 @@ namespace svgio::svgreader // get current TextPosition and TextWidth in units basegfx::B2DPoint aPosition(rSvgTextPosition.getPosition()); - double fTextWidth(aTextLayouterDevice.getTextWidth(getText(), nIndex, nLength)); + double fTextWidth(aTextLayouterDevice.getTextWidth(getText(), nIndex, nLength) / sizeFactor); // check for user-given TextLength if(0.0 != rSvgTextPosition.getTextLength() @@ -306,7 +309,10 @@ namespace svgio::svgreader // spacing, need to create and expand TextArray if(aTextArray.empty()) { - aTextArray = aTextLayouterDevice.getTextArray(getText(), nIndex, nLength); + auto aExtendArray(aTextLayouterDevice.getTextArray(getText(), nIndex, nLength)); + aTextArray.reserve(aExtendArray.size()); + for (auto n : aExtendArray) + aTextArray.push_back(n / sizeFactor); } for(auto &a : aTextArray) @@ -384,12 +390,12 @@ namespace svgio::svgreader { case BaselineShift::Sub: { - aPosition.setY(aPosition.getY() + aTextLayouterDevice.getUnderlineOffset()); + aPosition.setY(aPosition.getY() + aTextLayouterDevice.getUnderlineOffset() / sizeFactor); break; } case BaselineShift::Super: { - aPosition.setY(aPosition.getY() + aTextLayouterDevice.getOverlineOffset()); + aPosition.setY(aPosition.getY() + aTextLayouterDevice.getOverlineOffset() / sizeFactor); break; } case BaselineShift::Percentage: diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx index ec2e8e0589a9..5e3c37b07bb7 100644 --- a/svgio/source/svgreader/svgnode.cxx +++ b/svgio/source/svgreader/svgnode.cxx @@ -609,25 +609,12 @@ namespace svgio::svgreader return 0.0; } - double SvgNode::getCurrentXHeightInherited() const - { - if(getParent()) - { - return getParent()->getCurrentXHeight(); - } - else - { - return 0.0; - } - } - double SvgNode::getCurrentXHeight() const { - if(getSvgStyleAttributes()) - // for XHeight, use FontSize currently - return getSvgStyleAttributes()->getFontSizeNumber().solve(*this, NumberType::ycoordinate); - - return getCurrentXHeightInherited(); + // https://drafts.csswg.org/css-values-4/#ex + // for XHeight, use 0.5em fallback currently + // FIXME: use "x-height of the first available font" + return getCurrentFontSize() * 0.5; } void SvgNode::setId(OUString const & rId) diff --git a/svtools/source/svhtml/htmlout.cxx b/svtools/source/svhtml/htmlout.cxx index 3c9090f1062a..97d69198bbbf 100644 --- a/svtools/source/svhtml/htmlout.cxx +++ b/svtools/source/svhtml/htmlout.cxx @@ -702,7 +702,7 @@ SvStream& HTMLOutFuncs::Out_ImageMap( SvStream& rStream, sOut.append(OString::Concat("<") + OOO_STRING_SVTOOLS_HTML_area " " OOO_STRING_SVTOOLS_HTML_O_shape - "=" + pShape + " " + "=\"" + pShape + "\" " OOO_STRING_SVTOOLS_HTML_O_coords "=\"" + aCoords + "\" "); rStream.WriteOString( sOut ); @@ -756,7 +756,7 @@ SvStream& HTMLOutFuncs::Out_ImageMap( SvStream& rStream, Out_Events( rStream, rMacroTab, pEventTable, bOutStarBasic ); - rStream.WriteChar( '>' ); + rStream.WriteOString("/>"); } } diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx index efe322d54e76..86bae7d50447 100644 --- a/svx/qa/unit/customshapes.cxx +++ b/svx/qa/unit/customshapes.cxx @@ -406,10 +406,6 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145111_Fontwork_rendering_font_siz CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145111_anchor_in_Fontwork) { - // The tested positions depend on dpi. - if (!IsDefaultDPI()) - return; - // tdf#145004 In case ScaleX is true in property TextPath, SDRTEXTVERTADJUST is // evaluated and should shift the Fontwork text. That did not work for // 'Top-Left' and 'Bottom-Left'. @@ -423,8 +419,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145111_anchor_in_Fontwork) SdrObjCustomShape& rSdrCustomShape( static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape))); - // Without the fix in place top was 2295, but should be 2916 for 96dpi. - // Was 2184, should be 2886 for 120dpi. + // Without the fix in place top was 2295, but should be 2900. tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect()); CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(2916), aBoundRect.Top(), 5); } @@ -434,8 +429,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145111_anchor_in_Fontwork) SdrObjCustomShape& rSdrCustomShape( static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape))); - // Without the fix in place top was 10294, but should be 9519 for 96dpi. - // Was 10184, should be 9481 for 120dpi. + // Without the fix in place top was 10294, but should be 9500. tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect()); CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(9519), aBoundRect.Top(), 5); } diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx index d93dbee142a3..4c5214bf8674 100644 --- a/svx/source/customshapes/EnhancedCustomShape2d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx @@ -1171,9 +1171,9 @@ bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& r double fY =-dx * sin( a ); rReturnPosition = Point( - FRound( fX + aReferencePoint.X() ), + basegfx::fround<tools::Long>( fX + aReferencePoint.X() ), basegfx::fTools::equalZero(fXScale) ? aReferencePoint.Y() : - FRound( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) ); + basegfx::fround<tools::Long>( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) ); } else { diff --git a/svx/source/customshapes/EnhancedCustomShape3d.cxx b/svx/source/customshapes/EnhancedCustomShape3d.cxx index baaf37a4162c..537240aca199 100644 --- a/svx/source/customshapes/EnhancedCustomShape3d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape3d.cxx @@ -499,7 +499,7 @@ rtl::Reference<SdrObject> EnhancedCustomShape3d::Create3DObject( } const basegfx::B2DRange aTempRange(basegfx::utils::getRange(aPolyPoly)); - const tools::Rectangle aBoundRect(basegfx::fround(aTempRange.getMinX()), basegfx::fround(aTempRange.getMinY()), basegfx::fround(aTempRange.getMaxX()), basegfx::fround(aTempRange.getMaxY())); + const tools::Rectangle aBoundRect(basegfx::fround<tools::Long>(aTempRange.getMinX()), basegfx::fround<tools::Long>(aTempRange.getMinY()), basegfx::fround<tools::Long>(aTempRange.getMaxX()), basegfx::fround<tools::Long>(aTempRange.getMaxY())); aTotalPolyPoly.append(aPolyPoly); aBoundRect2d.Union( aBoundRect ); diff --git a/svx/source/dialog/_contdlg.cxx b/svx/source/dialog/_contdlg.cxx index 3ae8cba852e0..02608859b380 100644 --- a/svx/source/dialog/_contdlg.cxx +++ b/svx/source/dialog/_contdlg.cxx @@ -135,12 +135,12 @@ tools::PolyPolygon SvxContourDlg::CreateAutoContour( const Graphic& rGraphic, if( fWH <= 1.0 ) { aSizePix.setHeight(512); - aSizePix.setWidth( FRound( ( aSizePix.Height() ) * fWH ) ); + aSizePix.setWidth(basegfx::fround<tools::Long>(aSizePix.Height() * fWH)); } else { aSizePix.setWidth(512); - aSizePix.setHeight( FRound( ( aSizePix.Width() ) / fWH ) ); + aSizePix.setHeight(basegfx::fround<tools::Long>(aSizePix.Width() / fWH)); } } diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx index fed0d59d0d6d..9401af387c7a 100644 --- a/svx/source/dialog/frmsel.cxx +++ b/svx/source/dialog/frmsel.cxx @@ -426,12 +426,12 @@ void FrameSelectorImpl::InitBorderGeometry() { const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow )); const tools::Rectangle aRect( - basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()), - basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY())); + basegfx::fround<tools::Long>(aCellRange.getMinX()), basegfx::fround<tools::Long>(aCellRange.getMinY()), + basegfx::fround<tools::Long>(aCellRange.getMaxX()), basegfx::fround<tools::Long>(aCellRange.getMaxY())); const double fHorDiagAngle(atan2(fabs(aCellRange.getHeight()), fabs(aCellRange.getWidth()))); const double fVerDiagAngle(fHorDiagAngle > 0.0 ? M_PI_2 - fHorDiagAngle : 0.0); - const tools::Long nDiagFocusOffsX(basegfx::fround(-mnFocusOffs / tan(fHorDiagAngle) + mnFocusOffs / sin(fHorDiagAngle))); - const tools::Long nDiagFocusOffsY(basegfx::fround(-mnFocusOffs / tan(fVerDiagAngle) + mnFocusOffs / sin(fVerDiagAngle))); + const tools::Long nDiagFocusOffsX(basegfx::fround<tools::Long>(-mnFocusOffs / tan(fHorDiagAngle) + mnFocusOffs / sin(fHorDiagAngle))); + const tools::Long nDiagFocusOffsY(basegfx::fround<tools::Long>(-mnFocusOffs / tan(fVerDiagAngle) + mnFocusOffs / sin(fVerDiagAngle))); std::vector< Point > aFocusVec; aFocusVec.emplace_back( aRect.Left() - mnFocusOffs, aRect.Top() + nDiagFocusOffsY ); @@ -486,8 +486,8 @@ void FrameSelectorImpl::InitBorderGeometry() // the usable area between horizontal/vertical frame borders of current quadrant const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow )); const tools::Rectangle aRect( - basegfx::fround(aCellRange.getMinX()) + nClV + 1, basegfx::fround(aCellRange.getMinY()) + nClH + 1, - basegfx::fround(aCellRange.getMaxX()) - nClV + 1, basegfx::fround(aCellRange.getMaxY()) - nClH + 1); + basegfx::fround<tools::Long>(aCellRange.getMinX()) + nClV + 1, basegfx::fround<tools::Long>(aCellRange.getMinY()) + nClH + 1, + basegfx::fround<tools::Long>(aCellRange.getMaxX()) - nClV + 1, basegfx::fround<tools::Long>(aCellRange.getMaxY()) - nClH + 1); /* Both diagonal frame borders enabled. */ if( mbTLBR && mbBLTR ) diff --git a/svx/source/engine3d/obj3d.cxx b/svx/source/engine3d/obj3d.cxx index 1acf0b2a93f7..8cbdb1e07433 100644 --- a/svx/source/engine3d/obj3d.cxx +++ b/svx/source/engine3d/obj3d.cxx @@ -529,7 +529,7 @@ void E3dCompoundObject::AddToHdlList(SdrHdlList& rHdlList) const // to 2d world coor aPos2D *= rVCScene.getObjectTransformation(); - rHdlList.AddHdl(std::make_unique<SdrHdl>(Point(basegfx::fround(aPos2D.getX()), basegfx::fround(aPos2D.getY())), SdrHdlKind::BezierWeight)); + rHdlList.AddHdl(std::make_unique<SdrHdl>(Point(basegfx::fround<tools::Long>(aPos2D.getX()), basegfx::fround<tools::Long>(aPos2D.getY())), SdrHdlKind::BezierWeight)); } } } diff --git a/svx/source/engine3d/view3d.cxx b/svx/source/engine3d/view3d.cxx index ece5281baf63..dbd1e54b05de 100644 --- a/svx/source/engine3d/view3d.cxx +++ b/svx/source/engine3d/view3d.cxx @@ -1335,12 +1335,12 @@ void E3dView::Start3DCreation() } basegfx::B2DPoint aCenter(aR.getCenter()); - tools::Long nMarkHgt = basegfx::fround(aR.getHeight()) - 1; + tools::Long nMarkHgt = basegfx::fround<tools::Long>(aR.getHeight()) - 1; tools::Long nHgt = nMarkHgt + nObjDst * 2; if (nHgt < nMinLen) nHgt = nMinLen; - tools::Long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2; + tools::Long nY1 = basegfx::fround<tools::Long>(aCenter.getY()) - (nHgt + 1) / 2; tools::Long nY2 = nY1 + nHgt; if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt; @@ -1358,7 +1358,7 @@ void E3dView::Start3DCreation() } } - maRef1.setX( basegfx::fround(aR.getMinX()) ); // Initial move axis 2/100mm to the left + maRef1.setX( basegfx::fround<tools::Long>(aR.getMinX()) ); // Initial move axis 2/100mm to the left maRef1.setY( nY1 ); maRef2.setX( maRef1.X() ); maRef2.setY( nY2 ); diff --git a/svx/source/gallery2/galobj.cxx b/svx/source/gallery2/galobj.cxx index 44362b9a78ec..80d49228e750 100644 --- a/svx/source/gallery2/galobj.cxx +++ b/svx/source/gallery2/galobj.cxx @@ -118,9 +118,9 @@ bool SgaObject::CreateThumb( const Graphic& rGraphic ) double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height(); if( fFactorPix > fFactorLog ) - aBmpSize.setWidth( FRound( aBmpSize.Height() * fFactorLog ) ); + aBmpSize.setWidth( basegfx::fround<tools::Long>( aBmpSize.Height() * fFactorLog ) ); else - aBmpSize.setHeight( FRound( aBmpSize.Width() / fFactorLog ) ); + aBmpSize.setHeight( basegfx::fround<tools::Long>( aBmpSize.Width() / fFactorLog ) ); aBmpEx.Scale(aBmpSize, BmpScaleFlag::BestQuality); } diff --git a/svx/source/svdraw/gradtrns.cxx b/svx/source/svdraw/gradtrns.cxx index d665cd48ce16..34c547bba8ed 100644 --- a/svx/source/svdraw/gradtrns.cxx +++ b/svx/source/svdraw/gradtrns.cxx @@ -235,7 +235,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r } // to int and set - Degree10 nNewAngle( FRound(fNewFullAngle)); + Degree10 nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle)); if(nNewAngle != rGOld.aGradient.GetAngle()) { @@ -252,7 +252,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r const double fFullLen(aFullVec.getLength()); const double fOldLen(aOldVec.getLength()); const double fNewBorder((fFullLen * 100.0) / fOldLen); - sal_Int32 nNewBorder(100 - FRound(fNewBorder)); + sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder)); // clip if(nNewBorder < 0) @@ -283,7 +283,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r const double fFullLen(aFullVec.getLength()); const double fOldLen(aOldVec.getLength()); const double fNewBorder((fFullLen * 100.0) / fOldLen); - sal_Int32 nNewBorder = 100 - FRound(fNewBorder); + sal_Int32 nNewBorder = 100 - basegfx::fround(fNewBorder); // clip if(nNewBorder < 0) @@ -319,7 +319,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r } // to int and set - const Degree10 nNewAngle(FRound(fNewFullAngle)); + const Degree10 nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle)); if(nNewAngle != rGOld.aGradient.GetAngle()) { @@ -336,8 +336,8 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r { const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY()); const basegfx::B2DPoint aOffset(aEndPos - aTopLeft); - sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth())); - sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight())); + sal_Int32 nNewXOffset(basegfx::fround(aOffset.getX() * 100.0 / aRange.getWidth())); + sal_Int32 nNewYOffset(basegfx::fround(aOffset.getY() * 100.0 / aRange.getHeight())); // clip if(nNewXOffset < 0) @@ -376,7 +376,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r const double fFullLen(aFullVec.getLength()); const double fOldLen(aOldVec.getLength()); const double fNewBorder((fFullLen * 100.0) / fOldLen); - sal_Int32 nNewBorder(100 - FRound(fNewBorder)); + sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder)); // clip if(nNewBorder < 0) @@ -414,7 +414,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r } // to int and set - const Degree10 nNewAngle(FRound(fNewFullAngle)); + const Degree10 nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle)); if(nNewAngle != rGOld.aGradient.GetAngle()) { @@ -431,8 +431,8 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r { const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY()); const basegfx::B2DPoint aOffset(aEndPos - aTopLeft); - sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth())); - sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight())); + sal_Int32 nNewXOffset(basegfx::fround(aOffset.getX() * 100.0 / aRange.getWidth())); + sal_Int32 nNewYOffset(basegfx::fround(aOffset.getY() * 100.0 / aRange.getHeight())); // clip if(nNewXOffset < 0) @@ -471,7 +471,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r const double fFullLen(aFullVec.getLength()); const double fOldLen(aOldVec.getLength()); const double fNewBorder((fFullLen * 100.0) / fOldLen); - sal_Int32 nNewBorder(100 - FRound(fNewBorder)); + sal_Int32 nNewBorder(100 - basegfx::fround(fNewBorder)); // clip if(nNewBorder < 0) @@ -509,7 +509,7 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r } // to int and set - const Degree10 nNewAngle(FRound(fNewFullAngle)); + const Degree10 nNewAngle(basegfx::fround<sal_Int16>(fNewFullAngle)); if(nNewAngle != rGOld.aGradient.GetAngle()) { diff --git a/svx/source/svdraw/sdrpagewindow.cxx b/svx/source/svdraw/sdrpagewindow.cxx index 01be77135674..86fbe967ccbc 100644 --- a/svx/source/svdraw/sdrpagewindow.cxx +++ b/svx/source/svdraw/sdrpagewindow.cxx @@ -231,6 +231,7 @@ void SdrPageWindow::PrepareRedraw(const vcl::Region& rReg) // clip test #ifdef CLIPPER_TEST #include <svx/svdopath.hxx> +#include <basegfx/numeric/ftools.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <tools/helpers.hxx> #include <basegfx/polygon/b2dpolygoncutandtouch.hxx> @@ -262,8 +263,10 @@ namespace { const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a)); const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count())); - const Point aStart(FRound(aBStart.getX()), FRound(aBStart.getY())); - const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY())); + const Point aStart(basegfx::fround<tools::Long>(aBStart.getX()), + basegfx::fround<tools::Long>(aBStart.getY())); + const Point aEnd(basegfx::fround<tools::Long>(aBEnd.getX()), + basegfx::fround<tools::Long>(aBEnd.getY())); rOutDev.DrawLine(aStart, aEnd); } } diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx index 7e025cf044e1..ea96fb91fb0a 100644 --- a/svx/source/svdraw/svdcrtv.cxx +++ b/svx/source/svdraw/svdcrtv.cxx @@ -653,8 +653,8 @@ bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd) if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj.get(), mpCreatePV)) { const Size aOffset( - basegfx::fround(-aGridOffset.getX()), - basegfx::fround(-aGridOffset.getY())); + basegfx::fround<tools::Long>(-aGridOffset.getX()), + basegfx::fround<tools::Long>(-aGridOffset.getY())); pObj->NbcMove(aOffset); } diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 37531632c5b4..2fdf8c4ab8d0 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -3771,15 +3771,15 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/) // extract the old Rectangle structures tools::Rectangle aOldRect( - basegfx::fround(aRangeOriginalNoShearNoRotate.getMinX()), - basegfx::fround(aRangeOriginalNoShearNoRotate.getMinY()), - basegfx::fround(aRangeOriginalNoShearNoRotate.getMaxX()), - basegfx::fround(aRangeOriginalNoShearNoRotate.getMaxY())); + basegfx::fround<tools::Long>(aRangeOriginalNoShearNoRotate.getMinX()), + basegfx::fround<tools::Long>(aRangeOriginalNoShearNoRotate.getMinY()), + basegfx::fround<tools::Long>(aRangeOriginalNoShearNoRotate.getMaxX()), + basegfx::fround<tools::Long>(aRangeOriginalNoShearNoRotate.getMaxY())); tools::Rectangle aNewRect( - basegfx::fround(aRangeNewNoShearNoRotate.getMinX()), - basegfx::fround(aRangeNewNoShearNoRotate.getMinY()), - basegfx::fround(aRangeNewNoShearNoRotate.getMaxX()), - basegfx::fround(aRangeNewNoShearNoRotate.getMaxY())); + basegfx::fround<tools::Long>(aRangeNewNoShearNoRotate.getMinX()), + basegfx::fround<tools::Long>(aRangeNewNoShearNoRotate.getMinY()), + basegfx::fround<tools::Long>(aRangeNewNoShearNoRotate.getMaxX()), + basegfx::fround<tools::Long>(aRangeNewNoShearNoRotate.getMaxY())); // continue with the old original stuff if (!aOldRect.GetWidth() || !aOldRect.GetHeight()) diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx index 27b62dd17946..3a102234336f 100644 --- a/svx/source/svdraw/svddrgv.cxx +++ b/svx/source/svdraw/svddrgv.cxx @@ -123,8 +123,8 @@ void SdrDragView::TakeActionRect(tools::Rectangle& rRect) const else { rRect = tools::Rectangle( - basegfx::fround(aBoundRange.getMinX()), basegfx::fround(aBoundRange.getMinY()), - basegfx::fround(aBoundRange.getMaxX()), basegfx::fround(aBoundRange.getMaxY())); + basegfx::fround<tools::Long>(aBoundRange.getMinX()), basegfx::fround<tools::Long>(aBoundRange.getMinY()), + basegfx::fround<tools::Long>(aBoundRange.getMaxX()), basegfx::fround<tools::Long>(aBoundRange.getMaxY())); } } } @@ -164,8 +164,8 @@ bool SdrDragView::TakeDragObjAnchorPos(Point& rPos, bool bTR ) const { // drag the whole Object (Move, Resize, ...) const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y())); - rPos.setX( basegfx::fround(aTransformed.getX()) ); - rPos.setY( basegfx::fround(aTransformed.getY()) ); + rPos.setX( basegfx::fround<tools::Long>(aTransformed.getX()) ); + rPos.setY( basegfx::fround<tools::Long>(aTransformed.getY()) ); } } } @@ -216,8 +216,8 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl basegfx::B2DPoint(aPnt.X(), aPnt.Y()), GetSdrPageView()))) { - aPnt.AdjustX(basegfx::fround(-aGridOffset.getX())); - aPnt.AdjustY(basegfx::fround(-aGridOffset.getY())); + aPnt.AdjustX(basegfx::fround<tools::Long>(-aGridOffset.getX())); + aPnt.AdjustY(basegfx::fround<tools::Long>(-aGridOffset.getY())); } if(pHdl == nullptr @@ -520,8 +520,8 @@ void SdrDragView::MovDragObj(const Point& rPnt) basegfx::B2DPoint(aPnt.X(), aPnt.Y()), GetSdrPageView()))) { - aPnt.AdjustX(basegfx::fround(-aGridOffset.getX())); - aPnt.AdjustY(basegfx::fround(-aGridOffset.getY())); + aPnt.AdjustX(basegfx::fround<tools::Long>(-aGridOffset.getX())); + aPnt.AdjustY(basegfx::fround<tools::Long>(-aGridOffset.getY())); } ImpLimitToWorkArea(aPnt); diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index 2e4d218a3aee..7d40c4f211f8 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -559,7 +559,7 @@ void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRa aCtr1 -= aCtr0; if(bRotOk) - pO->Rotate(aCtr0, Degree100(FRound(basegfx::rad2deg<100>(nAngle))), nSin, nCos); + pO->Rotate(aCtr0, Degree100(basegfx::fround(basegfx::rad2deg<100>(nAngle))), nSin, nCos); pO->Move(Size(aCtr1.X(),aCtr1.Y())); } @@ -1675,7 +1675,7 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr, bool addPageMargin double nNew = tan(toRadians(nNewShearAngle)); nNew-=nOld; nNew = basegfx::rad2deg<100>(atan(nNew)); - nShearAngle=Degree100(FRound(nNew)); + nShearAngle = Degree100(basegfx::fround(nNew)); } else { nShearAngle=nNewShearAngle-nOldShearAngle; } diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 42be2aff97fb..aa11a4118142 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -276,8 +276,8 @@ void SdrObjEditView::ModelHasChanged() basegfx::B2DVector aGridOffset(0.0, 0.0); if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj.get(), GetSdrPageView())) { - const Point aOffset(basegfx::fround(aGridOffset.getX()), - basegfx::fround(aGridOffset.getY())); + const Point aOffset(basegfx::fround<tools::Long>(aGridOffset.getX()), + basegfx::fround<tools::Long>(aGridOffset.getY())); aEditArea1 += aOffset; aMinArea1 += aOffset; @@ -1357,8 +1357,8 @@ bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::W basegfx::B2DVector aGridOffset(0.0, 0.0); if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj.get(), pPV)) { - const Point aOffset(basegfx::fround(aGridOffset.getX()), - basegfx::fround(aGridOffset.getY())); + const Point aOffset(basegfx::fround<tools::Long>(aGridOffset.getX()), + basegfx::fround<tools::Long>(aGridOffset.getY())); aTextEditArea += aOffset; aMinTextEditArea += aOffset; diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx index eb1c9648b127..54760e0f6e18 100644 --- a/svx/source/svdraw/svdfmtf.cxx +++ b/svx/source/svdraw/svdfmtf.cxx @@ -394,7 +394,7 @@ void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr if(bText && mbFntDirty) { vcl::Font aFnt(mpVD->GetFont()); - const sal_uInt32 nHeight(FRound(aFnt.GetFontSize().Height() * mfScaleY)); + const sal_uInt32 nHeight(basegfx::fround(aFnt.GetFontSize().Height() * mfScaleY)); mpTextAttr->Put( SvxFontItem( aFnt.GetFamilyType(), aFnt.GetFamilyName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) ); mpTextAttr->Put( SvxFontItem( aFnt.GetFamilyType(), aFnt.GetFamilyName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) ); @@ -572,11 +572,11 @@ void ImpSdrGDIMetaFileImport::InsertObj(SdrObject* pObj1, bool bScale) const Size aOrigSizePixel(aBitmapEx.GetSizePixel()); const Point aClipTopLeft( - basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))), - basegfx::fround(floor(std::max(0.0, aPixel.getMinY())))); + basegfx::fround<tools::Long>(floor(std::max(0.0, aPixel.getMinX()))), + basegfx::fround<tools::Long>(floor(std::max(0.0, aPixel.getMinY())))); const Size aClipSize( - basegfx::fround(ceil(std::min(static_cast<double>(aOrigSizePixel.Width()), aPixel.getWidth()))), - basegfx::fround(ceil(std::min(static_cast<double>(aOrigSizePixel.Height()), aPixel.getHeight())))); + basegfx::fround<tools::Long>(ceil(std::min(static_cast<double>(aOrigSizePixel.Width()), aPixel.getWidth()))), + basegfx::fround<tools::Long>(ceil(std::min(static_cast<double>(aOrigSizePixel.Height()), aPixel.getHeight())))); const BitmapEx aClippedBitmap( aBitmapEx, aClipTopLeft, @@ -1002,11 +1002,12 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const OUString& rSt sal_Int32 nTextWidth = static_cast<sal_Int32>( mpVD->GetTextWidth( rStr ) * mfScaleX ); sal_Int32 nTextHeight = static_cast<sal_Int32>( mpVD->GetTextHeight() * mfScaleY ); - Point aPos( FRound(rPos.X() * mfScaleX + maOfs.X()), FRound(rPos.Y() * mfScaleY + maOfs.Y()) ); + Point aPos(basegfx::fround<tools::Long>(rPos.X() * mfScaleX + maOfs.X()), + basegfx::fround<tools::Long>(rPos.Y() * mfScaleY + maOfs.Y())); Size aSize( nTextWidth, nTextHeight ); if ( eAlg == ALIGN_BASELINE ) - aPos.AdjustY( -(FRound(aFontMetric.GetAscent() * mfScaleY)) ); + aPos.AdjustY(basegfx::fround<tools::Long>(aFontMetric.GetAscent() * -mfScaleY)); else if ( eAlg == ALIGN_BOTTOM ) aPos.AdjustY( -nTextHeight ); diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx index 379b3ed3f73e..75d6ae0c873f 100644 --- a/svx/source/svdraw/svdhdl.cxx +++ b/svx/source/svdraw/svdhdl.cxx @@ -1420,16 +1420,20 @@ void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, bool bSetItemOnObject, bool // back transformation, set values on pIAOHandle GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, _pObj); - SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY()))); - Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY()))); + SetPos({ basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()), + basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY()) }); + Set2ndPos({ basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()), + basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY()) }); if(pColHdl1) { - pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY()))); + pColHdl1->SetPos({ basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()), + basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY()) }); pColHdl1->SetColor(aGradTransVector.aCol1); } if(pColHdl2) { - pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY()))); + pColHdl2->SetPos({ basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()), + basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY()) }); pColHdl2->SetColor(aGradTransVector.aCol2); } } diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index 912135b0d1c0..80f979fa0852 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -1589,8 +1589,8 @@ void SdrMarkView::AddDragModeHdl(SdrDragMode eMode) GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, pObj); // build handles - const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY())); - const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY())); + const Point aTmpPos1(basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()), basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY())); + const Point aTmpPos2(basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()), basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY())); std::unique_ptr<SdrHdlColor> pColHdl1(new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, true)); std::unique_ptr<SdrHdlColor> pColHdl2(new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, true)); std::unique_ptr<SdrHdlGradient> pGradHdl(new SdrHdlGradient(aTmpPos1, aTmpPos2, false)); @@ -1630,8 +1630,8 @@ void SdrMarkView::AddDragModeHdl(SdrDragMode eMode) GradTransformer::GradToVec(aGradTransGradient, aGradTransVector, pObj); // build handles - const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY())); - const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY())); + const Point aTmpPos1(basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getX()), basegfx::fround<tools::Long>(aGradTransVector.maPositionA.getY())); + const Point aTmpPos2(basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getX()), basegfx::fround<tools::Long>(aGradTransVector.maPositionB.getY())); std::unique_ptr<SdrHdlColor> pColHdl1(new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, false)); std::unique_ptr<SdrHdlColor> pColHdl2(new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, false)); std::unique_ptr<SdrHdlGradient> pGradHdl(new SdrHdlGradient(aTmpPos1, aTmpPos2, true)); @@ -2317,8 +2317,8 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj, pPV)) { aRect += Point( - basegfx::fround(aGridOffset.getX()), - basegfx::fround(aGridOffset.getY())); + basegfx::fround<tools::Long>(aGridOffset.getX()), + basegfx::fround<tools::Long>(aGridOffset.getY())); } sal_uInt16 nTol2(nTol); diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx index 44ecb8fefded..fd0c43f851f1 100644 --- a/svx/source/svdraw/svdoashp.cxx +++ b/svx/source/svdraw/svdoashp.cxx @@ -3033,7 +3033,8 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, } // scale - Size aSize(FRound(fabs(aScale.getX())), FRound(fabs(aScale.getY()))); + Size aSize(basegfx::fround<tools::Long>(fabs(aScale.getX())), + basegfx::fround<tools::Long>(fabs(aScale.getY()))); // fdo#47434 We need a valid rectangle here if( !aSize.Height() ) aSize.setHeight( 1 ); if( !aSize.Width() ) aSize.setWidth( 1 ); @@ -3053,7 +3054,7 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, // #i123181# The fix for #121932# here was wrong, the trunk version does not correct the // mirrored shear values, neither at the object level, nor on the API or XML level. Taking // back the mirroring of the shear angle - aGeoStat.nShearAngle = Degree100(FRound(basegfx::rad2deg<100>(atan(fShearX)))); + aGeoStat.nShearAngle = Degree100(basegfx::fround(basegfx::rad2deg<100>(atan(fShearX)))); aGeoStat.RecalcTan(); Shear(Point(), aGeoStat.nShearAngle, aGeoStat.mfTanShearAngle, false); } @@ -3066,7 +3067,7 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, // #i78696# // fRotate is mathematically correct, but aGeoStat.nRotationAngle is // mirrored -> mirror value here - aGeoStat.nRotationAngle = NormAngle36000(Degree100(FRound(-basegfx::rad2deg<100>(fRotate)))); + aGeoStat.nRotationAngle = NormAngle36000(Degree100(basegfx::fround(-basegfx::rad2deg<100>(fRotate)))); aGeoStat.RecalcSinCos(); Rotate(Point(), aGeoStat.nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle); } @@ -3074,7 +3075,8 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, // translate? if(!aTranslate.equalZero()) { - Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY()))); + Move(Size(basegfx::fround<tools::Long>(aTranslate.getX()), + basegfx::fround<tools::Long>(aTranslate.getY()))); } // Apply flipping from enhanced geometry at center of the shape. @@ -3095,11 +3097,11 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, double fCenterX = aCenter.getX(); double fCenterY = aCenter.getY(); if (bIsMirroredX) // vertical axis - Mirror(Point(FRound(fCenterX),FRound(fCenterY)), - Point(FRound(fCenterX), FRound(fCenterY + 1000.0))); + Mirror(Point(basegfx::fround<tools::Long>(fCenterX), basegfx::fround<tools::Long>(fCenterY)), + Point(basegfx::fround<tools::Long>(fCenterX), basegfx::fround<tools::Long>(fCenterY + 1000.0))); if (bIsMirroredY) // horizontal axis - Mirror(Point(FRound(fCenterX),FRound(fCenterY)), - Point(FRound(fCenterX + 1000.0), FRound(fCenterY))); + Mirror(Point(basegfx::fround<tools::Long>(fCenterX), basegfx::fround<tools::Long>(fCenterY)), + Point(basegfx::fround<tools::Long>(fCenterX + 1000.0), basegfx::fround<tools::Long>(fCenterY))); } // taking fObjectRotation instead of aGeo.nAngle diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index 4bcd7c386270..a817ad295a9b 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -3036,8 +3036,10 @@ void SdrObject::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const ba } // build BaseRect - Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY())); - tools::Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY()))); + Point aPoint(basegfx::fround<tools::Long>(aTranslate.getX()), + basegfx::fround<tools::Long>(aTranslate.getY())); + tools::Rectangle aBaseRect(aPoint, Size(basegfx::fround<tools::Long>(aScale.getX()), + basegfx::fround<tools::Long>(aScale.getY()))); // set BaseRect SetSnapRect(aBaseRect); diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx index 6a886272bad1..0287b2391a5b 100644 --- a/svx/source/svdraw/svdocapt.cxx +++ b/svx/source/svdraw/svdocapt.cxx @@ -737,8 +737,10 @@ void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, cons } // build BaseRect - Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY())); - tools::Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY()))); + Point aPoint(basegfx::fround<tools::Long>(aTranslate.getX()), + basegfx::fround<tools::Long>(aTranslate.getY())); + tools::Rectangle aBaseRect(aPoint, Size(basegfx::fround<tools::Long>(aScale.getX()), + basegfx::fround<tools::Long>(aScale.getY()))); // set BaseRect, but rescue TailPos over this call const Point aTailPoint = GetTailPos(); diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx index 1207548114bf..270eda407493 100644 --- a/svx/source/svdraw/svdocirc.cxx +++ b/svx/source/svdraw/svdocirc.cxx @@ -57,7 +57,8 @@ static Point GetAnglePnt(const tools::Rectangle& rR, Degree100 nAngle) tools::Long nHgt=rR.Bottom()-rR.Top(); tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2; double a = toRadians(nAngle); - Point aRetval(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad)); + Point aRetval(basegfx::fround<tools::Long>(cos(a) * nMaxRad), + basegfx::fround<tools::Long>(-sin(a) * nMaxRad)); if (nWdt==0) aRetval.setX(0 ); if (nHgt==0) aRetval.setY(0 ); if (nWdt!=nHgt) { @@ -886,13 +887,15 @@ void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2) tools::Long nMaxRad=(std::max(nWdt,nHgt)+1) /2; // starting point double a = toRadians(nStartAngle); - aTmpPt1=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad)); + aTmpPt1 = Point(basegfx::fround<tools::Long>(cos(a) * nMaxRad), + basegfx::fround<tools::Long>(-sin(a) * nMaxRad)); if (nWdt==0) aTmpPt1.setX(0 ); if (nHgt==0) aTmpPt1.setY(0 ); aTmpPt1+=aCenter; // finishing point a = toRadians(nEndAngle); - aTmpPt2=Point(FRound(cos(a)*nMaxRad),-FRound(sin(a)*nMaxRad)); + aTmpPt2 = Point(basegfx::fround<tools::Long>(cos(a) * nMaxRad), + basegfx::fround<tools::Long>(-sin(a) * nMaxRad)); if (nWdt==0) aTmpPt2.setX(0 ); if (nHgt==0) aTmpPt2.setY(0 ); aTmpPt2+=aCenter; @@ -1011,7 +1014,7 @@ void SdrCircObj::TakeUnrotatedSnapRect(tools::Rectangle& rRect) const if (maGeo.nShearAngle==0_deg100) return; - tools::Long nDst = FRound((rRect.Bottom() - rRect.Top()) * maGeo.mfTanShearAngle); + tools::Long nDst = basegfx::fround<tools::Long>((rRect.Bottom() - rRect.Top()) * maGeo.mfTanShearAngle); if (maGeo.nShearAngle > 0_deg100) { Point aRef(rRect.TopLeft()); diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx index 15d507679789..1c121b886e6e 100644 --- a/svx/source/svdraw/svdoedge.cxx +++ b/svx/source/svdraw/svdoedge.cxx @@ -2012,15 +2012,15 @@ basegfx::B2DPolygon SdrEdgeObj::ImplAddConnectorOverlay(const SdrDragMethod& rDr if (bTail1) { const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aMyCon1.aObjOfs.X(), aMyCon1.aObjOfs.Y())); - aMyCon1.aObjOfs.setX( basegfx::fround(aTemp.getX()) ); - aMyCon1.aObjOfs.setY( basegfx::fround(aTemp.getY()) ); + aMyCon1.aObjOfs.setX( basegfx::fround<tools::Long>(aTemp.getX()) ); + aMyCon1.aObjOfs.setY( basegfx::fround<tools::Long>(aTemp.getY()) ); } if (bTail2) { const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aMyCon2.aObjOfs.X(), aMyCon2.aObjOfs.Y())); - aMyCon2.aObjOfs.setX( basegfx::fround(aTemp.getX()) ); - aMyCon2.aObjOfs.setY( basegfx::fround(aTemp.getY()) ); + aMyCon2.aObjOfs.setX( basegfx::fround<tools::Long>(aTemp.getX()) ); + aMyCon2.aObjOfs.setY( basegfx::fround<tools::Long>(aTemp.getY()) ); } SdrEdgeInfoRec aInfo(aEdgeInfo); @@ -2045,15 +2045,15 @@ basegfx::B2DPolygon SdrEdgeObj::ImplAddConnectorOverlay(const SdrDragMethod& rDr if (bTail1) { const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aPt1.X(), aPt1.Y())); - aPt1.setX( basegfx::fround(aTemp.getX()) ); - aPt1.setY( basegfx::fround(aTemp.getY()) ); + aPt1.setX( basegfx::fround<tools::Long>(aTemp.getX()) ); + aPt1.setY( basegfx::fround<tools::Long>(aTemp.getY()) ); } if (bTail2) { const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aPt2.X(), aPt2.Y())); - aPt2.setX( basegfx::fround(aTemp.getX()) ); - aPt2.setY( basegfx::fround(aTemp.getY()) ); + aPt2.setX( basegfx::fround<tools::Long>(aTemp.getX()) ); + aPt2.setY( basegfx::fround<tools::Long>(aTemp.getY()) ); } aResult.append(basegfx::B2DPoint(aPt1.X(), aPt1.Y())); diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx index 946cbee0ba0d..49fb0666af82 100644 --- a/svx/source/svdraw/svdograf.cxx +++ b/svx/source/svdraw/svdograf.cxx @@ -1051,7 +1051,7 @@ void SdrGrafObj::ImpSetAttrToGrafInfo() aGrafInfo.SetChannelG( rSet.Get( SDRATTR_GRAFGREEN ).GetValue() ); aGrafInfo.SetChannelB( rSet.Get( SDRATTR_GRAFBLUE ).GetValue() ); aGrafInfo.SetGamma( rSet.Get( SDRATTR_GRAFGAMMA ).GetValue() * 0.01 ); - aGrafInfo.SetAlpha( 255 - static_cast<sal_uInt8>(FRound( std::min( nTrans, sal_uInt16(100) ) * 2.55 )) ); + aGrafInfo.SetAlpha(255 - basegfx::fround<sal_uInt8>(nTrans * 2.55)); aGrafInfo.SetInvert( rSet.Get( SDRATTR_GRAFINVERT ).GetValue() ); aGrafInfo.SetDrawMode( rSet.Get( SDRATTR_GRAFMODE ).GetValue() ); aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() ); @@ -1244,21 +1244,21 @@ void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const basegfx::B2DPoint aPos; aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate)); aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdomeas.cxx b/svx/source/svdraw/svdomeas.cxx index 5e402646ef66..1f6ae999dbca 100644 --- a/svx/source/svdraw/svdomeas.cxx +++ b/svx/source/svdraw/svdomeas.cxx @@ -339,7 +339,7 @@ static tools::Long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon& rPo const basegfx::B2DRange aPolygonRange(rPolyPolygon.getB2DRange()); const double fOldWidth(std::max(aPolygonRange.getWidth(), 1.0)); const double fScale(static_cast<double>(nNewWidth) / fOldWidth); - tools::Long nHeight(basegfx::fround(aPolygonRange.getHeight() * fScale)); + tools::Long nHeight(basegfx::fround<tools::Long>(aPolygonRange.getHeight() * fScale)); if(bCenter) { @@ -462,14 +462,14 @@ void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec& rRec, ImpMeasurePoly& tools::Long nOverhang=rRec.nHelplineOverhang; tools::Long nHelplineDist=rRec.nHelplineDist; - tools::Long dx= FRound(nLineDist*nHlpCos); - tools::Long dy=-FRound(nLineDist*nHlpSin); - tools::Long dxh1a= FRound((nHelplineDist-rRec.nHelpline1Len)*nHlpCos); - tools::Long dyh1a=-FRound((nHelplineDist-rRec.nHelpline1Len)*nHlpSin); - tools::Long dxh1b= FRound((nHelplineDist-rRec.nHelpline2Len)*nHlpCos); - tools::Long dyh1b=-FRound((nHelplineDist-rRec.nHelpline2Len)*nHlpSin); - tools::Long dxh2= FRound((nLineDist+nOverhang)*nHlpCos); - tools::Long dyh2=-FRound((nLineDist+nOverhang)*nHlpSin); + tools::Long dx = basegfx::fround<tools::Long>(nLineDist * nHlpCos); + tools::Long dy = basegfx::fround<tools::Long>(nLineDist * -nHlpSin); + tools::Long dxh1a = basegfx::fround<tools::Long>((nHelplineDist - rRec.nHelpline1Len) * nHlpCos); + tools::Long dyh1a = basegfx::fround<tools::Long>((nHelplineDist - rRec.nHelpline1Len) * -nHlpSin); + tools::Long dxh1b = basegfx::fround<tools::Long>((nHelplineDist - rRec.nHelpline2Len) * nHlpCos); + tools::Long dyh1b = basegfx::fround<tools::Long>((nHelplineDist - rRec.nHelpline2Len) * -nHlpSin); + tools::Long dxh2 = basegfx::fround<tools::Long>((nLineDist + nOverhang) * nHlpCos); + tools::Long dyh2 = basegfx::fround<tools::Long>((nLineDist + nOverhang) * -nHlpSin); // extension line 1 rPol.aHelpline1.aP1=Point(aP1.X()+dxh1a,aP1.Y()+dyh1a); @@ -1407,8 +1407,8 @@ void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, cons } // derive new model data - const Point aNewPt1(basegfx::fround(aPosA.getX()), basegfx::fround(aPosA.getY())); - const Point aNewPt2(basegfx::fround(aPosB.getX()), basegfx::fround(aPosB.getY())); + const Point aNewPt1(basegfx::fround<tools::Long>(aPosA.getX()), basegfx::fround<tools::Long>(aPosA.getY())); + const Point aNewPt2(basegfx::fround<tools::Long>(aPosB.getX()), basegfx::fround<tools::Long>(aPosB.getY())); if(aNewPt1 == aPt1 && aNewPt2 == aPt2) return; diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx index a4998647c835..cfcb30c0edd0 100644 --- a/svx/source/svdraw/svdopath.cxx +++ b/svx/source/svdraw/svdopath.cxx @@ -324,18 +324,18 @@ void ImpPathCreateUser::CalcCircle(const Point& rP1, const Point& rP2, const Poi if (bRet) { double cs = cos(toRadians(nTmpAngle)); double nR=static_cast<double>(GetLen(Point(dx,dy)))/cs/2; - nRad=std::abs(FRound(nR)); + nRad = std::abs(basegfx::fround<tools::Long>(nR)); } if (dAngle<18000_deg100) { nCircStAngle=NormAngle36000(nTangAngle-9000_deg100); nCircRelAngle=NormAngle36000(2_deg100*dAngle); - aCircCenter.AdjustX(FRound(nRad * cos(toRadians(nTangAngle + 9000_deg100)))); - aCircCenter.AdjustY(-(FRound(nRad * sin(toRadians(nTangAngle + 9000_deg100))))); + aCircCenter.AdjustX(basegfx::fround<tools::Long>(nRad * cos(toRadians(nTangAngle + 9000_deg100)))); + aCircCenter.AdjustY(basegfx::fround<tools::Long>(nRad * -sin(toRadians(nTangAngle + 9000_deg100)))); } else { nCircStAngle=NormAngle36000(nTangAngle+9000_deg100); nCircRelAngle=-NormAngle36000(36000_deg100-2_deg100*dAngle); - aCircCenter.AdjustX(FRound(nRad * cos(toRadians(nTangAngle - 9000_deg100)))); - aCircCenter.AdjustY(-(FRound(nRad * sin(toRadians(nTangAngle - 9000_deg100))))); + aCircCenter.AdjustX(basegfx::fround<tools::Long>(nRad * cos(toRadians(nTangAngle - 9000_deg100)))); + aCircCenter.AdjustY(basegfx::fround<tools::Long>(nRad * -sin(toRadians(nTangAngle - 9000_deg100)))); } bAngleSnap=pView!=nullptr && pView->IsAngleSnapEnabled(); if (bAngleSnap) { @@ -457,8 +457,8 @@ void ImpPathCreateUser::CalcRect(const Point& rP1, const Point& rP2, const Point double sn=sin(a); double cs=cos(a); double nGKathLen=nHypLen*sn; - y+=FRound(nGKathLen*sn); - x+=FRound(nGKathLen*cs); + y += basegfx::fround<tools::Long>(nGKathLen * sn); + x += basegfx::fround<tools::Long>(nGKathLen * cs); } aRectP2.AdjustX(x ); aRectP2.AdjustY(y ); @@ -1659,8 +1659,8 @@ static tools::Rectangle lcl_ImpGetBoundRect(const basegfx::B2DPolyPolygon& rPoly return tools::Rectangle(); return tools::Rectangle( - FRound(aRange.getMinX()), FRound(aRange.getMinY()), - FRound(aRange.getMaxX()), FRound(aRange.getMaxY())); + basegfx::fround<tools::Long>(aRange.getMinX()), basegfx::fround<tools::Long>(aRange.getMinY()), + basegfx::fround<tools::Long>(aRange.getMaxX()), basegfx::fround<tools::Long>(aRange.getMaxY())); } void SdrPathObj::ImpForceLineAngle() @@ -1671,10 +1671,13 @@ void SdrPathObj::ImpForceLineAngle() const basegfx::B2DPolygon aPoly(GetPathPoly().getB2DPolygon(0)); const basegfx::B2DPoint aB2DPoint0(aPoly.getB2DPoint(0)); const basegfx::B2DPoint aB2DPoint1(aPoly.getB2DPoint(1)); - const Point aPoint0(FRound(aB2DPoint0.getX()), FRound(aB2DPoint0.getY())); - const Point aPoint1(FRound(aB2DPoint1.getX()), FRound(aB2DPoint1.getY())); + const Point aPoint0(basegfx::fround<tools::Long>(aB2DPoint0.getX()), + basegfx::fround<tools::Long>(aB2DPoint0.getY())); + const Point aPoint1(basegfx::fround<tools::Long>(aB2DPoint1.getX()), + basegfx::fround<tools::Long>(aB2DPoint1.getY())); const basegfx::B2DPoint aB2DDelt(aB2DPoint1 - aB2DPoint0); - const Point aDelt(FRound(aB2DDelt.getX()), FRound(aB2DDelt.getY())); + const Point aDelt(basegfx::fround<tools::Long>(aB2DDelt.getX()), + basegfx::fround<tools::Long>(aB2DDelt.getY())); maGeo.nRotationAngle=GetAngle(aDelt); maGeo.nShearAngle=0_deg100; @@ -2414,7 +2417,8 @@ Point SdrPathObj::GetSnapPoint(sal_uInt32 nSnapPnt) const } const basegfx::B2DPoint aB2DPoint(GetPathPoly().getB2DPolygon(nPoly).getB2DPoint(nPnt)); - return Point(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY())); + return Point(basegfx::fround<tools::Long>(aB2DPoint.getX()), + basegfx::fround<tools::Long>(aB2DPoint.getY())); } bool SdrPathObj::IsPolyObj() const @@ -2443,7 +2447,8 @@ Point SdrPathObj::GetPoint(sal_uInt32 nHdlNum) const { const basegfx::B2DPolygon aPoly(GetPathPoly().getB2DPolygon(nPoly)); const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(nPnt)); - aRetval = Point(FRound(aPoint.getX()), FRound(aPoint.getY())); + aRetval = Point(basegfx::fround<tools::Long>(aPoint.getX()), + basegfx::fround<tools::Long>(aPoint.getY())); } return aRetval; @@ -2953,7 +2958,7 @@ void SdrPathObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b if(!basegfx::fTools::equalZero(fShearX)) { aTransform.shearX(tan(-atan(fShearX))); - maGeo.nShearAngle = Degree100(FRound(basegfx::rad2deg<100>(atan(fShearX)))); + maGeo.nShearAngle = Degree100(basegfx::fround(basegfx::rad2deg<100>(atan(fShearX)))); maGeo.RecalcTan(); } @@ -2967,7 +2972,7 @@ void SdrPathObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b // #i78696# // fRotate is mathematically correct, but aGeoStat.nRotationAngle is // mirrored -> mirror value here - maGeo.nRotationAngle = NormAngle36000(Degree100(FRound(-basegfx::rad2deg<100>(fRotate)))); + maGeo.nRotationAngle = NormAngle36000(Degree100(basegfx::fround(-basegfx::rad2deg<100>(fRotate)))); maGeo.RecalcSinCos(); } diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx index 989fe0685e6b..694b92fb526d 100644 --- a/svx/source/svdraw/svdorect.cxx +++ b/svx/source/svdraw/svdorect.cxx @@ -181,7 +181,7 @@ void SdrRectObj::TakeUnrotatedSnapRect(tools::Rectangle& rRect) const if (maGeo.nShearAngle==0_deg100) return; - tools::Long nDst=FRound((maRect.Bottom()-maRect.Top()) * maGeo.mfTanShearAngle); + tools::Long nDst=basegfx::fround<tools::Long>((maRect.Bottom()-maRect.Top()) * maGeo.mfTanShearAngle); if (maGeo.nShearAngle>0_deg100) { Point aRef(rRect.TopLeft()); diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index 6e47273fe175..66d7da06d787 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1655,7 +1655,8 @@ void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b } // build and set BaseRect (use scale) - Size aSize(FRound(aScale.getX()), FRound(aScale.getY())); + Size aSize(basegfx::fround<tools::Long>(aScale.getX()), + basegfx::fround<tools::Long>(aScale.getY())); tools::Rectangle aBaseRect(Point(), aSize); SetSnapRect(aBaseRect); @@ -1673,7 +1674,7 @@ void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b if(!basegfx::fTools::equalZero(fShearX)) { GeoStat aGeoStat; - aGeoStat.nShearAngle = Degree100(FRound(basegfx::rad2deg<100>(atan(fShearX)))); + aGeoStat.nShearAngle = Degree100(basegfx::fround(basegfx::rad2deg<100>(atan(fShearX)))); aGeoStat.RecalcTan(); Shear(Point(), aGeoStat.nShearAngle, aGeoStat.mfTanShearAngle, false); } @@ -1686,7 +1687,7 @@ void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b // #i78696# // fRotate is matematically correct, but aGeoStat.nRotationAngle is // mirrored -> mirror value here - aGeoStat.nRotationAngle = NormAngle36000(Degree100(FRound(-basegfx::rad2deg<100>(fRotate)))); + aGeoStat.nRotationAngle = NormAngle36000(Degree100(basegfx::fround(-basegfx::rad2deg<100>(fRotate)))); aGeoStat.RecalcSinCos(); Rotate(Point(), aGeoStat.nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle); } @@ -1694,7 +1695,8 @@ void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const b // translate? if(!aTranslate.equalZero()) { - Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY()))); + Move(Size(basegfx::fround<tools::Long>(aTranslate.getX()), + basegfx::fround<tools::Long>(aTranslate.getY()))); } } diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx index 0955a8b23604..5a7b6372c68f 100644 --- a/svx/source/svdraw/svdotextdecomposition.cxx +++ b/svx/source/svdraw/svdotextdecomposition.cxx @@ -770,8 +770,8 @@ void SdrTextObj::impDecomposeAutoFitTextPrimitive( setSuitableOutlinerBg(rOutliner); // add one to range sizes to get back to the old Rectangle and outliner measurements - const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1)); - const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1)); + const sal_uInt32 nAnchorTextWidth(basegfx::fround<sal_uInt32>(aAnchorTextRange.getWidth() + 1)); + const sal_uInt32 nAnchorTextHeight(basegfx::fround<sal_uInt32>(aAnchorTextRange.getHeight() + 1)); const OutlinerParaObject* pOutlinerParaObject = rSdrAutofitTextPrimitive.getSdrText()->GetOutlinerParaObject(); OSL_ENSURE(pOutlinerParaObject, "impDecomposeBlockTextPrimitive used with no OutlinerParaObject (!)"); const bool bVerticalWriting(pOutlinerParaObject->IsEffectivelyVertical()); @@ -962,8 +962,8 @@ void SdrTextObj::impDecomposeBlockTextPrimitive( setSuitableOutlinerBg(rOutliner); // add one to range sizes to get back to the old Rectangle and outliner measurements - const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1)); - const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1)); + const sal_uInt32 nAnchorTextWidth(basegfx::fround<sal_uInt32>(aAnchorTextRange.getWidth() + 1)); + const sal_uInt32 nAnchorTextHeight(basegfx::fround<sal_uInt32>(aAnchorTextRange.getHeight() + 1)); const bool bVerticalWriting(rSdrBlockTextPrimitive.getOutlinerParaObject().IsEffectivelyVertical()); const bool bTopToBottom(rSdrBlockTextPrimitive.getOutlinerParaObject().IsTopToBottom()); const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight)); @@ -1571,8 +1571,8 @@ void SdrTextObj::impDecomposeChainedTextPrimitive( rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000)); // add one to range sizes to get back to the old Rectangle and outliner measurements - const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1)); - const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1)); + const sal_uInt32 nAnchorTextWidth(basegfx::fround<sal_uInt32>(aAnchorTextRange.getWidth() + 1)); + const sal_uInt32 nAnchorTextHeight(basegfx::fround<sal_uInt32>(aAnchorTextRange.getHeight() + 1)); // Text const OutlinerParaObject* pOutlinerParaObject = rSdrChainedTextPrimitive.getSdrText()->GetOutlinerParaObject(); diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 7509991ba346..a9229596d2c6 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -342,7 +342,8 @@ void ImpSdrPdfImport::SetAttributes(SdrObject* pObj, bool bForceTextAttr) if (bText && mbFntDirty) { vcl::Font aFnt(mpVD->GetFont()); - const sal_uInt32 nHeight(FRound(aFnt.GetFontSize().Height() * mfScaleY)); + const sal_uInt32 nHeight( + basegfx::fround<sal_uInt32>(aFnt.GetFontSize().Height() * mfScaleY)); mpTextAttr->Put(SvxFontItem(aFnt.GetFamilyType(), aFnt.GetFamilyName(), aFnt.GetStyleName(), aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO)); @@ -522,12 +523,12 @@ void ImpSdrPdfImport::InsertObj(SdrObject* pObj1, bool bScale) const Size aOrigSizePixel(aBitmapEx.GetSizePixel()); const Point aClipTopLeft( - basegfx::fround(floor(std::max(0.0, aPixel.getMinX()))), - basegfx::fround(floor(std::max(0.0, aPixel.getMinY())))); + basegfx::fround<tools::Long>(floor(std::max(0.0, aPixel.getMinX()))), + basegfx::fround<tools::Long>(floor(std::max(0.0, aPixel.getMinY())))); const Size aClipSize( - basegfx::fround(ceil(std::min( + basegfx::fround<tools::Long>(ceil(std::min( static_cast<double>(aOrigSizePixel.Width()), aPixel.getWidth()))), - basegfx::fround( + basegfx::fround<tools::Long>( ceil(std::min(static_cast<double>(aOrigSizePixel.Height()), aPixel.getHeight())))); const BitmapEx aClippedBitmap(aBitmapEx, aClipTopLeft, aClipSize); @@ -782,12 +783,13 @@ void ImpSdrPdfImport::InsertTextObject(const Point& rPos, const Size& rSize, con // sal_Int32 nTextWidth = static_cast<sal_Int32>(mpVD->GetTextWidth(rStr) * mfScaleX); sal_Int32 nTextHeight = static_cast<sal_Int32>(mpVD->GetTextHeight() * mfScaleY); - Point aPosition(FRound(rPos.X() * mfScaleX + maOfs.X()), - FRound(rPos.Y() * mfScaleY + maOfs.Y())); - Size aSize(FRound(rSize.Width() * mfScaleX), FRound(rSize.Height() * mfScaleY)); + Point aPosition(basegfx::fround<tools::Long>(rPos.X() * mfScaleX + maOfs.X()), + basegfx::fround<tools::Long>(rPos.Y() * mfScaleY + maOfs.Y())); + Size aSize(basegfx::fround<tools::Long>(rSize.Width() * mfScaleX), + basegfx::fround<tools::Long>(rSize.Height() * mfScaleY)); if (eAlignment == ALIGN_BASELINE) - aPosition.AdjustY(-FRound(aFontMetric.GetAscent() * mfScaleY)); + aPosition.AdjustY(basegfx::fround<tools::Long>(aFontMetric.GetAscent() * -mfScaleY)); else if (eAlignment == ALIGN_BOTTOM) aPosition.AdjustY(-nTextHeight); diff --git a/svx/source/svdraw/svdpoev.cxx b/svx/source/svdraw/svdpoev.cxx index b7365ea3b047..2d5fe3077b38 100644 --- a/svx/source/svdraw/svdpoev.cxx +++ b/svx/source/svdraw/svdpoev.cxx @@ -553,19 +553,22 @@ void SdrPolyEditView::ImpTransformMarkedPoints(PPolyTrFunc pTrFunc, const void* bool bC2(false); const basegfx::B2DPoint aB2DPos(aNewXP.getB2DPoint(nPointNum)); - aPos = Point(FRound(aB2DPos.getX()), FRound(aB2DPos.getY())); + aPos = Point(basegfx::fround<tools::Long>(aB2DPos.getX()), + basegfx::fround<tools::Long>(aB2DPos.getY())); if(aNewXP.isPrevControlPointUsed(nPointNum)) { const basegfx::B2DPoint aB2DC1(aNewXP.getPrevControlPoint(nPointNum)); - aC1 = Point(FRound(aB2DC1.getX()), FRound(aB2DC1.getY())); + aC1 = Point(basegfx::fround<tools::Long>(aB2DC1.getX()), + basegfx::fround<tools::Long>(aB2DC1.getY())); bC1 = true; } if(aNewXP.isNextControlPointUsed(nPointNum)) { const basegfx::B2DPoint aB2DC2(aNewXP.getNextControlPoint(nPointNum)); - aC2 = Point(FRound(aB2DC2.getX()), FRound(aB2DC2.getY())); + aC2 = Point(basegfx::fround<tools::Long>(aB2DC2.getX()), + basegfx::fround<tools::Long>(aB2DC2.getY())); bC2 = true; } diff --git a/svx/source/svdraw/svdtrans.cxx b/svx/source/svdraw/svdtrans.cxx index 23ce4787427e..e7e4ecce6d9c 100644 --- a/svx/source/svdraw/svdtrans.cxx +++ b/svx/source/svdraw/svdtrans.cxx @@ -46,8 +46,8 @@ void ResizeRect(tools::Rectangle& rRect, const Point& rRef, const Fraction& rxFa tools::Long nWdt = rRect.Right() - rRect.Left(); if (nWdt == 0) rRect.AdjustRight( 1 ); } - rRect.SetLeft( rRef.X() + FRound( (rRect.Left() - rRef.X()) * double(aXFact) ) ); - rRect.SetRight( rRef.X() + FRound( (rRect.Right() - rRef.X()) * double(aXFact) ) ); + rRect.SetLeft( rRef.X() + basegfx::fround<tools::Long>( (rRect.Left() - rRef.X()) * double(aXFact) ) ); + rRect.SetRight( rRef.X() + basegfx::fround<tools::Long>( (rRect.Right() - rRef.X()) * double(aXFact) ) ); if (!aYFact.IsValid()) { SAL_WARN( "svx.svdraw", "invalid fraction yFract, using Fraction(1,1)" ); @@ -55,8 +55,8 @@ void ResizeRect(tools::Rectangle& rRect, const Point& rRef, const Fraction& rxFa tools::Long nHgt = rRect.Bottom() - rRect.Top(); if (nHgt == 0) rRect.AdjustBottom( 1 ); } - rRect.SetTop( rRef.Y() + FRound( (rRect.Top() - rRef.Y()) * double(aYFact) ) ); - rRect.SetBottom( rRef.Y() + FRound( (rRect.Bottom() - rRef.Y()) * double(aYFact) ) ); + rRect.SetTop( rRef.Y() + basegfx::fround<tools::Long>( (rRect.Top() - rRef.Y()) * double(aYFact) ) ); + rRect.SetBottom( rRef.Y() + basegfx::fround<tools::Long>( (rRect.Bottom() - rRef.Y()) * double(aYFact) ) ); rRect.Normalize(); } @@ -178,7 +178,7 @@ double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCent // move into the direction of the center, as a basic position for the rotation pC1->AdjustY( -y0 ); // resize, account for the distance from the center - pC1->setY(FRound(static_cast<double>(pC1->Y()) /rRad.X()*(cx-pC1->X())) ); + pC1->setY(basegfx::fround<tools::Long>(static_cast<double>(pC1->Y()) /rRad.X()*(cx-pC1->X())) ); pC1->AdjustY(cy ); } else { // move into the direction of the center, as a basic position for the rotation @@ -186,7 +186,7 @@ double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCent // resize, account for the distance from the center tools::Long nPntRad=cy-pC1->Y(); double nFact=static_cast<double>(nPntRad)/static_cast<double>(rRad.Y()); - pC1->setX(FRound(static_cast<double>(pC1->X())*nFact) ); + pC1->setX(basegfx::fround<tools::Long>(static_cast<double>(pC1->X()) * nFact)); pC1->AdjustX(cx ); } RotatePoint(*pC1,rCenter,sn,cs); @@ -196,7 +196,7 @@ double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCent // move into the direction of the center, as a basic position for the rotation pC2->AdjustY( -y0 ); // resize, account for the distance from the center - pC2->setY(FRound(static_cast<double>(pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X())) ); + pC2->setY(basegfx::fround<tools::Long>(static_cast<double>(pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X())) ); pC2->AdjustY(cy ); } else { // move into the direction of the center, as a basic position for the rotation @@ -204,7 +204,7 @@ double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCent // resize, account for the distance from the center tools::Long nPntRad=rCenter.Y()-pC2->Y(); double nFact=static_cast<double>(nPntRad)/static_cast<double>(rRad.Y()); - pC2->setX(FRound(static_cast<double>(pC2->X())*nFact) ); + pC2->setX(basegfx::fround<tools::Long>(static_cast<double>(pC2->X()) * nFact)); pC2->AdjustX(cx ); } RotatePoint(*pC2,rCenter,sn,cs); @@ -283,7 +283,7 @@ double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCen tools::Long dy=rPnt.Y()-y0; double a=static_cast<double>(y0-nTop)/nHgt; a*=dy; - rPnt.setY(y0+FRound(a) ); + rPnt.setY(y0 + basegfx::fround<tools::Long>(a)); } return 0.0; } @@ -393,7 +393,7 @@ Degree100 GetAngle(const Point& rPnt) if (rPnt.Y()>0) a=-9000_deg100; else a=9000_deg100; } else { - a = Degree100(FRound(basegfx::rad2deg<100>(atan2(static_cast<double>(-rPnt.Y()), static_cast<double>(rPnt.X()))))); + a = Degree100(basegfx::fround(basegfx::rad2deg<100>(atan2(-static_cast<double>(rPnt.Y()), static_cast<double>(rPnt.X()))))); } return a; } @@ -423,7 +423,7 @@ tools::Long GetLen(const Point& rPnt) x*=x; y*=y; x+=y; - x=FRound(sqrt(static_cast<double>(x))); + x = basegfx::fround<tools::Long>(sqrt(x)); return x; } else { double nx=x; @@ -435,7 +435,7 @@ tools::Long GetLen(const Point& rPnt) if (nx>0x7FFFFFFF) { return 0x7FFFFFFF; // we can't go any further, for fear of an overrun! } else { - return FRound(nx); + return basegfx::fround<tools::Long>(nx); } } } diff --git a/svx/source/unodraw/UnoGraphicExporter.cxx b/svx/source/unodraw/UnoGraphicExporter.cxx index 66af82d6baac..9acec5198dc3 100644 --- a/svx/source/unodraw/UnoGraphicExporter.cxx +++ b/svx/source/unodraw/UnoGraphicExporter.cxx @@ -931,8 +931,8 @@ bool GraphicExporter::GetGraphic( ExportSettings const & rSettings, Graphic& aGr // that avoids to do it later by Metafile::Move what would be expensive aOutMap.SetOrigin( Point( - basegfx::fround(-aBound.getMinX() - aHalfPixelInMtf.getWidth()), - basegfx::fround(-aBound.getMinY() - aHalfPixelInMtf.getHeight()) ) ); + basegfx::fround<tools::Long>(-aBound.getMinX() - aHalfPixelInMtf.getWidth()), + basegfx::fround<tools::Long>(-aBound.getMinY() - aHalfPixelInMtf.getHeight()) ) ); aOut->SetRelativeMapMode( aOutMap ); sdr::contact::DisplayInfo aDisplayInfo; @@ -970,8 +970,8 @@ bool GraphicExporter::GetGraphic( ExportSettings const & rSettings, Graphic& aGr // export is always a risky thing, so it will have to show if this will // not influence something else. const Size aBoundSize( - basegfx::fround(aBound.getWidth() + 1), - basegfx::fround(aBound.getHeight() + 1)); + basegfx::fround<tools::Long>(aBound.getWidth() + 1), + basegfx::fround<tools::Long>(aBound.getHeight() + 1)); aMtf.SetPrefMapMode( aMap ); aMtf.SetPrefSize( aBoundSize ); diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index 60dd13aeac7d..99f86437a96f 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -2006,8 +2006,8 @@ bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn basegfx::B2DHomMatrix aNewHomogenMatrix; pSdrObject->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon); - aVclPoint.AdjustX(basegfx::fround(aNewHomogenMatrix.get(0, 2)) ); - aVclPoint.AdjustY(basegfx::fround(aNewHomogenMatrix.get(1, 2)) ); + aVclPoint.AdjustX(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(0, 2)) ); + aVclPoint.AdjustY(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(1, 2)) ); // #88491# position relative to anchor if( pSdrObject->getSdrModelFromSdrObject().IsWriter() ) @@ -2511,8 +2511,8 @@ bool SvxShape::getPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn basegfx::B2DHomMatrix aNewHomogenMatrix; GetSdrObject()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon); - aVclPoint.AdjustX( -(basegfx::fround(aNewHomogenMatrix.get(0, 2))) ); - aVclPoint.AdjustY( -(basegfx::fround(aNewHomogenMatrix.get(1, 2))) ); + aVclPoint.AdjustX( -(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(0, 2))) ); + aVclPoint.AdjustY( -(basegfx::fround<tools::Long>(aNewHomogenMatrix.get(1, 2))) ); // tdf#117145 metric of SdrModel is app-specific, metric of UNO API is 100thmm // Need to adapt aVclPoint from app-specific to 100thmm diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx index e9f0f1ebad15..d93e56412b7b 100644 --- a/svx/source/xoutdev/_xpoly.cxx +++ b/svx/source/xoutdev/_xpoly.cxx @@ -407,9 +407,10 @@ tools::Rectangle XPolygon::GetBoundRect() const // correct and never was. const basegfx::B2DRange aPolygonRange(basegfx::utils::getRange(getB2DPolygon())); - aRetval = tools::Rectangle( - FRound(aPolygonRange.getMinX()), FRound(aPolygonRange.getMinY()), - FRound(aPolygonRange.getMaxX()), FRound(aPolygonRange.getMaxY())); + aRetval = tools::Rectangle(basegfx::fround<tools::Long>(aPolygonRange.getMinX()), + basegfx::fround<tools::Long>(aPolygonRange.getMinY()), + basegfx::fround<tools::Long>(aPolygonRange.getMaxX()), + basegfx::fround<tools::Long>(aPolygonRange.getMaxY())); } return aRetval; diff --git a/sw/qa/extras/htmlexport/data/tdf160867_image_with_link.fodt b/sw/qa/extras/htmlexport/data/tdf160867_image_with_link.fodt new file mode 100644 index 000000000000..43c35cdff13e --- /dev/null +++ b/sw/qa/extras/htmlexport/data/tdf160867_image_with_link.fodt @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:styles> + <style:style style:name="Frame" style:family="graphic"> + <style:graphic-properties text:anchor-type="as-char" svg:x="0" svg:y="0" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" fo:background-color="transparent" draw:fill="none" fo:margin-left="0" fo:margin-right="0" fo:margin-top="0" fo:margin-bottom="0" style:wrap="none" style:vertical-pos="middle" style:vertical-rel="baseline" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:padding="0" fo:border="none" loext:rel-width-rel="paragraph"/> + </style:style> + </office:styles> + <office:body> + <office:text> + <text:p><draw:a xlink:type="simple" xlink:href="foo/bar"><draw:frame draw:style-name="Frame" draw:name="image1" svg:width="17cm" svg:height="25mm" style:rel-height="scale"><draw:image draw:mime-type="image/png"> + <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAMSURBVBhXY/jPwAAAAwEBAGMkVdMAAAAASUVORK5C</office:binary-data> + </draw:image> + </draw:frame></draw:a>image1 with a hyperlink, and this text with <text:a xlink:type="simple" xlink:href="baz" text:style-name="Internet_20_link" text:visited-style-name="Visited_20_Internet_20_Link">another hyperlink</text:a></text:p> + <text:p><draw:frame draw:style-name="Frame" draw:name="frame" svg:width="17cm"> + <draw:text-box fo:min-height="1pt"> + <text:p><draw:a xlink:type="simple" xlink:href="foo/bar"><draw:frame draw:style-name="Frame" draw:name="image2" svg:width="17cm" svg:height="25mm"><draw:image draw:mime-type="image/png"> + <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAMSURBVBhXY/jPwAAAAwEBAGMkVdMAAAAASUVORK5C</office:binary-data> + </draw:image> + </draw:frame></draw:a>image2 with a hyperlink, and this text with <text:a xlink:type="simple" xlink:href="baz" text:style-name="Internet_20_link" text:visited-style-name="Visited_20_Internet_20_Link">another hyperlink</text:a>, in a frame</text:p> + </draw:text-box> + </draw:frame></text:p> + </office:text> + </office:body> +</office:document>
\ No newline at end of file diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index 6c06299fb6df..f1e32f9d110e 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -3054,6 +3054,47 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_Tdf160390) save("HTML (StarWriter)"); } +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testHTML_160867) +{ + // Given a document with an image with hyperlink, and text with hyperlink, both in a frame: + createSwDoc("tdf160867_image_with_link.fodt"); + // When exporting to HTML: + save("HTML (StarWriter)"); + // Parse it as XML (strict!) + xmlDocUniquePtr pDoc = parseXml(maTempFile); + CPPUNIT_ASSERT(pDoc); + assertXPath(pDoc, "/html/body/p", 2); + + // Test export of image and text hyperlinks in the image map. + // Without the fix, the test would fail with + // - Expected: 1 + // - Actual : 0 + // - In <>, XPath '/html/body/p[2]/map' number of nodes is incorrect + const OUString mapName = getXPath(pDoc, "/html/body/p[2]/map", "name"); + assertXPath(pDoc, "/html/body/p[2]/map/area[1]", "shape", "rect"); + CPPUNIT_ASSERT(getXPath(pDoc, "/html/body/p[2]/map/area[1]", "href").endsWith("foo/bar")); + assertXPath(pDoc, "/html/body/p[2]/map/area[2]", "shape", "rect"); + CPPUNIT_ASSERT(getXPath(pDoc, "/html/body/p[2]/map/area[2]", "href").endsWith("baz")); + assertXPath(pDoc, "/html/body/p[2]/img", "usemap", "#" + mapName); +} + +CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_160867) +{ + // Given a document with an image with hyperlink, and text with hyperlink, both in a frame: + createSwDoc("tdf160867_image_with_link.fodt"); + // When exporting to reqif: + ExportToReqif(); + // For now, we don't (yet) output the whole map in ReqIF case. + // Make sure that the first hyperlink from the objects in the frame is output as an <a> element + // around the whole image of the frame. + SvMemoryStream aStream; + WrapReqifFromTempFile(aStream); + xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream); + assertXPath(pXmlDoc, "//reqif-xhtml:p[2]/reqif-xhtml:a/reqif-xhtml:object"); + CPPUNIT_ASSERT( + getXPath(pXmlDoc, "//reqif-xhtml:p[2]/reqif-xhtml:a", "href").endsWith("foo/bar")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 0ffdb543fbd9..65b31c5909c6 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -3673,7 +3673,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf106234) "type", "PortionType::Margin"); // This was a justified line, without width assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[1]/SwGluePortion", - "width", "7881"); + "width", "7882"); } CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287b) @@ -3686,7 +3686,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287b) assertXPath( pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::TabRight']", - "width", "17"); + "width", "19"); } CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287c) @@ -3819,7 +3819,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf122607) assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/txt[1]/anchored/fly/tab/row[2]/cell/txt[7]/anchored/" "fly/txt/SwParaPortion/SwLineLayout/child::*[1]", - "width", "428"); + "width", "427"); assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/txt[1]/anchored/fly/tab/row[2]/cell/txt[7]/anchored/" "fly/txt/SwParaPortion/SwLineLayout/child::*[1]", diff --git a/sw/qa/extras/ww8export/data/empty_group.docx b/sw/qa/extras/ww8export/data/empty_group.docx Binary files differnew file mode 100644 index 000000000000..a3454746c5e0 --- /dev/null +++ b/sw/qa/extras/ww8export/data/empty_group.docx diff --git a/sw/qa/extras/ww8export/ww8export4.cxx b/sw/qa/extras/ww8export/ww8export4.cxx index efb198ebae00..b4116ff2bbac 100644 --- a/sw/qa/extras/ww8export/ww8export4.cxx +++ b/sw/qa/extras/ww8export/ww8export4.cxx @@ -19,8 +19,11 @@ #include <comphelper/sequenceashashmap.hxx> #include <o3tl/string_view.hxx> +#include <svx/svdpage.hxx> #include <docsh.hxx> +#include <drawdoc.hxx> +#include <IDocumentDrawModelAccess.hxx> #include <IDocumentSettingAccess.hxx> #include <unotxdoc.hxx> @@ -78,6 +81,27 @@ DECLARE_WW8EXPORT_TEST(testTdf104704_mangledFooter, "tdf104704_mangledFooter.odt CPPUNIT_ASSERT_EQUAL(2, getPages()); } +CPPUNIT_TEST_FIXTURE(Test, testEmptyGroup) +{ + // Given a document with an empty group + createSwDoc("empty_group.docx"); + + CPPUNIT_ASSERT_EQUAL(1, getPages()); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pObject = pPage->GetObj(0); + + CPPUNIT_ASSERT_EQUAL(OUString("Empty group"), pObject->GetName()); + CPPUNIT_ASSERT(pObject->IsGroupObject()); + CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetSubList()->GetObjCount()); + + // it must not assert/crash on save + saveAndReload(OUString::createFromAscii(mpFilter)); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx index 9e2b96ce3118..8faf9e4a72eb 100644 --- a/sw/source/core/draw/dflyobj.cxx +++ b/sw/source/core/draw/dflyobj.cxx @@ -856,8 +856,8 @@ void SwVirtFlyDrawObj::NbcCrop(const basegfx::B2DPoint& rRef, double fxFact, dou // rRef is relative to the Crop-Action, si in X/Y-Ranges of [0.0 .. 1.0], // to get the correct absolute position, transform using the old Rect const Point aRef( - aOldRect.Left() + basegfx::fround(aOldRect.GetWidth() * rRef.getX()), - aOldRect.Top() + basegfx::fround(aOldRect.GetHeight() * rRef.getY())); + aOldRect.Left() + basegfx::fround<tools::Long>(aOldRect.GetWidth() * rRef.getX()), + aOldRect.Top() + basegfx::fround<tools::Long>(aOldRect.GetHeight() * rRef.getY())); // apply transformation, use old ResizeRect for now tools::Rectangle aNewRect( aOldRect ); @@ -946,8 +946,8 @@ void SwVirtFlyDrawObj::NbcCrop(const basegfx::B2DPoint& rRef, double fxFact, dou // Create the new TopLeft of the unrotated, cropped object by creating // as if re-creating the unrotated geometry aNewTopLeft = Point( - basegfx::fround(aRotNewCenter.getX() - (0.5 * aNewRect.getOpenWidth())), - basegfx::fround(aRotNewCenter.getY() - (0.5 * aNewRect.getOpenHeight()))); + basegfx::fround<tools::Long>(aRotNewCenter.getX() - (0.5 * aNewRect.getOpenWidth())), + basegfx::fround<tools::Long>(aRotNewCenter.getY() - (0.5 * aNewRect.getOpenHeight()))); } // check if we have movement and execute if yes @@ -1008,10 +1008,10 @@ void SwVirtFlyDrawObj::NbcResize(const Point& rRef, const Fraction& xFact, const // create new modified, but untransformed OutRect setOutRectangle(tools::Rectangle( - basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())), - basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())), - basegfx::fround(aCenter.getX() + (0.5 * aAbsScale.getX())), - basegfx::fround(aCenter.getY() + (0.5 * aAbsScale.getY())))); + basegfx::fround<tools::Long>(aCenter.getX() - (0.5 * aAbsScale.getX())), + basegfx::fround<tools::Long>(aCenter.getY() - (0.5 * aAbsScale.getY())), + basegfx::fround<tools::Long>(aCenter.getX() + (0.5 * aAbsScale.getX())), + basegfx::fround<tools::Long>(aCenter.getY() + (0.5 * aAbsScale.getY())))); // restore FrameAreas so that actions below not adapted to new // full transformations take the correct actions @@ -1232,21 +1232,21 @@ void SwVirtFlyDrawObj::addCropHandles(SdrHdlList& rTarget) const basegfx::B2DPoint aPos; aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::UpperLeft, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(0.5, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Upper, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::UpperRight, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(0.0, 0.5); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Left , fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(1.0, 0.5); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Right, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(0.0, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::LowerLeft, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(0.5, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::Lower, fShearX, fRotate)); aPos = aTargetTransform * basegfx::B2DPoint(1.0, 1.0); - rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate)); + rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround<tools::Long>(aPos.getX()), basegfx::fround<tools::Long>(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate)); } // Macro diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx index 1d13b7a7a917..3826c2afff41 100644 --- a/sw/source/core/graphic/ndgrf.cxx +++ b/sw/source/core/graphic/ndgrf.cxx @@ -813,8 +813,7 @@ GraphicAttr& SwGrfNode::GetGraphicAttr( GraphicAttr& rGA, rGA.SetInvert( rSet.GetInvertGrf().GetValue() ); const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue(); - rGA.SetAlpha( 255 - static_cast<sal_uInt8>(FRound( - std::min( nTrans, sal_uInt16(100) ) * 2.55 )) ); + rGA.SetAlpha(255 - basegfx::fround<sal_uInt8>(nTrans * 2.55)); return rGA; } diff --git a/sw/source/core/inc/noteurl.hxx b/sw/source/core/inc/noteurl.hxx index 1e5775d3c099..b575b60d20a0 100644 --- a/sw/source/core/inc/noteurl.hxx +++ b/sw/source/core/inc/noteurl.hxx @@ -20,12 +20,46 @@ #ifndef INCLUDED_SW_SOURCE_CORE_INC_NOTEURL_HXX #define INCLUDED_SW_SOURCE_CORE_INC_NOTEURL_HXX +#include <swrect.hxx> + +#include <rtl/ustring.hxx> + +#include <vector> + +class ImageMap; +class MapMode; + +class SwURLNote +{ + OUString aURL; + OUString aTarget; + SwRect aRect; + +public: + SwURLNote(const OUString& rURL, const OUString& rTarget, const SwRect& rRect) + : aURL(rURL) + , aTarget(rTarget) + , aRect(rRect) + { + } + const OUString& GetURL() const { return aURL; } + const OUString& GetTarget() const { return aTarget; } + const SwRect& GetRect() const { return aRect; } +}; + class SwNoteURL { +private: + std::vector<SwURLNote> m_List; + +public: + SwNoteURL() {} + void InsertURLNote(const OUString& rURL, const OUString& rTarget, const SwRect& rRect); + void FillImageMap(ImageMap* pMap, const Point& rPos, const MapMode& rMap); }; // globale Variable, in NoteURL.Cxx angelegt -extern SwNoteURL* pNoteURL; +extern thread_local SwNoteURL* pNoteURL; #endif diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx index 38936574a471..233b933175c2 100644 --- a/sw/source/core/inc/swfont.hxx +++ b/sw/source/core/inc/swfont.hxx @@ -169,6 +169,7 @@ class SwFont bool m_bFontChg :1; bool m_bOrgChg :1; // nOrgHeight/Ascent are invalid bool m_bGreyWave :1; // for the extended TextInput: gray waveline + bool m_bURL = false; public: SwFont( const SwAttrSet* pSet, const IDocumentSettingAccess* pIDocumentSettingAccess ); @@ -259,6 +260,8 @@ public: inline void SetGreyWave( const bool bNew ); bool IsGreyWave() const { return m_bGreyWave; } bool IsPaintBlank() const { return m_bPaintBlank; } + void SetURL(const bool bURL) { m_bURL = bURL; } + bool IsURL() const { return m_bURL; } // setting of the base class font for SwTextCharFormat void SetDiffFnt( const SfxItemSet* pSet, diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index 250b634bab16..08857566c832 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2751,7 +2751,7 @@ bool SwFlyFrame::GetContour( tools::PolyPolygon& rContour, else aNewPoint = OutputDevice::LogicToLogic( rPoly[ i ], aGrfMap, aDispMap ); - rPoly[ i ] = Point( FRound( aNewPoint.getX() * fScaleX ), FRound( aNewPoint.getY() * fScaleY ) ); + rPoly[ i ] = Point( basegfx::fround<tools::Long>( aNewPoint.getX() * fScaleX ), basegfx::fround<tools::Long>( aNewPoint.getY() * fScaleY ) ); } } } diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index be694a390350..3d11229acb9f 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -7627,7 +7627,7 @@ Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap, const sal_uInt32 /*nMaxim SfxItemState::SET != GetAttrSet().GetItemState( RES_URL ); if( bNoteURL ) { - OSL_ENSURE( !pNoteURL, "MakeGraphic: pNoteURL already used? " ); + assert(!pNoteURL); pNoteURL = new SwNoteURL; } SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pFirst); @@ -7708,7 +7708,8 @@ Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap, const sal_uInt32 /*nMaxim if( bNoteURL ) { - OSL_ENSURE( pNoteURL, "MakeGraphic: Good Bye, NoteURL." ); + assert(pNoteURL); + pNoteURL->FillImageMap(pMap, pFly->getFrameArea().Pos(), aMap); delete pNoteURL; pNoteURL = nullptr; } diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index c59717f94901..46751824b869 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -179,10 +179,10 @@ SwRect TransformableSwFrame::getUntransformedFrameArea() const const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale)); return SwRect( - basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())), - basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())), - basegfx::fround(aAbsScale.getX()), - basegfx::fround(aAbsScale.getY())); + basegfx::fround<tools::Long>(aCenter.getX() - (0.5 * aAbsScale.getX())), + basegfx::fround<tools::Long>(aCenter.getY() - (0.5 * aAbsScale.getY())), + basegfx::fround<tools::Long>(aAbsScale.getX()), + basegfx::fround<tools::Long>(aAbsScale.getY())); } } @@ -204,10 +204,10 @@ SwRect TransformableSwFrame::getUntransformedFramePrintArea() const const SwRect aUntransformedFrameArea(getUntransformedFrameArea()); return SwRect( - basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())) - aUntransformedFrameArea.Left(), - basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())) - aUntransformedFrameArea.Top(), - basegfx::fround(aAbsScale.getX()), - basegfx::fround(aAbsScale.getY())); + basegfx::fround<tools::Long>(aCenter.getX() - (0.5 * aAbsScale.getX())) - aUntransformedFrameArea.Left(), + basegfx::fround<tools::Long>(aCenter.getY() - (0.5 * aAbsScale.getY())) - aUntransformedFrameArea.Top(), + basegfx::fround<tools::Long>(aAbsScale.getX()), + basegfx::fround<tools::Long>(aAbsScale.getY())); } } @@ -238,8 +238,8 @@ void TransformableSwFrame::adaptFrameAreasToTransformations() basegfx::B2DRange aRangeFrameArea(0.0, 0.0, 1.0, 1.0); aRangeFrameArea.transform(getLocalFrameAreaTransformation()); const SwRect aNewFrm( - basegfx::fround(aRangeFrameArea.getMinX()), basegfx::fround(aRangeFrameArea.getMinY()), - basegfx::fround(aRangeFrameArea.getWidth()), basegfx::fround(aRangeFrameArea.getHeight())); + basegfx::fround<tools::Long>(aRangeFrameArea.getMinX()), basegfx::fround<tools::Long>(aRangeFrameArea.getMinY()), + basegfx::fround<tools::Long>(aRangeFrameArea.getWidth()), basegfx::fround<tools::Long>(aRangeFrameArea.getHeight())); if(aNewFrm != mrSwFrameAreaDefinition.getFrameArea()) { @@ -254,10 +254,10 @@ void TransformableSwFrame::adaptFrameAreasToTransformations() basegfx::B2DRange aRangeFramePrintArea(0.0, 0.0, 1.0, 1.0); aRangeFramePrintArea.transform(getLocalFramePrintAreaTransformation()); const SwRect aNewPrt( - basegfx::fround(aRangeFramePrintArea.getMinX()) - mrSwFrameAreaDefinition.getFrameArea().Left(), - basegfx::fround(aRangeFramePrintArea.getMinY()) - mrSwFrameAreaDefinition.getFrameArea().Top(), - basegfx::fround(aRangeFramePrintArea.getWidth()), - basegfx::fround(aRangeFramePrintArea.getHeight())); + basegfx::fround<tools::Long>(aRangeFramePrintArea.getMinX()) - mrSwFrameAreaDefinition.getFrameArea().Left(), + basegfx::fround<tools::Long>(aRangeFramePrintArea.getMinY()) - mrSwFrameAreaDefinition.getFrameArea().Top(), + basegfx::fround<tools::Long>(aRangeFramePrintArea.getWidth()), + basegfx::fround<tools::Long>(aRangeFramePrintArea.getHeight())); if(aNewPrt != mrSwFrameAreaDefinition.getFramePrintArea()) { diff --git a/sw/source/core/text/atrhndl.hxx b/sw/source/core/text/atrhndl.hxx index 851615325a06..efe1ae954958 100644 --- a/sw/source/core/text/atrhndl.hxx +++ b/sw/source/core/text/atrhndl.hxx @@ -46,6 +46,8 @@ private: // a template, if we have to restart the attribute evaluation std::optional<SwFont> m_oFnt; + int m_nINETFMT = 0; // for font's SetURL + bool m_bVertLayout; bool m_bVertLayoutLRBT; diff --git a/sw/source/core/text/atrstck.cxx b/sw/source/core/text/atrstck.cxx index 7fab6da10c5e..c6744d50e780 100644 --- a/sw/source/core/text/atrstck.cxx +++ b/sw/source/core/text/atrstck.cxx @@ -367,6 +367,13 @@ void SwAttrHandler::PushAndChg( const SwTextAttr& rAttr, SwFont& rFnt ) } } } + + if (rAttr.Which() == RES_TXTATR_INETFMT) + { + if (m_nINETFMT == 0) + rFnt.SetURL(true); + ++m_nINETFMT; + } } // this is the usual case, we have a basic attribute, push it onto the // stack and change the font @@ -433,6 +440,14 @@ void SwAttrHandler::PopAndChg( const SwTextAttr& rAttr, SwFont& rFnt ) const SfxItemSet* pSet = CharFormat::GetItemSet( rAttr.GetAttr() ); if ( !pSet ) return; + if (rAttr.Which() == RES_TXTATR_INETFMT) + { + assert(m_nINETFMT > 0); + --m_nINETFMT; + if (m_nINETFMT == 0) + rFnt.SetURL(false); + } + for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) { const SfxPoolItem* pItem; diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index 737b6b3b2700..2cc1b0329f62 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -21,7 +21,9 @@ #include <unotools/linguprops.hxx> #include <unotools/lingucfg.hxx> +#include <fmtinfmt.hxx> #include <hintids.hxx> +#include <txatbase.hxx> #include <svl/ctloptions.hxx> #include <sfx2/infobar.hxx> #include <sfx2/printer.hxx> @@ -42,6 +44,7 @@ #include <viewsh.hxx> #include <viewopt.hxx> #include <frmtool.hxx> +#include <fmturl.hxx> #include <IDocumentSettingAccess.hxx> #include <IDocumentDeviceAccess.hxx> #include <IDocumentMarkAccess.hxx> @@ -49,6 +52,7 @@ #include <rootfrm.hxx> #include "inftxt.hxx" #include <noteurl.hxx> +#include "porfly.hxx" #include "porftn.hxx" #include "porrst.hxx" #include "itratr.hxx" @@ -1363,6 +1367,39 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor, DrawBackground( rPor, pColor ); } +void SwTextPaintInfo::NotifyURL_(const SwLinePortion& rPor) const +{ + assert(pNoteURL); + + SwRect aIntersect; + CalcRect(rPor, nullptr, &aIntersect); + + if (aIntersect.HasArea()) + { + SwTextNode* pNd = const_cast<SwTextNode*>(GetTextFrame()->GetTextNodeFirst()); + SwTextAttr* const pAttr = pNd->GetTextAttrAt(sal_Int32(GetIdx()), RES_TXTATR_INETFMT); + if (pAttr) + { + const SwFormatINetFormat& rFormat = pAttr->GetINetFormat(); + pNoteURL->InsertURLNote(rFormat.GetValue(), rFormat.GetTargetFrame(), aIntersect); + } + else if (rPor.IsFlyCntPortion()) + { + if (auto* pFlyContentPortion = dynamic_cast<const sw::FlyContentPortion*>(&rPor)) + { + if (auto* pFlyFtame = pFlyContentPortion->GetFlyFrame()) + { + if (auto* pFormat = pFlyFtame->GetFormat()) + { + auto& url = pFormat->GetURL(); // TODO: url.GetMap() ? + pNoteURL->InsertURLNote(url.GetURL(), url.GetTargetFrameName(), aIntersect); + } + } + } + } + } +} + static void lcl_InitHyphValues( PropertyValues &rVals, sal_Int16 nMinLeading, sal_Int16 nMinTrailing, bool bNoCapsHyphenation, bool bNoLastWordHyphenation, diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index 8011b29b442a..1ab5e3496f6b 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -358,6 +358,7 @@ class SwTextPaintInfo : public SwTextSizeInfo const bool bGrammarCheck = false ); SwTextPaintInfo &operator=(const SwTextPaintInfo&) = delete; + void NotifyURL_(const SwLinePortion& rPor) const; protected: SwTextPaintInfo() @@ -416,6 +417,12 @@ public: void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const; + void NotifyURL(const SwLinePortion& rPor) const + { + if (URLNotify()) + NotifyURL_(rPor); + } + /** * Calculate the rectangular area where the portion takes place. * @param[in] rPor portion for which the method specify the painting area diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index dbf5765ef1b6..5d88b6e960b6 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -1286,7 +1286,7 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const } if( !pPor ) { - if( !rInf.X() && !m_pCurr->GetNextPortion() && !m_pCurr->GetLen() ) + if( !rInf.X() && !m_pCurr->GetNextPortion() && !m_pCurr->GetLen() && !GetFnt()->IsURL() ) pPor = m_pCurr; else pPor = new SwTextPortion; diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx index a66d358645f0..1f1959b06c66 100644 --- a/sw/source/core/text/itrpaint.cxx +++ b/sw/source/core/text/itrpaint.cxx @@ -32,6 +32,7 @@ #include <txtfrm.hxx> #include <swfont.hxx> #include "txtpaint.hxx" +#include "porfly.hxx" #include "portab.hxx" #include <txatbase.hxx> #include <charfmt.hxx> @@ -39,6 +40,7 @@ #include "porrst.hxx" #include "pormulti.hxx" #include <doc.hxx> +#include <fmturl.hxx> // Returns, if we have an underline breaking situation // Adding some more conditions here means you also have to change them @@ -404,6 +406,24 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip, // reset (for special vertical alignment) GetInfo().Y( nOldY ); + if (GetFnt()->IsURL() && pPor->InTextGrp()) + GetInfo().NotifyURL(*pPor); + else if (pPor->IsFlyCntPortion()) + { + if (auto* pFlyContentPortion = dynamic_cast<sw::FlyContentPortion*>(pPor)) + { + if (auto* pFlyFrame = pFlyContentPortion->GetFlyFrame()) + { + if (auto* pFormat = pFlyFrame->GetFormat()) + { + auto& url = pFormat->GetURL(); + if (!url.GetURL().isEmpty()) // TODO: url.GetMap() ? + GetInfo().NotifyURL(*pPor); + } + } + } + } + bFirst &= !pPor->GetLen(); if( pNext || !pPor->IsMarginPortion() ) pPor->Move( GetInfo() ); diff --git a/sw/source/core/text/noteurl.cxx b/sw/source/core/text/noteurl.cxx index fa91ea252d5f..d66736280bb5 100644 --- a/sw/source/core/text/noteurl.cxx +++ b/sw/source/core/text/noteurl.cxx @@ -19,7 +19,42 @@ #include <noteurl.hxx> +#include <vcl/imap.hxx> +#include <vcl/imaprect.hxx> +#include <vcl/mapmod.hxx> +#include <vcl/outdev.hxx> + // Global variable -SwNoteURL* pNoteURL = nullptr; +thread_local SwNoteURL* pNoteURL = nullptr; + +void SwNoteURL::InsertURLNote(const OUString& rURL, const OUString& rTarget, const SwRect& rRect) +{ + const size_t nCount = m_List.size(); + for (size_t i = 0; i < nCount; ++i) + if (rRect == m_List[i].GetRect()) + return; + + m_List.emplace_back(rURL, rTarget, rRect); +} + +void SwNoteURL::FillImageMap(ImageMap* pMap, const Point& rPos, const MapMode& rMap) +{ + assert(pMap && "FillImageMap: No ImageMap, no cookies!"); + const size_t nCount = m_List.size(); + if (nCount) + { + MapMode aMap(MapUnit::Map100thMM); + for (size_t i = 0; i < nCount; ++i) + { + const SwURLNote& rNote = m_List[i]; + SwRect aSwRect(rNote.GetRect()); + aSwRect -= rPos; + tools::Rectangle aRect(OutputDevice::LogicToLogic(aSwRect.SVRect(), rMap, aMap)); + IMapRectangleObject aObj(aRect, rNote.GetURL(), OUString(), OUString(), + rNote.GetTarget(), OUString(), true, false); + pMap->InsertIMapObject(aObj); + } + } +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/porfly.hxx b/sw/source/core/text/porfly.hxx index a519c1109c87..2c56563a4436 100644 --- a/sw/source/core/text/porfly.hxx +++ b/sw/source/core/text/porfly.hxx @@ -76,6 +76,7 @@ namespace sw FlyContentPortion(SwFlyInContentFrame* pFly); static FlyContentPortion* Create(const SwTextFrame& rFrame, SwFlyInContentFrame* pFly, const Point& rBase, tools::Long nAscent, tools::Long nDescent, tools::Long nFlyAsc, tools::Long nFlyDesc, AsCharFlags nFlags); SwFlyInContentFrame* GetFlyFrame() { return m_pFly; } + const SwFlyInContentFrame* GetFlyFrame() const { return m_pFly; } void GetFlyCursorOfst(Point& rPoint, SwPosition& rPos, SwCursorMoveState* pCMS) const { m_pFly->GetModelPositionForViewPoint(&rPos, rPoint, pCMS); }; virtual void Paint(const SwTextPaintInfo& rInf) const override; virtual ~FlyContentPortion() override; diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx index 0f00db0d8c26..c725a81c2320 100644 --- a/sw/source/core/text/pormulti.cxx +++ b/sw/source/core/text/pormulti.cxx @@ -1765,6 +1765,9 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint, else pPor->Paint( GetInfo() ); + if (GetFnt()->IsURL() && pPor->InTextGrp()) + GetInfo().NotifyURL(*pPor); + bFirst &= !pPor->GetLen(); if( pNext || !pPor->IsMarginPortion() ) pPor->Move( GetInfo() ); diff --git a/sw/source/core/txtnode/swfont.cxx b/sw/source/core/txtnode/swfont.cxx index c0149d9a6573..c18070ef493e 100644 --- a/sw/source/core/txtnode/swfont.cxx +++ b/sw/source/core/txtnode/swfont.cxx @@ -668,6 +668,7 @@ SwFont::SwFont( const SwFont &rFont ) m_bOrgChg = rFont.m_bOrgChg; m_bPaintBlank = rFont.m_bPaintBlank; m_bGreyWave = rFont.m_bGreyWave; + m_bURL = rFont.m_bURL; } SwFont::SwFont( const SwAttrSet* pAttrSet, @@ -857,6 +858,7 @@ SwFont& SwFont::operator=( const SwFont &rFont ) m_bOrgChg = rFont.m_bOrgChg; m_bPaintBlank = rFont.m_bPaintBlank; m_bGreyWave = rFont.m_bGreyWave; + m_bURL = rFont.m_bURL; } return *this; } diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx index 624d992fb273..32b97fe16bdc 100644 --- a/sw/source/filter/html/htmlflywriter.cxx +++ b/sw/source/filter/html/htmlflywriter.cxx @@ -1117,17 +1117,17 @@ OUString lclWriteOutImap(SwHTMLWriter& rHTMLWrt, const SfxItemSet& rItemSet, con OUString aIMapName; // Only consider the URL attribute if no ImageMap was supplied - if (!pAltImgMap) - pURLItem = rItemSet.GetItemIfSet( RES_URL ); // write ImageMap const ImageMap* pIMap = pAltImgMap; - if( !pIMap && pURLItem ) + if( !pIMap ) { - pIMap = pURLItem->GetMap(); + pURLItem = rItemSet.GetItemIfSet(RES_URL); + if (pURLItem) + pIMap = pURLItem->GetMap(); } - if (pIMap) + if (pIMap && !rHTMLWrt.mbReqIF) { // make the name unique aIMapName = pIMap->GetName(); @@ -1135,10 +1135,10 @@ OUString lclWriteOutImap(SwHTMLWriter& rHTMLWrt, const SfxItemSet& rItemSet, con if (!aIMapName.isEmpty()) aNameBase = aIMapName; else + { aNameBase = OOO_STRING_SVTOOLS_HTML_map; - - if (aIMapName.isEmpty()) aIMapName = aNameBase + OUString::number(rHTMLWrt.m_nImgMapCnt); + } bool bFound; do @@ -1309,7 +1309,7 @@ Writer& OutHTML_ImageStart( HtmlWriter& rHtml, Writer& rWrt, const SwFrameFormat // URL -> <a>...<img ... >...</a> const SvxMacroItem *pMacItem = rItemSet.GetItemIfSet(RES_FRMMACRO); - if (pURLItem || pMacItem) + if (pURLItem || pMacItem || (rHTMLWrt.mbReqIF && pAltImgMap)) { OUString aMapURL; OUString aName; @@ -1321,6 +1321,21 @@ Writer& OutHTML_ImageStart( HtmlWriter& rHtml, Writer& rWrt, const SwFrameFormat aName = pURLItem->GetName(); aTarget = pURLItem->GetTargetFrameName(); } + else if (rHTMLWrt.mbReqIF && pAltImgMap) + { + // Get first non-empty map element + for (size_t i = 0; i < pAltImgMap->GetIMapObjectCount(); ++i) + { + if (auto* pIMapObject = pAltImgMap->GetIMapObject(i)) + { + aMapURL = pIMapObject->GetURL(); + aName = pIMapObject->GetName(); + aTarget = pIMapObject->GetTarget(); + if (!aMapURL.isEmpty() || !aName.isEmpty() || !aTarget.isEmpty()) + break; + } + } + } bool bEvents = pMacItem && !pMacItem->GetMacroTable().empty(); diff --git a/sw/source/ui/table/autoformatpreview.cxx b/sw/source/ui/table/autoformatpreview.cxx index e04fffefcae4..08ec0e27d3d5 100644 --- a/sw/source/ui/table/autoformatpreview.cxx +++ b/sw/source/ui/table/autoformatpreview.cxx @@ -237,9 +237,10 @@ void AutoFormatPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nC Size aStrSize; sal_uInt8 nFormatIndex = GetFormatIndex(nCol, nRow); const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow)); - const tools::Rectangle cellRect( - basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()), - basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY())); + const tools::Rectangle cellRect(basegfx::fround<tools::Long>(aCellRange.getMinX()), + basegfx::fround<tools::Long>(aCellRange.getMinY()), + basegfx::fround<tools::Long>(aCellRange.getMaxX()), + basegfx::fround<tools::Long>(aCellRange.getMaxY())); Point aPos = cellRect.TopLeft(); tools::Long nRightX = 0; @@ -327,9 +328,11 @@ void AutoFormatPreview::DrawBackground(vcl::RenderContext& rRenderContext) rRenderContext.SetLineColor(); rRenderContext.SetFillColor(aBrushItem.GetColor()); const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow)); - rRenderContext.DrawRect(tools::Rectangle( - basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()), - basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()))); + rRenderContext.DrawRect( + tools::Rectangle(basegfx::fround<tools::Long>(aCellRange.getMinX()), + basegfx::fround<tools::Long>(aCellRange.getMinY()), + basegfx::fround<tools::Long>(aCellRange.getMaxX()), + basegfx::fround<tools::Long>(aCellRange.getMaxY()))); rRenderContext.Pop(); } } diff --git a/toolkit/source/awt/vclxfont.cxx b/toolkit/source/awt/vclxfont.cxx index 866a362e710f..f7338e79cfd0 100644 --- a/toolkit/source/awt/vclxfont.cxx +++ b/toolkit/source/awt/vclxfont.cxx @@ -156,7 +156,7 @@ sal_Int32 VCLXFont::getStringWidthArray( const OUString& str, css::uno::Sequence vcl::Font aOldFont = pOutDev->GetFont(); pOutDev->SetFont( maFont ); KernArray aDXA; - nRet = pOutDev->GetTextArray( str, &aDXA ); + nRet = basegfx::fround(pOutDev->GetTextArray(str, &aDXA)); rDXArray.realloc(aDXA.size()); sal_Int32* pArray = rDXArray.getArray(); for (size_t i = 0, nLen = aDXA.size(); i < nLen; ++i) diff --git a/tools/CppunitTest_tools_test.mk b/tools/CppunitTest_tools_test.mk index d27f8c3efa58..3d3c99e226a2 100644 --- a/tools/CppunitTest_tools_test.mk +++ b/tools/CppunitTest_tools_test.mk @@ -30,7 +30,6 @@ $(eval $(call gb_CppunitTest_add_exception_objects,tools_test, \ tools/qa/cppunit/test_rectangle \ tools/qa/cppunit/test_minmax \ tools/qa/cppunit/test_100mm2twips \ - tools/qa/cppunit/test_fround \ tools/qa/cppunit/test_xmlwalker \ tools/qa/cppunit/test_xmlwriter \ tools/qa/cppunit/test_GenericTypeSerializer \ diff --git a/tools/qa/cppunit/test_fround.cxx b/tools/qa/cppunit/test_fround.cxx deleted file mode 100644 index 4014ff3cb46b..000000000000 --- a/tools/qa/cppunit/test_fround.cxx +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/types.h> -#include <cppunit/TestFixture.h> -#include <cppunit/extensions/HelperMacros.h> - -#include <tools/helpers.hxx> - -namespace tools -{ -class FRoundTest : public CppUnit::TestFixture -{ -public: - void testPositiveFRound() - { - sal_Int64 nExpected = 2; - sal_Int64 nActual = FRound(1.6); - CPPUNIT_ASSERT_EQUAL(nExpected, nActual); - - nExpected = 1; - nActual = FRound(1.4); - CPPUNIT_ASSERT_EQUAL(nExpected, nActual); - } - - void testNegativeFRound() - { - sal_Int64 nExpected = -2; - sal_Int64 nActual = FRound(-1.6); - CPPUNIT_ASSERT_EQUAL(nExpected, nActual); - - nExpected = -1; - nActual = FRound(-1.4); - CPPUNIT_ASSERT_EQUAL(nExpected, nActual); - } - - CPPUNIT_TEST_SUITE(FRoundTest); - CPPUNIT_TEST(testPositiveFRound); - CPPUNIT_TEST(testNegativeFRound); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(FRoundTest); -} // namespace tools - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx index 1c740f03df03..b710638a3437 100644 --- a/tools/source/generic/color.cxx +++ b/tools/source/generic/color.cxx @@ -29,6 +29,7 @@ #include <tools/long.hxx> #include <o3tl/string_view.hxx> #include <basegfx/color/bcolortools.hxx> +#include <basegfx/numeric/ftools.hxx> void Color::IncreaseLuminance(sal_uInt8 cLumInc) { @@ -51,9 +52,9 @@ void Color::DecreaseContrast(sal_uInt8 nContDec) const double fM = (128.0 - 0.4985 * nContDec) / 128.0; const double fOff = 128.0 - fM * 128.0; - R = sal_uInt8(std::clamp(FRound(R * fM + fOff), tools::Long(0), tools::Long(255))); - G = sal_uInt8(std::clamp(FRound(G * fM + fOff), tools::Long(0), tools::Long(255))); - B = sal_uInt8(std::clamp(FRound(B * fM + fOff), tools::Long(0), tools::Long(255))); + R = basegfx::fround<sal_uInt8>(R * fM + fOff); + G = basegfx::fround<sal_uInt8>(G * fM + fOff); + B = basegfx::fround<sal_uInt8>(B * fM + fOff); } } diff --git a/tools/source/generic/line.cxx b/tools/source/generic/line.cxx index ee9ad979793c..328ae3e35e66 100644 --- a/tools/source/generic/line.cxx +++ b/tools/source/generic/line.cxx @@ -17,6 +17,9 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <basegfx/numeric/ftools.hxx> #include <tools/line.hxx> #include <tools/helpers.hxx> @@ -37,8 +40,8 @@ bool Line::Intersection( const Line& rLine, Point& rIntersection ) const if( Intersection( rLine, fX, fY ) ) { - rIntersection.setX( FRound( fX ) ); - rIntersection.setY( FRound( fY ) ); + rIntersection.setX(basegfx::fround<tools::Long>(fX)); + rIntersection.setY(basegfx::fround<tools::Long>(fY)); bRet = true; } else diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx index 2665b0381571..0ea2b99d840b 100644 --- a/tools/source/generic/poly.cxx +++ b/tools/source/generic/poly.cxx @@ -203,8 +203,8 @@ ImplPolygon::ImplPolygon( const Point& rCenter, tools::Long nRadX, tools::Long n for( i=0, nAngle = 0.0; i < nPoints4; i++, nAngle += nAngleStep ) { - tools::Long nX = FRound( nRadX * cos( nAngle ) ); - tools::Long nY = FRound( -nRadY * sin( nAngle ) ); + tools::Long nX = basegfx::fround<tools::Long>(nRadX * cos(nAngle)); + tools::Long nY = basegfx::fround<tools::Long>(nRadY * -sin(nAngle)); Point* pPt = &(mxPointAry[i]); pPt->setX( nX + rCenter.X() ); @@ -291,7 +291,8 @@ ImplPolygon::ImplPolygon(const tools::Rectangle& rBound, const Point& rStart, co if (PolyStyle::Pie == eStyle) { - const Point aCenter2(FRound(fCenterX), FRound(fCenterY)); + const Point aCenter2(basegfx::fround<tools::Long>(fCenterX), + basegfx::fround<tools::Long>(fCenterY)); nStart = 1; nEnd = nPoints + 1; @@ -310,8 +311,8 @@ ImplPolygon::ImplPolygon(const tools::Rectangle& rBound, const Point& rStart, co { Point& rPt = mxPointAry[nStart]; - rPt.setX( FRound( fCenterX + fRadX * cos( fStart ) ) ); - rPt.setY( FRound( fCenterY - fRadY * sin( fStart ) ) ); + rPt.setX(basegfx::fround<tools::Long>(fCenterX + fRadX * cos(fStart))); + rPt.setY(basegfx::fround<tools::Long>(fCenterY - fRadY * sin(fStart))); } if( PolyStyle::Chord == eStyle ) @@ -355,8 +356,8 @@ ImplPolygon::ImplPolygon( const Point& rBezPt1, const Point& rCtrlPt1, double fK12 = fK_1 * fK1_2; double fK21 = fK_2 * fK1_1; - rPt.setX( FRound( fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3 ) ); - rPt.setY( FRound( fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3 ) ); + rPt.setX(basegfx::fround<tools::Long>(fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3)); + rPt.setY(basegfx::fround<tools::Long>(fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3)); } } @@ -399,7 +400,9 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon) for(sal_uInt32 a(0); a < nLoopCount; a++) { // add current point (always) and remember StartPointIndex for evtl. later corrections - const Point aStartPoint(FRound(aBezier.getStartPoint().getX()), FRound(aBezier.getStartPoint().getY())); + const Point aStartPoint( + basegfx::fround<tools::Long>(aBezier.getStartPoint().getX()), + basegfx::fround<tools::Long>(aBezier.getStartPoint().getY())); const sal_uInt32 nStartPointIndex(nArrayInsert); mxPointAry[nStartPointIndex] = aStartPoint; mxFlagAry[nStartPointIndex] = PolyFlags::Normal; @@ -414,11 +417,13 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon) if(aBezier.isBezier()) { // if one is used, add always two control points due to the old schema - mxPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointA().getX()), FRound(aBezier.getControlPointA().getY())); + mxPointAry[nArrayInsert] = Point(basegfx::fround<tools::Long>(aBezier.getControlPointA().getX()), + basegfx::fround<tools::Long>(aBezier.getControlPointA().getY())); mxFlagAry[nArrayInsert] = PolyFlags::Control; nArrayInsert++; - mxPointAry[nArrayInsert] = Point(FRound(aBezier.getControlPointB().getX()), FRound(aBezier.getControlPointB().getY())); + mxPointAry[nArrayInsert] = Point(basegfx::fround<tools::Long>(aBezier.getControlPointB().getX()), + basegfx::fround<tools::Long>(aBezier.getControlPointB().getY())); mxFlagAry[nArrayInsert] = PolyFlags::Control; nArrayInsert++; } @@ -453,7 +458,8 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon) { // add last point as closing point const basegfx::B2DPoint aClosingPoint(rPolygon.getB2DPoint(nB2DLocalCount - 1)); - const Point aEnd(FRound(aClosingPoint.getX()), FRound(aClosingPoint.getY())); + const Point aEnd(basegfx::fround<tools::Long>(aClosingPoint.getX()), + basegfx::fround<tools::Long>(aClosingPoint.getY())); mxPointAry[nArrayInsert] = aEnd; mxFlagAry[nArrayInsert] = PolyFlags::Normal; nArrayInsert++; @@ -486,7 +492,8 @@ ImplPolygon::ImplPolygon(const basegfx::B2DPolygon& rPolygon) for(sal_uInt32 a(0); a < nB2DLocalCount; a++) { basegfx::B2DPoint aB2DPoint(rPolygon.getB2DPoint(a)); - Point aPoint(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY())); + Point aPoint(basegfx::fround<tools::Long>(aB2DPoint.getX()), + basegfx::fround<tools::Long>(aB2DPoint.getY())); mxPointAry[nIndex++] = aPoint; } @@ -1180,7 +1187,7 @@ static void ImplAdaptiveSubdivide( std::vector<Point>& rPoints, // requested resolution reached. // Add end points to output iterator. // order is preserved, since this is so to say depth first traversal. - rPoints.push_back(Point(FRound(P1x), FRound(P1y))); + rPoints.push_back(Point(basegfx::fround<tools::Long>(P1x), basegfx::fround<tools::Long>(P1y))); } } @@ -1432,8 +1439,8 @@ void Polygon::Rotate( const Point& rCenter, double fSin, double fCos ) const tools::Long nX = rPt.X() - nCenterX; const tools::Long nY = rPt.Y() - nCenterY; - rPt.setX( FRound(fCos * nX + fSin * nY + nCenterX) ); - rPt.setY( FRound(-(fSin * nX - fCos * nY - nCenterY)) ); + rPt.setX(basegfx::fround<tools::Long>(fCos * nX + fSin * nY + nCenterX)); + rPt.setY(basegfx::fround<tools::Long>(-(fSin * nX - fCos * nY - nCenterY))); } } diff --git a/vcl/inc/font/LogicalFontInstance.hxx b/vcl/inc/font/LogicalFontInstance.hxx index c9e837d540f1..e8124eac7eca 100644 --- a/vcl/inc/font/LogicalFontInstance.hxx +++ b/vcl/inc/font/LogicalFontInstance.hxx @@ -22,6 +22,7 @@ #include <sal/config.h> #include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/b2drectangle.hxx> #include <o3tl/hash_combine.hxx> #include <rtl/ref.hxx> #include <salhelper/simplereferenceobject.hxx> @@ -101,7 +102,7 @@ public: // TODO: make data members private vcl::font::PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); } const ImplFontCache* GetFontCache() const { return mpFontCache; } - bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; + bool GetGlyphBoundRect(sal_GlyphId, basegfx::B2DRectangle&, bool) const; virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0; bool GetGlyphOutlineUntransformed(sal_GlyphId, basegfx::B2DPolyPolygon&) const; @@ -120,8 +121,6 @@ protected: explicit LogicalFontInstance(const vcl::font::PhysicalFontFace&, const vcl::font::FontSelectPattern&); - virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const = 0; - hb_font_t* InitHbFont(); virtual void ImplInitHbFont(hb_font_t*) {} diff --git a/vcl/inc/impfontcache.hxx b/vcl/inc/impfontcache.hxx index 5ea19b05d9a5..4d197003b279 100644 --- a/vcl/inc/impfontcache.hxx +++ b/vcl/inc/impfontcache.hxx @@ -21,10 +21,10 @@ #include <sal/config.h> +#include <basegfx/range/b2drectangle.hxx> #include <rtl/ref.hxx> #include <o3tl/lru_map.hxx> #include <o3tl/hash_combine.hxx> -#include <tools/gen.hxx> #include "font/FontSelectPattern.hxx" #include "glyphid.hxx" @@ -59,7 +59,7 @@ struct GlyphBoundRectCacheHash } }; -typedef o3tl::lru_map<GlyphBoundRectCacheKey, tools::Rectangle, +typedef o3tl::lru_map<GlyphBoundRectCacheKey, basegfx::B2DRectangle, GlyphBoundRectCacheHash> GlyphBoundRectCache; class ImplFontCache @@ -86,8 +86,8 @@ public: LogicalFontInstance* pLogicalFont, int nFallbackLevel, OUString& rMissingCodes ); - bool GetCachedGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &); - void CacheGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &); + bool GetCachedGlyphBoundRect(const LogicalFontInstance*, sal_GlyphId, basegfx::B2DRectangle&); + void CacheGlyphBoundRect(const LogicalFontInstance*, sal_GlyphId, basegfx::B2DRectangle&); void Invalidate(); }; diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx index 87f966bd1676..a3f1b8a7a7a6 100644 --- a/vcl/inc/impglyphitem.hxx +++ b/vcl/inc/impglyphitem.hxx @@ -20,8 +20,8 @@ #ifndef INCLUDED_VCL_IMPGLYPHITEM_HXX #define INCLUDED_VCL_IMPGLYPHITEM_HXX +#include <basegfx/range/b2drectangle.hxx> #include <o3tl/typed_flags_set.hxx> -#include <tools/gen.hxx> #include <vcl/dllapi.h> #include <vcl/outdev.hxx> #include <vector> @@ -87,7 +87,7 @@ public: return bool(m_nFlags & GlyphItemFlags::IS_SAFE_TO_INSERT_KASHIDA); } - inline bool GetGlyphBoundRect(const LogicalFontInstance*, tools::Rectangle&) const; + inline bool GetGlyphBoundRect(const LogicalFontInstance*, basegfx::B2DRectangle&) const; inline bool GetGlyphOutline(const LogicalFontInstance*, basegfx::B2DPolyPolygon&) const; inline void dropGlyph(); @@ -117,7 +117,7 @@ public: }; bool GlyphItem::GetGlyphBoundRect(const LogicalFontInstance* pFontInstance, - tools::Rectangle& rRect) const + basegfx::B2DRectangle& rRect) const { return pFontInstance->GetGlyphBoundRect(m_aGlyphId, rRect, IsVertical()); } diff --git a/vcl/inc/pdf/pdfbuildin_fonts.hxx b/vcl/inc/pdf/pdfbuildin_fonts.hxx index 8cb34e74922b..a0c2fc06287d 100644 --- a/vcl/inc/pdf/pdfbuildin_fonts.hxx +++ b/vcl/inc/pdf/pdfbuildin_fonts.hxx @@ -49,8 +49,6 @@ struct BuildinFont class BuildinFontInstance final : public LogicalFontInstance { - bool ImplGetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect, bool) const override; - public: BuildinFontInstance(const vcl::font::PhysicalFontFace&, const vcl::font::FontSelectPattern&); diff --git a/vcl/inc/qt5/QtFont.hxx b/vcl/inc/qt5/QtFont.hxx index e19d6de21aa2..7d0b338c939d 100644 --- a/vcl/inc/qt5/QtFont.hxx +++ b/vcl/inc/qt5/QtFont.hxx @@ -33,7 +33,6 @@ class QtFont final : public QFont, public LogicalFontInstance QtFontFace::CreateFontInstance(const vcl::font::FontSelectPattern&) const; bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const override; - bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override; explicit QtFont(const vcl::font::PhysicalFontFace&, const vcl::font::FontSelectPattern&); }; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 6d1668c1f913..a255e9dc330d 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -103,8 +103,6 @@ public: private: explicit CoreTextFont(const CoreTextFontFace&, const vcl::font::FontSelectPattern&); - bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override; - CTFontRef mpCTFont; }; diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx index c80642b6126c..9c61e0ff60d1 100644 --- a/vcl/inc/unx/freetype_glyphcache.hxx +++ b/vcl/inc/unx/freetype_glyphcache.hxx @@ -107,8 +107,6 @@ class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : public LogicalFontInstance std::unique_ptr<FreetypeFont> mxFreetypeFont; - virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override; - explicit FreetypeFontInstance(const vcl::font::PhysicalFontFace& rPFF, const vcl::font::FontSelectPattern& rFSP); public: diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index 9de7bd59fe6c..4d21d34d05ea 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -123,7 +123,6 @@ public: void GetFontMetric(ImplFontMetricDataRef const &) const; - bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const; bool GetAntialiasAdvice() const; diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx index 67094052ebb5..a655df6459ea 100644 --- a/vcl/inc/win/DWriteTextRenderer.hxx +++ b/vcl/inc/win/DWriteTextRenderer.hxx @@ -72,21 +72,6 @@ private: D2DTextAntiAliasMode meTextAntiAliasMode; }; -/** - * Sets and unsets the needed DirectWrite transform to support the font's horizontal scaling and - * rotation. - */ -class WinFontTransformGuard -{ -public: - WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, float fHScale, const GenericSalLayout& rLayout, const D2D1_POINT_2F& rBaseline, bool bIsVertical); - ~WinFontTransformGuard(); - -private: - ID2D1RenderTarget* mpRenderTarget; - D2D1::Matrix3x2F maTransform; -}; - #endif // INCLUDED_VCL_INC_WIN_DWRITERENDERER_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index fb8e5a1c6e43..ac70e42b66cf 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -36,9 +36,6 @@ class WinFontInstance : public LogicalFontInstance public: ~WinFontInstance() override; - bool hasHScale() const; - float getHScale() const; - void SetGraphics(WinSalGraphics*); WinSalGraphics* GetGraphics() const { return m_pGraphics; } @@ -60,7 +57,6 @@ private: explicit WinFontInstance(const WinFontFace&, const vcl::font::FontSelectPattern&); virtual void ImplInitHbFont(hb_font_t*) override; - bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override; WinSalGraphics *m_pGraphics; HFONT m_hFont; diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm index 3892ef659cf2..3e0c57cfb83a 100644 --- a/vcl/osx/salframeview.mm +++ b/vcl/osx/salframeview.mm @@ -19,6 +19,7 @@ #include <sal/config.h> +#include <basegfx/numeric/ftools.hxx> #include <sal/macros.h> #include <tools/helpers.hxx> #include <tools/long.hxx> @@ -925,7 +926,7 @@ static AquaSalFrame* getMouseContainerFrame() // adapt NSEvent-sensitivity to application expectations // TODO: rather make CommandWheelMode::ZOOM handlers smarter const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor; - int nDeltaZ = FRound( fDeltaZ ); + int nDeltaZ = basegfx::fround<int>( fDeltaZ ); if( !nDeltaZ ) { // handle new series immediately diff --git a/vcl/qa/cppunit/cjktext.cxx b/vcl/qa/cppunit/cjktext.cxx index af63b29959fd..cd9bd2c165fd 100644 --- a/vcl/qa/cppunit/cjktext.cxx +++ b/vcl/qa/cppunit/cjktext.cxx @@ -178,7 +178,7 @@ void VclCjkTextTest::testVerticalText() tools::Long height36Rotated = getCharacterRightSideHeight(device, Point(99, 35)); CPPUNIT_ASSERT_DOUBLES_EQUAL(height36, height36Rotated, 1); tools::Long width36Rotated = getCharacterTopWidth(device, Point(25, 0)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(width36, width36Rotated, 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(width36, width36Rotated, 2); font = baseFont; font.SetFontSize(Size(0, 72)); diff --git a/vcl/qa/cppunit/complextext.cxx b/vcl/qa/cppunit/complextext.cxx index daf70a1c589d..cfe5d2213d7d 100644 --- a/vcl/qa/cppunit/complextext.cxx +++ b/vcl/qa/cppunit/complextext.cxx @@ -79,7 +79,7 @@ void VclComplexTextTest::testArabic() std::vector<sal_Int32> aRefCharWidths {6, 9, 16, 16, 22, 22, 26, 29, 32, 32, 36, 40, 49, 53, 56, 63, 63, 66, 72, 72}; KernArray aCharWidths; - tools::Long nTextWidth = pOutDev->GetTextArray(aOneTwoThree, &aCharWidths); + tools::Long nTextWidth = basegfx::fround<tools::Long>(pOutDev->GetTextArray(aOneTwoThree, &aCharWidths)); CPPUNIT_ASSERT_EQUAL(aRefCharWidths, aCharWidths.get_subunit_array()); // this sporadically returns 75 or 74 on some of the windows tinderboxes eg. tb73 diff --git a/vcl/qa/cppunit/fontmocks.hxx b/vcl/qa/cppunit/fontmocks.hxx index 7e33ce8e7e13..8eac463c143f 100644 --- a/vcl/qa/cppunit/fontmocks.hxx +++ b/vcl/qa/cppunit/fontmocks.hxx @@ -30,9 +30,6 @@ public: { return true; } - -protected: - bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const override { return true; } }; class TestFontFace : public vcl::font::PhysicalFontFace diff --git a/vcl/qa/cppunit/logicalfontinstance.cxx b/vcl/qa/cppunit/logicalfontinstance.cxx index 2a7a5c83ac27..77de9b9b4e3f 100644 --- a/vcl/qa/cppunit/logicalfontinstance.cxx +++ b/vcl/qa/cppunit/logicalfontinstance.cxx @@ -39,24 +39,71 @@ void VclLogicalFontInstanceTest::testglyphboundrect() { ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); device->SetOutputSizePixel(Size(1000, 1000)); - device->SetFont(vcl::Font("Liberation Sans", Size(0, 110))); + vcl::Font font("Liberation Sans", Size(0, 110)); + device->SetFont(font); const LogicalFontInstance* pFontInstance = device->GetFontInstance(); - tools::Rectangle aBoundRect; + basegfx::B2DRectangle aBoundRect; const auto LATIN_SMALL_LETTER_B = 0x0062; + const auto SECTION_SIGN = 0x00A7; // UTR#50: Vertical_Orientation (vo) property value U pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect, false); - const tools::Long nExpectedX = 7; - const tools::Long nExpectedY = -80; + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.1, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getHeight(), 0.05); - CPPUNIT_ASSERT_EQUAL_MESSAGE("x of glyph is wrong", nExpectedX, aBoundRect.getX()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("y of glyph is wrong", nExpectedY, aBoundRect.getY()); - CPPUNIT_ASSERT_MESSAGE("height of glyph of wrong", - aBoundRect.GetWidth() == 50 || aBoundRect.GetWidth() == 51); - CPPUNIT_ASSERT_MESSAGE("width of glyph of wrong", - aBoundRect.GetHeight() == 82 || aBoundRect.GetHeight() == 83); + // tdf#160436: test vertically oriented glyphs + pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getHeight(), 0.05); + + font.SetOrientation(900_deg10); + device->SetFont(font); + + pFontInstance = device->GetFontInstance(); + + pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect, + false); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-79.7, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.6, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80.8, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(49.5, aBoundRect.getHeight(), 0.05); + + // tdf#160436: test vertically oriented glyphs + pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-55.0, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.2, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(48.8, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(88.9, aBoundRect.getHeight(), 0.05); + + font.SetOrientation(450_deg10); + device->SetFont(font); + + pFontInstance = device->GetFontInstance(); + + pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(LATIN_SMALL_LETTER_B), aBoundRect, + false); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-51.3, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.4, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(92.1, aBoundRect.getHeight(), 0.05); + + // tdf#160436: test vertically oriented glyphs + pFontInstance->GetGlyphBoundRect(pFontInstance->GetGlyphIndex(SECTION_SIGN), aBoundRect, true); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-95.3, aBoundRect.getMinX(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-45.4, aBoundRect.getMinY(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getWidth(), 0.05); + CPPUNIT_ASSERT_DOUBLES_EQUAL(97.4, aBoundRect.getHeight(), 0.05); } CPPUNIT_TEST_SUITE_REGISTRATION(VclLogicalFontInstanceTest); diff --git a/vcl/qt5/QtFont.cxx b/vcl/qt5/QtFont.cxx index 384f56774ffd..e3a6c0b0a9d7 100644 --- a/vcl/qt5/QtFont.cxx +++ b/vcl/qt5/QtFont.cxx @@ -187,11 +187,4 @@ bool QtFont::GetGlyphOutline(sal_GlyphId nId, basegfx::B2DPolyPolygon& rB2DPolyP return true; } -bool QtFont::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, bool) const -{ - QRawFont aRawFont(QRawFont::fromFont(*this)); - rRect = toRectangle(aRawFont.boundingRect(nId).toAlignedRect()); - return true; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index 38112a7deb50..1cafd270552d 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -89,27 +89,6 @@ void CoreTextFont::GetFontMetric( ImplFontMetricDataRef const & rxFontMetric ) rxFontMetric->SetMinKashida(GetKashidaWidth()); } -bool CoreTextFont::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, bool bVertical) const -{ - CGGlyph nCGGlyph = nId; - - SAL_WNODEPRECATED_DECLARATIONS_PUSH //TODO: 10.11 kCTFontDefaultOrientation - const CTFontOrientation aFontOrientation = kCTFontDefaultOrientation; // TODO: horz/vert - SAL_WNODEPRECATED_DECLARATIONS_POP - CGRect aCGRect = CTFontGetBoundingRectsForGlyphs(mpCTFont, aFontOrientation, &nCGGlyph, nullptr, 1); - - // Apply font rotation to non-vertical glyphs. - if (mfFontRotation && !bVertical) - aCGRect = CGRectApplyAffineTransform(aCGRect, CGAffineTransformMakeRotation(mfFontRotation)); - - tools::Long xMin = floor(aCGRect.origin.x); - tools::Long yMin = floor(aCGRect.origin.y); - tools::Long xMax = ceil(aCGRect.origin.x + aCGRect.size.width); - tools::Long yMax = ceil(aCGRect.origin.y + aCGRect.size.height); - rRect = tools::Rectangle(xMin, -yMax, xMax, -yMin); - return true; -} - namespace { // callbacks from CTFontCreatePathForGlyph+CGPathApply for GetGlyphOutline() diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 7a240600be98..c40a010173a7 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -2099,8 +2099,8 @@ bool SkiaSalGraphicsImpl::implDrawGradient(const basegfx::B2DPolyPolygon& rPolyP } static double toRadian(Degree10 degree10th) { return toRadians(3600_deg10 - degree10th); } -static double toCos(Degree10 degree10th) { return SkScalarCos(toRadian(degree10th)); } -static double toSin(Degree10 degree10th) { return SkScalarSin(toRadian(degree10th)); } +static auto toCos(Degree10 degree10th) { return SkScalarCos(toRadian(degree10th)); } +static auto toSin(Degree10 degree10th) { return SkScalarSin(toRadian(degree10th)); } void SkiaSalGraphicsImpl::drawGenericLayout(const GenericSalLayout& layout, Color textColor, const SkFont& font, const SkFont& verticalFont) @@ -2115,22 +2115,23 @@ void SkiaSalGraphicsImpl::drawGenericLayout(const GenericSalLayout& layout, Colo DevicePoint aPos; const GlyphItem* pGlyph; int nStart = 0; + auto cos = toCos(layout.GetOrientation()); + auto sin = toSin(layout.GetOrientation()); while (layout.GetNextGlyph(&pGlyph, aPos, nStart)) { glyphIds.push_back(pGlyph->glyphId()); - Degree10 angle = layout.GetOrientation(); - if (pGlyph->IsVertical()) - angle += 900_deg10; - SkRSXform form = SkRSXform::Make(toCos(angle), toSin(angle), aPos.getX(), aPos.getY()); - glyphForms.emplace_back(std::move(form)); verticals.emplace_back(pGlyph->IsVertical()); + auto cos1 = pGlyph->IsVertical() ? sin : cos; // cos (x - 90) = sin (x) + auto sin1 = pGlyph->IsVertical() ? -cos : sin; // sin (x - 90) = -cos (x) + SkRSXform form = SkRSXform::Make(cos1, sin1, aPos.getX(), aPos.getY()); + glyphForms.emplace_back(std::move(form)); } if (glyphIds.empty()) return; preDraw(); auto getBoundRect = [&layout]() { - tools::Rectangle rect; + basegfx::B2DRectangle rect; layout.GetBoundRect(rect); return rect; }; diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx index 57cea14316c5..df0a06a94788 100644 --- a/vcl/skia/salbmp.cxx +++ b/vcl/skia/salbmp.cxx @@ -391,7 +391,8 @@ bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScale #ifdef DBG_UTIL assert(mWriteAccessCount == 0); #endif - Size newSize(FRound(mSize.Width() * rScaleX), FRound(mSize.Height() * rScaleY)); + Size newSize(basegfx::fround<tools::Long>(mSize.Width() * rScaleX), + basegfx::fround<tools::Long>(mSize.Height() * rScaleY)); if (mSize == newSize) return true; diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index d063b440cf31..04dad0123573 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -216,20 +216,22 @@ catch (const sal::systools::ComError& e) bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) { assert(dynamic_cast<const SkiaWinFontInstance*>(&rLayout.GetFont())); - const SkiaWinFontInstance* pWinFont - = static_cast<const SkiaWinFontInstance*>(&rLayout.GetFont()); - const HFONT hLayoutFont = pWinFont->GetHFONT(); - double hScale = pWinFont->getHScale(); + const SkiaWinFontInstance& rWinFont + = static_cast<const SkiaWinFontInstance&>(rLayout.GetFont()); + const vcl::font::FontSelectPattern& rFSD = rWinFont.GetFontSelectPattern(); + if (rFSD.mnHeight == 0) + return false; + const HFONT hLayoutFont = rWinFont.GetHFONT(); LOGFONTW logFont; if (GetObjectW(hLayoutFont, sizeof(logFont), &logFont) == 0) { assert(false); return false; } - sk_sp<SkTypeface> typeface = pWinFont->GetSkiaTypeface(); + sk_sp<SkTypeface> typeface = rWinFont.GetSkiaTypeface(); if (!typeface) { - typeface = createDirectWriteTypeface(pWinFont); + typeface = createDirectWriteTypeface(&rWinFont); bool dwrite = true; if (!typeface) // fall back to GDI text rendering { @@ -250,7 +252,7 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) return false; } // Cache the typeface. - const_cast<SkiaWinFontInstance*>(pWinFont)->SetSkiaTypeface(typeface, dwrite); + const_cast<SkiaWinFontInstance&>(rWinFont).SetSkiaTypeface(typeface, dwrite); } SkFont font(typeface); @@ -267,21 +269,14 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) font.setEdging(logFont.lfQuality == NONANTIALIASED_QUALITY ? SkFont::Edging::kAlias : ePreferredAliasing); - const vcl::font::FontSelectPattern& rFSD = pWinFont->GetFontSelectPattern(); - int nHeight = rFSD.mnHeight; - int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight; - if (nWidth == 0 || nHeight == 0) - return false; + double nHeight = rFSD.mnHeight; + double nWidth = rFSD.mnWidth ? rFSD.mnWidth * rWinFont.GetAverageWidthFactor() : nHeight; font.setSize(nHeight); - font.setScaleX(hScale); + font.setScaleX(nWidth / nHeight); - // Unlike with Freetype-based font handling, use height even in vertical mode, - // additionally multiply it by horizontal scale to get the proper - // size and then scale the width back, otherwise the height would - // not be correct. I don't know why this is inconsistent. SkFont verticalFont(font); - verticalFont.setSize(nHeight * hScale); - verticalFont.setScaleX(1.0 / hScale); + verticalFont.setSize(nWidth); + verticalFont.setScaleX(nHeight / nWidth); assert(dynamic_cast<SkiaSalGraphicsImpl*>(mWinParent.GetImpl())); SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(mWinParent.GetImpl()); diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx index fed5daa8a117..c598146be376 100644 --- a/vcl/skia/x11/textrender.cxx +++ b/vcl/skia/x11/textrender.cxx @@ -35,10 +35,10 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr const FreetypeFontInstance& rInstance = static_cast<FreetypeFontInstance&>(rLayout.GetFont()); const FreetypeFont& rFont = rInstance.GetFreetypeFont(); const vcl::font::FontSelectPattern& rFSD = rInstance.GetFontSelectPattern(); - int nHeight = rFSD.mnHeight; - int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight; - if (nWidth == 0 || nHeight == 0) + if (rFSD.mnHeight == 0) return; + double nHeight = rFSD.mnHeight; + double nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight; if (!fontManager) { @@ -49,7 +49,7 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()); SkFont font(typeface); font.setSize(nHeight); - font.setScaleX(1.0 * nWidth / nHeight); + font.setScaleX(nWidth / nHeight); if (rInstance.NeedsArtificialItalic()) font.setSkewX(-1.0 * ARTIFICIAL_ITALIC_SKEW); if (rInstance.NeedsArtificialBold()) @@ -76,7 +76,7 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr // Vertical font, use width as "height". SkFont verticalFont(font); verticalFont.setSize(nWidth); - verticalFont.setScaleX(1.0 * nHeight / nWidth); + verticalFont.setScaleX(nHeight / nWidth); assert(dynamic_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl())); SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl()); diff --git a/vcl/source/animate/AnimationRenderer.cxx b/vcl/source/animate/AnimationRenderer.cxx index 29f386e0d388..5755c549d3e5 100644 --- a/vcl/source/animate/AnimationRenderer.cxx +++ b/vcl/source/animate/AnimationRenderer.cxx @@ -121,11 +121,11 @@ void AnimationRenderer::getPosSize( const AnimationFrame& rAnimationFrame, Point else fFactY = 1.0; - rPosPix.setX( FRound( rAnimationFrame.maPositionPixel.X() * fFactX ) ); - rPosPix.setY( FRound( rAnimationFrame.maPositionPixel.Y() * fFactY ) ); + rPosPix.setX(basegfx::fround<tools::Long>(rAnimationFrame.maPositionPixel.X() * fFactX)); + rPosPix.setY(basegfx::fround<tools::Long>(rAnimationFrame.maPositionPixel.Y() * fFactY)); - aPt2.setX( FRound( aPt2.X() * fFactX ) ); - aPt2.setY( FRound( aPt2.Y() * fFactY ) ); + aPt2.setX(basegfx::fround<tools::Long>(aPt2.X() * fFactX)); + aPt2.setY(basegfx::fround<tools::Long>(aPt2.Y() * fFactY)); rSizePix.setWidth( aPt2.X() - rPosPix.X() + 1 ); rSizePix.setHeight( aPt2.Y() - rPosPix.Y() + 1 ); diff --git a/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx b/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx index a8705176f1d1..335db364b3de 100644 --- a/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx +++ b/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx @@ -51,9 +51,9 @@ BitmapEx BitmapEmbossGreyFilter::execute(BitmapEx const& rBitmapEx) const std::unique_ptr<sal_Int32[]> pHMap(new sal_Int32[nWidth + 2]); std::unique_ptr<sal_Int32[]> pVMap(new sal_Int32[nHeight + 2]); sal_Int32 nX, nY, nNx, nNy, nDotL; - const sal_Int32 nLx = FRound(cos(fAzim) * cos(fElev) * 255.0); - const sal_Int32 nLy = FRound(sin(fAzim) * cos(fElev) * 255.0); - const sal_Int32 nLz = FRound(sin(fElev) * 255.0); + const sal_Int32 nLx = basegfx::fround(cos(fAzim) * cos(fElev) * 255.0); + const sal_Int32 nLy = basegfx::fround(sin(fAzim) * cos(fElev) * 255.0); + const sal_Int32 nLz = basegfx::fround(sin(fElev) * 255.0); const auto nZ2 = ((6 * 255) / 4) * ((6 * 255) / 4); const sal_Int32 nNzLz = ((6 * 255) / 4) * nLz; const sal_uInt8 cLz diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx index c19ed0f02c3a..90e592a6b33a 100644 --- a/vcl/source/bitmap/BitmapEx.cxx +++ b/vcl/source/bitmap/BitmapEx.cxx @@ -763,7 +763,7 @@ BitmapEx BitmapEx::TransformBitmapEx( return BitmapEx(); // force destination to 24 bit, we want to smooth output - const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight)); + const Size aDestinationSize(basegfx::fround<tools::Long>(fWidth), basegfx::fround<tools::Long>(fHeight)); bool bSmooth = implTransformNeedsSmooth(rTransformation); const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bSmooth)); diff --git a/vcl/source/bitmap/BitmapFastScaleFilter.cxx b/vcl/source/bitmap/BitmapFastScaleFilter.cxx index 14fa2464f399..f7281dc1582d 100644 --- a/vcl/source/bitmap/BitmapFastScaleFilter.cxx +++ b/vcl/source/bitmap/BitmapFastScaleFilter.cxx @@ -32,8 +32,8 @@ BitmapEx BitmapFastScaleFilter::execute(BitmapEx const& rBitmapEx) const Bitmap aBitmap(rBitmapEx.GetBitmap()); const Size aSizePix(aBitmap.GetSizePixel()); - const sal_Int32 nNewWidth = FRound(aSizePix.Width() * mfScaleX); - const sal_Int32 nNewHeight = FRound(aSizePix.Height() * mfScaleY); + const sal_Int32 nNewWidth = basegfx::fround(aSizePix.Width() * mfScaleX); + const sal_Int32 nNewHeight = basegfx::fround(aSizePix.Height() * mfScaleY); bool bRet = false; SAL_INFO("vcl.gdi", "New width: " << nNewWidth << "\nNew height: " << nNewHeight); diff --git a/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx b/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx index ce32f2512163..e596362deae8 100644 --- a/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx +++ b/vcl/source/bitmap/BitmapInterpolateScaleFilter.cxx @@ -31,8 +31,8 @@ BitmapEx BitmapInterpolateScaleFilter::execute(BitmapEx const& rBitmapEx) const Bitmap aBitmap(rBitmapEx.GetBitmap()); const Size aSizePix(aBitmap.GetSizePixel()); - const sal_Int32 nNewWidth = FRound(aSizePix.Width() * mfScaleX); - const sal_Int32 nNewHeight = FRound(aSizePix.Height() * mfScaleY); + const sal_Int32 nNewWidth = basegfx::fround(aSizePix.Width() * mfScaleX); + const sal_Int32 nNewHeight = basegfx::fround(aSizePix.Height() * mfScaleY); bool bRet = false; if ((nNewWidth > 1) && (nNewHeight > 1)) diff --git a/vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx b/vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx index bb40e9846708..fa8633731447 100644 --- a/vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx +++ b/vcl/source/bitmap/BitmapScaleConvolutionFilter.cxx @@ -90,7 +90,7 @@ bool ImplScaleConvolutionHor(Bitmap& rSource, Bitmap& rTarget, const double& rSc // Do horizontal filtering OSL_ENSURE(rScaleX > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); const sal_Int32 nWidth(rSource.GetSizePixel().Width()); - const sal_Int32 nNewWidth(FRound(nWidth * rScaleX)); + const sal_Int32 nNewWidth(basegfx::fround(nWidth * rScaleX)); if(nWidth == nNewWidth) { @@ -180,7 +180,7 @@ bool ImplScaleConvolutionVer(Bitmap& rSource, Bitmap& rTarget, const double& rSc // Do vertical filtering OSL_ENSURE(rScaleY > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); const sal_Int32 nHeight(rSource.GetSizePixel().Height()); - const sal_Int32 nNewHeight(FRound(nHeight * rScaleY)); + const sal_Int32 nNewHeight(basegfx::fround(nHeight * rScaleY)); if(nHeight == nNewHeight) { @@ -271,8 +271,8 @@ bool ImplScaleConvolution(Bitmap& rBitmap, const double& rScaleX, const double& const double fScaleY(bMirrorVer ? -rScaleY : rScaleY); const sal_Int32 nWidth(rBitmap.GetSizePixel().Width()); const sal_Int32 nHeight(rBitmap.GetSizePixel().Height()); - const sal_Int32 nNewWidth(FRound(nWidth * fScaleX)); - const sal_Int32 nNewHeight(FRound(nHeight * fScaleY)); + const sal_Int32 nNewWidth(basegfx::fround(nWidth * fScaleX)); + const sal_Int32 nNewHeight(basegfx::fround(nHeight * fScaleY)); const bool bScaleHor(nWidth != nNewWidth); const bool bScaleVer(nHeight != nNewHeight); const bool bMirror(bMirrorHor || bMirrorVer); diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx index 59ed78c8d6f3..5037f2600819 100644 --- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx +++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx @@ -870,8 +870,8 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const double fScaleX = std::fabs(mrScaleX); double fScaleY = std::fabs(mrScaleY); - const sal_Int32 nDstW = FRound(aSizePix.Width() * fScaleX); - const sal_Int32 nDstH = FRound(aSizePix.Height() * fScaleY); + const sal_Int32 nDstW = basegfx::fround(aSizePix.Width() * fScaleX); + const sal_Int32 nDstH = basegfx::fround(aSizePix.Height() * fScaleY); constexpr double fScaleThresh = 0.6; diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index 969490bfecce..b9a6332a2f20 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -436,8 +436,8 @@ BitmapEx CanvasTransformBitmap( const BitmapEx& rBitmap, ::basegfx::B2DPoint aPoint(x,y); aPoint *= aTransform; - const int nSrcX( ::basegfx::fround( aPoint.getX() ) ); - const int nSrcY( ::basegfx::fround( aPoint.getY() ) ); + const tools::Long nSrcX( ::basegfx::fround<tools::Long>( aPoint.getX() ) ); + const tools::Long nSrcY( ::basegfx::fround<tools::Long>( aPoint.getY() ) ); if( nSrcX < 0 || nSrcX >= aBmpSize.Width() || nSrcY < 0 || nSrcY >= aBmpSize.Height() ) { @@ -460,8 +460,8 @@ BitmapEx CanvasTransformBitmap( const BitmapEx& rBitmap, ::basegfx::B2DPoint aPoint(x,y); aPoint *= aTransform; - const int nSrcX( ::basegfx::fround( aPoint.getX() ) ); - const int nSrcY( ::basegfx::fround( aPoint.getY() ) ); + const tools::Long nSrcX( ::basegfx::fround<tools::Long>( aPoint.getX() ) ); + const tools::Long nSrcY( ::basegfx::fround<tools::Long>( aPoint.getY() ) ); if( nSrcX < 0 || nSrcX >= aBmpSize.Width() || nSrcY < 0 || nSrcY >= aBmpSize.Height() ) { @@ -1278,13 +1278,13 @@ Bitmap GetDownsampledBitmap(Size const& rDstSizeTwip, Point const& rSrcPt, Size if (fBmpWH < fMaxWH) { - aNewBmpSize.setWidth(FRound(fMaxPixelY * fBmpWH)); - aNewBmpSize.setHeight(FRound(fMaxPixelY)); + aNewBmpSize.setWidth(basegfx::fround<tools::Long>(fMaxPixelY * fBmpWH)); + aNewBmpSize.setHeight(basegfx::fround<tools::Long>(fMaxPixelY)); } else if (fBmpWH > 0.0) { - aNewBmpSize.setWidth(FRound(fMaxPixelX)); - aNewBmpSize.setHeight(FRound(fMaxPixelX / fBmpWH)); + aNewBmpSize.setWidth(basegfx::fround<tools::Long>(fMaxPixelX)); + aNewBmpSize.setHeight(basegfx::fround<tools::Long>(fMaxPixelX / fBmpWH)); } if( aNewBmpSize.Width() && aNewBmpSize.Height() ) diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx index a92c4a41d793..b20977595e70 100644 --- a/vcl/source/bitmap/bitmap.cxx +++ b/vcl/source/bitmap/bitmap.cxx @@ -353,8 +353,8 @@ void Bitmap::ReassignWithSize(const Bitmap& rBitmap) if ((aOldSizePix != aNewSizePix) && aOldSizePix.Width() && aOldSizePix.Height()) { - aNewPrefSize.setWidth(FRound(maPrefSize.Width() * aNewSizePix.Width() / aOldSizePix.Width())); - aNewPrefSize.setHeight(FRound(maPrefSize.Height() * aNewSizePix.Height() / aOldSizePix.Height())); + aNewPrefSize.setWidth(maPrefSize.Width() * aNewSizePix.Width() / aOldSizePix.Width()); + aNewPrefSize.setHeight(maPrefSize.Height() * aNewSizePix.Height() / aOldSizePix.Height()); } else { @@ -1618,30 +1618,30 @@ bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent, fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); const bool bGamma = ( fGamma != 1.0 ); - // create mapping table - for( tools::Long nX = 0; nX < 256; nX++ ) - { - if(!msoBrightness) - { - cMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fROff ), 0, 255 )); - cMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fGOff ), 0, 255 )); - cMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fBOff ), 0, 255 )); - } - else - { - // LO simply uses (in a somewhat optimized form) "newcolor = (oldcolor-128)*contrast+brightness+128" - // as the formula, i.e. contrast first, brightness afterwards. MSOffice, for whatever weird reason, - // use neither first, but apparently it applies half of brightness before contrast and half afterwards. - cMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0, 255 )); - cMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0, 255 )); - cMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0, 255 )); - } - if( bGamma ) - { - cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma ); - cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma ); - cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma ); - } + // create mapping table + for( tools::Long nX = 0; nX < 256; nX++ ) + { + if(!msoBrightness) + { + cMapR[nX] = basegfx::fround<sal_uInt8>(nX * fM + fROff); + cMapG[nX] = basegfx::fround<sal_uInt8>(nX * fM + fGOff); + cMapB[nX] = basegfx::fround<sal_uInt8>(nX * fM + fBOff); + } + else + { + // LO simply uses (in a somewhat optimized form) "newcolor = (oldcolor-128)*contrast+brightness+128" + // as the formula, i.e. contrast first, brightness afterwards. MSOffice, for whatever weird reason, + // use neither first, but apparently it applies half of brightness before contrast and half afterwards. + cMapR[nX] = basegfx::fround<sal_uInt8>((nX + fROff / 2 - 128) * fM + 128 + fROff / 2); + cMapG[nX] = basegfx::fround<sal_uInt8>((nX + fGOff / 2 - 128) * fM + 128 + fGOff / 2); + cMapB[nX] = basegfx::fround<sal_uInt8>((nX + fBOff / 2 - 128) * fM + 128 + fBOff / 2); + } + if( bGamma ) + { + cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma ); + cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma ); + cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma ); + } if( bInvert ) { diff --git a/vcl/source/bitmap/impvect.cxx b/vcl/source/bitmap/impvect.cxx index f3bdff4a9a4f..62dde3980261 100644 --- a/vcl/source/bitmap/impvect.cxx +++ b/vcl/source/bitmap/impvect.cxx @@ -687,7 +687,7 @@ bool ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf, fPercentStep_2 = 45.0 / n; fPercent += 10.0; - VECT_PROGRESS( pProgress, FRound( fPercent ) ); + VECT_PROGRESS( pProgress, basegfx::fround<tools::Long>( fPercent ) ); for( sal_uInt16 i = 0; i < n; i++ ) { @@ -697,7 +697,7 @@ bool ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf, ImplExpand( oMap, pRAcc.get(), aFindColor ); fPercent += fPercentStep_2; - VECT_PROGRESS( pProgress, FRound( fPercent ) ); + VECT_PROGRESS( pProgress, basegfx::fround<tools::Long>( fPercent ) ); if( oMap ) { @@ -721,7 +721,7 @@ bool ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf, } fPercent += fPercentStep_2; - VECT_PROGRESS( pProgress, FRound( fPercent ) ); + VECT_PROGRESS( pProgress, basegfx::fround<tools::Long>( fPercent ) ); } if( rMtf.GetActionSize() ) diff --git a/vcl/source/filter/eps/eps.cxx b/vcl/source/filter/eps/eps.cxx index 9da4f666b238..5cbc64734469 100644 --- a/vcl/source/filter/eps/eps.cxx +++ b/vcl/source/filter/eps/eps.cxx @@ -1176,8 +1176,8 @@ void PSWriter::ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev ) if( fScaleX != 1.0 || fScaleY != 1.0 ) { aTmpMtf.Scale( fScaleX, fScaleY ); - aSrcPt.setX( FRound( aSrcPt.X() * fScaleX ) ); - aSrcPt.setY( FRound( aSrcPt.Y() * fScaleY ) ); + aSrcPt.setX(basegfx::fround<tools::Long>(aSrcPt.X() * fScaleX)); + aSrcPt.setY(basegfx::fround<tools::Long>(aSrcPt.Y() * fScaleY)); } nMoveX = aDestPt.X() - aSrcPt.X(); diff --git a/vcl/source/filter/wmf/emfwr.cxx b/vcl/source/filter/wmf/emfwr.cxx index a82c45de8d8e..dfdc3156f838 100644 --- a/vcl/source/filter/wmf/emfwr.cxx +++ b/vcl/source/filter/wmf/emfwr.cxx @@ -880,7 +880,7 @@ void EMFWriter::ImplWriteTextRecord( const Point& rPos, const OUString& rText, K } else { - nNormWidth = maVDev->GetTextArray( rText, &aOwnArray ); + nNormWidth = basegfx::fround<sal_uInt32>(maVDev->GetTextArray(rText, &aOwnArray)); pDX = aOwnArray; } @@ -898,7 +898,7 @@ void EMFWriter::ImplWriteTextRecord( const Point& rPos, const OUString& rText, K const double fFactor = static_cast<double>(nWidth) / nNormWidth; for( i = 0; i < ( nLen - 1 ); i++ ) - aOwnArray.set(i, FRound(aOwnArray[i] * fFactor)); + aOwnArray.set(i, basegfx::fround(aOwnArray[i] * fFactor)); } } @@ -1217,8 +1217,8 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf ) if( fScaleX != 1.0 || fScaleY != 1.0 ) { aTmpMtf.Scale( fScaleX, fScaleY ); - aSrcPt.setX( FRound( aSrcPt.X() * fScaleX ) ); - aSrcPt.setY( FRound( aSrcPt.Y() * fScaleY ) ); + aSrcPt.setX(basegfx::fround<tools::Long>(aSrcPt.X() * fScaleX)); + aSrcPt.setY(basegfx::fround<tools::Long>(aSrcPt.Y() * fScaleY)); } nMoveX = aDestPt.X() - aSrcPt.X(); diff --git a/vcl/source/filter/wmf/wmfwr.cxx b/vcl/source/filter/wmf/wmfwr.cxx index 2c52aa7f5946..c35d7236c9d9 100644 --- a/vcl/source/filter/wmf/wmfwr.cxx +++ b/vcl/source/filter/wmf/wmfwr.cxx @@ -1198,7 +1198,7 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF ) pVirDev->SetFont( aSrcFont ); const sal_Int32 nLen = aTemp.getLength(); KernArray aDXAry; - const sal_Int32 nNormSize = pVirDev->GetTextArray( aTemp, nLen ? &aDXAry : nullptr ); + const sal_Int32 nNormSize = basegfx::fround(pVirDev->GetTextArray( aTemp, nLen ? &aDXAry : nullptr )); if (nLen && nNormSize == 0) { OSL_FAIL("Impossible div by 0 action: MetaStretchTextAction!"); @@ -1574,8 +1574,8 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF ) if( fScaleX != 1.0 || fScaleY != 1.0 ) { aTmpMtf.Scale( fScaleX, fScaleY ); - aSrcPt.setX( FRound( aSrcPt.X() * fScaleX ) ); - aSrcPt.setY( FRound( aSrcPt.Y() * fScaleY ) ); + aSrcPt.setX(basegfx::fround<tools::Long>(aSrcPt.X() * fScaleX)); + aSrcPt.setY(basegfx::fround<tools::Long>(aSrcPt.Y() * fScaleY)); } nMoveX = aDestPt.X() - aSrcPt.X(); diff --git a/vcl/source/font/LogicalFontInstance.cxx b/vcl/source/font/LogicalFontInstance.cxx index 6c7a7e2bde09..9d893b85aa70 100644 --- a/vcl/source/font/LogicalFontInstance.cxx +++ b/vcl/source/font/LogicalFontInstance.cxx @@ -26,6 +26,8 @@ #include <font/LogicalFontInstance.hxx> #include <impfontcache.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + LogicalFontInstance::LogicalFontInstance(const vcl::font::PhysicalFontFace& rFontFace, const vcl::font::FontSelectPattern& rFontSelData) : mxFontMetric(new ImplFontMetricData(rFontSelData)) @@ -166,16 +168,42 @@ void LogicalFontInstance::IgnoreFallbackForUnicode(sal_UCS4 cChar, FontWeight eW maUnicodeFallbackList.erase(it); } -bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect, +bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, basegfx::B2DRectangle& rRect, bool bVertical) const { + // TODO: find out if it's possible for the same glyph in the same font to be used both + // normally and vertically; if yes, then these two variants must be cached separately + if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect)) return true; - bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical); - if (mpFontCache && res) + auto* pHbFont = const_cast<LogicalFontInstance*>(this)->GetHbFont(); + hb_glyph_extents_t aExtents; + if (!hb_font_get_glyph_extents(pHbFont, nID, &aExtents)) + return false; + + double nXScale = 0, nYScale = 0; + GetScale(&nXScale, &nYScale); + + double fMinX = aExtents.x_bearing * nXScale; + double fMinY = -aExtents.y_bearing * nYScale; + double fMaxX = (aExtents.x_bearing + aExtents.width) * nXScale; + double fMaxY = -(aExtents.y_bearing + aExtents.height) * nYScale; + rRect = basegfx::B2DRectangle(fMinX, fMinY, fMaxX, fMaxY); + + auto orientation = mnOrientation; + if (bVertical) + orientation += 900_deg10; + if (orientation) + { + // Apply font rotation. + rRect.transform(basegfx::utils::createRotateB2DHomMatrix(-toRadians(orientation))); + } + + if (mpFontCache) mpFontCache->CacheGlyphBoundRect(this, nID, rRect); - return res; + + return true; } sal_GlyphId LogicalFontInstance::GetGlyphIndex(uint32_t nUnicode, uint32_t nVariationSelector) const diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx index 58b68baa9fe3..a167f741de15 100644 --- a/vcl/source/font/fontcache.cxx +++ b/vcl/source/font/fontcache.cxx @@ -248,7 +248,7 @@ void ImplFontCache::Invalidate() m_aBoundRectCache.clear(); } -bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, tools::Rectangle &rRect) +bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, basegfx::B2DRectangle &rRect) { if (!pFont->GetFontCache()) return false; @@ -265,7 +265,7 @@ bool ImplFontCache::GetCachedGlyphBoundRect(const LogicalFontInstance *pFont, sa return false; } -void ImplFontCache::CacheGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, tools::Rectangle &rRect) +void ImplFontCache::CacheGlyphBoundRect(const LogicalFontInstance *pFont, sal_GlyphId nID, basegfx::B2DRectangle &rRect) { if (!pFont->GetFontCache()) return; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index be301edcd365..5167921bd7ed 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -561,12 +561,12 @@ bool GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay { // We need glyph's advance, top bearing, and height to // correct y offset. - tools::Rectangle aRect; + basegfx::B2DRectangle aRect; // Get cached bound rect value for the font, GetFont().GetGlyphBoundRect(nGlyphIndex, aRect, true); - nXOffset = -(aRect.Top() / nXScale + ( pHbPositions[i].y_advance - + ( aRect.GetHeight() / nXScale ) ) / 2 ); + nXOffset = -(aRect.getMinX() / nXScale + ( pHbPositions[i].y_advance + + ( aRect.getHeight() / nXScale ) ) / 2.0 ); } } diff --git a/vcl/source/gdi/gdimetafiletools.cxx b/vcl/source/gdi/gdimetafiletools.cxx index 982cb0d7fbdc..c2d148ff2b0f 100644 --- a/vcl/source/gdi/gdimetafiletools.cxx +++ b/vcl/source/gdi/gdimetafiletools.cxx @@ -221,11 +221,11 @@ namespace rTarget.AddAction( new MetaBmpExScaleAction( Point( - basegfx::fround(aLogicBitmapRange.getMinX()), - basegfx::fround(aLogicBitmapRange.getMinY())), + basegfx::fround<tools::Long>(aLogicBitmapRange.getMinX()), + basegfx::fround<tools::Long>(aLogicBitmapRange.getMinY())), Size( - basegfx::fround(aLogicBitmapRange.getWidth()), - basegfx::fround(aLogicBitmapRange.getHeight())), + basegfx::fround<tools::Long>(aLogicBitmapRange.getWidth()), + basegfx::fround<tools::Long>(aLogicBitmapRange.getHeight())), BitmapEx(rBitmapEx.GetBitmap(), aAlpha))); return true; diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 34b42e1e7f92..079611135d02 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -740,8 +740,8 @@ void GDIMetaFile::Scale( double fScaleX, double fScaleY ) pModAct->Scale( fScaleX, fScaleY ); } - m_aPrefSize.setWidth( FRound( m_aPrefSize.Width() * fScaleX ) ); - m_aPrefSize.setHeight( FRound( m_aPrefSize.Height() * fScaleY ) ); + m_aPrefSize.setWidth(basegfx::fround<tools::Long>(m_aPrefSize.Width() * fScaleX)); + m_aPrefSize.setHeight(basegfx::fround<tools::Long>(m_aPrefSize.Height() * fScaleY)); } void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY ) @@ -786,8 +786,8 @@ Point GDIMetaFile::ImplGetRotatedPoint( const Point& rPt, const Point& rRotatePt const tools::Long nX = rPt.X() - rRotatePt.X(); const tools::Long nY = rPt.Y() - rRotatePt.Y(); - return Point( FRound( fCos * nX + fSin * nY ) + rRotatePt.X() + rOffset.Width(), - -FRound( fSin * nX - fCos * nY ) + rRotatePt.Y() + rOffset.Height() ); + return { basegfx::fround<tools::Long>(fCos * nX + fSin * nY) + rRotatePt.X() + rOffset.Width(), + basegfx::fround<tools::Long>(fCos * nY - fSin * nX) + rRotatePt.Y() + rOffset.Height() }; } tools::Polygon GDIMetaFile::ImplGetRotatedPolygon( const tools::Polygon& rPoly, const Point& rRotatePt, @@ -2098,15 +2098,15 @@ void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent, { if(!msoBrightness) { - aColParam.pMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fROff ), 0, 255 )); - aColParam.pMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fGOff ), 0, 255 )); - aColParam.pMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( nX * fM + fBOff ), 0, 255 )); + aColParam.pMapR[nX] = basegfx::fround<sal_uInt8>(nX * fM + fROff); + aColParam.pMapG[nX] = basegfx::fround<sal_uInt8>(nX * fM + fGOff); + aColParam.pMapB[nX] = basegfx::fround<sal_uInt8>(nX * fM + fBOff); } else { - aColParam.pMapR[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0, 255 )); - aColParam.pMapG[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0, 255 )); - aColParam.pMapB[ nX ] = static_cast<sal_uInt8>(MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0, 255 )); + aColParam.pMapR[nX] = basegfx::fround<sal_uInt8>((nX+fROff/2-128) * fM + 128 + fROff/2); + aColParam.pMapG[nX] = basegfx::fround<sal_uInt8>((nX+fGOff/2-128) * fM + 128 + fGOff/2); + aColParam.pMapB[nX] = basegfx::fround<sal_uInt8>((nX+fBOff/2-128) * fM + 128 + fBOff/2); } if( bGamma ) { @@ -2288,17 +2288,17 @@ bool GDIMetaFile::CreateThumbnail(BitmapEx& rBitmapEx, BmpConversion eColorConve if ( fWH <= 1.0 ) { - aSizePix.setWidth( FRound( nMaximumExtent * fWH ) ); + aSizePix.setWidth(basegfx::fround<tools::Long>(nMaximumExtent * fWH)); aSizePix.setHeight( nMaximumExtent ); } else { aSizePix.setWidth( nMaximumExtent ); - aSizePix.setHeight( FRound( nMaximumExtent / fWH ) ); + aSizePix.setHeight(basegfx::fround<tools::Long>(nMaximumExtent / fWH)); } - aDrawSize.setWidth( FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() ) ); - aDrawSize.setHeight( FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() ) ); + aDrawSize.setWidth( basegfx::fround<tools::Long>( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() ) ); + aDrawSize.setHeight( basegfx::fround<tools::Long>( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() ) ); } // draw image(s) into VDev and get resulting image diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 36b9b7ffef1b..23e0ec0865b2 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -576,13 +576,13 @@ Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) con if(fWH <= 1.0) { - aDrawSize.setWidth(basegfx::fround(GRAPHIC_MTFTOBMP_MAXEXT * fWH)); + aDrawSize.setWidth(basegfx::fround<tools::Long>(GRAPHIC_MTFTOBMP_MAXEXT * fWH)); aDrawSize.setHeight(GRAPHIC_MTFTOBMP_MAXEXT); } else { aDrawSize.setWidth(GRAPHIC_MTFTOBMP_MAXEXT); - aDrawSize.setHeight(basegfx::fround(GRAPHIC_MTFTOBMP_MAXEXT / fWH)); + aDrawSize.setHeight(basegfx::fround<tools::Long>(GRAPHIC_MTFTOBMP_MAXEXT / fWH)); } } @@ -804,7 +804,7 @@ Size ImpGraphic::getPrefSize() const aSize = Size(basegfx::fround(rRange.getWidth() / 20.0f), basegfx::fround(rRange.getHeight() / 20.0f)); else #endif - aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight())); + aSize = Size(basegfx::fround<tools::Long>(rRange.getWidth()), basegfx::fround<tools::Long>(rRange.getHeight())); } else { diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 9fdb22003338..bf556b25cac2 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -40,8 +40,8 @@ namespace void ImplScalePoint( Point& rPt, double fScaleX, double fScaleY ) { - rPt.setX( FRound( fScaleX * rPt.X() ) ); - rPt.setY( FRound( fScaleY * rPt.Y() ) ); + rPt.setX(basegfx::fround<tools::Long>(fScaleX * rPt.X())); + rPt.setY(basegfx::fround<tools::Long>(fScaleY * rPt.Y())); } void ImplScaleRect( tools::Rectangle& rRect, double fScaleX, double fScaleY ) @@ -68,10 +68,10 @@ void ImplScaleLineInfo( LineInfo& rLineInfo, double fScaleX, double fScaleY ) { const double fScale = ( fabs(fScaleX) + fabs(fScaleY) ) * 0.5; - rLineInfo.SetWidth( FRound( fScale * rLineInfo.GetWidth() ) ); - rLineInfo.SetDashLen( FRound( fScale * rLineInfo.GetDashLen() ) ); - rLineInfo.SetDotLen( FRound( fScale * rLineInfo.GetDotLen() ) ); - rLineInfo.SetDistance( FRound( fScale * rLineInfo.GetDistance() ) ); + rLineInfo.SetWidth(fScale * rLineInfo.GetWidth()); + rLineInfo.SetDashLen(fScale * rLineInfo.GetDashLen()); + rLineInfo.SetDotLen(fScale * rLineInfo.GetDotLen()); + rLineInfo.SetDistance(fScale * rLineInfo.GetDistance()); } } @@ -292,8 +292,8 @@ void MetaRoundRectAction::Move( tools::Long nHorzMove, tools::Long nVertMove ) void MetaRoundRectAction::Scale( double fScaleX, double fScaleY ) { ImplScaleRect( maRect, fScaleX, fScaleY ); - mnHorzRound = FRound( mnHorzRound * fabs(fScaleX) ); - mnVertRound = FRound( mnVertRound * fabs(fScaleY) ); + mnHorzRound = basegfx::fround<sal_uInt32>(mnHorzRound * fabs(fScaleX)); + mnVertRound = basegfx::fround<sal_uInt32>(mnVertRound * fabs(fScaleY)); } MetaEllipseAction::MetaEllipseAction() : @@ -665,7 +665,7 @@ void MetaTextArrayAction::Scale( double fScaleX, double fScaleY ) if ( !maDXAry.empty() && mnLen ) { for ( sal_uInt16 i = 0, nCount = mnLen; i < nCount; i++ ) - maDXAry.set(i, FRound(maDXAry[i] * fabs(fScaleX))); + maDXAry.set(i, basegfx::fround(maDXAry[i] * fabs(fScaleX))); } } @@ -718,7 +718,7 @@ void MetaStretchTextAction::Move( tools::Long nHorzMove, tools::Long nVertMove ) void MetaStretchTextAction::Scale( double fScaleX, double fScaleY ) { ImplScalePoint( maPt, fScaleX, fScaleY ); - mnWidth = static_cast<sal_uLong>(FRound( mnWidth * fabs(fScaleX) )); + mnWidth = basegfx::fround<sal_uInt32>(mnWidth * fabs(fScaleX)); } MetaTextRectAction::MetaTextRectAction() : MetaAction ( MetaActionType::TEXTRECT ), @@ -819,7 +819,7 @@ void MetaTextLineAction::Move( tools::Long nHorzMove, tools::Long nVertMove ) void MetaTextLineAction::Scale( double fScaleX, double fScaleY ) { ImplScalePoint( maPos, fScaleX, fScaleY ); - mnWidth = FRound( mnWidth * fabs(fScaleX) ); + mnWidth = basegfx::fround<tools::Long>(mnWidth * fabs(fScaleX)); } MetaBmpAction::MetaBmpAction() : @@ -1480,8 +1480,8 @@ rtl::Reference<MetaAction> MetaMoveClipRegionAction::Clone() const void MetaMoveClipRegionAction::Scale( double fScaleX, double fScaleY ) { - mnHorzMove = FRound( mnHorzMove * fScaleX ); - mnVertMove = FRound( mnVertMove * fScaleY ); + mnHorzMove = basegfx::fround<tools::Long>(mnHorzMove * fScaleX); + mnVertMove = basegfx::fround<tools::Long>(mnVertMove * fScaleY); } MetaLineColorAction::MetaLineColorAction() : @@ -1730,8 +1730,8 @@ rtl::Reference<MetaAction> MetaFontAction::Clone() const void MetaFontAction::Scale( double fScaleX, double fScaleY ) { const Size aSize( - FRound(maFont.GetFontSize().Width() * fabs(fScaleX)), - FRound(maFont.GetFontSize().Height() * fabs(fScaleY))); + basegfx::fround<tools::Long>(maFont.GetFontSize().Width() * fabs(fScaleX)), + basegfx::fround<tools::Long>(maFont.GetFontSize().Height() * fabs(fScaleY))); maFont.SetFontSize( aSize ); } diff --git a/vcl/source/gdi/pdfbuildin_fonts.cxx b/vcl/source/gdi/pdfbuildin_fonts.cxx index e387f78638d3..7f80bfdd030d 100644 --- a/vcl/source/gdi/pdfbuildin_fonts.cxx +++ b/vcl/source/gdi/pdfbuildin_fonts.cxx @@ -738,11 +738,6 @@ BuildinFontInstance::BuildinFontInstance(const vcl::font::PhysicalFontFace& rFon { } -bool BuildinFontInstance::ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const -{ - return false; -} - bool BuildinFontInstance::GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const { return false; diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 6ea5c67f12a3..2e5c5904673f 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6982,11 +6982,20 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool writeBuffer( aLine.getStr(), aLine.getLength() ); Point aOffset(0,0); + Point aOffsetVert(0,0); if ( nEmphMark & FontEmphasisMark::PosBelow ) + { aOffset.AdjustY(GetFontInstance()->mxFontMetric->GetDescent() + aEmphasisMark.GetYOffset() ); + aOffsetVert = aOffset; + } else + { aOffset.AdjustY( -(GetFontInstance()->mxFontMetric->GetAscent() + aEmphasisMark.GetYOffset()) ); + // Todo: use ideographic em-box or ideographic character face information. + aOffsetVert.AdjustY(-(GetFontInstance()->mxFontMetric->GetAscent() + + GetFontInstance()->mxFontMetric->GetDescent() + aEmphasisMark.GetYOffset())); + } tools::Long nEmphWidth2 = aEmphasisMark.GetWidth() / 2; tools::Long nEmphHeight2 = nEmphHeight / 2; @@ -6997,13 +7006,27 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool else if ( eAlign == ALIGN_TOP ) aOffset.AdjustY(GetFontInstance()->mxFontMetric->GetAscent() ); + basegfx::B2DRectangle aRectangle; nIndex = 0; - while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex)) + while (rLayout.GetNextGlyph(&pGlyph, aPos, nIndex, &pGlyphFont)) { + if (!pGlyph->GetGlyphBoundRect(pGlyphFont, aRectangle)) + continue; + if (!pGlyph->IsSpacing()) { - DevicePoint aAdjOffset(aOffset.X(), aOffset.Y()); - aAdjOffset.adjustX((pGlyph->newWidth() - aEmphasisMark.GetWidth()) / 2); + DevicePoint aAdjOffset; + if (pGlyph->IsVertical()) + { + aAdjOffset = DevicePoint(aOffsetVert.X(), aOffsetVert.Y()); + aAdjOffset.adjustX((-pGlyph->origWidth() + aEmphasisMark.GetWidth()) / 2); + } + else + { + aAdjOffset = basegfx::B2DPoint(aOffset.X(), aOffset.Y()); + aAdjOffset.adjustX(aRectangle.getMinX() + (aRectangle.getWidth() - aEmphasisMark.GetWidth()) / 2 ); + } + aAdjOffset = aRotScale.transform( aAdjOffset ); aAdjOffset -= DevicePoint(nEmphWidth2, nEmphHeight2); @@ -8498,12 +8521,12 @@ void PDFWriterImpl::drawPolyLine( const tools::Polygon& rPoly, const PDFWriter:: const sal_uInt32 nNextIndex((a + 1) % nPointCount); const basegfx::B2DPoint aNext(aPoly.getB2DPoint(nNextIndex)); - m_aPages.back().appendPoint( Point( FRound(aCurrent.getX()), - FRound(aCurrent.getY()) ), + m_aPages.back().appendPoint( Point( basegfx::fround<tools::Long>(aCurrent.getX()), + basegfx::fround<tools::Long>(aCurrent.getY()) ), aLine ); aLine.append( " m " ); - m_aPages.back().appendPoint( Point( FRound(aNext.getX()), - FRound(aNext.getY()) ), + m_aPages.back().appendPoint( Point( basegfx::fround<tools::Long>(aNext.getX()), + basegfx::fround<tools::Long>(aNext.getY()) ), aLine ); aLine.append( " l" ); diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index cac3813cdedc..cbee392896fd 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -138,13 +138,13 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz if( fBmpWH < fMaxWH ) { - aNewBmpSize.setWidth( FRound( fMaxPixelY * fBmpWH ) ); - aNewBmpSize.setHeight( FRound( fMaxPixelY ) ); + aNewBmpSize.setWidth(basegfx::fround<tools::Long>(fMaxPixelY * fBmpWH)); + aNewBmpSize.setHeight(basegfx::fround<tools::Long>(fMaxPixelY)); } else if( fBmpWH > 0.0 ) { - aNewBmpSize.setWidth( FRound( fMaxPixelX ) ); - aNewBmpSize.setHeight( FRound( fMaxPixelX / fBmpWH) ); + aNewBmpSize.setWidth(basegfx::fround<tools::Long>(fMaxPixelX)); + aNewBmpSize.setHeight(basegfx::fround<tools::Long>(fMaxPixelX / fBmpWH)); } if( aNewBmpSize.Width() && aNewBmpSize.Height() ) diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 6225db3a6b35..26d210b2e5a3 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -161,10 +161,10 @@ void Printer::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask, // create forward mapping tables for( nX = 0; nX <= nSrcWidth; nX++ ) - pMapX[ nX ] = aDestPt.X() + FRound( static_cast<double>(aDestSz.Width()) * nX / nSrcWidth ); + pMapX[ nX ] = aDestPt.X() + basegfx::fround<tools::Long>( static_cast<double>(aDestSz.Width()) * nX / nSrcWidth ); for( nY = 0; nY <= nSrcHeight; nY++ ) - pMapY[ nY ] = aDestPt.Y() + FRound( static_cast<double>(aDestSz.Height()) * nY / nSrcHeight ); + pMapY[ nY ] = aDestPt.Y() + basegfx::fround<tools::Long>( static_cast<double>(aDestSz.Height()) * nY / nSrcHeight ); // walk through all rectangles of mask const vcl::Region aWorkRgn(aMask.CreateRegion(COL_BLACK, tools::Rectangle(Point(), aMask.GetSizePixel()))); @@ -245,7 +245,7 @@ void Printer::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly, tools::Rectangle aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() ); const Size aDPISize( LogicToPixel(Size(1, 1), MapMode(MapUnit::MapInch)) ); - const tools::Long nBaseExtent = std::max<tools::Long>( FRound( aDPISize.Width() / 300. ), 1 ); + const tools::Long nBaseExtent = std::max<tools::Long>( basegfx::fround<tools::Long>( aDPISize.Width() / 300. ), 1 ); tools::Long nMove; const sal_uInt16 nTrans = ( nTransparencePercent < 13 ) ? 0 : ( nTransparencePercent < 38 ) ? 25 : @@ -748,10 +748,10 @@ void Printer::DrawDeviceMask( const Bitmap& rMask, const Color& rMaskColor, // create forward mapping tables for( nX = 0; nX <= nSrcWidth; nX++ ) - pMapX[ nX ] = aDestPt.X() + FRound( static_cast<double>(aDestSz.Width()) * nX / nSrcWidth ); + pMapX[ nX ] = aDestPt.X() + basegfx::fround<tools::Long>( static_cast<double>(aDestSz.Width()) * nX / nSrcWidth ); for( nY = 0; nY <= nSrcHeight; nY++ ) - pMapY[ nY ] = aDestPt.Y() + FRound( static_cast<double>(aDestSz.Height()) * nY / nSrcHeight ); + pMapY[ nY ] = aDestPt.Y() + basegfx::fround<tools::Long>( static_cast<double>(aDestSz.Height()) * nY / nSrcHeight ); // walk through all rectangles of mask const vcl::Region aWorkRgn(aMask.CreateRegion(COL_BLACK, tools::Rectangle(Point(), aMask.GetSizePixel()))); diff --git a/vcl/source/gdi/regband.cxx b/vcl/source/gdi/regband.cxx index 675d99bc0975..db0000444fb8 100644 --- a/vcl/source/gdi/regband.cxx +++ b/vcl/source/gdi/regband.cxx @@ -17,6 +17,9 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <basegfx/numeric/ftools.hxx> #include <tools/helpers.hxx> #include <osl/diagnose.h> #include <sal/log.hxx> @@ -314,8 +317,8 @@ void ImplRegionBand::ScaleX( double fHorzScale ) ImplRegionBandSep* pSep = mpFirstSep; while ( pSep ) { - pSep->mnXLeft = FRound( pSep->mnXLeft * fHorzScale ); - pSep->mnXRight = FRound( pSep->mnXRight * fHorzScale ); + pSep->mnXLeft = basegfx::fround<tools::Long>(pSep->mnXLeft * fHorzScale); + pSep->mnXRight = basegfx::fround<tools::Long>(pSep->mnXRight * fHorzScale); pSep = pSep->mpNextSep; } } diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx index 78a862225ed2..21b977f4a53e 100644 --- a/vcl/source/gdi/region.cxx +++ b/vcl/source/gdi/region.cxx @@ -1245,8 +1245,8 @@ tools::Rectangle vcl::Region::GetBoundRect() const { // #i122149# corrected rounding, no need for ceil() and floor() here return tools::Rectangle( - basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()), - basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY())); + basegfx::fround<tools::Long>(aRange.getMinX()), basegfx::fround<tools::Long>(aRange.getMinY()), + basegfx::fround<tools::Long>(aRange.getMaxX()), basegfx::fround<tools::Long>(aRange.getMaxY())); } } diff --git a/vcl/source/gdi/regionband.cxx b/vcl/source/gdi/regionband.cxx index 5a8e3676e57e..c7ac8c5e7101 100644 --- a/vcl/source/gdi/regionband.cxx +++ b/vcl/source/gdi/regionband.cxx @@ -701,8 +701,8 @@ void RegionBand::Scale(double fScaleX, double fScaleY) // process the vertical move if(0.0 != fScaleY) { - pBand->mnYTop = basegfx::fround(pBand->mnYTop * fScaleY); - pBand->mnYBottom = basegfx::fround(pBand->mnYBottom * fScaleY); + pBand->mnYTop = basegfx::fround<tools::Long>(pBand->mnYTop * fScaleY); + pBand->mnYBottom = basegfx::fround<tools::Long>(pBand->mnYBottom * fScaleY); } // process the horizontal move diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index ed368f04022e..e801ac3057ca 100644 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -33,6 +33,7 @@ #include <sallayout.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <rtl/math.hxx> #include <i18nlangtag/lang.h> @@ -214,12 +215,17 @@ bool SalLayout::GetOutline(basegfx::B2DPolyPolygonVector& rVector) const return (bAllOk && bOneOk); } -bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const +// No need to expand to the next pixel, when the character only covers its tiny fraction +static double trimInsignificant(double n) { - bool bRet = false; - rRect.SetEmpty(); + return std::abs(n) >= 0x1p53 ? n : std::round(n * 1e5) / 1e5; +} - tools::Rectangle aRectangle; +bool SalLayout::GetBoundRect(basegfx::B2DRectangle& rRect) const +{ + bool bRet = false; + rRect.reset(); + basegfx::B2DRectangle aRectangle; DevicePoint aPos; const GlyphItem* pGlyph; @@ -230,18 +236,11 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const // get bounding rectangle of individual glyph if (pGlyph->GetGlyphBoundRect(pGlyphFont, aRectangle)) { - if (!aRectangle.IsEmpty()) + if (!aRectangle.isEmpty()) { - aRectangle.AdjustLeft(std::floor(aPos.getX())); - aRectangle.AdjustRight(std::ceil(aPos.getX())); - aRectangle.AdjustTop(std::floor(aPos.getY())); - aRectangle.AdjustBottom(std::ceil(aPos.getY())); - + aRectangle.transform(basegfx::utils::createTranslateB2DHomMatrix(aPos)); // merge rectangle - if (rRect.IsEmpty()) - rRect = aRectangle; - else - rRect.Union(aRectangle); + rRect.expand(aRectangle); } bRet = true; } @@ -250,6 +249,19 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const return bRet; } +tools::Rectangle SalLayout::BoundRect2Rectangle(basegfx::B2DRectangle& rRect) +{ + if (rRect.isEmpty()) + return {}; + + double l = rtl::math::approxFloor(trimInsignificant(rRect.getMinX())), + t = rtl::math::approxFloor(trimInsignificant(rRect.getMinY())), + r = rtl::math::approxCeil(trimInsignificant(rRect.getMaxX())), + b = rtl::math::approxCeil(trimInsignificant(rRect.getMaxY())); + assert(std::isfinite(l) && std::isfinite(t) && std::isfinite(r) && std::isfinite(b)); + return tools::Rectangle(l, t, r, b); +} + SalLayoutGlyphs SalLayout::GetGlyphs() const { return SalLayoutGlyphs(); // invalid diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx index 0ee1c9ba5faf..ce681a2e9eea 100644 --- a/vcl/source/gdi/textlayout.cxx +++ b/vcl/source/gdi/textlayout.cxx @@ -166,7 +166,7 @@ namespace vcl return 0; // retrieve the character widths from the reference device - tools::Long nTextWidth = m_rReferenceDevice.GetTextArray( _rText, _pDXAry, _nStartIndex, _nLength ); + tools::Long nTextWidth = basegfx::fround<tools::Long>(m_rReferenceDevice.GetTextArray( _rText, _pDXAry, _nStartIndex, _nLength )); #if OSL_DEBUG_LEVEL > 1 if ( _pDXAry ) { diff --git a/vcl/source/graphic/GraphicObject.cxx b/vcl/source/graphic/GraphicObject.cxx index d03db6be891a..249738e0174f 100644 --- a/vcl/source/graphic/GraphicObject.cxx +++ b/vcl/source/graphic/GraphicObject.cxx @@ -385,20 +385,20 @@ bool GraphicObject::ImplGetCropParams(const OutputDevice& rOut, Point& rPt, Size if( !aSize100.IsEmpty() && nTotalWidth > 0 && nTotalHeight > 0 ) { double fScale = static_cast<double>(aSize100.Width()) / nTotalWidth; - const tools::Long nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BmpMirrorFlags::Horizontal ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale ); - const tools::Long nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1; + const tools::Long nNewLeft = basegfx::fround<tools::Long>( ( ( pAttr->GetMirrorFlags() & BmpMirrorFlags::Horizontal ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * -fScale ); + const tools::Long nNewRight = nNewLeft + basegfx::fround<tools::Long>( aSize100.Width() * fScale ) - 1; fScale = static_cast<double>(rSz.Width()) / aSize100.Width(); - rPt.AdjustX(FRound( nNewLeft * fScale ) ); - rSz.setWidth( FRound( ( nNewRight - nNewLeft + 1 ) * fScale ) ); + rPt.AdjustX(basegfx::fround<tools::Long>(nNewLeft * fScale)); + rSz.setWidth(basegfx::fround<tools::Long>((nNewRight - nNewLeft + 1) * fScale)); fScale = static_cast<double>(aSize100.Height()) / nTotalHeight; - const tools::Long nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BmpMirrorFlags::Vertical ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale ); - const tools::Long nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1; + const tools::Long nNewTop = basegfx::fround<tools::Long>( ( ( pAttr->GetMirrorFlags() & BmpMirrorFlags::Vertical ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * -fScale ); + const tools::Long nNewBottom = nNewTop + basegfx::fround<tools::Long>( aSize100.Height() * fScale ) - 1; fScale = static_cast<double>(rSz.Height()) / aSize100.Height(); - rPt.AdjustY(FRound( nNewTop * fScale ) ); - rSz.setHeight( FRound( ( nNewBottom - nNewTop + 1 ) * fScale ) ); + rPt.AdjustY(basegfx::fround<tools::Long>(nNewTop * fScale)); + rSz.setHeight(basegfx::fround<tools::Long>((nNewBottom - nNewTop + 1) * fScale)); if( nRot10 ) { @@ -743,10 +743,10 @@ Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMo const double fFactorX(static_cast<double>(aBitmapEx.GetSizePixel().Width()) / aSrcSizePixel.Width()); const double fFactorY(static_cast<double>(aBitmapEx.GetSizePixel().Height()) / aSrcSizePixel.Height()); - aCropLeftTop.setWidth( basegfx::fround(aCropLeftTop.Width() * fFactorX) ); - aCropLeftTop.setHeight( basegfx::fround(aCropLeftTop.Height() * fFactorY) ); - aCropRightBottom.setWidth( basegfx::fround(aCropRightBottom.Width() * fFactorX) ); - aCropRightBottom.setHeight( basegfx::fround(aCropRightBottom.Height() * fFactorY) ); + aCropLeftTop.setWidth( basegfx::fround<tools::Long>(aCropLeftTop.Width() * fFactorX) ); + aCropLeftTop.setHeight( basegfx::fround<tools::Long>(aCropLeftTop.Height() * fFactorY) ); + aCropRightBottom.setWidth( basegfx::fround<tools::Long>(aCropRightBottom.Width() * fFactorX) ); + aCropRightBottom.setHeight( basegfx::fround<tools::Long>(aCropRightBottom.Height() * fFactorY) ); aSrcSizePixel = aBitmapEx.GetSizePixel(); } diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx index 595f12a959c8..a09c68745d54 100644 --- a/vcl/source/helper/canvastools.cxx +++ b/vcl/source/helper/canvastools.cxx @@ -325,8 +325,8 @@ namespace vcl::unotools ::Size sizeFromB2DSize( const basegfx::B2DVector& rVec ) { - return ::Size( FRound( rVec.getX() ), - FRound( rVec.getY() ) ); + return ::Size(basegfx::fround<tools::Long>(rVec.getX()), + basegfx::fround<tools::Long>(rVec.getY())); } ::Point pointFromB2DPoint( const basegfx::B2DPoint& rPoint ) diff --git a/vcl/source/outdev/bitmapex.cxx b/vcl/source/outdev/bitmapex.cxx index fc966b53c3d2..e0d82ab9c48d 100644 --- a/vcl/source/outdev/bitmapex.cxx +++ b/vcl/source/outdev/bitmapex.cxx @@ -544,10 +544,10 @@ void OutputDevice::DrawTransformedBitmapEx( // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx // do *not* execute the mirroring here, it's done in the fallback // #i124580# the correct DestSize needs to be calculated based on MaxXY values - Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + Point aDestPt(basegfx::fround<tools::Long>(aTranslate.getX()), basegfx::fround<tools::Long>(aTranslate.getY())); const Size aDestSize( - basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(), - basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); + basegfx::fround<tools::Long>(aScale.getX() + aTranslate.getX()) - aDestPt.X(), + basegfx::fround<tools::Long>(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); const Point aOrigin = GetMapMode().GetOrigin(); if (!bMetafile && comphelper::LibreOfficeKit::isActive() && GetMapMode().GetMapUnit() != MapUnit::MapPixel) { @@ -574,10 +574,10 @@ void OutputDevice::DrawTransformedBitmapEx( // with no rotation or shear it can be mapped to DrawBitmapEx // do *not* execute the mirroring here, it's done in the fallback // #i124580# the correct DestSize needs to be calculated based on MaxXY values - const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Point aDestPt(basegfx::fround<tools::Long>(aTranslate.getX()), basegfx::fround<tools::Long>(aTranslate.getY())); const Size aDestSize( - basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(), - basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); + basegfx::fround<tools::Long>(aScale.getX() + aTranslate.getX()) - aDestPt.X(), + basegfx::fround<tools::Long>(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); DrawBitmapEx(aDestPt, aDestSize, bitmapEx); return; @@ -671,10 +671,10 @@ void OutputDevice::DrawTransformedBitmapEx( // extract point and size; do not remove size, the bitmap may have been prepared reduced by purpose // #i124580# the correct DestSize needs to be calculated based on MaxXY values - const Point aDestPt(basegfx::fround(aVisibleRange.getMinX()), basegfx::fround(aVisibleRange.getMinY())); + const Point aDestPt(basegfx::fround<tools::Long>(aVisibleRange.getMinX()), basegfx::fround<tools::Long>(aVisibleRange.getMinY())); const Size aDestSize( - basegfx::fround(aVisibleRange.getMaxX()) - aDestPt.X(), - basegfx::fround(aVisibleRange.getMaxY()) - aDestPt.Y()); + basegfx::fround<tools::Long>(aVisibleRange.getMaxX()) - aDestPt.X(), + basegfx::fround<tools::Long>(aVisibleRange.getMaxY()) - aDestPt.Y()); DrawBitmapEx(aDestPt, aDestSize, aTransformed); } diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 3bfbb8f6d8ce..fee8021b43a9 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -950,8 +950,8 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout ) tools::Long nEmphasisHeight2 = nEmphasisHeight / 2; aOffset += Point( nEmphasisWidth2, nEmphasisHeight2 ); - DevicePoint aOutPoint; - tools::Rectangle aRectangle; + basegfx::B2DPoint aOutPoint; + basegfx::B2DRectangle aRectangle; const GlyphItem* pGlyph; const LogicalFontInstance* pGlyphFont; int nStart = 0; @@ -971,7 +971,7 @@ void OutputDevice::ImplDrawEmphasisMarks( SalLayout& rSalLayout ) else { aAdjPoint = aOffset; - aAdjPoint.AdjustX(aRectangle.Left() + (aRectangle.GetWidth() - aEmphasisMark.GetWidth()) / 2 ); + aAdjPoint.AdjustX(aRectangle.getMinX() + (aRectangle.getWidth() - aEmphasisMark.GetWidth()) / 2 ); } if ( mpFontInstance->mnOrientation ) diff --git a/vcl/source/outdev/hatch.cxx b/vcl/source/outdev/hatch.cxx index 0fc755864a5d..15a4f926a95e 100644 --- a/vcl/source/outdev/hatch.cxx +++ b/vcl/source/outdev/hatch.cxx @@ -280,10 +280,10 @@ void OutputDevice::CalcHatchValues( const tools::Rectangle& rRect, tools::Long n { const double fAngle = std::abs( toRadians(nAngle) ); const double fTan = tan( fAngle ); - const tools::Long nYOff = FRound( ( rRect.Right() - rRect.Left() ) * fTan ); + const tools::Long nYOff = basegfx::fround<tools::Long>( ( rRect.Right() - rRect.Left() ) * fTan ); tools::Long nPY; - nDist = FRound( nDist / cos( fAngle ) ); + nDist = basegfx::fround<tools::Long>(nDist / cos(fAngle)); rInc = Size( 0, nDist ); if( nAngle > 0_deg10 ) @@ -291,14 +291,14 @@ void OutputDevice::CalcHatchValues( const tools::Rectangle& rRect, tools::Long n rPt1 = rRect.TopLeft(); rPt2 = Point( rRect.Right(), rRect.Top() - nYOff ); rEndPt1 = Point( rRect.Left(), rRect.Bottom() + nYOff ); - nPY = FRound( aRef.Y() - ( ( rPt1.X() - aRef.X() ) * fTan ) ); + nPY = basegfx::fround<tools::Long>(aRef.Y() - ((rPt1.X() - aRef.X()) * fTan)); } else { rPt1 = rRect.TopRight(); rPt2 = Point( rRect.Left(), rRect.Top() - nYOff ); rEndPt1 = Point( rRect.Right(), rRect.Bottom() + nYOff ); - nPY = FRound( aRef.Y() + ( ( rPt1.X() - aRef.X() ) * fTan ) ); + nPY = basegfx::fround<tools::Long>(aRef.Y() + ((rPt1.X() - aRef.X()) * fTan)); } if( nPY <= rPt1.Y() ) @@ -313,10 +313,10 @@ void OutputDevice::CalcHatchValues( const tools::Rectangle& rRect, tools::Long n { const double fAngle = std::abs( toRadians(nAngle) ); const double fTan = tan( fAngle ); - const tools::Long nXOff = FRound( (static_cast<double>(rRect.Bottom()) - rRect.Top()) / fTan ); + const tools::Long nXOff = basegfx::fround<tools::Long>( (static_cast<double>(rRect.Bottom()) - rRect.Top()) / fTan ); tools::Long nPX; - nDist = FRound( nDist / sin( fAngle ) ); + nDist = basegfx::fround<tools::Long>(nDist / sin(fAngle)); rInc = Size( nDist, 0 ); if( nAngle > 0_deg10 ) @@ -324,14 +324,14 @@ void OutputDevice::CalcHatchValues( const tools::Rectangle& rRect, tools::Long n rPt1 = rRect.TopLeft(); rPt2 = Point( rRect.Left() - nXOff, rRect.Bottom() ); rEndPt1 = Point( rRect.Right() + nXOff, rRect.Top() ); - nPX = FRound( aRef.X() - ( (static_cast<double>(rPt1.Y()) - aRef.Y()) / fTan ) ); + nPX = basegfx::fround<tools::Long>( aRef.X() - ( (static_cast<double>(rPt1.Y()) - aRef.Y()) / fTan ) ); } else { rPt1 = rRect.BottomLeft(); rPt2 = Point( rRect.Left() - nXOff, rRect.Top() ); rEndPt1 = Point( rRect.Right() + nXOff, rRect.Bottom() ); - nPX = FRound( aRef.X() + ( (static_cast<double>(rPt1.Y()) - aRef.Y()) / fTan ) ); + nPX = basegfx::fround<tools::Long>( aRef.X() + ( (static_cast<double>(rPt1.Y()) - aRef.Y()) / fTan ) ); } if( nPX <= rPt1.X() ) @@ -401,7 +401,8 @@ void OutputDevice::DrawHatchLine( const tools::Line& rLine, const tools::PolyPol SAL_WARN("vcl.gdi", "too many hatch points"); return; } - pPtBuffer[ nPCounter++ ] = Point( FRound( fX ), FRound( fY ) ); + pPtBuffer[nPCounter++] = Point(basegfx::fround<tools::Long>(fX), + basegfx::fround<tools::Long>(fY)); } } diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx index 67414cb2976c..3359cc70c210 100644 --- a/vcl/source/outdev/map.cxx +++ b/vcl/source/outdev/map.cxx @@ -272,6 +272,19 @@ static tools::Long ImplPixelToLogic(tools::Long n, tools::Long nDPI, tools::Long return n; } +static double ImplPixelToLogicDouble(double n, tools::Long nDPI, tools::Long nMapNum, + tools::Long nMapDenom) +{ + assert(nDPI > 0); + if (nMapNum == 0) + return 0; + + n *= nMapDenom; + n /= nDPI; + n /= nMapNum; + return n; +} + tools::Long OutputDevice::ImplLogicXToDevicePixel( tools::Long nX ) const { if ( !mbMap ) @@ -314,6 +327,14 @@ tools::Long OutputDevice::ImplDevicePixelToLogicWidth( tools::Long nWidth ) cons return ImplPixelToLogic(nWidth, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX); } +SAL_DLLPRIVATE double OutputDevice::ImplDevicePixelToLogicWidthDouble(double nWidth) const +{ + if (!mbMap) + return nWidth; + + return ImplPixelToLogicDouble(nWidth, mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX); +} + tools::Long OutputDevice::ImplDevicePixelToLogicHeight( tools::Long nHeight ) const { if ( !mbMap ) @@ -322,6 +343,14 @@ tools::Long OutputDevice::ImplDevicePixelToLogicHeight( tools::Long nHeight ) co return ImplPixelToLogic(nHeight, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY); } +double OutputDevice::ImplDevicePixelToLogicHeightDouble(double nHeight) const +{ + if (!mbMap) + return nHeight; + + return ImplPixelToLogicDouble(nHeight, mnDPIY, maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY); +} + Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const { if ( !mbMap ) @@ -1230,6 +1259,14 @@ basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygo return aTransformedPoly; } +basegfx::B2DRectangle OutputDevice::PixelToLogic(const basegfx::B2DRectangle& rDeviceRect) const +{ + basegfx::B2DRectangle aTransformedRect = rDeviceRect; + const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation(); + aTransformedRect.transform(rTransformationMatrix); + return aTransformedRect; +} + vcl::Region OutputDevice::PixelToLogic( const vcl::Region& rDeviceRegion ) const { diff --git a/vcl/source/outdev/rect.cxx b/vcl/source/outdev/rect.cxx index 63ec16c62c61..227263f23fdf 100644 --- a/vcl/source/outdev/rect.cxx +++ b/vcl/source/outdev/rect.cxx @@ -377,10 +377,10 @@ BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix ) const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? static_cast<double>( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0; const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? static_cast<double>( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0; - const tools::Long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) ); - const tools::Long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) ); - const tools::Long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) ); - const tools::Long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) ); + const tools::Long nDstX1 = rTwoRect.mnDestX + basegfx::fround<tools::Long>( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) ); + const tools::Long nDstY1 = rTwoRect.mnDestY + basegfx::fround<tools::Long>( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) ); + const tools::Long nDstX2 = rTwoRect.mnDestX + basegfx::fround<tools::Long>( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) ); + const tools::Long nDstY2 = rTwoRect.mnDestY + basegfx::fround<tools::Long>( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) ); rTwoRect.mnSrcX = aCropRect.Left(); rTwoRect.mnSrcY = aCropRect.Top(); @@ -419,10 +419,10 @@ void AdjustTwoRect( SalTwoRect& rTwoRect, const tools::Rectangle& rValidSrcRect const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? static_cast<double>( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0; const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? static_cast<double>( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0; - const tools::Long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) ); - const tools::Long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) ); - const tools::Long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) ); - const tools::Long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) ); + const tools::Long nDstX1 = rTwoRect.mnDestX + basegfx::fround<tools::Long>( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) ); + const tools::Long nDstY1 = rTwoRect.mnDestY + basegfx::fround<tools::Long>( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) ); + const tools::Long nDstX2 = rTwoRect.mnDestX + basegfx::fround<tools::Long>( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) ); + const tools::Long nDstY2 = rTwoRect.mnDestY + basegfx::fround<tools::Long>( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) ); rTwoRect.mnSrcX = aCropRect.Left(); rTwoRect.mnSrcY = aCropRect.Top(); diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index f66ece92d48b..0ff3ac91f177 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -23,6 +23,7 @@ #include <rtl/ustrbuf.hxx> #include <sal/log.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> #include <comphelper/processfactory.hxx> #include <tools/lineend.hxx> #include <tools/debug.hxx> @@ -233,7 +234,11 @@ bool OutputDevice::ImplDrawRotateText( SalLayout& rSalLayout ) tools::Rectangle aBoundRect; rSalLayout.DrawBase() = DevicePoint( 0, 0 ); rSalLayout.DrawOffset() = Point( 0, 0 ); - if (!rSalLayout.GetBoundRect(aBoundRect)) + if (basegfx::B2DRectangle r; rSalLayout.GetBoundRect(r)) + { + aBoundRect = SalLayout::BoundRect2Rectangle(r); + } + else { // guess vertical text extents if GetBoundRect failed tools::Long nRight = rSalLayout.GetTextWidth(); @@ -887,11 +892,15 @@ tools::Long OutputDevice::GetTextWidth( const OUString& rStr, sal_Int32 nIndex, vcl::text::TextLayoutCache const*const pLayoutCache, SalLayoutGlyphs const*const pSalLayoutCache) const { + double nWidth = GetTextWidthDouble(rStr, nIndex, nLen, pLayoutCache, pSalLayoutCache); + return basegfx::fround<tools::Long>(nWidth); +} - tools::Long nWidth = GetTextArray( rStr, nullptr, nIndex, - nLen, false, pLayoutCache, pSalLayoutCache ); - - return nWidth; +double OutputDevice::GetTextWidthDouble(const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen, + vcl::text::TextLayoutCache const* const pLayoutCache, + SalLayoutGlyphs const* const pSalLayoutCache) const +{ + return GetTextArray(rStr, nullptr, nIndex, nLen, false, pLayoutCache, pSalLayoutCache); } tools::Long OutputDevice::GetTextHeight() const @@ -907,6 +916,16 @@ tools::Long OutputDevice::GetTextHeight() const return nHeight; } +double OutputDevice::GetTextHeightDouble() const +{ + if (!InitFont()) + return 0; + + tools::Long nHeight = mpFontInstance->mnLineHeight + mnEmphasisAscent + mnEmphasisDescent; + + return ImplDevicePixelToLogicHeightDouble(nHeight); +} + float OutputDevice::approximate_char_width() const { //note pango uses "The quick brown fox jumps over the lazy dog." for english @@ -955,7 +974,7 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr, mpAlphaVDev->DrawTextArray( rStartPt, rStr, pDXAry, pKashidaAry, nIndex, nLen, flags ); } -tools::Long OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernArray, +double OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernArray, sal_Int32 nIndex, sal_Int32 nLen, bool bCaret, vcl::text::TextLayoutCache const*const pLayoutCache, SalLayoutGlyphs const*const pSalLayoutCache) const @@ -1043,7 +1062,7 @@ tools::Long OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernAr if (mbMap) { for (int i = 0; i < nLen; ++i) - (*pDXAry)[i] = ImplDevicePixelToLogicWidth( (*pDXAry)[i] * nSubPixelFactor ); + (*pDXAry)[i] = ImplDevicePixelToLogicWidthDouble((*pDXAry)[i] * nSubPixelFactor); } else if (nSubPixelFactor) { @@ -1052,10 +1071,7 @@ tools::Long OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernAr } } - if (mbMap) - nWidth = ImplDevicePixelToLogicWidth( nWidth ); - - return nWidth; + return ImplDevicePixelToLogicWidthDouble(nWidth); #endif /* VCL_FLOAT_DEVICE_PIXEL */ } @@ -2327,8 +2343,21 @@ bool OutputDevice::GetTextBoundRect( tools::Rectangle& rRect, o3tl::span<const sal_Bool> pKashidaAry, const SalLayoutGlyphs* pGlyphs ) const { + basegfx::B2DRectangle aRect; + bool bRet = GetTextBoundRect(aRect, rStr, nBase, nIndex, nLen, nLayoutWidth, pDXAry, + pKashidaAry, pGlyphs); + rRect = SalLayout::BoundRect2Rectangle(aRect); + return bRet; +} + +bool OutputDevice::GetTextBoundRect(basegfx::B2DRectangle& rRect, const OUString& rStr, + sal_Int32 nBase, sal_Int32 nIndex, sal_Int32 nLen, + sal_uLong nLayoutWidth, KernArraySpan pDXAry, + o3tl::span<const sal_Bool> pKashidaAry, + const SalLayoutGlyphs* pGlyphs) const +{ bool bRet = false; - rRect.SetEmpty(); + rRect.reset(); std::unique_ptr<SalLayout> pSalLayout; const Point aPoint; @@ -2352,18 +2381,22 @@ bool OutputDevice::GetTextBoundRect( tools::Rectangle& rRect, nullptr, pGlyphs); if( pSalLayout ) { - tools::Rectangle aPixelRect; + basegfx::B2DRectangle aPixelRect; bRet = pSalLayout->GetBoundRect(aPixelRect); if( bRet ) { - Point aRotatedOfs( mnTextOffX, mnTextOffY ); - DevicePoint aPos = pSalLayout->GetDrawPosition(DevicePoint(nXOffset, 0)); - aRotatedOfs -= Point(aPos.getX(), aPos.getY()); - aPixelRect += aRotatedOfs; + basegfx::B2DPoint aPos = pSalLayout->GetDrawPosition(basegfx::B2DPoint(nXOffset, 0)); + auto m = basegfx::utils::createTranslateB2DHomMatrix(mnTextOffX - aPos.getX(), + mnTextOffY - aPos.getY()); + aPixelRect.transform(m); rRect = PixelToLogic( aPixelRect ); - if( mbMap ) - rRect += Point( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY ); + if (mbMap) + { + m = basegfx::utils::createTranslateB2DHomMatrix(maMapRes.mnMapOfsX, + maMapRes.mnMapOfsY); + rRect.transform(m); + } } } diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx index 7c0f2f55d7ce..fd4cfdb4795f 100644 --- a/vcl/source/outdev/textline.cxx +++ b/vcl/source/outdev/textline.cxx @@ -758,7 +758,7 @@ void OutputDevice::ImplDrawTextLine( tools::Long nX, tools::Long nY, { tools::Long nXAdd = nWidth - nDistX; if( mpFontInstance->mnOrientation ) - nXAdd = FRound( nXAdd * cos( toRadians(mpFontInstance->mnOrientation) ) ); + nXAdd = basegfx::fround<tools::Long>( nXAdd * cos( toRadians(mpFontInstance->mnOrientation) ) ); nX += nXAdd - 1; } @@ -831,7 +831,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, FontStrikeout eStri { const DeviceCoordinate nDY = aPos.getY() - aStartPt.getY(); const double fRad = toRadians(mpFontInstance->mnOrientation); - nDist = FRound( nDist*cos(fRad) - nDY*sin(fRad) ); + nDist = basegfx::fround<tools::Long>(nDist * cos(fRad) - nDY * sin(fRad)); } } diff --git a/vcl/source/outdev/transparent.cxx b/vcl/source/outdev/transparent.cxx index 18c1b8b7d7ca..5e83effc5251 100644 --- a/vcl/source/outdev/transparent.cxx +++ b/vcl/source/outdev/transparent.cxx @@ -341,7 +341,7 @@ void OutputDevice::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly, { ScopedVclPtrInstance< VirtualDevice > aVDev(*this); const Size aDstSz( aDstRect.GetSize() ); - const sal_uInt8 cTrans = static_cast<sal_uInt8>(MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 )); + const sal_uInt8 cTrans = basegfx::fround<sal_uInt8>(nTransparencePercent * 2.55); if( aDstRect.Left() || aDstRect.Top() ) aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() ); diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index eb483eb7f771..dcf696438012 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -328,7 +328,7 @@ void PrintDialog::PrintPreviewWindow::preparePreviewBitmap() const double fRatio(static_cast<double>(maPreviewSize.getWidth()) / static_cast<double>(maPreviewSize.getHeight())); const double fNewWidth(sqrt(static_cast<double>(nPlannedSquarePixels) * fRatio)); const double fNewHeight(sqrt(static_cast<double>(nPlannedSquarePixels) / fRatio)); - const Size aScaledSize(basegfx::fround(fNewWidth), basegfx::fround(fNewHeight)); + const Size aScaledSize(basegfx::fround<tools::Long>(fNewWidth), basegfx::fround<tools::Long>(fNewHeight)); // check if this eventual maximum is already reached // due to having hit the MaxSquarePixels. Due to using @@ -407,7 +407,7 @@ void PrintDialog::PrintPreviewWindow::preparePreviewBitmap() fScale *= fCorrection; } - const Size aScaledSize2(basegfx::fround(fWidth), basegfx::fround(fHeight)); + const Size aScaledSize2(basegfx::fround<tools::Long>(fWidth), basegfx::fround<tools::Long>(fHeight)); pPrerenderVDev->SetOutputSizePixel(aScaledSize2, false); aLogicSize = pPrerenderVDev->PixelToLogic( aScaledSize2, MapMode( MapUnit::Map100thMM ) ); } diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 180edf5cf961..38d7fe1df0f5 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -415,8 +415,8 @@ void Window::SetZoomedPointFont(vcl::RenderContext& rRenderContext, const vcl::F { vcl::Font aFont(rFont); Size aSize = aFont.GetFontSize(); - aSize.setWidth( FRound(double(aSize.Width() * rZoom)) ); - aSize.setHeight( FRound(double(aSize.Height() * rZoom)) ); + aSize.setWidth(basegfx::fround<tools::Long>(double(aSize.Width() * rZoom))); + aSize.setHeight(basegfx::fround<tools::Long>(double(aSize.Height() * rZoom))); aFont.SetFontSize(aSize); SetPointFont(rRenderContext, aFont); } @@ -433,7 +433,7 @@ tools::Long Window::CalcZoom( tools::Long nCalc ) const if ( rZoom.GetNumerator() != rZoom.GetDenominator() ) { double n = double(nCalc * rZoom); - nCalc = FRound( n ); + nCalc = basegfx::fround<tools::Long>(n); } return nCalc; } diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index 64fcb6bfc2bf..bed24e081ee5 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -564,44 +564,6 @@ void FreetypeFont::ApplyGlyphTransform(bool bVertical, FT_Glyph pGlyphFT ) const } } -bool FreetypeFont::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle& rRect, bool bVertical) const -{ - FT_Activate_Size( maSizeFT ); - - FT_Error rc = FT_Load_Glyph(maFaceFT, nID, mnLoadFlags); - - if (rc != FT_Err_Ok) - return false; - - if (mrFontInstance.NeedsArtificialBold()) - FT_GlyphSlot_Embolden(maFaceFT->glyph); - - FT_Glyph pGlyphFT; - rc = FT_Get_Glyph(maFaceFT->glyph, &pGlyphFT); - if (rc != FT_Err_Ok) - return false; - - ApplyGlyphTransform(bVertical, pGlyphFT); - - FT_BBox aBbox; - FT_Glyph_Get_CBox( pGlyphFT, FT_GLYPH_BBOX_PIXELS, &aBbox ); - FT_Done_Glyph( pGlyphFT ); - - tools::Rectangle aRect(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin); - if (mnCos != 0x10000 && mnSin != 0) - { - const double nCos = mnCos / 65536.0; - const double nSin = mnSin / 65536.0; - rRect.SetLeft( nCos*aRect.Left() + nSin*aRect.Top() ); - rRect.SetTop( -nSin*aRect.Left() - nCos*aRect.Top() ); - rRect.SetRight( nCos*aRect.Right() + nSin*aRect.Bottom() ); - rRect.SetBottom( -nSin*aRect.Right() - nCos*aRect.Bottom() ); - } - else - rRect = aRect; - return true; -} - bool FreetypeFont::GetAntialiasAdvice() const { // TODO: also use GASP info diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx index 39b10c78e123..ac3c5e15ab73 100644 --- a/vcl/unx/generic/glyphs/glyphcache.cxx +++ b/vcl/unx/generic/glyphs/glyphcache.cxx @@ -75,14 +75,6 @@ FreetypeFontInstance::~FreetypeFontInstance() { } -bool FreetypeFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, bool bVertical) const -{ - assert(mxFreetypeFont); - if (!mxFreetypeFont) - return false; - return mxFreetypeFont->GetGlyphBoundRect(nId, rRect, bVertical); -} - bool FreetypeFontInstance::GetGlyphOutline(sal_GlyphId nId, basegfx::B2DPolyPolygon& rPoly, bool bVertical) const { assert(mxFreetypeFont); diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 9a470308d6c5..c576294cbf4d 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -39,6 +39,7 @@ #include <sal/log.hxx> #include <rtl/uri.hxx> +#include <basegfx/numeric/ftools.hxx> #include <vcl/settings.hxx> #include <dlfcn.h> @@ -17316,7 +17317,7 @@ private: sal_Int64 fromGtk(double fValue) const { - return FRound(fValue * Power10(get_digits())); + return basegfx::fround64(fValue * Power10(get_digits())); } #if !GTK_CHECK_VERSION(4, 0, 0) diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx index b7d7c03e9995..f8c8c93958d7 100644 --- a/vcl/win/gdi/DWriteTextRenderer.cxx +++ b/vcl/win/gdi/DWriteTextRenderer.cxx @@ -97,6 +97,20 @@ HRESULT checkResult(HRESULT hr, const char* file, size_t line) #endif +// Sets and unsets the needed DirectWrite transform to support the font's rotation. +class WinFontTransformGuard +{ +public: + WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, + const GenericSalLayout& rLayout, const D2D1_POINT_2F& rBaseline, + bool bIsVertical); + ~WinFontTransformGuard(); + +private: + ID2D1RenderTarget* mpRenderTarget; + std::optional<D2D1::Matrix3x2F> moTransform; +}; + } // end anonymous namespace D2DWriteTextOutRenderer::D2DWriteTextOutRenderer(bool bRenderingModeNatural) @@ -218,15 +232,21 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa } const WinFontInstance& rWinFont = static_cast<const WinFontInstance&>(rLayout.GetFont()); - float fHScale = rWinFont.getHScale(); float lfEmHeight = 0; IDWriteFontFace* pFontFace = GetDWriteFace(rWinFont, &lfEmHeight); if (!pFontFace) return false; - tools::Rectangle bounds; - bool succeeded = rLayout.GetBoundRect(bounds); + auto [succeeded, bounds] = [&rLayout]() + { + basegfx::B2DRectangle r; + bool result = rLayout.GetBoundRect(r); + if (result) + r.grow(1); // plus 1 pixel to the tight range + return std::make_pair(result, SalLayout::BoundRect2Rectangle(r)); + }(); + if (succeeded) { hr = BindDC(hDC, bounds); // Update the bounding rect. @@ -251,11 +271,11 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart)) { UINT16 glyphIndices[] = { static_cast<UINT16>(pGlyph->glyphId()) }; - FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->newWidth()) / fHScale }; + FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->newWidth()) }; DWRITE_GLYPH_OFFSET glyphOffsets[] = { { 0.0f, 0.0f }, }; - D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.getX() - bounds.Left()) / fHScale, + D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.getX() - bounds.Left()), static_cast<FLOAT>(aPos.getY() - bounds.Top()) }; - WinFontTransformGuard aTransformGuard(mpRT, fHScale, rLayout, baseline, pGlyph->IsVertical()); + WinFontTransformGuard aTransformGuard(mpRT, rLayout, baseline, pGlyph->IsVertical()); DWRITE_GLYPH_RUN glyphs = { pFontFace, lfEmHeight, @@ -306,36 +326,46 @@ IDWriteFontFace* D2DWriteTextOutRenderer::GetDWriteFace(const WinFontInstance& r return pFontFace; } -WinFontTransformGuard::WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, float fHScale, +WinFontTransformGuard::WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, const GenericSalLayout& rLayout, const D2D1_POINT_2F& rBaseline, bool bIsVertical) : mpRenderTarget(pRenderTarget) { - pRenderTarget->GetTransform(&maTransform); - D2D1::Matrix3x2F aTransform = maTransform; - if (fHScale != 1.0f) + const float hscale = [&font = rLayout.GetFont()] { - aTransform - = aTransform * D2D1::Matrix3x2F::Scale(D2D1::Size(fHScale, 1.0f), D2D1::Point2F(0, 0)); - } + const auto& rPattern = font.GetFontSelectPattern(); + if (!rPattern.mnHeight || !rPattern.mnWidth) + return 1.0; + return rPattern.mnWidth * font.GetAverageWidthFactor() / rPattern.mnHeight; + }(); Degree10 angle = rLayout.GetOrientation(); - if (bIsVertical) angle += 900_deg10; - if (angle) + if (hscale != 1.0f || angle) { + D2D1::Matrix3x2F aTransform; + pRenderTarget->GetTransform(&aTransform); + moTransform = aTransform; + + if (hscale != 1.0f) // basegfx::fTools::equal is useless with float + aTransform = aTransform * D2D1::Matrix3x2F::Scale(hscale, 1.0f, { 0, 0 }); + // DWrite angle is in clockwise degrees, our orientation is in counter-clockwise 10th // degrees. - aTransform = aTransform - * D2D1::Matrix3x2F::Rotation( - -toDegrees(angle), rBaseline); + if (angle) + aTransform = aTransform * D2D1::Matrix3x2F::Rotation(-toDegrees(angle), rBaseline); + + mpRenderTarget->SetTransform(aTransform); } - mpRenderTarget->SetTransform(aTransform); } -WinFontTransformGuard::~WinFontTransformGuard() { mpRenderTarget->SetTransform(maTransform); } +WinFontTransformGuard::~WinFontTransformGuard() +{ + if (moTransform) + mpRenderTarget->SetTransform(*moTransform); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index 81d41cf41d33..cde2faf85fc5 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -2656,8 +2656,8 @@ bool WinSalGraphicsImpl::drawTransformedBitmap( if(nSrcWidth && nSrcHeight) { - const tools::Long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength())); - const tools::Long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength())); + const tools::Long nDestWidth(basegfx::fround<tools::Long>(basegfx::B2DVector(rX - rNull).getLength())); + const tools::Long nDestHeight(basegfx::fround<tools::Long>(basegfx::B2DVector(rY - rNull).getLength())); if(nDestWidth && nDestHeight) { diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 196932982c28..d5f41e2e8819 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -1156,59 +1156,6 @@ void WinSalGraphics::ClearDevFontCache() ImplReleaseTempFonts(*GetSalData(), false); } -bool WinFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, tools::Rectangle& rRect, bool bIsVertical) const -{ - assert(m_pGraphics); - HDC hDC = m_pGraphics->getHDC(); - const HFONT hOrigFont = static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)); - const HFONT hFont = GetHFONT(); - if (hFont != hOrigFont) - SelectObject(hDC, hFont); - - const ::comphelper::ScopeGuard aFontRestoreScopeGuard([hFont, hOrigFont, hDC]() - { if (hFont != hOrigFont) SelectObject(hDC, hOrigFont); }); - const float fFontScale = GetScale(); - - // use unity matrix - MAT2 aMat; - const vcl::font::FontSelectPattern& rFSD = GetFontSelectPattern(); - - // Use identity matrix for fonts requested in horizontal - // writing (LTR or RTL), or rotated glyphs in vertical writing. - if (!rFSD.mbVertical || !bIsVertical) - { - aMat.eM11 = aMat.eM22 = FixedFromDouble(1.0); - aMat.eM12 = aMat.eM21 = FixedFromDouble(0.0); - } - else - { - constexpr double nCos = 0.0; - constexpr double nSin = 1.0; - aMat.eM11 = FixedFromDouble(nCos); - aMat.eM12 = FixedFromDouble(nSin); - aMat.eM21 = FixedFromDouble(-nSin); - aMat.eM22 = FixedFromDouble(nCos); - } - - UINT nGGOFlags = GGO_METRICS; - nGGOFlags |= GGO_GLYPH_INDEX; - - GLYPHMETRICS aGM; - aGM.gmptGlyphOrigin.x = aGM.gmptGlyphOrigin.y = 0; - aGM.gmBlackBoxX = aGM.gmBlackBoxY = 0; - DWORD nSize = ::GetGlyphOutlineW(hDC, nId, nGGOFlags, &aGM, 0, nullptr, &aMat); - if (nSize == GDI_ERROR) - return false; - - rRect = tools::Rectangle( Point( +aGM.gmptGlyphOrigin.x, -aGM.gmptGlyphOrigin.y ), - Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) ); - rRect.SetLeft(static_cast<int>( fFontScale * rRect.Left() )); - rRect.SetRight(static_cast<int>( fFontScale * rRect.Right() ) + 1); - rRect.SetTop(static_cast<int>( fFontScale * rRect.Top() )); - rRect.SetBottom(static_cast<int>( fFontScale * rRect.Bottom() ) + 1); - return true; -} - bool WinFontInstance::GetGlyphOutline(sal_GlyphId nId, basegfx::B2DPolyPolygon& rB2DPolyPoly, bool) const { rB2DPolyPoly.clear(); diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 371bdeb9642e..f7ac7f5ff851 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -147,24 +147,6 @@ WinFontInstance::~WinFontInstance() ::DeleteFont(m_hFont); } -bool WinFontInstance::hasHScale() const -{ - const vcl::font::FontSelectPattern& rPattern = GetFontSelectPattern(); - int nHeight(rPattern.mnHeight); - int nWidth(rPattern.mnWidth ? rPattern.mnWidth * GetAverageWidthFactor() : nHeight); - return nWidth != nHeight; -} - -float WinFontInstance::getHScale() const -{ - const vcl::font::FontSelectPattern& rPattern = GetFontSelectPattern(); - int nHeight(rPattern.mnHeight); - if (!nHeight) - return 1.0; - float nWidth(rPattern.mnWidth ? rPattern.mnWidth * GetAverageWidthFactor() : nHeight); - return nWidth / nHeight; -} - void WinFontInstance::ImplInitHbFont(hb_font_t* /*pHbFont*/) { assert(m_pGraphics); diff --git a/vcl/workben/listglyphs.cxx b/vcl/workben/listglyphs.cxx index def2ff818122..341006d433dd 100644 --- a/vcl/workben/listglyphs.cxx +++ b/vcl/workben/listglyphs.cxx @@ -120,7 +120,7 @@ int ListGlyphs::Main() nChar = pCharMap->GetNextChar(nChar)) { auto nGlyphIndex = pFontInstance->GetGlyphIndex(nChar); - tools::Rectangle aGlyphBounds; + basegfx::B2DRectangle aGlyphBounds; pFontInstance->GetGlyphBoundRect(nGlyphIndex, aGlyphBounds, false); std::cout << "Codepoint: " << pFontFace->GetGlyphName(nGlyphIndex) << "; glyph bounds: " << aGlyphBounds << "\n"; diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx index 0f5b711a021a..6b5bdae55acf 100644 --- a/xmloff/source/draw/shapeexport.cxx +++ b/xmloff/source/draw/shapeexport.cxx @@ -1558,7 +1558,7 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple cons } mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, - FRound(aTRScale.getX())); + basegfx::fround(aTRScale.getX())); aStr = sStringBuffer.makeStringAndClear(); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr); @@ -1576,7 +1576,7 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple cons } mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, - FRound(aTRScale.getY())); + basegfx::fround(aTRScale.getY())); aStr = sStringBuffer.makeStringAndClear(); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr); @@ -1611,7 +1611,7 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple cons { // svg: x mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, - FRound(rTRTranslate.getX())); + basegfx::fround(rTRTranslate.getX())); aStr = sStringBuffer.makeStringAndClear(); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr); } @@ -1620,7 +1620,7 @@ void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple cons { // svg: y mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, - FRound(rTRTranslate.getY())); + basegfx::fround(rTRTranslate.getY())); aStr = sStringBuffer.makeStringAndClear(); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr); } @@ -2169,7 +2169,8 @@ void XMLShapeExport::ImpExportLineShape( ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint); // create base position - awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY())); + awt::Point aBasePosition(basegfx::fround(aTRTranslate.getX()), + basegfx::fround(aTRTranslate.getY())); if (xPropSet->getPropertySetInfo()->hasPropertyByName("Geometry")) { @@ -2327,7 +2328,8 @@ void XMLShapeExport::ImpExportPolygonShape( ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures); // create and export ViewBox - awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY())); + awt::Size aSize(basegfx::fround<tools::Long>(aTRScale.getX()), + basegfx::fround<tools::Long>(aTRScale.getY())); SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); @@ -2820,7 +2822,8 @@ void XMLShapeExport::ImpExportConnectorShape( fTRRotate, aTRTranslate, pRefPoint); // fdo#49678: create and export ViewBox - awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY())); + awt::Size aSize(basegfx::fround<tools::Long>(aTRScale.getX()), + basegfx::fround<tools::Long>(aTRScale.getY())); SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height); mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); |