diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-01-06 20:35:08 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-01-07 09:26:47 +0100 |
commit | bf540873f5e258452fed5006f65a403c95e7872a (patch) | |
tree | 027f723b6a0477cd2ae8c49aaebbd30339b26d9b /sw/source/core/text/inftxt.cxx | |
parent | ecb5130e16898c0d2485e99564c57882b5ef25b0 (diff) |
sw: add rendering for semi-transparent text
I considered passing the text color's alpha value down to the various
vcl backends, but this would need changes everywhere (cairo, opengl, pdf
export, etc). It's much easier to go via DrawTransparent(), that's how
semi-transparent text in Draw/Impress already works.
Change-Id: I96f15e6764c3c88ba67dd72dc8708414d7c6050c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86294
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw/source/core/text/inftxt.cxx')
-rw-r--r-- | sw/source/core/text/inftxt.cxx | 75 |
1 files changed, 75 insertions, 0 deletions
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 |