From 53e2bdb610cb46b8a2482c742820e2dbe80bfc47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Tue, 29 Mar 2011 14:00:33 +0100 Subject: [PATCH] Resolves: rhbz#684580 'X' and '/' strike-through escapes range i.e. it bleeds outside the text it is supposed to affect. See #i114076#, --- vcl/source/gdi/outdev3.cxx | 46 ++++++++++++++++++++++++------------- vcl/source/gdi/pdfwriter_impl.cxx | 23 ++++++++++++++++++ 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 02febe3..d43c163 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -4005,6 +4005,11 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, FontStrikeout eStrikeout, Color aColor ) { + //See qadevOOo/testdocs/StrikeThrough.odt for examples if you need + //to tweak this + if (!nWidth) + return; + // PDF-export does its own strikeout drawing... why again? if( mpPDFWriter && mpPDFWriter->isBuiltinFont(mpFontEntry->maFontSelData.mpFontData) ) return; @@ -4017,35 +4022,23 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, cStrikeoutChar = 'X'; static const int nTestStrLen = 4; static const int nMaxStrikeStrLen = 2048; - xub_Unicode aChars[ nMaxStrikeStrLen +1]; // +1 for valgrind... + xub_Unicode aChars[nMaxStrikeStrLen+1]; // +1 for valgrind... for( int i = 0; i < nTestStrLen; ++i) aChars[i] = cStrikeoutChar; const String aStrikeoutTest( aChars, nTestStrLen ); // calculate approximation of strikeout atom size - long nStrikeoutWidth = nWidth; + long nStrikeoutWidth = 0; SalLayout* pLayout = ImplLayout( aStrikeoutTest, 0, nTestStrLen ); if( pLayout ) { - nStrikeoutWidth = (pLayout->GetTextWidth() +nTestStrLen/2) / (nTestStrLen * pLayout->GetUnitsPerPixel()); + nStrikeoutWidth = pLayout->GetTextWidth() / (nTestStrLen * pLayout->GetUnitsPerPixel()); pLayout->Release(); } if( nStrikeoutWidth <= 0 ) // sanity check return; - // calculate acceptable strikeout length - // allow the strikeout to be one pixel larger than the text it strikes out - long nMaxWidth = nStrikeoutWidth * 3 / 4; - if ( nMaxWidth < 2 ) - nMaxWidth = 2; - nMaxWidth += nWidth + 1; - - int nStrikeStrLen = (nMaxWidth - 1) / nStrikeoutWidth; - // if the text width is smaller than the strikeout text, then do not - // strike out at all. This case requires user interaction, e.g. adding - // a space to the text - if( nStrikeStrLen <= 0 ) - return; + int nStrikeStrLen = (nWidth+(nStrikeoutWidth-1)) / nStrikeoutWidth; if( nStrikeStrLen > nMaxStrikeStrLen ) nStrikeStrLen = nMaxStrikeStrLen; @@ -4074,8 +4067,29 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, ImplInitTextColor(); pLayout->DrawBase() = Point( nBaseX+mnTextOffX, nBaseY+mnTextOffY ); + + Rectangle aPixelRect; + aPixelRect.nLeft = nBaseX+mnTextOffX; + aPixelRect.nRight = aPixelRect.nLeft+nWidth; + aPixelRect.nBottom = nBaseY+mpFontEntry->maMetric.mnDescent; + aPixelRect.nTop = nBaseY-mpFontEntry->maMetric.mnAscent; + + if (mpFontEntry->mnOrientation) + { + Polygon aPoly( aPixelRect ); + aPoly.Rotate( Point(nBaseX+mnTextOffX, nBaseY+mnTextOffY), mpFontEntry->mnOrientation); + aPixelRect = aPoly.GetBoundRect(); + } + + Push( PUSH_CLIPREGION ); + IntersectClipRegion( PixelToLogic(aPixelRect) ); + if( mbInitClipRegion ) + ImplInitClipRegion(); + pLayout->DrawText( *mpGraphics ); + pLayout->Release(); + Pop(); SetTextColor( aOldColor ); ImplInitTextColor(); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 442a25d..485dad3 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -8264,6 +8264,9 @@ void PDFWriterImpl::drawStrikeoutLine( OStringBuffer& aLine, long nWidth, FontSt void PDFWriterImpl::drawStrikeoutChar( const Point& rPos, long nWidth, FontStrikeout eStrikeout ) { + //See qadevOOo/testdocs/StrikeThrough.odt for examples if you need + //to tweak this + String aStrikeoutChar = String::CreateFromAscii( eStrikeout == STRIKEOUT_SLASH ? "/" : "X" ); String aStrikeout = aStrikeoutChar; while( m_pReferenceDevice->GetTextWidth( aStrikeout ) < nWidth ) @@ -8285,7 +8288,27 @@ void PDFWriterImpl::drawStrikeoutChar( const Point& rPos, long nWidth, FontStrik // strikeout string is left aligned non-CTL text sal_uLong nOrigTLM = m_pReferenceDevice->GetLayoutMode(); m_pReferenceDevice->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG|TEXT_LAYOUT_COMPLEX_DISABLED ); + + push( PUSH_CLIPREGION ); + FontMetric aRefDevFontMetric = m_pReferenceDevice->GetFontMetric(); + Rectangle aRect; + aRect.nLeft = rPos.X(); + aRect.nRight = aRect.nLeft+nWidth; + aRect.nBottom = rPos.Y()+aRefDevFontMetric.GetDescent(); + aRect.nTop = rPos.Y()-aRefDevFontMetric.GetAscent(); + + ImplFontEntry* pFontEntry = m_pReferenceDevice->mpFontEntry; + if (pFontEntry->mnOrientation) + { + Polygon aPoly( aRect ); + aPoly.Rotate( rPos, pFontEntry->mnOrientation); + aRect = aPoly.GetBoundRect(); + } + + intersectClipRegion( aRect ); drawText( rPos, aStrikeout, 0, aStrikeout.Len(), false ); + pop(); + m_pReferenceDevice->SetLayoutMode( nOrigTLM ); if ( bShadow ) -- 1.7.4.1