diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2019-06-28 00:03:19 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2019-07-01 04:49:07 +0200 |
commit | bfc19d77cb8db445f1c6123347c19a4c0c6a6cf8 (patch) | |
tree | d5deaaa44975838dec487d977d064c37080cf40e /vcl | |
parent | 45a2eecfee472d8822130a90999b46ad371dee95 (diff) |
Improve the looks of a wave line by draw it with bezier curves
This adds drawing the wave line (typically used to underline the
wrongly spelled words) with bezier curves. Previously the wave
lines were drawn with drawing pixels, which didn't look that good,
especially on HiDPI display, so the looks of wave lines now is
therefor much better.
The creation of the wave line as a polygon has been added to the
basegfx module, so it can be reused if needed.
In addition, everytime we draw the waveline, we have to enable
antialiasing, to have a much better quality of the curves. By
default the antialiasing is disabled for some reason.
This also adds ScopedStates.hxx file which currently includes
ScopedAntialiasing, which sets the antialiasing to a certain state
for the time the object is in scope, and then sets it back to the
original state.
Change-Id: I4b866fc5d69725eb7f6f78a1acf4176b1205aa73
Reviewed-on: https://gerrit.libreoffice.org/74810
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/outdev/textline.cxx | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx index 67feda6c4030..4290044edeb1 100644 --- a/vcl/source/outdev/textline.cxx +++ b/vcl/source/outdev/textline.cxx @@ -34,6 +34,10 @@ #include <outdata.hxx> #include <impglyphitem.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <basegfx/polygon/WaveLine.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> + #define UNDERLINE_LAST LINESTYLE_BOLDWAVE #define STRIKEOUT_LAST STRIKEOUT_X @@ -936,7 +940,7 @@ void OutputDevice::DrawTextLine( const Point& rPos, long nWidth, mpAlphaVDev->DrawTextLine( rPos, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); } -void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos, long nLineWidth ) +void OutputDevice::DrawWaveLine(const Point& rStartPos, const Point& rEndPos, long nLineWidth) { assert(!is_double_buffered_window()); @@ -956,30 +960,29 @@ void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos, l if (!InitFont()) return; - Point aStartPt = ImplLogicToDevicePixel( rStartPos ); - Point aEndPt = ImplLogicToDevicePixel( rEndPos ); - long nStartX = aStartPt.X(); - long nStartY = aStartPt.Y(); - long nEndX = aEndPt.X(); - long nEndY = aEndPt.Y(); - short nOrientation = 0; + Point aStartPt = ImplLogicToDevicePixel(rStartPos); + Point aEndPt = ImplLogicToDevicePixel(rEndPos); + + long nStartX = aStartPt.X(); + long nStartY = aStartPt.Y(); + long nEndX = aEndPt.X(); + long nEndY = aEndPt.Y(); + double fOrientation = 0.0; - // when rotated - if ( (nStartY != nEndY) || (nStartX > nEndX) ) + // handle rotation + if (nStartY != nEndY || nStartX > nEndX) { - long nDX = nEndX - nStartX; - double nO = atan2( -nEndY + nStartY, ((nDX == 0) ? 0.000000001 : nDX) ); - nO /= F_PI1800; - nOrientation = static_cast<short>(nO); - aStartPt.RotateAround( nEndX, nEndY, -nOrientation ); + long nLengthX = nEndX - nStartX; + fOrientation = std::atan2(nStartY - nEndY, (nLengthX == 0 ? 0.000000001 : nLengthX)); + fOrientation /= F_PI180; + // un-rotate the end point + aStartPt.RotateAround(nEndX, nEndY, -fOrientation * 10.0); } long nWaveHeight = 3; - nStartY++; - nEndY++; + // Handle HiDPI float fScaleFactor = GetDPIScaleFactor(); - if (fScaleFactor > 1.0f) { nWaveHeight *= fScaleFactor; @@ -995,14 +998,23 @@ void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos, l // #109280# make sure the waveline does not exceed the descent to avoid paint problems LogicalFontInstance* pFontInstance = mpFontInstance.get(); - if( nWaveHeight > pFontInstance->mxFontMetric->GetWavelineUnderlineSize() ) + if (nWaveHeight > pFontInstance->mxFontMetric->GetWavelineUnderlineSize()) { nWaveHeight = pFontInstance->mxFontMetric->GetWavelineUnderlineSize(); nLineWidth = 1; } - ImplDrawWaveLine(nStartX, nStartY, 0, 0, - nEndX-nStartX, nWaveHeight, - nLineWidth, nOrientation, GetLineColor()); + + const basegfx::B2DRectangle aWaveLineRectangle(nStartX, nStartY, nEndX, nEndY + nWaveHeight); + const basegfx::B2DPolygon aWaveLinePolygon = basegfx::createWaveLinePolygon(aWaveLineRectangle); + const basegfx::B2DHomMatrix aRotationMatrix = basegfx::utils::createRotateAroundPoint(nStartX, nStartY, basegfx::deg2rad(-fOrientation)); + const basegfx::B2DVector aLineWidth(nLineWidth, nLineWidth); + const bool bPixelSnapHairline(mnAntialiasing & AntialiasingFlags::PixelSnapHairline); + + mpGraphics->SetLineColor(GetLineColor()); + mpGraphics->DrawPolyLine( + aRotationMatrix, aWaveLinePolygon, 0.0, aLineWidth, + basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, + basegfx::deg2rad(15.0), bPixelSnapHairline, this); if( mpAlphaVDev ) mpAlphaVDev->DrawWaveLine( rStartPos, rEndPos, nLineWidth ); |