[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - 7 commits - vcl/inc vcl/quartz vcl/source vcl/unx vcl/win

2016-10-15 Thread Khaled Hosny
Rebased ref, commits from common ancestor:
commit bf7119d9217ba08c716af4f080623d2d167b989a
Author: Khaled Hosny 
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 787ddbf..28e7e99 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(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(CFDictionaryGetValue(rStyle.GetStyleDict(), 
kCTFontAttributeName));
+
 Point aPos;
 sal_GlyphId aGlyphId;
 std::vector aGlyphIds;
 std::vector aGlyphPos;
+std::vector aGlyphRotation;
 int nStart = 0;
-for (; rLayout.GetNextGlyphs(1, , aPos, nStart); )
+while (rLayout.GetNextGlyphs(1, , 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, );
+CFRelease(pDesc);
+}
+
+CGContextScaleCTM(mrContext, 1.0, -1.0);
+CGContextRotateCTM(mrContext, rStyle.mfFontRotation);
+CGContextSetShouldAntialias(mrContext, !mbNonAntialiasedText);
+CGContextSetFillColor(mrContext, maTextColor.AsArray());
+
+std::vector::const_iterator aStart = aGlyphRotation.begin();
+std::vector::const_iterator aEnd = aGlyphRotation.end();
+std::vector::const_iterator aI = aStart;
+while (aI != aEnd)
+{
+bool nGlyphRotation = *aI;
+std::vector::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, [nStartIndex], 
[nStartIndex], nLen, mrContext);
+else
+CTFontDrawGlyphs(pFont, [nStartIndex], 
[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)
commit 8e0d41fcae628582a01f50d0510d2e0daf3077fc
Author: Khaled Hosny 
Date:   Mon Sep 26 19:09:52 2016 +0200

Support vertical text in CommonSalLayout

Change-Id: I52a71c9c21ad75c7cb9c8574e5e7e3b7c1c0c0c3

diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index 

[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - 7 commits - vcl/inc vcl/quartz vcl/source vcl/unx vcl/win

2016-10-14 Thread Khaled Hosny
Rebased ref, commits from common ancestor:
commit c8e0298987f12f732c686f3ccd2ee4e342d8f89c
Author: Khaled Hosny 
Date:   Fri Oct 14 02:50:27 2016 -0700

Support font fallback on macOS for CommonSalLayout

Change-Id: Ifd26b7f14ed77a3aa2a38e5961cac5f9bbb6d796

diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index f7e5156..6958541 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -102,6 +102,8 @@ public:
 hb_font_t* GetHbFont() const { return mpHbFont; }
 void   SetHbFont(hb_font_t* pHbFont) const { mpHbFont = pHbFont; }
 
+CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
+
 const CoreTextFontFace*  mpFontData;
 /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
 float   mfFontStretch;
@@ -113,11 +115,6 @@ private:
 /// CoreText text style object
 CFMutableDictionaryRef  mpStyleDict;
 mutable hb_font_t*  mpHbFont;
-
-friend class CTLayout;
-friend class AquaSalGraphics;
-friend class CommonSalLayout;
-CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
 };
 
 // TODO: move into cross-platform headers
@@ -172,8 +169,8 @@ protected:
 RGBAColor   maFillColor;
 
 // Device Font settings
-const CoreTextFontFace* mpFontData;
-CoreTextStyle*  mpTextStyle;
+const CoreTextFontFace* mpFontData[MAX_FALLBACK];
+CoreTextStyle*  mpTextStyle[MAX_FALLBACK];
 RGBAColor   maTextColor;
 /// allows text to be rendered without antialiasing
 boolmbNonAntialiasedText;
diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx
index 856e066..983f50b 100644
--- a/vcl/quartz/ctlayout.cxx
+++ b/vcl/quartz/ctlayout.cxx
@@ -28,7 +28,6 @@
 #include "quartz/ctfonts.hxx"
 #include "CTRunData.hxx"
 #include "quartz/utils.h"
-#include "CommonSalLayout.hxx"
 
 
 class CTLayout : public SalLayout
@@ -782,10 +781,7 @@ void CTLayout::Simplify( bool /*bIsBase*/ ) {}
 
 SalLayout* CoreTextStyle::GetTextLayout() const
 {
-if (SalLayout::UseCommonLayout())
-return new CommonSalLayout(*this);
-else
-return new CTLayout(this);
+return new CTLayout(this);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index bb99737..caa7e35 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -42,6 +42,8 @@
 #include "impfontcharmap.hxx"
 #include "impfontmetricdata.hxx"
 #include "CommonSalLayout.hxx"
+#include "outdev.h"
+#include "PhysicalFontCollection.hxx"
 
 #ifdef MACOSX
 #include "osx/salframe.h"
@@ -55,6 +57,49 @@
 
 using namespace vcl;
 
+class CoreTextGlyphFallbackSubstititution
+:public ImplGlyphFallbackFontSubstitution
+{
+public:
+bool FindFontSubstitute(FontSelectPattern&, OUString&) const override;
+};
+
+bool 
CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern& 
rPattern,
+OUString& rMissingChars) const
+{
+bool bFound = false;
+CoreTextStyle rStyle(rPattern);
+CTFontRef pFont = 
static_cast(CFDictionaryGetValue(rStyle.GetStyleDict(), 
kCTFontAttributeName));
+CFStringRef pStr = CreateCFString(rMissingChars);
+if (pStr)
+{
+CTFontRef pFallback = CTFontCreateForString(pFont, pStr, 
CFRangeMake(0, CFStringGetLength(pStr)));
+if (pFallback)
+{
+bFound = true;
+
+CTFontDescriptorRef pDesc = CTFontCopyFontDescriptor(pFallback);
+FontAttributes rAttr = DevFontFromCTFontDescriptor(pDesc, nullptr);
+
+rPattern.maSearchName = rAttr.GetFamilyName();
+
+rPattern.SetWeight(rAttr.GetWeight());
+rPattern.SetItalic(rAttr.GetItalic());
+rPattern.SetPitch(rAttr.GetPitch());
+rPattern.SetWidthType(rAttr.GetWidthType());
+
+SalData* pSalData = GetSalData();
+if (pSalData->mpFontList)
+rPattern.mpFontData = 
pSalData->mpFontList->GetFontDataFromId(reinterpret_cast(pDesc));
+
+CFRelease(pFallback);
+}
+CFRelease(pStr);
+}
+
+return bFound;
+}
+
 CoreTextFontFace::CoreTextFontFace( const CoreTextFontFace& rSrc )
   : PhysicalFontFace( rSrc )
   , mnFontId( rSrc.mnFontId )
@@ -245,8 +290,6 @@ AquaSalGraphics::AquaSalGraphics()
 , mxClipPath( nullptr )
 , maLineColor( COL_WHITE )
 , maFillColor( COL_BLACK )
-, mpFontData( nullptr )
-, mpTextStyle( nullptr )
 , maTextColor( COL_BLACK )
 , mbNonAntialiasedText( false )
 , mbPrinter( false )
@@ -258,6 +301,12 @@ AquaSalGraphics::AquaSalGraphics()
 #endif
 {
 SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this 
);
+
+for (int i = 0; i < MAX_FALLBACK; ++i)
+{
+mpTextStyle[i] = nullptr;
+