1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <unistd.h> 32*cdf0e10cSrcweir #include <sys/stat.h> 33*cdf0e10cSrcweir #include <dirent.h> 34*cdf0e10cSrcweir #include <stdlib.h> 35*cdf0e10cSrcweir #include <osl/thread.h> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include "unotools/atom.hxx" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "fontcache.hxx" 40*cdf0e10cSrcweir #include "fontsubset.hxx" 41*cdf0e10cSrcweir #include "impfont.hxx" 42*cdf0e10cSrcweir #include "svdata.hxx" 43*cdf0e10cSrcweir #include "salinst.hxx" 44*cdf0e10cSrcweir #include "vcl/fontmanager.hxx" 45*cdf0e10cSrcweir #include "vcl/strhelper.hxx" 46*cdf0e10cSrcweir #include "vcl/ppdparser.hxx" 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #include "tools/urlobj.hxx" 49*cdf0e10cSrcweir #include "tools/stream.hxx" 50*cdf0e10cSrcweir #include "tools/debug.hxx" 51*cdf0e10cSrcweir #include "tools/config.hxx" 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #include "osl/file.hxx" 54*cdf0e10cSrcweir #include "osl/process.h" 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #include "rtl/tencinfo.h" 57*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 58*cdf0e10cSrcweir #include "rtl/strbuf.hxx" 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #include "i18npool/mslangid.hxx" 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir #include "parseAFM.hxx" 64*cdf0e10cSrcweir #include "sft.hxx" 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 67*cdf0e10cSrcweir #include <sys/times.h> 68*cdf0e10cSrcweir #include <stdio.h> 69*cdf0e10cSrcweir #endif 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir #include "sal/alloca.h" 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir #include <set> 74*cdf0e10cSrcweir #include <hash_set> 75*cdf0e10cSrcweir #include <algorithm> 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir #include "adobeenc.tab" // get encoding table for AFM metrics 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 80*cdf0e10cSrcweir #include <valgrind/callgrind.h> 81*cdf0e10cSrcweir #endif 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir #include "comphelper/processfactory.hxx" 84*cdf0e10cSrcweir #include "com/sun/star/beans/XMaterialHolder.hpp" 85*cdf0e10cSrcweir #include "com/sun/star/beans/NamedValue.hpp" 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir #define PRINTER_METRICDIR "fontmetric" 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir namespace { 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir namespace css = com::sun::star; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir using namespace vcl; 96*cdf0e10cSrcweir using namespace utl; 97*cdf0e10cSrcweir using namespace psp; 98*cdf0e10cSrcweir using namespace osl; 99*cdf0e10cSrcweir using namespace rtl; 100*cdf0e10cSrcweir using namespace com::sun::star::uno; 101*cdf0e10cSrcweir using namespace com::sun::star::beans; 102*cdf0e10cSrcweir using namespace com::sun::star::lang; 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir /* 105*cdf0e10cSrcweir * static helpers 106*cdf0e10cSrcweir */ 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir inline sal_uInt16 getUInt16BE( const sal_uInt8*& pBuffer ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir sal_uInt16 nRet = (sal_uInt16)pBuffer[1] | 111*cdf0e10cSrcweir (((sal_uInt16)pBuffer[0]) << 8); 112*cdf0e10cSrcweir pBuffer+=2; 113*cdf0e10cSrcweir return nRet; 114*cdf0e10cSrcweir } 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir inline sal_uInt32 getUInt32BE( const sal_uInt8*& pBuffer ) 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir sal_uInt32 nRet = (((sal_uInt32)pBuffer[0]) << 24) | 119*cdf0e10cSrcweir (((sal_uInt32)pBuffer[1]) << 16) | 120*cdf0e10cSrcweir (((sal_uInt32)pBuffer[2]) << 8) | 121*cdf0e10cSrcweir (((sal_uInt32)pBuffer[3]) ); 122*cdf0e10cSrcweir pBuffer += 4; 123*cdf0e10cSrcweir return nRet; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir static italic::type parseItalic( const ByteString& rItalic ) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir italic::type eItalic = italic::Unknown; 129*cdf0e10cSrcweir if( rItalic.EqualsIgnoreCaseAscii( "i" ) ) 130*cdf0e10cSrcweir eItalic = italic::Italic; 131*cdf0e10cSrcweir else if( rItalic.EqualsIgnoreCaseAscii( "o" ) ) 132*cdf0e10cSrcweir eItalic = italic::Oblique; 133*cdf0e10cSrcweir else 134*cdf0e10cSrcweir eItalic = italic::Upright; 135*cdf0e10cSrcweir return eItalic; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir // ------------------------------------------------------------------------- 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir static weight::type parseWeight( const ByteString& rWeight ) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir weight::type eWeight = weight::Unknown; 143*cdf0e10cSrcweir if( rWeight.Search( "bold" ) != STRING_NOTFOUND ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir if( rWeight.Search( "emi" ) != STRING_NOTFOUND ) // semi, demi 146*cdf0e10cSrcweir eWeight = weight::SemiBold; 147*cdf0e10cSrcweir else if( rWeight.Search( "ultra" ) != STRING_NOTFOUND ) 148*cdf0e10cSrcweir eWeight = weight::UltraBold; 149*cdf0e10cSrcweir else 150*cdf0e10cSrcweir eWeight = weight::Bold; 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir else if( rWeight.Search( "heavy" ) != STRING_NOTFOUND ) 153*cdf0e10cSrcweir eWeight = weight::Bold; 154*cdf0e10cSrcweir else if( rWeight.Search( "light" ) != STRING_NOTFOUND ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir if( rWeight.Search( "emi" ) != STRING_NOTFOUND ) // semi, demi 157*cdf0e10cSrcweir eWeight = weight::SemiLight; 158*cdf0e10cSrcweir else if( rWeight.Search( "ultra" ) != STRING_NOTFOUND ) 159*cdf0e10cSrcweir eWeight = weight::UltraLight; 160*cdf0e10cSrcweir else 161*cdf0e10cSrcweir eWeight = weight::Light; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir else if( rWeight.Search( "black" ) != STRING_NOTFOUND ) 164*cdf0e10cSrcweir eWeight = weight::Black; 165*cdf0e10cSrcweir else if( rWeight.Equals( "demi" ) ) 166*cdf0e10cSrcweir eWeight = weight::SemiBold; 167*cdf0e10cSrcweir else if( rWeight.Equals( "book" ) || 168*cdf0e10cSrcweir rWeight.Equals( "semicondensed" ) ) 169*cdf0e10cSrcweir eWeight = weight::Light; 170*cdf0e10cSrcweir else if( rWeight.Equals( "medium" ) || rWeight.Equals( "roman" ) ) 171*cdf0e10cSrcweir eWeight = weight::Medium; 172*cdf0e10cSrcweir else 173*cdf0e10cSrcweir eWeight = weight::Normal; 174*cdf0e10cSrcweir return eWeight; 175*cdf0e10cSrcweir } 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir // ------------------------------------------------------------------------- 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir static width::type parseWidth( const ByteString& rWidth ) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir width::type eWidth = width::Unknown; 182*cdf0e10cSrcweir if( rWidth.Equals( "bold" ) || 183*cdf0e10cSrcweir rWidth.Equals( "semiexpanded" ) ) 184*cdf0e10cSrcweir eWidth = width::SemiExpanded; 185*cdf0e10cSrcweir else if( rWidth.Equals( "condensed" ) || 186*cdf0e10cSrcweir rWidth.Equals( "narrow" ) ) 187*cdf0e10cSrcweir eWidth = width::Condensed; 188*cdf0e10cSrcweir else if( rWidth.Equals( "double wide" ) || 189*cdf0e10cSrcweir rWidth.Equals( "extraexpanded" ) || 190*cdf0e10cSrcweir rWidth.Equals( "ultraexpanded" ) ) 191*cdf0e10cSrcweir eWidth = width::UltraExpanded; 192*cdf0e10cSrcweir else if( rWidth.Equals( "expanded" ) || 193*cdf0e10cSrcweir rWidth.Equals( "wide" ) ) 194*cdf0e10cSrcweir eWidth = width::Expanded; 195*cdf0e10cSrcweir else if( rWidth.Equals( "extracondensed" ) ) 196*cdf0e10cSrcweir eWidth = width::ExtraCondensed; 197*cdf0e10cSrcweir else if( rWidth.Equals( "semicondensed" ) ) 198*cdf0e10cSrcweir eWidth = width::SemiCondensed; 199*cdf0e10cSrcweir else if( rWidth.Equals( "ultracondensed" ) ) 200*cdf0e10cSrcweir eWidth = width::UltraCondensed; 201*cdf0e10cSrcweir else 202*cdf0e10cSrcweir eWidth = width::Normal; 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir return eWidth; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir // ------------------------------------------------------------------------- 208*cdf0e10cSrcweir bool PrintFontManager::XLFDEntry::operator<(const PrintFontManager::XLFDEntry& rRight) const 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir sal_Int32 nCmp = 0; 211*cdf0e10cSrcweir if( (nMask & MaskFamily) && (rRight.nMask & MaskFamily) ) 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFamily.pData->buffer, 214*cdf0e10cSrcweir aFamily.pData->length, 215*cdf0e10cSrcweir rRight.aFamily.pData->buffer, 216*cdf0e10cSrcweir rRight.aFamily.pData->length ); 217*cdf0e10cSrcweir if( nCmp != 0 ) 218*cdf0e10cSrcweir return nCmp < 0; 219*cdf0e10cSrcweir } 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir if( (nMask & MaskFoundry) && (rRight.nMask & MaskFoundry) ) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFoundry.pData->buffer, 224*cdf0e10cSrcweir aFoundry.pData->length, 225*cdf0e10cSrcweir rRight.aFoundry.pData->buffer, 226*cdf0e10cSrcweir rRight.aFoundry.pData->length ); 227*cdf0e10cSrcweir if( nCmp != 0 ) 228*cdf0e10cSrcweir return nCmp < 0; 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir if( (nMask & MaskItalic) && (rRight.nMask & MaskItalic) ) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir if( eItalic != rRight.eItalic ) 234*cdf0e10cSrcweir return (int)eItalic < (int)rRight.eItalic; 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir if( (nMask & MaskWeight) && (rRight.nMask & MaskWeight) ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir if( eWeight != rRight.eWeight ) 240*cdf0e10cSrcweir return (int)eWeight < (int)rRight.eWeight; 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir if( (nMask & MaskWidth) && (rRight.nMask & MaskWidth) ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir if( eWidth != rRight.eWidth ) 246*cdf0e10cSrcweir return (int)eWidth < (int)rRight.eWidth; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir if( (nMask & MaskPitch) && (rRight.nMask & MaskPitch) ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir if( ePitch != rRight.ePitch ) 252*cdf0e10cSrcweir return (int)ePitch < (int)rRight.ePitch; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir if( (nMask & MaskAddStyle) && (rRight.nMask & MaskAddStyle) ) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aAddStyle.pData->buffer, 258*cdf0e10cSrcweir aAddStyle.pData->length, 259*cdf0e10cSrcweir rRight.aAddStyle.pData->buffer, 260*cdf0e10cSrcweir rRight.aAddStyle.pData->length ); 261*cdf0e10cSrcweir if( nCmp != 0 ) 262*cdf0e10cSrcweir return nCmp < 0; 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir if( (nMask & MaskEncoding) && (rRight.nMask & MaskEncoding) ) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir if( aEncoding != rRight.aEncoding ) 268*cdf0e10cSrcweir return aEncoding < rRight.aEncoding; 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir return false; 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir bool PrintFontManager::XLFDEntry::operator==(const PrintFontManager::XLFDEntry& rRight) const 275*cdf0e10cSrcweir { 276*cdf0e10cSrcweir sal_Int32 nCmp = 0; 277*cdf0e10cSrcweir if( (nMask & MaskFamily) && (rRight.nMask & MaskFamily) ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFamily.pData->buffer, 280*cdf0e10cSrcweir aFamily.pData->length, 281*cdf0e10cSrcweir rRight.aFamily.pData->buffer, 282*cdf0e10cSrcweir rRight.aFamily.pData->length ); 283*cdf0e10cSrcweir if( nCmp != 0 ) 284*cdf0e10cSrcweir return false; 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir if( (nMask & MaskFoundry) && (rRight.nMask & MaskFoundry) ) 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFoundry.pData->buffer, 290*cdf0e10cSrcweir aFoundry.pData->length, 291*cdf0e10cSrcweir rRight.aFoundry.pData->buffer, 292*cdf0e10cSrcweir rRight.aFoundry.pData->length ); 293*cdf0e10cSrcweir if( nCmp != 0 ) 294*cdf0e10cSrcweir return false; 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir if( (nMask & MaskItalic) && (rRight.nMask & MaskItalic) ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir if( eItalic != rRight.eItalic ) 300*cdf0e10cSrcweir return false; 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir if( (nMask & MaskWeight) && (rRight.nMask & MaskWeight) ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir if( eWeight != rRight.eWeight ) 306*cdf0e10cSrcweir return false; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir if( (nMask & MaskWidth) && (rRight.nMask & MaskWidth) ) 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir if( eWidth != rRight.eWidth ) 312*cdf0e10cSrcweir return false; 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir if( (nMask & MaskPitch) && (rRight.nMask & MaskPitch) ) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir if( ePitch != rRight.ePitch ) 318*cdf0e10cSrcweir return false; 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir if( (nMask & MaskAddStyle) && (rRight.nMask & MaskAddStyle) ) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aAddStyle.pData->buffer, 324*cdf0e10cSrcweir aAddStyle.pData->length, 325*cdf0e10cSrcweir rRight.aAddStyle.pData->buffer, 326*cdf0e10cSrcweir rRight.aAddStyle.pData->length ); 327*cdf0e10cSrcweir if( nCmp != 0 ) 328*cdf0e10cSrcweir return false; 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir if( (nMask & MaskEncoding) && (rRight.nMask & MaskEncoding) ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if( aEncoding != rRight.aEncoding ) 334*cdf0e10cSrcweir return false; 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir return true; 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir /* 341*cdf0e10cSrcweir * PrintFont implementations 342*cdf0e10cSrcweir */ 343*cdf0e10cSrcweir PrintFontManager::PrintFont::PrintFont( fonttype::type eType ) : 344*cdf0e10cSrcweir m_eType( eType ), 345*cdf0e10cSrcweir m_nFamilyName( 0 ), 346*cdf0e10cSrcweir m_nPSName( 0 ), 347*cdf0e10cSrcweir m_eItalic( italic::Unknown ), 348*cdf0e10cSrcweir m_eWidth( width::Unknown ), 349*cdf0e10cSrcweir m_eWeight( weight::Unknown ), 350*cdf0e10cSrcweir m_ePitch( pitch::Unknown ), 351*cdf0e10cSrcweir m_aEncoding( RTL_TEXTENCODING_DONTKNOW ), 352*cdf0e10cSrcweir m_bFontEncodingOnly( false ), 353*cdf0e10cSrcweir m_pMetrics( NULL ), 354*cdf0e10cSrcweir m_nAscend( 0 ), 355*cdf0e10cSrcweir m_nDescend( 0 ), 356*cdf0e10cSrcweir m_nLeading( 0 ), 357*cdf0e10cSrcweir m_nXMin( 0 ), 358*cdf0e10cSrcweir m_nYMin( 0 ), 359*cdf0e10cSrcweir m_nXMax( 0 ), 360*cdf0e10cSrcweir m_nYMax( 0 ), 361*cdf0e10cSrcweir m_bHaveVerticalSubstitutedGlyphs( false ), 362*cdf0e10cSrcweir m_bUserOverride( false ) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir // ------------------------------------------------------------------------- 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir PrintFontManager::PrintFont::~PrintFont() 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir if( m_pMetrics ) 371*cdf0e10cSrcweir delete m_pMetrics; 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir // ------------------------------------------------------------------------- 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir PrintFontManager::Type1FontFile::~Type1FontFile() 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir // ------------------------------------------------------------------------- 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir PrintFontManager::TrueTypeFontFile::TrueTypeFontFile() 383*cdf0e10cSrcweir : PrintFont( fonttype::TrueType ) 384*cdf0e10cSrcweir , m_nDirectory( 0 ) 385*cdf0e10cSrcweir , m_nCollectionEntry(-1) 386*cdf0e10cSrcweir , m_nTypeFlags( TYPEFLAG_INVALID ) 387*cdf0e10cSrcweir {} 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir // ------------------------------------------------------------------------- 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir PrintFontManager::TrueTypeFontFile::~TrueTypeFontFile() 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir // ------------------------------------------------------------------------- 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir PrintFontManager::BuiltinFont::~BuiltinFont() 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir // ------------------------------------------------------------------------- 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir bool PrintFontManager::Type1FontFile::queryMetricPage( int /*nPage*/, MultiAtomProvider* pProvider ) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir return readAfmMetrics( PrintFontManager::get().getAfmFile( this ), pProvider, false, false ); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir // ------------------------------------------------------------------------- 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir bool PrintFontManager::BuiltinFont::queryMetricPage( int /*nPage*/, MultiAtomProvider* pProvider ) 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir return readAfmMetrics( PrintFontManager::get().getAfmFile( this ), pProvider, false, false ); 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir // ------------------------------------------------------------------------- 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir bool PrintFontManager::TrueTypeFontFile::queryMetricPage( int nPage, MultiAtomProvider* pProvider ) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir bool bSuccess = false; 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir ByteString aFile( PrintFontManager::get().getFontFile( this ) ); 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), m_nCollectionEntry < 0 ? 0 : m_nCollectionEntry, &pTTFont ) == SF_OK ) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir if( ! m_pMetrics ) 428*cdf0e10cSrcweir { 429*cdf0e10cSrcweir m_pMetrics = new PrintFontMetrics; 430*cdf0e10cSrcweir memset (m_pMetrics->m_aPages, 0, sizeof(m_pMetrics->m_aPages)); 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir m_pMetrics->m_aPages[ nPage/8 ] |= (1 << ( nPage & 7 )); 433*cdf0e10cSrcweir int i; 434*cdf0e10cSrcweir sal_uInt16 table[256], table_vert[256]; 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir for( i = 0; i < 256; i++ ) 437*cdf0e10cSrcweir table[ i ] = 256*nPage + i; 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir int nCharacters = nPage < 255 ? 256 : 254; 440*cdf0e10cSrcweir MapString( pTTFont, table, nCharacters, NULL, 0 ); 441*cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleCharMetrics( pTTFont, nPage*256, nCharacters, 0 ); 442*cdf0e10cSrcweir if( pMetrics ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir for( i = 0; i < nCharacters; i++ ) 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir if( table[i] ) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir CharacterMetric& rChar = m_pMetrics->m_aMetrics[ nPage*256 + i ]; 449*cdf0e10cSrcweir rChar.width = pMetrics[ i ].adv; 450*cdf0e10cSrcweir rChar.height = m_aGlobalMetricX.height; 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir free( pMetrics ); 455*cdf0e10cSrcweir } 456*cdf0e10cSrcweir 457*cdf0e10cSrcweir for( i = 0; i < 256; i++ ) 458*cdf0e10cSrcweir table_vert[ i ] = 256*nPage + i; 459*cdf0e10cSrcweir MapString( pTTFont, table_vert, nCharacters, NULL, 1 ); 460*cdf0e10cSrcweir pMetrics = GetTTSimpleCharMetrics( pTTFont, nPage*256, nCharacters, 1 ); 461*cdf0e10cSrcweir if( pMetrics ) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir for( i = 0; i < nCharacters; i++ ) 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir if( table_vert[i] ) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir CharacterMetric& rChar = m_pMetrics->m_aMetrics[ nPage*256 + i + ( 1 << 16 ) ]; 468*cdf0e10cSrcweir rChar.width = m_aGlobalMetricY.width; 469*cdf0e10cSrcweir rChar.height = pMetrics[ i ].adv; 470*cdf0e10cSrcweir if( table_vert[i] != table[i] ) 471*cdf0e10cSrcweir m_pMetrics->m_bVerticalSubstitutions[ nPage*256 + i ] = 1; 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir free( pMetrics ); 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir if( ! m_pMetrics->m_bKernPairsQueried ) 478*cdf0e10cSrcweir { 479*cdf0e10cSrcweir m_pMetrics->m_bKernPairsQueried = true; 480*cdf0e10cSrcweir // this is really a hack 481*cdf0e10cSrcweir // in future MapString/KernGlyphs should be used 482*cdf0e10cSrcweir // but vcl is not in a state where that could be used 483*cdf0e10cSrcweir // so currently we get kernpairs by accessing the raw data 484*cdf0e10cSrcweir struct _TrueTypeFont* pImplTTFont = (struct _TrueTypeFont*)pTTFont; 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir //----------------------------------------------------------------- 487*cdf0e10cSrcweir // Kerning: KT_MICROSOFT 488*cdf0e10cSrcweir //----------------------------------------------------------------- 489*cdf0e10cSrcweir if( pImplTTFont->nkern && pImplTTFont->kerntype == KT_MICROSOFT ) 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir // create a glyph -> character mapping 492*cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode > aGlyphMap; 493*cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode >::iterator left, right; 494*cdf0e10cSrcweir for( i = 21; i < 0xfffd; i++ ) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir sal_uInt16 nGlyph = MapChar( pTTFont, (sal_Unicode)i, 0 ); // kerning for horz only 497*cdf0e10cSrcweir if( nGlyph != 0 ) 498*cdf0e10cSrcweir aGlyphMap[ nGlyph ] = (sal_Unicode)i; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir KernPair aPair; 503*cdf0e10cSrcweir for( i = 0; i < (int)pImplTTFont->nkern; i++ ) 504*cdf0e10cSrcweir { 505*cdf0e10cSrcweir const sal_uInt8* pTable = pImplTTFont->kerntables[i]; 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir /*sal_uInt16 nVersion =*/ getUInt16BE( pTable ); 508*cdf0e10cSrcweir /*sal_uInt16 nLength =*/ getUInt16BE( pTable ); 509*cdf0e10cSrcweir sal_uInt16 nCoverage = getUInt16BE( pTable ); 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir aPair.kern_x = 0; 512*cdf0e10cSrcweir aPair.kern_y = 0; 513*cdf0e10cSrcweir switch( nCoverage >> 8 ) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir case 0: 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir sal_uInt16 nPairs = getUInt16BE( pTable ); 518*cdf0e10cSrcweir pTable += 6; 519*cdf0e10cSrcweir for( int n = 0; n < nPairs; n++ ) 520*cdf0e10cSrcweir { 521*cdf0e10cSrcweir sal_uInt16 nLeftGlyph = getUInt16BE( pTable ); 522*cdf0e10cSrcweir sal_uInt16 nRightGlyph = getUInt16BE( pTable ); 523*cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTable ); 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir left = aGlyphMap.find( nLeftGlyph ); 526*cdf0e10cSrcweir right = aGlyphMap.find( nRightGlyph ); 527*cdf0e10cSrcweir if( left != aGlyphMap.end() && right != aGlyphMap.end() ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir aPair.first = left->second; 530*cdf0e10cSrcweir aPair.second = right->second; 531*cdf0e10cSrcweir switch( nCoverage & 1 ) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir case 1: 534*cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 535*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 536*cdf0e10cSrcweir break; 537*cdf0e10cSrcweir case 0: 538*cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 539*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 540*cdf0e10cSrcweir break; 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir break; 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir case 2: 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir const sal_uInt8* pSubTable = pTable; 550*cdf0e10cSrcweir /*sal_uInt16 nRowWidth =*/ getUInt16BE( pTable ); 551*cdf0e10cSrcweir sal_uInt16 nOfLeft = getUInt16BE( pTable ); 552*cdf0e10cSrcweir sal_uInt16 nOfRight = getUInt16BE( pTable ); 553*cdf0e10cSrcweir /*sal_uInt16 nOfArray =*/ getUInt16BE( pTable ); 554*cdf0e10cSrcweir const sal_uInt8* pTmp = pSubTable + nOfLeft; 555*cdf0e10cSrcweir sal_uInt16 nFirstLeft = getUInt16BE( pTmp ); 556*cdf0e10cSrcweir sal_uInt16 nLastLeft = getUInt16BE( pTmp ) + nFirstLeft - 1; 557*cdf0e10cSrcweir pTmp = pSubTable + nOfRight; 558*cdf0e10cSrcweir sal_uInt16 nFirstRight = getUInt16BE( pTmp ); 559*cdf0e10cSrcweir sal_uInt16 nLastRight = getUInt16BE( pTmp ) + nFirstRight -1; 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir // int nPairs = (int)(nLastLeft-nFirstLeft+1)*(int)(nLastRight-nFirstRight+1); 562*cdf0e10cSrcweir for( aPair.first = nFirstLeft; aPair.first < nLastLeft; aPair.first++ ) 563*cdf0e10cSrcweir { 564*cdf0e10cSrcweir for( aPair.second = 0; aPair.second < nLastRight; aPair.second++ ) 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTmp ); 567*cdf0e10cSrcweir switch( nCoverage & 1 ) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir case 1: 570*cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 571*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 572*cdf0e10cSrcweir break; 573*cdf0e10cSrcweir case 0: 574*cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 575*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 576*cdf0e10cSrcweir break; 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir break; 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir } 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir //----------------------------------------------------------------- 587*cdf0e10cSrcweir // Kerning: KT_APPLE_NEW 588*cdf0e10cSrcweir //----------------------------------------------------------------- 589*cdf0e10cSrcweir if( pImplTTFont->nkern && pImplTTFont->kerntype == KT_APPLE_NEW ) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir // create a glyph -> character mapping 592*cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode > aGlyphMap; 593*cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode >::iterator left, right; 594*cdf0e10cSrcweir for( i = 21; i < 0xfffd; i++ ) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir sal_uInt16 nGlyph = MapChar( pTTFont, (sal_Unicode)i, 0 ); // kerning for horz only 597*cdf0e10cSrcweir if( nGlyph != 0 ) 598*cdf0e10cSrcweir aGlyphMap[ nGlyph ] = (sal_Unicode)i; 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir // Loop through each of the 'kern' subtables 602*cdf0e10cSrcweir KernPair aPair; 603*cdf0e10cSrcweir for( i = 0; (unsigned int)i < pImplTTFont->nkern; i++ ) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir const sal_uInt8* pTable = pImplTTFont->kerntables[i]; 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir /*sal_uInt32 nLength =*/ getUInt32BE( pTable ); 608*cdf0e10cSrcweir sal_uInt16 nCoverage = getUInt16BE( pTable ); 609*cdf0e10cSrcweir /*sal_uInt16 nTupleIndex =*/ getUInt16BE( pTable ); 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir // Get kerning type 612*cdf0e10cSrcweir // sal_Bool bKernVertical = nCoverage & 0x8000; 613*cdf0e10cSrcweir // sal_Bool bKernCrossStream = nCoverage & 0x4000; 614*cdf0e10cSrcweir // sal_Bool bKernVariation = nCoverage & 0x2000; 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir // Kerning sub-table format, 0 through 3 617*cdf0e10cSrcweir sal_uInt8 nSubTableFormat = nCoverage & 0x00FF; 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir aPair.kern_x = 0; 620*cdf0e10cSrcweir aPair.kern_y = 0; 621*cdf0e10cSrcweir switch( nSubTableFormat ) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir case 0: 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir // Grab the # of kern pairs but skip over the: 626*cdf0e10cSrcweir // searchRange 627*cdf0e10cSrcweir // entrySelector 628*cdf0e10cSrcweir // rangeShift 629*cdf0e10cSrcweir sal_uInt16 nPairs = getUInt16BE( pTable ); 630*cdf0e10cSrcweir pTable += 6; 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir for( int n = 0; n < nPairs; n++ ) 633*cdf0e10cSrcweir { 634*cdf0e10cSrcweir sal_uInt16 nLeftGlyph = getUInt16BE( pTable ); 635*cdf0e10cSrcweir sal_uInt16 nRightGlyph = getUInt16BE( pTable ); 636*cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTable ); 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir left = aGlyphMap.find( nLeftGlyph ); 639*cdf0e10cSrcweir right = aGlyphMap.find( nRightGlyph ); 640*cdf0e10cSrcweir if( left != aGlyphMap.end() && right != aGlyphMap.end() ) 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir aPair.first = left->second; 643*cdf0e10cSrcweir aPair.second = right->second; 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir // Only support horizontal kerning for now 646*cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 647*cdf0e10cSrcweir aPair.kern_y = 0; 648*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir /* switch( nCoverage & 1 ) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir case 1: 653*cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 654*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 655*cdf0e10cSrcweir break; 656*cdf0e10cSrcweir case 0: 657*cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 658*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 659*cdf0e10cSrcweir break; 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir */ 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir break; 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir case 2: 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir const sal_uInt8* pSubTable = pTable; 670*cdf0e10cSrcweir /*sal_uInt16 nRowWidth =*/ getUInt16BE( pTable ); 671*cdf0e10cSrcweir sal_uInt16 nOfLeft = getUInt16BE( pTable ); 672*cdf0e10cSrcweir sal_uInt16 nOfRight = getUInt16BE( pTable ); 673*cdf0e10cSrcweir /*sal_uInt16 nOfArray =*/ getUInt16BE( pTable ); 674*cdf0e10cSrcweir const sal_uInt8* pTmp = pSubTable + nOfLeft; 675*cdf0e10cSrcweir sal_uInt16 nFirstLeft = getUInt16BE( pTmp ); 676*cdf0e10cSrcweir sal_uInt16 nLastLeft = getUInt16BE( pTmp ) + nFirstLeft - 1; 677*cdf0e10cSrcweir pTmp = pSubTable + nOfRight; 678*cdf0e10cSrcweir sal_uInt16 nFirstRight = getUInt16BE( pTmp ); 679*cdf0e10cSrcweir sal_uInt16 nLastRight = getUInt16BE( pTmp ) + nFirstRight -1; 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir for( aPair.first = nFirstLeft; aPair.first < nLastLeft; aPair.first++ ) 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir for( aPair.second = 0; aPair.second < nLastRight; aPair.second++ ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTmp ); 686*cdf0e10cSrcweir switch( nCoverage & 1 ) 687*cdf0e10cSrcweir { 688*cdf0e10cSrcweir case 1: 689*cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 690*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 691*cdf0e10cSrcweir break; 692*cdf0e10cSrcweir case 0: 693*cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 694*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 695*cdf0e10cSrcweir break; 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir break; 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir default: 703*cdf0e10cSrcweir fprintf( stderr, "Found unsupported Apple-style kern subtable type %d.\n", nSubTableFormat ); 704*cdf0e10cSrcweir break; 705*cdf0e10cSrcweir } 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 710*cdf0e10cSrcweir fprintf( stderr, "found %d/%d kern pairs for %s\n", 711*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.size(), 712*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.size(), 713*cdf0e10cSrcweir OUStringToOString( pProvider->getString( ATOM_FAMILYNAME, m_nFamilyName ), RTL_TEXTENCODING_MS_1252 ).getStr() ); 714*cdf0e10cSrcweir #else 715*cdf0e10cSrcweir (void) pProvider; /* avoid warnings */ 716*cdf0e10cSrcweir #endif 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir CloseTTFont( pTTFont ); 720*cdf0e10cSrcweir bSuccess = true; 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir return bSuccess; 723*cdf0e10cSrcweir } 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir // ------------------------------------------------------------------------- 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir /* #i73387# There seem to be fonts with a rather unwell chosen family name 728*cdf0e10cSrcweir * consider e.g. "Helvetica Narrow" which defines its family as "Helvetica" 729*cdf0e10cSrcweir * It can really only be distinguished by its PSName and FullName. Both of 730*cdf0e10cSrcweir * which are not user presentable in OOo. So replace it by something sensible. 731*cdf0e10cSrcweir * 732*cdf0e10cSrcweir * If other fonts feature this behaviour, insert them to the map. 733*cdf0e10cSrcweir */ 734*cdf0e10cSrcweir static bool familyNameOverride( const OUString& i_rPSname, OUString& o_rFamilyName ) 735*cdf0e10cSrcweir { 736*cdf0e10cSrcweir static std::hash_map< OUString, OUString, OUStringHash > aPSNameToFamily( 16 ); 737*cdf0e10cSrcweir if( aPSNameToFamily.empty() ) // initialization 738*cdf0e10cSrcweir { 739*cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow" ) ) ] = 740*cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 741*cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-Bold" ) ) ] = 742*cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 743*cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-BoldOblique" ) ) ] = 744*cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 745*cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-Oblique" ) ) ] = 746*cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 747*cdf0e10cSrcweir } 748*cdf0e10cSrcweir std::hash_map<OUString,OUString,OUStringHash>::const_iterator it = 749*cdf0e10cSrcweir aPSNameToFamily.find( i_rPSname ); 750*cdf0e10cSrcweir bool bReplaced = (it != aPSNameToFamily.end() ); 751*cdf0e10cSrcweir if( bReplaced ) 752*cdf0e10cSrcweir o_rFamilyName = it->second; 753*cdf0e10cSrcweir return bReplaced; 754*cdf0e10cSrcweir }; 755*cdf0e10cSrcweir 756*cdf0e10cSrcweir bool PrintFontManager::PrintFont::readAfmMetrics( const OString& rFileName, MultiAtomProvider* pProvider, bool bFillEncodingvector, bool bOnlyGlobalAttributes ) 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir PrintFontManager& rManager( PrintFontManager::get() ); 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir int i; 761*cdf0e10cSrcweir FontInfo* pInfo = NULL; 762*cdf0e10cSrcweir parseFile( rFileName.getStr(), &pInfo, P_ALL ); 763*cdf0e10cSrcweir if( ! pInfo || ! pInfo->numOfChars ) 764*cdf0e10cSrcweir { 765*cdf0e10cSrcweir if( pInfo ) 766*cdf0e10cSrcweir freeFontInfo( pInfo ); 767*cdf0e10cSrcweir return false; 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir m_aEncodingVector.clear(); 771*cdf0e10cSrcweir // fill in global info 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir // PSName 774*cdf0e10cSrcweir OUString aPSName( OStringToOUString( pInfo->gfi->fontName, RTL_TEXTENCODING_ISO_8859_1 ) ); 775*cdf0e10cSrcweir m_nPSName = pProvider->getAtom( ATOM_PSNAME, aPSName, sal_True ); 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir // family name (if not already set) 778*cdf0e10cSrcweir OUString aFamily; 779*cdf0e10cSrcweir if( ! m_nFamilyName ) 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir aFamily = OStringToOUString( pInfo->gfi->familyName, RTL_TEXTENCODING_ISO_8859_1 ); 782*cdf0e10cSrcweir if( ! aFamily.getLength() ) 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir aFamily = OStringToOUString( pInfo->gfi->fontName, RTL_TEXTENCODING_ISO_8859_1 ); 785*cdf0e10cSrcweir sal_Int32 nIndex = 0; 786*cdf0e10cSrcweir aFamily = aFamily.getToken( 0, '-', nIndex ); 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir familyNameOverride( aPSName, aFamily ); 789*cdf0e10cSrcweir m_nFamilyName = pProvider->getAtom( ATOM_FAMILYNAME, aFamily, sal_True ); 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir else 792*cdf0e10cSrcweir aFamily = pProvider->getString( ATOM_FAMILYNAME, m_nFamilyName ); 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir // style name: if fullname begins with family name 795*cdf0e10cSrcweir // interpret the rest of fullname as style 796*cdf0e10cSrcweir if( ! m_aStyleName.getLength() && pInfo->gfi->fullName && *pInfo->gfi->fullName ) 797*cdf0e10cSrcweir { 798*cdf0e10cSrcweir OUString aFullName( OStringToOUString( pInfo->gfi->fullName, RTL_TEXTENCODING_ISO_8859_1 ) ); 799*cdf0e10cSrcweir if( aFullName.indexOf( aFamily ) == 0 ) 800*cdf0e10cSrcweir m_aStyleName = WhitespaceToSpace( aFullName.copy( aFamily.getLength() ) ); 801*cdf0e10cSrcweir } 802*cdf0e10cSrcweir 803*cdf0e10cSrcweir // italic 804*cdf0e10cSrcweir if( pInfo->gfi->italicAngle > 0 ) 805*cdf0e10cSrcweir m_eItalic = italic::Oblique; 806*cdf0e10cSrcweir else if( pInfo->gfi->italicAngle < 0 ) 807*cdf0e10cSrcweir m_eItalic = italic::Italic; 808*cdf0e10cSrcweir else 809*cdf0e10cSrcweir m_eItalic = italic::Upright; 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir // weight 812*cdf0e10cSrcweir ByteString aLowerWeight( pInfo->gfi->weight ); 813*cdf0e10cSrcweir aLowerWeight.ToLowerAscii(); 814*cdf0e10cSrcweir m_eWeight = parseWeight( aLowerWeight ); 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir // pitch 817*cdf0e10cSrcweir m_ePitch = pInfo->gfi->isFixedPitch ? pitch::Fixed : pitch::Variable; 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir // encoding - only set if unknown 820*cdf0e10cSrcweir int nAdobeEncoding = 0; 821*cdf0e10cSrcweir if( pInfo->gfi->encodingScheme ) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir if( !strcmp( pInfo->gfi->encodingScheme, "AdobeStandardEncoding" ) ) 824*cdf0e10cSrcweir nAdobeEncoding = 1; 825*cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "ISO10646-1" ) ) 826*cdf0e10cSrcweir { 827*cdf0e10cSrcweir nAdobeEncoding = 1; 828*cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_UNICODE; 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "Symbol") ) 831*cdf0e10cSrcweir nAdobeEncoding = 2; 832*cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "FontSpecific") ) 833*cdf0e10cSrcweir nAdobeEncoding = 3; 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 836*cdf0e10cSrcweir m_aEncoding = nAdobeEncoding == 1 ? 837*cdf0e10cSrcweir RTL_TEXTENCODING_ADOBE_STANDARD : RTL_TEXTENCODING_SYMBOL; 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir else if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 840*cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_ADOBE_STANDARD; 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir // try to parse the font name and decide wether it might be a 843*cdf0e10cSrcweir // japanese font. Who invented this PITA ? 844*cdf0e10cSrcweir OUString aPSNameLastToken( aPSName.copy( aPSName.lastIndexOf( '-' )+1 ) ); 845*cdf0e10cSrcweir if( ! aPSNameLastToken.compareToAscii( "H" ) || 846*cdf0e10cSrcweir ! aPSNameLastToken.compareToAscii( "V" ) ) 847*cdf0e10cSrcweir { 848*cdf0e10cSrcweir static const char* pEncs[] = 849*cdf0e10cSrcweir { 850*cdf0e10cSrcweir "EUC", 851*cdf0e10cSrcweir "RKSJ", 852*cdf0e10cSrcweir "SJ" 853*cdf0e10cSrcweir }; 854*cdf0e10cSrcweir static const rtl_TextEncoding aEncs[] = 855*cdf0e10cSrcweir { 856*cdf0e10cSrcweir RTL_TEXTENCODING_EUC_JP, 857*cdf0e10cSrcweir RTL_TEXTENCODING_SHIFT_JIS, 858*cdf0e10cSrcweir RTL_TEXTENCODING_JIS_X_0208 859*cdf0e10cSrcweir }; 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir for( unsigned int enc = 0; enc < sizeof( aEncs )/sizeof(aEncs[0]) && m_aEncoding == RTL_TEXTENCODING_DONTKNOW; enc++ ) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir sal_Int32 nIndex = 0, nOffset = 1; 864*cdf0e10cSrcweir do 865*cdf0e10cSrcweir { 866*cdf0e10cSrcweir OUString aToken( aPSName.getToken( nOffset, '-', nIndex ) ); 867*cdf0e10cSrcweir if( nIndex == -1 ) 868*cdf0e10cSrcweir break; 869*cdf0e10cSrcweir nOffset = 0; 870*cdf0e10cSrcweir if( ! aToken.compareToAscii( pEncs[enc] ) ) 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir m_aEncoding = aEncs[ enc ]; 873*cdf0e10cSrcweir m_bFontEncodingOnly = true; 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir } while( nIndex != -1 ); 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir // default is jis 879*cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 880*cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_JIS_X_0208; 881*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 882*cdf0e10cSrcweir fprintf( stderr, "Encoding %d for %s\n", m_aEncoding, pInfo->gfi->fontName ); 883*cdf0e10cSrcweir #endif 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir 886*cdf0e10cSrcweir // hack for GB encoded builtin fonts posing as FontSpecific 887*cdf0e10cSrcweir if( m_eType == fonttype::Builtin && ( nAdobeEncoding == 3 || nAdobeEncoding == 0 ) ) 888*cdf0e10cSrcweir { 889*cdf0e10cSrcweir int nLen = aFamily.getLength(); 890*cdf0e10cSrcweir if( nLen > 2 && 891*cdf0e10cSrcweir aFamily.getStr()[ nLen-2 ] == 'G' && 892*cdf0e10cSrcweir aFamily.getStr()[ nLen-1 ] == 'B' && 893*cdf0e10cSrcweir pInfo->numOfChars > 255 ) 894*cdf0e10cSrcweir { 895*cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_GBK; 896*cdf0e10cSrcweir m_bFontEncodingOnly = true; 897*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 898*cdf0e10cSrcweir fprintf( stderr, "found builtin font %s with GBK encoding\n", pInfo->gfi->fontName ); 899*cdf0e10cSrcweir #endif 900*cdf0e10cSrcweir } 901*cdf0e10cSrcweir } 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir // #i37313# check if Fontspecific is not rather some character encoding 904*cdf0e10cSrcweir if( nAdobeEncoding == 3 && m_aEncoding == RTL_TEXTENCODING_SYMBOL ) 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir bool bYFound = false; 907*cdf0e10cSrcweir bool bQFound = false; 908*cdf0e10cSrcweir CharMetricInfo* pChar = pInfo->cmi; 909*cdf0e10cSrcweir for( int j = 0; j < pInfo->numOfChars && ! (bYFound && bQFound); j++ ) 910*cdf0e10cSrcweir { 911*cdf0e10cSrcweir if( pChar[j].name ) 912*cdf0e10cSrcweir { 913*cdf0e10cSrcweir if( pChar[j].name[0] == 'Y' && pChar[j].name[1] == 0 ) 914*cdf0e10cSrcweir bYFound = true; 915*cdf0e10cSrcweir else if( pChar[j].name[0] == 'Q' && pChar[j].name[1] == 0 ) 916*cdf0e10cSrcweir bQFound = true; 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir } 919*cdf0e10cSrcweir if( bQFound && bYFound ) 920*cdf0e10cSrcweir { 921*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 922*cdf0e10cSrcweir fprintf( stderr, "setting FontSpecific font %s (file %s) to unicode\n", 923*cdf0e10cSrcweir pInfo->gfi->fontName, 924*cdf0e10cSrcweir rFileName.getStr() 925*cdf0e10cSrcweir ); 926*cdf0e10cSrcweir #endif 927*cdf0e10cSrcweir nAdobeEncoding = 4; 928*cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_UNICODE; 929*cdf0e10cSrcweir bFillEncodingvector = false; // will be filled anyway, don't do the work twice 930*cdf0e10cSrcweir } 931*cdf0e10cSrcweir } 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir // ascend 934*cdf0e10cSrcweir m_nAscend = pInfo->gfi->fontBBox.ury; 935*cdf0e10cSrcweir 936*cdf0e10cSrcweir // descend 937*cdf0e10cSrcweir // descends have opposite sign of our definition 938*cdf0e10cSrcweir m_nDescend = -pInfo->gfi->fontBBox.lly; 939*cdf0e10cSrcweir 940*cdf0e10cSrcweir // fallback to ascender, descender 941*cdf0e10cSrcweir // interesting: the BBox seems to describe Ascender and Descender better 942*cdf0e10cSrcweir // as we understand it 943*cdf0e10cSrcweir if( m_nAscend == 0 ) 944*cdf0e10cSrcweir m_nAscend = pInfo->gfi->ascender; 945*cdf0e10cSrcweir if( m_nDescend == 0) 946*cdf0e10cSrcweir m_nDescend = -pInfo->gfi->descender; 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir m_nLeading = m_nAscend + m_nDescend - 1000; 949*cdf0e10cSrcweir 950*cdf0e10cSrcweir if( m_pMetrics ) 951*cdf0e10cSrcweir delete m_pMetrics; 952*cdf0e10cSrcweir m_pMetrics = new PrintFontMetrics; 953*cdf0e10cSrcweir // mark all pages as queried (or clear if only global font info queiried) 954*cdf0e10cSrcweir memset( m_pMetrics->m_aPages, bOnlyGlobalAttributes ? 0 : 0xff, sizeof( m_pMetrics->m_aPages ) ); 955*cdf0e10cSrcweir 956*cdf0e10cSrcweir m_aGlobalMetricX.width = m_aGlobalMetricY.width = 957*cdf0e10cSrcweir pInfo->gfi->charwidth ? pInfo->gfi->charwidth : pInfo->gfi->fontBBox.urx; 958*cdf0e10cSrcweir m_aGlobalMetricX.height = m_aGlobalMetricY.height = 959*cdf0e10cSrcweir pInfo->gfi->capHeight ? pInfo->gfi->capHeight : pInfo->gfi->fontBBox.ury; 960*cdf0e10cSrcweir 961*cdf0e10cSrcweir m_nXMin = pInfo->gfi->fontBBox.llx; 962*cdf0e10cSrcweir m_nYMin = pInfo->gfi->fontBBox.lly; 963*cdf0e10cSrcweir m_nXMax = pInfo->gfi->fontBBox.urx; 964*cdf0e10cSrcweir m_nYMax = pInfo->gfi->fontBBox.ury; 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir if( bFillEncodingvector || !bOnlyGlobalAttributes ) 967*cdf0e10cSrcweir { 968*cdf0e10cSrcweir // fill in character metrics 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir // first transform the character codes to unicode 971*cdf0e10cSrcweir // note: this only works with single byte encodings 972*cdf0e10cSrcweir sal_Unicode* pUnicodes = (sal_Unicode*)alloca( pInfo->numOfChars * sizeof(sal_Unicode)); 973*cdf0e10cSrcweir CharMetricInfo* pChar = pInfo->cmi; 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir for( i = 0; i < pInfo->numOfChars; i++, pChar++ ) 976*cdf0e10cSrcweir { 977*cdf0e10cSrcweir if( nAdobeEncoding == 4 ) 978*cdf0e10cSrcweir { 979*cdf0e10cSrcweir if( pChar->name ) 980*cdf0e10cSrcweir { 981*cdf0e10cSrcweir pUnicodes[i] = 0; 982*cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 983*cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir if( *it != 0 ) 986*cdf0e10cSrcweir { 987*cdf0e10cSrcweir m_aEncodingVector[ *it ] = pChar->code; 988*cdf0e10cSrcweir if( pChar->code == -1 ) 989*cdf0e10cSrcweir m_aNonEncoded[ *it ] = pChar->name; 990*cdf0e10cSrcweir if( ! pUnicodes[i] ) // map the first 991*cdf0e10cSrcweir pUnicodes[i] = *it; 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir } 994*cdf0e10cSrcweir } 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir else if( pChar->code != -1 ) 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir if( nAdobeEncoding == 3 && m_aEncoding == RTL_TEXTENCODING_SYMBOL ) 999*cdf0e10cSrcweir { 1000*cdf0e10cSrcweir pUnicodes[i] = pChar->code + 0xf000; 1001*cdf0e10cSrcweir if( bFillEncodingvector ) 1002*cdf0e10cSrcweir m_aEncodingVector[ pUnicodes[i] ] = pChar->code; 1003*cdf0e10cSrcweir continue; 1004*cdf0e10cSrcweir } 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_UNICODE ) 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir pUnicodes[i] = (sal_Unicode)pChar->code; 1009*cdf0e10cSrcweir continue; 1010*cdf0e10cSrcweir } 1011*cdf0e10cSrcweir 1012*cdf0e10cSrcweir ByteString aTranslate; 1013*cdf0e10cSrcweir if( pChar->code & 0xff000000 ) 1014*cdf0e10cSrcweir aTranslate += (char)(pChar->code >> 24 ); 1015*cdf0e10cSrcweir if( pChar->code & 0xffff0000 ) 1016*cdf0e10cSrcweir aTranslate += (char)((pChar->code & 0x00ff0000) >> 16 ); 1017*cdf0e10cSrcweir if( pChar->code & 0xffffff00 ) 1018*cdf0e10cSrcweir aTranslate += (char)((pChar->code & 0x0000ff00) >> 8 ); 1019*cdf0e10cSrcweir aTranslate += (char)(pChar->code & 0xff); 1020*cdf0e10cSrcweir String aUni( aTranslate, m_aEncoding ); 1021*cdf0e10cSrcweir pUnicodes[i] = *aUni.GetBuffer(); 1022*cdf0e10cSrcweir } 1023*cdf0e10cSrcweir else 1024*cdf0e10cSrcweir pUnicodes[i] = 0; 1025*cdf0e10cSrcweir } 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir // now fill in the character metrics 1028*cdf0e10cSrcweir // parseAFM.cxx effectively only supports direction 0 (horizontal) 1029*cdf0e10cSrcweir pChar = pInfo->cmi; 1030*cdf0e10cSrcweir CharacterMetric aMetric; 1031*cdf0e10cSrcweir for( i = 0; i < pInfo->numOfChars; i++, pChar++ ) 1032*cdf0e10cSrcweir { 1033*cdf0e10cSrcweir if( pChar->code == -1 && ! pChar->name ) 1034*cdf0e10cSrcweir continue; 1035*cdf0e10cSrcweir 1036*cdf0e10cSrcweir if( bFillEncodingvector && pChar->name ) 1037*cdf0e10cSrcweir { 1038*cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1039*cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1040*cdf0e10cSrcweir { 1041*cdf0e10cSrcweir if( *it != 0 ) 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir m_aEncodingVector[ *it ] = pChar->code; 1044*cdf0e10cSrcweir if( pChar->code == -1 ) 1045*cdf0e10cSrcweir m_aNonEncoded[ *it ] = pChar->name; 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir } 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir aMetric.width = pChar->wx ? pChar->wx : pChar->charBBox.urx; 1051*cdf0e10cSrcweir aMetric.height = pChar->wy ? pChar->wy : pChar->charBBox.ury - pChar->charBBox.lly; 1052*cdf0e10cSrcweir if( aMetric.width == 0 && aMetric.height == 0 ) 1053*cdf0e10cSrcweir // guess something for e.g. space 1054*cdf0e10cSrcweir aMetric.width = m_aGlobalMetricX.width/4; 1055*cdf0e10cSrcweir 1056*cdf0e10cSrcweir if( ( nAdobeEncoding == 0 ) || 1057*cdf0e10cSrcweir ( ( nAdobeEncoding == 3 ) && ( m_aEncoding != RTL_TEXTENCODING_SYMBOL ) ) ) 1058*cdf0e10cSrcweir { 1059*cdf0e10cSrcweir if( pChar->code != -1 ) 1060*cdf0e10cSrcweir { 1061*cdf0e10cSrcweir m_pMetrics->m_aMetrics[ pUnicodes[i] ] = aMetric; 1062*cdf0e10cSrcweir if( bFillEncodingvector ) 1063*cdf0e10cSrcweir m_aEncodingVector[ pUnicodes[i] ] = pChar->code; 1064*cdf0e10cSrcweir } 1065*cdf0e10cSrcweir else if( pChar->name ) 1066*cdf0e10cSrcweir { 1067*cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1068*cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1069*cdf0e10cSrcweir { 1070*cdf0e10cSrcweir if( *it != 0 ) 1071*cdf0e10cSrcweir m_pMetrics->m_aMetrics[ *it ] = aMetric; 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir } 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir else if( nAdobeEncoding == 1 || nAdobeEncoding == 2 || nAdobeEncoding == 4) 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir if( pChar->name ) 1078*cdf0e10cSrcweir { 1079*cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1080*cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1081*cdf0e10cSrcweir { 1082*cdf0e10cSrcweir if( *it != 0 ) 1083*cdf0e10cSrcweir m_pMetrics->m_aMetrics[ *it ] = aMetric; 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir } 1086*cdf0e10cSrcweir else if( pChar->code != -1 ) 1087*cdf0e10cSrcweir { 1088*cdf0e10cSrcweir ::std::pair< ::std::hash_multimap< sal_uInt8, sal_Unicode >::const_iterator, 1089*cdf0e10cSrcweir ::std::hash_multimap< sal_uInt8, sal_Unicode >::const_iterator > 1090*cdf0e10cSrcweir aCodes = rManager.getUnicodeFromAdobeCode( pChar->code ); 1091*cdf0e10cSrcweir while( aCodes.first != aCodes.second ) 1092*cdf0e10cSrcweir { 1093*cdf0e10cSrcweir if( (*aCodes.first).second != 0 ) 1094*cdf0e10cSrcweir { 1095*cdf0e10cSrcweir m_pMetrics->m_aMetrics[ (*aCodes.first).second ] = aMetric; 1096*cdf0e10cSrcweir if( bFillEncodingvector ) 1097*cdf0e10cSrcweir m_aEncodingVector[ (*aCodes.first).second ] = pChar->code; 1098*cdf0e10cSrcweir } 1099*cdf0e10cSrcweir ++aCodes.first; 1100*cdf0e10cSrcweir } 1101*cdf0e10cSrcweir } 1102*cdf0e10cSrcweir } 1103*cdf0e10cSrcweir else if( nAdobeEncoding == 3 ) 1104*cdf0e10cSrcweir { 1105*cdf0e10cSrcweir if( pChar->code != -1 ) 1106*cdf0e10cSrcweir { 1107*cdf0e10cSrcweir sal_Unicode code = 0xf000 + pChar->code; 1108*cdf0e10cSrcweir m_pMetrics->m_aMetrics[ code ] = aMetric; 1109*cdf0e10cSrcweir // maybe should try to find the name in the convtabs ? 1110*cdf0e10cSrcweir if( bFillEncodingvector ) 1111*cdf0e10cSrcweir m_aEncodingVector[ code ] = pChar->code; 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir } 1115*cdf0e10cSrcweir 1116*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.clear(); 1117*cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.clear(); 1118*cdf0e10cSrcweir 1119*cdf0e10cSrcweir // now fill in the kern pairs 1120*cdf0e10cSrcweir // parseAFM.cxx effectively only supports direction 0 (horizontal) 1121*cdf0e10cSrcweir PairKernData* pKern = pInfo->pkd; 1122*cdf0e10cSrcweir KernPair aPair; 1123*cdf0e10cSrcweir for( i = 0; i < pInfo->numOfPairs; i++, pKern++ ) 1124*cdf0e10cSrcweir { 1125*cdf0e10cSrcweir // #i37703# broken kern table 1126*cdf0e10cSrcweir if( ! pKern->name1 || ! pKern->name2 ) 1127*cdf0e10cSrcweir continue; 1128*cdf0e10cSrcweir 1129*cdf0e10cSrcweir aPair.first = 0; 1130*cdf0e10cSrcweir aPair.second = 0; 1131*cdf0e10cSrcweir // currently we have to find the adobe character names 1132*cdf0e10cSrcweir // in the already parsed character metrics to find 1133*cdf0e10cSrcweir // the corresponding UCS2 code which is a bit dangerous 1134*cdf0e10cSrcweir // since the character names are not required 1135*cdf0e10cSrcweir // in the metric descriptions 1136*cdf0e10cSrcweir pChar = pInfo->cmi; 1137*cdf0e10cSrcweir for( int j = 0; 1138*cdf0e10cSrcweir j < pInfo->numOfChars && ( aPair.first == 0 || aPair.second == 0 ); 1139*cdf0e10cSrcweir j++, pChar++ ) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir if( pChar->code != -1 ) 1142*cdf0e10cSrcweir { 1143*cdf0e10cSrcweir if( ! strcmp( pKern->name1, pChar->name ? pChar->name : "" ) ) 1144*cdf0e10cSrcweir aPair.first = pUnicodes[ j ]; 1145*cdf0e10cSrcweir if( ! strcmp( pKern->name2, pChar->name ? pChar->name : "" ) ) 1146*cdf0e10cSrcweir aPair.second = pUnicodes[ j ]; 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir } 1149*cdf0e10cSrcweir if( aPair.first && aPair.second ) 1150*cdf0e10cSrcweir { 1151*cdf0e10cSrcweir aPair.kern_x = pKern->xamt; 1152*cdf0e10cSrcweir aPair.kern_y = pKern->yamt; 1153*cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 1154*cdf0e10cSrcweir } 1155*cdf0e10cSrcweir } 1156*cdf0e10cSrcweir m_pMetrics->m_bKernPairsQueried = true; 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir 1159*cdf0e10cSrcweir freeFontInfo( pInfo ); 1160*cdf0e10cSrcweir return true; 1161*cdf0e10cSrcweir } 1162*cdf0e10cSrcweir 1163*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1164*cdf0e10cSrcweir 1165*cdf0e10cSrcweir OString PrintFontManager::s_aEmptyOString; 1166*cdf0e10cSrcweir 1167*cdf0e10cSrcweir /* 1168*cdf0e10cSrcweir * one instance only 1169*cdf0e10cSrcweir */ 1170*cdf0e10cSrcweir PrintFontManager& PrintFontManager::get() 1171*cdf0e10cSrcweir { 1172*cdf0e10cSrcweir static PrintFontManager* theManager = NULL; 1173*cdf0e10cSrcweir if( ! theManager ) 1174*cdf0e10cSrcweir { 1175*cdf0e10cSrcweir theManager = new PrintFontManager(); 1176*cdf0e10cSrcweir theManager->initialize(); 1177*cdf0e10cSrcweir } 1178*cdf0e10cSrcweir return *theManager; 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1182*cdf0e10cSrcweir 1183*cdf0e10cSrcweir /* 1184*cdf0e10cSrcweir * the PrintFontManager 1185*cdf0e10cSrcweir */ 1186*cdf0e10cSrcweir 1187*cdf0e10cSrcweir PrintFontManager::PrintFontManager() : 1188*cdf0e10cSrcweir m_nNextFontID( 1 ), 1189*cdf0e10cSrcweir m_pAtoms( new MultiAtomProvider() ), 1190*cdf0e10cSrcweir m_nNextDirAtom( 1 ), 1191*cdf0e10cSrcweir m_pFontCache( NULL ), 1192*cdf0e10cSrcweir m_bFontconfigSuccess( false ) 1193*cdf0e10cSrcweir { 1194*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir m_aUnicodeToAdobename.insert( ::std::hash_multimap< sal_Unicode, ::rtl::OString >::value_type( aAdobeCodes[i].aUnicode, aAdobeCodes[i].pAdobename ) ); 1197*cdf0e10cSrcweir m_aAdobenameToUnicode.insert( ::std::hash_multimap< ::rtl::OString, sal_Unicode, ::rtl::OStringHash >::value_type( aAdobeCodes[i].pAdobename, aAdobeCodes[i].aUnicode ) ); 1198*cdf0e10cSrcweir if( aAdobeCodes[i].aAdobeStandardCode ) 1199*cdf0e10cSrcweir { 1200*cdf0e10cSrcweir m_aUnicodeToAdobecode.insert( ::std::hash_multimap< sal_Unicode, sal_uInt8 >::value_type( aAdobeCodes[i].aUnicode, aAdobeCodes[i].aAdobeStandardCode ) ); 1201*cdf0e10cSrcweir m_aAdobecodeToUnicode.insert( ::std::hash_multimap< sal_uInt8, sal_Unicode >::value_type( aAdobeCodes[i].aAdobeStandardCode, aAdobeCodes[i].aUnicode ) ); 1202*cdf0e10cSrcweir } 1203*cdf0e10cSrcweir #if 0 1204*cdf0e10cSrcweir m_aUnicodeToAdobename[ aAdobeCodes[i].aUnicode ] = aAdobeCodes[i].pAdobename; 1205*cdf0e10cSrcweir m_aAdobenameToUnicode[ aAdobeCodes[i].pAdobename ] = aAdobeCodes[i].aUnicode; 1206*cdf0e10cSrcweir if( aAdobeCodes[i].aAdobeStandardCode ) 1207*cdf0e10cSrcweir { 1208*cdf0e10cSrcweir m_aUnicodeToAdobecode[ aAdobeCodes[i].aUnicode ] = aAdobeCodes[i].aAdobeStandardCode; 1209*cdf0e10cSrcweir m_aAdobecodeToUnicode[ aAdobeCodes[i].aAdobeStandardCode ] = aAdobeCodes[i].aUnicode; 1210*cdf0e10cSrcweir } 1211*cdf0e10cSrcweir #endif 1212*cdf0e10cSrcweir } 1213*cdf0e10cSrcweir } 1214*cdf0e10cSrcweir 1215*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1216*cdf0e10cSrcweir 1217*cdf0e10cSrcweir PrintFontManager::~PrintFontManager() 1218*cdf0e10cSrcweir { 1219*cdf0e10cSrcweir deinitFontconfig(); 1220*cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 1221*cdf0e10cSrcweir delete (*it).second; 1222*cdf0e10cSrcweir delete m_pAtoms; 1223*cdf0e10cSrcweir if( m_pFontCache ) 1224*cdf0e10cSrcweir delete m_pFontCache; 1225*cdf0e10cSrcweir } 1226*cdf0e10cSrcweir 1227*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir const OString& PrintFontManager::getDirectory( int nAtom ) const 1230*cdf0e10cSrcweir { 1231*cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it( m_aAtomToDir.find( nAtom ) ); 1232*cdf0e10cSrcweir return it != m_aAtomToDir.end() ? it->second : s_aEmptyOString; 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir 1235*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1236*cdf0e10cSrcweir 1237*cdf0e10cSrcweir int PrintFontManager::getDirectoryAtom( const OString& rDirectory, bool bCreate ) 1238*cdf0e10cSrcweir { 1239*cdf0e10cSrcweir int nAtom = 0; 1240*cdf0e10cSrcweir ::std::hash_map< OString, int, OStringHash >::const_iterator it 1241*cdf0e10cSrcweir ( m_aDirToAtom.find( rDirectory ) ); 1242*cdf0e10cSrcweir if( it != m_aDirToAtom.end() ) 1243*cdf0e10cSrcweir nAtom = it->second; 1244*cdf0e10cSrcweir else if( bCreate ) 1245*cdf0e10cSrcweir { 1246*cdf0e10cSrcweir nAtom = m_nNextDirAtom++; 1247*cdf0e10cSrcweir m_aDirToAtom[ rDirectory ] = nAtom; 1248*cdf0e10cSrcweir m_aAtomToDir[ nAtom ] = rDirectory; 1249*cdf0e10cSrcweir } 1250*cdf0e10cSrcweir return nAtom; 1251*cdf0e10cSrcweir } 1252*cdf0e10cSrcweir 1253*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1254*cdf0e10cSrcweir 1255*cdf0e10cSrcweir int PrintFontManager::addFontFile( const ::rtl::OString& rFileName, int /*nFaceNum*/ ) 1256*cdf0e10cSrcweir { 1257*cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 1258*cdf0e10cSrcweir INetURLObject aPath( OStringToOUString( rFileName, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 1259*cdf0e10cSrcweir OString aName( OUStringToOString( aPath.GetName(), aEncoding ) ); 1260*cdf0e10cSrcweir OString aDir( OUStringToOString( aPath.GetPath(), aEncoding ) ); 1261*cdf0e10cSrcweir 1262*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 1263*cdf0e10cSrcweir fontID nFontId = findFontFileID( nDirID, aName ); 1264*cdf0e10cSrcweir if( !nFontId ) 1265*cdf0e10cSrcweir { 1266*cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 1267*cdf0e10cSrcweir if( analyzeFontFile( nDirID, aName, ::std::list<OString>(), aNewFonts ) ) 1268*cdf0e10cSrcweir { 1269*cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); 1270*cdf0e10cSrcweir it != aNewFonts.end(); ++it ) 1271*cdf0e10cSrcweir { 1272*cdf0e10cSrcweir m_aFonts[ nFontId = m_nNextFontID++ ] = *it; 1273*cdf0e10cSrcweir m_aFontFileToFontID[ aName ].insert( nFontId ); 1274*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, true ); 1275*cdf0e10cSrcweir } 1276*cdf0e10cSrcweir } 1277*cdf0e10cSrcweir } 1278*cdf0e10cSrcweir return nFontId; 1279*cdf0e10cSrcweir } 1280*cdf0e10cSrcweir 1281*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1282*cdf0e10cSrcweir 1283*cdf0e10cSrcweir bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, const ::std::list<OString>& rXLFDs, ::std::list< PrintFontManager::PrintFont* >& rNewFonts ) const 1284*cdf0e10cSrcweir { 1285*cdf0e10cSrcweir rNewFonts.clear(); 1286*cdf0e10cSrcweir 1287*cdf0e10cSrcweir OString aDir( getDirectory( nDirID ) ); 1288*cdf0e10cSrcweir 1289*cdf0e10cSrcweir OString aFullPath( aDir ); 1290*cdf0e10cSrcweir aFullPath += "/"; 1291*cdf0e10cSrcweir aFullPath += rFontFile; 1292*cdf0e10cSrcweir 1293*cdf0e10cSrcweir // #i1872# reject unreadable files 1294*cdf0e10cSrcweir if( access( aFullPath.getStr(), R_OK ) ) 1295*cdf0e10cSrcweir return false; 1296*cdf0e10cSrcweir 1297*cdf0e10cSrcweir ByteString aExt( rFontFile.copy( rFontFile.lastIndexOf( '.' )+1 ) ); 1298*cdf0e10cSrcweir if( aExt.EqualsIgnoreCaseAscii( "pfb" ) || aExt.EqualsIgnoreCaseAscii( "pfa" ) ) 1299*cdf0e10cSrcweir { 1300*cdf0e10cSrcweir // check for corresponding afm metric 1301*cdf0e10cSrcweir // first look for an adjacent file 1302*cdf0e10cSrcweir static const char* pSuffix[] = { ".afm", ".AFM" }; 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(pSuffix)/sizeof(pSuffix[0]); i++ ) 1305*cdf0e10cSrcweir { 1306*cdf0e10cSrcweir ByteString aName( rFontFile ); 1307*cdf0e10cSrcweir aName.Erase( aName.Len()-4 ); 1308*cdf0e10cSrcweir aName.Append( pSuffix[i] ); 1309*cdf0e10cSrcweir 1310*cdf0e10cSrcweir ByteString aFilePath( aDir ); 1311*cdf0e10cSrcweir aFilePath.Append( '/' ); 1312*cdf0e10cSrcweir aFilePath.Append( aName ); 1313*cdf0e10cSrcweir 1314*cdf0e10cSrcweir ByteString aAfmFile; 1315*cdf0e10cSrcweir if( access( aFilePath.GetBuffer(), R_OK ) ) 1316*cdf0e10cSrcweir { 1317*cdf0e10cSrcweir // try in subdirectory afm instead 1318*cdf0e10cSrcweir aFilePath = aDir; 1319*cdf0e10cSrcweir aFilePath.Append( "/afm/" ); 1320*cdf0e10cSrcweir aFilePath.Append( aName ); 1321*cdf0e10cSrcweir 1322*cdf0e10cSrcweir if( ! access( aFilePath.GetBuffer(), R_OK ) ) 1323*cdf0e10cSrcweir { 1324*cdf0e10cSrcweir aAfmFile = "afm/"; 1325*cdf0e10cSrcweir aAfmFile += aName; 1326*cdf0e10cSrcweir } 1327*cdf0e10cSrcweir } 1328*cdf0e10cSrcweir else 1329*cdf0e10cSrcweir aAfmFile = aName; 1330*cdf0e10cSrcweir 1331*cdf0e10cSrcweir if( aAfmFile.Len() ) 1332*cdf0e10cSrcweir { 1333*cdf0e10cSrcweir Type1FontFile* pFont = new Type1FontFile(); 1334*cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1337*cdf0e10cSrcweir pFont->m_aMetricFile = aAfmFile; 1338*cdf0e10cSrcweir 1339*cdf0e10cSrcweir if( ! pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ) ) 1340*cdf0e10cSrcweir { 1341*cdf0e10cSrcweir delete pFont; 1342*cdf0e10cSrcweir pFont = NULL; 1343*cdf0e10cSrcweir } 1344*cdf0e10cSrcweir if( pFont && rXLFDs.size() ) 1345*cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1346*cdf0e10cSrcweir if( pFont ) 1347*cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1348*cdf0e10cSrcweir break; 1349*cdf0e10cSrcweir } 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir } 1352*cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "afm" ) ) 1353*cdf0e10cSrcweir { 1354*cdf0e10cSrcweir ByteString aFilePath( aDir ); 1355*cdf0e10cSrcweir aFilePath.Append( '/' ); 1356*cdf0e10cSrcweir aFilePath.Append( ByteString( rFontFile ) ); 1357*cdf0e10cSrcweir BuiltinFont* pFont = new BuiltinFont(); 1358*cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1359*cdf0e10cSrcweir pFont->m_aMetricFile = rFontFile; 1360*cdf0e10cSrcweir if( pFont->readAfmMetrics( aFilePath, m_pAtoms, false, true ) ) 1361*cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1362*cdf0e10cSrcweir else 1363*cdf0e10cSrcweir delete pFont; 1364*cdf0e10cSrcweir } 1365*cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "ttf" ) 1366*cdf0e10cSrcweir || aExt.EqualsIgnoreCaseAscii( "tte" ) // #i33947# for Gaiji support 1367*cdf0e10cSrcweir || aExt.EqualsIgnoreCaseAscii( "otf" ) ) // check for TTF- and PS-OpenType too 1368*cdf0e10cSrcweir { 1369*cdf0e10cSrcweir TrueTypeFontFile* pFont = new TrueTypeFontFile(); 1370*cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1371*cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1372*cdf0e10cSrcweir pFont->m_nCollectionEntry = -1; 1373*cdf0e10cSrcweir 1374*cdf0e10cSrcweir if( rXLFDs.size() ) 1375*cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1376*cdf0e10cSrcweir // need to read the font anyway to get aliases inside the font file 1377*cdf0e10cSrcweir if( ! analyzeTrueTypeFile( pFont ) ) 1378*cdf0e10cSrcweir { 1379*cdf0e10cSrcweir delete pFont; 1380*cdf0e10cSrcweir pFont = NULL; 1381*cdf0e10cSrcweir } 1382*cdf0e10cSrcweir else 1383*cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1384*cdf0e10cSrcweir } 1385*cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "ttc" ) ) 1386*cdf0e10cSrcweir { 1387*cdf0e10cSrcweir // get number of ttc entries 1388*cdf0e10cSrcweir int nLength = CountTTCFonts( aFullPath.getStr() ); 1389*cdf0e10cSrcweir if( nLength ) 1390*cdf0e10cSrcweir { 1391*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1392*cdf0e10cSrcweir fprintf( stderr, "%s contains %d fonts\n", aFullPath.getStr(), nLength ); 1393*cdf0e10cSrcweir #endif 1394*cdf0e10cSrcweir for( int i = 0; i < nLength; i++ ) 1395*cdf0e10cSrcweir { 1396*cdf0e10cSrcweir TrueTypeFontFile* pFont = new TrueTypeFontFile(); 1397*cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1398*cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1399*cdf0e10cSrcweir pFont->m_nCollectionEntry = i; 1400*cdf0e10cSrcweir if( nLength == 1 ) 1401*cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1402*cdf0e10cSrcweir if( ! analyzeTrueTypeFile( pFont ) ) 1403*cdf0e10cSrcweir { 1404*cdf0e10cSrcweir delete pFont; 1405*cdf0e10cSrcweir pFont = NULL; 1406*cdf0e10cSrcweir } 1407*cdf0e10cSrcweir else 1408*cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1409*cdf0e10cSrcweir } 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1412*cdf0e10cSrcweir else 1413*cdf0e10cSrcweir fprintf( stderr, "CountTTCFonts( \"%s/%s\" ) failed\n", getDirectory(nDirID).getStr(), rFontFile.getStr() ); 1414*cdf0e10cSrcweir #endif 1415*cdf0e10cSrcweir } 1416*cdf0e10cSrcweir return ! rNewFonts.empty(); 1417*cdf0e10cSrcweir } 1418*cdf0e10cSrcweir 1419*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1420*cdf0e10cSrcweir 1421*cdf0e10cSrcweir fontID PrintFontManager::findFontBuiltinID( int nPSNameAtom ) const 1422*cdf0e10cSrcweir { 1423*cdf0e10cSrcweir fontID nID = 0; 1424*cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator it; 1425*cdf0e10cSrcweir for( it = m_aFonts.begin(); nID == 0 && it != m_aFonts.end(); ++it ) 1426*cdf0e10cSrcweir { 1427*cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin && 1428*cdf0e10cSrcweir it->second->m_nPSName == nPSNameAtom ) 1429*cdf0e10cSrcweir nID = it->first; 1430*cdf0e10cSrcweir } 1431*cdf0e10cSrcweir return nID; 1432*cdf0e10cSrcweir } 1433*cdf0e10cSrcweir 1434*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1435*cdf0e10cSrcweir 1436*cdf0e10cSrcweir fontID PrintFontManager::findFontFileID( int nDirID, const OString& rFontFile ) const 1437*cdf0e10cSrcweir { 1438*cdf0e10cSrcweir fontID nID = 0; 1439*cdf0e10cSrcweir 1440*cdf0e10cSrcweir ::std::hash_map< OString, ::std::set< fontID >, OStringHash >::const_iterator set_it = m_aFontFileToFontID.find( rFontFile ); 1441*cdf0e10cSrcweir if( set_it != m_aFontFileToFontID.end() ) 1442*cdf0e10cSrcweir { 1443*cdf0e10cSrcweir for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end() && ! nID; ++font_it ) 1444*cdf0e10cSrcweir { 1445*cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); 1446*cdf0e10cSrcweir if( it != m_aFonts.end() ) 1447*cdf0e10cSrcweir { 1448*cdf0e10cSrcweir switch( it->second->m_eType ) 1449*cdf0e10cSrcweir { 1450*cdf0e10cSrcweir case fonttype::Type1: 1451*cdf0e10cSrcweir { 1452*cdf0e10cSrcweir Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); 1453*cdf0e10cSrcweir if( pFont->m_nDirectory == nDirID && 1454*cdf0e10cSrcweir pFont->m_aFontFile == rFontFile ) 1455*cdf0e10cSrcweir nID = it->first; 1456*cdf0e10cSrcweir } 1457*cdf0e10cSrcweir break; 1458*cdf0e10cSrcweir case fonttype::TrueType: 1459*cdf0e10cSrcweir { 1460*cdf0e10cSrcweir TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); 1461*cdf0e10cSrcweir if( pFont->m_nDirectory == nDirID && 1462*cdf0e10cSrcweir pFont->m_aFontFile == rFontFile ) 1463*cdf0e10cSrcweir nID = it->first; 1464*cdf0e10cSrcweir } 1465*cdf0e10cSrcweir break; 1466*cdf0e10cSrcweir case fonttype::Builtin: 1467*cdf0e10cSrcweir if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && 1468*cdf0e10cSrcweir static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) 1469*cdf0e10cSrcweir nID = it->first; 1470*cdf0e10cSrcweir break; 1471*cdf0e10cSrcweir default: 1472*cdf0e10cSrcweir break; 1473*cdf0e10cSrcweir } 1474*cdf0e10cSrcweir } 1475*cdf0e10cSrcweir } 1476*cdf0e10cSrcweir } 1477*cdf0e10cSrcweir return nID; 1478*cdf0e10cSrcweir } 1479*cdf0e10cSrcweir 1480*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1481*cdf0e10cSrcweir 1482*cdf0e10cSrcweir bool PrintFontManager::parseXLFD( const OString& rXLFD, XLFDEntry& rEntry ) 1483*cdf0e10cSrcweir { 1484*cdf0e10cSrcweir sal_Int32 nIndex = 0; 1485*cdf0e10cSrcweir OString aFoundry = WhitespaceToSpace( rXLFD.getToken( 1, '-', nIndex ) ); 1486*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1487*cdf0e10cSrcweir OString aFamilyXLFD = WhitespaceToSpace( rXLFD.getToken( 0, '-', nIndex ) ); 1488*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1489*cdf0e10cSrcweir OString aWeight = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1490*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1491*cdf0e10cSrcweir OString aSlant = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1492*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1493*cdf0e10cSrcweir OString aWidth = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1494*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1495*cdf0e10cSrcweir OString aAddStyle = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1496*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1497*cdf0e10cSrcweir OString aPitch = rXLFD.getToken( 4, '-', nIndex ).toAsciiLowerCase(); 1498*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1499*cdf0e10cSrcweir OString aRegEnc = WhitespaceToSpace( rXLFD.getToken( 1, '-', nIndex ).toAsciiLowerCase() ); 1500*cdf0e10cSrcweir if( nIndex < 0 ) return false; 1501*cdf0e10cSrcweir OString aEnc = WhitespaceToSpace( rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase() ); 1502*cdf0e10cSrcweir 1503*cdf0e10cSrcweir // capitalize words 1504*cdf0e10cSrcweir sal_Int32 nFamIndex = 0; 1505*cdf0e10cSrcweir OStringBuffer aFamilyName; 1506*cdf0e10cSrcweir while( nFamIndex >= 0 ) 1507*cdf0e10cSrcweir { 1508*cdf0e10cSrcweir OString aToken = aFamilyXLFD.getToken( 0, ' ', nFamIndex ); 1509*cdf0e10cSrcweir sal_Char aFirst = aToken.toChar(); 1510*cdf0e10cSrcweir if( aFirst >= 'a' && aFirst <= 'z' ) 1511*cdf0e10cSrcweir aFirst = aFirst - 'a' + 'A'; 1512*cdf0e10cSrcweir OStringBuffer aNewToken( aToken.getLength() ); 1513*cdf0e10cSrcweir aNewToken.append( aToken ); 1514*cdf0e10cSrcweir aNewToken.setCharAt( 0, aFirst ); 1515*cdf0e10cSrcweir if( aFamilyName.getLength() > 0 ) 1516*cdf0e10cSrcweir aFamilyName.append( ' ' ); 1517*cdf0e10cSrcweir aFamilyName.append( aNewToken.makeStringAndClear() ); 1518*cdf0e10cSrcweir } 1519*cdf0e10cSrcweir 1520*cdf0e10cSrcweir rEntry.aFoundry = aFoundry; 1521*cdf0e10cSrcweir rEntry.aFamily = aFamilyName.makeStringAndClear(); 1522*cdf0e10cSrcweir rEntry.aAddStyle = aAddStyle; 1523*cdf0e10cSrcweir // evaluate weight 1524*cdf0e10cSrcweir rEntry.eWeight = parseWeight( aWeight ); 1525*cdf0e10cSrcweir // evaluate slant 1526*cdf0e10cSrcweir rEntry.eItalic = parseItalic( aSlant ); 1527*cdf0e10cSrcweir // evaluate width 1528*cdf0e10cSrcweir rEntry.eWidth = parseWidth( aWidth ); 1529*cdf0e10cSrcweir 1530*cdf0e10cSrcweir // evaluate pitch 1531*cdf0e10cSrcweir if( aPitch.toChar() == 'c' || aPitch.toChar() == 'm' ) 1532*cdf0e10cSrcweir rEntry.ePitch = pitch::Fixed; 1533*cdf0e10cSrcweir else 1534*cdf0e10cSrcweir rEntry.ePitch = pitch::Variable; 1535*cdf0e10cSrcweir 1536*cdf0e10cSrcweir OString aToken = aEnc.toAsciiLowerCase(); 1537*cdf0e10cSrcweir // get encoding 1538*cdf0e10cSrcweir if( aAddStyle.indexOf( "symbol" ) != -1 ) 1539*cdf0e10cSrcweir rEntry.aEncoding = RTL_TEXTENCODING_SYMBOL; 1540*cdf0e10cSrcweir else 1541*cdf0e10cSrcweir { 1542*cdf0e10cSrcweir if( aToken.equals( "symbol" ) ) 1543*cdf0e10cSrcweir rEntry.aEncoding = RTL_TEXTENCODING_SYMBOL; 1544*cdf0e10cSrcweir else 1545*cdf0e10cSrcweir { 1546*cdf0e10cSrcweir OStringBuffer aCharset( aRegEnc.getLength() + aEnc.getLength() + 1 ); 1547*cdf0e10cSrcweir aCharset.append( aRegEnc ); 1548*cdf0e10cSrcweir aCharset.append( '-' ); 1549*cdf0e10cSrcweir aCharset.append( aEnc ); 1550*cdf0e10cSrcweir rEntry.aEncoding = rtl_getTextEncodingFromUnixCharset( aCharset.getStr() ); 1551*cdf0e10cSrcweir } 1552*cdf0e10cSrcweir } 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir // set correct mask flags 1555*cdf0e10cSrcweir rEntry.nMask = 0; 1556*cdf0e10cSrcweir if( rEntry.aFoundry != "*" ) rEntry.nMask |= XLFDEntry::MaskFoundry; 1557*cdf0e10cSrcweir if( rEntry.aFamily != "*" ) rEntry.nMask |= XLFDEntry::MaskFamily; 1558*cdf0e10cSrcweir if( rEntry.aAddStyle != "*" ) rEntry.nMask |= XLFDEntry::MaskAddStyle; 1559*cdf0e10cSrcweir if( aWeight != "*" ) rEntry.nMask |= XLFDEntry::MaskWeight; 1560*cdf0e10cSrcweir if( aSlant != "*" ) rEntry.nMask |= XLFDEntry::MaskItalic; 1561*cdf0e10cSrcweir if( aWidth != "*" ) rEntry.nMask |= XLFDEntry::MaskWidth; 1562*cdf0e10cSrcweir if( aPitch != "*" ) rEntry.nMask |= XLFDEntry::MaskPitch; 1563*cdf0e10cSrcweir if( aRegEnc != "*" && aEnc != "*" ) rEntry.nMask |= XLFDEntry::MaskEncoding; 1564*cdf0e10cSrcweir 1565*cdf0e10cSrcweir return true; 1566*cdf0e10cSrcweir } 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1569*cdf0e10cSrcweir 1570*cdf0e10cSrcweir void PrintFontManager::parseXLFD_appendAliases( const std::list< OString >& rXLFDs, std::list< XLFDEntry >& rEntries ) const 1571*cdf0e10cSrcweir { 1572*cdf0e10cSrcweir for( std::list< OString >::const_iterator it = rXLFDs.begin(); it != rXLFDs.end(); ++it ) 1573*cdf0e10cSrcweir { 1574*cdf0e10cSrcweir XLFDEntry aEntry; 1575*cdf0e10cSrcweir if( ! parseXLFD(*it, aEntry) ) 1576*cdf0e10cSrcweir continue; 1577*cdf0e10cSrcweir rEntries.push_back( aEntry ); 1578*cdf0e10cSrcweir std::map< XLFDEntry, std::list< XLFDEntry > >::const_iterator alias_it = 1579*cdf0e10cSrcweir m_aXLFD_Aliases.find( aEntry ); 1580*cdf0e10cSrcweir if( alias_it != m_aXLFD_Aliases.end() ) 1581*cdf0e10cSrcweir { 1582*cdf0e10cSrcweir rEntries.insert( rEntries.end(), alias_it->second.begin(), alias_it->second.end() ); 1583*cdf0e10cSrcweir } 1584*cdf0e10cSrcweir } 1585*cdf0e10cSrcweir } 1586*cdf0e10cSrcweir 1587*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1588*cdf0e10cSrcweir 1589*cdf0e10cSrcweir void PrintFontManager::getFontAttributesFromXLFD( PrintFont* pFont, const std::list< OString >& rXLFDs ) const 1590*cdf0e10cSrcweir { 1591*cdf0e10cSrcweir bool bFamilyName = false; 1592*cdf0e10cSrcweir 1593*cdf0e10cSrcweir std::list< XLFDEntry > aXLFDs; 1594*cdf0e10cSrcweir 1595*cdf0e10cSrcweir parseXLFD_appendAliases( rXLFDs, aXLFDs ); 1596*cdf0e10cSrcweir 1597*cdf0e10cSrcweir for( std::list< XLFDEntry >::const_iterator it = aXLFDs.begin(); 1598*cdf0e10cSrcweir it != aXLFDs.end(); ++it ) 1599*cdf0e10cSrcweir { 1600*cdf0e10cSrcweir // set family name or alias 1601*cdf0e10cSrcweir int nFam = 1602*cdf0e10cSrcweir m_pAtoms->getAtom( ATOM_FAMILYNAME, 1603*cdf0e10cSrcweir OStringToOUString( it->aFamily, it->aAddStyle.indexOf( "utf8" ) != -1 ? RTL_TEXTENCODING_UTF8 : RTL_TEXTENCODING_ISO_8859_1 ), 1604*cdf0e10cSrcweir sal_True ); 1605*cdf0e10cSrcweir if( ! bFamilyName ) 1606*cdf0e10cSrcweir { 1607*cdf0e10cSrcweir bFamilyName = true; 1608*cdf0e10cSrcweir pFont->m_nFamilyName = nFam; 1609*cdf0e10cSrcweir switch( pFont->m_eType ) 1610*cdf0e10cSrcweir { 1611*cdf0e10cSrcweir case fonttype::Type1: 1612*cdf0e10cSrcweir static_cast<Type1FontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1613*cdf0e10cSrcweir break; 1614*cdf0e10cSrcweir case fonttype::TrueType: 1615*cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1616*cdf0e10cSrcweir break; 1617*cdf0e10cSrcweir default: 1618*cdf0e10cSrcweir break; 1619*cdf0e10cSrcweir } 1620*cdf0e10cSrcweir } 1621*cdf0e10cSrcweir else 1622*cdf0e10cSrcweir { 1623*cdf0e10cSrcweir // make sure that aliases are unique 1624*cdf0e10cSrcweir if( nFam != pFont->m_nFamilyName ) 1625*cdf0e10cSrcweir { 1626*cdf0e10cSrcweir std::list< int >::const_iterator al_it; 1627*cdf0e10cSrcweir for( al_it = pFont->m_aAliases.begin(); al_it != pFont->m_aAliases.end() && *al_it != nFam; ++al_it ) 1628*cdf0e10cSrcweir ; 1629*cdf0e10cSrcweir if( al_it == pFont->m_aAliases.end() ) 1630*cdf0e10cSrcweir pFont->m_aAliases.push_back( nFam ); 1631*cdf0e10cSrcweir 1632*cdf0e10cSrcweir } 1633*cdf0e10cSrcweir // for the rest of the attributes there can only be one value; 1634*cdf0e10cSrcweir // we'll trust the first one 1635*cdf0e10cSrcweir continue; 1636*cdf0e10cSrcweir } 1637*cdf0e10cSrcweir 1638*cdf0e10cSrcweir // fill in weight 1639*cdf0e10cSrcweir pFont->m_eWeight = it->eWeight; 1640*cdf0e10cSrcweir // fill in slant 1641*cdf0e10cSrcweir pFont->m_eItalic = it->eItalic; 1642*cdf0e10cSrcweir // fill in width 1643*cdf0e10cSrcweir pFont->m_eWidth = it->eWidth; 1644*cdf0e10cSrcweir // fill in pitch 1645*cdf0e10cSrcweir pFont->m_ePitch = it->ePitch; 1646*cdf0e10cSrcweir // fill in encoding 1647*cdf0e10cSrcweir pFont->m_aEncoding = it->aEncoding; 1648*cdf0e10cSrcweir } 1649*cdf0e10cSrcweir 1650*cdf0e10cSrcweir // handle iso8859-1 as ms1252 to fill the "gap" starting at 0x80 1651*cdf0e10cSrcweir if( pFont->m_aEncoding == RTL_TEXTENCODING_ISO_8859_1 ) 1652*cdf0e10cSrcweir pFont->m_aEncoding = RTL_TEXTENCODING_MS_1252; 1653*cdf0e10cSrcweir if( rXLFDs.begin() != rXLFDs.end() ) 1654*cdf0e10cSrcweir { 1655*cdf0e10cSrcweir switch( pFont->m_eType ) 1656*cdf0e10cSrcweir { 1657*cdf0e10cSrcweir case fonttype::Type1: 1658*cdf0e10cSrcweir static_cast<Type1FontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1659*cdf0e10cSrcweir break; 1660*cdf0e10cSrcweir case fonttype::TrueType: 1661*cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1662*cdf0e10cSrcweir break; 1663*cdf0e10cSrcweir default: break; 1664*cdf0e10cSrcweir } 1665*cdf0e10cSrcweir } 1666*cdf0e10cSrcweir } 1667*cdf0e10cSrcweir 1668*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1669*cdf0e10cSrcweir 1670*cdf0e10cSrcweir OString PrintFontManager::getXLFD( PrintFont* pFont ) const 1671*cdf0e10cSrcweir { 1672*cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 ) 1673*cdf0e10cSrcweir { 1674*cdf0e10cSrcweir if( static_cast<Type1FontFile*>(pFont)->m_aXLFD.getLength() ) 1675*cdf0e10cSrcweir return static_cast<Type1FontFile*>(pFont)->m_aXLFD; 1676*cdf0e10cSrcweir } 1677*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 1678*cdf0e10cSrcweir { 1679*cdf0e10cSrcweir if( static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD.getLength() ) 1680*cdf0e10cSrcweir return static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD; 1681*cdf0e10cSrcweir } 1682*cdf0e10cSrcweir 1683*cdf0e10cSrcweir OStringBuffer aXLFD( 128 ); 1684*cdf0e10cSrcweir 1685*cdf0e10cSrcweir aXLFD.append( "-misc-" ); 1686*cdf0e10cSrcweir ByteString aFamily( String( m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ) ), RTL_TEXTENCODING_UTF8 ); 1687*cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '-',' ' ); 1688*cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '?',' ' ); 1689*cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '*',' ' ); 1690*cdf0e10cSrcweir aXLFD.append( OString( aFamily ) ); 1691*cdf0e10cSrcweir aXLFD.append( '-' ); 1692*cdf0e10cSrcweir switch( pFont->m_eWeight ) 1693*cdf0e10cSrcweir { 1694*cdf0e10cSrcweir case weight::Thin: aXLFD.append("thin");break; 1695*cdf0e10cSrcweir case weight::UltraLight: aXLFD.append("ultralight");break; 1696*cdf0e10cSrcweir case weight::Light: aXLFD.append("light");break; 1697*cdf0e10cSrcweir case weight::SemiLight: aXLFD.append("semilight");break; 1698*cdf0e10cSrcweir case weight::Normal: aXLFD.append("normal");break; 1699*cdf0e10cSrcweir case weight::Medium: aXLFD.append("medium");break; 1700*cdf0e10cSrcweir case weight::SemiBold: aXLFD.append("semibold");break; 1701*cdf0e10cSrcweir case weight::Bold: aXLFD.append("bold");break; 1702*cdf0e10cSrcweir case weight::UltraBold: aXLFD.append("ultrabold");break; 1703*cdf0e10cSrcweir case weight::Black: aXLFD.append("black");break; 1704*cdf0e10cSrcweir default: break; 1705*cdf0e10cSrcweir } 1706*cdf0e10cSrcweir aXLFD.append('-'); 1707*cdf0e10cSrcweir switch( pFont->m_eItalic ) 1708*cdf0e10cSrcweir { 1709*cdf0e10cSrcweir case italic::Upright: aXLFD.append('r');break; 1710*cdf0e10cSrcweir case italic::Oblique: aXLFD.append('o');break; 1711*cdf0e10cSrcweir case italic::Italic: aXLFD.append('i');break; 1712*cdf0e10cSrcweir default: break; 1713*cdf0e10cSrcweir } 1714*cdf0e10cSrcweir aXLFD.append('-'); 1715*cdf0e10cSrcweir switch( pFont->m_eWidth ) 1716*cdf0e10cSrcweir { 1717*cdf0e10cSrcweir case width::UltraCondensed: aXLFD.append("ultracondensed");break; 1718*cdf0e10cSrcweir case width::ExtraCondensed: aXLFD.append("extracondensed");break; 1719*cdf0e10cSrcweir case width::Condensed: aXLFD.append("condensed");break; 1720*cdf0e10cSrcweir case width::SemiCondensed: aXLFD.append("semicondensed");break; 1721*cdf0e10cSrcweir case width::Normal: aXLFD.append("normal");break; 1722*cdf0e10cSrcweir case width::SemiExpanded: aXLFD.append("semiexpanded");break; 1723*cdf0e10cSrcweir case width::Expanded: aXLFD.append("expanded");break; 1724*cdf0e10cSrcweir case width::ExtraExpanded: aXLFD.append("extraexpanded");break; 1725*cdf0e10cSrcweir case width::UltraExpanded: aXLFD.append("ultraexpanded");break; 1726*cdf0e10cSrcweir default: break; 1727*cdf0e10cSrcweir } 1728*cdf0e10cSrcweir aXLFD.append("-utf8-0-0-0-0-"); 1729*cdf0e10cSrcweir aXLFD.append( pFont->m_ePitch == pitch::Fixed ? "m" : "p" ); 1730*cdf0e10cSrcweir aXLFD.append("-0-"); 1731*cdf0e10cSrcweir const char* pEnc = rtl_getBestUnixCharsetFromTextEncoding( pFont->m_aEncoding ); 1732*cdf0e10cSrcweir if( ! pEnc ) 1733*cdf0e10cSrcweir { 1734*cdf0e10cSrcweir if( pFont->m_aEncoding == RTL_TEXTENCODING_ADOBE_STANDARD ) 1735*cdf0e10cSrcweir pEnc = "adobe-standard"; 1736*cdf0e10cSrcweir else 1737*cdf0e10cSrcweir pEnc = "iso8859-1"; 1738*cdf0e10cSrcweir } 1739*cdf0e10cSrcweir aXLFD .append( pEnc ); 1740*cdf0e10cSrcweir 1741*cdf0e10cSrcweir return aXLFD.makeStringAndClear(); 1742*cdf0e10cSrcweir } 1743*cdf0e10cSrcweir 1744*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1745*cdf0e10cSrcweir 1746*cdf0e10cSrcweir OUString PrintFontManager::convertTrueTypeName( void* pRecord ) const 1747*cdf0e10cSrcweir { 1748*cdf0e10cSrcweir NameRecord* pNameRecord = (NameRecord*)pRecord; 1749*cdf0e10cSrcweir OUString aValue; 1750*cdf0e10cSrcweir if( 1751*cdf0e10cSrcweir ( pNameRecord->platformID == 3 && ( pNameRecord->encodingID == 0 || pNameRecord->encodingID == 1 ) ) // MS, Unicode 1752*cdf0e10cSrcweir || 1753*cdf0e10cSrcweir ( pNameRecord->platformID == 0 ) // Apple, Unicode 1754*cdf0e10cSrcweir ) 1755*cdf0e10cSrcweir { 1756*cdf0e10cSrcweir OUStringBuffer aName( pNameRecord->slen/2 ); 1757*cdf0e10cSrcweir const sal_uInt8* pNameBuffer = pNameRecord->sptr; 1758*cdf0e10cSrcweir for(int n = 0; n < pNameRecord->slen/2; n++ ) 1759*cdf0e10cSrcweir aName.append( (sal_Unicode)getUInt16BE( pNameBuffer ) ); 1760*cdf0e10cSrcweir aValue = aName.makeStringAndClear(); 1761*cdf0e10cSrcweir } 1762*cdf0e10cSrcweir else if( pNameRecord->platformID == 3 ) 1763*cdf0e10cSrcweir { 1764*cdf0e10cSrcweir if( pNameRecord->encodingID >= 2 && pNameRecord->encodingID <= 6 ) 1765*cdf0e10cSrcweir { 1766*cdf0e10cSrcweir /* 1767*cdf0e10cSrcweir * and now for a special kind of madness: 1768*cdf0e10cSrcweir * some fonts encode their byte value string as BE uint16 1769*cdf0e10cSrcweir * (leading to stray zero bytes in the string) 1770*cdf0e10cSrcweir * while others code two bytes as a uint16 and swap to BE 1771*cdf0e10cSrcweir */ 1772*cdf0e10cSrcweir OStringBuffer aName; 1773*cdf0e10cSrcweir const sal_uInt8* pNameBuffer = pNameRecord->sptr; 1774*cdf0e10cSrcweir for(int n = 0; n < pNameRecord->slen/2; n++ ) 1775*cdf0e10cSrcweir { 1776*cdf0e10cSrcweir sal_Unicode aCode = (sal_Unicode)getUInt16BE( pNameBuffer ); 1777*cdf0e10cSrcweir sal_Char aChar = aCode >> 8; 1778*cdf0e10cSrcweir if( aChar ) 1779*cdf0e10cSrcweir aName.append( aChar ); 1780*cdf0e10cSrcweir aChar = aCode & 0x00ff; 1781*cdf0e10cSrcweir if( aChar ) 1782*cdf0e10cSrcweir aName.append( aChar ); 1783*cdf0e10cSrcweir } 1784*cdf0e10cSrcweir switch( pNameRecord->encodingID ) 1785*cdf0e10cSrcweir { 1786*cdf0e10cSrcweir case 2: 1787*cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_932 ); 1788*cdf0e10cSrcweir break; 1789*cdf0e10cSrcweir case 3: 1790*cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_936 ); 1791*cdf0e10cSrcweir break; 1792*cdf0e10cSrcweir case 4: 1793*cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_950 ); 1794*cdf0e10cSrcweir break; 1795*cdf0e10cSrcweir case 5: 1796*cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_949 ); 1797*cdf0e10cSrcweir break; 1798*cdf0e10cSrcweir case 6: 1799*cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_1361 ); 1800*cdf0e10cSrcweir break; 1801*cdf0e10cSrcweir } 1802*cdf0e10cSrcweir } 1803*cdf0e10cSrcweir } 1804*cdf0e10cSrcweir return aValue; 1805*cdf0e10cSrcweir } 1806*cdf0e10cSrcweir 1807*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1808*cdf0e10cSrcweir 1809*cdf0e10cSrcweir void PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont, ::std::list< OUString >& rNames ) const 1810*cdf0e10cSrcweir { 1811*cdf0e10cSrcweir OUString aFamily; 1812*cdf0e10cSrcweir 1813*cdf0e10cSrcweir rNames.clear(); 1814*cdf0e10cSrcweir ::std::set< OUString > aSet; 1815*cdf0e10cSrcweir 1816*cdf0e10cSrcweir NameRecord* pNameRecords = NULL; 1817*cdf0e10cSrcweir int nNameRecords = GetTTNameRecords( (TrueTypeFont*)pTTFont, &pNameRecords ); 1818*cdf0e10cSrcweir if( nNameRecords && pNameRecords ) 1819*cdf0e10cSrcweir { 1820*cdf0e10cSrcweir LanguageType aLang = MsLangId::getSystemLanguage(); 1821*cdf0e10cSrcweir int nLastMatch = -1; 1822*cdf0e10cSrcweir for( int i = 0; i < nNameRecords; i++ ) 1823*cdf0e10cSrcweir { 1824*cdf0e10cSrcweir if( pNameRecords[i].nameID != 1 || pNameRecords[i].sptr == NULL ) 1825*cdf0e10cSrcweir continue; 1826*cdf0e10cSrcweir int nMatch = -1; 1827*cdf0e10cSrcweir if( pNameRecords[i].platformID == 0 ) // Unicode 1828*cdf0e10cSrcweir nMatch = 4000; 1829*cdf0e10cSrcweir else if( pNameRecords[i].platformID == 3 ) 1830*cdf0e10cSrcweir { 1831*cdf0e10cSrcweir // this bases on the LanguageType actually being a Win LCID 1832*cdf0e10cSrcweir if( pNameRecords[i].languageID == aLang ) 1833*cdf0e10cSrcweir nMatch = 8000; 1834*cdf0e10cSrcweir else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH_US ) 1835*cdf0e10cSrcweir nMatch = 2000; 1836*cdf0e10cSrcweir else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH || 1837*cdf0e10cSrcweir pNameRecords[i].languageID == LANGUAGE_ENGLISH_UK ) 1838*cdf0e10cSrcweir nMatch = 1500; 1839*cdf0e10cSrcweir else 1840*cdf0e10cSrcweir nMatch = 1000; 1841*cdf0e10cSrcweir } 1842*cdf0e10cSrcweir OUString aName = convertTrueTypeName( pNameRecords + i ); 1843*cdf0e10cSrcweir aSet.insert( aName ); 1844*cdf0e10cSrcweir if( nMatch > nLastMatch ) 1845*cdf0e10cSrcweir { 1846*cdf0e10cSrcweir nLastMatch = nMatch; 1847*cdf0e10cSrcweir aFamily = aName; 1848*cdf0e10cSrcweir } 1849*cdf0e10cSrcweir } 1850*cdf0e10cSrcweir DisposeNameRecords( pNameRecords, nNameRecords ); 1851*cdf0e10cSrcweir } 1852*cdf0e10cSrcweir if( aFamily.getLength() ) 1853*cdf0e10cSrcweir { 1854*cdf0e10cSrcweir rNames.push_front( aFamily ); 1855*cdf0e10cSrcweir for( ::std::set< OUString >::const_iterator it = aSet.begin(); it != aSet.end(); ++it ) 1856*cdf0e10cSrcweir if( *it != aFamily ) 1857*cdf0e10cSrcweir rNames.push_back( *it ); 1858*cdf0e10cSrcweir } 1859*cdf0e10cSrcweir return; 1860*cdf0e10cSrcweir } 1861*cdf0e10cSrcweir 1862*cdf0e10cSrcweir // ------------------------------------------------------------------------- 1863*cdf0e10cSrcweir 1864*cdf0e10cSrcweir bool PrintFontManager::analyzeTrueTypeFile( PrintFont* pFont ) const 1865*cdf0e10cSrcweir { 1866*cdf0e10cSrcweir bool bSuccess = false; 1867*cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 1868*cdf0e10cSrcweir ByteString aFile = getFontFile( pFont ); 1869*cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 1870*cdf0e10cSrcweir 1871*cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 1872*cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 1873*cdf0e10cSrcweir { 1874*cdf0e10cSrcweir TTGlobalFontInfo aInfo; 1875*cdf0e10cSrcweir GetTTGlobalFontInfo( pTTFont, & aInfo ); 1876*cdf0e10cSrcweir 1877*cdf0e10cSrcweir ::std::list< OUString > aNames; 1878*cdf0e10cSrcweir analyzeTrueTypeFamilyName( pTTFont, aNames ); 1879*cdf0e10cSrcweir 1880*cdf0e10cSrcweir // set family name from XLFD if possible 1881*cdf0e10cSrcweir if( ! pFont->m_nFamilyName ) 1882*cdf0e10cSrcweir { 1883*cdf0e10cSrcweir if( aNames.begin() != aNames.end() ) 1884*cdf0e10cSrcweir { 1885*cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, aNames.front(), sal_True ); 1886*cdf0e10cSrcweir aNames.pop_front(); 1887*cdf0e10cSrcweir } 1888*cdf0e10cSrcweir else 1889*cdf0e10cSrcweir { 1890*cdf0e10cSrcweir sal_Int32 dotIndex; 1891*cdf0e10cSrcweir 1892*cdf0e10cSrcweir // poor font does not have a family name 1893*cdf0e10cSrcweir // name it to file name minus the extension 1894*cdf0e10cSrcweir dotIndex = pTTFontFile->m_aFontFile.lastIndexOf( '.' ); 1895*cdf0e10cSrcweir if ( dotIndex == -1 ) 1896*cdf0e10cSrcweir dotIndex = pTTFontFile->m_aFontFile.getLength(); 1897*cdf0e10cSrcweir 1898*cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, OStringToOUString( pTTFontFile->m_aFontFile.copy( 0, dotIndex ), aEncoding ), sal_True ); 1899*cdf0e10cSrcweir } 1900*cdf0e10cSrcweir } 1901*cdf0e10cSrcweir for( ::std::list< OUString >::iterator it = aNames.begin(); it != aNames.end(); ++it ) 1902*cdf0e10cSrcweir { 1903*cdf0e10cSrcweir if( it->getLength() ) 1904*cdf0e10cSrcweir { 1905*cdf0e10cSrcweir int nAlias = m_pAtoms->getAtom( ATOM_FAMILYNAME, *it, sal_True ); 1906*cdf0e10cSrcweir if( nAlias != pFont->m_nFamilyName ) 1907*cdf0e10cSrcweir { 1908*cdf0e10cSrcweir std::list< int >::const_iterator al_it; 1909*cdf0e10cSrcweir for( al_it = pFont->m_aAliases.begin(); al_it != pFont->m_aAliases.end() && *al_it != nAlias; ++al_it ) 1910*cdf0e10cSrcweir ; 1911*cdf0e10cSrcweir if( al_it == pFont->m_aAliases.end() ) 1912*cdf0e10cSrcweir pFont->m_aAliases.push_back( nAlias ); 1913*cdf0e10cSrcweir } 1914*cdf0e10cSrcweir } 1915*cdf0e10cSrcweir } 1916*cdf0e10cSrcweir 1917*cdf0e10cSrcweir if( aInfo.usubfamily ) 1918*cdf0e10cSrcweir pFont->m_aStyleName = OUString( aInfo.usubfamily ); 1919*cdf0e10cSrcweir 1920*cdf0e10cSrcweir pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, String( ByteString( aInfo.psname ), aEncoding ), sal_True ); 1921*cdf0e10cSrcweir switch( aInfo.weight ) 1922*cdf0e10cSrcweir { 1923*cdf0e10cSrcweir case FW_THIN: pFont->m_eWeight = weight::Thin; break; 1924*cdf0e10cSrcweir case FW_EXTRALIGHT: pFont->m_eWeight = weight::UltraLight; break; 1925*cdf0e10cSrcweir case FW_LIGHT: pFont->m_eWeight = weight::Light; break; 1926*cdf0e10cSrcweir case FW_MEDIUM: pFont->m_eWeight = weight::Medium; break; 1927*cdf0e10cSrcweir case FW_SEMIBOLD: pFont->m_eWeight = weight::SemiBold; break; 1928*cdf0e10cSrcweir case FW_BOLD: pFont->m_eWeight = weight::Bold; break; 1929*cdf0e10cSrcweir case FW_EXTRABOLD: pFont->m_eWeight = weight::UltraBold; break; 1930*cdf0e10cSrcweir case FW_BLACK: pFont->m_eWeight = weight::Black; break; 1931*cdf0e10cSrcweir 1932*cdf0e10cSrcweir case FW_NORMAL: 1933*cdf0e10cSrcweir default: pFont->m_eWeight = weight::Normal; break; 1934*cdf0e10cSrcweir } 1935*cdf0e10cSrcweir 1936*cdf0e10cSrcweir switch( aInfo.width ) 1937*cdf0e10cSrcweir { 1938*cdf0e10cSrcweir case FWIDTH_ULTRA_CONDENSED: pFont->m_eWidth = width::UltraCondensed; break; 1939*cdf0e10cSrcweir case FWIDTH_EXTRA_CONDENSED: pFont->m_eWidth = width::ExtraCondensed; break; 1940*cdf0e10cSrcweir case FWIDTH_CONDENSED: pFont->m_eWidth = width::Condensed; break; 1941*cdf0e10cSrcweir case FWIDTH_SEMI_CONDENSED: pFont->m_eWidth = width::SemiCondensed; break; 1942*cdf0e10cSrcweir case FWIDTH_SEMI_EXPANDED: pFont->m_eWidth = width::SemiExpanded; break; 1943*cdf0e10cSrcweir case FWIDTH_EXPANDED: pFont->m_eWidth = width::Expanded; break; 1944*cdf0e10cSrcweir case FWIDTH_EXTRA_EXPANDED: pFont->m_eWidth = width::ExtraExpanded; break; 1945*cdf0e10cSrcweir case FWIDTH_ULTRA_EXPANDED: pFont->m_eWidth = width::UltraExpanded; break; 1946*cdf0e10cSrcweir 1947*cdf0e10cSrcweir case FWIDTH_NORMAL: 1948*cdf0e10cSrcweir default: pFont->m_eWidth = width::Normal; break; 1949*cdf0e10cSrcweir } 1950*cdf0e10cSrcweir 1951*cdf0e10cSrcweir pFont->m_ePitch = aInfo.pitch ? pitch::Fixed : pitch::Variable; 1952*cdf0e10cSrcweir pFont->m_eItalic = aInfo.italicAngle == 0 ? italic::Upright : ( aInfo.italicAngle < 0 ? italic::Italic : italic::Oblique ); 1953*cdf0e10cSrcweir // #104264# there are fonts that set italic angle 0 although they are 1954*cdf0e10cSrcweir // italic; use macstyle bit here 1955*cdf0e10cSrcweir if( aInfo.italicAngle == 0 && (aInfo.macStyle & 2) ) 1956*cdf0e10cSrcweir pFont->m_eItalic = italic::Italic; 1957*cdf0e10cSrcweir 1958*cdf0e10cSrcweir pFont->m_aEncoding = aInfo.symbolEncoded ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UCS2; 1959*cdf0e10cSrcweir 1960*cdf0e10cSrcweir pFont->m_aGlobalMetricY.width = pFont->m_aGlobalMetricX.width = aInfo.xMax - aInfo.xMin; 1961*cdf0e10cSrcweir pFont->m_aGlobalMetricY.height = pFont->m_aGlobalMetricX.height = aInfo.yMax - aInfo.yMin; 1962*cdf0e10cSrcweir 1963*cdf0e10cSrcweir if( aInfo.winAscent && aInfo.winDescent ) 1964*cdf0e10cSrcweir { 1965*cdf0e10cSrcweir pFont->m_nAscend = aInfo.winAscent; 1966*cdf0e10cSrcweir pFont->m_nDescend = aInfo.winDescent; 1967*cdf0e10cSrcweir pFont->m_nLeading = pFont->m_nAscend + pFont->m_nDescend - 1000; 1968*cdf0e10cSrcweir } 1969*cdf0e10cSrcweir else if( aInfo.typoAscender && aInfo.typoDescender ) 1970*cdf0e10cSrcweir { 1971*cdf0e10cSrcweir pFont->m_nLeading = aInfo.typoLineGap; 1972*cdf0e10cSrcweir pFont->m_nAscend = aInfo.typoAscender; 1973*cdf0e10cSrcweir pFont->m_nDescend = -aInfo.typoDescender; 1974*cdf0e10cSrcweir } 1975*cdf0e10cSrcweir else 1976*cdf0e10cSrcweir { 1977*cdf0e10cSrcweir pFont->m_nLeading = aInfo.linegap; 1978*cdf0e10cSrcweir pFont->m_nAscend = aInfo.ascender; 1979*cdf0e10cSrcweir pFont->m_nDescend = -aInfo.descender; 1980*cdf0e10cSrcweir } 1981*cdf0e10cSrcweir 1982*cdf0e10cSrcweir // last try: font bounding box 1983*cdf0e10cSrcweir if( pFont->m_nAscend == 0 ) 1984*cdf0e10cSrcweir pFont->m_nAscend = aInfo.yMax; 1985*cdf0e10cSrcweir if( pFont->m_nDescend == 0 ) 1986*cdf0e10cSrcweir pFont->m_nDescend = -aInfo.yMin; 1987*cdf0e10cSrcweir if( pFont->m_nLeading == 0 ) 1988*cdf0e10cSrcweir pFont->m_nLeading = 15 * (pFont->m_nAscend+pFont->m_nDescend) / 100; 1989*cdf0e10cSrcweir 1990*cdf0e10cSrcweir if( pFont->m_nAscend ) 1991*cdf0e10cSrcweir pFont->m_aGlobalMetricX.height = pFont->m_aGlobalMetricY.height = pFont->m_nAscend + pFont->m_nDescend; 1992*cdf0e10cSrcweir 1993*cdf0e10cSrcweir // get bounding box 1994*cdf0e10cSrcweir pFont->m_nXMin = aInfo.xMin; 1995*cdf0e10cSrcweir pFont->m_nYMin = aInfo.yMin; 1996*cdf0e10cSrcweir pFont->m_nXMax = aInfo.xMax; 1997*cdf0e10cSrcweir pFont->m_nYMax = aInfo.yMax; 1998*cdf0e10cSrcweir 1999*cdf0e10cSrcweir // get type flags 2000*cdf0e10cSrcweir pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; 2001*cdf0e10cSrcweir 2002*cdf0e10cSrcweir // get vertical substitutions flag 2003*cdf0e10cSrcweir pFont->m_bHaveVerticalSubstitutedGlyphs = DoesVerticalSubstitution( pTTFont, 1 ); 2004*cdf0e10cSrcweir 2005*cdf0e10cSrcweir CloseTTFont( pTTFont ); 2006*cdf0e10cSrcweir bSuccess = true; 2007*cdf0e10cSrcweir } 2008*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2009*cdf0e10cSrcweir else 2010*cdf0e10cSrcweir fprintf( stderr, "could not OpenTTFont \"%s\"\n", aFile.GetBuffer() ); 2011*cdf0e10cSrcweir #endif 2012*cdf0e10cSrcweir 2013*cdf0e10cSrcweir return bSuccess; 2014*cdf0e10cSrcweir } 2015*cdf0e10cSrcweir 2016*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2017*cdf0e10cSrcweir 2018*cdf0e10cSrcweir void PrintFontManager::initFontsAlias() 2019*cdf0e10cSrcweir { 2020*cdf0e10cSrcweir m_aXLFD_Aliases.clear(); 2021*cdf0e10cSrcweir rtl_TextEncoding aEnc = osl_getThreadTextEncoding(); 2022*cdf0e10cSrcweir for( std::list< OString >::const_iterator dir_it = m_aFontDirectories.begin(); 2023*cdf0e10cSrcweir dir_it != m_aFontDirectories.end(); ++dir_it ) 2024*cdf0e10cSrcweir { 2025*cdf0e10cSrcweir OStringBuffer aDirName(512); 2026*cdf0e10cSrcweir aDirName.append( *dir_it ); 2027*cdf0e10cSrcweir aDirName.append( "/fonts.alias" ); 2028*cdf0e10cSrcweir SvFileStream aStream( OStringToOUString( aDirName.makeStringAndClear(), aEnc ), STREAM_READ ); 2029*cdf0e10cSrcweir if( ! aStream.IsOpen() ) 2030*cdf0e10cSrcweir continue; 2031*cdf0e10cSrcweir 2032*cdf0e10cSrcweir do 2033*cdf0e10cSrcweir { 2034*cdf0e10cSrcweir ByteString aLine; 2035*cdf0e10cSrcweir aStream.ReadLine( aLine ); 2036*cdf0e10cSrcweir 2037*cdf0e10cSrcweir // get the alias and the pattern it gets translated to 2038*cdf0e10cSrcweir ByteString aAlias = GetCommandLineToken( 0, aLine ); 2039*cdf0e10cSrcweir ByteString aMap = GetCommandLineToken( 1, aLine ); 2040*cdf0e10cSrcweir 2041*cdf0e10cSrcweir // remove eventual quotes 2042*cdf0e10cSrcweir aAlias.EraseLeadingChars( '"' ); 2043*cdf0e10cSrcweir aAlias.EraseTrailingChars( '"' ); 2044*cdf0e10cSrcweir aMap.EraseLeadingChars( '"' ); 2045*cdf0e10cSrcweir aMap.EraseTrailingChars( '"' ); 2046*cdf0e10cSrcweir 2047*cdf0e10cSrcweir XLFDEntry aAliasEntry, aMapEntry; 2048*cdf0e10cSrcweir parseXLFD( aAlias, aAliasEntry ); 2049*cdf0e10cSrcweir parseXLFD( aMap, aMapEntry ); 2050*cdf0e10cSrcweir 2051*cdf0e10cSrcweir if( aAliasEntry.nMask && aMapEntry.nMask ) 2052*cdf0e10cSrcweir m_aXLFD_Aliases[ aMapEntry ].push_back( aAliasEntry ); 2053*cdf0e10cSrcweir } while( ! aStream.IsEof() ); 2054*cdf0e10cSrcweir } 2055*cdf0e10cSrcweir } 2056*cdf0e10cSrcweir 2057*cdf0e10cSrcweir // code stolen from vcl's RegisterFontSubstitutors() 2058*cdf0e10cSrcweir // TODO: use that method once psprint gets merged into vcl 2059*cdf0e10cSrcweir static bool AreFCSubstitutionsEnabled() 2060*cdf0e10cSrcweir { 2061*cdf0e10cSrcweir // init font substitution defaults 2062*cdf0e10cSrcweir int nDisableBits = 0; 2063*cdf0e10cSrcweir #ifdef SOLARIS 2064*cdf0e10cSrcweir // TODO: check the OS version and fc-data maintenance level 2065*cdf0e10cSrcweir nDisableBits = 1; // disable "font fallback" here on default 2066*cdf0e10cSrcweir #endif 2067*cdf0e10cSrcweir // apply the environment variable if any 2068*cdf0e10cSrcweir const char* pEnvStr = ::getenv( "SAL_DISABLE_FC_SUBST" ); 2069*cdf0e10cSrcweir if( pEnvStr ) 2070*cdf0e10cSrcweir { 2071*cdf0e10cSrcweir // 2072*cdf0e10cSrcweir if( (*pEnvStr >= '0') && (*pEnvStr <= '9') ) 2073*cdf0e10cSrcweir nDisableBits = (*pEnvStr - '0'); 2074*cdf0e10cSrcweir else 2075*cdf0e10cSrcweir nDisableBits = ~0U; // no specific bits set: disable all 2076*cdf0e10cSrcweir } 2077*cdf0e10cSrcweir 2078*cdf0e10cSrcweir return ((nDisableBits & 3) == 0); 2079*cdf0e10cSrcweir } 2080*cdf0e10cSrcweir 2081*cdf0e10cSrcweir void PrintFontManager::initialize() 2082*cdf0e10cSrcweir { 2083*cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 2084*cdf0e10cSrcweir CALLGRIND_TOGGLE_COLLECT(); 2085*cdf0e10cSrcweir CALLGRIND_ZERO_STATS(); 2086*cdf0e10cSrcweir #endif 2087*cdf0e10cSrcweir 2088*cdf0e10cSrcweir long aDirEntBuffer[ (sizeof(struct dirent)+_PC_NAME_MAX)+1 ]; 2089*cdf0e10cSrcweir 2090*cdf0e10cSrcweir if( ! m_pFontCache ) 2091*cdf0e10cSrcweir { 2092*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2093*cdf0e10cSrcweir fprintf( stderr, "creating font cache ... " ); 2094*cdf0e10cSrcweir clock_t aStart; 2095*cdf0e10cSrcweir struct tms tms; 2096*cdf0e10cSrcweir aStart = times( &tms ); 2097*cdf0e10cSrcweir #endif 2098*cdf0e10cSrcweir m_pFontCache = new FontCache(); 2099*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2100*cdf0e10cSrcweir clock_t aStop = times( &tms ); 2101*cdf0e10cSrcweir fprintf( stderr, "done in %lf s\n", (double)(aStop - aStart)/(double)sysconf( _SC_CLK_TCK ) ); 2102*cdf0e10cSrcweir #endif 2103*cdf0e10cSrcweir } 2104*cdf0e10cSrcweir 2105*cdf0e10cSrcweir // initialize may be called twice in the future 2106*cdf0e10cSrcweir { 2107*cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2108*cdf0e10cSrcweir delete (*it).second; 2109*cdf0e10cSrcweir m_nNextFontID = 1; 2110*cdf0e10cSrcweir m_aFonts.clear(); 2111*cdf0e10cSrcweir m_aFontDirectories.clear(); 2112*cdf0e10cSrcweir m_aPrivateFontDirectories.clear(); 2113*cdf0e10cSrcweir m_aOverrideFonts.clear(); 2114*cdf0e10cSrcweir } 2115*cdf0e10cSrcweir 2116*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2117*cdf0e10cSrcweir clock_t aStart; 2118*cdf0e10cSrcweir clock_t aStep1; 2119*cdf0e10cSrcweir clock_t aStep2; 2120*cdf0e10cSrcweir clock_t aStep3; 2121*cdf0e10cSrcweir int nBuiltinFonts = 0; 2122*cdf0e10cSrcweir int nCached = 0; 2123*cdf0e10cSrcweir 2124*cdf0e10cSrcweir struct tms tms; 2125*cdf0e10cSrcweir 2126*cdf0e10cSrcweir aStart = times( &tms ); 2127*cdf0e10cSrcweir #endif 2128*cdf0e10cSrcweir 2129*cdf0e10cSrcweir // first try fontconfig 2130*cdf0e10cSrcweir m_bFontconfigSuccess = initFontconfig(); 2131*cdf0e10cSrcweir 2132*cdf0e10cSrcweir // part one - look for downloadable fonts 2133*cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 2134*cdf0e10cSrcweir const ::rtl::OUString &rSalPrivatePath = psp::getFontPath(); 2135*cdf0e10cSrcweir 2136*cdf0e10cSrcweir // search for the fonts in SAL_PRIVATE_FONTPATH first; those are 2137*cdf0e10cSrcweir // the fonts installed with the office 2138*cdf0e10cSrcweir if( rSalPrivatePath.getLength() ) 2139*cdf0e10cSrcweir { 2140*cdf0e10cSrcweir OString aPath = rtl::OUStringToOString( rSalPrivatePath, aEncoding ); 2141*cdf0e10cSrcweir const bool bAreFCSubstitutionsEnabled = AreFCSubstitutionsEnabled(); 2142*cdf0e10cSrcweir sal_Int32 nIndex = 0; 2143*cdf0e10cSrcweir do 2144*cdf0e10cSrcweir { 2145*cdf0e10cSrcweir OString aToken = aPath.getToken( 0, ';', nIndex ); 2146*cdf0e10cSrcweir normPath( aToken ); 2147*cdf0e10cSrcweir // if registering an app-specific fontdir with fontconfig fails 2148*cdf0e10cSrcweir // and fontconfig-based substitutions are enabled 2149*cdf0e10cSrcweir // then trying to use these app-specific fonts doesn't make sense 2150*cdf0e10cSrcweir if( m_bFontconfigSuccess && !addFontconfigDir( aToken ) ) 2151*cdf0e10cSrcweir if( bAreFCSubstitutionsEnabled ) 2152*cdf0e10cSrcweir continue; 2153*cdf0e10cSrcweir m_aFontDirectories.push_back( aToken ); 2154*cdf0e10cSrcweir m_aPrivateFontDirectories.push_back( getDirectoryAtom( aToken, true ) ); 2155*cdf0e10cSrcweir } while( nIndex >= 0 ); 2156*cdf0e10cSrcweir } 2157*cdf0e10cSrcweir 2158*cdf0e10cSrcweir // protect against duplicate paths 2159*cdf0e10cSrcweir std::hash_map< OString, int, OStringHash > visited_dirs; 2160*cdf0e10cSrcweir 2161*cdf0e10cSrcweir // now that all global and local font dirs are known to fontconfig 2162*cdf0e10cSrcweir // check that there are fonts actually managed by fontconfig 2163*cdf0e10cSrcweir // also don't search directories that fontconfig already did 2164*cdf0e10cSrcweir if( m_bFontconfigSuccess ) 2165*cdf0e10cSrcweir m_bFontconfigSuccess = (countFontconfigFonts( visited_dirs ) > 0); 2166*cdf0e10cSrcweir 2167*cdf0e10cSrcweir // don't search through many directories fontconfig already told us about 2168*cdf0e10cSrcweir if( ! m_bFontconfigSuccess ) 2169*cdf0e10cSrcweir ImplGetSVData()->mpDefInst->FillFontPathList( m_aFontDirectories ); 2170*cdf0e10cSrcweir 2171*cdf0e10cSrcweir // fill XLFD aliases from fonts.alias files 2172*cdf0e10cSrcweir initFontsAlias(); 2173*cdf0e10cSrcweir 2174*cdf0e10cSrcweir // search for font files in each path 2175*cdf0e10cSrcweir std::list< OString >::iterator dir_it; 2176*cdf0e10cSrcweir for( dir_it = m_aFontDirectories.begin(); dir_it != m_aFontDirectories.end(); ++dir_it ) 2177*cdf0e10cSrcweir { 2178*cdf0e10cSrcweir OString aPath( *dir_it ); 2179*cdf0e10cSrcweir // see if we were here already 2180*cdf0e10cSrcweir if( visited_dirs.find( aPath ) != visited_dirs.end() ) 2181*cdf0e10cSrcweir continue; 2182*cdf0e10cSrcweir visited_dirs[ aPath ] = 1; 2183*cdf0e10cSrcweir 2184*cdf0e10cSrcweir // there may be ":unscaled" directories (see XFree86) 2185*cdf0e10cSrcweir // it should be safe to ignore them since they should not 2186*cdf0e10cSrcweir // contain any of our recognizeable fonts 2187*cdf0e10cSrcweir 2188*cdf0e10cSrcweir // ask the font cache whether it handles this directory 2189*cdf0e10cSrcweir std::list< PrintFont* > aCacheFonts; 2190*cdf0e10cSrcweir if( m_pFontCache->listDirectory( aPath, aCacheFonts ) ) 2191*cdf0e10cSrcweir { 2192*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2193*cdf0e10cSrcweir fprintf( stderr, "adding cache directory: %s\n", aPath.getStr() ); 2194*cdf0e10cSrcweir #endif 2195*cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aCacheFonts.begin(); it != aCacheFonts.end(); ++it ) 2196*cdf0e10cSrcweir { 2197*cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2198*cdf0e10cSrcweir m_aFonts[ aFont ] = *it; 2199*cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Type1 ) 2200*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<Type1FontFile*>(*it)->m_aFontFile ].insert( aFont ); 2201*cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::TrueType ) 2202*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<TrueTypeFontFile*>(*it)->m_aFontFile ].insert( aFont ); 2203*cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::Builtin ) 2204*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<BuiltinFont*>(*it)->m_aMetricFile ].insert( aFont ); 2205*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2206*cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Builtin ) 2207*cdf0e10cSrcweir nBuiltinFonts++; 2208*cdf0e10cSrcweir nCached++; 2209*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2210*cdf0e10cSrcweir fprintf( stderr, "adding cached font %d: \"%s\" from %s\n", aFont, 2211*cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2212*cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2213*cdf0e10cSrcweir #endif 2214*cdf0e10cSrcweir #endif 2215*cdf0e10cSrcweir } 2216*cdf0e10cSrcweir if( ! m_pFontCache->scanAdditionalFiles( aPath ) ) 2217*cdf0e10cSrcweir continue; 2218*cdf0e10cSrcweir } 2219*cdf0e10cSrcweir 2220*cdf0e10cSrcweir DIR* pDIR = opendir( aPath.getStr() ); 2221*cdf0e10cSrcweir struct dirent* pEntry = (struct dirent*)aDirEntBuffer; 2222*cdf0e10cSrcweir if( pDIR ) 2223*cdf0e10cSrcweir { 2224*cdf0e10cSrcweir // read fonts.dir if possible 2225*cdf0e10cSrcweir ::std::hash_map< OString, ::std::list<OString>, OStringHash > aFontsDir; 2226*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aPath, true ); 2227*cdf0e10cSrcweir // #i38367# no fonts.dir in our own directories anymore 2228*cdf0e10cSrcweir std::list< int >::const_iterator priv_dir; 2229*cdf0e10cSrcweir for( priv_dir = m_aPrivateFontDirectories.begin(); 2230*cdf0e10cSrcweir priv_dir != m_aPrivateFontDirectories.end() && *priv_dir != nDirID; 2231*cdf0e10cSrcweir ++priv_dir ) 2232*cdf0e10cSrcweir ; 2233*cdf0e10cSrcweir 2234*cdf0e10cSrcweir if( priv_dir == m_aPrivateFontDirectories.end() ) 2235*cdf0e10cSrcweir { 2236*cdf0e10cSrcweir ByteString aGccDummy( aPath ); 2237*cdf0e10cSrcweir String aFontsDirPath( aGccDummy, aEncoding ); 2238*cdf0e10cSrcweir aFontsDirPath.AppendAscii( "/fonts.dir" ); 2239*cdf0e10cSrcweir SvFileStream aStream( aFontsDirPath, STREAM_READ ); 2240*cdf0e10cSrcweir if( aStream.IsOpen() ) 2241*cdf0e10cSrcweir { 2242*cdf0e10cSrcweir ByteString aLine; 2243*cdf0e10cSrcweir while( ! aStream.IsEof() ) 2244*cdf0e10cSrcweir { 2245*cdf0e10cSrcweir aStream.ReadLine( aLine ); 2246*cdf0e10cSrcweir ByteString aFileName( GetCommandLineToken( 0, aLine ) ); 2247*cdf0e10cSrcweir ByteString aXLFD( aLine.Copy( aFileName.Len() ) ); 2248*cdf0e10cSrcweir if( aFileName.Len() && aXLFD.Len() ) 2249*cdf0e10cSrcweir aFontsDir[ aFileName ].push_back(aXLFD); 2250*cdf0e10cSrcweir } 2251*cdf0e10cSrcweir } 2252*cdf0e10cSrcweir } 2253*cdf0e10cSrcweir 2254*cdf0e10cSrcweir int nDirFonts = 0; 2255*cdf0e10cSrcweir while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pEntry ) && pEntry ) 2256*cdf0e10cSrcweir { 2257*cdf0e10cSrcweir OString aFileName( pEntry->d_name ); 2258*cdf0e10cSrcweir // ignore .afm files here 2259*cdf0e10cSrcweir if( aFileName.getLength() > 3 && 2260*cdf0e10cSrcweir aFileName.lastIndexOf( ".afm" ) == aFileName.getLength()-4 ) 2261*cdf0e10cSrcweir continue; 2262*cdf0e10cSrcweir 2263*cdf0e10cSrcweir struct stat aStat; 2264*cdf0e10cSrcweir ByteString aFilePath( aPath ); 2265*cdf0e10cSrcweir aFilePath.Append( '/' ); 2266*cdf0e10cSrcweir aFilePath.Append( ByteString( aFileName ) ); 2267*cdf0e10cSrcweir if( ! stat( aFilePath.GetBuffer(), &aStat ) && 2268*cdf0e10cSrcweir S_ISREG( aStat.st_mode ) ) 2269*cdf0e10cSrcweir { 2270*cdf0e10cSrcweir if( findFontFileID( nDirID, aFileName ) == 0 ) 2271*cdf0e10cSrcweir { 2272*cdf0e10cSrcweir ::std::list<OString> aXLFDs; 2273*cdf0e10cSrcweir ::std::hash_map< OString, ::std::list<OString>, OStringHash >::const_iterator it = 2274*cdf0e10cSrcweir aFontsDir.find( aFileName ); 2275*cdf0e10cSrcweir if( it != aFontsDir.end() ) 2276*cdf0e10cSrcweir aXLFDs = (*it).second; 2277*cdf0e10cSrcweir 2278*cdf0e10cSrcweir // fill in font attributes from XLFD rather 2279*cdf0e10cSrcweir // than reading every file 2280*cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 2281*cdf0e10cSrcweir if( analyzeFontFile( nDirID, aFileName, aXLFDs, aNewFonts ) ) 2282*cdf0e10cSrcweir { 2283*cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator font_it = aNewFonts.begin(); font_it != aNewFonts.end(); ++font_it ) 2284*cdf0e10cSrcweir { 2285*cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2286*cdf0e10cSrcweir m_aFonts[ aFont ] = *font_it; 2287*cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( aFont ); 2288*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *font_it, false ); 2289*cdf0e10cSrcweir nDirFonts++; 2290*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2291*cdf0e10cSrcweir fprintf( stderr, "adding font %d: \"%s\" from %s\n", aFont, 2292*cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2293*cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2294*cdf0e10cSrcweir #endif 2295*cdf0e10cSrcweir } 2296*cdf0e10cSrcweir } 2297*cdf0e10cSrcweir } 2298*cdf0e10cSrcweir } 2299*cdf0e10cSrcweir } 2300*cdf0e10cSrcweir closedir( pDIR ); 2301*cdf0e10cSrcweir m_pFontCache->updateDirTimestamp( nDirID ); 2302*cdf0e10cSrcweir if( ! nDirFonts ) 2303*cdf0e10cSrcweir m_pFontCache->markEmptyDir( nDirID ); 2304*cdf0e10cSrcweir } 2305*cdf0e10cSrcweir } 2306*cdf0e10cSrcweir 2307*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2308*cdf0e10cSrcweir aStep1 = times( &tms ); 2309*cdf0e10cSrcweir #endif 2310*cdf0e10cSrcweir 2311*cdf0e10cSrcweir // part two - look for metrics for builtin printer fonts 2312*cdf0e10cSrcweir std::list< OUString > aMetricDirs; 2313*cdf0e10cSrcweir psp::getPrinterPathList( aMetricDirs, PRINTER_METRICDIR ); 2314*cdf0e10cSrcweir 2315*cdf0e10cSrcweir std::list< OString > aEmptyFontsDir; 2316*cdf0e10cSrcweir for( std::list< OUString >::const_iterator met_dir_it = aMetricDirs.begin(); met_dir_it != aMetricDirs.end(); ++met_dir_it ) 2317*cdf0e10cSrcweir { 2318*cdf0e10cSrcweir OString aDir = OUStringToOString( *met_dir_it, aEncoding ); 2319*cdf0e10cSrcweir 2320*cdf0e10cSrcweir // ask the font cache whether it handles this directory 2321*cdf0e10cSrcweir std::list< PrintFont* > aCacheFonts; 2322*cdf0e10cSrcweir 2323*cdf0e10cSrcweir if( m_pFontCache->listDirectory( aDir, aCacheFonts ) ) 2324*cdf0e10cSrcweir { 2325*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2326*cdf0e10cSrcweir fprintf( stderr, "adding cache directory: %s\n", aDir.getStr() ); 2327*cdf0e10cSrcweir #endif 2328*cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aCacheFonts.begin(); it != aCacheFonts.end(); ++it ) 2329*cdf0e10cSrcweir { 2330*cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2331*cdf0e10cSrcweir m_aFonts[ aFont ] = *it; 2332*cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Type1 ) 2333*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<Type1FontFile*>(*it)->m_aFontFile ].insert( aFont ); 2334*cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::TrueType ) 2335*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<TrueTypeFontFile*>(*it)->m_aFontFile ].insert( aFont ); 2336*cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::Builtin ) 2337*cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<BuiltinFont*>(*it)->m_aMetricFile ].insert( aFont ); 2338*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2339*cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Builtin ) 2340*cdf0e10cSrcweir nBuiltinFonts++; 2341*cdf0e10cSrcweir nCached++; 2342*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2343*cdf0e10cSrcweir fprintf( stderr, "adding cached font %d: \"%s\" from %s\n", aFont, 2344*cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2345*cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2346*cdf0e10cSrcweir #endif 2347*cdf0e10cSrcweir #endif 2348*cdf0e10cSrcweir } 2349*cdf0e10cSrcweir continue; 2350*cdf0e10cSrcweir } 2351*cdf0e10cSrcweir 2352*cdf0e10cSrcweir DIR* pDIR = opendir( aDir.getStr() ); 2353*cdf0e10cSrcweir if( pDIR ) 2354*cdf0e10cSrcweir { 2355*cdf0e10cSrcweir struct dirent* pDirEntry = (struct dirent*)aDirEntBuffer; 2356*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 2357*cdf0e10cSrcweir int nDirFonts = 0; 2358*cdf0e10cSrcweir 2359*cdf0e10cSrcweir while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pDirEntry ) && pDirEntry ) 2360*cdf0e10cSrcweir { 2361*cdf0e10cSrcweir ByteString aFile( aDir ); 2362*cdf0e10cSrcweir aFile += '/'; 2363*cdf0e10cSrcweir aFile += pDirEntry->d_name; 2364*cdf0e10cSrcweir struct stat aStat; 2365*cdf0e10cSrcweir if( ! stat( aFile.GetBuffer(), &aStat ) 2366*cdf0e10cSrcweir && S_ISREG( aStat.st_mode ) 2367*cdf0e10cSrcweir ) 2368*cdf0e10cSrcweir { 2369*cdf0e10cSrcweir OString aFileName( pDirEntry->d_name, strlen( pDirEntry->d_name ) ); 2370*cdf0e10cSrcweir OString aExt( aFileName.copy( aFileName.lastIndexOf( '.' )+1 ) ); 2371*cdf0e10cSrcweir if( aExt.equalsIgnoreAsciiCase( "afm" ) ) 2372*cdf0e10cSrcweir { 2373*cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 2374*cdf0e10cSrcweir 2375*cdf0e10cSrcweir analyzeFontFile( nDirID, aFileName, aEmptyFontsDir, aNewFonts ); 2376*cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) 2377*cdf0e10cSrcweir { 2378*cdf0e10cSrcweir if( findFontBuiltinID( (*it)->m_nPSName ) == 0 ) 2379*cdf0e10cSrcweir { 2380*cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); 2381*cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = *it; 2382*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, false ); 2383*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2384*cdf0e10cSrcweir nBuiltinFonts++; 2385*cdf0e10cSrcweir #endif 2386*cdf0e10cSrcweir } 2387*cdf0e10cSrcweir else 2388*cdf0e10cSrcweir delete *it; 2389*cdf0e10cSrcweir } 2390*cdf0e10cSrcweir } 2391*cdf0e10cSrcweir } 2392*cdf0e10cSrcweir } 2393*cdf0e10cSrcweir closedir( pDIR ); 2394*cdf0e10cSrcweir if( ! nDirFonts ) 2395*cdf0e10cSrcweir m_pFontCache->markEmptyDir( nDirID ); 2396*cdf0e10cSrcweir } 2397*cdf0e10cSrcweir } 2398*cdf0e10cSrcweir 2399*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2400*cdf0e10cSrcweir aStep2 = times( &tms ); 2401*cdf0e10cSrcweir #endif 2402*cdf0e10cSrcweir 2403*cdf0e10cSrcweir // part three - fill in family styles 2404*cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::iterator font_it; 2405*cdf0e10cSrcweir for (font_it = m_aFonts.begin(); font_it != m_aFonts.end(); ++font_it) 2406*cdf0e10cSrcweir { 2407*cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator it = 2408*cdf0e10cSrcweir m_aFamilyTypes.find( font_it->second->m_nFamilyName ); 2409*cdf0e10cSrcweir if (it != m_aFamilyTypes.end()) 2410*cdf0e10cSrcweir continue; 2411*cdf0e10cSrcweir const ::rtl::OUString& rFamily = 2412*cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, font_it->second->m_nFamilyName); 2413*cdf0e10cSrcweir family::type eType = matchFamilyName( rFamily ); 2414*cdf0e10cSrcweir m_aFamilyTypes[ font_it->second->m_nFamilyName ] = eType; 2415*cdf0e10cSrcweir } 2416*cdf0e10cSrcweir 2417*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2418*cdf0e10cSrcweir aStep3 = times( &tms ); 2419*cdf0e10cSrcweir fprintf( stderr, "PrintFontManager::initialize: collected %d fonts (%d builtin, %d cached)\n", m_aFonts.size(), nBuiltinFonts, nCached ); 2420*cdf0e10cSrcweir double fTick = (double)sysconf( _SC_CLK_TCK ); 2421*cdf0e10cSrcweir fprintf( stderr, "Step 1 took %lf seconds\n", (double)(aStep1 - aStart)/fTick ); 2422*cdf0e10cSrcweir fprintf( stderr, "Step 2 took %lf seconds\n", (double)(aStep2 - aStep1)/fTick ); 2423*cdf0e10cSrcweir fprintf( stderr, "Step 3 took %lf seconds\n", (double)(aStep3 - aStep2)/fTick ); 2424*cdf0e10cSrcweir #endif 2425*cdf0e10cSrcweir 2426*cdf0e10cSrcweir m_pFontCache->flush(); 2427*cdf0e10cSrcweir 2428*cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 2429*cdf0e10cSrcweir CALLGRIND_DUMP_STATS(); 2430*cdf0e10cSrcweir CALLGRIND_TOGGLE_COLLECT(); 2431*cdf0e10cSrcweir #endif 2432*cdf0e10cSrcweir } 2433*cdf0e10cSrcweir 2434*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2435*cdf0e10cSrcweir inline bool 2436*cdf0e10cSrcweir equalPitch (psp::pitch::type from, psp::pitch::type to) 2437*cdf0e10cSrcweir { 2438*cdf0e10cSrcweir return from == to; 2439*cdf0e10cSrcweir } 2440*cdf0e10cSrcweir 2441*cdf0e10cSrcweir inline bool 2442*cdf0e10cSrcweir equalWeight (psp::weight::type from, psp::weight::type to) 2443*cdf0e10cSrcweir { 2444*cdf0e10cSrcweir return from > to ? (from - to) <= 3 : (to - from) <= 3; 2445*cdf0e10cSrcweir } 2446*cdf0e10cSrcweir 2447*cdf0e10cSrcweir inline bool 2448*cdf0e10cSrcweir equalItalic (psp::italic::type from, psp::italic::type to) 2449*cdf0e10cSrcweir { 2450*cdf0e10cSrcweir if ( (from == psp::italic::Italic) || (from == psp::italic::Oblique) ) 2451*cdf0e10cSrcweir return (to == psp::italic::Italic) || (to == psp::italic::Oblique); 2452*cdf0e10cSrcweir return to == from; 2453*cdf0e10cSrcweir } 2454*cdf0e10cSrcweir inline bool 2455*cdf0e10cSrcweir equalEncoding (rtl_TextEncoding from, rtl_TextEncoding to) 2456*cdf0e10cSrcweir { 2457*cdf0e10cSrcweir if ((from == RTL_TEXTENCODING_ISO_8859_1) || (from == RTL_TEXTENCODING_MS_1252)) 2458*cdf0e10cSrcweir return (to == RTL_TEXTENCODING_ISO_8859_1) || (to == RTL_TEXTENCODING_MS_1252); 2459*cdf0e10cSrcweir return from == to; 2460*cdf0e10cSrcweir } 2461*cdf0e10cSrcweir 2462*cdf0e10cSrcweir namespace { 2463*cdf0e10cSrcweir struct BuiltinFontIdentifier 2464*cdf0e10cSrcweir { 2465*cdf0e10cSrcweir OUString aFamily; 2466*cdf0e10cSrcweir italic::type eItalic; 2467*cdf0e10cSrcweir weight::type eWeight; 2468*cdf0e10cSrcweir pitch::type ePitch; 2469*cdf0e10cSrcweir rtl_TextEncoding aEncoding; 2470*cdf0e10cSrcweir 2471*cdf0e10cSrcweir BuiltinFontIdentifier( const OUString& rFam, 2472*cdf0e10cSrcweir italic::type eIt, 2473*cdf0e10cSrcweir weight::type eWg, 2474*cdf0e10cSrcweir pitch::type ePt, 2475*cdf0e10cSrcweir rtl_TextEncoding enc ) : 2476*cdf0e10cSrcweir aFamily( rFam ), 2477*cdf0e10cSrcweir eItalic( eIt ), 2478*cdf0e10cSrcweir eWeight( eWg ), 2479*cdf0e10cSrcweir ePitch( ePt ), 2480*cdf0e10cSrcweir aEncoding( enc ) 2481*cdf0e10cSrcweir {} 2482*cdf0e10cSrcweir 2483*cdf0e10cSrcweir bool operator==( const BuiltinFontIdentifier& rRight ) const 2484*cdf0e10cSrcweir { 2485*cdf0e10cSrcweir return equalItalic( eItalic, rRight.eItalic ) && 2486*cdf0e10cSrcweir equalWeight( eWeight, rRight.eWeight ) && 2487*cdf0e10cSrcweir equalPitch( ePitch, rRight.ePitch ) && 2488*cdf0e10cSrcweir equalEncoding( aEncoding, rRight.aEncoding ) && 2489*cdf0e10cSrcweir aFamily.equalsIgnoreAsciiCase( rRight.aFamily ); 2490*cdf0e10cSrcweir } 2491*cdf0e10cSrcweir }; 2492*cdf0e10cSrcweir 2493*cdf0e10cSrcweir struct BuiltinFontIdentifierHash 2494*cdf0e10cSrcweir { 2495*cdf0e10cSrcweir size_t operator()( const BuiltinFontIdentifier& rFont ) const 2496*cdf0e10cSrcweir { 2497*cdf0e10cSrcweir return rFont.aFamily.hashCode() ^ rFont.eItalic ^ rFont.eWeight ^ rFont.ePitch ^ rFont.aEncoding; 2498*cdf0e10cSrcweir } 2499*cdf0e10cSrcweir }; 2500*cdf0e10cSrcweir } 2501*cdf0e10cSrcweir 2502*cdf0e10cSrcweir void PrintFontManager::getFontList( ::std::list< fontID >& rFontIDs, const PPDParser* pParser, bool bUseOverrideMetrics ) 2503*cdf0e10cSrcweir { 2504*cdf0e10cSrcweir rFontIDs.clear(); 2505*cdf0e10cSrcweir std::hash_map< fontID, PrintFont* >::const_iterator it; 2506*cdf0e10cSrcweir 2507*cdf0e10cSrcweir /* 2508*cdf0e10cSrcweir * Note: there are two easy steps making this faster: 2509*cdf0e10cSrcweir * first: insert the printer builtins first, then the not builtins, 2510*cdf0e10cSrcweir * if they do not match. 2511*cdf0e10cSrcweir * drawback: this would change the sequence of fonts; this could have 2512*cdf0e10cSrcweir * subtle, unknown consequences in vcl font matching 2513*cdf0e10cSrcweir * second: instead of comparing attributes to see whether a softfont 2514*cdf0e10cSrcweir * is duplicate to a builtin one could simply compare the PSName (which is 2515*cdf0e10cSrcweir * supposed to be unique), which at this point is just an int. 2516*cdf0e10cSrcweir * drawback: this could change which fonts are listed; especially TrueType 2517*cdf0e10cSrcweir * fonts often have a rather dubious PSName, so this could change the 2518*cdf0e10cSrcweir * font list not so subtle. 2519*cdf0e10cSrcweir * Until getFontList for a printer becomes a performance issue (which is 2520*cdf0e10cSrcweir * currently not the case), best stay with the current algorithm. 2521*cdf0e10cSrcweir */ 2522*cdf0e10cSrcweir 2523*cdf0e10cSrcweir // fill sets of printer supported fonts 2524*cdf0e10cSrcweir if( pParser ) 2525*cdf0e10cSrcweir { 2526*cdf0e10cSrcweir std::set<int> aBuiltinPSNames; 2527*cdf0e10cSrcweir std::hash_set< BuiltinFontIdentifier, 2528*cdf0e10cSrcweir BuiltinFontIdentifierHash 2529*cdf0e10cSrcweir > aBuiltinFonts; 2530*cdf0e10cSrcweir 2531*cdf0e10cSrcweir std::map<int, fontID > aOverridePSNames; 2532*cdf0e10cSrcweir if( bUseOverrideMetrics ) 2533*cdf0e10cSrcweir { 2534*cdf0e10cSrcweir readOverrideMetrics(); 2535*cdf0e10cSrcweir for( std::vector<fontID>::const_iterator over = m_aOverrideFonts.begin(); 2536*cdf0e10cSrcweir over != m_aOverrideFonts.end(); ++over ) 2537*cdf0e10cSrcweir { 2538*cdf0e10cSrcweir std::hash_map<fontID,PrintFont*>::const_iterator font_it = m_aFonts.find( *over ); 2539*cdf0e10cSrcweir DBG_ASSERT( font_it != m_aFonts.end(), "override to nonexistant font" ); 2540*cdf0e10cSrcweir if( font_it != m_aFonts.end() ) 2541*cdf0e10cSrcweir aOverridePSNames[ font_it->second->m_nPSName ] = *over; 2542*cdf0e10cSrcweir } 2543*cdf0e10cSrcweir } 2544*cdf0e10cSrcweir 2545*cdf0e10cSrcweir int nFonts = pParser->getFonts(); 2546*cdf0e10cSrcweir for( int i = 0; i < nFonts; i++ ) 2547*cdf0e10cSrcweir aBuiltinPSNames.insert( m_pAtoms->getAtom( ATOM_PSNAME, pParser->getFont( i ) ) ); 2548*cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2549*cdf0e10cSrcweir { 2550*cdf0e10cSrcweir PrintFont* pFont = it->second; 2551*cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin && 2552*cdf0e10cSrcweir aBuiltinPSNames.find( pFont->m_nPSName ) != aBuiltinPSNames.end() ) 2553*cdf0e10cSrcweir { 2554*cdf0e10cSrcweir bool bInsert = true; 2555*cdf0e10cSrcweir if( bUseOverrideMetrics ) 2556*cdf0e10cSrcweir { 2557*cdf0e10cSrcweir // in override case only use the override fonts, not their counterparts 2558*cdf0e10cSrcweir std::map<int,fontID>::const_iterator over = aOverridePSNames.find( pFont->m_nPSName ); 2559*cdf0e10cSrcweir if( over != aOverridePSNames.end() && over->second != it->first ) 2560*cdf0e10cSrcweir bInsert = false; 2561*cdf0e10cSrcweir } 2562*cdf0e10cSrcweir else 2563*cdf0e10cSrcweir { 2564*cdf0e10cSrcweir // do not insert override fonts in non override case 2565*cdf0e10cSrcweir if( std::find( m_aOverrideFonts.begin(), m_aOverrideFonts.end(), it->first ) != m_aOverrideFonts.end() ) 2566*cdf0e10cSrcweir bInsert = false; 2567*cdf0e10cSrcweir } 2568*cdf0e10cSrcweir if( bInsert ) 2569*cdf0e10cSrcweir { 2570*cdf0e10cSrcweir aBuiltinFonts.insert( BuiltinFontIdentifier( 2571*cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ), 2572*cdf0e10cSrcweir pFont->m_eItalic, 2573*cdf0e10cSrcweir pFont->m_eWeight, 2574*cdf0e10cSrcweir pFont->m_ePitch, 2575*cdf0e10cSrcweir pFont->m_aEncoding 2576*cdf0e10cSrcweir ) ); 2577*cdf0e10cSrcweir } 2578*cdf0e10cSrcweir } 2579*cdf0e10cSrcweir } 2580*cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2581*cdf0e10cSrcweir { 2582*cdf0e10cSrcweir PrintFont* pFont = it->second; 2583*cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin ) 2584*cdf0e10cSrcweir { 2585*cdf0e10cSrcweir if( aBuiltinPSNames.find( pFont->m_nPSName ) != aBuiltinPSNames.end() ) 2586*cdf0e10cSrcweir { 2587*cdf0e10cSrcweir bool bInsert = true; 2588*cdf0e10cSrcweir if( bUseOverrideMetrics ) 2589*cdf0e10cSrcweir { 2590*cdf0e10cSrcweir // in override case only use the override fonts, not their counterparts 2591*cdf0e10cSrcweir std::map<int,fontID>::const_iterator over = aOverridePSNames.find( pFont->m_nPSName ); 2592*cdf0e10cSrcweir if( over != aOverridePSNames.end() && over->second != it->first ) 2593*cdf0e10cSrcweir bInsert = false; 2594*cdf0e10cSrcweir } 2595*cdf0e10cSrcweir else 2596*cdf0e10cSrcweir { 2597*cdf0e10cSrcweir // do not insert override fonts in non override case 2598*cdf0e10cSrcweir if( std::find( m_aOverrideFonts.begin(), m_aOverrideFonts.end(), it->first ) != m_aOverrideFonts.end() ) 2599*cdf0e10cSrcweir bInsert = false; 2600*cdf0e10cSrcweir } 2601*cdf0e10cSrcweir if( bInsert ) 2602*cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2603*cdf0e10cSrcweir } 2604*cdf0e10cSrcweir } 2605*cdf0e10cSrcweir else if( aBuiltinFonts.find( BuiltinFontIdentifier( 2606*cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ), 2607*cdf0e10cSrcweir pFont->m_eItalic, 2608*cdf0e10cSrcweir pFont->m_eWeight, 2609*cdf0e10cSrcweir pFont->m_ePitch, 2610*cdf0e10cSrcweir pFont->m_aEncoding 2611*cdf0e10cSrcweir ) ) == aBuiltinFonts.end() ) 2612*cdf0e10cSrcweir { 2613*cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2614*cdf0e10cSrcweir } 2615*cdf0e10cSrcweir } 2616*cdf0e10cSrcweir } 2617*cdf0e10cSrcweir else // no specific printer 2618*cdf0e10cSrcweir { 2619*cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2620*cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2621*cdf0e10cSrcweir } 2622*cdf0e10cSrcweir } 2623*cdf0e10cSrcweir 2624*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2625*cdf0e10cSrcweir 2626*cdf0e10cSrcweir void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& rInfo ) const 2627*cdf0e10cSrcweir { 2628*cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator style_it = 2629*cdf0e10cSrcweir m_aFamilyTypes.find( pFont->m_nFamilyName ); 2630*cdf0e10cSrcweir rInfo.m_eType = pFont->m_eType; 2631*cdf0e10cSrcweir rInfo.m_aFamilyName = m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ); 2632*cdf0e10cSrcweir rInfo.m_aStyleName = pFont->m_aStyleName; 2633*cdf0e10cSrcweir rInfo.m_eFamilyStyle = style_it != m_aFamilyTypes.end() ? style_it->second : family::Unknown; 2634*cdf0e10cSrcweir rInfo.m_eItalic = pFont->m_eItalic; 2635*cdf0e10cSrcweir rInfo.m_eWidth = pFont->m_eWidth; 2636*cdf0e10cSrcweir rInfo.m_eWeight = pFont->m_eWeight; 2637*cdf0e10cSrcweir rInfo.m_ePitch = pFont->m_ePitch; 2638*cdf0e10cSrcweir rInfo.m_aEncoding = pFont->m_aEncoding; 2639*cdf0e10cSrcweir 2640*cdf0e10cSrcweir rInfo.m_bEmbeddable = (pFont->m_eType == fonttype::Type1); 2641*cdf0e10cSrcweir rInfo.m_bSubsettable = (pFont->m_eType == fonttype::TrueType); // TODO: rename to SfntType 2642*cdf0e10cSrcweir 2643*cdf0e10cSrcweir rInfo.m_aAliases.clear(); 2644*cdf0e10cSrcweir for( ::std::list< int >::iterator it = pFont->m_aAliases.begin(); it != pFont->m_aAliases.end(); ++it ) 2645*cdf0e10cSrcweir rInfo.m_aAliases.push_back( m_pAtoms->getString( ATOM_FAMILYNAME, *it ) ); 2646*cdf0e10cSrcweir } 2647*cdf0e10cSrcweir 2648*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2649*cdf0e10cSrcweir 2650*cdf0e10cSrcweir void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, PrintFontInfo& rInfo ) const 2651*cdf0e10cSrcweir { 2652*cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) || 2653*cdf0e10cSrcweir ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 2654*cdf0e10cSrcweir ) 2655*cdf0e10cSrcweir { 2656*cdf0e10cSrcweir // might be a truetype font not analyzed or type1 without metrics read 2657*cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 ) 2658*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 2659*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 2660*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2661*cdf0e10cSrcweir } 2662*cdf0e10cSrcweir 2663*cdf0e10cSrcweir fillPrintFontInfo( pFont, static_cast< FastPrintFontInfo& >( rInfo ) ); 2664*cdf0e10cSrcweir 2665*cdf0e10cSrcweir rInfo.m_nAscend = pFont->m_nAscend; 2666*cdf0e10cSrcweir rInfo.m_nDescend = pFont->m_nDescend; 2667*cdf0e10cSrcweir rInfo.m_nLeading = pFont->m_nLeading; 2668*cdf0e10cSrcweir rInfo.m_nWidth = pFont->m_aGlobalMetricX.width < pFont->m_aGlobalMetricY.width ? pFont->m_aGlobalMetricY.width : pFont->m_aGlobalMetricX.width; 2669*cdf0e10cSrcweir } 2670*cdf0e10cSrcweir 2671*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2672*cdf0e10cSrcweir 2673*cdf0e10cSrcweir void PrintFontManager::getFontListWithInfo( ::std::list< PrintFontInfo >& rFonts, const PPDParser* pParser, bool bUseOverrideMetrics ) 2674*cdf0e10cSrcweir { 2675*cdf0e10cSrcweir rFonts.clear(); 2676*cdf0e10cSrcweir ::std::list< fontID > aFontList; 2677*cdf0e10cSrcweir getFontList( aFontList, pParser, bUseOverrideMetrics ); 2678*cdf0e10cSrcweir 2679*cdf0e10cSrcweir ::std::list< fontID >::iterator it; 2680*cdf0e10cSrcweir for( it = aFontList.begin(); it != aFontList.end(); ++it ) 2681*cdf0e10cSrcweir { 2682*cdf0e10cSrcweir PrintFontInfo aInfo; 2683*cdf0e10cSrcweir aInfo.m_nID = *it; 2684*cdf0e10cSrcweir fillPrintFontInfo( getFont( *it ), aInfo ); 2685*cdf0e10cSrcweir rFonts.push_back( aInfo ); 2686*cdf0e10cSrcweir } 2687*cdf0e10cSrcweir } 2688*cdf0e10cSrcweir 2689*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2690*cdf0e10cSrcweir 2691*cdf0e10cSrcweir void PrintFontManager::getFontListWithFastInfo( ::std::list< FastPrintFontInfo >& rFonts, const PPDParser* pParser, bool bUseOverrideMetrics ) 2692*cdf0e10cSrcweir { 2693*cdf0e10cSrcweir rFonts.clear(); 2694*cdf0e10cSrcweir ::std::list< fontID > aFontList; 2695*cdf0e10cSrcweir getFontList( aFontList, pParser, bUseOverrideMetrics ); 2696*cdf0e10cSrcweir 2697*cdf0e10cSrcweir ::std::list< fontID >::iterator it; 2698*cdf0e10cSrcweir for( it = aFontList.begin(); it != aFontList.end(); ++it ) 2699*cdf0e10cSrcweir { 2700*cdf0e10cSrcweir FastPrintFontInfo aInfo; 2701*cdf0e10cSrcweir aInfo.m_nID = *it; 2702*cdf0e10cSrcweir fillPrintFontInfo( getFont( *it ), aInfo ); 2703*cdf0e10cSrcweir rFonts.push_back( aInfo ); 2704*cdf0e10cSrcweir } 2705*cdf0e10cSrcweir } 2706*cdf0e10cSrcweir 2707*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2708*cdf0e10cSrcweir 2709*cdf0e10cSrcweir bool PrintFontManager::getFontInfo( fontID nFontID, PrintFontInfo& rInfo ) const 2710*cdf0e10cSrcweir { 2711*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2712*cdf0e10cSrcweir if( pFont ) 2713*cdf0e10cSrcweir { 2714*cdf0e10cSrcweir rInfo.m_nID = nFontID; 2715*cdf0e10cSrcweir fillPrintFontInfo( pFont, rInfo ); 2716*cdf0e10cSrcweir } 2717*cdf0e10cSrcweir return pFont ? true : false; 2718*cdf0e10cSrcweir } 2719*cdf0e10cSrcweir 2720*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2721*cdf0e10cSrcweir 2722*cdf0e10cSrcweir bool PrintFontManager::getFontFastInfo( fontID nFontID, FastPrintFontInfo& rInfo ) const 2723*cdf0e10cSrcweir { 2724*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2725*cdf0e10cSrcweir if( pFont ) 2726*cdf0e10cSrcweir { 2727*cdf0e10cSrcweir rInfo.m_nID = nFontID; 2728*cdf0e10cSrcweir fillPrintFontInfo( pFont, rInfo ); 2729*cdf0e10cSrcweir } 2730*cdf0e10cSrcweir return pFont ? true : false; 2731*cdf0e10cSrcweir } 2732*cdf0e10cSrcweir 2733*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2734*cdf0e10cSrcweir 2735*cdf0e10cSrcweir bool PrintFontManager::getFontBoundingBox( fontID nFontID, int& xMin, int& yMin, int& xMax, int& yMax ) 2736*cdf0e10cSrcweir { 2737*cdf0e10cSrcweir bool bSuccess = false; 2738*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2739*cdf0e10cSrcweir if( pFont ) 2740*cdf0e10cSrcweir { 2741*cdf0e10cSrcweir if( pFont->m_nXMin == 0 && pFont->m_nYMin == 0 && pFont->m_nXMax == 0 && pFont->m_nYMax == 0 ) 2742*cdf0e10cSrcweir { 2743*cdf0e10cSrcweir // might be a truetype font not analyzed or type1 without metrics read 2744*cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2745*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2746*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 2747*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2748*cdf0e10cSrcweir } 2749*cdf0e10cSrcweir bSuccess = true; 2750*cdf0e10cSrcweir xMin = pFont->m_nXMin; 2751*cdf0e10cSrcweir yMin = pFont->m_nYMin; 2752*cdf0e10cSrcweir xMax = pFont->m_nXMax; 2753*cdf0e10cSrcweir yMax = pFont->m_nYMax; 2754*cdf0e10cSrcweir } 2755*cdf0e10cSrcweir return bSuccess; 2756*cdf0e10cSrcweir } 2757*cdf0e10cSrcweir 2758*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2759*cdf0e10cSrcweir 2760*cdf0e10cSrcweir int PrintFontManager::getFontFaceNumber( fontID nFontID ) const 2761*cdf0e10cSrcweir { 2762*cdf0e10cSrcweir int nRet = -1; 2763*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2764*cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 2765*cdf0e10cSrcweir nRet = static_cast< TrueTypeFontFile* >(pFont)->m_nCollectionEntry; 2766*cdf0e10cSrcweir return nRet; 2767*cdf0e10cSrcweir } 2768*cdf0e10cSrcweir 2769*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2770*cdf0e10cSrcweir 2771*cdf0e10cSrcweir 2772*cdf0e10cSrcweir family::type PrintFontManager::matchFamilyName( const ::rtl::OUString& rFamily ) const 2773*cdf0e10cSrcweir { 2774*cdf0e10cSrcweir typedef struct { 2775*cdf0e10cSrcweir const char* mpName; 2776*cdf0e10cSrcweir sal_uInt16 mnLength; 2777*cdf0e10cSrcweir family::type meType; 2778*cdf0e10cSrcweir } family_t; 2779*cdf0e10cSrcweir 2780*cdf0e10cSrcweir #define InitializeClass( p, a ) p, sizeof(p) - 1, a 2781*cdf0e10cSrcweir const family_t pFamilyMatch[] = { 2782*cdf0e10cSrcweir { InitializeClass( "arial", family::Swiss ) }, 2783*cdf0e10cSrcweir { InitializeClass( "arioso", family::Script ) }, 2784*cdf0e10cSrcweir { InitializeClass( "avant garde", family::Swiss ) }, 2785*cdf0e10cSrcweir { InitializeClass( "avantgarde", family::Swiss ) }, 2786*cdf0e10cSrcweir { InitializeClass( "bembo", family::Roman ) }, 2787*cdf0e10cSrcweir { InitializeClass( "bookman", family::Roman ) }, 2788*cdf0e10cSrcweir { InitializeClass( "conga", family::Roman ) }, 2789*cdf0e10cSrcweir { InitializeClass( "courier", family::Modern ) }, 2790*cdf0e10cSrcweir { InitializeClass( "curl", family::Script ) }, 2791*cdf0e10cSrcweir { InitializeClass( "fixed", family::Modern ) }, 2792*cdf0e10cSrcweir { InitializeClass( "gill", family::Swiss ) }, 2793*cdf0e10cSrcweir { InitializeClass( "helmet", family::Modern ) }, 2794*cdf0e10cSrcweir { InitializeClass( "helvetica", family::Swiss ) }, 2795*cdf0e10cSrcweir { InitializeClass( "international", family::Modern ) }, 2796*cdf0e10cSrcweir { InitializeClass( "lucida", family::Swiss ) }, 2797*cdf0e10cSrcweir { InitializeClass( "new century schoolbook", family::Roman ) }, 2798*cdf0e10cSrcweir { InitializeClass( "palatino", family::Roman ) }, 2799*cdf0e10cSrcweir { InitializeClass( "roman", family::Roman ) }, 2800*cdf0e10cSrcweir { InitializeClass( "sans serif", family::Swiss ) }, 2801*cdf0e10cSrcweir { InitializeClass( "sansserif", family::Swiss ) }, 2802*cdf0e10cSrcweir { InitializeClass( "serf", family::Roman ) }, 2803*cdf0e10cSrcweir { InitializeClass( "serif", family::Roman ) }, 2804*cdf0e10cSrcweir { InitializeClass( "times", family::Roman ) }, 2805*cdf0e10cSrcweir { InitializeClass( "utopia", family::Roman ) }, 2806*cdf0e10cSrcweir { InitializeClass( "zapf chancery", family::Script ) }, 2807*cdf0e10cSrcweir { InitializeClass( "zapfchancery", family::Script ) } 2808*cdf0e10cSrcweir }; 2809*cdf0e10cSrcweir 2810*cdf0e10cSrcweir rtl::OString aFamily = rtl::OUStringToOString( rFamily, RTL_TEXTENCODING_ASCII_US ); 2811*cdf0e10cSrcweir sal_uInt32 nLower = 0; 2812*cdf0e10cSrcweir sal_uInt32 nUpper = sizeof(pFamilyMatch) / sizeof(pFamilyMatch[0]); 2813*cdf0e10cSrcweir 2814*cdf0e10cSrcweir while( nLower < nUpper ) 2815*cdf0e10cSrcweir { 2816*cdf0e10cSrcweir sal_uInt32 nCurrent = (nLower + nUpper) / 2; 2817*cdf0e10cSrcweir const family_t* pHaystack = pFamilyMatch + nCurrent; 2818*cdf0e10cSrcweir sal_Int32 nComparison = 2819*cdf0e10cSrcweir rtl_str_compareIgnoreAsciiCase_WithLength 2820*cdf0e10cSrcweir ( 2821*cdf0e10cSrcweir aFamily.getStr(), aFamily.getLength(), 2822*cdf0e10cSrcweir pHaystack->mpName, pHaystack->mnLength 2823*cdf0e10cSrcweir ); 2824*cdf0e10cSrcweir 2825*cdf0e10cSrcweir if( nComparison < 0 ) 2826*cdf0e10cSrcweir nUpper = nCurrent; 2827*cdf0e10cSrcweir else 2828*cdf0e10cSrcweir if( nComparison > 0 ) 2829*cdf0e10cSrcweir nLower = nCurrent + 1; 2830*cdf0e10cSrcweir else 2831*cdf0e10cSrcweir return pHaystack->meType; 2832*cdf0e10cSrcweir } 2833*cdf0e10cSrcweir 2834*cdf0e10cSrcweir return family::Unknown; 2835*cdf0e10cSrcweir } 2836*cdf0e10cSrcweir 2837*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2838*cdf0e10cSrcweir 2839*cdf0e10cSrcweir family::type PrintFontManager::getFontFamilyType( fontID nFontID ) const 2840*cdf0e10cSrcweir { 2841*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2842*cdf0e10cSrcweir if( !pFont ) 2843*cdf0e10cSrcweir return family::Unknown; 2844*cdf0e10cSrcweir 2845*cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator it = 2846*cdf0e10cSrcweir m_aFamilyTypes.find( pFont->m_nFamilyName ); 2847*cdf0e10cSrcweir return (it != m_aFamilyTypes.end()) ? it->second : family::Unknown; 2848*cdf0e10cSrcweir } 2849*cdf0e10cSrcweir 2850*cdf0e10cSrcweir 2851*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2852*cdf0e10cSrcweir 2853*cdf0e10cSrcweir const ::rtl::OUString& PrintFontManager::getFontFamily( fontID nFontID ) const 2854*cdf0e10cSrcweir { 2855*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2856*cdf0e10cSrcweir return m_pAtoms->getString( ATOM_FAMILYNAME, pFont ? pFont->m_nFamilyName : INVALID_ATOM ); 2857*cdf0e10cSrcweir } 2858*cdf0e10cSrcweir 2859*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2860*cdf0e10cSrcweir 2861*cdf0e10cSrcweir OString PrintFontManager::getAfmFile( PrintFont* pFont ) const 2862*cdf0e10cSrcweir { 2863*cdf0e10cSrcweir OString aMetricPath; 2864*cdf0e10cSrcweir if( pFont ) 2865*cdf0e10cSrcweir { 2866*cdf0e10cSrcweir switch( pFont->m_eType ) 2867*cdf0e10cSrcweir { 2868*cdf0e10cSrcweir case fonttype::Type1: 2869*cdf0e10cSrcweir { 2870*cdf0e10cSrcweir Type1FontFile* pPSFont = static_cast< Type1FontFile* >(pFont); 2871*cdf0e10cSrcweir aMetricPath = getDirectory( pPSFont->m_nDirectory ); 2872*cdf0e10cSrcweir aMetricPath += "/"; 2873*cdf0e10cSrcweir aMetricPath += pPSFont->m_aMetricFile; 2874*cdf0e10cSrcweir } 2875*cdf0e10cSrcweir break; 2876*cdf0e10cSrcweir case fonttype::Builtin: 2877*cdf0e10cSrcweir { 2878*cdf0e10cSrcweir BuiltinFont* pBuiltinFont = static_cast< BuiltinFont* >(pFont); 2879*cdf0e10cSrcweir aMetricPath = getDirectory( pBuiltinFont->m_nDirectory ); 2880*cdf0e10cSrcweir aMetricPath += "/"; 2881*cdf0e10cSrcweir aMetricPath += pBuiltinFont->m_aMetricFile; 2882*cdf0e10cSrcweir } 2883*cdf0e10cSrcweir break; 2884*cdf0e10cSrcweir default: break; 2885*cdf0e10cSrcweir } 2886*cdf0e10cSrcweir } 2887*cdf0e10cSrcweir return aMetricPath; 2888*cdf0e10cSrcweir } 2889*cdf0e10cSrcweir 2890*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2891*cdf0e10cSrcweir 2892*cdf0e10cSrcweir OString PrintFontManager::getFontFile( PrintFont* pFont ) const 2893*cdf0e10cSrcweir { 2894*cdf0e10cSrcweir OString aPath; 2895*cdf0e10cSrcweir 2896*cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::Type1 ) 2897*cdf0e10cSrcweir { 2898*cdf0e10cSrcweir Type1FontFile* pPSFont = static_cast< Type1FontFile* >(pFont); 2899*cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it = m_aAtomToDir.find( pPSFont->m_nDirectory ); 2900*cdf0e10cSrcweir aPath = it->second; 2901*cdf0e10cSrcweir aPath += "/"; 2902*cdf0e10cSrcweir aPath += pPSFont->m_aFontFile; 2903*cdf0e10cSrcweir } 2904*cdf0e10cSrcweir else if( pFont && pFont->m_eType == fonttype::TrueType ) 2905*cdf0e10cSrcweir { 2906*cdf0e10cSrcweir TrueTypeFontFile* pTTFont = static_cast< TrueTypeFontFile* >(pFont); 2907*cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it = m_aAtomToDir.find( pTTFont->m_nDirectory ); 2908*cdf0e10cSrcweir aPath = it->second; 2909*cdf0e10cSrcweir aPath += "/"; 2910*cdf0e10cSrcweir aPath += pTTFont->m_aFontFile; 2911*cdf0e10cSrcweir } 2912*cdf0e10cSrcweir return aPath; 2913*cdf0e10cSrcweir } 2914*cdf0e10cSrcweir 2915*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2916*cdf0e10cSrcweir 2917*cdf0e10cSrcweir const ::rtl::OUString& PrintFontManager::getPSName( fontID nFontID ) const 2918*cdf0e10cSrcweir { 2919*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2920*cdf0e10cSrcweir if( pFont && pFont->m_nPSName == 0 ) 2921*cdf0e10cSrcweir { 2922*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2923*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2924*cdf0e10cSrcweir } 2925*cdf0e10cSrcweir 2926*cdf0e10cSrcweir return m_pAtoms->getString( ATOM_PSNAME, pFont ? pFont->m_nPSName : INVALID_ATOM ); 2927*cdf0e10cSrcweir } 2928*cdf0e10cSrcweir 2929*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2930*cdf0e10cSrcweir 2931*cdf0e10cSrcweir const CharacterMetric& PrintFontManager::getGlobalFontMetric( fontID nFontID, bool bHorizontal ) const 2932*cdf0e10cSrcweir { 2933*cdf0e10cSrcweir static CharacterMetric aMetric; 2934*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2935*cdf0e10cSrcweir return pFont ? ( bHorizontal ? pFont->m_aGlobalMetricX : pFont->m_aGlobalMetricY ) : aMetric; 2936*cdf0e10cSrcweir } 2937*cdf0e10cSrcweir 2938*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2939*cdf0e10cSrcweir 2940*cdf0e10cSrcweir int PrintFontManager::getFontAscend( fontID nFontID ) const 2941*cdf0e10cSrcweir { 2942*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2943*cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2944*cdf0e10cSrcweir { 2945*cdf0e10cSrcweir // might be a truetype font not yet analyzed 2946*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2947*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2948*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2949*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2950*cdf0e10cSrcweir } 2951*cdf0e10cSrcweir return pFont->m_nAscend; 2952*cdf0e10cSrcweir } 2953*cdf0e10cSrcweir 2954*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2955*cdf0e10cSrcweir 2956*cdf0e10cSrcweir int PrintFontManager::getFontDescend( fontID nFontID ) const 2957*cdf0e10cSrcweir { 2958*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2959*cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2960*cdf0e10cSrcweir { 2961*cdf0e10cSrcweir // might be a truetype font not yet analyzed 2962*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2963*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2964*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2965*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2966*cdf0e10cSrcweir } 2967*cdf0e10cSrcweir return pFont->m_nDescend; 2968*cdf0e10cSrcweir } 2969*cdf0e10cSrcweir 2970*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2971*cdf0e10cSrcweir 2972*cdf0e10cSrcweir int PrintFontManager::getFontLeading( fontID nFontID ) const 2973*cdf0e10cSrcweir { 2974*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2975*cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2976*cdf0e10cSrcweir { 2977*cdf0e10cSrcweir // might be a truetype font not yet analyzed 2978*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2979*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2980*cdf0e10cSrcweir } 2981*cdf0e10cSrcweir return pFont->m_nLeading; 2982*cdf0e10cSrcweir } 2983*cdf0e10cSrcweir 2984*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2985*cdf0e10cSrcweir 2986*cdf0e10cSrcweir bool PrintFontManager::hasVerticalSubstitutions( fontID nFontID ) const 2987*cdf0e10cSrcweir { 2988*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2989*cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2990*cdf0e10cSrcweir { 2991*cdf0e10cSrcweir // might be a truetype font not yet analyzed 2992*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2993*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2994*cdf0e10cSrcweir } 2995*cdf0e10cSrcweir return pFont->m_bHaveVerticalSubstitutedGlyphs; 2996*cdf0e10cSrcweir } 2997*cdf0e10cSrcweir 2998*cdf0e10cSrcweir // ------------------------------------------------------------------------- 2999*cdf0e10cSrcweir 3000*cdf0e10cSrcweir void PrintFontManager::hasVerticalSubstitutions( fontID nFontID, 3001*cdf0e10cSrcweir const sal_Unicode* pCharacters, int nCharacters, bool* pHasSubst ) const 3002*cdf0e10cSrcweir { 3003*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3004*cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3005*cdf0e10cSrcweir { 3006*cdf0e10cSrcweir // might be a truetype font not yet analyzed 3007*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 3008*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3009*cdf0e10cSrcweir } 3010*cdf0e10cSrcweir 3011*cdf0e10cSrcweir if( ! pFont->m_bHaveVerticalSubstitutedGlyphs ) 3012*cdf0e10cSrcweir memset( pHasSubst, 0, sizeof(bool)*nCharacters ); 3013*cdf0e10cSrcweir else 3014*cdf0e10cSrcweir { 3015*cdf0e10cSrcweir for( int i = 0; i < nCharacters; i++ ) 3016*cdf0e10cSrcweir { 3017*cdf0e10cSrcweir sal_Unicode code = pCharacters[i]; 3018*cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3019*cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ code >> 11 ] & ( 1 << ( ( code >> 8 ) & 7 ) ) ) ) 3020*cdf0e10cSrcweir pFont->queryMetricPage( code >> 8, m_pAtoms ); 3021*cdf0e10cSrcweir ::std::hash_map< sal_Unicode, bool >::const_iterator it = pFont->m_pMetrics->m_bVerticalSubstitutions.find( code ); 3022*cdf0e10cSrcweir pHasSubst[i] = it != pFont->m_pMetrics->m_bVerticalSubstitutions.end(); 3023*cdf0e10cSrcweir } 3024*cdf0e10cSrcweir } 3025*cdf0e10cSrcweir } 3026*cdf0e10cSrcweir 3027*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3028*cdf0e10cSrcweir 3029*cdf0e10cSrcweir OUString PrintFontManager::getFontXLFD( fontID nFontID ) const 3030*cdf0e10cSrcweir { 3031*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3032*cdf0e10cSrcweir OUString aRet; 3033*cdf0e10cSrcweir if( pFont ) 3034*cdf0e10cSrcweir { 3035*cdf0e10cSrcweir ByteString aXLFD( getXLFD( pFont ) ); 3036*cdf0e10cSrcweir rtl_TextEncoding aEncoding = aXLFD.GetToken( 6, '-' ).Search( "utf8" ) != STRING_NOTFOUND ? RTL_TEXTENCODING_UTF8 : RTL_TEXTENCODING_ISO_8859_1; 3037*cdf0e10cSrcweir aRet = OStringToOUString( aXLFD, aEncoding ); 3038*cdf0e10cSrcweir } 3039*cdf0e10cSrcweir return aRet; 3040*cdf0e10cSrcweir } 3041*cdf0e10cSrcweir 3042*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3043*cdf0e10cSrcweir 3044*cdf0e10cSrcweir const ::std::list< KernPair >& PrintFontManager::getKernPairs( fontID nFontID, bool bVertical ) const 3045*cdf0e10cSrcweir { 3046*cdf0e10cSrcweir static ::std::list< KernPair > aEmpty; 3047*cdf0e10cSrcweir 3048*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3049*cdf0e10cSrcweir if( ! pFont ) 3050*cdf0e10cSrcweir return aEmpty; 3051*cdf0e10cSrcweir 3052*cdf0e10cSrcweir if( ! pFont->m_pMetrics || ! pFont->m_pMetrics->m_bKernPairsQueried ) 3053*cdf0e10cSrcweir pFont->queryMetricPage( 0, m_pAtoms ); 3054*cdf0e10cSrcweir if( ! pFont->m_pMetrics || ! pFont->m_pMetrics->m_bKernPairsQueried ) 3055*cdf0e10cSrcweir return aEmpty; 3056*cdf0e10cSrcweir return bVertical ? pFont->m_pMetrics->m_aYKernPairs : pFont->m_pMetrics->m_aXKernPairs; 3057*cdf0e10cSrcweir } 3058*cdf0e10cSrcweir 3059*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3060*cdf0e10cSrcweir 3061*cdf0e10cSrcweir bool PrintFontManager::isFontDownloadingAllowed( fontID nFont ) const 3062*cdf0e10cSrcweir { 3063*cdf0e10cSrcweir static const char* pEnable = getenv( "PSPRINT_ENABLE_TTF_COPYRIGHTAWARENESS" ); 3064*cdf0e10cSrcweir bool bRet = true; 3065*cdf0e10cSrcweir 3066*cdf0e10cSrcweir if( pEnable && *pEnable ) 3067*cdf0e10cSrcweir { 3068*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3069*cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 3070*cdf0e10cSrcweir { 3071*cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast<TrueTypeFontFile*>(pFont); 3072*cdf0e10cSrcweir if( pTTFontFile->m_nTypeFlags & TYPEFLAG_INVALID ) 3073*cdf0e10cSrcweir { 3074*cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 3075*cdf0e10cSrcweir ByteString aFile = getFontFile( pFont ); 3076*cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 3077*cdf0e10cSrcweir { 3078*cdf0e10cSrcweir // get type flags 3079*cdf0e10cSrcweir TTGlobalFontInfo aInfo; 3080*cdf0e10cSrcweir GetTTGlobalFontInfo( pTTFont, & aInfo ); 3081*cdf0e10cSrcweir pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; 3082*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3083*cdf0e10cSrcweir } 3084*cdf0e10cSrcweir } 3085*cdf0e10cSrcweir 3086*cdf0e10cSrcweir unsigned int nCopyrightFlags = pTTFontFile->m_nTypeFlags & TYPEFLAG_COPYRIGHT_MASK; 3087*cdf0e10cSrcweir 3088*cdf0e10cSrcweir // font embedding is allowed if either 3089*cdf0e10cSrcweir // no restriction at all (bit 1 clear) 3090*cdf0e10cSrcweir // printing allowed (bit 1 set, bit 2 set ) 3091*cdf0e10cSrcweir bRet = ! ( nCopyrightFlags & 0x02 ) || ( nCopyrightFlags & 0x04 ); 3092*cdf0e10cSrcweir } 3093*cdf0e10cSrcweir } 3094*cdf0e10cSrcweir return bRet; 3095*cdf0e10cSrcweir } 3096*cdf0e10cSrcweir 3097*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3098*cdf0e10cSrcweir 3099*cdf0e10cSrcweir bool PrintFontManager::getMetrics( fontID nFontID, const sal_Unicode* pString, int nLen, CharacterMetric* pArray, bool bVertical ) const 3100*cdf0e10cSrcweir { 3101*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3102*cdf0e10cSrcweir if( ! pFont ) 3103*cdf0e10cSrcweir return false; 3104*cdf0e10cSrcweir 3105*cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3106*cdf0e10cSrcweir || ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 3107*cdf0e10cSrcweir ) 3108*cdf0e10cSrcweir { 3109*cdf0e10cSrcweir // might be a font not yet analyzed 3110*cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 3111*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 3112*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 3113*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3114*cdf0e10cSrcweir } 3115*cdf0e10cSrcweir 3116*cdf0e10cSrcweir for( int i = 0; i < nLen; i++ ) 3117*cdf0e10cSrcweir { 3118*cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3119*cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ pString[i] >> 11 ] & ( 1 << ( ( pString[i] >> 8 ) & 7 ) ) ) ) 3120*cdf0e10cSrcweir pFont->queryMetricPage( pString[i] >> 8, m_pAtoms ); 3121*cdf0e10cSrcweir pArray[i].width = pArray[i].height = -1; 3122*cdf0e10cSrcweir if( pFont->m_pMetrics ) 3123*cdf0e10cSrcweir { 3124*cdf0e10cSrcweir int effectiveCode = pString[i]; 3125*cdf0e10cSrcweir effectiveCode |= bVertical ? 1 << 16 : 0; 3126*cdf0e10cSrcweir ::std::hash_map< int, CharacterMetric >::const_iterator it = 3127*cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.find( effectiveCode ); 3128*cdf0e10cSrcweir // if no vertical metrics are available assume rotated horizontal metrics 3129*cdf0e10cSrcweir if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) ) 3130*cdf0e10cSrcweir it = pFont->m_pMetrics->m_aMetrics.find( pString[i] ); 3131*cdf0e10cSrcweir // the character metrics are in it->second 3132*cdf0e10cSrcweir if( it != pFont->m_pMetrics->m_aMetrics.end() ) 3133*cdf0e10cSrcweir pArray[ i ] = it->second; 3134*cdf0e10cSrcweir } 3135*cdf0e10cSrcweir } 3136*cdf0e10cSrcweir 3137*cdf0e10cSrcweir return true; 3138*cdf0e10cSrcweir } 3139*cdf0e10cSrcweir 3140*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3141*cdf0e10cSrcweir 3142*cdf0e10cSrcweir bool PrintFontManager::getMetrics( fontID nFontID, sal_Unicode minCharacter, sal_Unicode maxCharacter, CharacterMetric* pArray, bool bVertical ) const 3143*cdf0e10cSrcweir { 3144*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3145*cdf0e10cSrcweir if( ! pFont ) 3146*cdf0e10cSrcweir return false; 3147*cdf0e10cSrcweir 3148*cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3149*cdf0e10cSrcweir || ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 3150*cdf0e10cSrcweir ) 3151*cdf0e10cSrcweir { 3152*cdf0e10cSrcweir // might be a font not yet analyzed 3153*cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 3154*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 3155*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 3156*cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3157*cdf0e10cSrcweir } 3158*cdf0e10cSrcweir 3159*cdf0e10cSrcweir sal_Unicode code = minCharacter; 3160*cdf0e10cSrcweir do 3161*cdf0e10cSrcweir { 3162*cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3163*cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ code >> 11 ] & ( 1 << ( ( code >> 8 ) & 7 ) ) ) ) 3164*cdf0e10cSrcweir pFont->queryMetricPage( code >> 8, m_pAtoms ); 3165*cdf0e10cSrcweir pArray[ code - minCharacter ].width = -1; 3166*cdf0e10cSrcweir pArray[ code - minCharacter ].height = -1; 3167*cdf0e10cSrcweir if( pFont->m_pMetrics ) 3168*cdf0e10cSrcweir { 3169*cdf0e10cSrcweir int effectiveCode = code; 3170*cdf0e10cSrcweir effectiveCode |= bVertical ? 1 << 16 : 0; 3171*cdf0e10cSrcweir ::std::hash_map< int, CharacterMetric >::const_iterator it = 3172*cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.find( effectiveCode ); 3173*cdf0e10cSrcweir // if no vertical metrics are available assume rotated horizontal metrics 3174*cdf0e10cSrcweir if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) ) 3175*cdf0e10cSrcweir it = pFont->m_pMetrics->m_aMetrics.find( code ); 3176*cdf0e10cSrcweir // the character metrics are in it->second 3177*cdf0e10cSrcweir if( it != pFont->m_pMetrics->m_aMetrics.end() ) 3178*cdf0e10cSrcweir pArray[ code - minCharacter ] = it->second; 3179*cdf0e10cSrcweir } 3180*cdf0e10cSrcweir } while( code++ != maxCharacter ); 3181*cdf0e10cSrcweir 3182*cdf0e10cSrcweir return true; 3183*cdf0e10cSrcweir } 3184*cdf0e10cSrcweir 3185*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3186*cdf0e10cSrcweir 3187*cdf0e10cSrcweir static bool createWriteablePath( const ByteString& rPath ) 3188*cdf0e10cSrcweir { 3189*cdf0e10cSrcweir bool bSuccess = false; 3190*cdf0e10cSrcweir 3191*cdf0e10cSrcweir if( access( rPath.GetBuffer(), W_OK ) ) 3192*cdf0e10cSrcweir { 3193*cdf0e10cSrcweir int nPos = rPath.SearchBackward( '/' ); 3194*cdf0e10cSrcweir if( nPos != STRING_NOTFOUND ) 3195*cdf0e10cSrcweir while( nPos > 0 && rPath.GetChar( nPos ) == '/' ) 3196*cdf0e10cSrcweir nPos--; 3197*cdf0e10cSrcweir 3198*cdf0e10cSrcweir if( nPos != STRING_NOTFOUND && nPos != 0 && createWriteablePath( rPath.Copy( 0, nPos+1 ) ) ) 3199*cdf0e10cSrcweir { 3200*cdf0e10cSrcweir bSuccess = mkdir( rPath.GetBuffer(), 0777 ) ? false : true; 3201*cdf0e10cSrcweir } 3202*cdf0e10cSrcweir } 3203*cdf0e10cSrcweir else 3204*cdf0e10cSrcweir bSuccess = true; 3205*cdf0e10cSrcweir 3206*cdf0e10cSrcweir return bSuccess; 3207*cdf0e10cSrcweir } 3208*cdf0e10cSrcweir 3209*cdf0e10cSrcweir 3210*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3211*cdf0e10cSrcweir 3212*cdf0e10cSrcweir int PrintFontManager::importFonts( const ::std::list< OString >& rFiles, bool bLinkOnly, ImportFontCallback* pCallback ) 3213*cdf0e10cSrcweir { 3214*cdf0e10cSrcweir int nSuccess = 0; 3215*cdf0e10cSrcweir 3216*cdf0e10cSrcweir // find a directory with write access 3217*cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 3218*cdf0e10cSrcweir bool bCanWrite = false; 3219*cdf0e10cSrcweir int nDirID = 0; 3220*cdf0e10cSrcweir INetURLObject aDir; 3221*cdf0e10cSrcweir for( ::std::list< int >::const_iterator dir_it = m_aPrivateFontDirectories.begin(); 3222*cdf0e10cSrcweir ! bCanWrite && dir_it != m_aPrivateFontDirectories.end(); ++dir_it ) 3223*cdf0e10cSrcweir { 3224*cdf0e10cSrcweir // check if we can create files in that directory 3225*cdf0e10cSrcweir ByteString aDirPath = getDirectory( *dir_it ); 3226*cdf0e10cSrcweir if( createWriteablePath( aDirPath ) ) 3227*cdf0e10cSrcweir { 3228*cdf0e10cSrcweir aDir = INetURLObject( OStringToOUString( aDirPath, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 3229*cdf0e10cSrcweir nDirID = *dir_it; 3230*cdf0e10cSrcweir bCanWrite = true; 3231*cdf0e10cSrcweir } 3232*cdf0e10cSrcweir } 3233*cdf0e10cSrcweir if( bCanWrite ) 3234*cdf0e10cSrcweir { 3235*cdf0e10cSrcweir for( ::std::list< OString >::const_iterator font_it = rFiles.begin(); 3236*cdf0e10cSrcweir font_it != rFiles.end(); ++font_it ) 3237*cdf0e10cSrcweir { 3238*cdf0e10cSrcweir INetURLObject aFrom( OStringToOUString( *font_it, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 3239*cdf0e10cSrcweir INetURLObject aTo( aDir ); 3240*cdf0e10cSrcweir aTo.Append( aFrom.GetName() ); 3241*cdf0e10cSrcweir 3242*cdf0e10cSrcweir if( pCallback ) 3243*cdf0e10cSrcweir pCallback->progress( aTo.PathToFileName() ); 3244*cdf0e10cSrcweir 3245*cdf0e10cSrcweir if( pCallback && pCallback->isCanceled() ) 3246*cdf0e10cSrcweir break; 3247*cdf0e10cSrcweir 3248*cdf0e10cSrcweir if( ! access( ByteString( String(aTo.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3249*cdf0e10cSrcweir { 3250*cdf0e10cSrcweir if( ! ( pCallback ? pCallback->queryOverwriteFile( aTo.PathToFileName() ) : false ) ) 3251*cdf0e10cSrcweir continue; 3252*cdf0e10cSrcweir } 3253*cdf0e10cSrcweir // look for afm if necessary 3254*cdf0e10cSrcweir OUString aAfmCopied; 3255*cdf0e10cSrcweir FileBase::RC nError; 3256*cdf0e10cSrcweir if( aFrom.getExtension().equalsIgnoreAsciiCaseAscii( "pfa" ) || 3257*cdf0e10cSrcweir aFrom.getExtension().equalsIgnoreAsciiCaseAscii( "pfb" ) ) 3258*cdf0e10cSrcweir { 3259*cdf0e10cSrcweir INetURLObject aFromAfm( aFrom ); 3260*cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3261*cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3262*cdf0e10cSrcweir { 3263*cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFM" ) ) ); 3264*cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3265*cdf0e10cSrcweir { 3266*cdf0e10cSrcweir aFromAfm.removeSegment(); 3267*cdf0e10cSrcweir aFromAfm.Append( String( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3268*cdf0e10cSrcweir aFromAfm.Append( aTo.GetName() ); 3269*cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3270*cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3271*cdf0e10cSrcweir { 3272*cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFM" ) ) ); 3273*cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3274*cdf0e10cSrcweir { 3275*cdf0e10cSrcweir // give up 3276*cdf0e10cSrcweir if( pCallback ) 3277*cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::NoAfmMetric ); 3278*cdf0e10cSrcweir continue; 3279*cdf0e10cSrcweir } 3280*cdf0e10cSrcweir } 3281*cdf0e10cSrcweir } 3282*cdf0e10cSrcweir } 3283*cdf0e10cSrcweir INetURLObject aToAfm( aTo ); 3284*cdf0e10cSrcweir aToAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3285*cdf0e10cSrcweir OUString aFromPath, aToPath; 3286*cdf0e10cSrcweir if( bLinkOnly ) 3287*cdf0e10cSrcweir { 3288*cdf0e10cSrcweir ByteString aLinkFromPath( String(aFromAfm.PathToFileName()), 3289*cdf0e10cSrcweir aEncoding ); 3290*cdf0e10cSrcweir ByteString aLinkToPath( String(aToAfm.PathToFileName()), 3291*cdf0e10cSrcweir aEncoding ); 3292*cdf0e10cSrcweir nError = (FileBase::RC)symlink( aLinkFromPath.GetBuffer(), aLinkToPath.GetBuffer() ); 3293*cdf0e10cSrcweir } 3294*cdf0e10cSrcweir else 3295*cdf0e10cSrcweir nError = File::copy( aFromAfm.GetMainURL(INetURLObject::DECODE_TO_IURI), aToAfm.GetMainURL(INetURLObject::DECODE_TO_IURI) ); 3296*cdf0e10cSrcweir if( nError ) 3297*cdf0e10cSrcweir { 3298*cdf0e10cSrcweir if( pCallback ) 3299*cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::AfmCopyFailed ); 3300*cdf0e10cSrcweir continue; 3301*cdf0e10cSrcweir } 3302*cdf0e10cSrcweir aAfmCopied = aToPath; 3303*cdf0e10cSrcweir } 3304*cdf0e10cSrcweir if( bLinkOnly ) 3305*cdf0e10cSrcweir { 3306*cdf0e10cSrcweir ByteString aFromPath( String(aFrom.PathToFileName()), 3307*cdf0e10cSrcweir aEncoding ); 3308*cdf0e10cSrcweir ByteString aToPath( String(aTo.PathToFileName()), aEncoding ); 3309*cdf0e10cSrcweir nError = (FileBase::RC)symlink( aFromPath.GetBuffer(), 3310*cdf0e10cSrcweir aToPath.GetBuffer() ); 3311*cdf0e10cSrcweir } 3312*cdf0e10cSrcweir else 3313*cdf0e10cSrcweir nError = File::copy( aFrom.GetMainURL(INetURLObject::DECODE_TO_IURI), aTo.GetMainURL(INetURLObject::DECODE_TO_IURI) ); 3314*cdf0e10cSrcweir // copy font file 3315*cdf0e10cSrcweir if( nError ) 3316*cdf0e10cSrcweir { 3317*cdf0e10cSrcweir if( aAfmCopied.getLength() ) 3318*cdf0e10cSrcweir File::remove( aAfmCopied ); 3319*cdf0e10cSrcweir if( pCallback ) 3320*cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::FontCopyFailed ); 3321*cdf0e10cSrcweir continue; 3322*cdf0e10cSrcweir } 3323*cdf0e10cSrcweir 3324*cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 3325*cdf0e10cSrcweir ::std::list< PrintFont* >::iterator it; 3326*cdf0e10cSrcweir if( analyzeFontFile( nDirID, OUStringToOString( aTo.GetName(), aEncoding ), ::std::list<OString>(), aNewFonts ) ) 3327*cdf0e10cSrcweir { 3328*cdf0e10cSrcweir // remove all fonts for the same file 3329*cdf0e10cSrcweir // discarding their font ids 3330*cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::iterator current, next; 3331*cdf0e10cSrcweir current = m_aFonts.begin(); 3332*cdf0e10cSrcweir OString aFileName( OUStringToOString( aTo.GetName(), aEncoding ) ); 3333*cdf0e10cSrcweir while( current != m_aFonts.end() ) 3334*cdf0e10cSrcweir { 3335*cdf0e10cSrcweir bool bRemove = false; 3336*cdf0e10cSrcweir switch( current->second->m_eType ) 3337*cdf0e10cSrcweir { 3338*cdf0e10cSrcweir case fonttype::Type1: 3339*cdf0e10cSrcweir if( static_cast<Type1FontFile*>(current->second)->m_aFontFile == aFileName ) 3340*cdf0e10cSrcweir bRemove = true; 3341*cdf0e10cSrcweir break; 3342*cdf0e10cSrcweir case fonttype::TrueType: 3343*cdf0e10cSrcweir if( static_cast<TrueTypeFontFile*>(current->second)->m_aFontFile == aFileName ) 3344*cdf0e10cSrcweir bRemove = true; 3345*cdf0e10cSrcweir break; 3346*cdf0e10cSrcweir default: break; 3347*cdf0e10cSrcweir } 3348*cdf0e10cSrcweir if( bRemove ) 3349*cdf0e10cSrcweir { 3350*cdf0e10cSrcweir next = current; 3351*cdf0e10cSrcweir ++next; 3352*cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].erase( current->first ); 3353*cdf0e10cSrcweir delete current->second; 3354*cdf0e10cSrcweir m_aFonts.erase( current ); 3355*cdf0e10cSrcweir current = next; 3356*cdf0e10cSrcweir } 3357*cdf0e10cSrcweir else 3358*cdf0e10cSrcweir ++current; 3359*cdf0e10cSrcweir } 3360*cdf0e10cSrcweir 3361*cdf0e10cSrcweir DBG_ASSERT( !findFontFileID( nDirID, aFileName ), "not all fonts removed for file" ); 3362*cdf0e10cSrcweir 3363*cdf0e10cSrcweir nSuccess++; 3364*cdf0e10cSrcweir for( it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) 3365*cdf0e10cSrcweir { 3366*cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); 3367*cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = *it; 3368*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, false ); 3369*cdf0e10cSrcweir } 3370*cdf0e10cSrcweir } 3371*cdf0e10cSrcweir } 3372*cdf0e10cSrcweir 3373*cdf0e10cSrcweir m_pFontCache->updateDirTimestamp( nDirID ); 3374*cdf0e10cSrcweir m_pFontCache->flush(); 3375*cdf0e10cSrcweir } 3376*cdf0e10cSrcweir else if( pCallback ) 3377*cdf0e10cSrcweir pCallback->importFontsFailed( ImportFontCallback::NoWritableDirectory ); 3378*cdf0e10cSrcweir 3379*cdf0e10cSrcweir return nSuccess; 3380*cdf0e10cSrcweir } 3381*cdf0e10cSrcweir 3382*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3383*cdf0e10cSrcweir 3384*cdf0e10cSrcweir bool PrintFontManager::checkImportPossible() const 3385*cdf0e10cSrcweir { 3386*cdf0e10cSrcweir bool bSuccess = false; 3387*cdf0e10cSrcweir 3388*cdf0e10cSrcweir // find a directory with write access 3389*cdf0e10cSrcweir ByteString aDir; 3390*cdf0e10cSrcweir for( std::list< int >::const_iterator dir_it = m_aPrivateFontDirectories.begin(); 3391*cdf0e10cSrcweir dir_it != m_aPrivateFontDirectories.end(); ++dir_it ) 3392*cdf0e10cSrcweir { 3393*cdf0e10cSrcweir aDir = getDirectory( *dir_it ); 3394*cdf0e10cSrcweir if( createWriteablePath( aDir ) ) 3395*cdf0e10cSrcweir { 3396*cdf0e10cSrcweir bSuccess = true; 3397*cdf0e10cSrcweir break; 3398*cdf0e10cSrcweir } 3399*cdf0e10cSrcweir } 3400*cdf0e10cSrcweir 3401*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3402*cdf0e10cSrcweir if( bSuccess ) 3403*cdf0e10cSrcweir fprintf( stderr, "found writable %s\n", aDir.GetBuffer() ); 3404*cdf0e10cSrcweir #endif 3405*cdf0e10cSrcweir 3406*cdf0e10cSrcweir return bSuccess; 3407*cdf0e10cSrcweir } 3408*cdf0e10cSrcweir 3409*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3410*cdf0e10cSrcweir 3411*cdf0e10cSrcweir bool PrintFontManager::checkChangeFontPropertiesPossible( fontID /*nFontID*/ ) const 3412*cdf0e10cSrcweir { 3413*cdf0e10cSrcweir // since font properties are changed in the font cache file only nowadays 3414*cdf0e10cSrcweir // they can always be changed 3415*cdf0e10cSrcweir return true; 3416*cdf0e10cSrcweir } 3417*cdf0e10cSrcweir 3418*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3419*cdf0e10cSrcweir 3420*cdf0e10cSrcweir bool PrintFontManager::changeFontProperties( fontID nFontID, const ::rtl::OUString& rXLFD ) 3421*cdf0e10cSrcweir { 3422*cdf0e10cSrcweir ByteString aXLFD( OUStringToOString( rXLFD, RTL_TEXTENCODING_UTF8 ) ); 3423*cdf0e10cSrcweir ByteString aAddStyle = aXLFD.GetToken( '-', 6 ); 3424*cdf0e10cSrcweir if( aAddStyle.Search( "utf8" ) == STRING_NOTFOUND ) 3425*cdf0e10cSrcweir { 3426*cdf0e10cSrcweir aAddStyle.Append( aAddStyle.Len() ? ";utf8" : "utf8" ); 3427*cdf0e10cSrcweir aXLFD.SetToken( 6, ';', aAddStyle ); 3428*cdf0e10cSrcweir } 3429*cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3430*cdf0e10cSrcweir std::list< OString > aDummyList; 3431*cdf0e10cSrcweir aDummyList.push_back( aXLFD ); 3432*cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, aDummyList ); 3433*cdf0e10cSrcweir pFont->m_bUserOverride = true; 3434*cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( pFont, true ); 3435*cdf0e10cSrcweir 3436*cdf0e10cSrcweir return true; 3437*cdf0e10cSrcweir } 3438*cdf0e10cSrcweir 3439*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3440*cdf0e10cSrcweir 3441*cdf0e10cSrcweir bool PrintFontManager:: 3442*cdf0e10cSrcweir getImportableFontProperties( 3443*cdf0e10cSrcweir const OString& rFile, 3444*cdf0e10cSrcweir ::std::list< FastPrintFontInfo >& rFontProps 3445*cdf0e10cSrcweir ) 3446*cdf0e10cSrcweir { 3447*cdf0e10cSrcweir rFontProps.clear(); 3448*cdf0e10cSrcweir int nIndex = rFile.lastIndexOf( '/' ); 3449*cdf0e10cSrcweir OString aDir, aFile( rFile.copy( nIndex+1 ) ); 3450*cdf0e10cSrcweir if( nIndex != -1 ) 3451*cdf0e10cSrcweir aDir = rFile.copy( 0, nIndex ); 3452*cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 3453*cdf0e10cSrcweir ::std::list< PrintFont* > aFonts; 3454*cdf0e10cSrcweir bool bRet = analyzeFontFile( nDirID, aFile, ::std::list<OString>(), aFonts ); 3455*cdf0e10cSrcweir while( aFonts.begin() != aFonts.end() ) 3456*cdf0e10cSrcweir { 3457*cdf0e10cSrcweir PrintFont* pFont = aFonts.front(); 3458*cdf0e10cSrcweir aFonts.pop_front(); 3459*cdf0e10cSrcweir FastPrintFontInfo aInfo; 3460*cdf0e10cSrcweir fillPrintFontInfo( pFont, aInfo ); 3461*cdf0e10cSrcweir rFontProps.push_back( aInfo ); 3462*cdf0e10cSrcweir delete pFont; 3463*cdf0e10cSrcweir } 3464*cdf0e10cSrcweir return bRet; 3465*cdf0e10cSrcweir } 3466*cdf0e10cSrcweir 3467*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3468*cdf0e10cSrcweir 3469*cdf0e10cSrcweir bool PrintFontManager::getFileDuplicates( fontID nFont, ::std::list< fontID >& rFonts ) const 3470*cdf0e10cSrcweir { 3471*cdf0e10cSrcweir bool bRet = false; 3472*cdf0e10cSrcweir 3473*cdf0e10cSrcweir rFonts.clear(); 3474*cdf0e10cSrcweir 3475*cdf0e10cSrcweir PrintFont* pSearchFont = getFont( nFont ); 3476*cdf0e10cSrcweir if( ! pSearchFont || 3477*cdf0e10cSrcweir pSearchFont->m_eType != fonttype::TrueType || 3478*cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pSearchFont)->m_nCollectionEntry == -1 3479*cdf0e10cSrcweir ) 3480*cdf0e10cSrcweir return false; 3481*cdf0e10cSrcweir 3482*cdf0e10cSrcweir OString aFile( getFontFileSysPath( nFont ) ); 3483*cdf0e10cSrcweir if( ! aFile.getLength() ) 3484*cdf0e10cSrcweir return false; 3485*cdf0e10cSrcweir 3486*cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 3487*cdf0e10cSrcweir { 3488*cdf0e10cSrcweir if( nFont != it->first ) 3489*cdf0e10cSrcweir { 3490*cdf0e10cSrcweir OString aCompFile( getFontFile( it->second ) ); 3491*cdf0e10cSrcweir if( aCompFile == aFile ) 3492*cdf0e10cSrcweir { 3493*cdf0e10cSrcweir rFonts.push_back( it->first ); 3494*cdf0e10cSrcweir bRet = true; 3495*cdf0e10cSrcweir } 3496*cdf0e10cSrcweir } 3497*cdf0e10cSrcweir } 3498*cdf0e10cSrcweir return bRet; 3499*cdf0e10cSrcweir } 3500*cdf0e10cSrcweir 3501*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3502*cdf0e10cSrcweir 3503*cdf0e10cSrcweir bool PrintFontManager::removeFonts( const ::std::list< fontID >& rFonts ) 3504*cdf0e10cSrcweir { 3505*cdf0e10cSrcweir bool bRet = true; 3506*cdf0e10cSrcweir ::std::list< fontID > aDuplicates; 3507*cdf0e10cSrcweir for( ::std::list< fontID >::const_iterator it = rFonts.begin(); it != rFonts.end(); ++it ) 3508*cdf0e10cSrcweir { 3509*cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator haveFont = m_aFonts.find( *it ); 3510*cdf0e10cSrcweir if( haveFont == m_aFonts.end() ) 3511*cdf0e10cSrcweir continue; 3512*cdf0e10cSrcweir 3513*cdf0e10cSrcweir PrintFont* pFont = haveFont->second; 3514*cdf0e10cSrcweir bool bRemoveDuplicates = getFileDuplicates( *it, aDuplicates ); 3515*cdf0e10cSrcweir ByteString aFile( getFontFile( pFont ) ); 3516*cdf0e10cSrcweir if( aFile.Len() ) 3517*cdf0e10cSrcweir { 3518*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3519*cdf0e10cSrcweir fprintf( stderr, "try unlink( \"%s\" ) ... ", aFile.GetBuffer() ); 3520*cdf0e10cSrcweir #endif 3521*cdf0e10cSrcweir if( unlink( aFile.GetBuffer() ) ) 3522*cdf0e10cSrcweir { 3523*cdf0e10cSrcweir bRet = false; 3524*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3525*cdf0e10cSrcweir fprintf( stderr, "failed\n" ); 3526*cdf0e10cSrcweir #endif 3527*cdf0e10cSrcweir continue; 3528*cdf0e10cSrcweir } 3529*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3530*cdf0e10cSrcweir fprintf( stderr, "succeeded\n" ); 3531*cdf0e10cSrcweir #endif 3532*cdf0e10cSrcweir OString aAfm( getAfmFile( pFont ) ); 3533*cdf0e10cSrcweir if( aAfm.getLength() ) 3534*cdf0e10cSrcweir { 3535*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3536*cdf0e10cSrcweir fprintf( stderr, "unlink( \"%s\" )\n", aAfm.getStr() ); 3537*cdf0e10cSrcweir #endif 3538*cdf0e10cSrcweir unlink( aAfm.getStr() ); 3539*cdf0e10cSrcweir } 3540*cdf0e10cSrcweir m_aFonts.erase( *it ); 3541*cdf0e10cSrcweir delete pFont; 3542*cdf0e10cSrcweir if( bRemoveDuplicates ) 3543*cdf0e10cSrcweir { 3544*cdf0e10cSrcweir for( ::std::list< fontID >::iterator dup = aDuplicates.begin(); dup != aDuplicates.end(); ++dup ) 3545*cdf0e10cSrcweir { 3546*cdf0e10cSrcweir m_aFontFileToFontID[ aFile ].erase( *dup ); 3547*cdf0e10cSrcweir PrintFont* pDup = m_aFonts[ *dup ]; 3548*cdf0e10cSrcweir m_aFonts.erase( *dup ); 3549*cdf0e10cSrcweir delete pDup; 3550*cdf0e10cSrcweir } 3551*cdf0e10cSrcweir } 3552*cdf0e10cSrcweir } 3553*cdf0e10cSrcweir } 3554*cdf0e10cSrcweir return bRet; 3555*cdf0e10cSrcweir } 3556*cdf0e10cSrcweir 3557*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3558*cdf0e10cSrcweir 3559*cdf0e10cSrcweir bool PrintFontManager::isPrivateFontFile( fontID nFont ) const 3560*cdf0e10cSrcweir { 3561*cdf0e10cSrcweir bool bRet = false; 3562*cdf0e10cSrcweir int nDirID = -1; 3563*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3564*cdf0e10cSrcweir if( pFont ) 3565*cdf0e10cSrcweir { 3566*cdf0e10cSrcweir switch( pFont->m_eType ) 3567*cdf0e10cSrcweir { 3568*cdf0e10cSrcweir case fonttype::Type1: nDirID = static_cast< Type1FontFile* >(pFont)->m_nDirectory;break; 3569*cdf0e10cSrcweir case fonttype::TrueType: nDirID = static_cast< TrueTypeFontFile* >(pFont)->m_nDirectory;break; 3570*cdf0e10cSrcweir default: break; 3571*cdf0e10cSrcweir } 3572*cdf0e10cSrcweir } 3573*cdf0e10cSrcweir if( nDirID != -1 ) 3574*cdf0e10cSrcweir { 3575*cdf0e10cSrcweir for( ::std::list< int >::const_iterator it = m_aPrivateFontDirectories.begin(); it != m_aPrivateFontDirectories.end(); ++it ) 3576*cdf0e10cSrcweir { 3577*cdf0e10cSrcweir if( nDirID == *it ) 3578*cdf0e10cSrcweir { 3579*cdf0e10cSrcweir bRet = true; 3580*cdf0e10cSrcweir break; 3581*cdf0e10cSrcweir } 3582*cdf0e10cSrcweir } 3583*cdf0e10cSrcweir } 3584*cdf0e10cSrcweir return bRet; 3585*cdf0e10cSrcweir } 3586*cdf0e10cSrcweir 3587*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3588*cdf0e10cSrcweir 3589*cdf0e10cSrcweir bool PrintFontManager::getAlternativeFamilyNames( fontID nFont, ::std::list< OUString >& rNames ) const 3590*cdf0e10cSrcweir { 3591*cdf0e10cSrcweir rNames.clear(); 3592*cdf0e10cSrcweir 3593*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3594*cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 3595*cdf0e10cSrcweir { 3596*cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3597*cdf0e10cSrcweir ByteString aFile( getFontFile( pFont ) ); 3598*cdf0e10cSrcweir TrueTypeFont* pTTFont; 3599*cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 3600*cdf0e10cSrcweir { 3601*cdf0e10cSrcweir NameRecord* pNameRecords = NULL; 3602*cdf0e10cSrcweir int nNameRecords = GetTTNameRecords( pTTFont, &pNameRecords ); 3603*cdf0e10cSrcweir for( int i = 0; i < nNameRecords; i++ ) 3604*cdf0e10cSrcweir { 3605*cdf0e10cSrcweir if( pNameRecords[i].nameID != 1 ) // family name 3606*cdf0e10cSrcweir continue; 3607*cdf0e10cSrcweir 3608*cdf0e10cSrcweir OUString aFamily( convertTrueTypeName( pNameRecords+i ) ); 3609*cdf0e10cSrcweir if( aFamily.getLength() 3610*cdf0e10cSrcweir && 3611*cdf0e10cSrcweir m_pAtoms->getAtom( ATOM_FAMILYNAME, aFamily, sal_True ) != pFont->m_nFamilyName 3612*cdf0e10cSrcweir ) 3613*cdf0e10cSrcweir { 3614*cdf0e10cSrcweir rNames.push_back( aFamily ); 3615*cdf0e10cSrcweir } 3616*cdf0e10cSrcweir } 3617*cdf0e10cSrcweir 3618*cdf0e10cSrcweir if( nNameRecords ) 3619*cdf0e10cSrcweir DisposeNameRecords( pNameRecords, nNameRecords ); 3620*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3621*cdf0e10cSrcweir } 3622*cdf0e10cSrcweir } 3623*cdf0e10cSrcweir return rNames.begin() != rNames.end(); 3624*cdf0e10cSrcweir } 3625*cdf0e10cSrcweir 3626*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3627*cdf0e10cSrcweir 3628*cdf0e10cSrcweir // TODO: move most of this stuff into the central font-subsetting code 3629*cdf0e10cSrcweir bool PrintFontManager::createFontSubset( 3630*cdf0e10cSrcweir FontSubsetInfo& rInfo, 3631*cdf0e10cSrcweir fontID nFont, 3632*cdf0e10cSrcweir const OUString& rOutFile, 3633*cdf0e10cSrcweir sal_Int32* pGlyphIDs, 3634*cdf0e10cSrcweir sal_uInt8* pNewEncoding, 3635*cdf0e10cSrcweir sal_Int32* pWidths, 3636*cdf0e10cSrcweir int nGlyphs, 3637*cdf0e10cSrcweir bool bVertical 3638*cdf0e10cSrcweir ) 3639*cdf0e10cSrcweir { 3640*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3641*cdf0e10cSrcweir if( !pFont ) 3642*cdf0e10cSrcweir return false; 3643*cdf0e10cSrcweir 3644*cdf0e10cSrcweir switch( pFont->m_eType ) 3645*cdf0e10cSrcweir { 3646*cdf0e10cSrcweir case psp::fonttype::TrueType: rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; break; 3647*cdf0e10cSrcweir case psp::fonttype::Type1: rInfo.m_nFontType = FontSubsetInfo::ANY_TYPE1; break; 3648*cdf0e10cSrcweir default: 3649*cdf0e10cSrcweir return false; 3650*cdf0e10cSrcweir } 3651*cdf0e10cSrcweir // TODO: remove when Type1 subsetting gets implemented 3652*cdf0e10cSrcweir if( pFont->m_eType != fonttype::TrueType ) 3653*cdf0e10cSrcweir return false; 3654*cdf0e10cSrcweir 3655*cdf0e10cSrcweir // reshuffle array of requested glyphs to make sure glyph0==notdef 3656*cdf0e10cSrcweir sal_uInt8 pEnc[256]; 3657*cdf0e10cSrcweir sal_uInt16 pGID[256]; 3658*cdf0e10cSrcweir sal_uInt8 pOldIndex[256]; 3659*cdf0e10cSrcweir memset( pEnc, 0, sizeof( pEnc ) ); 3660*cdf0e10cSrcweir memset( pGID, 0, sizeof( pGID ) ); 3661*cdf0e10cSrcweir memset( pOldIndex, 0, sizeof( pOldIndex ) ); 3662*cdf0e10cSrcweir if( nGlyphs > 256 ) 3663*cdf0e10cSrcweir return false; 3664*cdf0e10cSrcweir int nChar = 1; 3665*cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3666*cdf0e10cSrcweir { 3667*cdf0e10cSrcweir if( pNewEncoding[i] == 0 ) 3668*cdf0e10cSrcweir { 3669*cdf0e10cSrcweir pOldIndex[ 0 ] = i; 3670*cdf0e10cSrcweir } 3671*cdf0e10cSrcweir else 3672*cdf0e10cSrcweir { 3673*cdf0e10cSrcweir DBG_ASSERT( !(pGlyphIDs[i] & 0x007f0000), "overlong glyph id" ); 3674*cdf0e10cSrcweir DBG_ASSERT( (int)pNewEncoding[i] < nGlyphs, "encoding wrong" ); 3675*cdf0e10cSrcweir DBG_ASSERT( pEnc[pNewEncoding[i]] == 0 && pGID[pNewEncoding[i]] == 0, "duplicate encoded glyph" ); 3676*cdf0e10cSrcweir pEnc[ pNewEncoding[i] ] = pNewEncoding[i]; 3677*cdf0e10cSrcweir pGID[ pNewEncoding[i] ] = (sal_uInt16)pGlyphIDs[ i ]; 3678*cdf0e10cSrcweir pOldIndex[ pNewEncoding[i] ] = i; 3679*cdf0e10cSrcweir nChar++; 3680*cdf0e10cSrcweir } 3681*cdf0e10cSrcweir } 3682*cdf0e10cSrcweir nGlyphs = nChar; // either input value or increased by one 3683*cdf0e10cSrcweir 3684*cdf0e10cSrcweir // prepare system name for read access for subset source file 3685*cdf0e10cSrcweir // TODO: since this file is usually already mmapped there is no need to open it again 3686*cdf0e10cSrcweir const ByteString aFromFile = getFontFile( pFont ); 3687*cdf0e10cSrcweir 3688*cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; // TODO: rename to SfntFont 3689*cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3690*cdf0e10cSrcweir if( OpenTTFontFile( aFromFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) != SF_OK ) 3691*cdf0e10cSrcweir return false; 3692*cdf0e10cSrcweir 3693*cdf0e10cSrcweir // prepare system name for write access for subset file target 3694*cdf0e10cSrcweir OUString aSysPath; 3695*cdf0e10cSrcweir if( osl_File_E_None != osl_getSystemPathFromFileURL( rOutFile.pData, &aSysPath.pData ) ) 3696*cdf0e10cSrcweir return false; 3697*cdf0e10cSrcweir const rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 3698*cdf0e10cSrcweir const ByteString aToFile( OUStringToOString( aSysPath, aEncoding ) ); 3699*cdf0e10cSrcweir 3700*cdf0e10cSrcweir // do CFF subsetting if possible 3701*cdf0e10cSrcweir int nCffLength = 0; 3702*cdf0e10cSrcweir const sal_uInt8* pCffBytes = NULL; 3703*cdf0e10cSrcweir if( GetSfntTable( pTTFont, O_CFF, &pCffBytes, &nCffLength ) ) 3704*cdf0e10cSrcweir { 3705*cdf0e10cSrcweir rInfo.LoadFont( FontSubsetInfo::CFF_FONT, pCffBytes, nCffLength ); 3706*cdf0e10cSrcweir #if 1 // TODO: remove 16bit->long conversion when related methods handle non-16bit glyphids 3707*cdf0e10cSrcweir long aRequestedGlyphs[256]; 3708*cdf0e10cSrcweir for( int i = 0; i < nGlyphs; ++i ) 3709*cdf0e10cSrcweir aRequestedGlyphs[i] = pGID[i]; 3710*cdf0e10cSrcweir #endif 3711*cdf0e10cSrcweir // create subset file at requested path 3712*cdf0e10cSrcweir FILE* pOutFile = fopen( aToFile.GetBuffer(), "wb" ); 3713*cdf0e10cSrcweir // create font subset 3714*cdf0e10cSrcweir const char* pGlyphSetName = NULL; // TODO: better name? 3715*cdf0e10cSrcweir const bool bOK = rInfo.CreateFontSubset( 3716*cdf0e10cSrcweir FontSubsetInfo::TYPE1_PFB, 3717*cdf0e10cSrcweir pOutFile, pGlyphSetName, 3718*cdf0e10cSrcweir aRequestedGlyphs, pEnc, nGlyphs, pWidths ); 3719*cdf0e10cSrcweir fclose( pOutFile ); 3720*cdf0e10cSrcweir // cleanup before early return 3721*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3722*cdf0e10cSrcweir return bOK; 3723*cdf0e10cSrcweir } 3724*cdf0e10cSrcweir 3725*cdf0e10cSrcweir // do TTF->Type42 or Type3 subsetting 3726*cdf0e10cSrcweir // fill in font info 3727*cdf0e10cSrcweir psp::PrintFontInfo aFontInfo; 3728*cdf0e10cSrcweir if( ! getFontInfo( nFont, aFontInfo ) ) 3729*cdf0e10cSrcweir return false; 3730*cdf0e10cSrcweir 3731*cdf0e10cSrcweir rInfo.m_nAscent = aFontInfo.m_nAscend; 3732*cdf0e10cSrcweir rInfo.m_nDescent = aFontInfo.m_nDescend; 3733*cdf0e10cSrcweir rInfo.m_aPSName = getPSName( nFont ); 3734*cdf0e10cSrcweir 3735*cdf0e10cSrcweir int xMin, yMin, xMax, yMax; 3736*cdf0e10cSrcweir getFontBoundingBox( nFont, xMin, yMin, xMax, yMax ); 3737*cdf0e10cSrcweir rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) ); 3738*cdf0e10cSrcweir rInfo.m_nCapHeight = yMax; // Well ... 3739*cdf0e10cSrcweir 3740*cdf0e10cSrcweir // fill in glyph advance widths 3741*cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleGlyphMetrics( pTTFont, 3742*cdf0e10cSrcweir pGID, 3743*cdf0e10cSrcweir nGlyphs, 3744*cdf0e10cSrcweir bVertical ? 1 : 0 ); 3745*cdf0e10cSrcweir if( pMetrics ) 3746*cdf0e10cSrcweir { 3747*cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3748*cdf0e10cSrcweir pWidths[pOldIndex[i]] = pMetrics[i].adv; 3749*cdf0e10cSrcweir free( pMetrics ); 3750*cdf0e10cSrcweir } 3751*cdf0e10cSrcweir else 3752*cdf0e10cSrcweir { 3753*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3754*cdf0e10cSrcweir return false; 3755*cdf0e10cSrcweir } 3756*cdf0e10cSrcweir 3757*cdf0e10cSrcweir bool bSuccess = ( SF_OK == CreateTTFromTTGlyphs( pTTFont, 3758*cdf0e10cSrcweir aToFile.GetBuffer(), 3759*cdf0e10cSrcweir pGID, 3760*cdf0e10cSrcweir pEnc, 3761*cdf0e10cSrcweir nGlyphs, 3762*cdf0e10cSrcweir 0, 3763*cdf0e10cSrcweir NULL, 3764*cdf0e10cSrcweir 0 ) ); 3765*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3766*cdf0e10cSrcweir 3767*cdf0e10cSrcweir return bSuccess; 3768*cdf0e10cSrcweir } 3769*cdf0e10cSrcweir 3770*cdf0e10cSrcweir void PrintFontManager::getGlyphWidths( fontID nFont, 3771*cdf0e10cSrcweir bool bVertical, 3772*cdf0e10cSrcweir std::vector< sal_Int32 >& rWidths, 3773*cdf0e10cSrcweir std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) 3774*cdf0e10cSrcweir { 3775*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3776*cdf0e10cSrcweir if( !pFont || 3777*cdf0e10cSrcweir (pFont->m_eType != fonttype::TrueType && pFont->m_eType != fonttype::Type1) ) 3778*cdf0e10cSrcweir return; 3779*cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 3780*cdf0e10cSrcweir { 3781*cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 3782*cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3783*cdf0e10cSrcweir ByteString aFromFile = getFontFile( pFont ); 3784*cdf0e10cSrcweir if( OpenTTFontFile( aFromFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) != SF_OK ) 3785*cdf0e10cSrcweir return; 3786*cdf0e10cSrcweir int nGlyphs = GetTTGlyphCount( pTTFont ); 3787*cdf0e10cSrcweir if( nGlyphs > 0 ) 3788*cdf0e10cSrcweir { 3789*cdf0e10cSrcweir rWidths.resize(nGlyphs); 3790*cdf0e10cSrcweir std::vector<sal_uInt16> aGlyphIds(nGlyphs); 3791*cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3792*cdf0e10cSrcweir aGlyphIds[i] = sal_uInt16(i); 3793*cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleGlyphMetrics( pTTFont, 3794*cdf0e10cSrcweir &aGlyphIds[0], 3795*cdf0e10cSrcweir nGlyphs, 3796*cdf0e10cSrcweir bVertical ? 1 : 0 ); 3797*cdf0e10cSrcweir if( pMetrics ) 3798*cdf0e10cSrcweir { 3799*cdf0e10cSrcweir for( int i = 0; i< nGlyphs; i++ ) 3800*cdf0e10cSrcweir rWidths[i] = pMetrics[i].adv; 3801*cdf0e10cSrcweir free( pMetrics ); 3802*cdf0e10cSrcweir rUnicodeEnc.clear(); 3803*cdf0e10cSrcweir } 3804*cdf0e10cSrcweir 3805*cdf0e10cSrcweir // fill the unicode map 3806*cdf0e10cSrcweir // TODO: isn't this map already available elsewhere in the fontmanager? 3807*cdf0e10cSrcweir const sal_uInt8* pCmapData = NULL; 3808*cdf0e10cSrcweir int nCmapSize = 0; 3809*cdf0e10cSrcweir if( GetSfntTable( pTTFont, O_cmap, &pCmapData, &nCmapSize ) ) 3810*cdf0e10cSrcweir { 3811*cdf0e10cSrcweir CmapResult aCmapResult; 3812*cdf0e10cSrcweir if( ParseCMAP( pCmapData, nCmapSize, aCmapResult ) ) 3813*cdf0e10cSrcweir { 3814*cdf0e10cSrcweir const ImplFontCharMap aCharMap( aCmapResult ); 3815*cdf0e10cSrcweir for( sal_uInt32 cOld = 0;;) 3816*cdf0e10cSrcweir { 3817*cdf0e10cSrcweir // get next unicode covered by font 3818*cdf0e10cSrcweir const sal_uInt32 c = aCharMap.GetNextChar( cOld ); 3819*cdf0e10cSrcweir if( c == cOld ) 3820*cdf0e10cSrcweir break; 3821*cdf0e10cSrcweir cOld = c; 3822*cdf0e10cSrcweir #if 1 // TODO: remove when sal_Unicode covers all of unicode 3823*cdf0e10cSrcweir if( c > (sal_Unicode)~0 ) 3824*cdf0e10cSrcweir break; 3825*cdf0e10cSrcweir #endif 3826*cdf0e10cSrcweir // get the matching glyph index 3827*cdf0e10cSrcweir const sal_uInt32 nGlyphId = aCharMap.GetGlyphIndex( c ); 3828*cdf0e10cSrcweir // update the requested map 3829*cdf0e10cSrcweir rUnicodeEnc[ (sal_Unicode)c ] = nGlyphId; 3830*cdf0e10cSrcweir } 3831*cdf0e10cSrcweir } 3832*cdf0e10cSrcweir } 3833*cdf0e10cSrcweir } 3834*cdf0e10cSrcweir CloseTTFont( pTTFont ); 3835*cdf0e10cSrcweir } 3836*cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 ) 3837*cdf0e10cSrcweir { 3838*cdf0e10cSrcweir if( ! pFont->m_aEncodingVector.size() ) 3839*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, true, true ); 3840*cdf0e10cSrcweir if( pFont->m_pMetrics ) 3841*cdf0e10cSrcweir { 3842*cdf0e10cSrcweir rUnicodeEnc.clear(); 3843*cdf0e10cSrcweir rWidths.clear(); 3844*cdf0e10cSrcweir rWidths.reserve( pFont->m_pMetrics->m_aMetrics.size() ); 3845*cdf0e10cSrcweir for( std::hash_map< int, CharacterMetric >::const_iterator it = 3846*cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.begin(); 3847*cdf0e10cSrcweir it != pFont->m_pMetrics->m_aMetrics.end(); ++it ) 3848*cdf0e10cSrcweir { 3849*cdf0e10cSrcweir if( (it->first & 0x00010000) == 0 || bVertical ) 3850*cdf0e10cSrcweir { 3851*cdf0e10cSrcweir rUnicodeEnc[ sal_Unicode(it->first & 0x0000ffff) ] = sal_uInt32(rWidths.size()); 3852*cdf0e10cSrcweir rWidths.push_back( it->second.width ); 3853*cdf0e10cSrcweir } 3854*cdf0e10cSrcweir } 3855*cdf0e10cSrcweir } 3856*cdf0e10cSrcweir } 3857*cdf0e10cSrcweir } 3858*cdf0e10cSrcweir 3859*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3860*cdf0e10cSrcweir 3861*cdf0e10cSrcweir const std::map< sal_Unicode, sal_Int32 >* PrintFontManager::getEncodingMap( fontID nFont, const std::map< sal_Unicode, rtl::OString >** pNonEncoded ) const 3862*cdf0e10cSrcweir { 3863*cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3864*cdf0e10cSrcweir if( !pFont || 3865*cdf0e10cSrcweir (pFont->m_eType != fonttype::Type1 && pFont->m_eType != fonttype::Builtin) 3866*cdf0e10cSrcweir ) 3867*cdf0e10cSrcweir return NULL; 3868*cdf0e10cSrcweir 3869*cdf0e10cSrcweir if( ! pFont->m_aEncodingVector.size() ) 3870*cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, true, true ); 3871*cdf0e10cSrcweir 3872*cdf0e10cSrcweir if( pNonEncoded ) 3873*cdf0e10cSrcweir *pNonEncoded = pFont->m_aNonEncoded.size() ? &pFont->m_aNonEncoded : NULL; 3874*cdf0e10cSrcweir 3875*cdf0e10cSrcweir return pFont->m_aEncodingVector.size() ? &pFont->m_aEncodingVector : NULL; 3876*cdf0e10cSrcweir } 3877*cdf0e10cSrcweir 3878*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3879*cdf0e10cSrcweir 3880*cdf0e10cSrcweir std::list< OString > PrintFontManager::getAdobeNameFromUnicode( sal_Unicode aChar ) const 3881*cdf0e10cSrcweir { 3882*cdf0e10cSrcweir std::pair< std::hash_multimap< sal_Unicode, rtl::OString >::const_iterator, 3883*cdf0e10cSrcweir std::hash_multimap< sal_Unicode, rtl::OString >::const_iterator > range 3884*cdf0e10cSrcweir = m_aUnicodeToAdobename.equal_range( aChar ); 3885*cdf0e10cSrcweir 3886*cdf0e10cSrcweir std::list< OString > aRet; 3887*cdf0e10cSrcweir for( ; range.first != range.second; ++range.first ) 3888*cdf0e10cSrcweir aRet.push_back( range.first->second ); 3889*cdf0e10cSrcweir 3890*cdf0e10cSrcweir if( aRet.begin() == aRet.end() && aChar != 0 ) 3891*cdf0e10cSrcweir { 3892*cdf0e10cSrcweir sal_Char aBuf[8]; 3893*cdf0e10cSrcweir sal_Int32 nChars = snprintf( (char*)aBuf, sizeof( aBuf ), "uni%.4hX", aChar ); 3894*cdf0e10cSrcweir aRet.push_back( OString( aBuf, nChars ) ); 3895*cdf0e10cSrcweir } 3896*cdf0e10cSrcweir 3897*cdf0e10cSrcweir return aRet; 3898*cdf0e10cSrcweir } 3899*cdf0e10cSrcweir 3900*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3901*cdf0e10cSrcweir std::list< sal_Unicode > PrintFontManager::getUnicodeFromAdobeName( const rtl::OString& rName ) const 3902*cdf0e10cSrcweir { 3903*cdf0e10cSrcweir std::pair< std::hash_multimap< rtl::OString, sal_Unicode, rtl::OStringHash >::const_iterator, 3904*cdf0e10cSrcweir std::hash_multimap< rtl::OString, sal_Unicode, rtl::OStringHash >::const_iterator > range 3905*cdf0e10cSrcweir = m_aAdobenameToUnicode.equal_range( rName ); 3906*cdf0e10cSrcweir 3907*cdf0e10cSrcweir std::list< sal_Unicode > aRet; 3908*cdf0e10cSrcweir for( ; range.first != range.second; ++range.first ) 3909*cdf0e10cSrcweir aRet.push_back( range.first->second ); 3910*cdf0e10cSrcweir 3911*cdf0e10cSrcweir if( aRet.begin() == aRet.end() ) 3912*cdf0e10cSrcweir { 3913*cdf0e10cSrcweir if( rName.getLength() == 7 && rName.indexOf( "uni" ) == 0 ) 3914*cdf0e10cSrcweir { 3915*cdf0e10cSrcweir sal_Unicode aCode = (sal_Unicode)rName.copy( 3 ).toInt32( 16 ); 3916*cdf0e10cSrcweir aRet.push_back( aCode ); 3917*cdf0e10cSrcweir } 3918*cdf0e10cSrcweir } 3919*cdf0e10cSrcweir 3920*cdf0e10cSrcweir return aRet; 3921*cdf0e10cSrcweir } 3922*cdf0e10cSrcweir 3923*cdf0e10cSrcweir // ------------------------------------------------------------------------- 3924*cdf0e10cSrcweir namespace 3925*cdf0e10cSrcweir { 3926*cdf0e10cSrcweir OUString getString( const Any& rAny ) 3927*cdf0e10cSrcweir { 3928*cdf0e10cSrcweir OUString aStr; 3929*cdf0e10cSrcweir rAny >>= aStr; 3930*cdf0e10cSrcweir return aStr; 3931*cdf0e10cSrcweir } 3932*cdf0e10cSrcweir bool getBool( const Any& rAny ) 3933*cdf0e10cSrcweir { 3934*cdf0e10cSrcweir sal_Bool bBool = sal_False; 3935*cdf0e10cSrcweir rAny >>= bBool; 3936*cdf0e10cSrcweir return static_cast<bool>(bBool); 3937*cdf0e10cSrcweir } 3938*cdf0e10cSrcweir sal_Int32 getInt( const Any& rAny ) 3939*cdf0e10cSrcweir { 3940*cdf0e10cSrcweir sal_Int32 n = 0; 3941*cdf0e10cSrcweir rAny >>= n; 3942*cdf0e10cSrcweir return n; 3943*cdf0e10cSrcweir } 3944*cdf0e10cSrcweir } 3945*cdf0e10cSrcweir bool PrintFontManager::readOverrideMetrics() 3946*cdf0e10cSrcweir { 3947*cdf0e10cSrcweir if( ! m_aOverrideFonts.empty() ) 3948*cdf0e10cSrcweir return false; 3949*cdf0e10cSrcweir 3950*cdf0e10cSrcweir css::uno::Reference< XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory() ); 3951*cdf0e10cSrcweir if( !xFact.is() ) 3952*cdf0e10cSrcweir return false; 3953*cdf0e10cSrcweir css::uno::Reference< XMaterialHolder > xMat( 3954*cdf0e10cSrcweir xFact->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.psprint.CompatMetricOverride" ) ) ), 3955*cdf0e10cSrcweir UNO_QUERY ); 3956*cdf0e10cSrcweir if( !xMat.is() ) 3957*cdf0e10cSrcweir return false; 3958*cdf0e10cSrcweir 3959*cdf0e10cSrcweir Any aAny( xMat->getMaterial() ); 3960*cdf0e10cSrcweir Sequence< Any > aOverrideFonts; 3961*cdf0e10cSrcweir if( ! (aAny >>= aOverrideFonts ) ) 3962*cdf0e10cSrcweir return false; 3963*cdf0e10cSrcweir sal_Int32 nFonts = aOverrideFonts.getLength(); 3964*cdf0e10cSrcweir for( sal_Int32 i = 0; i < nFonts; i++ ) 3965*cdf0e10cSrcweir { 3966*cdf0e10cSrcweir Sequence< NamedValue > aMetrics; 3967*cdf0e10cSrcweir if( ! (aOverrideFonts.getConstArray()[i] >>= aMetrics) ) 3968*cdf0e10cSrcweir continue; 3969*cdf0e10cSrcweir BuiltinFont* pFont = new BuiltinFont(); 3970*cdf0e10cSrcweir pFont->m_nDirectory = 0; 3971*cdf0e10cSrcweir pFont->m_bUserOverride = false; 3972*cdf0e10cSrcweir pFont->m_pMetrics = new PrintFontMetrics; 3973*cdf0e10cSrcweir memset( pFont->m_pMetrics->m_aPages, 0xff, sizeof( pFont->m_pMetrics->m_aPages ) ); 3974*cdf0e10cSrcweir pFont->m_pMetrics->m_bKernPairsQueried = true; 3975*cdf0e10cSrcweir sal_Int32 nProps = aMetrics.getLength(); 3976*cdf0e10cSrcweir const NamedValue* pProps = aMetrics.getConstArray(); 3977*cdf0e10cSrcweir for( sal_Int32 n = 0; n < nProps; n++ ) 3978*cdf0e10cSrcweir { 3979*cdf0e10cSrcweir if( pProps[n].Name.equalsAscii( "FamilyName" ) ) 3980*cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, 3981*cdf0e10cSrcweir getString(pProps[n].Value), 3982*cdf0e10cSrcweir sal_True ); 3983*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "PSName" ) ) 3984*cdf0e10cSrcweir pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, 3985*cdf0e10cSrcweir getString(pProps[n].Value), 3986*cdf0e10cSrcweir sal_True ); 3987*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "StyleName" ) ) 3988*cdf0e10cSrcweir pFont->m_aStyleName = getString(pProps[n].Value); 3989*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Italic" ) ) 3990*cdf0e10cSrcweir pFont->m_eItalic = static_cast<italic::type>(getInt(pProps[n].Value)); 3991*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Width" ) ) 3992*cdf0e10cSrcweir pFont->m_eWidth = static_cast<width::type>(getInt(pProps[n].Value)); 3993*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Weight" ) ) 3994*cdf0e10cSrcweir pFont->m_eWeight = static_cast<weight::type>(getInt(pProps[n].Value)); 3995*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Pitch" ) ) 3996*cdf0e10cSrcweir pFont->m_ePitch = static_cast<pitch::type>(getInt(pProps[n].Value)); 3997*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Encoding" ) ) 3998*cdf0e10cSrcweir pFont->m_aEncoding = static_cast<rtl_TextEncoding>(getInt(pProps[n].Value)); 3999*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "FontEncodingOnly" ) ) 4000*cdf0e10cSrcweir pFont->m_bFontEncodingOnly = getBool(pProps[n].Value); 4001*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricXWidth" ) ) 4002*cdf0e10cSrcweir pFont->m_aGlobalMetricX.width = getInt(pProps[n].Value); 4003*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricXHeight" ) ) 4004*cdf0e10cSrcweir pFont->m_aGlobalMetricX.height = getInt(pProps[n].Value); 4005*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricYWidth" ) ) 4006*cdf0e10cSrcweir pFont->m_aGlobalMetricY.width = getInt(pProps[n].Value); 4007*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricYHeight" ) ) 4008*cdf0e10cSrcweir pFont->m_aGlobalMetricY.height = getInt(pProps[n].Value); 4009*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Ascend" ) ) 4010*cdf0e10cSrcweir pFont->m_nAscend = getInt(pProps[n].Value); 4011*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Descend" ) ) 4012*cdf0e10cSrcweir pFont->m_nDescend = getInt(pProps[n].Value); 4013*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Leading" ) ) 4014*cdf0e10cSrcweir pFont->m_nLeading = getInt(pProps[n].Value); 4015*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XMin" ) ) 4016*cdf0e10cSrcweir pFont->m_nXMin = getInt(pProps[n].Value); 4017*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "YMin" ) ) 4018*cdf0e10cSrcweir pFont->m_nYMin = getInt(pProps[n].Value); 4019*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XMax" ) ) 4020*cdf0e10cSrcweir pFont->m_nXMax = getInt(pProps[n].Value); 4021*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "YMax" ) ) 4022*cdf0e10cSrcweir pFont->m_nYMax = getInt(pProps[n].Value); 4023*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "VerticalSubstitutes" ) ) 4024*cdf0e10cSrcweir pFont->m_bHaveVerticalSubstitutedGlyphs = getBool(pProps[n].Value); 4025*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "EncodingVector" ) ) 4026*cdf0e10cSrcweir { 4027*cdf0e10cSrcweir Sequence< NamedValue > aEncoding; 4028*cdf0e10cSrcweir pProps[n].Value >>= aEncoding; 4029*cdf0e10cSrcweir sal_Int32 nEnc = aEncoding.getLength(); 4030*cdf0e10cSrcweir const NamedValue* pEnc = aEncoding.getConstArray(); 4031*cdf0e10cSrcweir for( sal_Int32 m = 0; m < nEnc; m++ ) 4032*cdf0e10cSrcweir { 4033*cdf0e10cSrcweir sal_Unicode cCode = *pEnc[m].Name.getStr(); 4034*cdf0e10cSrcweir sal_Int32 nGlyph = getInt(pEnc[m].Value); 4035*cdf0e10cSrcweir pFont->m_aEncodingVector[ cCode ] = nGlyph; 4036*cdf0e10cSrcweir } 4037*cdf0e10cSrcweir } 4038*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "NonEncoded" ) ) 4039*cdf0e10cSrcweir { 4040*cdf0e10cSrcweir Sequence< NamedValue > aEncoding; 4041*cdf0e10cSrcweir pProps[n].Value >>= aEncoding; 4042*cdf0e10cSrcweir sal_Int32 nEnc = aEncoding.getLength(); 4043*cdf0e10cSrcweir const NamedValue* pEnc = aEncoding.getConstArray(); 4044*cdf0e10cSrcweir for( sal_Int32 m = 0; m < nEnc; m++ ) 4045*cdf0e10cSrcweir { 4046*cdf0e10cSrcweir sal_Unicode cCode = *pEnc[m].Name.getStr(); 4047*cdf0e10cSrcweir OUString aGlyphName( getString(pEnc[m].Value) ); 4048*cdf0e10cSrcweir pFont->m_aNonEncoded[ cCode ] = OUStringToOString(aGlyphName,RTL_TEXTENCODING_ASCII_US); 4049*cdf0e10cSrcweir } 4050*cdf0e10cSrcweir } 4051*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "CharacterMetrics" ) ) 4052*cdf0e10cSrcweir { 4053*cdf0e10cSrcweir // fill pFont->m_pMetrics->m_aMetrics 4054*cdf0e10cSrcweir // expect triples of int: int -> CharacterMetric.{ width, height } 4055*cdf0e10cSrcweir Sequence< sal_Int32 > aSeq; 4056*cdf0e10cSrcweir pProps[n].Value >>= aSeq; 4057*cdf0e10cSrcweir sal_Int32 nInts = aSeq.getLength(); 4058*cdf0e10cSrcweir const sal_Int32* pInts = aSeq.getConstArray(); 4059*cdf0e10cSrcweir for( sal_Int32 m = 0; m < nInts; m+=3 ) 4060*cdf0e10cSrcweir { 4061*cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics[ pInts[m] ].width = static_cast<short int>(pInts[m+1]); 4062*cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics[ pInts[m] ].height = static_cast<short int>(pInts[m+2]); 4063*cdf0e10cSrcweir } 4064*cdf0e10cSrcweir } 4065*cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XKernPairs" ) ) 4066*cdf0e10cSrcweir { 4067*cdf0e10cSrcweir // fill pFont->m_pMetrics->m_aXKernPairs 4068*cdf0e10cSrcweir // expection name: <unicode1><unicode2> value: ((height << 16)| width) 4069*cdf0e10cSrcweir Sequence< NamedValue > aKern; 4070*cdf0e10cSrcweir pProps[n].Value >>= aKern; 4071*cdf0e10cSrcweir KernPair aPair; 4072*cdf0e10cSrcweir const NamedValue* pVals = aKern.getConstArray(); 4073*cdf0e10cSrcweir int nPairs = aKern.getLength(); 4074*cdf0e10cSrcweir for( int m = 0; m < nPairs; m++ ) 4075*cdf0e10cSrcweir { 4076*cdf0e10cSrcweir if( pVals[m].Name.getLength() == 2 ) 4077*cdf0e10cSrcweir { 4078*cdf0e10cSrcweir aPair.first = pVals[m].Name.getStr()[0]; 4079*cdf0e10cSrcweir aPair.second = pVals[m].Name.getStr()[1]; 4080*cdf0e10cSrcweir sal_Int32 nKern = getInt( pVals[m].Value ); 4081*cdf0e10cSrcweir aPair.kern_x = static_cast<short int>(nKern & 0xffff); 4082*cdf0e10cSrcweir aPair.kern_y = static_cast<short int>((sal_uInt32(nKern) >> 16) & 0xffff); 4083*cdf0e10cSrcweir pFont->m_pMetrics->m_aXKernPairs.push_back( aPair ); 4084*cdf0e10cSrcweir } 4085*cdf0e10cSrcweir } 4086*cdf0e10cSrcweir } 4087*cdf0e10cSrcweir } 4088*cdf0e10cSrcweir // sanity check 4089*cdf0e10cSrcweir if( pFont->m_nPSName && 4090*cdf0e10cSrcweir pFont->m_nFamilyName && 4091*cdf0e10cSrcweir ! pFont->m_pMetrics->m_aMetrics.empty() ) 4092*cdf0e10cSrcweir { 4093*cdf0e10cSrcweir m_aOverrideFonts.push_back( m_nNextFontID ); 4094*cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = pFont; 4095*cdf0e10cSrcweir } 4096*cdf0e10cSrcweir else 4097*cdf0e10cSrcweir { 4098*cdf0e10cSrcweir DBG_ASSERT( 0, "override font failed" ); 4099*cdf0e10cSrcweir delete pFont; 4100*cdf0e10cSrcweir } 4101*cdf0e10cSrcweir } 4102*cdf0e10cSrcweir 4103*cdf0e10cSrcweir return true; 4104*cdf0e10cSrcweir } 4105