[Libreoffice-commits] core.git: include/vcl vcl/inc vcl/quartz vcl/source

Norbert Thiebaud nthiebaud at gmail.com
Mon Mar 17 00:43:18 PDT 2014


 include/vcl/outdev.hxx     |    2 -
 vcl/inc/sallayout.hxx      |    2 +
 vcl/quartz/ctlayout.cxx    |   59 ++++++++++++++++++++++++++++++++---
 vcl/source/gdi/outdev3.cxx |   75 +++++++++++++++++++++++++++------------------
 4 files changed, 102 insertions(+), 36 deletions(-)

New commits:
commit 45b0c12a021fb0eb896faf4f0de9026586407012
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Fri Mar 14 23:18:13 2014 -0500

    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 at gmail.com>
    Tested-by: Norbert Thiebaud <nthiebaud at gmail.com>

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 951a26b..da696af 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 b824e74..f3727ba 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 ec75168..b8b1b98 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 bfcccbd..c78794d 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();
+            }
         }
     }
 }


More information about the Libreoffice-commits mailing list