summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2016-11-23 23:28:53 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2016-11-26 05:58:33 +0000
commit47ea13ef8dc8ab9aeded6121845e3ebd1d28b292 (patch)
treee1fef0a1fd6a908d9ea8556f25aeb12e9d265635
parent8b920435c09a56bab35876d5e43a1e6098bf3dcf (diff)
Kill the old Unix layout engines
Change-Id: I9e1667faf9644dfab025c82cb11a6490d1e8f998 Reviewed-on: https://gerrit.libreoffice.org/31221 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/unx/genpspgraphics.h1
-rw-r--r--vcl/inc/unx/glyphcache.hxx43
-rw-r--r--vcl/inc/unx/salgdi.h2
-rw-r--r--vcl/unx/generic/fontmanager/fontconfig.cxx18
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx42
-rw-r--r--vcl/unx/generic/glyphs/freetype_glyphcache.cxx233
-rw-r--r--vcl/unx/generic/glyphs/gcach_layout.cxx621
-rw-r--r--vcl/unx/generic/print/genpspgraphics.cxx65
9 files changed, 21 insertions, 1005 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 90650adcebcd..990ca11a5829 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -543,7 +543,6 @@ vcl_headless_freetype_code=\
vcl/headless/svpglyphcache \
vcl/unx/generic/gdi/cairotextrender \
vcl/unx/generic/glyphs/freetype_glyphcache \
- vcl/unx/generic/glyphs/gcach_layout \
vcl/unx/generic/glyphs/glyphcache \
vcl/unx/generic/fontmanager/fontsubst \
vcl/unx/generic/fontmanager/fontcache \
diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h
index 792e44f832bb..5d0acd4484f5 100644
--- a/vcl/inc/unx/genpspgraphics.h
+++ b/vcl/inc/unx/genpspgraphics.h
@@ -34,7 +34,6 @@ class PhysicalFontCollection;
namespace psp { struct JobData; class PrinterGfx; }
class FreetypeFont;
-class ServerFontLayout;
class FontAttributes;
class SalInfoPrinter;
class GlyphCache;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index ce5dd1f30885..28a3665e8e6d 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -43,8 +43,6 @@ class GlyphData;
class FontConfigFontOptions;
class PhysicalFontCollection;
class FreetypeFont;
-class ServerFontLayout;
-class ServerFontLayoutEngine;
class SvpGcpHelper;
namespace basegfx { class B2DPolyPolygon; }
@@ -178,7 +176,6 @@ public:
private:
friend class GlyphCache;
- friend class ServerFontLayout;
friend class FreetypeFontInstance;
friend class X11SalGraphics;
friend class CairoTextRender;
@@ -193,9 +190,6 @@ private:
void ReleaseFromGarbageCollect();
void ApplyGlyphTransform( int nGlyphFlags, FT_GlyphRec_* ) const;
- void ApplyGSUB( const FontSelectPattern& );
-
- ServerFontLayoutEngine* GetLayoutEngine();
typedef std::unordered_map<int,GlyphData> GlyphList;
mutable GlyphList maGlyphList;
@@ -233,7 +227,6 @@ private:
typedef std::unordered_map<int,int> GlyphSubstitution;
GlyphSubstitution maGlyphSubstitution;
- ServerFontLayoutEngine* mpLayoutEngine;
hb_font_t* mpHbFont;
};
@@ -250,42 +243,6 @@ private:
FreetypeFont* mpFreetypeFont;
};
-class VCL_DLLPUBLIC ServerFontLayout : public GenericSalLayout
-{
-public:
- ServerFontLayout( FreetypeFont& );
-
- virtual bool LayoutText( ImplLayoutArgs& ) override;
- virtual void AdjustLayout( ImplLayoutArgs& ) override;
- virtual void DrawText( SalGraphics& ) const override;
-
- void SetNeedFallback(
- ImplLayoutArgs& rArgs,
- sal_Int32 nIndex,
- bool bRightToLeft);
-
- FreetypeFont& GetFreetypeFont() const { return mrFreetypeFont; }
-
- virtual std::shared_ptr<vcl::TextLayoutCache>
- CreateTextLayoutCache(OUString const&) const override;
-
-private:
- FreetypeFont& mrFreetypeFont;
- css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
-
- ServerFontLayout( const ServerFontLayout& ) = delete;
- ServerFontLayout& operator=( const ServerFontLayout& ) = delete;
-
-};
-
-class ServerFontLayoutEngine
-{
-public:
- virtual ~ServerFontLayoutEngine() {}
-
- virtual bool Layout(ServerFontLayout&, ImplLayoutArgs&) = 0;
-};
-
#endif // INCLUDED_VCL_INC_GENERIC_GLYPHCACHE_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index acdaa297b61f..3bad16eea681 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -54,7 +54,6 @@ class X11OpenGLSalGraphicsImpl;
class X11OpenGLSalVirtualDevice;
class FreetypeFont;
class ImplLayoutArgs;
-class ServerFontLayout;
class PhysicalFontCollection;
class PhysicalFontFace;
class SalGraphicsImpl;
@@ -66,7 +65,6 @@ namespace basegfx {
class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
{
- friend class ServerFontLayout;
friend class X11SalGraphicsImpl;
friend class X11OpenGLSalGraphicsImpl;
friend class X11CairoTextRender;
diff --git a/vcl/unx/generic/fontmanager/fontconfig.cxx b/vcl/unx/generic/fontmanager/fontconfig.cxx
index dd9d17b7ad28..ea01866cf4a2 100644
--- a/vcl/unx/generic/fontmanager/fontconfig.cxx
+++ b/vcl/unx/generic/fontmanager/fontconfig.cxx
@@ -120,17 +120,13 @@ void FontCfgWrapper::addFontSet( FcSetName eSetName )
FcResult eOutRes = FcPatternGetBool( pPattern, FC_OUTLINE, 0, &bOutline );
if( (eOutRes != FcResultMatch) || (bOutline == FcFalse) )
continue;
- if (SalLayout::UseCommonLayout())
- {
- // Ignore Type 1 fonts; CommonSalLayout does not support them.
- FcChar8* pFormat = nullptr;
- FcResult eFormatRes = FcPatternGetString(pPattern, FC_FONTFORMAT, 0, &pFormat);
- if ((eFormatRes == FcResultMatch) &&
- (strcmp(reinterpret_cast<char*>(pFormat), "Type 1") == 0))
- {
- continue;
- }
- }
+
+ // Ignore Type 1 fonts, too.
+ FcChar8* pFormat = nullptr;
+ FcResult eFormatRes = FcPatternGetString(pPattern, FC_FONTFORMAT, 0, &pFormat);
+ if ((eFormatRes == FcResultMatch) && (strcmp(reinterpret_cast<char*>(pFormat), "Type 1") == 0))
+ continue;
+
FcPatternReference( pPattern );
FcFontSetAdd( m_pOutlineSet, pPattern );
}
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 289a066cf878..69e07a0c00c9 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -185,9 +185,6 @@ void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, con
case GF_ROTL: // left
glyph_extrarotation.push_back(1);
break;
- case GF_ROTR: // right
- glyph_extrarotation.push_back(-1);
- break;
default:
glyph_extrarotation.push_back(0);
break;
@@ -293,35 +290,17 @@ void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, con
//like them
double xdiff = 0.0;
double ydiff = 0.0;
- if (nGlyphRotation == 1)
+ if (nGlyphRotation)
{
- if (SalLayout::UseCommonLayout())
- {
- // The y is the origin point position, but Cairo will draw
- // the glyph *above* that point, we need to move it down to
- // the glyph’s baseline.
- cairo_text_extents_t aExt;
- cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen, &aExt);
- double nDescender = std::fmax(aExt.height + aExt.y_bearing, 0);
- ydiff = (aExt.x_advance - nDescender) / nHeight;
- }
- else
- {
- ydiff = font_extents.ascent/nHeight;
- }
+ // The y is the origin point position, but Cairo will draw
+ // the glyph *above* that point, we need to move it down to
+ // the glyph’s baseline.
+ cairo_text_extents_t aExt;
+ cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen, &aExt);
+ double nDescender = std::fmax(aExt.height + aExt.y_bearing, 0);
+ ydiff = (aExt.x_advance - nDescender) / nHeight;
xdiff = -font_extents.descent/nHeight;
}
- else if (nGlyphRotation == -1)
- {
- cairo_text_extents_t text_extents;
- cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
- &text_extents);
-
- xdiff = -text_extents.x_advance/nHeight;
- //to restore an apparent bug in the original X11 impl, replace
- //nHeight with nWidth below
- xdiff += font_extents.descent/nHeight;
- }
cairo_matrix_translate(&m, xdiff, ydiff);
}
@@ -506,10 +485,7 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL
if( mpFreetypeFont[ nFallbackLevel ]
&& !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
{
- if (SalLayout::UseCommonLayout())
- pLayout = new CommonSalLayout(*mpFreetypeFont[nFallbackLevel]);
- else
- pLayout = new ServerFontLayout( *mpFreetypeFont[ nFallbackLevel ] );
+ pLayout = new CommonSalLayout(*mpFreetypeFont[nFallbackLevel]);
}
return pLayout;
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 409972619201..156a1968ba74 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -225,7 +225,6 @@ void FreetypeFontInfo::ReleaseFaceFT()
static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8)+p[1]);}
-//static signed GetSShort( const unsigned char* p ){ return((short)((p[0]<<8)+p[1]));}
static const sal_uInt32 T_true = 0x74727565; /* 'true' */
static const sal_uInt32 T_ttcf = 0x74746366; /* 'ttcf' */
@@ -398,7 +397,6 @@ FreetypeFont::FreetypeFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI
mbArtItalic( false ),
mbArtBold( false ),
mbUseGamma( false ),
- mpLayoutEngine( nullptr ),
mpHbFont( nullptr )
{
// TODO: move update of mpFontInstance into FontEntry class when
@@ -445,9 +443,6 @@ FreetypeFont::FreetypeFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI
mbFaceOk = true;
- if (!SalLayout::UseCommonLayout())
- ApplyGSUB( rFSD );
-
// TODO: query GASP table for load flags
mnLoadFlags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_TRANSFORM;
@@ -562,8 +557,6 @@ int FreetypeFont::GetFontFaceIndex() const
FreetypeFont::~FreetypeFont()
{
- delete mpLayoutEngine;
-
if( maSizeFT )
FT_Done_Size( maSizeFT );
@@ -1213,232 +1206,6 @@ bool FreetypeFont::GetGlyphOutline( sal_GlyphId aGlyphId,
return true;
}
-void FreetypeFont::ApplyGSUB( const FontSelectPattern& rFSD )
-{
-#define MKTAG(s) ((((((s[0]<<8)+s[1])<<8)+s[2])<<8)+s[3])
-
- std::vector<sal_uInt32> aReqFeatureTagList;
- if( rFSD.mbVertical )
- aReqFeatureTagList.push_back( MKTAG("vert") );
- // TODO: request more features depending on script and language system
-
- if( aReqFeatureTagList.empty()) // nothing to do
- return;
-
- // load GSUB table into memory
- sal_uLong nLength = 0;
- const FT_Byte* const pGsubBase = mpFontInfo->GetTable( "GSUB", &nLength );
- if( !pGsubBase )
- return;
-
- // parse GSUB header
- const FT_Byte* pGsubHeader = pGsubBase;
- const sal_uInt16 nOfsScriptList = GetUShort( pGsubHeader+4 );
- const sal_uInt16 nOfsFeatureTable = GetUShort( pGsubHeader+6 );
- const sal_uInt16 nOfsLookupList = GetUShort( pGsubHeader+8 );
-
- std::vector<sal_uInt16> aFeatureIndexList;
-
- // parse Script Table
- const FT_Byte* pScriptHeader = pGsubBase + nOfsScriptList;
- const sal_uInt16 nCntScript = GetUShort( pScriptHeader+0 );
- pScriptHeader += 2;
- for( sal_uInt16 nScriptIndex = 0; nScriptIndex < nCntScript; ++nScriptIndex )
- {
- const sal_uInt16 nOfsScriptTable= GetUShort( pScriptHeader+4 );
- pScriptHeader += 6;
-
- const FT_Byte* pScriptTable = pGsubBase + nOfsScriptList + nOfsScriptTable;
- const sal_uInt16 nDefaultLangsysOfs = GetUShort( pScriptTable+0 );
- const sal_uInt16 nCntLangSystem = GetUShort( pScriptTable+2 );
- pScriptTable += 4;
- sal_uInt16 nLangsysOffset = 0;
-
- if (nCntLangSystem != 0)
- {
- nLangsysOffset = GetUShort( pScriptTable+4 );
- }
-
- if (nDefaultLangsysOfs != 0 && nDefaultLangsysOfs != nLangsysOffset)
- {
- const FT_Byte* pLangSys = pGsubBase + nOfsScriptList + nOfsScriptTable + nDefaultLangsysOfs;
- const sal_uInt16 nReqFeatureIdx = GetUShort( pLangSys+2 );
- const sal_uInt16 nCntFeature = GetUShort( pLangSys+4 );
- pLangSys += 6;
- aFeatureIndexList.push_back( nReqFeatureIdx );
- for( sal_uInt16 i = 0; i < nCntFeature; ++i )
- {
- const sal_uInt16 nFeatureIndex = GetUShort( pLangSys );
- pLangSys += 2;
- aFeatureIndexList.push_back( nFeatureIndex );
- }
- }
-
- if( nLangsysOffset != 0 )
- {
- const FT_Byte* pLangSys = pGsubBase + nOfsScriptList + nOfsScriptTable + nLangsysOffset;
- const sal_uInt16 nReqFeatureIdx = GetUShort( pLangSys+2 );
- const sal_uInt16 nCntFeature = GetUShort( pLangSys+4 );
- pLangSys += 6;
- aFeatureIndexList.push_back( nReqFeatureIdx );
- for( sal_uInt16 i = 0; i < nCntFeature; ++i )
- {
- const sal_uInt16 nFeatureIndex = GetUShort( pLangSys );
- pLangSys += 2;
- aFeatureIndexList.push_back( nFeatureIndex );
- }
- }
- }
-
- if( aFeatureIndexList.empty() )
- return;
-
- std::vector<sal_uInt16> aLookupIndexList;
- std::vector<sal_uInt16> aLookupOffsetList;
-
- // parse Feature Table
- const FT_Byte* pFeatureHeader = pGsubBase + nOfsFeatureTable;
- const sal_uInt16 nCntFeature = GetUShort( pFeatureHeader );
- pFeatureHeader += 2;
- for( sal_uInt16 nFeatureIndex = 0; nFeatureIndex < nCntFeature; ++nFeatureIndex )
- {
- const sal_uLong nTag = GetUInt( pFeatureHeader+0 ); // e.g. locl/vert/trad/smpl/liga/fina/...
- const sal_uInt16 nOffset= GetUShort( pFeatureHeader+4 );
- pFeatureHeader += 6;
-
- // short circuit some feature lookups
- if( aFeatureIndexList[0] != nFeatureIndex ) // required feature?
- {
- const int nRequested = std::count( aFeatureIndexList.begin(), aFeatureIndexList.end(), nFeatureIndex);
- if( !nRequested ) // ignore features that are not requested
- continue;
- const int nAvailable = std::count( aReqFeatureTagList.begin(), aReqFeatureTagList.end(), nTag);
- if( !nAvailable ) // some fonts don't provide features they request!
- continue;
- }
-
- const FT_Byte* pFeatureTable = pGsubBase + nOfsFeatureTable + nOffset;
- pFeatureTable += 2; // ignore FeatureParams
- const sal_uInt16 nCntLookups = GetUShort( pFeatureTable+0 );
- pFeatureTable += 2;
- for( sal_uInt16 i = 0; i < nCntLookups; ++i )
- {
- const sal_uInt16 nLookupIndex = GetUShort( pFeatureTable );
- pFeatureTable += 2;
- aLookupIndexList.push_back( nLookupIndex );
- }
- if( nCntLookups == 0 ) //### hack needed by Mincho/Gothic/Mingliu/Simsun/...
- aLookupIndexList.push_back( 0 );
- }
-
- // parse Lookup List
- const FT_Byte* pLookupHeader = pGsubBase + nOfsLookupList;
- const sal_uInt16 nCntLookupTable = GetUShort( pLookupHeader );
- pLookupHeader += 2;
- for( sal_uInt16 nLookupIdx = 0; nLookupIdx < nCntLookupTable; ++nLookupIdx )
- {
- const sal_uInt16 nOffset = GetUShort( pLookupHeader );
- pLookupHeader += 2;
- if( std::count( aLookupIndexList.begin(), aLookupIndexList.end(), nLookupIdx ) )
- aLookupOffsetList.push_back( nOffset );
- }
-
- std::vector<sal_uInt16>::const_iterator lookup_it = aLookupOffsetList.begin();
- for(; lookup_it != aLookupOffsetList.end(); ++lookup_it )
- {
- const sal_uInt16 nOfsLookupTable = *lookup_it;
- const FT_Byte* pLookupTable = pGsubBase + nOfsLookupList + nOfsLookupTable;
- const sal_uInt16 eLookupType = GetUShort( pLookupTable+0 );
- const sal_uInt16 nCntLookupSubtable = GetUShort( pLookupTable+4 );
- pLookupTable += 6;
-
- // TODO: switch( eLookupType )
- if( eLookupType != 1 ) // TODO: once we go beyond SingleSubst
- continue;
-
- for( sal_uInt16 nSubTableIdx = 0; nSubTableIdx < nCntLookupSubtable; ++nSubTableIdx )
- {
- const sal_uInt16 nOfsSubLookupTable = GetUShort( pLookupTable );
- pLookupTable += 2;
- const FT_Byte* pSubLookup = pGsubBase + nOfsLookupList + nOfsLookupTable + nOfsSubLookupTable;
-
- const sal_uInt16 nFmtSubstitution = GetUShort( pSubLookup+0 );
- const sal_uInt16 nOfsCoverage = GetUShort( pSubLookup+2 );
- pSubLookup += 4;
-
- typedef std::pair<sal_uInt16,sal_uInt16> GlyphSubst;
- std::vector<GlyphSubst> aSubstVector;
-
- const FT_Byte* pCoverage = pGsubBase + nOfsLookupList + nOfsLookupTable + nOfsSubLookupTable + nOfsCoverage;
- const sal_uInt16 nFmtCoverage = GetUShort( pCoverage+0 );
- pCoverage += 2;
- switch( nFmtCoverage )
- {
- case 1: // Coverage Format 1
- {
- const sal_uInt16 nCntGlyph = GetUShort( pCoverage );
- pCoverage += 2;
- aSubstVector.reserve( nCntGlyph );
- for( sal_uInt16 i = 0; i < nCntGlyph; ++i )
- {
- const sal_uInt16 nGlyphId = GetUShort( pCoverage );
- pCoverage += 2;
- aSubstVector.push_back( GlyphSubst( nGlyphId, 0 ) );
- }
- }
- break;
-
- case 2: // Coverage Format 2
- {
- const sal_uInt16 nCntRange = GetUShort( pCoverage );
- pCoverage += 2;
- for( int i = nCntRange; --i >= 0; )
- {
- const sal_uInt32 nGlyph0 = GetUShort( pCoverage+0 );
- const sal_uInt32 nGlyph1 = GetUShort( pCoverage+2 );
- const sal_uInt16 nCovIdx = GetUShort( pCoverage+4 );
- pCoverage += 6;
- for( sal_uInt32 j = nGlyph0; j <= nGlyph1; ++j )
- aSubstVector.push_back( GlyphSubst( static_cast<sal_uInt16>(j + nCovIdx), 0 ) );
- }
- }
- break;
- }
-
- std::vector<GlyphSubst>::iterator it( aSubstVector.begin() );
-
- switch( nFmtSubstitution )
- {
- case 1: // Single Substitution Format 1
- {
- const sal_uInt16 nDeltaGlyphId = GetUShort( pSubLookup );
- for(; it != aSubstVector.end(); ++it )
- (*it).second = (*it).first + nDeltaGlyphId;
- }
- break;
-
- case 2: // Single Substitution Format 2
- {
- const sal_uInt16 nCntGlyph = GetUShort( pSubLookup );
- pSubLookup += 2;
- for( int i = nCntGlyph; (it != aSubstVector.end()) && (--i>=0); ++it )
- {
- const sal_uInt16 nGlyphId = GetUShort( pSubLookup );
- pSubLookup += 2;
- (*it).second = nGlyphId;
- }
- }
- break;
- }
-
- SAL_WARN_IF( (it != aSubstVector.end()), "vcl", "lookup<->coverage table mismatch" );
- // now apply the glyph substitutions that have been collected in this subtable
- for( it = aSubstVector.begin(); it != aSubstVector.end(); ++it )
- maGlyphSubstitution[ (*it).first ] = (*it).second;
- }
- }
-}
-
const unsigned char* FreetypeFont::GetTable(const char* pName, sal_uLong* pLength)
{
return mpFontInfo->GetTable( pName, pLength );
diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx
deleted file mode 100644
index 71eb88f7cbd8..000000000000
--- a/vcl/unx/generic/glyphs/gcach_layout.cxx
+++ /dev/null
@@ -1,621 +0,0 @@
-/* -*- 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 "unx/freetype_glyphcache.hxx"
-#include <sallayout.hxx>
-#include <salgdi.hxx>
-#include <scrptrun.h>
-#include <unx/genpspgraphics.h>
-
-#include <i18nlangtag/mslangid.hxx>
-
-#include <vcl/svapp.hxx>
-#include <vcl/unohelp.hxx>
-
-#include <rtl/instance.hxx>
-
-#include <hb-icu.h>
-#include <hb-ot.h>
-
-#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
-
-#ifndef HB_VERSION_ATLEAST
-#define HB_VERSION_ATLEAST(a,b,c) 0
-#endif
-
-// layout implementation for FreetypeFont
-ServerFontLayout::ServerFontLayout( FreetypeFont& rFont )
-: mrFreetypeFont( rFont )
-{
-}
-
-void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
-{
- rSalGraphics.DrawServerFontLayout( *this, mrFreetypeFont );
-}
-
-bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs )
-{
- return mrFreetypeFont.GetLayoutEngine()->Layout(*this, rArgs);
-}
-
-void ServerFontLayout::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);
-
- // insert kashidas where requested by the formatting array
- if( (rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray )
- {
- int nKashidaIndex = mrFreetypeFont.GetGlyphIndex( 0x0640 );
- if( nKashidaIndex != 0 )
- {
- const GlyphMetric& rGM = mrFreetypeFont.GetGlyphMetric( nKashidaIndex );
- KashidaJustify( nKashidaIndex, rGM.GetCharWidth() );
- // TODO: kashida-GSUB/GPOS
- }
- }
-}
-
-void ServerFontLayout::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);
-}
-
-std::ostream &operator <<(std::ostream& s, FreetypeFont* pFont)
-{
-#ifndef SAL_LOG_INFO
- (void) pFont;
-#else
- FT_Face aFace = pFont->GetFtFace();
- const char* pName = FT_Get_Postscript_Name(aFace);
- if (pName)
- s << pName;
- else
- s << pFont->GetFontFileName();
-#endif
- return s;
-}
-
-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;
-
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pUserData);
-
- SAL_INFO("vcl.harfbuzz", "getFontTable(" << pFont << ", " << pTagName << ")");
-
- sal_uLong nLength;
- const unsigned char* pBuffer = pFont->GetTable(pTagName, &nLength);
-
- hb_blob_t* pBlob = nullptr;
- if (pBuffer != nullptr)
- pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, const_cast<unsigned char *>(pBuffer), nullptr);
-
- return pBlob;
-}
-
-static hb_bool_t getFontGlyph(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t ch, hb_codepoint_t vs,
- hb_codepoint_t* nGlyphIndex,
- void* /*pUserData*/)
-{
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pFontData);
- *nGlyphIndex = pFont->GetRawGlyphIndex(ch, vs);
-
- // tdf#89231 if the font is missing non-breaking space, then use a normal space
- if (*nGlyphIndex == 0 && ch == 0x202F && !vs)
- *nGlyphIndex = pFont->GetRawGlyphIndex(' ');
-
- return *nGlyphIndex != 0;
-}
-
-static hb_position_t getGlyphAdvanceH(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex,
- void* /*pUserData*/)
-{
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pFontData);
- const GlyphMetric& rGM = pFont->GetGlyphMetric(nGlyphIndex);
- return rGM.GetCharWidth() << 6;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 2)
-static hb_position_t getGlyphAdvanceV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- void* /*pUserData*/)
-{
- // XXX: vertical metrics
- return 0;
-}
-
-static hb_bool_t getGlyphOriginH(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- hb_position_t* /*x*/, hb_position_t* /*y*/,
- void* /*pUserData*/)
-{
- // the horizontal origin is always (0, 0)
- return true;
-}
-
-static hb_bool_t getGlyphOriginV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- hb_position_t* /*x*/, hb_position_t* /*y*/,
- void* /*pUserData*/)
-{
- // XXX: vertical origin
- return true;
-}
-#endif
-
-static hb_position_t getGlyphKerningH(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex1, hb_codepoint_t nGlyphIndex2,
- void* /*pUserData*/)
-{
- // This callback is for old style 'kern' table, GPOS kerning is handled by HarfBuzz directly
-
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphKerningH(" << pFont << ", " << nGlyphIndex1 << ", " << nGlyphIndex2 << ")");
-
- FT_Error error;
- FT_Vector kerning;
- hb_position_t ret;
-
- error = FT_Get_Kerning(aFace, nGlyphIndex1, nGlyphIndex2, FT_KERNING_DEFAULT, &kerning);
- if (error)
- ret = 0;
- else
- ret = kerning.x;
-
- return ret;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 2)
-static hb_position_t getGlyphKerningV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex1*/, hb_codepoint_t /*nGlyphIndex2*/,
- void* /*pUserData*/)
-{
- // XXX vertical kerning
- return 0;
-}
-#endif
-
-static hb_bool_t getGlyphExtents(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex,
- hb_glyph_extents_t* pExtents,
- void* /*pUserData*/)
-{
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphExtents(" << pFont << ", " << nGlyphIndex << ")");
-
- FT_Error error;
- error = FT_Load_Glyph(aFace, nGlyphIndex, FT_LOAD_DEFAULT);
- if (!error)
- {
- pExtents->x_bearing = aFace->glyph->metrics.horiBearingX;
- pExtents->y_bearing = aFace->glyph->metrics.horiBearingY;
- pExtents->width = aFace->glyph->metrics.width;
- pExtents->height = -aFace->glyph->metrics.height;
- }
-
- return !error;
-}
-
-static hb_bool_t getGlyphContourPoint(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex, unsigned int nPointIndex,
- hb_position_t *x, hb_position_t *y,
- void* /*pUserData*/)
-{
- bool ret = false;
- FreetypeFont* pFont = static_cast<FreetypeFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphContourPoint(" << pFont << ", " << nGlyphIndex << ", " << nPointIndex << ")");
-
- FT_Error error;
- error = FT_Load_Glyph(aFace, nGlyphIndex, FT_LOAD_DEFAULT);
- if (!error)
- {
- if (aFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
- {
- if (nPointIndex < (unsigned int) aFace->glyph->outline.n_points)
- {
- *x = aFace->glyph->outline.points[nPointIndex].x;
- *y = aFace->glyph->outline.points[nPointIndex].y;
- ret = true;
- }
- }
- }
-
- return ret;
-}
-
-static hb_font_funcs_t* getFontFuncs()
-{
- static hb_font_funcs_t* funcs = hb_font_funcs_create();
-
- hb_font_funcs_set_glyph_func (funcs, getFontGlyph, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_advance_func (funcs, getGlyphAdvanceH, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_kerning_func (funcs, getGlyphKerningH, nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func (funcs, getGlyphExtents, nullptr, nullptr);
- hb_font_funcs_set_glyph_contour_point_func (funcs, getGlyphContourPoint, nullptr, nullptr);
-#if !HB_VERSION_ATLEAST(1, 1, 2)
- hb_font_funcs_set_glyph_v_advance_func (funcs, getGlyphAdvanceV, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_origin_func (funcs, getGlyphOriginH, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func (funcs, getGlyphOriginV, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_kerning_func (funcs, getGlyphKerningV, nullptr, nullptr);
-#endif
-
- return funcs;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 0)
-// Disabled Unicode compatibility decomposition, see fdo#66715
-static unsigned int unicodeDecomposeCompatibility(hb_unicode_funcs_t* /*ufuncs*/,
- hb_codepoint_t /*u*/,
- hb_codepoint_t* /*decomposed*/,
- void* /*user_data*/)
-{
- return 0;
-}
-
-static hb_unicode_funcs_t* getUnicodeFuncs()
-{
- static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
- hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, unicodeDecomposeCompatibility, nullptr, nullptr);
- return ufuncs;
-}
-#endif
-
-class HbLayoutEngine : public ServerFontLayoutEngine
-{
-private:
- hb_script_t maHbScript;
- hb_face_t* mpHbFace;
- int mnUnitsPerEM;
-
-public:
- explicit HbLayoutEngine(FreetypeFont&);
- virtual ~HbLayoutEngine() override;
-
- virtual bool Layout(ServerFontLayout&, ImplLayoutArgs&) override;
-};
-
-HbLayoutEngine::HbLayoutEngine(FreetypeFont& rFreetypeFont)
-: maHbScript(HB_SCRIPT_INVALID),
- mpHbFace(nullptr),
- mnUnitsPerEM(0)
-{
- FT_Face aFtFace = rFreetypeFont.GetFtFace();
- mnUnitsPerEM = rFreetypeFont.GetEmUnits();
-
- mpHbFace = hb_face_create_for_tables(getFontTable, &rFreetypeFont, nullptr);
- hb_face_set_index(mpHbFace, aFtFace->face_index);
- hb_face_set_upem(mpHbFace, mnUnitsPerEM);
-}
-
-HbLayoutEngine::~HbLayoutEngine()
-{
- hb_face_destroy(mpHbFace);
-}
-
-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> ServerFontLayout::CreateTextLayoutCache(
- OUString const& rString) const
-{
- return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength());
-}
-
-bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
-{
- FreetypeFont& rFont = rLayout.GetFreetypeFont();
- FT_Face aFtFace = rFont.GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "layout(" << this << ",rArgs=" << rArgs << ")");
-
- static hb_font_funcs_t* pHbFontFuncs = getFontFuncs();
-
- hb_font_t *pHbFont = hb_font_create(mpHbFace);
- hb_font_set_funcs(pHbFont, pHbFontFuncs, &rFont, nullptr);
- hb_font_set_scale(pHbFont,
- ((uint64_t) aFtFace->size->metrics.x_scale * (uint64_t) mnUnitsPerEM) >> 16,
- ((uint64_t) aFtFace->size->metrics.y_scale * (uint64_t) mnUnitsPerEM) >> 16);
- hb_font_set_ppem(pHbFont, aFtFace->size->metrics.x_ppem, aFtFace->size->metrics.y_ppem);
-
- // allocate temporary arrays, note: round to even
- int nGlyphCapacity = (3 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos) | 15) + 1;
- int32_t nVirtAdv = int32_t(aFtFace->size->metrics.height*rFont.GetStretch())>>6;
-
- rLayout.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;
- maHbScript = 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();
-#if !HB_VERSION_ATLEAST(1, 1, 0)
- static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs();
- 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, maHbScript);
- 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);
- 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);
-
- 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)
- {
- rLayout.SetNeedFallback(rArgs, nCharPos, bRightToLeft);
- if (SalLayoutFlags::ForFallback & rArgs.mnFlags)
- continue;
- }
-
- // apply vertical flags and glyph substitution
- // XXX: Use HB_DIRECTION_TTB above and apply whatever flags magic
- // FixupGlyphIndex() is doing, minus the GSUB part.
- sal_Int32 indexUtf16 = nCharPos;
- sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0);
- nGlyphIndex = rFont.FixupGlyphIndex(nGlyphIndex, aChar);
-
- bool bInCluster = false;
- if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
- bInCluster = true;
-
- long nGlyphFlags = 0;
- if (bRightToLeft)
- nGlyphFlags |= GlyphItem::IS_RTL_GLYPH;
-
- if (bInCluster)
- nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
-
- // The whole IS_DIACRITIC concept is a stupid hack that was
- // introduced ages ago to work around the utter brokenness of the
- // way justification adjustments are applied (the DXArray fiasco).
- // Since it is such a stupid hack, there is no sane way to directly
- // map to concepts of the "outside" world, so we do some rather
- // ugly hacks:
- // * If the font has a GDEF table, we check for glyphs with mark
- // glyph class which is sensible, except that some fonts
- // (fdo#70968) assign mark class to spacing marks (which is wrong
- // but usually harmless), so we try to sniff what HarfBuzz thinks
- // about this glyph by checking if it gives it a zero advance
- // width.
- // * If the font has no GDEF table, we just check if the glyph has
- // zero advance width, but this is stupid and can be wrong. A
- // better way would to check the character's Unicode combining
- // class, but unfortunately HarfBuzz gives combining marks the
- // cluster value of its base character, so nCharPos will be
- // pointing to the wrong character (but HarfBuzz might change
- // this in the future).
- // Newer versions of HarfBuzz can control this behaviour with
- // hb_buffer_set_cluster_level().
- bool bDiacritic = false;
- if (hb_ot_layout_has_glyph_classes(mpHbFace))
- {
- // the font has GDEF table
- bool bMark = hb_ot_layout_get_glyph_class(mpHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
- if (bMark && pHbPositions[i].x_advance == 0)
- bDiacritic = true;
- }
- else
- {
- // the font lacks GDEF table
- if (pHbPositions[i].x_advance == 0)
- bDiacritic = true;
- }
-
- if (bDiacritic)
- nGlyphFlags |= GlyphItem::IS_DIACRITIC;
-
- int32_t nXOffset = pHbPositions[i].x_offset >> 6;
- int32_t nYOffset = pHbPositions[i].y_offset >> 6;
- int32_t nXAdvance = pHbPositions[i].x_advance >> 6;
- int32_t nYAdvance = pHbPositions[i].y_advance >> 6;
- if ( nGlyphIndex & GF_ROTMASK )
- nXAdvance = nVirtAdv;
-
- Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset));
- const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset);
- rLayout.AppendGlyph(aGI);
-
- aCurrPos.X() += nXAdvance;
- aCurrPos.Y() += nYAdvance;
- }
-
- hb_buffer_destroy(pHbBuffer);
- }
- }
-
- hb_font_destroy(pHbFont);
-
- // sort glyphs in visual order
- // and then in logical order (e.g. diacritics after cluster start)
- // XXX: why?
- rLayout.SortGlyphItems();
-
- // determine need for kashida justification
- if((rArgs.mpDXArray || rArgs.mnLayoutWidth)
- && ((maHbScript == HB_SCRIPT_ARABIC) || (maHbScript == HB_SCRIPT_SYRIAC)))
- rArgs.mnFlags |= SalLayoutFlags::KashidaJustification;
-
- return true;
-}
-
-ServerFontLayoutEngine* FreetypeFont::GetLayoutEngine()
-{
- if (!mpLayoutEngine) {
- mpLayoutEngine = new HbLayoutEngine(*this);
- }
- return mpLayoutEngine;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx
index ee605546dc5f..91a363e22054 100644
--- a/vcl/unx/generic/print/genpspgraphics.cxx
+++ b/vcl/unx/generic/print/genpspgraphics.cxx
@@ -640,48 +640,6 @@ bool PspFontLayout::LayoutText( ImplLayoutArgs& rArgs )
return (aOldGlyphId != GF_DROPPED);
}
-class PspServerFontLayout : public ServerFontLayout
-{
-public:
- PspServerFontLayout( psp::PrinterGfx&, FreetypeFont& rFont, const ImplLayoutArgs& rArgs );
-
- virtual void InitFont() const override;
- const sal_Unicode* getTextPtr() const { return maText.getStr() - mnMinCharPos; }
- int getMinCharPos() const { return mnMinCharPos; }
- int getMaxCharPos() const { return mnMinCharPos+maText.getLength()-1; }
-private:
- ::psp::PrinterGfx& mrPrinterGfx;
- sal_IntPtr mnFontID;
- int mnFontHeight;
- int mnFontWidth;
- bool mbVertical;
- bool mbArtItalic;
- bool mbArtBold;
- OUString maText;
- int mnMinCharPos;
-};
-
-PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx& rGfx, FreetypeFont& rFont, const ImplLayoutArgs& rArgs )
- : ServerFontLayout( rFont ),
- mrPrinterGfx( rGfx )
-{
- mnFontID = mrPrinterGfx.GetFontID();
- mnFontHeight = mrPrinterGfx.GetFontHeight();
- mnFontWidth = mrPrinterGfx.GetFontWidth();
- mbVertical = mrPrinterGfx.GetFontVertical();
- mbArtItalic = mrPrinterGfx.GetArtificialItalic();
- mbArtBold = mrPrinterGfx.GetArtificialBold();
- const sal_Unicode *pStr = rArgs.mrStr.getStr();
- maText = OUString( pStr + rArgs.mnMinCharPos, rArgs.mnEndCharPos - rArgs.mnMinCharPos+1 );
- mnMinCharPos = rArgs.mnMinCharPos;
-}
-
-void PspServerFontLayout::InitFont() const
-{
- mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
- mnOrientation, mbVertical, mbArtItalic, mbArtBold );
-}
-
class PspCommonSalLayout : public CommonSalLayout
{
public:
@@ -718,7 +676,7 @@ void PspCommonSalLayout::InitFont() const
mnOrientation, mbVertical, mbArtItalic, mbArtBold);
}
-static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout )
+static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx)
{
const int nMaxGlyphs = 1;
sal_GlyphId aGlyphAry[ nMaxGlyphs ];
@@ -732,16 +690,6 @@ static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx
const sal_Unicode* pText = nullptr;
int nMinCharPos = 0;
int nMaxCharPos = 0;
- if (bIsPspServerFontLayout)
- {
- const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout);
- if (pPspLayout)
- {
- pText = pPspLayout->getTextPtr();
- nMinCharPos = pPspLayout->getMinCharPos();
- nMaxCharPos = pPspLayout->getMaxCharPos();
- }
- }
for( int nStart = 0;; )
{
int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : nullptr );
@@ -773,18 +721,18 @@ void PspFontLayout::InitFont() const
void PspFontLayout::DrawText( SalGraphics& ) const
{
- DrawPrinterLayout( *this, mrPrinterGfx, false );
+ DrawPrinterLayout(*this, mrPrinterGfx);
}
void GenPspGraphics::DrawServerFontLayout( const GenericSalLayout& rLayout, const FreetypeFont& /*unused*/ )
{
// print complex text
- DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
+ DrawPrinterLayout(rLayout, *m_pPrinterGfx);
}
void GenPspGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
{
- DrawPrinterLayout(rLayout, *m_pPrinterGfx, false);
+ DrawPrinterLayout(rLayout, *m_pPrinterGfx);
}
const FontCharMapRef GenPspGraphics::GetFontCharMap() const
@@ -1012,10 +960,7 @@ SalLayout* GenPspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
if( m_pFreetypeFont[ nFallbackLevel ]
&& !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
{
- if (SalLayout::UseCommonLayout())
- pLayout = new PspCommonSalLayout(*m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel]);
- else
- pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel], rArgs );
+ pLayout = new PspCommonSalLayout(*m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel]);
}
else
pLayout = new PspFontLayout( *m_pPrinterGfx );