[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - 140 commits - android/source chart2/source compilerplugins/clang config_host.mk.in configure.ac cppuhelper/qa cui/source cui/uiconfig dbaccess/source desktop/source distro-configs/Jenkins download.lst editeng/source extensions/source external/accessories external/harfbuzz external/libzmf external/Module_external.mk filter/source helpcontent2 icon-themes/breeze icon-themes/galaxy icon-themes/sifr icon-themes/tango idl/inc idl/source include/sfx2 include/sot include/store include/svl include/svtools include/svx include/vcl include/xmloff Makefile.fetch officecfg/registry registry/source Repository.mk scp2/InstallModule_accessories.mk scp2/InstallModule_extensions.mk scp2/Module_scp2.mk scp2/source sc/qa sc/source sc/uiconfig sd/inc sd/sdi sd/source sd/uiconfig sd/UIConfig_simpress.mk setup_native/source sfx2/Library_sfx.mk sfx2/source sfx2/uiconfig shell/inc shell/source sot/source starmath/inc starmath/source stoc/source svl/source svtools/source svx/inc svx/sdi svx/source sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk vcl/headless vcl/inc vcl/Library_vcl.mk vcl/quartz vcl/README.vars vcl/source vcl/unx vcl/win writerfilter/source writerperfect/inc writerperfect/Library_wpftdraw.mk writerperfect/qa writerperfect/source xmloff/inc xmloff/source
Khaled Hosny
khaledhosny at eglug.org
Fri Sep 9 15:28:29 UTC 2016
Rebased ref, commits from common ancestor:
commit 044f956d279a87a34d26674b67bcfd631b4d7424
Author: Khaled Hosny <khaledhosny at eglug.org>
Date: Wed Sep 7 23:26:14 2016 +0200
Don’t check glyph class unnecessarily
Don’t call hb_ot_layout_get_glyph_class() unless the glyph advance width
is zero, as we really do not use its result otherwise.
Change-Id: Id02238abef91b9343931f1886d54d966d7157f25
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 6ce42d2..71fc186 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -439,9 +439,8 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
if (hb_ot_layout_has_glyph_classes(pHBFace))
{
// the font has GDEF table
- bool bMark = hb_ot_layout_get_glyph_class(pHBFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
- if (bMark && pHbPositions[i].x_advance == 0)
- bDiacritic = true;
+ if (pHbPositions[i].x_advance == 0)
+ bDiacritic = hb_ot_layout_get_glyph_class(pHBFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
}
else
{
commit eb5b2a609578ff5e28ed27cf9a92e78538c945c7
Author: Khaled Hosny <khaledhosny at eglug.org>
Date: Wed Sep 7 19:40:11 2016 +0200
Cache HarfBuzz font
We now create it only once per physical font, saves us few percents from
the all over time spent on layout.
Change-Id: I8de582cb20a168c93d72921e539c2477fa97fb54
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index cd68c93..34cca79 100755
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -35,7 +35,7 @@
class CommonSalLayout : public GenericSalLayout
{
- hb_face_t* mpHBFace;
+ hb_font_t* mpHBFont;
FontSelectPattern maFontSelData;
css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
#ifdef _WIN32
@@ -48,7 +48,6 @@ class CommonSalLayout : public GenericSalLayout
ServerFont& mrServerFont;
#endif
- hb_font_t* GetHBFont();
public:
#if defined(_WIN32)
explicit CommonSalLayout(WinSalGraphics*, WinFontInstance&, const WinFontFace&);
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 0302203..a14b2d8 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -99,8 +99,8 @@ public:
void GetFontMetric( ImplFontMetricDataRef& ) const;
bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const;
bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const;
- hb_face_t* GetHBFace() const { return mpHBFace; }
- void SetHBFace(hb_face_t* pHBFace) const { mpHBFace = pHBFace; }
+ hb_font_t* GetHBFont() const { return mpHBFont; }
+ void SetHBFont(hb_font_t* pHBFont) const { mpHBFont = pHBFont; }
const CoreTextFontFace* mpFontData;
/// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
@@ -112,7 +112,7 @@ public:
private:
/// CoreText text style object
CFMutableDictionaryRef mpStyleDict;
- mutable hb_face_t* mpHBFace;
+ mutable hb_font_t* mpHBFont;
friend class CTLayout;
friend class AquaSalGraphics;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index af21922..11f94d9 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -182,8 +182,8 @@ public:
sal_GlyphId FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const;
bool GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& ) const;
bool GetAntialiasAdvice() const;
- hb_face_t* GetHBFace() { return mpHBFace; }
- void SetHBFace( hb_face_t* pHBFace ) { mpHBFace=pHBFace; }
+ hb_font_t* GetHBFont() { return mpHBFont; }
+ void SetHBFont( hb_font_t* pHBFont ) { mpHBFont = pHBFont; }
private:
friend class GlyphCache;
@@ -243,7 +243,7 @@ private:
GlyphSubstitution maGlyphSubstitution;
ServerFontLayoutEngine* mpLayoutEngine;
- hb_face_t* mpHBFace;
+ hb_font_t* mpHBFont;
};
// a class for cache entries for physical font instances that are based on serverfonts
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 4e84b6f..b1b542e 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -142,12 +142,12 @@ private:
mutable std::unordered_set<sal_UCS4> maGsubTable;
mutable bool mbGsubRead;
- mutable hb_face_t* mpHBFace;
+ mutable hb_font_t* mpHBFont;
public:
bool HasGSUBstitutions( HDC ) const;
bool IsGSUBstituted( sal_UCS4 ) const;
- hb_face_t* GetHBFace() const { return mpHBFace; }
- void SetHBFace( hb_face_t* pHBFace ) const { mpHBFace = pHBFace; }
+ hb_font_t* GetHBFont() const { return mpHBFont; }
+ void SetHBFont( hb_font_t* pHBFont ) const { mpHBFont = pHBFont; }
};
/** Class that creates (and destroys) a compatible Device Context.
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 943cc31..9e2c624 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -50,7 +50,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
, mfFontRotation( 0.0 )
, maFontSelData( rFSD )
, mpStyleDict( nullptr )
- , mpHBFace( nullptr )
+ , mpHBFont( nullptr )
{
const FontSelectPattern* const pReqFont = &rFSD;
@@ -117,8 +117,8 @@ CoreTextStyle::~CoreTextStyle()
{
if( mpStyleDict )
CFRelease( mpStyleDict );
- if( mpHBFace )
- hb_face_destroy( mpHBFace );
+ if( mpHBFont )
+ hb_font_destroy( mpHBFont );
}
void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef& rxFontMetric ) const
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index e373a15..6ce42d2 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -90,6 +90,32 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
return pBlob;
}
+static hb_font_t* createHBFont(hb_face_t* pHBFace)
+{
+ hb_font_t* pHBFont = hb_font_create(pHBFace);
+ hb_ot_font_set_funcs(pHBFont);
+
+ return pHBFont;
+}
+
+static void scaleHBFont(hb_font_t* pHBFont, FontSelectPattern aFontSelData)
+{
+ uint64_t nXScale = aFontSelData.mnWidth << 6;
+ uint64_t nYScale = aFontSelData.mnHeight << 6;
+
+#if defined(_WIN32)
+ // HACK to get stretched/shrunken text. TODO: Get rid of HACK
+ if (nXScale)
+ nXScale = double(nXScale) * 1.812;
+#endif
+
+ if (!nXScale)
+ nXScale = nYScale;
+
+ hb_font_set_ppem(pHBFont, nXScale, nYScale);
+ hb_font_set_scale(pHBFont, nXScale, nYScale);
+}
+
static hb_unicode_funcs_t* getUnicodeFuncs()
{
static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
@@ -103,16 +129,15 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
: mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)),
mhDC(WSL->getHDC()),
- mpHBFace(nullptr),
maFontSelData(rWinFontInstance.maFontSelData),
mpD2DRenderer(nullptr)
{
- mpHBFace = rWinFontFace.GetHBFace();
- if(!mpHBFace)
+ mpHBFont = rWinFontFace.GetHBFont();
+ if (!mpHBFont)
{
mpD2DRenderer = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get());
WinSalGraphicsWithIDFace* pWSLWithIDFace = new WinSalGraphicsWithIDFace(WSL, mpD2DRenderer->GetDWriteFontFace(mhDC));
- mpHBFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
+ hb_face_t* pHBFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
[](void* pUserData)
{
WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>( pUserData );
@@ -121,8 +146,14 @@ CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontI
delete pUData;
}
);
- rWinFontFace.SetHBFace(mpHBFace);
+
+ mpHBFont = createHBFont(pHBFace);
+ rWinFontFace.SetHBFont(mpHBFont);
+
+ hb_face_destroy(pHBFace);
}
+
+ scaleHBFont(mpHBFont, maFontSelData);
}
void CommonSalLayout::InitFont() const
@@ -132,58 +163,49 @@ void CommonSalLayout::InitFont() const
#elif defined(MACOSX) || defined(IOS)
CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
-: mpHBFace(nullptr),
- maFontSelData(rCoreTextStyle.maFontSelData),
+: maFontSelData(rCoreTextStyle.maFontSelData),
mrCoreTextStyle(rCoreTextStyle)
{
- mpHBFace = rCoreTextStyle.GetHBFace();
- if(!mpHBFace)
+ mpHBFont = rCoreTextStyle.GetHBFont();
+ if (!mpHBFont)
{
+ hb_face_t* pHBFace;
CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
if(pCGFont)
- {
- mpHBFace = hb_coretext_face_create(pCGFont);
- }
+ pHBFace = hb_coretext_face_create(pCGFont);
else
- {
- mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
- }
+ pHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
CGFontRelease(pCGFont);
- rCoreTextStyle.SetHBFace(mpHBFace);
+
+ mpHBFont = createHBFont(pHBFace);
+ rCoreTextStyle.SetHBFont(mpHBFont);
+
+ hb_face_destroy(pHBFace);
}
+
+ scaleHBFont(mpHBFont, maFontSelData);
}
#else
CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
-: mpHBFace(nullptr),
- maFontSelData(rServerFont.GetFontSelData()),
+: maFontSelData(rServerFont.GetFontSelData()),
mrServerFont(rServerFont)
{
- mpHBFace = rServerFont.GetHBFace();
- if(!mpHBFace)
+ mpHBFont = rServerFont.GetHBFont();
+ if (!mpHBFont)
{
- mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
- mrServerFont.SetHBFace(mpHBFace);
- }
-}
-#endif
+ hb_face_t* pHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
-hb_font_t* CommonSalLayout::GetHBFont()
-{
- // HACK. TODO: Get rid of HACK
-#if defined(_WIN32)
- if(maFontSelData.mnWidth)
- maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812;
-#endif
+ mpHBFont = createHBFont(pHBFace);
+ mrServerFont.SetHBFont(mpHBFont);
- hb_font_t* pHBFont = hb_font_create(mpHBFace);
- hb_font_set_ppem(pHBFont, maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight , maFontSelData.mnHeight);
- hb_font_set_scale(pHBFont, (uint64_t)(maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight) << 6
- , (uint64_t)maFontSelData.mnHeight << 6);
- hb_ot_font_set_funcs(pHBFont);
- return pHBFont;
+ hb_face_destroy(pHBFace);
+ }
+
+ scaleHBFont(mpHBFont, maFontSelData);
}
+#endif
struct HbScriptRun
{
@@ -271,18 +293,16 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
if((rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray)
{
- hb_font_t* pHBFont = GetHBFont();
hb_codepoint_t nKashidaCodePoint = 0x0640;
hb_codepoint_t nKashidaGlyphIndex;
- if(hb_font_get_glyph(pHBFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex))
+ if(hb_font_get_glyph(mpHBFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex))
{
if(nKashidaGlyphIndex)
{
- KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(pHBFont, nKashidaGlyphIndex) >> 6);
+ KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(mpHBFont, nKashidaGlyphIndex) >> 6);
}
}
- hb_font_destroy(pHBFont);
}
}
@@ -294,7 +314,6 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const
bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
{
- hb_font_t* pHBFont = GetHBFont();
hb_script_t aHbScript = HB_SCRIPT_INVALID;
int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos);
@@ -383,7 +402,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
#if HB_VERSION_ATLEAST(0, 9, 42)
hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
#endif
- hb_shape(pHBFont, pHbBuffer, nullptr, 0);
+ hb_shape(mpHBFont, pHbBuffer, nullptr, 0);
int nRunGlyphCount = hb_buffer_get_length(pHbBuffer);
hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
@@ -416,10 +435,11 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
bool bDiacritic = false;
- if (hb_ot_layout_has_glyph_classes(mpHBFace))
+ hb_face_t* pHBFace = hb_font_get_face(mpHBFont);
+ if (hb_ot_layout_has_glyph_classes(pHBFace))
{
// the font has GDEF table
- bool bMark = hb_ot_layout_get_glyph_class(mpHBFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
+ bool bMark = hb_ot_layout_get_glyph_class(pHBFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
if (bMark && pHbPositions[i].x_advance == 0)
bDiacritic = true;
}
@@ -456,8 +476,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
}
}
- hb_font_destroy(pHBFont);
-
SortGlyphItems();
if((rArgs.mpDXArray || rArgs.mnLayoutWidth)
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index ce06ee0..eb44e66 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -462,7 +462,7 @@ ServerFont::ServerFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI )
mbArtBold( false ),
mbUseGamma( false ),
mpLayoutEngine( nullptr ),
- mpHBFace( nullptr )
+ mpHBFont( nullptr )
{
// TODO: move update of mpFontInstance into FontEntry class when
// it becomes responsible for the ServerFont instantiation
@@ -611,8 +611,8 @@ ServerFont::~ServerFont()
mpFontInfo->ReleaseFaceFT();
- if( mpHBFace )
- hb_face_destroy( mpHBFace );
+ if( mpHBFont )
+ hb_font_destroy( mpHBFont );
ReleaseFromGarbageCollect();
}
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 295c640..eb6c9d3 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1009,7 +1009,7 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
mbAliasSymbolsHigh( false ),
mbAliasSymbolsLow( false ),
mbGsubRead( false ),
- mpHBFace( nullptr )
+ mpHBFont( nullptr )
{
SetBitmapSize( 0, nHeight );
@@ -1051,8 +1051,8 @@ WinFontFace::~WinFontFace()
#endif // ENABLE_GRAPHITE
delete mpEncodingVector;
- if( mpHBFace )
- hb_face_destroy( mpHBFace );
+ if( mpHBFont )
+ hb_font_destroy( mpHBFont );
}
sal_IntPtr WinFontFace::GetFontId() const
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 514029d..6fe411a 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -4065,8 +4065,8 @@ PhysicalFontFace* WinFontFace::Clone() const
if ( mpGraphiteData )
mpGraphiteData->AddReference();
#endif
- if( mpHBFace )
- hb_face_reference( mpHBFace );
+ if( mpHBFont )
+ hb_font_reference( mpHBFont );
PhysicalFontFace* pClone = new WinFontFace( *this );
return pClone;
commit 126181727a20dadc2b0f7630afdd4f022bb1b483
Author: Khaled Hosny <khaledhosny at eglug.org>
Date: Wed Sep 7 17:44:49 2016 +0200
Match changes in master
Change-Id: I667a18e65dd8243340776fa71842e84b08f4680d
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index f03cc0c..e373a15 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -389,12 +389,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
hb_glyph_position_t *pHbPositions = hb_buffer_get_glyph_positions(pHbBuffer, nullptr);
- sal_Int32 nGraphemeStartPos = std::numeric_limits<sal_Int32>::max();
- sal_Int32 nGraphemeEndPos = std::numeric_limits<sal_Int32>::min();
- com::sun::star::lang::Locale aLocale(rArgs.maLanguageTag.getLocale());
- if (!mxBreak.is())
- mxBreak = vcl::unohelper::CreateBreakIterator();
-
for (int i = 0; i < nRunGlyphCount; ++i) {
int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
int32_t nCharPos = pHbGlyphInfos[i].cluster;
@@ -411,22 +405,8 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0);
bool bInCluster = false;
- if(bRightToLeft && (nCharPos < nGraphemeStartPos))
- {
- sal_Int32 nDone;
- nGraphemeStartPos = mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale,
- com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
- }
- else if(!bRightToLeft && (nCharPos >= nGraphemeEndPos))
- {
- sal_Int32 nDone;
- nGraphemeEndPos = mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale,
- com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
- }
- else
- {
+ if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
bInCluster = true;
- }
long nGlyphFlags = 0;
if (bRightToLeft)
commit db476db156033af6bf52902b4e23c9702ce82d7a
Author: Akash Jain <akash96j at gmail.com>
Date: Wed Aug 17 21:31:22 2016 +0530
GSoC: Speed up CommonSalLayout by caching hb_face
Cache hb_face so it is not created again and again.
Switch from GDI to DirectWrite on Windows to obtain SFNT table data.
Change-Id: I9c532cd72e1f6b57313f3b7d42a6b9b0633eb0ef
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 8fc398a..cd68c93 100755
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -41,6 +41,7 @@ class CommonSalLayout : public GenericSalLayout
#ifdef _WIN32
HDC mhDC;
HFONT mhFont;
+ D2DWriteTextOutRenderer* mpD2DRenderer;
#elif defined(MACOSX) || defined(IOS)
const CoreTextStyle& mrCoreTextStyle;
#else
@@ -50,7 +51,7 @@ class CommonSalLayout : public GenericSalLayout
hb_font_t* GetHBFont();
public:
#if defined(_WIN32)
- explicit CommonSalLayout(HDC, WinFontInstance&);
+ explicit CommonSalLayout(WinSalGraphics*, WinFontInstance&, const WinFontFace&);
virtual void InitFont() const override;
#elif defined(MACOSX) || defined(IOS)
explicit CommonSalLayout(const CoreTextStyle&);
@@ -60,7 +61,6 @@ public:
const ServerFont& getFontData() const { return mrServerFont; };
#endif
- virtual ~CommonSalLayout();
void SetNeedFallback(ImplLayoutArgs&, sal_Int32, bool);
void AdjustLayout(ImplLayoutArgs&) override;
virtual bool LayoutText(ImplLayoutArgs&) override;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index a1a8b28..0302203 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -45,6 +45,7 @@
#include "quartz/salgdicommon.hxx"
#include <unordered_map>
+#include <hb-ot.h>
class AquaSalFrame;
class FontAttributes;
@@ -98,6 +99,8 @@ public:
void GetFontMetric( ImplFontMetricDataRef& ) const;
bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const;
bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const;
+ hb_face_t* GetHBFace() const { return mpHBFace; }
+ void SetHBFace(hb_face_t* pHBFace) const { mpHBFace = pHBFace; }
const CoreTextFontFace* mpFontData;
/// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
@@ -109,6 +112,7 @@ public:
private:
/// CoreText text style object
CFMutableDictionaryRef mpStyleDict;
+ mutable hb_face_t* mpHBFace;
friend class CTLayout;
friend class AquaSalGraphics;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index f3754a3..af21922 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -35,6 +35,7 @@
#include <sallayout.hxx>
#include "fontattributes.hxx"
#include "impfontmetricdata.hxx"
+#include "hb-ot.h"
#include <unordered_map>
@@ -181,6 +182,8 @@ public:
sal_GlyphId FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const;
bool GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& ) const;
bool GetAntialiasAdvice() const;
+ hb_face_t* GetHBFace() { return mpHBFace; }
+ void SetHBFace( hb_face_t* pHBFace ) { mpHBFace=pHBFace; }
private:
friend class GlyphCache;
@@ -240,6 +243,7 @@ private:
GlyphSubstitution maGlyphSubstitution;
ServerFontLayoutEngine* mpLayoutEngine;
+ hb_face_t* mpHBFace;
};
// a class for cache entries for physical font instances that are based on serverfonts
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 2defd7f..4e84b6f 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -44,6 +44,9 @@
# include "postwin.h"
#endif
+#include <hb-ot.h>
+#include <dwrite.h>
+
class FontSelectPattern;
class WinFontInstance;
class ImplFontAttrCache;
@@ -139,10 +142,12 @@ private:
mutable std::unordered_set<sal_UCS4> maGsubTable;
mutable bool mbGsubRead;
+ mutable hb_face_t* mpHBFace;
public:
bool HasGSUBstitutions( HDC ) const;
bool IsGSUBstituted( sal_UCS4 ) const;
- static int GetTable( const char pTagName[5], const unsigned char*&, HDC );
+ hb_face_t* GetHBFace() const { return mpHBFace; }
+ void SetHBFace( hb_face_t* pHBFace ) const { mpHBFace = pHBFace; }
};
/** Class that creates (and destroys) a compatible Device Context.
@@ -354,6 +359,7 @@ private:
sal_uLong GetKernPairs();
public:
+ sal_uLong GetTable( const char pTagName[5], const unsigned char*&, void*&, IDWriteFontFace*& );
// public SalGraphics methods, the interface to the independent vcl part
// get device resolution
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 28be80b..943cc31 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -50,6 +50,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
, mfFontRotation( 0.0 )
, maFontSelData( rFSD )
, mpStyleDict( nullptr )
+ , mpHBFace( nullptr )
{
const FontSelectPattern* const pReqFont = &rFSD;
@@ -116,6 +117,8 @@ CoreTextStyle::~CoreTextStyle()
{
if( mpStyleDict )
CFRelease( mpStyleDict );
+ if( mpHBFace )
+ hb_face_destroy( mpHBFace );
}
void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef& rxFontMetric ) const
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index e527174..f03cc0c 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -26,6 +26,21 @@
#include <limits>
#include <salgdi.hxx>
+#if defined(_WIN32)
+struct WinSalGraphicsWithIDFace
+{
+ WinSalGraphics* mpWSL;
+ IDWriteFontFace* mpIDFace;
+ void* mpTableContext;
+
+ WinSalGraphicsWithIDFace( WinSalGraphics* pWSL, IDWriteFontFace* pIDFace )
+ : mpWSL( pWSL ),
+ mpIDFace( pIDFace ),
+ mpTableContext( nullptr )
+ {}
+};
+#endif
+
static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
{
char pTagName[5];
@@ -38,8 +53,8 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
sal_uLong nLength=0;
#if defined(_WIN32)
const unsigned char* pBuffer = nullptr;
- HDC* phDC = static_cast<HDC*>(pUserData);
- nLength = WinFontFace::GetTable(pTagName, pBuffer, *phDC);
+ WinSalGraphicsWithIDFace* pWSLWithIDFace = static_cast<WinSalGraphicsWithIDFace*>(pUserData);
+ nLength = (pWSLWithIDFace->mpWSL)->GetTable(pTagName, pBuffer, pWSLWithIDFace->mpTableContext, pWSLWithIDFace->mpIDFace);
#elif defined(MACOSX) || defined(IOS)
unsigned char* pBuffer = nullptr;
CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData);
@@ -57,7 +72,15 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
hb_blob_t* pBlob = nullptr;
if (pBuffer != nullptr)
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
+#if defined(_WIN32)
+ pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, pWSLWithIDFace,
+ [](void* pUserData)
+ {
+ WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>(pUserData);
+ pUData->mpIDFace->ReleaseFontTable(pUData->mpTableContext);
+ }
+ );
+#elif defined(MACOSX) || defined(IOS)
pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
#else
@@ -77,13 +100,29 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
}
#if defined(_WIN32)
-CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
-: mhDC(hDC),
- mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)),
+CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
+: mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)),
+ mhDC(WSL->getHDC()),
mpHBFace(nullptr),
- maFontSelData(rWinFontInstance.maFontSelData)
+ maFontSelData(rWinFontInstance.maFontSelData),
+ mpD2DRenderer(nullptr)
{
- mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr);
+ mpHBFace = rWinFontFace.GetHBFace();
+ if(!mpHBFace)
+ {
+ mpD2DRenderer = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get());
+ WinSalGraphicsWithIDFace* pWSLWithIDFace = new WinSalGraphicsWithIDFace(WSL, mpD2DRenderer->GetDWriteFontFace(mhDC));
+ mpHBFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
+ [](void* pUserData)
+ {
+ WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>( pUserData );
+ if(pUData->mpIDFace)
+ pUData->mpIDFace->Release();
+ delete pUData;
+ }
+ );
+ rWinFontFace.SetHBFace(mpHBFace);
+ }
}
void CommonSalLayout::InitFont() const
@@ -97,17 +136,22 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
maFontSelData(rCoreTextStyle.maFontSelData),
mrCoreTextStyle(rCoreTextStyle)
{
- CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
- CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
- if(pCGFont)
- {
- mpHBFace = hb_coretext_face_create(pCGFont);
- }
- else
+ mpHBFace = rCoreTextStyle.GetHBFace();
+ if(!mpHBFace)
{
- mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+ CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
+ CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
+ if(pCGFont)
+ {
+ mpHBFace = hb_coretext_face_create(pCGFont);
+ }
+ else
+ {
+ mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+ }
+ CGFontRelease(pCGFont);
+ rCoreTextStyle.SetHBFace(mpHBFace);
}
- CGFontRelease(pCGFont);
}
#else
@@ -116,15 +160,15 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
maFontSelData(rServerFont.GetFontSelData()),
mrServerFont(rServerFont)
{
- mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
+ mpHBFace = rServerFont.GetHBFace();
+ if(!mpHBFace)
+ {
+ mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
+ mrServerFont.SetHBFace(mpHBFace);
+ }
}
#endif
-CommonSalLayout::~CommonSalLayout()
-{
- hb_face_destroy(mpHBFace);
-}
-
hb_font_t* CommonSalLayout::GetHBFont()
{
// HACK. TODO: Get rid of HACK
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index c7c59bb..ce06ee0 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -461,7 +461,8 @@ ServerFont::ServerFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI )
mbArtItalic( false ),
mbArtBold( false ),
mbUseGamma( false ),
- mpLayoutEngine( nullptr )
+ mpLayoutEngine( nullptr ),
+ mpHBFace( nullptr )
{
// TODO: move update of mpFontInstance into FontEntry class when
// it becomes responsible for the ServerFont instantiation
@@ -610,6 +611,9 @@ ServerFont::~ServerFont()
mpFontInfo->ReleaseFaceFT();
+ if( mpHBFace )
+ hb_face_destroy( mpHBFace );
+
ReleaseFromGarbageCollect();
}
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 0ba1467..295c640 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1008,7 +1008,8 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
mnPitchAndFamily( nPitchAndFamily ),
mbAliasSymbolsHigh( false ),
mbAliasSymbolsLow( false ),
- mbGsubRead( false )
+ mbGsubRead( false ),
+ mpHBFace( nullptr )
{
SetBitmapSize( 0, nHeight );
@@ -1049,6 +1050,9 @@ WinFontFace::~WinFontFace()
#endif
#endif // ENABLE_GRAPHITE
delete mpEncodingVector;
+
+ if( mpHBFace )
+ hb_face_destroy( mpHBFace );
}
sal_IntPtr WinFontFace::GetFontId() const
@@ -1201,16 +1205,22 @@ void WinFontFace::ReadCmapTable( HDC hDC ) const
}
}
-int WinFontFace::GetTable(const char pTagName[5], const unsigned char*& pResBuffer, HDC hDC)
+sal_uLong WinSalGraphics::GetTable( const char pTagName[5], const unsigned char*& pResBuffer, void*& pTableContext, IDWriteFontFace*& pIDFace )
{
- const DWORD nTableTag = CalcTag( pTagName );
- RawFontData aRawFontData( hDC, nTableTag );
-
- if( !aRawFontData.get() )
+ if( !pIDFace )
return 0;
-
- pResBuffer = aRawFontData.steal();
- return aRawFontData.size();
+ const void* pResBuf;
+ UINT32 nSize;
+ BOOL bExists;
+ HRESULT hr = S_OK;
+ const DWORD nTableTag = DWRITE_MAKE_OPENTYPE_TAG( pTagName[0], pTagName[1], pTagName[2], pTagName[3] );
+ hr = pIDFace->TryGetFontTable( nTableTag, &pResBuf, &nSize, &pTableContext, &bExists );
+ if( SUCCEEDED( hr ) && ( bExists ) )
+ {
+ pResBuffer = static_cast<const unsigned char*>(pResBuf);
+ return static_cast<sal_uLong>(nSize);
+ }
+ return 0;
}
void WinFontFace::GetFontCapabilities( HDC hDC ) const
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 538f46a..514029d 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -3518,6 +3518,24 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
return (succeeded && nGlyphs >= 1 && pRectToErase);
}
+IDWriteFontFace* D2DWriteTextOutRenderer::GetDWriteFontFace(HDC hDC) const
+{
+ IDWriteFontFace* pFontFace;
+ bool succeeded = false;
+ try
+ {
+ succeeded = SUCCEEDED(mpGdiInterop->CreateFontFaceFromHdc(hDC, &pFontFace));
+ }
+ catch (const std::exception& e)
+ {
+ SAL_WARN("vcl.gdi.opengl", "Error in dwrite while creating font face: " << e.what());
+ return nullptr;
+ }
+ if(succeeded)
+ return pFontFace;
+ else return nullptr;
+}
+
bool D2DWriteTextOutRenderer::BindFont(HDC hDC)
{
// A TextOutRender can only be bound to one font at a time, so the
@@ -3884,7 +3902,7 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
if( getenv("SAL_USE_COMMON_LAYOUT") )
{
- return new CommonSalLayout( getHDC(), rFontInstance );
+ return new CommonSalLayout( this, rFontInstance, rFontFace );
}
else
{
@@ -4047,6 +4065,9 @@ PhysicalFontFace* WinFontFace::Clone() const
if ( mpGraphiteData )
mpGraphiteData->AddReference();
#endif
+ if( mpHBFace )
+ hb_face_reference( mpHBFace );
+
PhysicalFontFace* pClone = new WinFontFace( *this );
return pClone;
}
commit 269e72cbd3fce33f6a19ac428710f6b66845a82e
Author: Akash Jain <akash96j at gmail.com>
Date: Thu Aug 18 20:51:25 2016 +0530
GSoC: Move TextOutRenderer definition to winlayout.hxx
Change-Id: I705f92d5ad55d7612c6413436c801de13f5352a6
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 7905513..4c6874f 100755
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -417,4 +417,105 @@ public:
#endif
+class TextOutRenderer
+{
+protected:
+ explicit TextOutRenderer() = default;
+ TextOutRenderer(const TextOutRenderer &) = delete;
+ TextOutRenderer & operator = (const TextOutRenderer &) = delete;
+
+public:
+ static TextOutRenderer & get();
+
+ virtual ~TextOutRenderer() = default;
+
+ virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
+ const Rectangle* pRectToErase,
+ Point* pPos, int* pGetNextGlypInfo) = 0;
+};
+
+class ExTextOutRenderer : public TextOutRenderer
+{
+ ExTextOutRenderer(const ExTextOutRenderer &) = delete;
+ ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete;
+
+public:
+ explicit ExTextOutRenderer() = default;
+ virtual ~ExTextOutRenderer() override = default;
+
+ bool operator ()(SalLayout const &rLayout, HDC hDC,
+ const Rectangle* pRectToErase,
+ Point* pPos, int* pGetNextGlypInfo) override;
+};
+
+#if ENABLE_GRAPHITE_DWRITE
+
+class D2DWriteTextOutRenderer : public TextOutRenderer
+{
+ typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
+ REFIID, const D2D1_FACTORY_OPTIONS *, void **);
+ typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
+ REFIID, IUnknown **);
+
+ static HINSTANCE mmD2d1, mmDWrite;
+ static pD2D1CreateFactory_t D2D1CreateFactory;
+ static pDWriteCreateFactory_t DWriteCreateFactory;
+
+public:
+ static bool InitModules();
+
+ explicit D2DWriteTextOutRenderer();
+ virtual ~D2DWriteTextOutRenderer() override;
+
+ bool operator ()(SalLayout const &rLayout, HDC hDC,
+ const Rectangle* pRectToErase,
+ Point* pPos, int* pGetNextGlypInfo) override;
+
+ inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) {
+ RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() };
+ HRESULT ok= mpRT->BindDC(hDC, &rc);
+ return SUCCEEDED(ok);
+ }
+
+ bool BindFont(HDC hDC) /*override*/;
+ bool ReleaseFont() /*override*/;
+
+ std::vector<Rectangle> GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/;
+ ID2D1RenderTarget * GetRenderTarget() const { return mpRT; }
+ IDWriteFontFace* GetDWriteFontFace(HDC) const;
+ IDWriteFontFace * GetFontFace() const { return mpFontFace; }
+ float GetEmHeight() const { return mlfEmHeight; }
+
+ inline HRESULT CreateRenderTarget() {
+ if (mpRT) mpRT->Release(); mpRT = nullptr;
+ return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT);
+ }
+
+ inline bool Ready() const { return mpGdiInterop && mpRT; }
+
+private:
+ static void CleanupModules();
+
+ // This is a singleton object disable copy ctor and assignemnt operator
+ D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete;
+ D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
+
+ bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
+ bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
+ bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
+ float * pAdvances, Point * pOffsets) /*override*/;
+
+ ID2D1Factory * mpD2DFactory;
+ IDWriteFactory * mpDWriteFactory;
+ IDWriteGdiInterop * mpGdiInterop;
+ ID2D1DCRenderTarget * mpRT;
+ const D2D1_RENDER_TARGET_PROPERTIES mRTProps;
+
+ IDWriteFontFace * mpFontFace;
+ float mlfEmHeight;
+ HDC mhDC;
+};
+
+#endif
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 48c40af..538f46a 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -17,8 +17,6 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include "win/winlayout.hxx"
-
#include "osl/module.h"
#include "osl/file.h"
@@ -56,104 +54,8 @@
std::unique_ptr<GlobalGlyphCache> GlyphCache::gGlobalGlyphCache(new GlobalGlyphCache);
GLuint WinFontInstance::mnGLyphyProgram = 0;
-class TextOutRenderer
-{
-protected:
- explicit TextOutRenderer() = default;
- TextOutRenderer(const TextOutRenderer &) = delete;
- TextOutRenderer & operator = (const TextOutRenderer &) = delete;
-
-public:
- static TextOutRenderer & get();
-
- virtual ~TextOutRenderer() = default;
-
- virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
- const Rectangle* pRectToErase,
- Point* pPos, int* pGetNextGlypInfo) = 0;
-};
-
-class ExTextOutRenderer : public TextOutRenderer
-{
- ExTextOutRenderer(const ExTextOutRenderer &) = delete;
- ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete;
-
-public:
- explicit ExTextOutRenderer() = default;
- virtual ~ExTextOutRenderer() override = default;
-
- bool operator ()(SalLayout const &rLayout, HDC hDC,
- const Rectangle* pRectToErase,
- Point* pPos, int* pGetNextGlypInfo) override;
-};
-
#if ENABLE_GRAPHITE_DWRITE
-class D2DWriteTextOutRenderer : public TextOutRenderer
-{
- typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
- REFIID, const D2D1_FACTORY_OPTIONS *, void **);
-
- typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
- REFIID, IUnknown **);
-
- static HINSTANCE mmD2d1, mmDWrite;
- static pD2D1CreateFactory_t D2D1CreateFactory;
- static pDWriteCreateFactory_t DWriteCreateFactory;
-
-public:
- static bool InitModules();
-
- explicit D2DWriteTextOutRenderer();
- virtual ~D2DWriteTextOutRenderer() override;
-
- bool operator ()(SalLayout const &rLayout, HDC hDC,
- const Rectangle* pRectToErase,
- Point* pPos, int* pGetNextGlypInfo) override;
-
- inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) {
- RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() };
- return SUCCEEDED(mpRT->BindDC(hDC, &rc));
- }
-
- bool BindFont(HDC hDC) /*override*/;
- bool ReleaseFont() /*override*/;
-
- std::vector<Rectangle> GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/;
- ID2D1RenderTarget * GetRenderTarget() const { return mpRT; }
- IDWriteFontFace * GetFontFace() const { return mpFontFace; }
- float GetEmHeight() const { return mlfEmHeight; }
-
- inline HRESULT CreateRenderTarget() {
- if (mpRT) mpRT->Release(); mpRT = nullptr;
- return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT);
- }
-
- inline bool Ready() const { return mpGdiInterop && mpRT; }
-
-private:
- static void CleanupModules();
-
- // This is a singleton object disable copy ctor and assignemnt operator
- D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete;
- D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
-
- bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
- bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
- bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
- float * pAdvances, Point * pOffsets) /*override*/;
-
- ID2D1Factory * mpD2DFactory;
- IDWriteFactory * mpDWriteFactory;
- IDWriteGdiInterop * mpGdiInterop;
- ID2D1DCRenderTarget * mpRT;
- const D2D1_RENDER_TARGET_PROPERTIES mRTProps;
-
- IDWriteFontFace * mpFontFace;
- float mlfEmHeight;
- HDC mhDC;
-};
-
inline void WinFontInstance::CacheGlyphWidth( int nCharCode, int nCharWidth )
{
maWidthMap[ nCharCode ] = nCharWidth;
commit 69f6e062b67b852c1e30f188b41d21f82efad32c
Author: Akash Jain <akash96j at gmail.com>
Date: Sat Jul 23 21:41:40 2016 +0530
GSoC: Add Graphite support for CommonSalLayout
Enable Graphite font rendering in CommonSalLayout through Harfbuzz
Change-Id: Ia6a00a1bb6ea1a7bd705ed91d4f4f6cb9803e062
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 6dabc15..d4bc0f7 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -532,23 +532,23 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL
if( mpServerFont[ nFallbackLevel ]
&& !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
{
-#if ENABLE_GRAPHITE
- // Is this a Graphite font?
- if (!bDisableGraphite_ &&
- GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
+ if(getenv("SAL_USE_COMMON_LAYOUT"))
{
- pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
+ pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
}
else
-#endif
- if(getenv("SAL_USE_COMMON_LAYOUT"))
+ {
+#if ENABLE_GRAPHITE
+ // Is this a Graphite font?
+ if (!bDisableGraphite_ &&
+ GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
{
- pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
+ pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
}
else
- {
+#endif
pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
- }
+ }
}
return pLayout;
commit 2e9618aa607c0390994d228da396bc6ae08e7382
Author: Akash Jain <akash96j at gmail.com>
Date: Sat Jul 23 21:21:46 2016 +0530
GSoC: Enable building Harfbuzz with Graphite
Harfbuzz will now need to be built with Graphite support. This allows
Harfbuzz to handle Graphite fonts. In case we all building with
system Harfbuzz, then it should be built with Graphite support else
we error out.
Change-Id: I156ec08b9e5ad7ce87cc15e4b5852d9c57c98f7f
diff --git a/configure.ac b/configure.ac
index 9753f01..7702f67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9262,10 +9262,14 @@ if test $_os != Darwin -a $_os != Android -a $_os != iOS -a \( -z "$enable_graph
AC_MSG_RESULT([yes])
ENABLE_GRAPHITE="TRUE"
AC_DEFINE(ENABLE_GRAPHITE)
- libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3])
+ libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3],["-I${WORKDIR}/UnpackedTarball/graphite/include"],["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"])
if test "$with_system_graphite" = "yes"; then
libo_MINGW_CHECK_DLL([libgraphite2])
fi
+ if test "$COM" = "MSC"; then # override the above
+ GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib"
+ fi
+
else
AC_MSG_RESULT([no])
fi
@@ -9351,12 +9355,22 @@ if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os !
AC_MSG_RESULT([yes])
ENABLE_HARFBUZZ="TRUE"
if $PKG_CONFIG --atleast-version 0.9.18 harfbuzz; then
- libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz -lharfbuzz-icu"])
+ libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"])
else
- libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz -lharfbuzz-icu"])
+ libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"])
fi
if test "$COM" = "MSC"; then # override the above
- HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib ${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz-icu.lib"
+ HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib"
+ fi
+ if test "$with_system_harfbuzz" = "yes"; then
+ AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support])
+ _save_libs="$LIBS"
+ _save_cflags="$CFLAGS"
+ LIBS="$LIBS $HARFBUZZ_LIBS"
+ CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
+ AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])])
+ LIBS="$_save_libs"
+ CFLAGS="$_save_cflags"
fi
else
AC_MSG_RESULT([no])
diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk
index 9e01833..f6a2d49 100644
--- a/external/harfbuzz/ExternalProject_harfbuzz.mk
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -23,19 +23,22 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) :
$(call gb_ExternalProject_run,build,\
$(if $(CROSS_COMPILING),ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \
$(if $(SYSTEM_ICU),,ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \
+ GRAPHITE2_CFLAGS="$(GRAPHITE_CFLAGS)" \
+ GRAPHITE2_LIBS="$(GRAPHITE_LIBS)" \
./configure \
--enable-static \
--disable-shared \
--disable-gtk-doc \
--with-pic \
- --with-icu=yes \
+ --with-icu=builtin \
--with-freetype=no \
--with-cairo=no \
--with-glib=no \
+ --with-graphite2=yes \
$(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
$(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \
$(if $(filter LINUX,$(OS)),CXXFLAGS="$(CXXFLAGS) -fvisibility=hidden") \
- && (cd $(EXTERNAL_WORKDIR)/src && $(MAKE)) \
+ && (cd $(EXTERNAL_WORKDIR)/src && $(MAKE) lib) \
)
# vim: set noet sw=4 ts=4:
commit 2ba13c5a045fb96a155746aba094e0ec11fefb3c
Author: Akash Jain <akash96j at gmail.com>
Date: Wed Jul 20 23:51:56 2016 +0530
GSoC: Integrate new CommonSalLayout in quartz/ code
Change-Id: I07a9c956f09be5d43ee58ff0784ba0f81f52cd9a
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 53d4468..8fc398a 100755
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -23,6 +23,7 @@
#elif defined(MACOSX) || defined(IOS)
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include "quartz/ctfonts.hxx"
+#include <hb-coretext.h>
#else
#include "unx/freetype_glyphcache.hxx"
diff --git a/vcl/quartz/ctfonts.hxx b/vcl/inc/quartz/ctfonts.hxx
similarity index 100%
rename from vcl/quartz/ctfonts.hxx
rename to vcl/inc/quartz/ctfonts.hxx
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 754dca2..a1a8b28 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -111,6 +111,8 @@ private:
CFMutableDictionaryRef mpStyleDict;
friend class CTLayout;
+ friend class AquaSalGraphics;
+ friend class CommonSalLayout;
CFMutableDictionaryRef GetStyleDict( void ) const { return mpStyleDict; }
};
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 36b155d..28be80b 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -25,7 +25,7 @@
#include <vcl/settings.hxx>
-#include "ctfonts.hxx"
+#include "quartz/ctfonts.hxx"
#include "impfont.hxx"
#ifdef MACOSX
#include "osx/saldata.hxx"
diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx
index 2415298..5e031ec 100644
--- a/vcl/quartz/ctlayout.cxx
+++ b/vcl/quartz/ctlayout.cxx
@@ -25,9 +25,10 @@
#include <sal/types.h>
#include <tools/debug.hxx>
-#include "ctfonts.hxx"
+#include "quartz/ctfonts.hxx"
#include "CTRunData.hxx"
#include "quartz/utils.h"
+#include "CommonSalLayout.hxx"
class CTLayout : public SalLayout
@@ -781,7 +782,14 @@ void CTLayout::Simplify( bool /*bIsBase*/ ) {}
SalLayout* CoreTextStyle::GetTextLayout() const
{
- return new CTLayout( this);
+ if( getenv("SAL_USE_COMMON_LAYOUT") )
+ {
+ return new CommonSalLayout( *this );
+ }
+ else
+ {
+ return new CTLayout( this);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index d0f73a8..8362696 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -36,7 +36,7 @@
#include <vcl/svapp.hxx>
#include <vcl/sysdata.hxx>
-#include "ctfonts.hxx"
+#include "quartz/ctfonts.hxx"
#include "fontsubset.hxx"
#include "impfont.hxx"
#include "impfontcharmap.hxx"
@@ -414,8 +414,39 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect
return bRC;
}
-void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& )
-{
+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
+ Point aPos;
+ sal_GlyphId aGlyphId;
+ std::vector<CGGlyph> aGlyphIds;
+ std::vector<CGPoint> aGlyphPos;
+ int nStart = 0;
+ for(; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
+ {
+ aGlyphIds.push_back( aGlyphId & GF_IDXMASK );
+ aGlyphPos.push_back( CGPointApplyAffineTransform( CGPointMake( aPos.X(), -1*aPos.Y() ), aInvMatrix ) );
+ }
+ CTFontDrawGlyphs( pFont, aGlyphIds.data(), aGlyphPos.data(), nStart, context);
+
+ // restore the original graphic context transformations
+ SAL_INFO( "vcl.ct", "CGContextRestoreGState(" << context << ")" );
+ CGContextRestoreGState( context );
}
void AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ )
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 1cb4828..e527174 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -57,7 +57,7 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
hb_blob_t* pBlob = nullptr;
if (pBuffer != nullptr)
-#if defined(_WIN32)
+#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
#else
@@ -97,7 +97,17 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
maFontSelData(rCoreTextStyle.maFontSelData),
mrCoreTextStyle(rCoreTextStyle)
{
- mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+ CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
+ CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
+ if(pCGFont)
+ {
+ mpHBFace = hb_coretext_face_create(pCGFont);
+ }
+ else
+ {
+ mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+ }
+ CGFontRelease(pCGFont);
}
#else
commit d777650e5a4cbb8f1800c59ec87854d2f4c9e932
Author: Akash Jain <akash96j at gmail.com>
Date: Wed Jul 6 17:56:15 2016 +0530
GSoC: Integrate new CommonSalLayout in win/ code
Change-Id: Ifeb2fa7ca9e2cd0da1c504d4e770aa0bb1b0b0de
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index b376748..1cb4828 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -57,7 +57,12 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
hb_blob_t* pBlob = nullptr;
if (pBuffer != nullptr)
+#if defined(_WIN32)
+ pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
+ const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
+#else
pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+#endif
return pBlob;
}
@@ -74,12 +79,18 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
#if defined(_WIN32)
CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
: mhDC(hDC),
+ mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)),
mpHBFace(nullptr),
maFontSelData(rWinFontInstance.maFontSelData)
{
mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr);
}
+void CommonSalLayout::InitFont() const
+{
+ SelectObject( mhDC, mhFont );
+}
+
#elif defined(MACOSX) || defined(IOS)
CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
: mpHBFace(nullptr),
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 2eae16e..0ba1467 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2612,7 +2612,4 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
}
}
-void WinSalGraphics::DrawSalLayout( const CommonSalLayout& )
-{}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index cbf0b58..48c40af 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -34,6 +34,7 @@
#include "sft.hxx"
#include "sallayout.hxx"
+#include "CommonSalLayout.hxx"
#include <cstdio>
#include <cstdlib>
@@ -67,7 +68,7 @@ public:
virtual ~TextOutRenderer() = default;
- virtual bool operator ()(WinLayout const &rLayout, HDC hDC,
+ virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo) = 0;
};
@@ -81,7 +82,7 @@ public:
explicit ExTextOutRenderer() = default;
virtual ~ExTextOutRenderer() override = default;
- bool operator ()(WinLayout const &rLayout, HDC hDC,
+ bool operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo) override;
};
@@ -106,7 +107,7 @@ public:
explicit D2DWriteTextOutRenderer();
virtual ~D2DWriteTextOutRenderer() override;
- bool operator ()(WinLayout const &rLayout, HDC hDC,
+ bool operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo) override;
@@ -138,7 +139,7 @@ private:
D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
- bool GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
+ bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
float * pAdvances, Point * pOffsets) /*override*/;
@@ -3485,7 +3486,7 @@ TextOutRenderer & TextOutRenderer::get()
}
-bool ExTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC,
+bool ExTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo)
{
@@ -3544,7 +3545,7 @@ D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer()
CleanupModules();
}
-bool D2DWriteTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC,
+bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
const Rectangle* pRectToErase,
Point* pPos, int* pGetNextGlypInfo)
{
@@ -3784,7 +3785,7 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p
return succeeded;
}
-bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const
+bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const
{
rOut.SetEmpty();
@@ -3979,66 +3980,73 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
const WinFontFace& rFontFace = *mpWinFontData[ nFallbackLevel ];
WinFontInstance& rFontInstance = *mpWinFontEntry[ nFallbackLevel ];
- bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
-
- if (!bUspInited)
- InitUSP();
-
- if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) )
+ if( getenv("SAL_USE_COMMON_LAYOUT") )
{
-#if ENABLE_GRAPHITE
- if (rFontFace.SupportsGraphite())
- {
- pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
- }
- else
-#endif // ENABLE_GRAPHITE
- {
- // script complexity is determined in upper layers
- pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
- // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
- // the created UniscribeLayout, otherwise the data passed into the
- // constructor might become invalid too early
- }
+ return new CommonSalLayout( getHDC(), rFontInstance );
}
else
{
-#if ENABLE_GRAPHITE
- if (rFontFace.SupportsGraphite())
- {
- pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
- }
- else
-#endif // ENABLE_GRAPHITE
- {
- static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+ bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
- if (!bAvoidSimpleWinLayout)
- {
- if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
- {
- // TODO: directly cache kerning info in the rFontInstance
- // TODO: get rid of kerning methods+data in WinSalGraphics object
- GetKernPairs();
- rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
- }
+ if (!bUspInited)
+ InitUSP();
- pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+ if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) )
+ {
+#if ENABLE_GRAPHITE
+ if (rFontFace.SupportsGraphite())
+ {
+ pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
}
else
+#endif // ENABLE_GRAPHITE
{
+ // script complexity is determined in upper layers
pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
// NOTE: it must be guaranteed that the WinSalGraphics lives longer than
// the created UniscribeLayout, otherwise the data passed into the
// constructor might become invalid too early
}
}
- }
+ else
+ {
+#if ENABLE_GRAPHITE
+ if (rFontFace.SupportsGraphite())
+ {
+ pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+ }
+ else
+#endif // ENABLE_GRAPHITE
+ {
+ static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+
+ if (!bAvoidSimpleWinLayout)
+ {
+ if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
+ {
+ // TODO: directly cache kerning info in the rFontInstance
+ // TODO: get rid of kerning methods+data in WinSalGraphics object
+ GetKernPairs();
+ rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
+ }
+
+ pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+ }
+ else
+ {
+ pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+ // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
+ // the created UniscribeLayout, otherwise the data passed into the
+ // constructor might become invalid too early
+ }
+ }
+ }
- if( mfFontScale[nFallbackLevel] != 1.0 )
- pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
+ if( mfFontScale[nFallbackLevel] != 1.0 )
+ pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
- return pWinLayout;
+ return pWinLayout;
+ }
}
int WinSalGraphics::GetMinKashidaWidth()
@@ -4147,4 +4155,32 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
return pFontInstance;
}
+void WinSalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+ HDC hDC = getHDC();
+
+ if((std::getenv("SAL_DWRITE_COMMON_LAYOUT")))
+ {
+ Point aPos(0, 0);
+ int nGlyphCount(0);
+ TextOutRenderer &render = TextOutRenderer::get();
+ bool result = render( rLayout, hDC, nullptr, &aPos, &nGlyphCount );
+ assert( !result );
+ }
+ else
+ {
+ Point aPos;
+ sal_GlyphId aGlyphId;
+ int nFetchedGlyphs = 0;
+ UINT oldTa = GetTextAlign( hDC );
+ SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) );
+ while( rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nFetchedGlyphs ) )
+ {
+ ExtTextOutW( hDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( &aGlyphId ),
+ 1, nullptr);
+ }
+ SetTextAlign(hDC, oldTa);
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 11b295243f37e6a8ebef905c4dfc8405cdf414cc
Author: Akash Jain <akash96j at gmail.com>
Date: Wed Jul 6 10:35:24 2016 +0530
GSoC: Integrate new CommonSalLayout in unx/ code
Change-Id: I991cb5cbd2adad4f4c9f62f807990b9fde2a5133
diff --git a/vcl/README.vars b/vcl/README.vars
index bf85485..b72d499 100644
--- a/vcl/README.vars
+++ b/vcl/README.vars
@@ -6,6 +6,7 @@ SAL_USE_VCLPLUGIN - use a VCL plugin
SAL_NO_NWF - disable native widgets
SAL_FORCEDPI - force a specific DPI (gtk & gtk3 plugins only)
SAL_FORCE_HC - force high-contrast mode
+SAL_USE_COMMON_LAYOUT - use CommonSalLayout layout engine for text layout
VCL_DOUBLEBUFFERING_AVOID_PAINT - don't paint the buffer, useful to see where we do direct painting
VCL_DOUBLEBUFFERING_FORCE_ENABLE - enable double buffered painting
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 372cd4d..6dabc15 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -42,6 +42,7 @@
#include <cairo.h>
#include <cairo-ft.h>
+#include "CommonSalLayout.hxx"
namespace {
@@ -540,7 +541,14 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL
}
else
#endif
- pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
+ if(getenv("SAL_USE_COMMON_LAYOUT"))
+ {
+ pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
+ }
+ else
+ {
+ pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
+ }
}
return pLayout;
commit 7bcd2f3bb8c0b6e998ebabe8bfb0c12008e2fb84
Author: Akash Jain <akash96j at gmail.com>
Date: Wed Jul 6 10:15:49 2016 +0530
GSoC: Modify DrawServerFontLayout and add DrawSalLayout
Modify the definiton of the DrawServerFontLayout method.
Add new DrawSalLayout method which will be used for drawing text
independent of the platform.
Change-Id: Ie3eefb172b1781c685def1ef549db2538f672a62
diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx
index 5202109..494cada 100644
--- a/vcl/headless/svptext.cxx
+++ b/vcl/headless/svptext.cxx
@@ -23,6 +23,7 @@
#include "headless/svpgdi.hxx"
#include <config_cairo_canvas.h>
#include "impfontmetricdata.hxx"
+#include "CommonSalLayout.hxx"
void SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel )
{
@@ -116,9 +117,14 @@ SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
return m_aTextRenderImpl.GetTextLayout(rArgs, nFallbackLevel);
}
-void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout )
+void SvpSalGraphics::DrawServerFontLayout( const GenericSalLayout& rSalLayout, const ServerFont& rServerFont )
{
- m_aTextRenderImpl.DrawServerFontLayout(rSalLayout );
+ m_aTextRenderImpl.DrawServerFontLayout( rSalLayout, rServerFont );
+}
+
+void SvpSalGraphics::DrawSalLayout( const CommonSalLayout& rSalLayout )
+{
+ DrawServerFontLayout( rSalLayout, rSalLayout.getFontData() );
}
void SvpSalGraphics::SetTextColor( SalColor nSalColor )
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index a22b84f..b942f86 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -166,7 +166,8 @@ public:
virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawSalLayout( const CommonSalLayout& ) override;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
virtual bool supportsOperation( OutDevSupportType ) const override;
virtual void drawPixel( long nX, long nY ) override;
virtual void drawPixel( long nX, long nY, SalColor nSalColor ) override;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 54a424e..754dca2 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -50,6 +50,7 @@ class AquaSalFrame;
class FontAttributes;
class CoreTextStyle;
class XorEmulation;
+class CommonSalLayout;
typedef sal_uInt32 sal_GlyphId;
@@ -402,7 +403,8 @@ public:
virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawSalLayout( const CommonSalLayout& ) override;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {};
virtual bool supportsOperation( OutDevSupportType ) const override;
#ifdef MACOSX
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 0a151d2..5bab4e8 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -43,7 +43,8 @@ class Rectangle;
class FontSubsetInfo;
class OpenGLContext;
class OutputDevice;
-class ServerFontLayout;
+class ServerFont;
+class CommonSalLayout;
struct SystemGraphicsData;
#if ENABLE_CAIRO_CANVAS
@@ -216,7 +217,8 @@ public:
virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) = 0;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) = 0;
+ virtual void DrawSalLayout( const CommonSalLayout& ) = 0;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0;
virtual bool supportsOperation( OutDevSupportType ) const = 0;
diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx
index 70fc9d2..5c4335e 100644
--- a/vcl/inc/textrender.hxx
+++ b/vcl/inc/textrender.hxx
@@ -26,7 +26,6 @@
class ImplLayoutArgs;
class ImplFontMetricData;
-class ServerFontLayout;
class PhysicalFontCollection;
class PhysicalFontFace;
@@ -71,7 +70,7 @@ public:
virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0;
virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) = 0;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) = 0;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0;
#if ENABLE_CAIRO_CANVAS
virtual SystemFontData GetSysFontData( int nFallbackLevel ) const = 0;
#endif // ENABLE_CAIRO_CANVAS
diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx
index 5cb39d3..2eb87df 100644
--- a/vcl/inc/unx/cairotextrender.hxx
+++ b/vcl/inc/unx/cairotextrender.hxx
@@ -88,7 +88,7 @@ public:
virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
#if ENABLE_CAIRO_CANVAS
virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override;
#endif
diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h
index 6451a73..fdef50b 100644
--- a/vcl/inc/unx/genpspgraphics.h
+++ b/vcl/inc/unx/genpspgraphics.h
@@ -34,6 +34,7 @@ class PhysicalFontCollection;
namespace psp { struct JobData; class PrinterGfx; }
class ServerFont;
+class ServerFontLayout;
class FontAttributes;
class SalInfoPrinter;
class GlyphCache;
@@ -131,7 +132,8 @@ public:
virtual bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) override;
virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawSalLayout( const CommonSalLayout& ) {};
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& );
virtual bool supportsOperation( OutDevSupportType ) const override;
virtual void drawPixel( long nX, long nY ) override;
virtual void drawPixel( long nX, long nY, SalColor nSalColor ) override;
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 73f22b7..853f678 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -154,7 +154,8 @@ public:
virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawSalLayout( const CommonSalLayout& ) override;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
virtual bool supportsOperation( OutDevSupportType ) const override;
virtual void drawPixel( long nX, long nY ) override;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 291dc08..2defd7f 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -52,6 +52,7 @@ class PhysicalFontCollection;
class SalGraphicsImpl;
class WinOpenGLSalGraphicsImpl;
class ImplFontMetricData;
+class CommonSalLayout;
#define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000)
#define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff)
@@ -450,7 +451,8 @@ public:
virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
- virtual void DrawServerFontLayout( const ServerFontLayout& ) override;
+ virtual void DrawSalLayout( const CommonSalLayout& ) override;
+ virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {};
virtual bool supportsOperation( OutDevSupportType ) const override;
// Query the platform layer for control support
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 0d39e96..d0f73a8 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -41,6 +41,7 @@
#include "impfont.hxx"
#include "impfontcharmap.hxx"
#include "impfontmetricdata.hxx"
+#include "CommonSalLayout.hxx"
#ifdef MACOSX
#include "osx/salframe.h"
@@ -413,7 +414,7 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect
return bRC;
}
-void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& )
{
}
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index d25ae5c..b376748 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -221,9 +221,10 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
}
}
-void CommonSalLayout::DrawText( SalGraphics& ) const
+void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const
{
//call platform dependent DrawText functions
+ rSalGraphics.DrawSalLayout( *this );
}
bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index f697a0c..372cd4d 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -186,7 +186,7 @@ namespace
}
}
-void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rFont )
{
std::vector<cairo_glyph_t> cairo_glyphs;
std::vector<int> glyph_extrarotation;
@@ -219,7 +219,6 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
if (cairo_glyphs.empty())
return;
- ServerFont& rFont = rLayout.GetServerFont();
const FontSelectPattern& rFSD = rFont.GetFontSelData();
int nHeight = rFSD.mnHeight;
int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
diff --git a/vcl/unx/generic/gdi/font.cxx b/vcl/unx/generic/gdi/font.cxx
index 36c7ecb..7353e24 100644
--- a/vcl/unx/generic/gdi/font.cxx
+++ b/vcl/unx/generic/gdi/font.cxx
@@ -24,6 +24,7 @@
#include "unx/salgdi.h"
#include "unx/salvd.h"
#include "textrender.hxx"
+#include "CommonSalLayout.hxx"
GC
X11SalGraphics::GetFontGC()
@@ -52,9 +53,14 @@ X11SalGraphics::GetFontGC()
return pFontGC_;
}
-void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void X11SalGraphics::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont )
{
- mxTextRenderImpl->DrawServerFontLayout(rLayout);
+ mxTextRenderImpl->DrawServerFontLayout(rLayout, rServerFont);
+}
+
+void X11SalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+ DrawServerFontLayout( rLayout, rLayout.getFontData() );
}
const FontCharMapRef X11SalGraphics::GetFontCharMap() const
diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx
index d8bf44b..eb654b7 100644
--- a/vcl/unx/generic/glyphs/gcach_layout.cxx
+++ b/vcl/unx/generic/glyphs/gcach_layout.cxx
@@ -22,6 +22,7 @@
#include <salgdi.hxx>
#include <scrptrun.h>
#include <limits>
+#include <unx/genpspgraphics.h>
#include <i18nlangtag/mslangid.hxx>
@@ -47,7 +48,7 @@ ServerFontLayout::ServerFontLayout( ServerFont& rFont )
void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
{
- rSalGraphics.DrawServerFontLayout( *this );
+ rSalGraphics.DrawServerFontLayout( *this, mrServerFont );
}
bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs )
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx
index bbcb5a5..a9c0af4 100644
--- a/vcl/unx/generic/print/genpspgraphics.cxx
+++ b/vcl/unx/generic/print/genpspgraphics.cxx
@@ -761,7 +761,7 @@ void PspFontLayout::DrawText( SalGraphics& ) const
DrawPrinterLayout( *this, mrPrinterGfx, false );
}
-void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void GenPspGraphics::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& /*unused*/ )
{
// print complex text
DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index ad059c1..2eae16e 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2612,7 +2612,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
}
}
-void WinSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+void WinSalGraphics::DrawSalLayout( const CommonSalLayout& )
{}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 39cbdf3367a33ce15092f06f4d4debec915ed2c5
Author: Akash Jain <akash96j at gmail.com>
Date: Tue Jun 14 14:52:16 2016 +0530
GSoC: Modify HARFBUZZ_LIBS flag if compiling with MSVC
MSVC has a different format for specifying libs to be linked.
Therefore, modify libs flag accordingly.
Change-Id: Ib919c4b6b0cdac47a8a6ad6730d20e19bc05b0d4
diff --git a/configure.ac b/configure.ac
index ac5866d..9753f01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9355,6 +9355,9 @@ if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os !
else
libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz -lharfbuzz-icu"])
fi
+ if test "$COM" = "MSC"; then # override the above
+ HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib ${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz-icu.lib"
+ fi
else
AC_MSG_RESULT([no])
fi
commit 25be1fa2be637729aff7888a373b2339130fa27c
Author: Akash Jain <akash96j at gmail.com>
Date: Tue Jun 14 14:38:12 2016 +0530
GSoC: Add new CommonSalLayout class
Change-Id: Ic11e573da2f5fd6ef931f53ab674f8894815c3b4
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a0dfee3..67bcbe5 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -303,6 +303,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/virdev \
vcl/source/gdi/wall \
vcl/source/gdi/scrptrun \
+ vcl/source/gdi/CommonSalLayout \
vcl/source/bitmap/bitmapfilter \
vcl/source/bitmap/bitmapscalesuper \
vcl/source/bitmap/BitmapScaleConvolution \
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
new file mode 100755
index 0000000..53d4468
--- /dev/null
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifdef _WIN32
+#include "win/winlayout.hxx"
+
+#elif defined(MACOSX) || defined(IOS)
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include "quartz/ctfonts.hxx"
+
+#else
+#include "unx/freetype_glyphcache.hxx"
+#endif
+
+#include <sallayout.hxx>
+#include <hb-icu.h>
+#include <hb-ot.h>
+
+class CommonSalLayout : public GenericSalLayout
+{
+ hb_face_t* mpHBFace;
+ FontSelectPattern maFontSelData;
+ css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
+#ifdef _WIN32
+ HDC mhDC;
+ HFONT mhFont;
+#elif defined(MACOSX) || defined(IOS)
+ const CoreTextStyle& mrCoreTextStyle;
+#else
+ ServerFont& mrServerFont;
+#endif
+
+ hb_font_t* GetHBFont();
+public:
+#if defined(_WIN32)
+ explicit CommonSalLayout(HDC, WinFontInstance&);
+ virtual void InitFont() const override;
+#elif defined(MACOSX) || defined(IOS)
+ explicit CommonSalLayout(const CoreTextStyle&);
+ const CoreTextStyle& getFontData() const { return mrCoreTextStyle; };
+#else
+ explicit CommonSalLayout(ServerFont&);
+ const ServerFont& getFontData() const { return mrServerFont; };
+#endif
+
+ virtual ~CommonSalLayout();
+ void SetNeedFallback(ImplLayoutArgs&, sal_Int32, bool);
+ void AdjustLayout(ImplLayoutArgs&) override;
+ virtual bool LayoutText(ImplLayoutArgs&) override;
+ virtual void DrawText( SalGraphics& ) const override;
+ std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const override;
+};
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 738bed3..54a424e 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -103,6 +103,7 @@ public:
float mfFontStretch;
/// text rotation in radian
float mfFontRotation;
+ FontSelectPattern maFontSelData;
private:
/// CoreText text style object
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index bd2ab4f..36b155d 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -48,6 +48,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
: mpFontData( static_cast<CoreTextFontFace const *>(rFSD.mpFontData) )
, mfFontStretch( 1.0 )
, mfFontRotation( 0.0 )
+ , maFontSelData( rFSD )
, mpStyleDict( nullptr )
{
const FontSelectPattern* const pReqFont = &rFSD;
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
new file mode 100755
index 0000000..d25ae5c
--- /dev/null
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "CommonSalLayout.hxx"
+
+#include <vcl/unohelp.hxx>
+#include <scrptrun.h>
+#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
+#include <i18nlangtag/mslangid.hxx>
+#include <limits>
+#include <salgdi.hxx>
+
+static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
+{
+ char pTagName[5];
+ pTagName[0] = (char)(nTableTag >> 24);
+ pTagName[1] = (char)(nTableTag >> 16);
+ pTagName[2] = (char)(nTableTag >> 8);
+ pTagName[3] = (char)(nTableTag);
+ pTagName[4] = 0;
+
+ sal_uLong nLength=0;
+#if defined(_WIN32)
+ const unsigned char* pBuffer = nullptr;
+ HDC* phDC = static_cast<HDC*>(pUserData);
+ nLength = WinFontFace::GetTable(pTagName, pBuffer, *phDC);
+#elif defined(MACOSX) || defined(IOS)
+ unsigned char* pBuffer = nullptr;
+ CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData);
+ nLength = pFont->GetFontTable(pTagName, nullptr);
+ if( nLength>0 )
+ {
+ pBuffer = new unsigned char[nLength];
+ }
+ pFont->GetFontTable(pTagName, pBuffer);
+#else
+ const unsigned char* pBuffer = nullptr;
+ ServerFont* pFont = static_cast<ServerFont*>(pUserData);
+ pBuffer = pFont->GetTable(pTagName, &nLength);
+#endif
+
+ hb_blob_t* pBlob = nullptr;
+ if (pBuffer != nullptr)
+ pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+
+ return pBlob;
+}
+
+static hb_unicode_funcs_t* getUnicodeFuncs()
+{
+ static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
+#if !HB_VERSION_ATLEAST(1, 1, 0)
+ hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, unicodeDecomposeCompatibility, nullptr, nullptr);
+#endif
+ return ufuncs;
+}
+
+#if defined(_WIN32)
+CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
+: mhDC(hDC),
+ mpHBFace(nullptr),
+ maFontSelData(rWinFontInstance.maFontSelData)
+{
+ mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr);
+}
+
+#elif defined(MACOSX) || defined(IOS)
+CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
+: mpHBFace(nullptr),
+ maFontSelData(rCoreTextStyle.maFontSelData),
+ mrCoreTextStyle(rCoreTextStyle)
+{
+ mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+}
+
+#else
+CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
+: mpHBFace(nullptr),
+ maFontSelData(rServerFont.GetFontSelData()),
+ mrServerFont(rServerFont)
+{
+ mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
+}
+#endif
+
+CommonSalLayout::~CommonSalLayout()
+{
+ hb_face_destroy(mpHBFace);
+}
+
+hb_font_t* CommonSalLayout::GetHBFont()
+{
+ // HACK. TODO: Get rid of HACK
+#if defined(_WIN32)
+ if(maFontSelData.mnWidth)
+ maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812;
+#endif
+
+ hb_font_t* pHBFont = hb_font_create(mpHBFace);
+ hb_font_set_ppem(pHBFont, maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight , maFontSelData.mnHeight);
+ hb_font_set_scale(pHBFont, (uint64_t)(maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight) << 6
+ , (uint64_t)maFontSelData.mnHeight << 6);
+ hb_ot_font_set_funcs(pHBFont);
+ return pHBFont;
+}
+
+struct HbScriptRun
+{
+ int32_t mnMin;
+ int32_t mnEnd;
+ hb_script_t maScript;
+
+ HbScriptRun(int32_t nMin, int32_t nEnd, UScriptCode aScript)
+ : mnMin(nMin), mnEnd(nEnd),
+ maScript(hb_icu_script_to_script(aScript))
+ {}
+};
+
+typedef std::vector<HbScriptRun> HbScriptRuns;
+
+namespace vcl {
+ struct Run
+ {
+ int32_t nStart;
+ int32_t nEnd;
+ UScriptCode nCode;
+ Run(int32_t nStart_, int32_t nEnd_, UScriptCode nCode_)
+ : nStart(nStart_), nEnd(nEnd_), nCode(nCode_)
+ {}
+ };
+
+ class TextLayoutCache
+ {
+ public:
+ std::vector<vcl::Run> runs;
+ TextLayoutCache(sal_Unicode const* pStr, sal_Int32 const nEnd)
+ {
+ vcl::ScriptRun aScriptRun(
+ reinterpret_cast<const UChar *>(pStr),
+ nEnd);
+ while (aScriptRun.next())
+ {
+ runs.push_back(Run(aScriptRun.getScriptStart(),
+ aScriptRun.getScriptEnd(), aScriptRun.getScriptCode()));
+ }
+ }
+ };
+}
+
+std::shared_ptr<vcl::TextLayoutCache> CommonSalLayout::CreateTextLayoutCache(OUString const& rString) const
+{
+ return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength());
+}
+
+void CommonSalLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, bool bRightToLeft)
+{
+ if (nCharPos < 0)
+ return;
+
+ using namespace ::com::sun::star;
+
+ if (!mxBreak.is())
+ mxBreak = vcl::unohelper::CreateBreakIterator();
+
+ lang::Locale aLocale(rArgs.maLanguageTag.getLocale());
+
+ //if position nCharPos is missing in the font, grab the entire grapheme and
+ //mark all glyphs as missing so the whole thing is rendered with the same
+ //font
+ sal_Int32 nDone;
+ sal_Int32 nGraphemeStartPos =
+ mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale,
+ i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+ sal_Int32 nGraphemeEndPos =
+ mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale,
+ i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+
+ rArgs.NeedFallback(nGraphemeStartPos, nGraphemeEndPos, bRightToLeft);
+}
+
+void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
+{
+ GenericSalLayout::AdjustLayout(rArgs);
+
+ // apply asian kerning if the glyphs are not already formatted
+ if( (rArgs.mnFlags & SalLayoutFlags::KerningAsian)
+ && !(rArgs.mnFlags & SalLayoutFlags::Vertical) )
+ if( (rArgs.mpDXArray != nullptr) || (rArgs.mnLayoutWidth != 0) )
+ ApplyAsianKerning(rArgs.mrStr);
+
+ if((rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray)
+ {
+ hb_font_t* pHBFont = GetHBFont();
+ hb_codepoint_t nKashidaCodePoint = 0x0640;
+ hb_codepoint_t nKashidaGlyphIndex;
+
+ if(hb_font_get_glyph(pHBFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex))
+ {
+ if(nKashidaGlyphIndex)
+ {
+ KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(pHBFont, nKashidaGlyphIndex) >> 6);
+ }
+ }
+ hb_font_destroy(pHBFont);
+ }
+}
+
+void CommonSalLayout::DrawText( SalGraphics& ) const
+{
+ //call platform dependent DrawText functions
+}
+
+bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
+{
+ hb_font_t* pHBFont = GetHBFont();
+ hb_script_t aHbScript = HB_SCRIPT_INVALID;
+
+ int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos);
+ Reserve(nGlyphCapacity);
+
+ const int nLength = rArgs.mrStr.getLength();
+ const sal_Unicode *pStr = rArgs.mrStr.getStr();
+
+ std::unique_ptr<vcl::TextLayoutCache> pNewScriptRun;
+ vcl::TextLayoutCache const* pTextLayout;
+ if (rArgs.m_pTextLayoutCache)
+ {
+ pTextLayout = rArgs.m_pTextLayoutCache; // use cache!
+ }
+ else
+ {
+ pNewScriptRun.reset(new vcl::TextLayoutCache(pStr, rArgs.mnEndCharPos));
+ pTextLayout = pNewScriptRun.get();
+ }
+
+ Point aCurrPos(0, 0);
+ while (true)
+ {
+ int nBidiMinRunPos, nBidiEndRunPos;
+ bool bRightToLeft;
+ if (!rArgs.GetNextRun(&nBidiMinRunPos, &nBidiEndRunPos, &bRightToLeft))
+ break;
+
+ // Find script subruns.
+ int nCurrentPos = nBidiMinRunPos;
+ HbScriptRuns aScriptSubRuns;
+ size_t k = 0;
+ for (; k < pTextLayout->runs.size(); ++k)
+ {
+ vcl::Run const& rRun(pTextLayout->runs[k]);
+ if (rRun.nStart <= nCurrentPos && nCurrentPos < rRun.nEnd)
+ {
+ break;
+ }
+ }
+
+ while (nCurrentPos < nBidiEndRunPos && k < pTextLayout->runs.size())
+ {
+ int32_t nMinRunPos = nCurrentPos;
+ int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos);
+ HbScriptRun aRun(nMinRunPos, nEndRunPos, pTextLayout->runs[k].nCode);
+ aScriptSubRuns.push_back(aRun);
+
+ nCurrentPos = nEndRunPos;
+ ++k;
+ }
+
+ // RTL subruns should be reversed to ensure that final glyph order is
+ // correct.
+ if (bRightToLeft)
+ std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end());
+
+ for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it)
+ {
+ int nMinRunPos = it->mnMin;
+ int nEndRunPos = it->mnEnd;
+ int nRunLen = nEndRunPos - nMinRunPos;
+ aHbScript = it->maScript;
+ // hb_language_from_string() accept ISO639-3 language tag except for Chinese.
+ LanguageTag &rTag = rArgs.maLanguageTag;
+ OString sLanguage = OUStringToOString( MsLangId::isChinese(rTag.getLanguageType()) ? rTag.getBcp47():rTag.getLanguage() , RTL_TEXTENCODING_UTF8 );
+
+ int nHbFlags = HB_BUFFER_FLAGS_DEFAULT;
+ if (nMinRunPos == 0)
+ nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */
+ if (nEndRunPos == nLength)
+ nHbFlags |= HB_BUFFER_FLAG_EOT; /* End-of-text */
+
+ hb_buffer_t *pHbBuffer = hb_buffer_create();
+ static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs();
+#if !HB_VERSION_ATLEAST(1, 1, 0)
+ hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs);
+#endif
+ hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR);
+ hb_buffer_set_script(pHbBuffer, aHbScript);
+ hb_buffer_set_language(pHbBuffer, hb_language_from_string(sLanguage.getStr(), -1));
+ hb_buffer_set_flags(pHbBuffer, (hb_buffer_flags_t) nHbFlags);
+ hb_buffer_add_utf16(
+ pHbBuffer, reinterpret_cast<uint16_t const *>(pStr), nLength,
+ nMinRunPos, nRunLen);
+#if HB_VERSION_ATLEAST(0, 9, 42)
+ hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+#endif
+ hb_shape(pHBFont, pHbBuffer, nullptr, 0);
+
+ int nRunGlyphCount = hb_buffer_get_length(pHbBuffer);
+ hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
+ hb_glyph_position_t *pHbPositions = hb_buffer_get_glyph_positions(pHbBuffer, nullptr);
+
+ sal_Int32 nGraphemeStartPos = std::numeric_limits<sal_Int32>::max();
+ sal_Int32 nGraphemeEndPos = std::numeric_limits<sal_Int32>::min();
+ com::sun::star::lang::Locale aLocale(rArgs.maLanguageTag.getLocale());
+ if (!mxBreak.is())
+ mxBreak = vcl::unohelper::CreateBreakIterator();
+
+ for (int i = 0; i < nRunGlyphCount; ++i) {
+ int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
+ int32_t nCharPos = pHbGlyphInfos[i].cluster;
+
+ // if needed request glyph fallback by updating LayoutArgs
+ if (!nGlyphIndex)
+ {
+ SetNeedFallback(rArgs, nCharPos, bRightToLeft);
+ if (SalLayoutFlags::ForFallback & rArgs.mnFlags)
+ continue;
+ }
+
+ sal_Int32 indexUtf16 = nCharPos;
+ sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0);
+
+ bool bInCluster = false;
+ if(bRightToLeft && (nCharPos < nGraphemeStartPos))
+ {
+ sal_Int32 nDone;
+ nGraphemeStartPos = mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale,
+ com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+ }
+ else if(!bRightToLeft && (nCharPos >= nGraphemeEndPos))
+ {
+ sal_Int32 nDone;
+ nGraphemeEndPos = mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale,
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list