[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - vcl/quartz

Khaled Hosny khaledhosny at eglug.org
Sat Oct 15 20:44:34 UTC 2016


 vcl/quartz/salgdi.cxx |   85 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 63 insertions(+), 22 deletions(-)

New commits:
commit d557cae6d36faa6bde6a66c085ae009e7a276eeb
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sat Oct 15 06:11:26 2016 -0700

    Rewrite AquaSalGraphics::DrawSalLayout()
    
    Slightly cleaner code and now handles glyph rotation for vertical text.
    
    Change-Id: I98cc8fd7df5e73068294e4d7dd6b38a71dcbdcc7

diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index caa7e35..1f156e0 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -485,37 +485,78 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect
 
 void AquaSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
 {
-    CGContextRef context = mrContext;
-    SAL_INFO("vcl.ct", "CGContextSaveGState(" << context << ")");
-    CGContextSaveGState(context);
-    SAL_INFO("vcl.ct", "CGContextScaleCTM(" << context << ",1.0,-1.0)");
-    const CoreTextStyle& rCTStyle = rLayout.getFontData();
-
-    CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCTStyle.GetStyleDict(), kCTFontAttributeName));
-    CGContextScaleCTM(context, 1.0, -1.0);
-    CGContextSetShouldAntialias(context, !mbNonAntialiasedText);
-    // rotate the matrix
-    const CGFloat fRadians = rCTStyle.mfFontRotation;
-    CGContextRotateCTM(context, +fRadians);
-    const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation(-fRadians);
-    CGContextSetFillColor(context, maTextColor.AsArray());
-
-    // draw the text
+    const CoreTextStyle& rStyle = rLayout.getFontData();
+    const FontSelectPattern& rFontSelect = rStyle.maFontSelData;
+    if (rFontSelect.mnHeight == 0)
+        return;
+
+    CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(rStyle.GetStyleDict(), kCTFontAttributeName));
+
     Point aPos;
     sal_GlyphId aGlyphId;
     std::vector<CGGlyph> aGlyphIds;
     std::vector<CGPoint> aGlyphPos;
+    std::vector<bool> aGlyphRotation;
     int nStart = 0;
-    for (; rLayout.GetNextGlyphs(1, &aGlyphId, aPos, nStart); )
+    while (rLayout.GetNextGlyphs(1, &aGlyphId, aPos, nStart))
     {
+        CGAffineTransform aMatrix = CGAffineTransformMakeRotation(-rStyle.mfFontRotation);
+        bool nGlyphRotation = false;
+        if ((aGlyphId & GF_ROTMASK) == GF_ROTL)
+        {
+            nGlyphRotation = true;
+            double nYdiff = CTFontGetAscent(pFont) - CTFontGetDescent(pFont);
+            aMatrix = CGAffineTransformTranslate(aMatrix, 0, -nYdiff);
+        }
+
         aGlyphIds.push_back(aGlyphId & GF_IDXMASK);
-        aGlyphPos.push_back(CGPointApplyAffineTransform(CGPointMake(aPos.X(), -1*aPos.Y()), aInvMatrix));
+        aGlyphPos.push_back(CGPointApplyAffineTransform(CGPointMake(aPos.X(), -aPos.Y()), aMatrix));
+        aGlyphRotation.push_back(nGlyphRotation);
+    }
+
+    if (aGlyphIds.empty())
+        return;
+
+    CGContextSaveGState(mrContext);
+
+    CTFontRef pRotatedFont = nullptr;
+    if (rStyle.mfFontRotation)
+    {
+        CTFontDescriptorRef pDesc = CTFontCopyFontDescriptor(pFont);
+        CGFloat nSize = CTFontGetSize(pFont);
+        CGAffineTransform aMatrix = CTFontGetMatrix(pFont);
+        aMatrix = CGAffineTransformRotate(aMatrix, -rStyle.mfFontRotation);
+        pRotatedFont = CTFontCreateWithFontDescriptor(pDesc, nSize, &aMatrix);
+        CFRelease(pDesc);
+    }
+
+    CGContextScaleCTM(mrContext, 1.0, -1.0);
+    CGContextRotateCTM(mrContext, rStyle.mfFontRotation);
+    CGContextSetShouldAntialias(mrContext, !mbNonAntialiasedText);
+    CGContextSetFillColor(mrContext, maTextColor.AsArray());
+
+    std::vector<bool>::const_iterator aStart = aGlyphRotation.begin();
+    std::vector<bool>::const_iterator aEnd = aGlyphRotation.end();
+    std::vector<bool>::const_iterator aI = aStart;
+    while (aI != aEnd)
+    {
+        bool nGlyphRotation = *aI;
+        std::vector<bool>::const_iterator aNext = std::find(aI + 1, aEnd, !nGlyphRotation);
+
+        size_t nStartIndex = std::distance(aStart, aI);
+        size_t nLen = std::distance(aI, aNext);
+
+        if (nGlyphRotation && pRotatedFont)
+            CTFontDrawGlyphs(pRotatedFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrContext);
+        else
+            CTFontDrawGlyphs(pFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrContext);
+
+        aI = aNext;
     }
-    CTFontDrawGlyphs(pFont, aGlyphIds.data(), aGlyphPos.data(), nStart, context);
 
-    // restore the original graphic context transformations
-    SAL_INFO("vcl.ct", "CGContextRestoreGState(" << context << ")");
-    CGContextRestoreGState(context);
+    if (pRotatedFont)
+        CFRelease(pRotatedFont);
+    CGContextRestoreGState(mrContext);
 }
 
 void AquaSalGraphics::SetFont(FontSelectPattern* pReqFont, int nFallbackLevel)


More information about the Libreoffice-commits mailing list