summaryrefslogtreecommitdiff
path: root/vcl/win/source/gdi/salgdi3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/source/gdi/salgdi3.cxx')
-rw-r--r--vcl/win/source/gdi/salgdi3.cxx127
1 files changed, 84 insertions, 43 deletions
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index 99f276faa964..73f4d8320acc 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
- * $RCSfile: salgdi3.cxx,v $
- * $Revision: 1.95.14.5 $
- *
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -47,6 +44,7 @@
#include "vcl/svapp.hxx"
#include "vcl/outfont.hxx"
#include "vcl/font.hxx"
+#include "vcl/fontsubset.hxx"
#include "vcl/sallayout.hxx"
#include "rtl/logfile.hxx"
@@ -74,6 +72,11 @@
#include <algorithm>
#endif
+#ifdef ENABLE_GRAPHITE
+#include <graphite/GrClient.h>
+#include <graphite/WinFont.h>
+#endif
+
#include <vector>
#include <set>
#include <map>
@@ -551,13 +554,10 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXA& rE
aDFA.mbEmbeddable = false;
aDFA.mbSubsettable = false;
- if( (rMetric.tmPitchAndFamily & TMPF_TRUETYPE) != 0 )
- if( (rMetric.tmPitchAndFamily & TMPF_DEVICE) == 0 )
- // TODO: implement type1 or CFF subsetting
- if( 0 == (rMetric.ntmFlags & (NTM_PS_OPENTYPE | NTM_TYPE1) ) )
- aDFA.mbSubsettable = true;
- // for now we can only embed Type1 fonts
- if( 0 != (rMetric.ntmFlags & NTM_TYPE1 ) )
+ if( 0 != (rMetric.ntmFlags & (NTM_TT_OPENTYPE | NTM_PS_OPENTYPE))
+ || 0 != (rMetric.tmPitchAndFamily & TMPF_TRUETYPE))
+ aDFA.mbSubsettable = true;
+ else if( 0 != (rMetric.tmPitchAndFamily & NTM_TYPE1) ) // TODO: implement subsetting for type1 too
aDFA.mbEmbeddable = true;
// heuristics for font quality
@@ -566,7 +566,7 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXA& rE
aDFA.mnQuality = 0;
if( rMetric.tmPitchAndFamily & TMPF_TRUETYPE )
aDFA.mnQuality += 50;
- if( rMetric.ntmFlags & NTM_TT_OPENTYPE )
+ if( 0 != (rMetric.ntmFlags & (NTM_TT_OPENTYPE | NTM_PS_OPENTYPE)) )
aDFA.mnQuality += 10;
if( aDFA.mbSubsettable )
aDFA.mnQuality += 200;
@@ -633,13 +633,10 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXW& rE
aDFA.mbEmbeddable = false;
aDFA.mbSubsettable = false;
- if( (rMetric.tmPitchAndFamily & TMPF_TRUETYPE) != 0 )
- if( (rMetric.tmPitchAndFamily & TMPF_DEVICE) == 0 )
- // TODO: implement type1 or CFF subsetting
- if( 0 == (rMetric.ntmFlags & (NTM_PS_OPENTYPE | NTM_TYPE1) ) )
- aDFA.mbSubsettable = true;
- // for now we can only embed Type1 fonts
- if( rMetric.ntmFlags & NTM_TYPE1 )
+ if( 0 != (rMetric.ntmFlags & (NTM_TT_OPENTYPE | NTM_PS_OPENTYPE))
+ || 0 != (rMetric.tmPitchAndFamily & TMPF_TRUETYPE))
+ aDFA.mbSubsettable = true;
+ else if( 0 != (rMetric.tmPitchAndFamily & NTM_TYPE1) ) // TODO: implement subsetting for type1 too
aDFA.mbEmbeddable = true;
// heuristics for font quality
@@ -648,7 +645,7 @@ static ImplDevFontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXW& rE
aDFA.mnQuality = 0;
if( rMetric.tmPitchAndFamily & TMPF_TRUETYPE )
aDFA.mnQuality += 50;
- if( rMetric.ntmFlags & NTM_TT_OPENTYPE )
+ if( 0 != (rMetric.ntmFlags & (NTM_TT_OPENTYPE | NTM_PS_OPENTYPE)) )
aDFA.mnQuality += 10;
if( aDFA.mbSubsettable )
aDFA.mnQuality += 200;
@@ -807,6 +804,9 @@ ImplWinFontData::ImplWinFontData( const ImplDevFontAttributes& rDFS,
mbDisableGlyphApi( false ),
mbHasKoreanRange( false ),
mbHasCJKSupport( false ),
+#ifdef ENABLE_GRAPHITE
+ mbHasGraphiteSupport( false ),
+#endif
mbHasArabicSupport ( false ),
mbAliasSymbolsLow( false ),
mbAliasSymbolsHigh( false ),
@@ -865,6 +865,13 @@ void ImplWinFontData::UpdateFromHDC( HDC hDC ) const
ReadCmapTable( hDC );
ReadOs2Table( hDC );
+#ifdef ENABLE_GRAPHITE
+ static const char* pDisableGraphiteText = getenv( "SAL_DISABLE_GRAPHITE" );
+ if( !pDisableGraphiteText || (pDisableGraphiteText[0] == '0') )
+ {
+ mbHasGraphiteSupport = gr::WinFont::FontHasGraphiteTables(hDC);
+ }
+#endif
// even if the font works some fonts have problems with the glyph API
// => the heuristic below tries to figure out which fonts have the problem
@@ -993,27 +1000,25 @@ void ImplWinFontData::ReadGsubTable( HDC hDC ) const
void ImplWinFontData::ReadCmapTable( HDC hDC ) const
{
- CmapResult aResult;
- aResult.mnPairCount = 0;
- aResult.mpPairCodes = NULL;
- aResult.mpStartGlyphs = NULL;
- aResult.mbSymbolic = (meWinCharSet == SYMBOL_CHARSET);
- aResult.mbRecoded = true;
+ if( mpUnicodeMap != NULL )
+ return;
+ bool bIsSymbolFont = (meWinCharSet == SYMBOL_CHARSET);
// get the CMAP table from the font which is selected into the DC
const DWORD nCmapTag = CalcTag( "cmap" );
const RawFontData aRawFontData( hDC, nCmapTag );
// parse the CMAP table if available
- if( aRawFontData.get() )
+ if( aRawFontData.get() ) {
+ CmapResult aResult;
ParseCMAP( aRawFontData.get(), aRawFontData.size(), aResult );
+ mbDisableGlyphApi |= aResult.mbRecoded;
+ aResult.mbSymbolic = bIsSymbolFont;
+ if( aResult.mnRangeCount > 0 )
+ mpUnicodeMap = new ImplFontCharMap( aResult );
+ }
- mbDisableGlyphApi |= aResult.mbRecoded;
-
- if( aResult.mnPairCount > 0 )
- mpUnicodeMap = new ImplFontCharMap( aResult.mnPairCount,
- aResult.mpPairCodes, aResult.mpStartGlyphs );
- else
- mpUnicodeMap = ImplFontCharMap::GetDefaultMap();
+ if( !mpUnicodeMap )
+ mpUnicodeMap = ImplFontCharMap::GetDefaultMap( bIsSymbolFont );
}
// =======================================================================
@@ -2547,6 +2552,8 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
const ImplFontData* pFont, long* pGlyphIDs, sal_uInt8* pEncoding,
sal_Int32* pGlyphWidths, int nGlyphCount, FontSubsetInfo& rInfo )
{
+ // TODO: use more of the central font-subsetting code, move stuff there if needed
+
// create matching ImplFontSelectData
// we need just enough to get to the font file data
// use height=1000 for easier debugging (to match psprint's font units)
@@ -2554,10 +2561,14 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
// TODO: much better solution: move SetFont and restoration of old font to caller
ScopedFont aOldFont(*this);
- float fScale = 0.0;
+ float fScale = 1.0;
HFONT hOldFont = 0;
ImplDoSetFont( &aIFSD, fScale, hOldFont );
+ ImplWinFontData* pWinFontData = (ImplWinFontData*)aIFSD.mpFontData;
+ pWinFontData->UpdateFromHDC( mhDC );
+/*const*/ ImplFontCharMap* pImplFontCharMap = pWinFontData->GetImplFontCharMap();
+
#if OSL_DEBUG_LEVEL > 1
// get font metrics
TEXTMETRICA aWinMetric;
@@ -2568,8 +2579,42 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
DBG_ASSERT( aWinMetric.tmPitchAndFamily & TMPF_TRUETYPE, "can only subset TT font" );
#endif
+ rtl::OUString aSysPath;
+ if( osl_File_E_None != osl_getSystemPathFromFileURL( rToFile.pData, &aSysPath.pData ) )
+ return FALSE;
+ const rtl_TextEncoding aThreadEncoding = osl_getThreadTextEncoding();
+ const ByteString aToFile( aSysPath.getStr(), (xub_StrLen)aSysPath.getLength(), aThreadEncoding );
+
+ // check if the font has a CFF-table
+ const DWORD nCffTag = CalcTag( "CFF " );
+ const RawFontData aRawCffData( mhDC, nCffTag );
+ if( aRawCffData.get() )
+ {
+ long nRealGlyphIds[ 256 ];
+ for( int i = 0; i < nGlyphCount; ++i )
+ {
+ // TODO: remap notdef glyph if needed
+ // TODO: use GDI's GetGlyphIndices instead? Does it handle GSUB properly?
+ sal_uInt32 nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK;
+ if( pGlyphIDs[i] & GF_ISCHAR ) // remaining pseudo-glyphs need to be translated
+ nGlyphIdx = pImplFontCharMap->GetGlyphIndex( nGlyphIdx );
+ if( (pGlyphIDs[i] & (GF_ROTMASK|GF_GSUB)) != 0) // TODO: vertical substitution
+ {/*####*/}
+
+ nRealGlyphIds[i] = nGlyphIdx;
+ }
+
+ // provide a font subset from the CFF-table
+ FILE* pOutFile = fopen( aToFile.GetBuffer(), "wb" );
+ rInfo.LoadFont( FontSubsetInfo::CFF_FONT, aRawCffData.get(), aRawCffData.size() );
+ bool bRC = rInfo.CreateFontSubset( FontSubsetInfo::TYPE1_PFB, pOutFile, NULL,
+ nRealGlyphIds, pEncoding, nGlyphCount, pGlyphWidths );
+ fclose( pOutFile );
+ return bRC;
+ }
+
// get raw font file data
- const RawFontData xRawFontData( mhDC );
+ const RawFontData xRawFontData( mhDC, NULL );
if( !xRawFontData.get() )
return FALSE;
@@ -2585,7 +2630,7 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
TTGlobalFontInfo aTTInfo;
::GetTTGlobalFontInfo( aSftTTF.get(), &aTTInfo );
- rInfo.m_nFontType = SAL_FONTSUBSETINFO_TYPE_TRUETYPE;
+ rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
rInfo.m_aPSName = ImplSalGetUniString( aTTInfo.psname );
rInfo.m_nAscent = +aTTInfo.winAscent;
rInfo.m_nDescent = -aTTInfo.winDescent;
@@ -2593,7 +2638,7 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
Point( aTTInfo.xMax, aTTInfo.yMax ) );
rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
- // subset glyphs and get their properties
+ // subset TTF-glyphs and get their properties
// take care that subset fonts require the NotDef glyph in pos 0
int nOrigCount = nGlyphCount;
USHORT aShortIDs[ 256 ];
@@ -2649,11 +2694,6 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
free( pMetrics );
// write subset into destination file
- rtl::OUString aSysPath;
- if( osl_File_E_None != osl_getSystemPathFromFileURL( rToFile.pData, &aSysPath.pData ) )
- return FALSE;
- rtl_TextEncoding aThreadEncoding = osl_getThreadTextEncoding();
- ByteString aToFile( rtl::OUStringToOString( aSysPath, aThreadEncoding ) );
nRC = ::CreateTTFromTTGlyphs( aSftTTF.get(), aToFile.GetBuffer(), aShortIDs,
aTempEncs, nGlyphCount, 0, NULL, 0 );
return (nRC == SF_OK);
@@ -2683,7 +2723,7 @@ const void* WinSalGraphics::GetEmbedFontData( const ImplFontData* pFont,
TEXTMETRICA aTm;
if( !::GetTextMetricsA( mhDC, &aTm ) )
*pDataLen = 0;
- rInfo.m_nFontType = SAL_FONTSUBSETINFO_TYPE_TYPE1;
+ rInfo.m_nFontType = FontSubsetInfo::ANY_TYPE1;
WCHAR aFaceName[64];
int nFNLen = ::GetTextFaceW( mhDC, 64, aFaceName );
// #i59854# strip eventual null byte
@@ -2876,3 +2916,4 @@ SystemFontData WinSalGraphics::GetSysFontData( int nFallbacklevel ) const
}
//--------------------------------------------------------------------------
+