summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorNorbert Thiebaud <nthiebaud@gmail.com>2014-03-14 23:18:13 -0500
committerNorbert Thiebaud <nthiebaud@gmail.com>2014-03-17 07:42:57 +0000
commit45b0c12a021fb0eb896faf4f0de9026586407012 (patch)
treedf3a63f3494bf67ee4c3c6ea709b986797b6b4d0 /vcl
parent7af311d2813139660dd2e55cd34bfbd34b650255 (diff)
fdo#67808 Fix Outline Font Effect support with CoreText
We add a new DrawTextSpecial() virtual to SalLayout that allows to attempt to delegate font effects to the underlying native graphic system. The function return false if it was not capable of handling the effect, true otherwise. Right now only Outline Font effect on Coretext is actually handled that way. OutPutDevice is augmented to attempt to delegate the font decoration work, if the task was not handled properly it fallback on the generic code. Note: ideally these effects should really be part of the FontSelector info that is given during layoutting, and the layout should indicate which of these decorations it was able to manage natively but that is a much bigger architectural change.. this will do for now. Change-Id: I5eb1a15e985cc3f234ec3dee899f349f309b42cb Reviewed-on: https://gerrit.libreoffice.org/8599 Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com> Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/sallayout.hxx2
-rw-r--r--vcl/quartz/ctlayout.cxx59
-rw-r--r--vcl/source/gdi/outdev3.cxx75
3 files changed, 101 insertions, 35 deletions
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();
+ }
}
}
}