diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/CppunitTest_sw_core_text.mk | 1 | ||||
-rw-r--r-- | sw/qa/core/text/text.cxx | 32 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.cxx | 75 |
3 files changed, 108 insertions, 0 deletions
diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk index 9fe4fadbf357..cb901fde29f2 100644 --- a/sw/CppunitTest_sw_core_text.mk +++ b/sw/CppunitTest_sw_core_text.mk @@ -27,6 +27,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \ test \ unotest \ utl \ + vcl \ )) $(eval $(call gb_CppunitTest_use_externals,sw_core_text,\ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 8074cbc9f45e..4e6d4fcdb14e 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -8,6 +8,9 @@ */ #include <swmodeltestbase.hxx> + +#include <vcl/gdimtf.hxx> + #include <wrtsh.hxx> static char const DATA_DIRECTORY[] = "/sw/qa/core/text/data/"; @@ -46,6 +49,35 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testFootnoteConnect) pWrtShell->DelLeft(); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testSemiTransparentText) +{ + // Create an in-memory empty document. + loadURL("private:factory/swriter", nullptr); + + // Set text to half-transparent and type a character. + uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT(xParagraph.is()); + sal_Int16 nTransparence = 50; + xParagraph->setPropertyValue("CharTransparence", uno::makeAny(nTransparence)); + uno::Reference<text::XTextRange> xTextRange(xParagraph, uno::UNO_QUERY); + CPPUNIT_ASSERT(xTextRange.is()); + xTextRange->setString("x"); + + // Render the document to a metafile. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDocShell* pDocShell = pTextDoc->GetDocShell(); + CPPUNIT_ASSERT(pDocShell); + std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile(); + CPPUNIT_ASSERT(xMetaFile); + + // Make sure that DrawTransparent() was used during rendering. + MetafileXmlDump dumper; + xmlDocPtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + CPPUNIT_ASSERT(pXmlDoc); + assertXPath(pXmlDoc, "//floattransparent"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index 9fc9116fe1e4..efe9d54e1222 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -64,6 +64,9 @@ #include <EnhancedPDFExportHelper.hxx> #include <docsh.hxx> #include <strings.hrc> +#include <vcl/gdimtf.hxx> +#include <vcl/virdev.hxx> +#include <vcl/gradient.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::linguistic2; @@ -552,6 +555,71 @@ static bool lcl_IsDarkBackground( const SwTextPaintInfo& rInf ) return pCol->IsDark(); } +namespace +{ +/** + * Context class that captures the draw operations on rDrawInf's output device for transparency + * purposes. + */ +class SwTransparentTextGuard +{ + ScopedVclPtrInstance<VirtualDevice> m_aContentVDev; + GDIMetaFile m_aContentMetafile; + MapMode m_aNewMapMode; + SwRect m_aPorRect; + SwTextPaintInfo& m_rPaintInf; + SwDrawTextInfo& m_rDrawInf; + +public: + SwTransparentTextGuard(const SwLinePortion& rPor, SwTextPaintInfo& rPaintInf, + SwDrawTextInfo& rDrawInf); + ~SwTransparentTextGuard(); +}; + +SwTransparentTextGuard::SwTransparentTextGuard(const SwLinePortion& rPor, + SwTextPaintInfo& rPaintInf, SwDrawTextInfo& rDrawInf) + : m_aNewMapMode(rPaintInf.GetOut()->GetMapMode()) + , m_rPaintInf(rPaintInf) + , m_rDrawInf(rDrawInf) +{ + rPaintInf.CalcRect(rPor, &m_aPorRect); + rDrawInf.SetOut(*m_aContentVDev); + m_aContentVDev->SetMapMode(rPaintInf.GetOut()->GetMapMode()); + m_aContentMetafile.Record(m_aContentVDev.get()); + m_aContentVDev->SetLineColor(rPaintInf.GetOut()->GetLineColor()); + m_aContentVDev->SetFillColor(rPaintInf.GetOut()->GetFillColor()); + m_aContentVDev->SetFont(rPaintInf.GetOut()->GetFont()); + m_aContentVDev->SetDrawMode(rPaintInf.GetOut()->GetDrawMode()); + m_aContentVDev->SetSettings(rPaintInf.GetOut()->GetSettings()); + m_aContentVDev->SetRefPoint(rPaintInf.GetOut()->GetRefPoint()); +} + +SwTransparentTextGuard::~SwTransparentTextGuard() +{ + m_aContentMetafile.Stop(); + m_aContentMetafile.WindStart(); + m_aNewMapMode.SetOrigin(m_aPorRect.TopLeft()); + m_aContentMetafile.SetPrefMapMode(m_aNewMapMode); + m_aContentMetafile.SetPrefSize(m_aPorRect.SSize()); + m_rDrawInf.SetOut(*m_rPaintInf.GetOut()); + Gradient aVCLGradient; + sal_uInt8 nTransPercentVcl = m_rPaintInf.GetFont()->GetColor().GetTransparency(); + const Color aTransColor(nTransPercentVcl, nTransPercentVcl, nTransPercentVcl); + aVCLGradient.SetStyle(GradientStyle::Linear); + aVCLGradient.SetStartColor(aTransColor); + aVCLGradient.SetEndColor(aTransColor); + aVCLGradient.SetAngle(0); + aVCLGradient.SetBorder(0); + aVCLGradient.SetOfsX(0); + aVCLGradient.SetOfsY(0); + aVCLGradient.SetStartIntensity(100); + aVCLGradient.SetEndIntensity(100); + aVCLGradient.SetSteps(2); + m_rPaintInf.GetOut()->DrawTransparent(m_aContentMetafile, m_aPorRect.TopLeft(), + m_aPorRect.SSize(), aVCLGradient); +} +} + void SwTextPaintInfo::DrawText_( const OUString &rText, const SwLinePortion &rPor, TextFrameIndex const nStart, TextFrameIndex const nLength, const bool bKern, const bool bWrong, @@ -678,6 +746,13 @@ void SwTextPaintInfo::DrawText_( const OUString &rText, const SwLinePortion &rPo aFontPos.setY( 0 ); } + // Handle semi-transparent text if necessary. + std::unique_ptr<SwTransparentTextGuard> pTransparentText; + if (m_pFnt->GetColor() != COL_AUTO && m_pFnt->GetColor().GetTransparency() != 0) + { + pTransparentText.reset(new SwTransparentTextGuard(rPor, *this, aDrawInf)); + } + if( GetTextFly().IsOn() ) { // aPos needs to be the TopLeft, because we cannot calculate the |