diff options
-rw-r--r-- | include/vcl/outdev.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 2 | ||||
-rw-r--r-- | vcl/quartz/ctlayout.cxx | 59 | ||||
-rw-r--r-- | vcl/source/gdi/outdev3.cxx | 75 |
4 files changed, 102 insertions, 36 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 951a26b7625d..da696aff81cf 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -621,7 +621,7 @@ public: SAL_DLLPRIVATE void ImplDrawTextBackground( const SalLayout& ); SAL_DLLPRIVATE void ImplDrawTextLines( SalLayout&, FontStrikeout eStrikeout, FontUnderline eUnderline, FontUnderline eOverline, bool bWordLine, bool bUnderlineAbove ); SAL_DLLPRIVATE bool ImplDrawRotateText( SalLayout& ); - SAL_DLLPRIVATE void ImplDrawTextDirect( SalLayout&, bool bTextLines ); + SAL_DLLPRIVATE bool ImplDrawTextDirect( SalLayout&, bool bTextLines, sal_uInt32 flags = 0 ); SAL_DLLPRIVATE void ImplDrawSpecialText( SalLayout& ); SAL_DLLPRIVATE void ImplDrawText( SalLayout& ); SAL_DLLPRIVATE Rectangle ImplGetTextBoundRect( const SalLayout& ); diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index b824e74d627f..f3727bab61b3 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -179,6 +179,8 @@ public: virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting after fallback etc. virtual void InitFont() const {} virtual void DrawText( SalGraphics& ) const = 0; + virtual bool DrawTextSpecial( SalGraphics& /* rGraphics */, sal_uInt32 /* flags */ ) const { return false; } +#define DRAWTEXT_F_OUTLINE ((sal_uInt32)(1<<0)) int GetUnitsPerPixel() const { return mnUnitsPerPixel; } int GetOrientation() const { return mnOrientation; } diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx index ec7516882e7a..b8b1b98e6ce0 100644 --- a/vcl/quartz/ctlayout.cxx +++ b/vcl/quartz/ctlayout.cxx @@ -31,6 +31,7 @@ public: virtual bool LayoutText( ImplLayoutArgs& ) SAL_OVERRIDE; virtual void AdjustLayout( ImplLayoutArgs& ) SAL_OVERRIDE; virtual void DrawText( SalGraphics& ) const SAL_OVERRIDE; + virtual bool DrawTextSpecial( SalGraphics& rGraphics, sal_uInt32 flags ) const SAL_OVERRIDE; virtual int GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, int&, sal_Int32* pGlyphAdvances, int* pCharIndexes, @@ -48,6 +49,7 @@ public: virtual void Simplify( bool bIsBase ) SAL_OVERRIDE; private: + void drawCTLine(AquaSalGraphics& rAquaGraphics, CTLineRef ctline, const CoreTextStyle* const pStyle) const; CGPoint GetTextDrawPosition(void) const; double GetWidth(void) const; @@ -244,14 +246,50 @@ CGPoint CTLayout::GetTextDrawPosition(void) const return aTextPos; } -void CTLayout::DrawText( SalGraphics& rGraphics ) const +/* use to deal with special font decoration like 'outline' drawing + * return true if it was able to handle the drawing + * false if not, in which case the caller + * is supposed to fallback to 'generic' method + */ +bool CTLayout::DrawTextSpecial( SalGraphics& rGraphics, sal_uInt32 flags ) const { AquaSalGraphics& rAquaGraphics = static_cast<AquaSalGraphics&>(rGraphics); // short circuit if there is nothing to do if( (mnCharCount <= 0) || !rAquaGraphics.CheckContext() ) - return; + return true; + if (flags & DRAWTEXT_F_OUTLINE) + { + CFMutableDictionaryRef styledict = CFDictionaryCreateMutableCopy( + CFAllocatorGetDefault(), + CFDictionaryGetCount(mpTextStyle->GetStyleDict()), + mpTextStyle->GetStyleDict()); + + int nStroke = 2; + CFNumberRef rStroke = CFNumberCreate(NULL, kCFNumberSInt32Type, &nStroke); + CFDictionarySetValue(styledict, kCTStrokeWidthAttributeName, rStroke); + + CFAttributedStringRef pAttrStr = CFAttributedStringCreate( + NULL, + CFAttributedStringGetString(mpAttrString), + styledict); + CTLineRef pCTLine = CTLineCreateWithAttributedString( pAttrStr ); + CFRelease( pAttrStr ); + + /* draw the text in 'outline' */ + drawCTLine(rAquaGraphics, pCTLine, mpTextStyle); + CFRelease(pCTLine); + return true; + } + else + { + return SalLayout::DrawTextSpecial(rGraphics, flags); + } +} + +void CTLayout::drawCTLine(AquaSalGraphics& rAquaGraphics, CTLineRef ctline, const CoreTextStyle* const pStyle) const +{ // the view is vertically flipped => flipped glyphs // so apply a temporary transformation that it flips back // also compensate if the font was size limited @@ -262,9 +300,9 @@ void CTLayout::DrawText( SalGraphics& rGraphics ) const // Draw the text CGPoint aTextPos = GetTextDrawPosition(); - if( mpTextStyle->mfFontRotation != 0.0 ) + if( pStyle->mfFontRotation != 0.0 ) { - const CGFloat fRadians = mpTextStyle->mfFontRotation; + const CGFloat fRadians = pStyle->mfFontRotation; CGContextRotateCTM( rAquaGraphics.mrContext, +fRadians ); const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians ); @@ -272,7 +310,7 @@ void CTLayout::DrawText( SalGraphics& rGraphics ) const } CGContextSetTextPosition( rAquaGraphics.mrContext, aTextPos.x, aTextPos.y ); - CTLineDraw( mpCTLine, rAquaGraphics.mrContext ); + CTLineDraw( ctline, rAquaGraphics.mrContext ); #ifndef IOS // request an update of the changed window area if( rAquaGraphics.IsWindowGraphics() ) @@ -286,6 +324,17 @@ void CTLayout::DrawText( SalGraphics& rGraphics ) const CGContextRestoreGState( rAquaGraphics.mrContext ); } +void CTLayout::DrawText( SalGraphics& rGraphics ) const +{ + AquaSalGraphics& rAquaGraphics = static_cast<AquaSalGraphics&>(rGraphics); + + // short circuit if there is nothing to do + if( (mnCharCount <= 0) || !rAquaGraphics.CheckContext() ) + return; + + drawCTLine(rAquaGraphics, mpCTLine, mpTextStyle); +} + int CTLayout::GetNextGlyphs( int nLen, sal_GlyphId* pOutGlyphIds, Point& rPos, int& nStart, sal_Int32* pGlyphAdvances, int* pCharIndexes, const PhysicalFontFace** pFallbackFonts ) const diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index bfcccbd0002c..c78794d76bb9 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -4495,11 +4495,11 @@ bool OutputDevice::ImplDrawRotateText( SalLayout& rSalLayout ) return true; } -void OutputDevice::ImplDrawTextDirect( SalLayout& rSalLayout, bool bTextLines ) +bool OutputDevice::ImplDrawTextDirect( SalLayout& rSalLayout, bool bTextLines, sal_uInt32 flags ) { if( mpFontEntry->mnOwnOrientation ) if( ImplDrawRotateText( rSalLayout ) ) - return; + return true; long nOldX = rSalLayout.DrawBase().X(); if( HasMirroredGraphics() ) @@ -4524,8 +4524,18 @@ void OutputDevice::ImplDrawTextDirect( SalLayout& rSalLayout, bool bTextLines ) rSalLayout.DrawBase().X() = pOutDevRef->mnOutWidth - 1 - (rSalLayout.DrawBase().X() - devX) + devX; } - rSalLayout.DrawText( *mpGraphics ); - + if(flags) + { + if( ! rSalLayout.DrawTextSpecial( *mpGraphics, flags )) + { + rSalLayout.DrawBase().X() = nOldX; + return false; + } + } + else + { + rSalLayout.DrawText( *mpGraphics ); + } rSalLayout.DrawBase().X() = nOldX; if( bTextLines ) @@ -4536,6 +4546,8 @@ void OutputDevice::ImplDrawTextDirect( SalLayout& rSalLayout, bool bTextLines ) // emphasis marks if( maFont.GetEmphasisMark() & EMPHASISMARK_STYLE ) ImplDrawEmphasisMarks( rSalLayout ); + + return true; } void OutputDevice::ImplDrawSpecialText( SalLayout& rSalLayout ) @@ -4626,33 +4638,36 @@ void OutputDevice::ImplDrawSpecialText( SalLayout& rSalLayout ) if ( maFont.IsOutline() ) { - rSalLayout.DrawBase() = aOrigPos + Point(-1,-1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(+1,+1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(-1,+0); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(-1,+1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(+0,+1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(+0,-1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(+1,-1); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos + Point(+1,+0); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - rSalLayout.DrawBase() = aOrigPos; + if(! ImplDrawTextDirect( rSalLayout, mbTextLines, DRAWTEXT_F_OUTLINE)) + { + rSalLayout.DrawBase() = aOrigPos + Point(-1,-1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(+1,+1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(-1,+0); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(-1,+1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(+0,+1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(+0,-1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(+1,-1); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos + Point(+1,+0); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + rSalLayout.DrawBase() = aOrigPos; - SetTextColor( Color( COL_WHITE ) ); - SetTextLineColor( Color( COL_WHITE ) ); - SetOverlineColor( Color( COL_WHITE ) ); - ImplInitTextColor(); - ImplDrawTextDirect( rSalLayout, mbTextLines ); - SetTextColor( aOldColor ); - SetTextLineColor( aOldTextLineColor ); - SetOverlineColor( aOldOverlineColor ); - ImplInitTextColor(); + SetTextColor( Color( COL_WHITE ) ); + SetTextLineColor( Color( COL_WHITE ) ); + SetOverlineColor( Color( COL_WHITE ) ); + ImplInitTextColor(); + ImplDrawTextDirect( rSalLayout, mbTextLines ); + SetTextColor( aOldColor ); + SetTextLineColor( aOldTextLineColor ); + SetOverlineColor( aOldOverlineColor ); + ImplInitTextColor(); + } } } } |