summaryrefslogtreecommitdiffstats
path: root/vcl/os2/source/gdi/salgdi3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/os2/source/gdi/salgdi3.cxx')
-rw-r--r--vcl/os2/source/gdi/salgdi3.cxx1701
1 files changed, 0 insertions, 1701 deletions
diff --git a/vcl/os2/source/gdi/salgdi3.cxx b/vcl/os2/source/gdi/salgdi3.cxx
deleted file mode 100644
index 63fd79b8fa2e..000000000000
--- a/vcl/os2/source/gdi/salgdi3.cxx
+++ /dev/null
@@ -1,1701 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#define INCL_GRE_STRINGS
-#define INCL_GPI
-#define INCL_DOS
-
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <svpm.h>
-
-#define _SV_SALGDI3_CXX
-#include <rtl/tencinfo.h>
-#include <osl/file.hxx>
-#include <osl/thread.hxx>
-#include <osl/process.h>
-#include <vcl/svapp.hxx>
-#include <saldata.hxx>
-#include <salgdi.h>
-#include <vcl/font.hxx>
-#include <vcl/sallayout.hxx>
-#include <tools/poly.hxx>
-#include <tools/debug.hxx>
-#include <rtl/textcvt.h>
-#include <tools/debug.hxx>
-#include <saldata.hxx>
-#include <salgdi.h>
-#include <vcl/outfont.hxx>
-#include <sallayout.h>
-#include <tools/poly.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-
-#ifndef __H_FT2LIB
-#include <wingdi.h>
-#include <ft2lib.h>
-#endif
-
-#include "sft.hxx"
-
-#ifdef GCP_KERN_HACK
-#include <algorithm>
-#endif
-
-using namespace vcl;
-
-// -----------
-// - Inlines -
-// -----------
-
-
-inline W32FIXED FixedFromDouble( double d )
-{
- const long l = (long) ( d * 65536. );
- return *(W32FIXED*) &l;
-}
-
-// -----------------------------------------------------------------------
-
-inline int IntTimes256FromFixed(W32FIXED f)
-{
- int nFixedTimes256 = (f.value << 8) + ((f.fract+0x80) >> 8);
- return nFixedTimes256;
-}
-
-// -----------
-// - Defines -
-// -----------
-
-// this is a special codepage code, used to identify OS/2 symbol font.
-#define SYMBOL_CHARSET 65400
-
-// =======================================================================
-
-UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen = STRING_LEN)
-{
- return UniString( pStr, nLen, gsl_getSystemTextEncoding(),
- RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
- RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
- RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
-}
-
-// =======================================================================
-
-static USHORT ImplSalToCharSet( CharSet eCharSet )
-{
- // !!! Fuer DBCS-Systeme muss dieser Code auskommentiert werden und 0
- // !!! zurueckgegeben werden, solange die DBCS-Charsets nicht
- // !!! durchgereicht werden
-
- switch ( eCharSet )
- {
- case RTL_TEXTENCODING_IBM_437:
- return 437;
-
- case RTL_TEXTENCODING_IBM_850:
- return 850;
-
- case RTL_TEXTENCODING_IBM_860:
- return 860;
-
- case RTL_TEXTENCODING_IBM_861:
- return 861;
-
- case RTL_TEXTENCODING_IBM_863:
- return 863;
-
- case RTL_TEXTENCODING_IBM_865:
- return 865;
- case RTL_TEXTENCODING_MS_1252:
- return 1004;
- case RTL_TEXTENCODING_SYMBOL:
- return 65400;
- }
-
- return 0;
-}
-
-// -----------------------------------------------------------------------
-
-static CharSet ImplCharSetToSal( USHORT usCodePage )
-{
- switch ( usCodePage )
- {
- case 437:
- return RTL_TEXTENCODING_IBM_437;
-
- case 850:
- return RTL_TEXTENCODING_IBM_850;
-
- case 860:
- return RTL_TEXTENCODING_IBM_860;
-
- case 861:
- return RTL_TEXTENCODING_IBM_861;
-
- case 863:
- return RTL_TEXTENCODING_IBM_863;
-
- case 865:
- return RTL_TEXTENCODING_IBM_865;
- case 1004:
- return RTL_TEXTENCODING_MS_1252;
- case 65400:
- return RTL_TEXTENCODING_SYMBOL;
- }
-
- return RTL_TEXTENCODING_DONTKNOW;
-}
-
-// -----------------------------------------------------------------------
-
-static FontFamily ImplFamilyToSal( BYTE bFamilyType )
-{
- switch ( bFamilyType )
- {
- case 4:
- return FAMILY_DECORATIVE;
- case 3:
- return FAMILY_SCRIPT;
- }
-
- return FAMILY_DONTKNOW;
-}
-
-// -----------------------------------------------------------------------
-
-static FontWeight ImplWeightToSal( USHORT nWeight )
-{
- // Falls sich jemand an die alte Doku gehalten hat
- if ( nWeight > 999 )
- nWeight /= 1000;
-
- switch ( nWeight )
- {
- case 1:
- return WEIGHT_THIN;
-
- case 2:
- return WEIGHT_ULTRALIGHT;
-
- case 3:
- return WEIGHT_LIGHT;
-
- case 4:
- return WEIGHT_SEMILIGHT;
-
- case 5:
- return WEIGHT_NORMAL;
-
- case 6:
- return WEIGHT_SEMIBOLD;
-
- case 7:
- return WEIGHT_BOLD;
-
- case 8:
- return WEIGHT_ULTRABOLD;
-
- case 9:
- return WEIGHT_BLACK;
- }
-
- return WEIGHT_DONTKNOW;
-}
-
-// -----------------------------------------------------------------------
-
-static UniString ImpStyleNameToSal( const char* pFamilyName,
- const char* pFaceName,
- USHORT nLen )
-{
- if ( !nLen )
- nLen = strlen(pFamilyName);
-
- // strip FamilyName from FaceName
- if ( strncmp( pFamilyName, pFaceName, nLen ) == 0 )
- {
- USHORT nFaceLen = (USHORT)strlen( pFaceName+nLen );
- // Ist Facename laenger, schneiden wir den FamilyName ab
- if ( nFaceLen > 1 )
- return UniString( pFaceName+(nLen+1), gsl_getSystemTextEncoding());
- else
- return UniString();
- }
- else
- return UniString( pFaceName, gsl_getSystemTextEncoding());
-}
-
-// -----------------------------------------------------------------------
-
-inline FontPitch ImplLogPitchToSal( BYTE fsType )
-{
- if ( fsType & FM_TYPE_FIXED )
- return PITCH_FIXED;
- else
- return PITCH_VARIABLE;
-}
-
-// -----------------------------------------------------------------------
-
-inline BYTE ImplPitchToWin( FontPitch ePitch )
-{
- if ( ePitch == PITCH_FIXED )
- return FM_TYPE_FIXED;
- //else if ( ePitch == PITCH_VARIABLE )
-
- return 0;
-}
-
-// -----------------------------------------------------------------------
-
-static ImplDevFontAttributes Os2Font2DevFontAttributes( const PFONTMETRICS pFontMetric)
-{
- ImplDevFontAttributes aDFA;
-
- // get font face attributes
- aDFA.meFamily = ImplFamilyToSal( pFontMetric->panose.bFamilyType);
- aDFA.meWidthType = WIDTH_DONTKNOW;
- aDFA.meWeight = ImplWeightToSal( pFontMetric->usWeightClass);
- aDFA.meItalic = (pFontMetric->fsSelection & FM_SEL_ITALIC) ? ITALIC_NORMAL : ITALIC_NONE;
- aDFA.mePitch = ImplLogPitchToSal( pFontMetric->fsType );
- aDFA.mbSymbolFlag = (pFontMetric->usCodePage == SYMBOL_CHARSET);
-
- // get the font face name
- // the maName field stores the font name without the style, so under OS/2
- // we must use the family name
- aDFA.maName = UniString( pFontMetric->szFamilyname, gsl_getSystemTextEncoding());
-
- aDFA.maStyleName = ImpStyleNameToSal( pFontMetric->szFamilyname,
- pFontMetric->szFacename,
- strlen( pFontMetric->szFamilyname) );
-
- // get device specific font attributes
- aDFA.mbOrientation = (pFontMetric->fsDefn & FM_DEFN_OUTLINE) != 0;
- aDFA.mbDevice = (pFontMetric->fsDefn & FM_DEFN_GENERIC) ? FALSE : TRUE;
-
- aDFA.mbEmbeddable = false;
- aDFA.mbSubsettable = false;
- DWORD fontType = Ft2QueryFontType( 0, pFontMetric->szFamilyname);
- if( fontType == FT2_FONTTYPE_TRUETYPE && !aDFA.mbDevice)
- aDFA.mbSubsettable = true;
- // for now we can only embed Type1 fonts
- if( fontType == FT2_FONTTYPE_TYPE1 )
- aDFA.mbEmbeddable = true;
-
- // heuristics for font quality
- // - standard-type1 > opentypeTT > truetype > non-standard-type1 > raster
- // - subsetting > embedding > none
- aDFA.mnQuality = 0;
- if( fontType == FT2_FONTTYPE_TRUETYPE )
- aDFA.mnQuality += 50;
- if( aDFA.mbSubsettable )
- aDFA.mnQuality += 200;
- else if( aDFA.mbEmbeddable )
- aDFA.mnQuality += 100;
-
- // #i38665# prefer Type1 versions of the standard postscript fonts
- if( aDFA.mbEmbeddable )
- {
- if( aDFA.maName.EqualsAscii( "AvantGarde" )
- || aDFA.maName.EqualsAscii( "Bookman" )
- || aDFA.maName.EqualsAscii( "Courier" )
- || aDFA.maName.EqualsAscii( "Helvetica" )
- || aDFA.maName.EqualsAscii( "NewCenturySchlbk" )
- || aDFA.maName.EqualsAscii( "Palatino" )
- || aDFA.maName.EqualsAscii( "Symbol" )
- || aDFA.maName.EqualsAscii( "Times" )
- || aDFA.maName.EqualsAscii( "ZapfChancery" )
- || aDFA.maName.EqualsAscii( "ZapfDingbats" ) )
- aDFA.mnQuality += 500;
- }
-
- aDFA.meEmbeddedBitmap = EMBEDDEDBITMAP_DONTKNOW;
- aDFA.meAntiAlias = ANTIALIAS_DONTKNOW;
-
- // TODO: add alias names
-
- return aDFA;
-}
-
-// =======================================================================
-
-// -----------------------------------------------------------------------
-
-// =======================================================================
-
-ImplOs2FontData::ImplOs2FontData( PFONTMETRICS _pFontMetric,
- int nHeight, BYTE nPitchAndFamily )
-: ImplFontData( Os2Font2DevFontAttributes(_pFontMetric), 0 ),
- pFontMetric( _pFontMetric ),
- meOs2CharSet( _pFontMetric->usCodePage),
- mnPitchAndFamily( nPitchAndFamily ),
- mpFontCharSets( NULL ),
- mpUnicodeMap( NULL ),
- mbDisableGlyphApi( false ),
- mbHasKoreanRange( false ),
- mbHasCJKSupport( false ),
- mbAliasSymbolsLow( false ),
- mbAliasSymbolsHigh( false ),
- mnId( 0 )
-{
- SetBitmapSize( 0, nHeight );
-}
-
-// -----------------------------------------------------------------------
-
-ImplOs2FontData::~ImplOs2FontData()
-{
- delete[] mpFontCharSets;
-
- if( mpUnicodeMap )
- mpUnicodeMap->DeReference();
-}
-
-// -----------------------------------------------------------------------
-
-sal_IntPtr ImplOs2FontData::GetFontId() const
-{
- return mnId;
-}
-
-// -----------------------------------------------------------------------
-
-void ImplOs2FontData::UpdateFromHPS( HPS hPS ) const
-{
- // short circuit if already initialized
- if( mpUnicodeMap != NULL )
- return;
-
- ReadCmapTable( hPS );
- ReadOs2Table( hPS );
-
- // 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
- DWORD fontType = Ft2QueryFontType( 0, pFontMetric->szFacename);
- if( fontType != FT2_FONTTYPE_TRUETYPE
- && (pFontMetric->fsDefn & FM_DEFN_GENERIC) == 0)
- mbDisableGlyphApi = true;
-}
-
-// -----------------------------------------------------------------------
-
-#ifdef GNG_VERT_HACK
-bool ImplOs2FontData::HasGSUBstitutions( HPS hPS ) const
-{
- if( !mbGsubRead )
- ReadGsubTable( hPS );
- return !maGsubTable.empty();
-}
-
-// -----------------------------------------------------------------------
-
-bool ImplOs2FontData::IsGSUBstituted( sal_Ucs cChar ) const
-{
- return( maGsubTable.find( cChar ) != maGsubTable.end() );
-}
-#endif // GNG_VERT_HACK
-
-// -----------------------------------------------------------------------
-
-const ImplFontCharMap* ImplOs2FontData::GetImplFontCharMap() const
-{
- return mpUnicodeMap;
-}
-
-// -----------------------------------------------------------------------
-
-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 inline DWORD CalcTag( const char p[4]) { return (p[0]+(p[1]<<8)+(p[2]<<16)+(p[3]<<24)); }
-
-void ImplOs2FontData::ReadOs2Table( HPS hPS ) const
-{
- const DWORD Os2Tag = CalcTag( "OS/2" );
- DWORD nLength = Ft2GetFontData( hPS, Os2Tag, 0, NULL, 0 );
- if( (nLength == FT2_ERROR) || !nLength )
- return;
- std::vector<unsigned char> aOS2map( nLength );
- unsigned char* pOS2map = &aOS2map[0];
- DWORD nRC = Ft2GetFontData( hPS, Os2Tag, 0, pOS2map, nLength );
- sal_uInt32 nVersion = GetUShort( pOS2map );
- if ( nVersion >= 0x0001 && nLength >= 58 )
- {
- // We need at least version 0x0001 (TrueType rev 1.66)
- // to have access to the needed struct members.
- sal_uInt32 ulUnicodeRange1 = GetUInt( pOS2map + 42 );
- sal_uInt32 ulUnicodeRange2 = GetUInt( pOS2map + 46 );
- sal_uInt32 ulUnicodeRange3 = GetUInt( pOS2map + 50 );
- sal_uInt32 ulUnicodeRange4 = GetUInt( pOS2map + 54 );
-
- // Check for CJK capabilities of the current font
- mbHasCJKSupport = (ulUnicodeRange2 & 0x2fff0000)
- | (ulUnicodeRange3 & 0x00000001);
- mbHasKoreanRange= (ulUnicodeRange1 & 0x10000000)
- | (ulUnicodeRange2 & 0x01100000);
- }
-}
-
-
-// -----------------------------------------------------------------------
-
-#ifdef GNG_VERT_HACK
-void ImplOs2FontData::ReadGsubTable( HPS hPS ) const
-{
- mbGsubRead = true;
-
- // check the existence of a GSUB table
- const DWORD GsubTag = CalcTag( "GSUB" );
- DWORD nRC = Ft2GetFontData( hPS, GsubTag, 0, NULL, 0 );
- if( (nRC == FT2_ERROR) || !nRC )
- return;
-
- // TODO: directly read the GSUB table instead of going through sft
-
- // get raw font file data
- DWORD nFontSize = Ft2GetFontData( hPS, 0, 0, NULL, 0 );
- if( nFontSize == FT2_ERROR )
- return;
- std::vector<char> aRawFont( nFontSize+1 );
- aRawFont[ nFontSize ] = 0;
- DWORD nFontSize2 = Ft2GetFontData( hPS, 0, 0, (void*)&aRawFont[0], nFontSize );
- if( nFontSize != nFontSize2 )
- return;
-
- // open font file
- sal_uInt32 nFaceNum = 0;
- if( !aRawFont[0] ) // TTC candidate
- nFaceNum = ~0U; // indicate "TTC font extracts only"
-
- TrueTypeFont* pTTFont = NULL;
- ::OpenTTFontBuffer( &aRawFont[0], nFontSize, 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, 0 ) != ::MapChar( pTTFont, cChar, 1 ) )
- maGsubTable.insert( cChar ); // insert GSUBbed unicodes
-
- CloseTTFont( pTTFont );
-}
-#endif // GNG_VERT_HACK
-
-// -----------------------------------------------------------------------
-
-void ImplOs2FontData::ReadCmapTable( HPS hPS ) const
-{
- CmapResult aResult;
- aResult.mnPairCount = 0;
- aResult.mbSymbolic = (meOs2CharSet == SYMBOL_CHARSET);
- aResult.mbRecoded = true;
-
- // get the CMAP table from the font which is selected into the DC
- const DWORD CmapTag = CalcTag( "cmap" );
- DWORD nRC = Ft2GetFontData( hPS, CmapTag, 0, NULL, 0 );
- // read the CMAP table if available
- if( nRC != FT2_ERROR )
- {
- const int nLength = nRC;
- std::vector<unsigned char> aCmap( nLength );
- unsigned char* pCmap = &aCmap[0];
- nRC = Ft2GetFontData( hPS, CmapTag, 0, pCmap, nLength );
- // parse the CMAP table
- if( nRC == nLength )
- ParseCMAP( pCmap, nLength, aResult );
- } else {
- // we need to define at least a simple charmap, otherwise this font
- // will be mapped to default charmap, and OOo doesn't accept the
- // system font to match the default charmap
- aResult.mnPairCount = 1;
- // ImplFontCharMap destructor will free this memory
- aResult.mpPairCodes = new sal_uInt32[ 2 * aResult.mnPairCount ];
- aResult.mpPairCodes[0] = 0x0020;
- aResult.mpPairCodes[1] = 0x00FF;
- aResult.mpStartGlyphs = NULL;
- }
-
- mbDisableGlyphApi |= aResult.mbRecoded;
-
- if( aResult.mnPairCount > 0 )
- mpUnicodeMap = new ImplFontCharMap( aResult.mnPairCount,
- aResult.mpPairCodes, aResult.mpStartGlyphs );
- else
- mpUnicodeMap = ImplFontCharMap::GetDefaultMap();
- mpUnicodeMap->AddReference();
-}
-
-// =======================================================================
-
-void Os2SalGraphics::SetTextColor( SalColor nSalColor )
-{
- CHARBUNDLE cb;
-
- cb.lColor = RGBCOLOR( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
-
- // set default color attributes
- Ft2SetAttrs( mhPS,
- PRIM_CHAR,
- CBB_COLOR,
- 0,
- &cb );
-}
-
-// -----------------------------------------------------------------------
-
-USHORT Os2SalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFontScale, int nFallbackLevel)
-{
-
-#if OSL_DEBUG_LEVEL > 1
- debug_printf( "Os2SalGraphics::ImplDoSetFont\n");
-#endif
-
- ImplOs2FontData* pFontData = (ImplOs2FontData*)i_pFont->mpFontData;
- PFONTMETRICS pFontMetric = NULL;
- FATTRS aFAttrs;
- BOOL bOutline = FALSE;
- APIRET rc;
-
- memset( &aFAttrs, 0, sizeof( FATTRS ) );
- aFAttrs.usRecordLength = sizeof( FATTRS );
-
- aFAttrs.lMaxBaselineExt = i_pFont->mnHeight;
- aFAttrs.lAveCharWidth = i_pFont->mnWidth;
-
- // do we have a pointer to the FONTMETRICS of the selected font? -> use it!
- if ( pFontData )
- {
- pFontMetric = pFontData->GetFontMetrics();
-
- bOutline = (pFontMetric->fsDefn & FM_DEFN_OUTLINE) != 0;
-
- // use match&registry fields to get correct match
- aFAttrs.lMatch = pFontMetric->lMatch;
- aFAttrs.idRegistry = pFontMetric->idRegistry;
- aFAttrs.usCodePage = pFontMetric->usCodePage;
-
- if ( bOutline )
- {
- aFAttrs.fsFontUse |= FATTR_FONTUSE_OUTLINE;
- if ( i_pFont->mnOrientation )
- aFAttrs.fsFontUse |= FATTR_FONTUSE_TRANSFORMABLE;
- }
- else
- {
- aFAttrs.lMaxBaselineExt = pFontMetric->lMaxBaselineExt;
- aFAttrs.lAveCharWidth = pFontMetric->lAveCharWidth;
- }
-
- }
-
- // use family name for outline fonts
- if ( mbPrinter ) {
- // use font face name for printers because otherwise ft2lib will fail
- // to select the correct font for GPI (ticket#117)
- strncpy( (char*)(aFAttrs.szFacename), pFontMetric->szFacename, sizeof( aFAttrs.szFacename ) );
- } else if ( !pFontMetric) {
- // use OOo name if fontmetrics not available!
- ByteString aName( i_pFont->maName.GetToken( 0 ), gsl_getSystemTextEncoding());
- strncpy( (char*)(aFAttrs.szFacename), aName.GetBuffer(), sizeof( aFAttrs.szFacename ) );
- } else if ( bOutline) {
- // use fontmetric family name for outline fonts
- strncpy( (char*)(aFAttrs.szFacename), pFontMetric->szFamilyname, sizeof( aFAttrs.szFacename ) );
- } else {
- // use real font face name for bitmaps (WarpSans only)
- strncpy( (char*)(aFAttrs.szFacename), pFontMetric->szFacename, sizeof( aFAttrs.szFacename ) );
- }
-
- if ( i_pFont->meItalic != ITALIC_NONE )
- aFAttrs.fsSelection |= FATTR_SEL_ITALIC;
- if ( i_pFont->meWeight > WEIGHT_MEDIUM )
- aFAttrs.fsSelection |= FATTR_SEL_BOLD;
-
-#if OSL_DEBUG_LEVEL > 1
- if (pFontMetric->szFacename[0] == 'A') {
- debug_printf( "Os2SalGraphics::SetFont hps %x lMatch '%d'\n", mhPS, pFontMetric->lMatch);
- debug_printf( "Os2SalGraphics::SetFont hps %x fontmetrics facename '%s'\n", mhPS, pFontMetric->szFacename);
- debug_printf( "Os2SalGraphics::SetFont hps %x fattrs facename '%s'\n", mhPS, aFAttrs.szFacename);
- }
-#endif
-
- Ft2DeleteSetId( mhPS, nFallbackLevel + LCID_BASE);
- if ( (rc=Ft2CreateLogFont( mhPS, NULL, nFallbackLevel + LCID_BASE, &aFAttrs)) == GPI_ERROR ) {
-#if OSL_DEBUG_LEVEL > 1
- ERRORID nLastError = WinGetLastError( GetSalData()->mhAB );
- debug_printf( "Os2SalGraphics::SetFont hps %x Ft2CreateLogFont failed err %x\n", mhPS, nLastError );
-#endif
- return SAL_SETFONT_REMOVEANDMATCHNEW;
- }
-
- CHARBUNDLE aBundle;
-
- ULONG nAttrsDefault = 0;
- ULONG nAttrs = CBB_SET;
- aBundle.usSet = nFallbackLevel + LCID_BASE;
-
- if ( bOutline )
- {
- nAttrs |= CBB_BOX;
- aBundle.sizfxCell.cy = MAKEFIXED( i_pFont->mnHeight, 0 );
-
- if ( !i_pFont->mnWidth )
- {
- LONG nXFontRes;
- LONG nYFontRes;
- LONG nHeight;
-
- // Auf die Aufloesung achten, damit das Ergebnis auch auf
- // Drucken mit 180*360 DPI stimmt. Ausserdem muss gerundet
- // werden, da auf meinem OS2 beispielsweise als
- // Bildschirmaufloesung 3618*3622 PixelPerMeter zurueck-
- // gegeben wird
- GetResolution( nXFontRes, nYFontRes );
- nHeight = i_pFont->mnHeight;
- nHeight *= nXFontRes;
- nHeight += nYFontRes/2;
- nHeight /= nYFontRes;
- aBundle.sizfxCell.cx = MAKEFIXED( nHeight, 0 );
- }
- else
- aBundle.sizfxCell.cx = MAKEFIXED( i_pFont->mnWidth, 0 );
- }
-
- // set orientation for outlinefonts
- if ( i_pFont->mnOrientation )
- {
- if ( bOutline )
- {
- nAttrs |= CBB_ANGLE;
- double alpha = (double)(i_pFont->mnOrientation);
- alpha *= 0.0017453292; // *PI / 1800
- mnOrientationY = (long) (1000.0 * sin( alpha ));
- mnOrientationX = (long) (1000.0 * cos( alpha ));
- aBundle.ptlAngle.x = mnOrientationX;
- aBundle.ptlAngle.y = mnOrientationY;
- }
- else
- {
- mnOrientationX = 1;
- mnOrientationY = 0;
- nAttrs |= CBB_ANGLE;
- aBundle.ptlAngle.x = 1;
- aBundle.ptlAngle.y = 0;
- }
- }
- else
- {
- mnOrientationX = 1;
- mnOrientationY = 0;
- nAttrs |= CBB_ANGLE;
- aBundle.ptlAngle.x = 1;
- aBundle.ptlAngle.y = 0;
- }
-
- rc = Ft2SetAttrs( mhPS, PRIM_CHAR, nAttrs, nAttrsDefault, &aBundle );
-
-#if OSL_DEBUG_LEVEL > 1
- FONTMETRICS aOS2Metric = {0};
- Ft2QueryFontMetrics( mhPS, sizeof( aOS2Metric ), &aOS2Metric );
-#endif
-
- return 0;
-}
-
-
-USHORT Os2SalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel )
-{
-
- // return early if there is no new font
- if( !pFont )
- {
- mhDefFont = 0;
- return 0;
- }
-
-#if OSL_DEBUG_LEVEL > 1
- debug_printf( "Os2SalGraphics::SetFont\n");
-#endif
-
- DBG_ASSERT( pFont->mpFontData, "WinSalGraphics mpFontData==NULL");
- mpOs2FontEntry[ nFallbackLevel ] = reinterpret_cast<ImplOs2FontEntry*>( pFont->mpFontEntry );
- mpOs2FontData[ nFallbackLevel ] = static_cast<const ImplOs2FontData*>( pFont->mpFontData );
-
- ImplDoSetFont( pFont, mfFontScale, nFallbackLevel);
-
- if( !mhDefFont )
- {
- // keep default font
- mhDefFont = nFallbackLevel + LCID_BASE;
- }
- else
- {
- // release no longer referenced font handles
- for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
- {
- if( mhFonts[i] )
- {
- mhFonts[i] = 0;
- }
- }
- }
-
- // store new font in correct layer
- mhFonts[ nFallbackLevel ] = nFallbackLevel + LCID_BASE;
-
- // now the font is live => update font face
- if( mpOs2FontData[ nFallbackLevel ] )
- mpOs2FontData[ nFallbackLevel ]->UpdateFromHPS( mhPS );
-
- if( !nFallbackLevel )
- {
- mbFontKernInit = TRUE;
- if ( mpFontKernPairs )
- {
- delete[] mpFontKernPairs;
- mpFontKernPairs = NULL;
- }
- mnFontKernPairCount = 0;
- }
-
- // some printers have higher internal resolution, so their
- // text output would be different from what we calculated
- // => suggest DrawTextArray to workaround this problem
- if ( mbPrinter )
- return SAL_SETFONT_USEDRAWTEXTARRAY;
- else
- return 0;
-}
-
-// -----------------------------------------------------------------------
-
-void Os2SalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel )
-{
- FONTMETRICS aOS2Metric;
- Ft2QueryFontMetrics( mhPS, sizeof( aOS2Metric ), &aOS2Metric );
-
-#if OSL_DEBUG_LEVEL > 1
- debug_printf( "Os2SalGraphics::GetFontMetric hps %x\n", mhPS);
- if (aOS2Metric.szFacename[0] == 'A') {
- debug_printf( "Os2SalGraphics::GetFontMetric hps %x fontmetrics facename '%s'\n", mhPS, aOS2Metric.szFacename);
- debug_printf( "Os2SalGraphics::GetFontMetric hps %x fontmetrics lMatch '%d'\n", mhPS, aOS2Metric.lMatch);
- }
-#endif
-
- pMetric->maName = UniString( aOS2Metric.szFamilyname, gsl_getSystemTextEncoding());
- pMetric->maStyleName = ImpStyleNameToSal( aOS2Metric.szFamilyname,
- aOS2Metric.szFacename,
- strlen( aOS2Metric.szFamilyname ) );
-
- // device independent font attributes
- pMetric->meFamily = ImplFamilyToSal( aOS2Metric.panose.bFamilyType);
- pMetric->mbSymbolFlag = (aOS2Metric.usCodePage == SYMBOL_CHARSET);
- pMetric->meWeight = ImplWeightToSal( aOS2Metric.usWeightClass );
- pMetric->mePitch = ImplLogPitchToSal( aOS2Metric.fsType );
- pMetric->meItalic = (aOS2Metric.fsSelection & FM_SEL_ITALIC) ? ITALIC_NORMAL : ITALIC_NONE;
- pMetric->mnSlant = 0;
-
- // device dependend font attributes
- pMetric->mbDevice = (aOS2Metric.fsDefn & FM_DEFN_GENERIC) ? FALSE : TRUE;
- pMetric->mbScalableFont = (aOS2Metric.fsDefn & FM_DEFN_OUTLINE) ? true : false;
- if( pMetric->mbScalableFont )
- {
- // check if there are kern pairs
- // TODO: does this work with GPOS kerning?
- pMetric->mbKernableFont = (aOS2Metric.sKerningPairs > 0);
- }
- else
- {
- // bitmap fonts cannot be rotated directly
- pMetric->mnOrientation = 0;
- // bitmap fonts have no kerning
- pMetric->mbKernableFont = false;
- }
-
- // transformation dependend font metrics
- if ( aOS2Metric.fsDefn & FM_DEFN_OUTLINE )
- {
- pMetric->mnWidth = aOS2Metric.lEmInc;
- }
- else
- {
- pMetric->mnWidth = aOS2Metric.lAveCharWidth;
- pMetric->mnOrientation = 0;
- }
- pMetric->mnIntLeading = aOS2Metric.lInternalLeading;
- pMetric->mnExtLeading = aOS2Metric.lExternalLeading;
- pMetric->mnAscent = aOS2Metric.lMaxAscender;
- pMetric->mnDescent = aOS2Metric.lMaxDescender;
-
- // #107888# improved metric compatibility for Asian fonts...
- // TODO: assess workaround below for CWS >= extleading
- // TODO: evaluate use of aWinMetric.sTypo* members for CJK
- if( mpOs2FontData[nFallbackLevel] && mpOs2FontData[nFallbackLevel]->SupportsCJK() )
- {
- pMetric->mnIntLeading += pMetric->mnExtLeading;
-
- // #109280# The line height for Asian fonts is too small.
- // Therefore we add half of the external leading to the
- // ascent, the other half is added to the descent.
- const long nHalfTmpExtLeading = pMetric->mnExtLeading / 2;
- const long nOtherHalfTmpExtLeading = pMetric->mnExtLeading - nHalfTmpExtLeading;
-
- // #110641# external leading for Asian fonts.
- // The factor 0.3 has been confirmed with experiments.
- long nCJKExtLeading = static_cast<long>(0.30 * (pMetric->mnAscent + pMetric->mnDescent));
- nCJKExtLeading -= pMetric->mnExtLeading;
- pMetric->mnExtLeading = (nCJKExtLeading > 0) ? nCJKExtLeading : 0;
-
- pMetric->mnAscent += nHalfTmpExtLeading;
- pMetric->mnDescent += nOtherHalfTmpExtLeading;
-
- // #109280# HACK korean only: increase descent for wavelines and impr
- // YD win9x only
- }
-
-}
-
-// -----------------------------------------------------------------------
-
-ULONG Os2SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs )
-{
- DBG_ASSERT( sizeof( KERNINGPAIRS ) == sizeof( ImplKernPairData ),
- "Os2SalGraphics::GetKernPairs(): KERNINGPAIRS != ImplKernPairData" );
-
- if ( mbFontKernInit )
- {
- if( mpFontKernPairs )
- {
- delete[] mpFontKernPairs;
- mpFontKernPairs = NULL;
- }
- mnFontKernPairCount = 0;
-
- {
- KERNINGPAIRS* pPairs = NULL;
- FONTMETRICS aOS2Metric;
- Ft2QueryFontMetrics( mhPS, sizeof( aOS2Metric ), &aOS2Metric );
- int nCount = aOS2Metric.sKerningPairs;
- if( nCount )
- {
-#ifdef GCP_KERN_HACK
- pPairs = new KERNINGPAIRS[ nCount+1 ];
- mpFontKernPairs = pPairs;
- mnFontKernPairCount = nCount;
- Ft2QueryKerningPairs( mhPS, nCount, (KERNINGPAIRS*)pPairs );
-#else // GCP_KERN_HACK
- pPairs = (KERNINGPAIRS*)pKernPairs;
- nCount = (nCount < nPairs) ? nCount : nPairs;
- Ft2QueryKerningPairs( mhPS, nCount, (KERNINGPAIRS*)pPairs );
- return nCount;
-#endif // GCP_KERN_HACK
- }
- }
-
- mbFontKernInit = FALSE;
-
- std::sort( mpFontKernPairs, mpFontKernPairs + mnFontKernPairCount, ImplCmpKernData );
- }
-
- if( !pKernPairs )
- return mnFontKernPairCount;
- else if( mpFontKernPairs )
- {
- if ( nPairs < mnFontKernPairCount )
- nPairs = mnFontKernPairCount;
- memcpy( pKernPairs, mpFontKernPairs,
- nPairs*sizeof( ImplKernPairData ) );
- return nPairs;
- }
-
- return 0;
-}
-
-
-// -----------------------------------------------------------------------
-
-static const ImplFontCharMap* pOs2DefaultImplFontCharMap = NULL;
-static const sal_uInt32 pOs2DefaultRangeCodes[] = {0x0020,0x00FF};
-
-const ImplFontCharMap* Os2SalGraphics::GetImplFontCharMap() const
-{
- if( !mpOs2FontData[0] )
- return ImplFontCharMap::GetDefaultMap();
- return mpOs2FontData[0]->GetImplFontCharMap();
-}
-
-// -----------------------------------------------------------------------
-
-bool Os2SalGraphics::AddTempDevFont( ImplDevFontList* pFontList,
- const String& rFontFileURL, const String& rFontName )
-{
-#if OSL_DEBUG_LEVEL > 1
- debug_printf("Os2SalGraphics::AddTempDevFont\n");
-#endif
- return false;
-}
-
-// -----------------------------------------------------------------------
-
-void Os2SalGraphics::GetDevFontList( ImplDevFontList* pList )
-{
- PFONTMETRICS pFontMetrics;
- ULONG nFontMetricCount;
- SalData* pSalData;
-
-#if OSL_DEBUG_LEVEL > 1
- debug_printf("Os2SalGraphics::GetDevFontList\n");
-#endif
-
- // install OpenSymbol
- HMODULE hMod;
- ULONG ObjNum, Offset, rc;
- CHAR Buff[2*_MAX_PATH];
- // get module handle (and name)
- rc = DosQueryModFromEIP( &hMod, &ObjNum, sizeof( Buff), Buff,
- &Offset, (ULONG)ImplSalGetUniString);
- DosQueryModuleName(hMod, sizeof(Buff), Buff);
- // replace module path with font path
- char* slash = strrchr( Buff, '\\');
- *slash = '\0';
- slash = strrchr( Buff, '\\');
- *slash = '\0';
- strcat( Buff, "\\SHARE\\FONTS\\TRUETYPE\\OPENS___.TTF");
- rc = GpiLoadPublicFonts( GetSalData()->mhAB, Buff);
-
- if ( !mbPrinter )
- {
- // Bei Bildschirm-Devices cachen wir die Liste global, da
- // dies im unabhaengigen Teil auch so gemacht wird und wir
- // ansonsten auf geloeschten Systemdaten arbeiten koennten
- pSalData = GetSalData();
- nFontMetricCount = pSalData->mnFontMetricCount;
- pFontMetrics = pSalData->mpFontMetrics;
- // Bei Bildschirm-Devices holen wir uns die Fontliste jedesmal neu
- if ( pFontMetrics )
- {
- delete pFontMetrics;
- pFontMetrics = NULL;
- nFontMetricCount = 0;
- }
- }
- else
- {
- nFontMetricCount = mnFontMetricCount;
- pFontMetrics = mpFontMetrics;
- }
-
- // do we have to create the cached font list first?
- if ( !pFontMetrics )
- {
- // query the number of fonts available
- LONG nTemp = 0;
- nFontMetricCount = Ft2QueryFonts( mhPS,
- QF_PUBLIC | QF_PRIVATE,
- NULL, &nTemp,
- sizeof( FONTMETRICS ), NULL );
-
- // procede only if at least one is available!
- if ( nFontMetricCount )
- {
- // allocate memory for font list
- pFontMetrics = new FONTMETRICS[nFontMetricCount];
-
- // query font list
- Ft2QueryFonts( mhPS,
- QF_PUBLIC | QF_PRIVATE,
- NULL,
- (PLONG)&nFontMetricCount,
- (LONG) sizeof( FONTMETRICS ),
- pFontMetrics );
- }
-
- if ( !mbPrinter )
- {
- pSalData->mnFontMetricCount = nFontMetricCount;
- pSalData->mpFontMetrics = pFontMetrics;
- }
- else
- {
- mnFontMetricCount = nFontMetricCount;
- mpFontMetrics = pFontMetrics;
- }
- }
-
- // copy data from the font list
- for( ULONG i = 0; i < nFontMetricCount; i++ )
- {
- PFONTMETRICS pFontMetric = &pFontMetrics[i];
-
- // skip font starting with '@', this is an alias internally
- // used by truetype engine.
- if (pFontMetric->szFacename[0] == '@')
- continue;
-
- // skip bitmap fonts (but keep WarpSans)
- if ( (pFontMetric->fsDefn & FM_DEFN_OUTLINE) == 0
- && strncmp( pFontMetric->szFacename, "WarpSans", 8) )
- // Font nicht aufnehmen
- continue;
-
- // replace '-' in facename with ' ' (for ft2lib)
- char* dash = pFontMetric->szFacename;
- while( (dash=strchr( dash, '-')))
- *dash++ = ' ';
-
- // create new font list element
- ImplOs2FontData* pData = new ImplOs2FontData( pFontMetric, 0, 0 );
-
- // add font list element to font list
- pList->Add( pData );
-
- }
-}
-
-// ----------------------------------------------------------------------------
-
-void Os2SalGraphics::GetDevFontSubstList( OutputDevice* pOutDev )
-{
-}
-
-// -----------------------------------------------------------------------
-
-BOOL Os2SalGraphics::GetGlyphBoundRect( long nIndex, Rectangle& rRect )
-{
- // use unity matrix
- MAT2 aMat;
- aMat.eM11 = aMat.eM22 = FixedFromDouble( 1.0 );
- aMat.eM12 = aMat.eM21 = FixedFromDouble( 0.0 );
-
- UINT nGGOFlags = GGO_METRICS;
- if( !(nIndex & GF_ISCHAR) )
- nGGOFlags |= GGO_GLYPH_INDEX;
- nIndex &= GF_IDXMASK;
-
- GLYPHMETRICS aGM;
- DWORD nSize = FT2_ERROR;
- nSize = Ft2GetGlyphOutline( mhPS, nIndex, nGGOFlags, &aGM, 0, NULL, &aMat );
- if( nSize == FT2_ERROR )
- return false;
-
- rRect = Rectangle( Point( +aGM.gmptGlyphOrigin.x, -aGM.gmptGlyphOrigin.y ),
- Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) );
- rRect.Left() = static_cast<int>( mfFontScale * rRect.Left() );
- rRect.Right() = static_cast<int>( mfFontScale * rRect.Right() );
- rRect.Top() = static_cast<int>( mfFontScale * rRect.Top() );
- rRect.Bottom() = static_cast<int>( mfFontScale * rRect.Bottom() );
- return true;
-}
-
-// -----------------------------------------------------------------------
-
-BOOL Os2SalGraphics::GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& rB2DPolyPoly )
-{
-#if OSL_DEBUG_LEVEL > 1
- debug_printf("Os2SalGraphics::GetGlyphOutline\n");
-#endif
- rB2DPolyPoly.clear();
-
- BOOL bRet = FALSE;
-
- // use unity matrix
- MAT2 aMat;
- aMat.eM11 = aMat.eM22 = FixedFromDouble( 1.0 );
- aMat.eM12 = aMat.eM21 = FixedFromDouble( 0.0 );
-
- UINT nGGOFlags = GGO_NATIVE;
- if( !(nIndex & GF_ISCHAR) )
- nGGOFlags |= GGO_GLYPH_INDEX;
- nIndex &= GF_IDXMASK;
-
- GLYPHMETRICS aGlyphMetrics;
- DWORD nSize1 = FT2_ERROR;
- nSize1 = Ft2GetGlyphOutline( mhPS, nIndex, nGGOFlags, &aGlyphMetrics, 0, NULL, &aMat );
-
- if( !nSize1 ) // blank glyphs are ok
- bRet = TRUE;
- else if( nSize1 != FT2_ERROR )
- {
- BYTE* pData = new BYTE[ nSize1 ];
- ULONG nTotalCount = 0;
- DWORD nSize2;
- nSize2 = Ft2GetGlyphOutline( mhPS, nIndex, nGGOFlags,
- &aGlyphMetrics, nSize1, pData, &aMat );
-
- if( nSize1 == nSize2 )
- {
- bRet = TRUE;
-
- int nPtSize = 512;
- Point* pPoints = new Point[ nPtSize ];
- BYTE* pFlags = new BYTE[ nPtSize ];
-
- TTPOLYGONHEADER* pHeader = (TTPOLYGONHEADER*)pData;
- while( (BYTE*)pHeader < pData+nSize2 )
- {
- // only outline data is interesting
- if( pHeader->dwType != TT_POLYGON_TYPE )
- break;
-
- // get start point; next start points are end points
- // of previous segment
- int nPnt = 0;
-
- long nX = IntTimes256FromFixed( pHeader->pfxStart.x );
- long nY = IntTimes256FromFixed( pHeader->pfxStart.y );
- pPoints[ nPnt ] = Point( nX, nY );
- pFlags[ nPnt++ ] = POLY_NORMAL;
-
- bool bHasOfflinePoints = false;
- TTPOLYCURVE* pCurve = (TTPOLYCURVE*)( pHeader + 1 );
- pHeader = (TTPOLYGONHEADER*)( (BYTE*)pHeader + pHeader->cb );
- while( (BYTE*)pCurve < (BYTE*)pHeader )
- {
- int nNeededSize = nPnt + 16 + 3 * pCurve->cpfx;
- if( nPtSize < nNeededSize )
- {
- Point* pOldPoints = pPoints;
- BYTE* pOldFlags = pFlags;
- nPtSize = 2 * nNeededSize;
- pPoints = new Point[ nPtSize ];
- pFlags = new BYTE[ nPtSize ];
- for( int i = 0; i < nPnt; ++i )
- {
- pPoints[ i ] = pOldPoints[ i ];
- pFlags[ i ] = pOldFlags[ i ];
- }
- delete[] pOldPoints;
- delete[] pOldFlags;
- }
-
- int i = 0;
- if( TT_PRIM_LINE == pCurve->wType )
- {
- while( i < pCurve->cpfx )
- {
- nX = IntTimes256FromFixed( pCurve->apfx[ i ].x );
- nY = IntTimes256FromFixed( pCurve->apfx[ i ].y );
- ++i;
- pPoints[ nPnt ] = Point( nX, nY );
- pFlags[ nPnt ] = POLY_NORMAL;
- ++nPnt;
- }
- }
- else if( TT_PRIM_QSPLINE == pCurve->wType )
- {
- bHasOfflinePoints = true;
- while( i < pCurve->cpfx )
- {
- // get control point of quadratic bezier spline
- nX = IntTimes256FromFixed( pCurve->apfx[ i ].x );
- nY = IntTimes256FromFixed( pCurve->apfx[ i ].y );
- ++i;
- Point aControlP( nX, nY );
-
- // calculate first cubic control point
- // P0 = 1/3 * (PBeg + 2 * PQControl)
- nX = pPoints[ nPnt-1 ].X() + 2 * aControlP.X();
- nY = pPoints[ nPnt-1 ].Y() + 2 * aControlP.Y();
- pPoints[ nPnt+0 ] = Point( (2*nX+3)/6, (2*nY+3)/6 );
- pFlags[ nPnt+0 ] = POLY_CONTROL;
-
- // calculate endpoint of segment
- nX = IntTimes256FromFixed( pCurve->apfx[ i ].x );
- nY = IntTimes256FromFixed( pCurve->apfx[ i ].y );
-
- if ( i+1 >= pCurve->cpfx )
- {
- // endpoint is either last point in segment => advance
- ++i;
- }
- else
- {
- // or endpoint is the middle of two control points
- nX += IntTimes256FromFixed( pCurve->apfx[ i-1 ].x );
- nY += IntTimes256FromFixed( pCurve->apfx[ i-1 ].y );
- nX = (nX + 1) / 2;
- nY = (nY + 1) / 2;
- // no need to advance, because the current point
- // is the control point in next bezier spline
- }
-
- pPoints[ nPnt+2 ] = Point( nX, nY );
- pFlags[ nPnt+2 ] = POLY_NORMAL;
-
- // calculate second cubic control point
- // P1 = 1/3 * (PEnd + 2 * PQControl)
- nX = pPoints[ nPnt+2 ].X() + 2 * aControlP.X();
- nY = pPoints[ nPnt+2 ].Y() + 2 * aControlP.Y();
- pPoints[ nPnt+1 ] = Point( (2*nX+3)/6, (2*nY+3)/6 );
- pFlags[ nPnt+1 ] = POLY_CONTROL;
-
- nPnt += 3;
- }
- }
-
- // next curve segment
- pCurve = (TTPOLYCURVE*)&pCurve->apfx[ i ];
- }
-
- // end point is start point for closed contour
- // disabled, because Polygon class closes the contour itself
- // pPoints[nPnt++] = pPoints[0];
- // #i35928#
- // Added again, but add only when not yet closed
- if(pPoints[nPnt - 1] != pPoints[0])
- {
- if( bHasOfflinePoints )
- pFlags[nPnt] = pFlags[0];
-
- pPoints[nPnt++] = pPoints[0];
- }
-
- // convert y-coordinates W32 -> VCL
- for( int i = 0; i < nPnt; ++i )
- pPoints[i].Y() = -pPoints[i].Y();
-
- // insert into polypolygon
- Polygon aPoly( nPnt, pPoints, (bHasOfflinePoints ? pFlags : NULL) );
- // convert to B2DPolyPolygon
- // TODO: get rid of the intermediate PolyPolygon
- rB2DPolyPoly.append( aPoly.getB2DPolygon() );
- }
-
- delete[] pPoints;
- delete[] pFlags;
- }
-
- delete[] pData;
- }
-
- // rescaling needed for the PolyPolygon conversion
- if( rB2DPolyPoly.count() )
- {
- const double fFactor((1.0/256) * mfFontScale);
- rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor));
- }
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------
-
-// TODO: Replace this class with boost::scoped_array
-class ScopedCharArray
-{
-public:
- inline explicit ScopedCharArray(char * pArray): m_pArray(pArray) {}
-
- inline ~ScopedCharArray() { delete[] m_pArray; }
-
- inline char * get() const { return m_pArray; }
-
-private:
- char * m_pArray;
-};
-
-class ScopedFont
-{
-public:
- explicit ScopedFont(Os2SalGraphics & rData);
-
- ~ScopedFont();
-
-private:
- Os2SalGraphics & m_rData;
- ULONG m_hOrigFont;
-};
-
-ScopedFont::ScopedFont(Os2SalGraphics & rData): m_rData(rData)
-{
-}
-
-ScopedFont::~ScopedFont()
-{
-}
-
-class ScopedTrueTypeFont
-{
-public:
- inline ScopedTrueTypeFont(): m_pFont(0) {}
-
- ~ScopedTrueTypeFont();
-
- int open(void * pBuffer, sal_uInt32 nLen, sal_uInt32 nFaceNum);
-
- inline TrueTypeFont * get() const { return m_pFont; }
-
-private:
- TrueTypeFont * m_pFont;
-};
-
-ScopedTrueTypeFont::~ScopedTrueTypeFont()
-{
- if (m_pFont != 0)
- CloseTTFont(m_pFont);
-}
-
-int ScopedTrueTypeFont::open(void * pBuffer, sal_uInt32 nLen,
- sal_uInt32 nFaceNum)
-{
- OSL_ENSURE(m_pFont == 0, "already open");
- return OpenTTFontBuffer(pBuffer, nLen, nFaceNum, &m_pFont);
-}
-
-BOOL Os2SalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
- const ImplFontData* pFont, long* pGlyphIDs, sal_uInt8* pEncoding,
- sal_Int32* pGlyphWidths, int nGlyphCount, FontSubsetInfo& rInfo )
-{
- // 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)
- ImplFontSelectData aIFSD( *pFont, Size(0,1000), 1000.0, 0, false );
-
- // TODO: much better solution: move SetFont and restoration of old font to caller
- ScopedFont aOldFont(*this);
- SetFont( &aIFSD, 0 );
-
-#if OSL_DEBUG_LEVEL > 1
- // get font metrics
- TEXTMETRICA aWinMetric;
- if( !::GetTextMetricsA( mhDC, &aWinMetric ) )
- return FALSE;
-
- DBG_ASSERT( !(aWinMetric.tmPitchAndFamily & TMPF_DEVICE), "cannot subset device font" );
- DBG_ASSERT( aWinMetric.tmPitchAndFamily & TMPF_TRUETYPE, "can only subset TT font" );
-#endif
-
- // get raw font file data
- DWORD nFontSize1 = Ft2GetFontData( mhPS, 0, 0, NULL, 0 );
- if( nFontSize1 == FT2_ERROR )
- return FALSE;
- ScopedCharArray xRawFontData(new char[ nFontSize1 ]);
- DWORD nFontSize2 = Ft2GetFontData( mhPS, 0, 0, (void*)xRawFontData.get(), nFontSize1 );
- if( nFontSize1 != nFontSize2 )
- return FALSE;
-
- // open font file
- sal_uInt32 nFaceNum = 0;
- if( !*xRawFontData.get() ) // TTC candidate
- nFaceNum = ~0U; // indicate "TTC font extracts only"
-
- ScopedTrueTypeFont aSftTTF;
- int nRC = aSftTTF.open( xRawFontData.get(), nFontSize1, nFaceNum );
- if( nRC != SF_OK )
- return FALSE;
-
- TTGlobalFontInfo aTTInfo;
- ::GetTTGlobalFontInfo( aSftTTF.get(), &aTTInfo );
- rInfo.m_nFontType = SAL_FONTSUBSETINFO_TYPE_TRUETYPE;
- rInfo.m_aPSName = ImplSalGetUniString( aTTInfo.psname );
- rInfo.m_nAscent = +aTTInfo.winAscent;
- rInfo.m_nDescent = -aTTInfo.winDescent;
- rInfo.m_aFontBBox = Rectangle( Point( aTTInfo.xMin, aTTInfo.yMin ),
- Point( aTTInfo.xMax, aTTInfo.yMax ) );
- rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
-
- // subset glyphs and get their properties
- // take care that subset fonts require the NotDef glyph in pos 0
- int nOrigCount = nGlyphCount;
- USHORT aShortIDs[ 256 ];
- sal_uInt8 aTempEncs[ 256 ];
-
- int nNotDef=-1, i;
- for( i = 0; i < nGlyphCount; ++i )
- {
- aTempEncs[i] = pEncoding[i];
- sal_uInt32 nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK;
- if( pGlyphIDs[i] & GF_ISCHAR )
- {
- bool bVertical = (pGlyphIDs[i] & GF_ROTMASK) != 0;
- nGlyphIdx = ::MapChar( aSftTTF.get(), sal::static_int_cast<sal_uInt16>(nGlyphIdx), bVertical );
- if( nGlyphIdx == 0 && pFont->IsSymbolFont() )
- {
- // #i12824# emulate symbol aliasing U+FXXX <-> U+0XXX
- nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK;
- nGlyphIdx = (nGlyphIdx & 0xF000) ? (nGlyphIdx & 0x00FF) : (nGlyphIdx | 0xF000 );
- nGlyphIdx = ::MapChar( aSftTTF.get(), sal::static_int_cast<sal_uInt16>(nGlyphIdx), bVertical );
- }
- }
- aShortIDs[i] = static_cast<USHORT>( nGlyphIdx );
- if( !nGlyphIdx )
- if( nNotDef < 0 )
- nNotDef = i; // first NotDef glyph found
- }
-
- if( nNotDef != 0 )
- {
- // add fake NotDef glyph if needed
- if( nNotDef < 0 )
- nNotDef = nGlyphCount++;
-
- // NotDef glyph must be in pos 0 => swap glyphids
- aShortIDs[ nNotDef ] = aShortIDs[0];
- aTempEncs[ nNotDef ] = aTempEncs[0];
- aShortIDs[0] = 0;
- aTempEncs[0] = 0;
- }
- DBG_ASSERT( nGlyphCount < 257, "too many glyphs for subsetting" );
-
- // fill pWidth array
- TTSimpleGlyphMetrics* pMetrics =
- ::GetTTSimpleGlyphMetrics( aSftTTF.get(), aShortIDs, nGlyphCount, aIFSD.mbVertical );
- if( !pMetrics )
- return FALSE;
- sal_uInt16 nNotDefAdv = pMetrics[0].adv;
- pMetrics[0].adv = pMetrics[nNotDef].adv;
- pMetrics[nNotDef].adv = nNotDefAdv;
- for( i = 0; i < nOrigCount; ++i )
- pGlyphWidths[i] = pMetrics[i].adv;
- 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;
-}
-
-//--------------------------------------------------------------------------
-
-const void* Os2SalGraphics::GetEmbedFontData( const ImplFontData* pFont,
- const sal_Ucs* pUnicodes, sal_Int32* pCharWidths,
- FontSubsetInfo& rInfo, long* pDataLen )
-{
- // create matching ImplFontSelectData
- // we need just enough to get to the font file data
- ImplFontSelectData aIFSD( *pFont, Size(0,1000), 1000.0, 0, false );
-
- // TODO: much better solution: move SetFont and restoration of old font to caller
- ScopedFont aOldFont(*this);
- SetFont( &aIFSD, 0 );
-
- // get the raw font file data
- DWORD nFontSize1 = Ft2GetFontData( mhPS, 0, 0, NULL, 0 );
- if( nFontSize1 == FT2_ERROR || nFontSize1 <= 0 )
- return NULL;
- *pDataLen = nFontSize1;
- void* pData = reinterpret_cast<void*>(new char[ nFontSize1 ]);
- DWORD nFontSize2 = Ft2GetFontData( mhPS, 0, 0, pData, nFontSize1 );
- if( nFontSize1 != nFontSize2 )
- *pDataLen = 0;
-
- // get important font properties
- FONTMETRICS aOS2Metric;
- if (Ft2QueryFontMetrics( mhPS, sizeof( aOS2Metric ), &aOS2Metric ) == GPI_ERROR)
- *pDataLen = 0;
- rInfo.m_nFontType = SAL_FONTSUBSETINFO_TYPE_TYPE1;
- rInfo.m_aPSName = ImplSalGetUniString( aOS2Metric.szFacename );
- rInfo.m_nAscent = +aOS2Metric.lMaxAscender;
- rInfo.m_nDescent = -aOS2Metric.lMaxDescender;
- rInfo.m_aFontBBox = Rectangle( Point( 0, -aOS2Metric.lMaxDescender ),
- Point( aOS2Metric.lMaxCharInc, aOS2Metric.lMaxAscender+aOS2Metric.lExternalLeading ) );
- rInfo.m_nCapHeight = aOS2Metric.lMaxAscender; // Well ...
-
- // get individual character widths
- for( int i = 0; i < 256; ++i )
- {
- LONG nCharWidth = 0;
- const sal_Ucs cChar = pUnicodes[i];
- if( !Ft2QueryStringWidthW( mhPS, (LPWSTR)&cChar, 1, &nCharWidth ) )
- *pDataLen = 0;
- pCharWidths[i] = nCharWidth;
- }
-
- if( !*pDataLen )
- {
- FreeEmbedFontData( pData, nFontSize1 );
- pData = NULL;
- }
-
- return pData;
-}
-
-//--------------------------------------------------------------------------
-
-void Os2SalGraphics::FreeEmbedFontData( const void* pData, long /*nLen*/ )
-{
- delete[] reinterpret_cast<char*>(const_cast<void*>(pData));
-}
-
-const Ucs2SIntMap* Os2SalGraphics::GetFontEncodingVector( const ImplFontData* pFont, const Ucs2OStrMap** pNonEncoded )
-{
- // TODO: even for builtin fonts we get here... why?
- if( !pFont->IsEmbeddable() )
- return NULL;
-
- // fill the encoding vector
- Ucs2SIntMap& rMap = *new Ucs2SIntMap;
-
- for( sal_Unicode i = 32; i < 256; ++i )
- rMap[i] = i;
- if( pNonEncoded )
- *pNonEncoded = NULL;
-
- return &rMap;
-}
-
-//--------------------------------------------------------------------------
-
-void Os2SalGraphics::GetGlyphWidths( const ImplFontData* pFont,
- bool bVertical,
- Int32Vector& rWidths,
- Ucs2UIntMap& rUnicodeEnc )
-{
- // create matching ImplFontSelectData
- // we need just enough to get to the font file data
- ImplFontSelectData aIFSD( *pFont, Size(0,1000), 1000.0, 0, false );
-
- // TODO: much better solution: move SetFont and restoration of old font to caller
- ScopedFont aOldFont(*this);
-
- float fScale = 0.0;
- ImplDoSetFont( &aIFSD, fScale, 0);
-
- if( pFont->IsSubsettable() )
- {
- // get raw font file data
- DWORD nFontSize1 = ::Ft2GetFontData( mhPS, 0, 0, NULL, 0 );
- if( nFontSize1 == FT2_ERROR )
- return;
- ScopedCharArray xRawFontData(new char[ nFontSize1 ]);
- DWORD nFontSize2 = ::Ft2GetFontData( mhPS, 0, 0, (void*)xRawFontData.get(), nFontSize1 );
- if( nFontSize1 != nFontSize2 )
- return;
-
- // open font file
- sal_uInt32 nFaceNum = 0;
- if( !*xRawFontData.get() ) // TTC candidate
- nFaceNum = ~0U; // indicate "TTC font extracts only"
-
- ScopedTrueTypeFont aSftTTF;
- int nRC = aSftTTF.open( xRawFontData.get(), nFontSize1, nFaceNum );
- if( nRC != SF_OK )
- return;
-
- int nGlyphs = GetTTGlyphCount( aSftTTF.get() );
- if( nGlyphs > 0 )
- {
- rWidths.resize(nGlyphs);
- std::vector<sal_uInt16> aGlyphIds(nGlyphs);
- for( int i = 0; i < nGlyphs; i++ )
- aGlyphIds[i] = sal_uInt16(i);
- TTSimpleGlyphMetrics* pMetrics = ::GetTTSimpleGlyphMetrics( aSftTTF.get(),
- &aGlyphIds[0],
- nGlyphs,
- bVertical ? 1 : 0 );
- if( pMetrics )
- {
- for( int i = 0; i< nGlyphs; i++ )
- rWidths[i] = pMetrics[i].adv;
- free( pMetrics );
- rUnicodeEnc.clear();
- }
- const ImplOs2FontData* pWinFont = static_cast<const ImplOs2FontData*>(pFont);
- const ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap();
- DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" );
-
- int nCharCount = pMap->GetCharCount();
- sal_uInt32 nChar = pMap->GetFirstChar();
- for( int i = 0; i < nCharCount; i++ )
- {
- if( nChar < 0x00010000 )
- {
- sal_uInt16 nGlyph = ::MapChar( aSftTTF.get(),
- static_cast<sal_uInt16>(nChar),
- bVertical ? 1 : 0 );
- if( nGlyph )
- rUnicodeEnc[ static_cast<sal_Unicode>(nChar) ] = nGlyph;
- }
- nChar = pMap->GetNextChar( nChar );
- }
- }
- }
- else if( pFont->IsEmbeddable() )
- {
- // get individual character widths
- rWidths.clear();
- rUnicodeEnc.clear();
- rWidths.reserve( 224 );
- for( sal_Unicode i = 32; i < 256; ++i )
- {
- int nCharWidth = 0;
- if( Ft2QueryStringWidthW( mhPS, (LPWSTR)&i, 1, (LONG*)&nCharWidth ) )
- {
- rUnicodeEnc[ i ] = rWidths.size();
- rWidths.push_back( nCharWidth );
- }
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-void Os2SalGraphics::DrawServerFontLayout( const ServerFontLayout& )
-{}
-
-//--------------------------------------------------------------------------
-
-SystemFontData Os2SalGraphics::GetSysFontData( int nFallbacklevel ) const
-{
- SystemFontData aSysFontData;
-
- if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
- if (nFallbacklevel < 0 ) nFallbacklevel = 0;
-
- aSysFontData.nSize = sizeof( SystemFontData );
- aSysFontData.hFont = mhFonts[nFallbacklevel];
- aSysFontData.bFakeBold = false;
- aSysFontData.bFakeItalic = false;
- aSysFontData.bAntialias = true;
- aSysFontData.bVerticalCharacterType = false;
-
- return aSysFontData;
-}
-
-//--------------------------------------------------------------------------
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */