[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - vcl/inc vcl/quartz
Khaled Hosny
khaledhosny at eglug.org
Fri Oct 14 15:14:58 UTC 2016
Rebased ref, commits from common ancestor:
commit 06971a9d9a17e73c8f589df1f9a0402c8ce8cab7
Author: Khaled Hosny <khaledhosny at eglug.org>
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
bool mbNonAntialiasedText;
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..a7895c3 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<CTFontRef>(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<sal_IntPtr>(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;
+ mpFontData[i] = nullptr;
+ }
}
AquaSalGraphics::~AquaSalGraphics()
@@ -270,7 +319,8 @@ AquaSalGraphics::~AquaSalGraphics()
CGPathRelease( mxClipPath );
}
- delete mpTextStyle;
+ for (int i = 0; i < MAX_FALLBACK; ++i)
+ delete mpTextStyle[i];
if( mpXorEmulation )
delete mpXorEmulation;
@@ -308,9 +358,12 @@ void AquaSalGraphics::SetTextColor( SalColor nSalColor )
// SAL_ DEBUG(std::hex << nSalColor << std::dec << "={" << maTextColor.GetRed() << ", " << maTextColor.GetGreen() << ", " << maTextColor.GetBlue() << ", " << maTextColor.GetAlpha() << "}");
}
-void AquaSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int /*nFallbackLevel*/ )
+void AquaSalGraphics::GetFontMetric(ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel)
{
- mpTextStyle->GetFontMetric( rxFontMetric );
+ if (nFallbackLevel < MAX_FALLBACK && mpTextStyle[nFallbackLevel])
+ {
+ mpTextStyle[nFallbackLevel]->GetFontMetric(rxFontMetric);
+ }
}
static bool AddTempDevFont(const OUString& rFontFileURL)
@@ -387,6 +440,12 @@ void AquaSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection )
// Copy all PhysicalFontFace objects contained in the SystemFontList
pSalData->mpFontList->AnnounceFonts( *pFontCollection );
+
+ if (SalLayout::UseCommonLayout())
+ {
+ static CoreTextGlyphFallbackSubstititution aSubstFallback;
+ pFontCollection->SetFallbackHook(&aSubstFallback);
+ }
}
void AquaSalGraphics::ClearDevFontCache()
@@ -404,14 +463,24 @@ bool AquaSalGraphics::AddTempDevFont( PhysicalFontCollection*,
bool AquaSalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& rPolyPoly )
{
- const bool bRC = mpTextStyle->GetGlyphOutline( aGlyphId, rPolyPoly );
- return bRC;
+ const int nFallbackLevel = aGlyphId >> GF_FONTSHIFT;
+ if (nFallbackLevel < MAX_FALLBACK && mpTextStyle[nFallbackLevel])
+ {
+ const bool bRC = mpTextStyle[nFallbackLevel]->GetGlyphOutline(aGlyphId, rPolyPoly);
+ return bRC;
+ }
+ return false;
}
bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
{
- const bool bRC = mpTextStyle->GetGlyphBoundRect( aGlyphId, rRect );
- return bRC;
+ const int nFallbackLevel = aGlyphId >> GF_FONTSHIFT;
+ if (nFallbackLevel < MAX_FALLBACK && mpTextStyle[nFallbackLevel])
+ {
+ const bool bRC = mpTextStyle[nFallbackLevel]->GetGlyphBoundRect(aGlyphId, rRect);
+ return bRC;
+ }
+ return false;
}
void AquaSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
@@ -449,60 +518,71 @@ void AquaSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
CGContextRestoreGState(context);
}
-void AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ )
+void AquaSalGraphics::SetFont(FontSelectPattern* pReqFont, int nFallbackLevel)
{
// release the text style
- delete mpTextStyle;
- mpTextStyle = nullptr;
+ for (int i = nFallbackLevel; i < MAX_FALLBACK; ++i)
+ {
+ delete mpTextStyle[i];
+ mpTextStyle[i] = nullptr;
+ }
// handle NULL request meaning: release-font-resources request
if( !pReqFont )
{
- mpFontData = nullptr;
+ mpFontData[nFallbackLevel] = nullptr;
return;
}
// update the text style
- mpFontData = static_cast<const CoreTextFontFace*>( pReqFont->mpFontData );
- mpTextStyle = new CoreTextStyle( *pReqFont );
+ mpFontData[nFallbackLevel] = static_cast<const CoreTextFontFace*>(pReqFont->mpFontData);
+ mpTextStyle[nFallbackLevel] = new CoreTextStyle(*pReqFont);
SAL_INFO("vcl.ct",
"SetFont"
- " to " << mpFontData->GetFamilyName()
- << ", " << mpFontData->GetStyleName()
- << " fontid=" << mpFontData->GetFontId()
+ " to " << mpFontData[nFallbackLevel]->GetFamilyName()
+ << ", " << mpFontData[nFallbackLevel]->GetStyleName()
+ << " fontid=" << mpFontData[nFallbackLevel]->GetFontId()
<< " for " << pReqFont->GetFamilyName()
<< ", " << pReqFont->GetStyleName()
<< " weight=" << pReqFont->GetWeight()
<< " slant=" << pReqFont->GetItalic()
<< " size=" << pReqFont->mnHeight << "x" << pReqFont->mnWidth
<< " orientation=" << pReqFont->mnOrientation
+ << " fallback level " << nFallbackLevel
);
}
-SalLayout* AquaSalGraphics::GetTextLayout( ImplLayoutArgs& /*rArgs*/, int /*nFallbackLevel*/ )
+SalLayout* AquaSalGraphics::GetTextLayout(ImplLayoutArgs& /*rArgs*/, int nFallbackLevel)
{
- SalLayout* pSalLayout = mpTextStyle->GetTextLayout();
+ SalLayout* pSalLayout = nullptr;
+ if (mpTextStyle[nFallbackLevel])
+ {
+ if (SalLayout::UseCommonLayout())
+ pSalLayout = new CommonSalLayout(*mpTextStyle[nFallbackLevel]);
+ else
+ pSalLayout = mpTextStyle[nFallbackLevel]->GetTextLayout();
+ }
return pSalLayout;
}
const FontCharMapRef AquaSalGraphics::GetFontCharMap() const
{
- if( !mpFontData )
+ if (!mpFontData[0])
{
FontCharMapRef xFontCharMap( new FontCharMap() );
return xFontCharMap;
}
- return mpFontData->GetFontCharMap();
+ return mpFontData[0]->GetFontCharMap();
}
bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
{
- if( !mpFontData )
+ if (!mpFontData[0])
return false;
- return mpFontData->GetFontCapabilities(rFontCapabilities);
+ return mpFontData[0]->GetFontCapabilities(rFontCapabilities);
}
// fake a SFNT font directory entry for a font table
@@ -772,7 +852,8 @@ void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bV
free( const_cast<TTSimpleGlyphMetrics *>(pGlyphMetrics) );
}
- FontCharMapRef xFCMap = mpFontData->GetFontCharMap();
+ // XXX: mpFontData[0] is most likely wrong here
+ FontCharMapRef xFCMap = mpFontData[0]->GetFontCharMap();
SAL_WARN_IF( !xFCMap || !xFCMap->GetCharCount(), "vcl", "no charmap" );
// get unicode<->glyph encoding
More information about the Libreoffice-commits
mailing list