diff options
-rw-r--r-- | editeng/source/items/svxfont.cxx | 105 | ||||
-rw-r--r-- | include/editeng/smallcaps.hxx | 58 | ||||
-rw-r--r-- | include/editeng/svxfont.hxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdotextdecomposition.cxx | 322 |
4 files changed, 333 insertions, 154 deletions
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx index 544d80c7d4a9..08bae76685ed 100644 --- a/editeng/source/items/svxfont.cxx +++ b/editeng/source/items/svxfont.cxx @@ -29,6 +29,7 @@ #include <unotools/charclass.hxx> #include <com/sun/star/i18n/KCharacterType.hpp> #include <editeng/escapementitem.hxx> +#include <editeng/smallcaps.hxx> #include <sal/log.hxx> #include <limits> @@ -220,40 +221,6 @@ OUString SvxFont::CalcCaseMap(const OUString &rTxt) const return aTxt; } -/************************************************************************* - * class SvxDoCapitals - * The virtual Method Do si called by SvxFont::DoOnCapitals alternately - * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills - * this method with life. - *************************************************************************/ - -class SvxDoCapitals -{ -protected: - VclPtr<OutputDevice> pOut; - const OUString &rTxt; - const sal_Int32 nIdx; - const sal_Int32 nLen; - -public: - SvxDoCapitals( OutputDevice *_pOut, const OUString &_rTxt, - const sal_Int32 _nIdx, const sal_Int32 _nLen ) - : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen) - { } - - virtual ~SvxDoCapitals() {} - - virtual void DoSpace( const bool bDraw ); - virtual void SetSpace(); - virtual void Do( const OUString &rTxt, - const sal_Int32 nIdx, const sal_Int32 nLen, - const bool bUpper ) = 0; - - const OUString &GetTxt() const { return rTxt; } - sal_Int32 GetIdx() const { return nIdx; } - sal_Int32 GetLen() const { return nLen; } -}; - void SvxDoCapitals::DoSpace( const bool /*bDraw*/ ) { } void SvxDoCapitals::SetSpace() { } @@ -501,8 +468,13 @@ Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, if ( !IsCaseMap() ) aTxtSize.setWidth( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ) ); else - aTxtSize.setWidth( GetTextArray( pOut, CalcCaseMap( rTxt ), - pDXArray, nIdx, nLen ) ); + { + if (IsCapital() && !rTxt.isEmpty()) + aTxtSize = GetCapitalSize(pOut, rTxt, pDXArray, nIdx, nLen); + else + aTxtSize.setWidth( GetTextArray( pOut, CalcCaseMap( rTxt ), + pDXArray, nIdx, nLen ) ); + } SAL_INFO( "editeng.quicktextsize", "SvxFont::QuickGetTextSize after GetTextArray(): Text length: " << nLen << " Text size: " << aTxtSize.Width() << "x" << aTxtSize.Height()); if( IsFixKerning() && ( nLen > 1 ) ) @@ -544,7 +516,7 @@ Size SvxFont::GetTextSize(const OutputDevice& rOut, const OUString &rTxt, Size aTxtSize; if( IsCapital() && !rTxt.isEmpty() ) { - aTxtSize = GetCapitalSize(&rOut, rTxt, nIdx, nTmp); + aTxtSize = GetCapitalSize(&rOut, rTxt, nullptr, nIdx, nTmp); } else aTxtSize = GetPhysTxtSize(&rOut,rTxt,nIdx,nTmp); const_cast<OutputDevice&>(rOut).SetFont(aOldFont); @@ -703,17 +675,27 @@ namespace { class SvxDoGetCapitalSize : public SvxDoCapitals { protected: + VclPtr<OutputDevice> pOut; SvxFont* pFont; Size aTxtSize; short nKern; + KernArray* pDXAry; public: SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut, - const OUString &_rTxt, const sal_Int32 _nIdx, + const OUString &_rTxt, KernArray* _pDXAry, const sal_Int32 _nIdx, const sal_Int32 _nLen, const short _nKrn ) - : SvxDoCapitals( const_cast<OutputDevice*>(_pOut), _rTxt, _nIdx, _nLen ), + : SvxDoCapitals( _rTxt, _nIdx, _nLen ), + pOut( const_cast<OutputDevice*>(_pOut) ), pFont( _pFnt ), - nKern( _nKrn ) - { } + nKern( _nKrn ), + pDXAry( _pDXAry ) + { + if (pDXAry) + { + pDXAry->clear(); + pDXAry->reserve(_nLen); + } + } virtual void Do( const OUString &rTxt, const sal_Int32 nIdx, const sal_Int32 nLen, const bool bUpper ) override; @@ -727,31 +709,50 @@ void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx, const sal_Int32 _nLen, const bool bUpper ) { Size aPartSize; + sal_uInt8 nProp(0); if ( !bUpper ) { - sal_uInt8 nProp = pFont->GetPropr(); + nProp = pFont->GetPropr(); pFont->SetProprRel( SMALL_CAPS_PERCENTAGE ); pFont->SetPhysFont( *pOut ); - aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); - aPartSize.setHeight( pOut->GetTextHeight() ); - aTxtSize.setHeight( aPartSize.Height() ); - pFont->SetPropr( nProp ); - pFont->SetPhysFont( *pOut ); + } + + if (pDXAry) + { + KernArray aKernArray; + aPartSize.setWidth(pOut->GetTextArray(_rTxt, &aKernArray, _nIdx, _nLen)); + assert(pDXAry->get_factor() == aKernArray.get_factor()); + auto& dest = pDXAry->get_subunit_array(); + sal_Int32 nStart = dest.empty() ? 0 : dest.back(); + size_t nSrcLen = aKernArray.size(); + dest.reserve(dest.size() + nSrcLen); + const auto& src = aKernArray.get_subunit_array(); + for (size_t i = 0; i < nSrcLen; ++i) + dest.push_back(src[i] + nStart); } else { aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); - aPartSize.setHeight( pOut->GetTextHeight() ); } + + aPartSize.setHeight( pOut->GetTextHeight() ); + + if ( !bUpper ) + { + aTxtSize.setHeight( aPartSize.Height() ); + pFont->SetPropr( nProp ); + pFont->SetPhysFont( *pOut ); + } + aTxtSize.AdjustWidth(aPartSize.Width() ); aTxtSize.AdjustWidth( _nLen * tools::Long( nKern ) ); } -Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, +Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, KernArray* pDXAry, const sal_Int32 nIdx, const sal_Int32 nLen) const { // Start: - SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, nIdx, nLen, GetFixKerning() ); + SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, pDXAry, nIdx, nLen, GetFixKerning() ); DoOnCapitals( aDo ); Size aTxtSize( aDo.GetSize() ); @@ -769,6 +770,7 @@ namespace { class SvxDoDrawCapital : public SvxDoCapitals { protected: + VclPtr<OutputDevice> pOut; SvxFont *pFont; Point aPos; Point aSpacePos; @@ -777,7 +779,8 @@ public: SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt, const sal_Int32 _nIdx, const sal_Int32 _nLen, const Point &rPos, const short nKrn ) - : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ), + : SvxDoCapitals( _rTxt, _nIdx, _nLen ), + pOut( _pOut ), pFont( pFnt ), aPos( rPos ), aSpacePos( rPos ), diff --git a/include/editeng/smallcaps.hxx b/include/editeng/smallcaps.hxx new file mode 100644 index 000000000000..8a453b1185f6 --- /dev/null +++ b/include/editeng/smallcaps.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include <editeng/editengdllapi.h> + +/************************************************************************* + * class SvxDoCapitals + * The virtual Method Do is called by SvxFont::DoOnCapitals alternately + * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills + * this method with life. + *************************************************************************/ + +class EDITENG_DLLPUBLIC SvxDoCapitals +{ +protected: + const OUString& rTxt; + const sal_Int32 nIdx; + const sal_Int32 nLen; + +public: + SvxDoCapitals(const OUString& _rTxt, const sal_Int32 _nIdx, const sal_Int32 _nLen) + : rTxt(_rTxt) + , nIdx(_nIdx) + , nLen(_nLen) + { + } + + virtual ~SvxDoCapitals() {} + + virtual void DoSpace(const bool bDraw); + virtual void SetSpace(); + virtual void Do(const OUString& rTxt, const sal_Int32 nIdx, const sal_Int32 nLen, + const bool bUpper) + = 0; + + const OUString& GetTxt() const { return rTxt; } + sal_Int32 GetIdx() const { return nIdx; } + sal_Int32 GetLen() const { return nLen; } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/editeng/svxfont.hxx b/include/editeng/svxfont.hxx index 0968181327e8..9fa7097d04e1 100644 --- a/include/editeng/svxfont.hxx +++ b/include/editeng/svxfont.hxx @@ -76,7 +76,7 @@ public: void SetPhysFont(OutputDevice& rOut) const; vcl::Font ChgPhysFont(OutputDevice& rOut) const; - Size GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, + Size GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, KernArray* pDXAry, const sal_Int32 nIdx, const sal_Int32 nLen) const; void DrawCapital( OutputDevice *pOut, const Point &rPos, const OUString &rTxt, const sal_Int32 nIdx, const sal_Int32 nLen ) const; diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx index 66c97d29b9b1..6a1a54f2321e 100644 --- a/svx/source/svdraw/svdotextdecomposition.cxx +++ b/svx/source/svdraw/svdotextdecomposition.cxx @@ -34,11 +34,13 @@ #include <svx/xbtmpit.hxx> #include <basegfx/vector/b2dvector.hxx> #include <sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/textprimitive2d.hxx> #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> #include <basegfx/range/b2drange.hxx> #include <editeng/eeitem.hxx> #include <editeng/editstat.hxx> +#include <editeng/smallcaps.hxx> #include <tools/helpers.hxx> #include <svl/itemset.hxx> #include <drawinglayer/animation/animationtiming.hxx> @@ -66,6 +68,11 @@ using namespace com::sun::star; namespace { + rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> buildTextPortionPrimitive(const DrawPortionInfo& rInfo, const OUString& rText, + const drawinglayer::attribute::FontAttribute& rFontAttribute, + const std::vector<double>& rDXArray, + const basegfx::B2DHomMatrix& rNewTransform); + class impTextBreakupHandler { private: @@ -94,7 +101,6 @@ namespace DECL_LINK(decomposeBlockBulletPrimitive, DrawBulletInfo*, void); DECL_LINK(decomposeStretchBulletPrimitive, DrawBulletInfo*, void); - void impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo); static rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo); void impFlushTextPortionPrimitivesToLinePrimitives(); void impFlushLinePrimitivesToParagraphPrimitives(sal_Int32 nPara); @@ -146,6 +152,71 @@ namespace } drawinglayer::primitive2d::Primitive2DContainer extractPrimitive2DSequence(); + + void impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo); + }; + + class DoCapitalsDrawPortionInfo : public SvxDoCapitals + { + private: + impTextBreakupHandler& m_rHandler; + const DrawPortionInfo& m_rInfo; + SvxFont m_aFont; + public: + DoCapitalsDrawPortionInfo(impTextBreakupHandler& rHandler, const DrawPortionInfo& rInfo) + : SvxDoCapitals(rInfo.maText, rInfo.mnTextStart, rInfo.mnTextLen) + , m_rHandler(rHandler) + , m_rInfo(rInfo) + , m_aFont(rInfo.mrFont) + { + assert(!m_rInfo.mpDXArray.empty()); + + /* turn all these off as they are handled outside subportions for the whole portion */ + m_aFont.SetTransparent(false); + m_aFont.SetUnderline(LINESTYLE_NONE); + m_aFont.SetOverline(LINESTYLE_NONE); + m_aFont.SetStrikeout(STRIKEOUT_NONE); + + m_aFont.SetCaseMap(SvxCaseMap::NotMapped); /* otherwise this would call itself */ + } + virtual void Do( const OUString &rSpanTxt, const sal_Int32 nSpanIdx, + const sal_Int32 nSpanLen, const bool bUpper ) override + { + sal_uInt8 nProp(0); + if (!bUpper) + { + nProp = m_aFont.GetPropr(); + m_aFont.SetProprRel(SMALL_CAPS_PERCENTAGE); + } + + sal_Int32 nStartOffset = nSpanIdx - nIdx; + sal_Int32 nStartX = nStartOffset ? m_rInfo.mpDXArray[nStartOffset - 1] : 0; + + Point aStartPos(m_rInfo.mrStartPos.X() + nStartX, m_rInfo.mrStartPos.Y()); + + std::vector<sal_Int32> aDXArray; + aDXArray.reserve(nSpanLen); + for (sal_Int32 i = 0; i < nSpanLen; ++i) + aDXArray.push_back(m_rInfo.mpDXArray[nStartOffset + i] - nStartX); + + auto aKashidaArray = !m_rInfo.mpKashidaArray.empty() ? + o3tl::span<const sal_Bool>(m_rInfo.mpKashidaArray.data() + nStartOffset, nSpanLen) : + o3tl::span<const sal_Bool>(); + + DrawPortionInfo aInfo(aStartPos, rSpanTxt, + nSpanIdx, nSpanLen, + m_aFont, m_rInfo.mnPara, + aDXArray, aKashidaArray, + nullptr, /* no spelling in subportion, handled outside */ + nullptr, /* no field in subportion, handled outside */ + m_rInfo.mpLocale, m_rInfo.maOverlineColor, m_rInfo.maTextLineColor, + m_rInfo.mnBiDiLevel, false, 0, false, false, false); + + m_rHandler.impCreateTextPortionPrimitive(aInfo); + + if (!bUpper) + m_aFont.SetPropr(nProp); + } }; void impTextBreakupHandler::impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo) @@ -153,7 +224,6 @@ namespace if(rInfo.maText.isEmpty() || !rInfo.mnTextLen) return; - OUString caseMappedText = rInfo.mrFont.CalcCaseMap( rInfo.maText ); basegfx::B2DVector aFontScaling; drawinglayer::attribute::FontAttribute aFontAttribute( drawinglayer::primitive2d::getFontAttributeFromVclFont( @@ -222,16 +292,153 @@ namespace // the text transformation), scale it to unit coordinates ::std::vector< double > aDXArray; - if(!rInfo.mpDXArray.empty() && rInfo.mnTextLen) + if (!rInfo.mpDXArray.empty()) { aDXArray.reserve(rInfo.mnTextLen); - for(sal_Int32 a=0; a < rInfo.mnTextLen; a++) { aDXArray.push_back(static_cast<double>(rInfo.mpDXArray[a])); } } + OUString caseMappedText = rInfo.mrFont.CalcCaseMap(rInfo.maText); + rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> pNewPrimitive(buildTextPortionPrimitive(rInfo, caseMappedText, + aFontAttribute, + aDXArray, aNewTransform)); + + bool bSmallCaps = rInfo.mrFont.IsCapital(); + if (bSmallCaps && rInfo.mpDXArray.empty()) + { + SAL_WARN("svx", "SmallCaps requested with DXArray, abandoning"); + bSmallCaps = false; + } + if (bSmallCaps) + { + // rerun with each sub-portion + DoCapitalsDrawPortionInfo aDoDrawPortionInfo(*this, rInfo); + rInfo.mrFont.DoOnCapitals(aDoDrawPortionInfo); + + // transfer collected primitives from maTextPortionPrimitives to a new container + drawinglayer::primitive2d::Primitive2DContainer aContainer; + aContainer.swap(maTextPortionPrimitives); + + // Take any decoration for the whole formatted portion and keep it to get continous over/under/strike-through + if (pNewPrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D) + { + const drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D* pTCPP = + static_cast<const drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D*>(pNewPrimitive.get()); + + pTCPP->CreateDecorationGeometryContent( + aContainer, + pTCPP->getTextTransform(), + caseMappedText, + rInfo.mnTextStart, + rInfo.mnTextLen, + aDXArray); + } + + pNewPrimitive = new drawinglayer::primitive2d::GroupPrimitive2D(std::move(aContainer)); + } + + const Color aFontColor(rInfo.mrFont.GetColor()); + if (aFontColor.IsTransparent()) + { + // Handle semi-transparent text for both the decorated and simple case here. + pNewPrimitive = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + drawinglayer::primitive2d::Primitive2DContainer{ pNewPrimitive }, + (255 - aFontColor.GetAlpha()) / 255.0); + } + + if(rInfo.mbEndOfBullet) + { + // embed in TextHierarchyBulletPrimitive2D + drawinglayer::primitive2d::Primitive2DReference aNewReference(pNewPrimitive); + drawinglayer::primitive2d::Primitive2DContainer aNewSequence { aNewReference } ; + pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(std::move(aNewSequence)); + } + + if(rInfo.mpFieldData) + { + pNewPrimitive = impCheckFieldPrimitive(pNewPrimitive.get(), rInfo); + } + + maTextPortionPrimitives.push_back(pNewPrimitive); + + // support for WrongSpellVector. Create WrongSpellPrimitives as needed + if(!rInfo.mpWrongSpellVector || aDXArray.empty()) + return; + + const sal_Int32 nSize(rInfo.mpWrongSpellVector->size()); + const sal_Int32 nDXCount(aDXArray.size()); + const basegfx::BColor aSpellColor(1.0, 0.0, 0.0); // red, hard coded + + for(sal_Int32 a(0); a < nSize; a++) + { + const EEngineData::WrongSpellClass& rCandidate = (*rInfo.mpWrongSpellVector)[a]; + + if(rCandidate.nStart >= rInfo.mnTextStart && rCandidate.nEnd >= rInfo.mnTextStart && rCandidate.nEnd > rCandidate.nStart) + { + const sal_Int32 nStart(rCandidate.nStart - rInfo.mnTextStart); + const sal_Int32 nEnd(rCandidate.nEnd - rInfo.mnTextStart); + double fStart(0.0); + double fEnd(0.0); + + if(nStart > 0 && nStart - 1 < nDXCount) + { + fStart = aDXArray[nStart - 1]; + } + + if(nEnd > 0 && nEnd - 1 < nDXCount) + { + fEnd = aDXArray[nEnd - 1]; + } + + if(!basegfx::fTools::equal(fStart, fEnd)) + { + if(rInfo.IsRTL()) + { + // #i98523# + // When the portion is RTL, mirror the redlining using the + // full portion width + const double fTextWidth(aDXArray[aDXArray.size() - 1]); + + fStart = fTextWidth - fStart; + fEnd = fTextWidth - fEnd; + + // tdf#151968 + // if start < end, OutputDevice::DrawWaveLine() will + // think it is a rotated line, so we swap fStart and + // fEnd to avoid this. + std::swap(fStart, fEnd); + } + + // need to take FontScaling out of values; it's already part of + // aNewTransform and would be double applied + const double fFontScaleX(aFontScaling.getX() * fPropFontFactor); + + if(!basegfx::fTools::equal(fFontScaleX, 1.0) + && !basegfx::fTools::equalZero(fFontScaleX)) + { + fStart /= fFontScaleX; + fEnd /= fFontScaleX; + } + + maTextPortionPrimitives.push_back(new drawinglayer::primitive2d::WrongSpellPrimitive2D( + aNewTransform, + fStart, + fEnd, + aSpellColor)); + } + } + } + } + + rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> buildTextPortionPrimitive( + const DrawPortionInfo& rInfo, const OUString& rText, + const drawinglayer::attribute::FontAttribute& rFontAttribute, + const std::vector<double>& rDXArray, + const basegfx::B2DHomMatrix& rNewTransform) + { ::std::vector< sal_Bool > aKashidaArray; if(!rInfo.mpKashidaArray.empty() && rInfo.mnTextLen) @@ -321,13 +528,13 @@ namespace pNewPrimitive = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D( // attributes for TextSimplePortionPrimitive2D - aNewTransform, - caseMappedText, + rNewTransform, + rText, rInfo.mnTextStart, rInfo.mnTextLen, - std::vector(aDXArray), + std::vector(rDXArray), std::vector(aKashidaArray), - aFontAttribute, + rFontAttribute, rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(), aBFontColor, aTextFillColor, @@ -350,13 +557,13 @@ namespace { // TextSimplePortionPrimitive2D is enough pNewPrimitive = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( - aNewTransform, - caseMappedText, + rNewTransform, + rText, rInfo.mnTextStart, rInfo.mnTextLen, - std::vector(aDXArray), + std::vector(rDXArray), std::vector(aKashidaArray), - std::move(aFontAttribute), + rFontAttribute, rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(), aBFontColor, rInfo.mbFilled, @@ -364,96 +571,7 @@ namespace aTextFillColor); } - if (aFontColor.IsTransparent()) - { - // Handle semi-transparent text for both the decorated and simple case here. - pNewPrimitive = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( - drawinglayer::primitive2d::Primitive2DContainer{ pNewPrimitive }, - (255 - aFontColor.GetAlpha()) / 255.0); - } - - if(rInfo.mbEndOfBullet) - { - // embed in TextHierarchyBulletPrimitive2D - drawinglayer::primitive2d::Primitive2DReference aNewReference(pNewPrimitive); - drawinglayer::primitive2d::Primitive2DContainer aNewSequence { aNewReference } ; - pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(std::move(aNewSequence)); - } - - if(rInfo.mpFieldData) - { - pNewPrimitive = impCheckFieldPrimitive(pNewPrimitive.get(), rInfo); - } - - maTextPortionPrimitives.push_back(pNewPrimitive); - - // support for WrongSpellVector. Create WrongSpellPrimitives as needed - if(!rInfo.mpWrongSpellVector || aDXArray.empty()) - return; - - const sal_Int32 nSize(rInfo.mpWrongSpellVector->size()); - const sal_Int32 nDXCount(aDXArray.size()); - const basegfx::BColor aSpellColor(1.0, 0.0, 0.0); // red, hard coded - - for(sal_Int32 a(0); a < nSize; a++) - { - const EEngineData::WrongSpellClass& rCandidate = (*rInfo.mpWrongSpellVector)[a]; - - if(rCandidate.nStart >= rInfo.mnTextStart && rCandidate.nEnd >= rInfo.mnTextStart && rCandidate.nEnd > rCandidate.nStart) - { - const sal_Int32 nStart(rCandidate.nStart - rInfo.mnTextStart); - const sal_Int32 nEnd(rCandidate.nEnd - rInfo.mnTextStart); - double fStart(0.0); - double fEnd(0.0); - - if(nStart > 0 && nStart - 1 < nDXCount) - { - fStart = aDXArray[nStart - 1]; - } - - if(nEnd > 0 && nEnd - 1 < nDXCount) - { - fEnd = aDXArray[nEnd - 1]; - } - - if(!basegfx::fTools::equal(fStart, fEnd)) - { - if(rInfo.IsRTL()) - { - // #i98523# - // When the portion is RTL, mirror the redlining using the - // full portion width - const double fTextWidth(aDXArray[aDXArray.size() - 1]); - - fStart = fTextWidth - fStart; - fEnd = fTextWidth - fEnd; - - // tdf#151968 - // if start < end, OutputDevice::DrawWaveLine() will - // think it is a rotated line, so we swap fStart and - // fEnd to avoid this. - std::swap(fStart, fEnd); - } - - // need to take FontScaling out of values; it's already part of - // aNewTransform and would be double applied - const double fFontScaleX(aFontScaling.getX() * fPropFontFactor); - - if(!basegfx::fTools::equal(fFontScaleX, 1.0) - && !basegfx::fTools::equalZero(fFontScaleX)) - { - fStart /= fFontScaleX; - fEnd /= fFontScaleX; - } - - maTextPortionPrimitives.push_back(new drawinglayer::primitive2d::WrongSpellPrimitive2D( - aNewTransform, - fStart, - fEnd, - aSpellColor)); - } - } - } + return pNewPrimitive; } rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> impTextBreakupHandler::impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo) |