tdf#74702 vcl: make helper funcs for ImplDrawWaveLine() and ImplDrawWavePixel()
Unit tests written for Printer and OutputDevice, note that I might have
uncovered a bug.
Change-Id: Ic8e6e02ce0df349fc6fb6a3334105c1e6dfa3f36
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113563
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 95df09d..e2a4b4d1 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1077,6 +1077,11 @@
static
SAL_DLLPRIVATE tools::Long ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo, tools::Long nWidth, const OUString& rStr, DrawTextFlags nStyle, const vcl::ITextLayout& _rLayout );
SAL_DLLPRIVATE float approximate_char_width() const;
virtual bool shouldDrawWavePixelAsRect(tools::Long nLineWidth) const;
virtual void SetWaveLineColors(Color const& rColor, tools::Long nLineWidth);
virtual Size GetWaveLineSize(tools::Long nLineWidth) const;
private:
SAL_DLLPRIVATE void ImplInitTextColor();
@@ -1084,8 +1089,8 @@
SAL_DLLPRIVATE void ImplDrawSpecialText( SalLayout& );
SAL_DLLPRIVATE void ImplDrawTextRect( tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight );
SAL_DLLPRIVATE static void ImplDrawWavePixel( tools::Long nOriginX, tools::Long nOriginY, tools::Long nCurX, tools::Long nCurY, Degree10 nOrientation, SalGraphics* pGraphics, const OutputDevice& rOutDev,
bool bDrawPixAsRect, tools::Long nPixWidth, tools::Long nPixHeight );
SAL_DLLPRIVATE void ImplDrawWavePixel( tools::Long nOriginX, tools::Long nOriginY, tools::Long nCurX, tools::Long nCurY, tools::Long nWidth, Degree10 nOrientation, SalGraphics* pGraphics, const OutputDevice& rOutDev, tools::Long nPixWidth, tools::Long nPixHeight );
SAL_DLLPRIVATE void ImplDrawWaveLine( tools::Long nBaseX, tools::Long nBaseY, tools::Long nStartX, tools::Long nStartY, tools::Long nWidth, tools::Long nHeight, tools::Long nLineWidth, Degree10 nOrientation, const Color& rColor );
SAL_DLLPRIVATE void ImplDrawWaveTextLine( tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove );
SAL_DLLPRIVATE void ImplDrawStraightTextLine( tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove );
diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx
index 1ffce12..b4db139 100644
--- a/include/vcl/print.hxx
+++ b/include/vcl/print.hxx
@@ -248,6 +248,10 @@
virtual void SetFontOrientation( LogicalFontInstance* const pFontInstance ) const override;
bool shouldDrawWavePixelAsRect(tools::Long) const override { return true; }
void SetWaveLineColors(Color const& rColor, tools::Long) override;
Size GetWaveLineSize(tools::Long nLineWidth) const override;
public:
Printer();
Printer( const JobSetup& rJobSetup );
diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx
index bc70ba1..d9aa34a 100644
--- a/vcl/qa/cppunit/outdev.cxx
+++ b/vcl/qa/cppunit/outdev.cxx
@@ -49,6 +49,8 @@
void testTransparentFillColor();
void testFillColor();
void testSystemTextColor();
void testShouldDrawWavePixelAsRect();
void testGetWaveLineSize();
CPPUNIT_TEST_SUITE(VclOutdevTest);
CPPUNIT_TEST(testVirtualDevice);
@@ -71,6 +73,8 @@
CPPUNIT_TEST(testTransparentFillColor);
CPPUNIT_TEST(testFillColor);
CPPUNIT_TEST(testSystemTextColor);
CPPUNIT_TEST(testShouldDrawWavePixelAsRect);
CPPUNIT_TEST(testGetWaveLineSize);
CPPUNIT_TEST_SUITE_END();
};
@@ -549,6 +553,78 @@
}
}
namespace
{
class WaveLineTester : public OutputDevice
{
public:
WaveLineTester()
: OutputDevice(OUTDEV_VIRDEV)
{
}
bool AcquireGraphics() const { return true; }
void ReleaseGraphics(bool) {}
bool UsePolyPolygonForComplexGradient() { return false; }
bool testShouldDrawWavePixelAsRect(tools::Long nLineWidth)
{
return shouldDrawWavePixelAsRect(nLineWidth);
}
Size testGetWaveLineSize(tools::Long nLineWidth) { return GetWaveLineSize(nLineWidth); }
};
class WaveLineTesterPrinter : public Printer
{
public:
WaveLineTesterPrinter() {}
bool AcquireGraphics() const { return true; }
void ReleaseGraphics(bool) {}
bool UsePolyPolygonForComplexGradient() { return false; }
Size testGetWaveLineSize(tools::Long nLineWidth) { return GetWaveLineSize(nLineWidth); }
};
}
void VclOutdevTest::testShouldDrawWavePixelAsRect()
{
ScopedVclPtrInstance<WaveLineTester> pTestOutDev;
CPPUNIT_ASSERT(!pTestOutDev->testShouldDrawWavePixelAsRect(0));
CPPUNIT_ASSERT(!pTestOutDev->testShouldDrawWavePixelAsRect(1));
CPPUNIT_ASSERT(pTestOutDev->testShouldDrawWavePixelAsRect(10));
}
void VclOutdevTest::testGetWaveLineSize()
{
{
ScopedVclPtrInstance<WaveLineTester> pTestOutDev;
pTestOutDev->SetDPIX(96);
pTestOutDev->SetDPIY(96);
CPPUNIT_ASSERT_EQUAL(Size(1, 1), pTestOutDev->testGetWaveLineSize(0));
CPPUNIT_ASSERT_EQUAL(Size(1, 1), pTestOutDev->testGetWaveLineSize(1));
CPPUNIT_ASSERT_EQUAL(Size(10, 10), pTestOutDev->testGetWaveLineSize(10));
}
{
ScopedVclPtrInstance<WaveLineTesterPrinter> pTestOutDev;
pTestOutDev->SetDPIX(96);
pTestOutDev->SetDPIY(96);
CPPUNIT_ASSERT_EQUAL(Size(0, 0), pTestOutDev->testGetWaveLineSize(0));
CPPUNIT_ASSERT_EQUAL(Size(1, 1), pTestOutDev->testGetWaveLineSize(1));
CPPUNIT_ASSERT_EQUAL(Size(10, 10), pTestOutDev->testGetWaveLineSize(10));
}
}
CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
index 593744b..6b6b070 100644
--- a/vcl/source/gdi/print.cxx
+++ b/vcl/source/gdi/print.cxx
@@ -1750,6 +1750,25 @@
return aInfo;
}
void Printer::SetWaveLineColors(Color const& rColor, tools::Long)
{
if (mbLineColor || mbInitLineColor)
{
mpGraphics->SetLineColor();
mbInitLineColor = true;
}
mpGraphics->SetFillColor(rColor);
mbInitFillColor = true;
}
Size Printer::GetWaveLineSize(tools::Long nLineWidth) const
{
// FIXME - do we have a bug here? If the linewidth is 0, then we will return
// Size(0, 0) - is this correct?
return Size(nLineWidth, ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY);
}
void Printer::SetSystemTextColor(SystemTextColorFlags, bool)
{
SetTextColor(COL_BLACK);
diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx
index 2ce85be..9fd8254 100644
--- a/vcl/source/outdev/textline.cxx
+++ b/vcl/source/outdev/textline.cxx
@@ -113,21 +113,20 @@
void OutputDevice::ImplDrawWavePixel( tools::Long nOriginX, tools::Long nOriginY,
tools::Long nCurX, tools::Long nCurY,
tools::Long nWidth,
Degree10 nOrientation,
SalGraphics* pGraphics,
const OutputDevice& rOutDev,
bool bDrawPixAsRect,
tools::Long nPixWidth, tools::Long nPixHeight )
{
if ( nOrientation )
if (nOrientation)
{
Point aPoint( nOriginX, nOriginY );
aPoint.RotateAround( nCurX, nCurY, nOrientation );
}
if ( bDrawPixAsRect )
if (shouldDrawWavePixelAsRect(nWidth))
{
pGraphics->DrawRect( nCurX, nCurY, nPixWidth, nPixHeight, rOutDev );
}
else
@@ -136,6 +135,43 @@
}
}
bool OutputDevice::shouldDrawWavePixelAsRect(tools::Long nLineWidth) const
{
if (nLineWidth > 1)
return true;
return false;
}
void OutputDevice::SetWaveLineColors(Color const& rColor, tools::Long nLineWidth)
{
// On printers that output pixel via DrawRect()
if (nLineWidth > 1)
{
if (mbLineColor || mbInitLineColor)
{
mpGraphics->SetLineColor();
mbInitLineColor = true;
}
mpGraphics->SetFillColor( rColor );
mbInitFillColor = true;
}
else
{
mpGraphics->SetLineColor( rColor );
mbInitLineColor = true;
}
}
Size OutputDevice::GetWaveLineSize(tools::Long nLineWidth) const
{
if (nLineWidth > 1)
return Size(nLineWidth, ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY);
return Size(1, 1);
}
void OutputDevice::ImplDrawWaveLine( tools::Long nBaseX, tools::Long nBaseY,
tools::Long nDistX, tools::Long nDistY,
tools::Long nWidth, tools::Long nHeight,
@@ -172,39 +208,20 @@
tools::Long nDiffY = nHeight-1;
tools::Long nCount = nWidth;
tools::Long nOffY = -1;
tools::Long nPixWidth;
tools::Long nPixHeight;
bool bDrawPixAsRect;
// On printers that output pixel via DrawRect()
if ( (GetOutDevType() == OUTDEV_PRINTER) || (nLineWidth > 1) )
{
if ( mbLineColor || mbInitLineColor )
{
mpGraphics->SetLineColor();
mbInitLineColor = true;
}
mpGraphics->SetFillColor( rColor );
mbInitFillColor = true;
bDrawPixAsRect = true;
nPixWidth = nLineWidth;
nPixHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY;
}
else
{
mpGraphics->SetLineColor( rColor );
mbInitLineColor = true;
nPixWidth = 1;
nPixHeight = 1;
bDrawPixAsRect = false;
}
SetWaveLineColors(rColor, nLineWidth);
Size aSize(GetWaveLineSize(nLineWidth));
tools::Long nPixWidth = aSize.Width();
tools::Long nPixHeight = aSize.Height();
if ( !nDiffY )
{
while ( nWidth )
{
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nLineWidth, nOrientation,
mpGraphics, *this,
bDrawPixAsRect, nPixWidth, nPixHeight );
nPixWidth, nPixHeight );
nCurX++;
nWidth--;
}
@@ -217,17 +234,17 @@
{
for( tools::Long i = nDiffY; i; --i )
{
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nLineWidth, nOrientation,
mpGraphics, *this,
bDrawPixAsRect, nPixWidth, nPixHeight );
nPixWidth, nPixHeight );
nCurX++;
nCurY += nOffY;
}
for( tools::Long i = nDiffX; i; --i )
{
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nLineWidth, nOrientation,
mpGraphics, *this,
bDrawPixAsRect, nPixWidth, nPixHeight );
nPixWidth, nPixHeight );
nCurX++;
}
nOffY = -nOffY;
@@ -237,18 +254,18 @@
{
for( tools::Long i = nDiffY; i && nFreq; --i, --nFreq )
{
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nLineWidth, nOrientation,
mpGraphics, *this,
bDrawPixAsRect, nPixWidth, nPixHeight );
nPixWidth, nPixHeight );
nCurX++;
nCurY += nOffY;
}
for( tools::Long i = nDiffX; i && nFreq; --i, --nFreq )
{
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nLineWidth, nOrientation,
mpGraphics, *this,
bDrawPixAsRect, nPixWidth, nPixHeight );
nPixWidth, nPixHeight );
nCurX++;
}
}