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