Kaydet (Commit) 6c436ba0 authored tarafından Khaled Hosny's avatar Khaled Hosny

Kill old Windows layout engines

Change-Id: I33f8322a6371150698bf926165fb6dddb9d4092c
Reviewed-on: https://gerrit.libreoffice.org/31452Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarKhaled Hosny <khaledhosny@eglug.org>
üst 6e5e55c2
......@@ -74,27 +74,16 @@ public:
BYTE GetCharSet() const { return meWinCharSet; }
BYTE GetPitchAndFamily() const { return mnPitchAndFamily; }
bool SupportsCJK() const { return mbHasCJKSupport; }
bool SupportsArabic() const { return mbHasArabicSupport; }
FontCharMapRef GetFontCharMap() const;
bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; }
void SetEncodingVector( const Ucs2SIntMap* pNewVec ) const
{
if( mpEncodingVector )
delete mpEncodingVector;
mpEncodingVector = pNewVec;
}
private:
sal_IntPtr mnId;
// some members that are initalized lazily when the font gets selected into a HDC
mutable bool mbHasCJKSupport;
mutable bool mbHasArabicSupport;
mutable bool mbFontCapabilitiesRead;
mutable FontCharMapRef mxUnicodeMap;
mutable const Ucs2SIntMap* mpEncodingVector;
mutable vcl::FontCapabilities maFontCapabilities;
BYTE meWinCharSet;
......@@ -105,14 +94,8 @@ private:
void ReadCmapTable( HDC ) const;
void GetFontCapabilities( HDC hDC ) const;
void ReadGsubTable( HDC ) const;
mutable std::unordered_set<sal_UCS4> maGsubTable;
mutable bool mbGsubRead;
mutable hb_font_t* mpHbFont;
public:
bool HasGSUBstitutions( HDC ) const;
bool IsGSUBstituted( sal_UCS4 ) const;
hb_font_t* GetHbFont() const { return mpHbFont; }
void SetHbFont( hb_font_t* pHbFont ) const { mpHbFont = pHbFont; }
};
......@@ -168,9 +151,6 @@ class WinSalGraphics : public SalGraphics
friend class WinOpenGLSalGraphicsImpl;
friend class ScopedFont;
friend class OpenGLCompatibleDC;
friend class WinLayout;
friend class SimpleWinLayout;
friend class UniscribeLayout;
protected:
std::unique_ptr<SalGraphicsImpl> mpImpl;
......@@ -196,9 +176,6 @@ private:
COLORREF mnTextColor; // TextColor
RGNDATA* mpClipRgnData; // ClipRegion-Data
RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
bool mbFontKernInit; // FALSE: FontKerns must be queried
KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font
sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of the current Font
int mnPenWidth; // Linienbreite
LogicalFontInstance* GetWinFontEntry(int nFallbackLevel);
......@@ -321,9 +298,6 @@ protected:
private:
// local helpers
// get kernign pairs of the current font
sal_uLong GetKernPairs();
static void DrawTextLayout(const CommonSalLayout&, HDC, bool bUseDWrite);
public:
......@@ -427,17 +401,6 @@ void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*,
#define MAX_64KSALPOINTS ((((sal_uInt16)0xFFFF)-8)/sizeof(POINTS))
// #102411# Win's GCP mishandles kerning => we need to do it ourselves
// SalGraphicsData::mpFontKernPairs is sorted by
inline bool ImplCmpKernData( const KERNINGPAIR& a, const KERNINGPAIR& b )
{
if( a.wFirst < b.wFirst )
return true;
if( a.wFirst > b.wFirst )
return false;
return (a.wSecond < b.wSecond);
}
// called extremely often from just one spot => inline
inline bool WinFontFace::HasChar( sal_uInt32 cChar ) const
{
......
......@@ -35,7 +35,6 @@
typedef std::unordered_map<int,int> IntMap;
class WinFontInstance;
struct VisualItem;
namespace
{
......@@ -53,7 +52,6 @@ struct OpenGLGlyphDrawElement
int mnBaselineOffset;
int mnHeight;
bool mbVertical;
bool mbRealGlyphIndices;
int getExtraSpace() const
{
......@@ -159,15 +157,6 @@ public:
private:
// TODO: also add HFONT??? Watch out for issues with too many active fonts...
public:
bool HasKernData() const;
void SetKernData( int, const KERNINGPAIR* );
int GetKerning( sal_Unicode, sal_Unicode ) const;
private:
KERNINGPAIR* mpKerningPairs;
int mnKerningPairs;
public:
SCRIPT_CACHE& GetScriptCache() const
{ return maScriptCache; }
......@@ -175,9 +164,6 @@ private:
mutable SCRIPT_CACHE maScriptCache;
public:
int GetCachedGlyphWidth( int nCharCode ) const;
void CacheGlyphWidth( int nCharCode, int nCharWidth );
bool InitKashidaHandling( HDC );
int GetMinKashidaWidth() const { return mnMinKashidaWidth; }
int GetMinKashidaGlyph() const { return mnMinKashidaGlyph; }
......@@ -185,7 +171,7 @@ public:
private:
GlyphCache maGlyphCache;
public:
bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics);
bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics);
GlyphCache& GetGlyphCache()
{
......@@ -193,155 +179,10 @@ public:
}
private:
std::unordered_map<int, int> maWidthMap;
mutable int mnMinKashidaWidth;
mutable int mnMinKashidaGlyph;
};
class WinLayout : public SalLayout
{
public:
WinLayout(HDC, const WinFontFace&, WinFontInstance&, bool bUseOpenGL);
virtual ~WinLayout() override;
virtual void InitFont() const override;
void SetFontScale( float f ) { mfFontScale = f; }
HFONT DisableFontScaling() const;
SCRIPT_CACHE& GetScriptCache() const;
/// In the non-OpenGL case, call the DrawTextImpl directly, otherwise make
/// sure we draw to an interim texture.
virtual void DrawText(SalGraphics&) const override;
/// Draw to the provided HDC.
virtual bool DrawTextImpl(HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) const = 0;
virtual bool CacheGlyphs(SalGraphics& rGraphics) const = 0;
virtual bool DrawCachedGlyphs(SalGraphics& rGraphics) const = 0;
HDC mhDC; // WIN32 device handle
HFONT mhFont; // WIN32 font handle
int mnBaseAdv; // x-offset relative to Layout origin
float mfFontScale; // allows metrics emulation of huge font sizes
bool mbUseOpenGL; ///< We need to render via OpenGL
const WinFontFace& mrWinFontData;
WinFontInstance& mrWinFontEntry;
};
class SimpleWinLayout : public WinLayout
{
public:
SimpleWinLayout(HDC, const WinFontFace&, WinFontInstance&, bool bUseOpenGL);
virtual ~SimpleWinLayout() override;
virtual bool LayoutText( ImplLayoutArgs& ) override;
virtual void AdjustLayout( ImplLayoutArgs& ) override;
virtual bool DrawTextImpl(HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) const override;
virtual bool CacheGlyphs(SalGraphics& rGraphics) const override;
virtual bool DrawCachedGlyphs(SalGraphics& rGraphics) const override;
virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
DeviceCoordinate* pGlyphAdvances = nullptr, int* pCharIndexes = nullptr,
const PhysicalFontFace** pFallbackFonts = nullptr ) const override;
virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override;
virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override;
virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override;
// for glyph+font+script fallback
virtual void MoveGlyph( int nStart, long nNewXPos ) override;
virtual void DropGlyph( int nStart ) override;
virtual void Simplify( bool bIsBase ) override;
protected:
void Justify( DeviceCoordinate nNewWidth );
void ApplyDXArray( const ImplLayoutArgs& );
private:
int mnGlyphCount;
int mnCharCount;
WCHAR* mpOutGlyphs;
int* mpGlyphAdvances; // if possible this is shared with mpGlyphAdvances[]
int* mpGlyphOrigAdvs;
int* mpCharWidths; // map rel char pos to char width
int* mpChars2Glyphs; // map rel char pos to abs glyph pos
int* mpGlyphs2Chars; // map abs glyph pos to abs char pos
bool* mpGlyphRTLFlags; // BiDi status for glyphs: true=>RTL
mutable long mnWidth;
int mnNotdefWidth;
};
class UniscribeLayout : public WinLayout
{
public:
UniscribeLayout(HDC, const WinFontFace&, WinFontInstance&, bool bUseOpenGL);
virtual bool LayoutText( ImplLayoutArgs& ) override;
virtual void AdjustLayout( ImplLayoutArgs& ) override;
virtual bool DrawTextImpl(HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) const override;
virtual bool CacheGlyphs(SalGraphics& rGraphics) const override;
virtual bool DrawCachedGlyphs(SalGraphics& rGraphics) const override;
virtual int GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, int&,
DeviceCoordinate* pGlyphAdvances = nullptr, int* pCharPosAry = nullptr,
const PhysicalFontFace** pFallbackFonts = nullptr ) const override;
virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override;
virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override;
virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override;
virtual bool IsKashidaPosValid ( int nCharPos ) const override;
// for glyph+font+script fallback
virtual void MoveGlyph( int nStart, long nNewXPos ) override;
virtual void DropGlyph( int nStart ) override;
virtual void Simplify( bool bIsBase ) override;
virtual void DisableGlyphInjection( bool bDisable ) override { mbDisableGlyphInjection = bDisable; }
protected:
virtual ~UniscribeLayout() override;
void Justify( DeviceCoordinate nNewWidth );
void ApplyDXArray( const ImplLayoutArgs& );
bool GetItemSubrange( const VisualItem&,
int& rMinIndex, int& rEndIndex ) const;
private:
// item specific info
SCRIPT_ITEM* mpScriptItems; // in logical order
VisualItem* mpVisualItems; // in visual order
int mnItemCount; // number of visual items
// string specific info
// everything is in logical order
OUString msTheString; // Sadly we need it in GetNextGlyphs(), to be able to call GetVerticalFlags()
int mnCharCapacity;
WORD* mpLogClusters; // map from absolute_char_pos to relative_glyph_pos
int* mpCharWidths; // map from absolute_char_pos to char_width
int mnSubStringMin; // char_pos of first char in context
// glyph specific info
// everything is in visual order
int mnGlyphCount;
int mnGlyphCapacity;
int* mpGlyphAdvances; // glyph advance width before justification
int* mpJustifications; // glyph advance width after justification
WORD* mpOutGlyphs; // glyphids in visual order
GOFFSET* mpGlyphOffsets; // glyph offsets to the "naive" layout
SCRIPT_VISATTR* mpVisualAttrs; // glyph visual attributes
mutable int* mpGlyphs2Chars; // map from absolute_glyph_pos to absolute_char_pos
// kashida stuff
void InitKashidaHandling();
void KashidaItemFix( int nMinGlyphPos, int nEndGlyphPos );
bool KashidaWordFix( int nMinGlyphPos, int nEndGlyphPos, int* pnCurrentPos );
int mnMinKashidaWidth;
int mnMinKashidaGlyph;
bool mbDisableGlyphInjection;
};
class TextOutRenderer
{
protected:
......
......@@ -613,16 +613,12 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
int nHeight, BYTE eWinCharSet, BYTE nPitchAndFamily )
: PhysicalFontFace( rDFS ),
mnId( 0 ),
mbHasCJKSupport( false ),
mbHasArabicSupport ( false ),
mbFontCapabilitiesRead( false ),
mxUnicodeMap( nullptr ),
mpEncodingVector( nullptr ),
meWinCharSet( eWinCharSet ),
mnPitchAndFamily( nPitchAndFamily ),
mbAliasSymbolsHigh( false ),
mbAliasSymbolsLow( false ),
mbGsubRead( false ),
mpHbFont( nullptr )
{
SetBitmapSize( 0, nHeight );
......@@ -657,8 +653,6 @@ WinFontFace::~WinFontFace()
if( mxUnicodeMap.Is() )
mxUnicodeMap = nullptr;
delete mpEncodingVector;
if( mpHbFont )
hb_font_destroy( mpHbFont );
}
......@@ -681,18 +675,6 @@ void WinFontFace::UpdateFromHDC( HDC hDC ) const
GetFontCapabilities( hDC );
}
bool WinFontFace::HasGSUBstitutions( HDC hDC ) const
{
if( !mbGsubRead )
ReadGsubTable( hDC );
return !maGsubTable.empty();
}
bool WinFontFace::IsGSUBstituted( sal_UCS4 cChar ) const
{
return( maGsubTable.find( cChar ) != maGsubTable.end() );
}
FontCharMapRef WinFontFace::GetFontCharMap() const
{
return mxUnicodeMap;
......@@ -704,51 +686,6 @@ bool WinFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities)
return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange;
}
void WinFontFace::ReadGsubTable( HDC hDC ) const
{
mbGsubRead = true;
// check the existence of a GSUB table
const DWORD GsubTag = CalcTag( "GSUB" );
DWORD nRC = ::GetFontData( hDC, GsubTag, 0, nullptr, 0 );
if( (nRC == GDI_ERROR) || !nRC )
return;
// parse the GSUB table through sft
// TODO: parse it directly
// sft needs the full font file data => get it
const RawFontData aRawFontData( hDC );
if( !aRawFontData.get() )
return;
// open font file
sal_uInt32 nFaceNum = 0;
if( !*aRawFontData.get() ) // TTC candidate
nFaceNum = ~0U; // indicate "TTC font extracts only"
TrueTypeFont* pTTFont = nullptr;
::OpenTTFontBuffer( aRawFontData.get(), aRawFontData.size(), nFaceNum, &pTTFont );
if( !pTTFont )
return;
// add vertically substituted characters to list
static const sal_Unicode aGSUBCandidates[] = {
0x0020, 0x0080, // ASCII
0x2000, 0x2600, // misc
0x3000, 0x3100, // CJK punctutation
0x3300, 0x3400, // squared words
0xFF00, 0xFFF0, // halfwidth|fullwidth forms
0 };
for( const sal_Unicode* pPair = aGSUBCandidates; *pPair; pPair += 2 )
for( sal_Unicode cChar = pPair[0]; cChar < pPair[1]; ++cChar )
if( ::MapChar( pTTFont, cChar, false ) != ::MapChar( pTTFont, cChar, true ) )
maGsubTable.insert( cChar ); // insert GSUBbed unicodes
CloseTTFont( pTTFont );
}
void WinFontFace::ReadCmapTable( HDC hDC ) const
{
if( mxUnicodeMap.Is() )
......@@ -784,37 +721,15 @@ void WinFontFace::GetFontCapabilities( HDC hDC ) const
mbFontCapabilitiesRead = true;
// GSUB table
DWORD nLength;
const DWORD GsubTag = CalcTag( "GSUB" );
nLength = ::GetFontData( hDC, GsubTag, 0, nullptr, 0 );
if( (nLength != GDI_ERROR) && nLength )
{
std::vector<unsigned char> aTable( nLength );
unsigned char* pTable = &aTable[0];
::GetFontData( hDC, GsubTag, 0, pTable, nLength );
vcl::getTTScripts(maFontCapabilities.maGSUBScriptTags, pTable, nLength);
}
// OS/2 table
const DWORD OS2Tag = CalcTag( "OS/2" );
nLength = ::GetFontData( hDC, OS2Tag, 0, nullptr, 0 );
DWORD nLength = ::GetFontData( hDC, OS2Tag, 0, nullptr, 0 );
if( (nLength != GDI_ERROR) && nLength )
{
std::vector<unsigned char> aTable( nLength );
unsigned char* pTable = &aTable[0];
::GetFontData( hDC, OS2Tag, 0, pTable, nLength );
if (vcl::getTTCoverage(maFontCapabilities.oUnicodeRange, maFontCapabilities.oCodePageRange, pTable, nLength))
{
// Check for CJK capabilities of the current font
// TODO, we have this info already from getTT, decode bits to
// a readable bitset
sal_uInt32 ulUnicodeRange1 = GetUInt( pTable + 42 );
sal_uInt32 ulUnicodeRange2 = GetUInt( pTable + 46 );
mbHasCJKSupport = (ulUnicodeRange2 & 0x2DF00000);
mbHasArabicSupport = (ulUnicodeRange1 & 0x00002000);
}
vcl::getTTCoverage(maFontCapabilities.oUnicodeRange, maFontCapabilities.oCodePageRange, pTable, nLength);
}
}
......@@ -1051,17 +966,6 @@ void WinSalGraphics::SetFont( FontSelectPattern* pFont, int nFallbackLevel )
// now the font is live => update font face
if( mpWinFontData[ nFallbackLevel ] )
mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() );
if( !nFallbackLevel )
{
mbFontKernInit = TRUE;
if ( mpFontKernPairs )
{
delete[] mpFontKernPairs;
mpFontKernPairs = nullptr;
}
mnFontKernPairCount = 0;
}
}
void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel )
......@@ -1106,35 +1010,6 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa
rxFontMetric->SetMinKashida( GetMinKashidaWidth() );
}
sal_uLong WinSalGraphics::GetKernPairs()
{
if ( mbFontKernInit )
{
if( mpFontKernPairs )
{
delete[] mpFontKernPairs;
mpFontKernPairs = nullptr;
}
mnFontKernPairCount = 0;
KERNINGPAIR* pPairs = nullptr;
int nCount = ::GetKerningPairsW( getHDC(), 0, nullptr );
if( nCount )
{
pPairs = new KERNINGPAIR[ nCount+1 ];
mpFontKernPairs = pPairs;
mnFontKernPairCount = nCount;
::GetKerningPairsW( getHDC(), nCount, pPairs );
}
mbFontKernInit = FALSE;
std::sort( mpFontKernPairs, mpFontKernPairs + mnFontKernPairCount, ImplCmpKernData );
}
return mnFontKernPairCount;
}
const FontCharMapRef WinSalGraphics::GetFontCharMap() const
{
if( !mpWinFontData[0] )
......
......@@ -615,9 +615,6 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW
mhDefFont(nullptr),
mhDefPal(nullptr),
mpStdClipRgnData(nullptr),
mbFontKernInit(false),
mpFontKernPairs(nullptr),
mnFontKernPairCount(0),
mnPenWidth(GSL_PEN_WIDTH)
{
if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter)
......@@ -647,8 +644,6 @@ WinSalGraphics::~WinSalGraphics()
// delete cache data
delete [] reinterpret_cast<BYTE*>(mpStdClipRgnData);
delete [] mpFontKernPairs;
}
SalGraphicsImpl* WinSalGraphics::GetImpl() const
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment