summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/CppunitTest_sw_core_text.mk1
-rw-r--r--sw/qa/core/text/text.cxx32
-rw-r--r--sw/source/core/text/inftxt.cxx75
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