Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <basegfx/range/b2drange.hxx>
30 : : #include <basegfx/range/b2ibox.hxx>
31 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
32 : :
33 : : #include <basebmp/scanlineformats.hxx>
34 : :
35 : : #include <tools/debug.hxx>
36 : :
37 : : #include <outfont.hxx>
38 : : #include <impfont.hxx>
39 : : #include <rtl/instance.hxx>
40 : :
41 : : #include "generic/geninst.h"
42 : : #include "generic/genpspgraphics.h"
43 : : #include "generic/glyphcache.hxx"
44 : : #include "headless/svpgdi.hxx"
45 : : #include "headless/svpbmp.hxx"
46 : :
47 : : using namespace basegfx;
48 : : using namespace basebmp;
49 : :
50 : : // ===========================================================================
51 : :
52 [ - + ]: 472 : class SvpGlyphPeer
53 : : : public GlyphCachePeer
54 : : {
55 : : public:
56 : 236 : SvpGlyphPeer() {}
57 : :
58 : : BitmapDeviceSharedPtr GetGlyphBmp( ServerFont&, int nGlyphIndex,
59 : : sal_uInt32 nBmpFormat, B2IPoint& rTargetPos );
60 : :
61 : : protected:
62 : : virtual void RemovingFont( ServerFont& );
63 : : virtual void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
64 : :
65 [ + - ][ + - ]: 1939832 : class SvpGcpHelper
66 : : {
67 : : public:
68 : : RawBitmap maRawBitmap;
69 : : BitmapDeviceSharedPtr maBitmapDev;
70 : : };
71 : : };
72 : :
73 : : // ===========================================================================
74 : :
75 : 236 : class SvpGlyphCache : public GlyphCache
76 : : {
77 : : public:
78 : 236 : SvpGlyphCache( SvpGlyphPeer& rPeer ) : GlyphCache( rPeer) {}
79 : 152598 : SvpGlyphPeer& GetPeer() { return reinterpret_cast<SvpGlyphPeer&>( mrPeer ); }
80 : : static SvpGlyphCache& GetInstance();
81 : : };
82 : :
83 : : namespace
84 : : {
85 : : struct GlyphCacheHolder
86 : : {
87 : : private:
88 : : SvpGlyphPeer* m_pSvpGlyphPeer;
89 : : SvpGlyphCache* m_pSvpGlyphCache;
90 : : public:
91 : 236 : GlyphCacheHolder()
92 : : {
93 : 236 : m_pSvpGlyphPeer = new SvpGlyphPeer();
94 [ + - ]: 236 : m_pSvpGlyphCache = new SvpGlyphCache( *m_pSvpGlyphPeer );
95 : 236 : }
96 : 236 : void release()
97 : : {
98 [ + - ]: 236 : delete m_pSvpGlyphCache;
99 [ + - ]: 236 : delete m_pSvpGlyphPeer;
100 : 236 : m_pSvpGlyphCache = NULL;
101 : 236 : m_pSvpGlyphPeer = NULL;
102 : 236 : }
103 : 545226 : SvpGlyphCache& getGlyphCache()
104 : : {
105 : 545226 : return *m_pSvpGlyphCache;
106 : : }
107 : 236 : ~GlyphCacheHolder()
108 : : {
109 : 236 : release();
110 : 236 : }
111 : : };
112 : :
113 : : struct theGlyphCacheHolder :
114 : : public rtl::Static<GlyphCacheHolder, theGlyphCacheHolder>
115 : : {};
116 : : }
117 : :
118 : 545226 : SvpGlyphCache& SvpGlyphCache::GetInstance()
119 : : {
120 : 545226 : return theGlyphCacheHolder::get().getGlyphCache();
121 : : }
122 : :
123 : : // ===========================================================================
124 : :
125 : 1939313 : BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont,
126 : : int nGlyphIndex, sal_uInt32 nBmpFormat, B2IPoint& rTargetPos )
127 : : {
128 : 1939313 : GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
129 : 1939313 : SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
130 : :
131 : : // nothing to do if the GlyphPeer hasn't allocated resources for the glyph
132 [ + - ]: 1939313 : if( rGlyphData.ExtDataRef().meInfo != sal::static_int_cast<int>(nBmpFormat) )
133 : : {
134 [ + - ]: 1939313 : if( rGlyphData.ExtDataRef().meInfo == Format::NONE )
135 [ + - ][ + - ]: 1939313 : pGcpHelper = new SvpGcpHelper;
136 : 1939313 : RawBitmap& rRawBitmap = pGcpHelper->maRawBitmap;
137 : :
138 : : // get glyph bitmap in matching format
139 : 1939313 : bool bFound = false;
140 [ + + - ]: 1939313 : switch( nBmpFormat )
141 : : {
142 : : case Format::ONE_BIT_LSB_GREY:
143 [ + - ]: 210 : bFound = rServerFont.GetGlyphBitmap1( nGlyphIndex, pGcpHelper->maRawBitmap );
144 : 210 : break;
145 : : case Format::EIGHT_BIT_GREY:
146 [ + - ]: 1939103 : bFound = rServerFont.GetGlyphBitmap8( nGlyphIndex, pGcpHelper->maRawBitmap );
147 : 1939103 : break;
148 : : default:
149 : : OSL_FAIL( "SVP GCP::GetGlyphBmp(): illegal scanline format");
150 : : // fall back to black&white mask
151 : 0 : nBmpFormat = Format::ONE_BIT_LSB_GREY;
152 : 0 : bFound = false;
153 : 0 : break;
154 : : }
155 : :
156 : : // return .notdef glyph if needed
157 [ + + ][ + - ]: 1939313 : if( !bFound && (nGlyphIndex != 0) )
158 : : {
159 [ + - ][ + - ]: 519 : delete pGcpHelper;
160 [ + - ]: 519 : return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos );
161 : : }
162 : :
163 : : // construct alpha mask from raw bitmap
164 : 1938794 : const B2IVector aSize( rRawBitmap.mnScanlineSize, rRawBitmap.mnHeight );
165 [ + - ][ + + ]: 1938794 : if( aSize.getX() && aSize.getY() )
[ + + ]
166 : : {
167 [ + + ][ + - ]: 1772001 : static PaletteMemorySharedVector aDummyPAL;
[ + - ][ # # ]
168 [ + - ]: 1772001 : RawMemorySharedArray aRawPtr( rRawBitmap.mpBits );
169 [ + - ][ + - ]: 1772001 : pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aRawPtr, aDummyPAL );
[ + - ][ + - ]
170 : : }
171 : :
172 [ + - ]: 1939313 : rServerFont.SetExtended( nBmpFormat, (void*)pGcpHelper );
173 : : }
174 : :
175 : 1938794 : rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset );
176 : 1939313 : return pGcpHelper->maBitmapDev;
177 : : }
178 : :
179 : : //--------------------------------------------------------------------------
180 : :
181 : 4519 : void SvpGlyphPeer::RemovingFont( ServerFont& )
182 : : {
183 : : // nothing to do: no font resources held in SvpGlyphPeer
184 : 4519 : }
185 : :
186 : : //--------------------------------------------------------------------------
187 : :
188 : 0 : void SvpGlyphPeer::RemovingGlyph( ServerFont&, GlyphData& rGlyphData, int /*nGlyphIndex*/ )
189 : : {
190 [ # # ]: 0 : if( rGlyphData.ExtDataRef().mpData != Format::NONE )
191 : : {
192 : : // release the glyph related resources
193 : : DBG_ASSERT( (rGlyphData.ExtDataRef().meInfo <= Format::MAX), "SVP::RG() invalid alpha format" );
194 : 0 : SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
195 [ # # ]: 0 : delete[] pGcpHelper->maRawBitmap.mpBits;
196 [ # # ]: 0 : delete pGcpHelper;
197 : : }
198 : 0 : }
199 : :
200 : : // ===========================================================================
201 : :
202 : : // PspKernInfo allows on-demand-querying of psprint provided kerning info (#i29881#)
203 [ - + ]: 16520 : class PspKernInfo : public ExtraKernInfo
204 : : {
205 : : public:
206 : 8575 : PspKernInfo( int nFontId ) : ExtraKernInfo(nFontId) {}
207 : : protected:
208 : : virtual void Initialize() const;
209 : : };
210 : :
211 : : //--------------------------------------------------------------------------
212 : :
213 : 17 : void PspKernInfo::Initialize() const
214 : : {
215 : 17 : mbInitialized = true;
216 : :
217 : : // get the kerning pairs from psprint
218 [ + - ]: 17 : const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
219 : : typedef std::list< psp::KernPair > PspKernPairs;
220 [ + - ]: 17 : const PspKernPairs& rKernPairs = rMgr.getKernPairs( mnFontId );
221 [ + + ]: 17 : if( rKernPairs.empty() )
222 : 17 : return;
223 : :
224 : 8 : PspKernPairs::const_iterator it = rKernPairs.begin();
225 [ + + ]: 4428 : for(; it != rKernPairs.end(); ++it )
226 : : {
227 : 4411 : ImplKernPairData aKernPair = { it->first, it->second, it->kern_x };
228 [ + - ]: 4411 : maUnicodeKernPairs.insert( aKernPair );
229 : : }
230 : : }
231 : :
232 : : // ===========================================================================
233 : :
234 : 419216 : sal_uInt16 SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel )
235 : : {
236 : : // release all no longer needed font resources
237 [ + + ]: 7113922 : for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
238 : : {
239 [ + + ]: 6694706 : if( m_pServerFont[i] != NULL )
240 : : {
241 : : // old server side font is no longer referenced
242 : 195886 : SvpGlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] );
243 : 195886 : m_pServerFont[i] = NULL;
244 : : }
245 : : }
246 : :
247 : : // return early if there is no new font
248 [ + + ]: 419216 : if( !pIFSD )
249 : 222719 : return 0;
250 : :
251 : : // handle the request for a non-native X11-font => use the GlyphCache
252 : 196497 : ServerFont* pServerFont = SvpGlyphCache::GetInstance().CacheFont( *pIFSD );
253 [ - + ]: 196497 : if( !pServerFont )
254 : 0 : return SAL_SETFONT_BADFONT;
255 : :
256 : : // check selected font
257 [ - + ]: 196497 : if( !pServerFont->TestFont() )
258 : : {
259 : 0 : SvpGlyphCache::GetInstance().UncacheFont( *pServerFont );
260 : 0 : return SAL_SETFONT_BADFONT;
261 : : }
262 : :
263 : : // update SalGraphics font settings
264 : 196497 : m_pServerFont[ nFallbackLevel ] = pServerFont;
265 : 419216 : return SAL_SETFONT_USEDRAWTEXTARRAY;
266 : : }
267 : :
268 : : // ---------------------------------------------------------------------------
269 : :
270 : 16570 : void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel )
271 : : {
272 [ - + ]: 16570 : if( nFallbackLevel >= MAX_FALLBACK )
273 : 16570 : return;
274 : :
275 [ + - ]: 16570 : if( m_pServerFont[nFallbackLevel] != NULL )
276 : : {
277 : : long rDummyFactor;
278 [ + - ]: 16570 : m_pServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
279 : : }
280 : : }
281 : :
282 : : // ---------------------------------------------------------------------------
283 : :
284 : 0 : sal_uLong SvpSalGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData* pKernPairs )
285 : : {
286 : 0 : sal_uLong nGotPairs = 0;
287 : :
288 [ # # ]: 0 : if( m_pServerFont[0] != NULL )
289 : : {
290 : 0 : ImplKernPairData* pTmpKernPairs = NULL;
291 [ # # ]: 0 : nGotPairs = m_pServerFont[0]->GetKernPairs( &pTmpKernPairs );
292 [ # # ][ # # ]: 0 : for( sal_uLong i = 0; i < nPairs && i < nGotPairs; ++i )
[ # # ]
293 : 0 : pKernPairs[ i ] = pTmpKernPairs[ i ];
294 [ # # ]: 0 : delete[] pTmpKernPairs;
295 : : }
296 : :
297 : 0 : return nGotPairs;
298 : : }
299 : :
300 : : // ---------------------------------------------------------------------------
301 : :
302 : 6520 : const ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const
303 : : {
304 [ - + ]: 6520 : if( !m_pServerFont[0] )
305 : 0 : return NULL;
306 : :
307 : 6520 : const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
308 : 6520 : return pIFCMap;
309 : : }
310 : :
311 : 2 : bool SvpSalGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
312 : : {
313 [ - + ]: 2 : if (!m_pServerFont[0])
314 : 0 : return false;
315 : :
316 : 2 : return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities);
317 : : }
318 : :
319 : : // ---------------------------------------------------------------------------
320 : :
321 : 245 : void SvpSalGraphics::GetDevFontList( ImplDevFontList* pDevFontList )
322 : : {
323 [ + - ]: 245 : GlyphCache& rGC = SvpGlyphCache::GetInstance();
324 : :
325 [ + - ]: 245 : psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
326 [ + - ]: 245 : psp::FastPrintFontInfo aInfo;
327 [ + - ]: 245 : ::std::list< psp::fontID > aList;
328 [ + - ]: 245 : rMgr.getFontList( aList );
329 [ + - ]: 245 : ::std::list< psp::fontID >::iterator it;
330 [ + - ][ + - ]: 41131 : for( it = aList.begin(); it != aList.end(); ++it )
[ + + ]
331 : : {
332 [ + - ][ + - ]: 40886 : if( !rMgr.getFontFastInfo( *it, aInfo ) )
[ - + ]
333 : 0 : continue;
334 : :
335 : : // the GlyphCache must not bother with builtin fonts because
336 : : // it cannot access or use them anyway
337 [ + + ]: 40886 : if( aInfo.m_eType == psp::fonttype::Builtin )
338 : 4898 : continue;
339 : :
340 : : // normalize face number to the GlyphCache
341 [ + - ]: 35988 : int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
342 : :
343 : : // for fonts where extra kerning info can be provided on demand
344 : : // an ExtraKernInfo object is supplied
345 : 35988 : const ExtraKernInfo* pExtraKernInfo = NULL;
346 [ + + ]: 35988 : if( aInfo.m_eType == psp::fonttype::Type1 )
347 [ + - ][ + - ]: 8575 : pExtraKernInfo = new PspKernInfo( *it );
[ + - ]
348 : :
349 : : // inform GlyphCache about this font provided by the PsPrint subsystem
350 [ + - ]: 35988 : ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
351 : 35988 : aDFA.mnQuality += 4096;
352 [ + - ]: 35988 : const rtl::OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
353 [ + - ]: 35988 : rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA, pExtraKernInfo );
354 [ + - ]: 40886 : }
355 : :
356 : : // announce glyphcache fonts
357 [ + - ]: 245 : rGC.AnnounceFonts( pDevFontList );
358 : :
359 : : // register platform specific font substitutions if available
360 [ + - ]: 245 : SalGenericInstance::RegisterFontSubstitutors( pDevFontList );
361 : :
362 [ + - ]: 245 : ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
363 : 245 : }
364 : :
365 : : // ---------------------------------------------------------------------------
366 : :
367 : 3 : void SvpSalGraphics::GetDevFontSubstList( OutputDevice* )
368 : 3 : {}
369 : :
370 : : // ---------------------------------------------------------------------------
371 : :
372 : 0 : bool SvpSalGraphics::AddTempDevFont( ImplDevFontList*,
373 : : const rtl::OUString&, const rtl::OUString& )
374 : : {
375 : 0 : return false;
376 : : }
377 : :
378 : : // ---------------------------------------------------------------------------
379 : :
380 : 0 : sal_Bool SvpSalGraphics::CreateFontSubset(
381 : : const rtl::OUString& rToFile,
382 : : const PhysicalFontFace* pFont,
383 : : sal_Int32* pGlyphIDs,
384 : : sal_uInt8* pEncoding,
385 : : sal_Int32* pWidths,
386 : : int nGlyphCount,
387 : : FontSubsetInfo& rInfo
388 : : )
389 : : {
390 : : // in this context the pFont->GetFontId() is a valid PSP
391 : : // font since they are the only ones left after the PDF
392 : : // export has filtered its list of subsettable fonts (for
393 : : // which this method was created). The correct way would
394 : : // be to have the GlyphCache search for the PhysicalFontFace pFont
395 : 0 : psp::fontID aFont = pFont->GetFontId();
396 : :
397 : 0 : psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
398 : : bool bSuccess = rMgr.createFontSubset( rInfo,
399 : : aFont,
400 : : rToFile,
401 : : pGlyphIDs,
402 : : pEncoding,
403 : : pWidths,
404 : 0 : nGlyphCount );
405 : 0 : return bSuccess;
406 : : }
407 : :
408 : : // ---------------------------------------------------------------------------
409 : :
410 : 0 : const Ucs2SIntMap* SvpSalGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
411 : : {
412 : : // in this context the pFont->GetFontId() is a valid PSP
413 : : // font since they are the only ones left after the PDF
414 : : // export has filtered its list of subsettable fonts (for
415 : : // which this method was created). The correct way would
416 : : // be to have the GlyphCache search for the PhysicalFontFace pFont
417 : 0 : psp::fontID aFont = pFont->GetFontId();
418 : 0 : return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
419 : : }
420 : :
421 : : // ---------------------------------------------------------------------------
422 : :
423 : 0 : const void* SvpSalGraphics::GetEmbedFontData(
424 : : const PhysicalFontFace* pFont,
425 : : const sal_Ucs* pUnicodes,
426 : : sal_Int32* pWidths,
427 : : FontSubsetInfo& rInfo,
428 : : long* pDataLen
429 : : )
430 : : {
431 : : // in this context the pFont->GetFontId() is a valid PSP
432 : : // font since they are the only ones left after the PDF
433 : : // export has filtered its list of subsettable fonts (for
434 : : // which this method was created). The correct way would
435 : : // be to have the GlyphCache search for the PhysicalFontFace pFont
436 : 0 : psp::fontID aFont = pFont->GetFontId();
437 : 0 : return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
438 : : }
439 : :
440 : : // ---------------------------------------------------------------------------
441 : :
442 : 0 : void SvpSalGraphics::FreeEmbedFontData( const void* pData, long nLen )
443 : : {
444 : 0 : GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
445 : 0 : }
446 : :
447 : 0 : void SvpSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
448 : : bool bVertical,
449 : : Int32Vector& rWidths,
450 : : Ucs2UIntMap& rUnicodeEnc )
451 : : {
452 : : // in this context the pFont->GetFontId() is a valid PSP
453 : : // font since they are the only ones left after the PDF
454 : : // export has filtered its list of subsettable fonts (for
455 : : // which this method was created). The correct way would
456 : : // be to have the GlyphCache search for the PhysicalFontFace pFont
457 : 0 : psp::fontID aFont = pFont->GetFontId();
458 : 0 : GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
459 : 0 : }
460 : :
461 : : // ---------------------------------------------------------------------------
462 : :
463 : 354411 : sal_Bool SvpSalGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphIndex, Rectangle& rRect )
464 : : {
465 : 354411 : int nLevel = nGlyphIndex >> GF_FONTSHIFT;
466 [ - + ]: 354411 : if( nLevel >= MAX_FALLBACK )
467 : 0 : return sal_False;
468 : :
469 : 354411 : ServerFont* pSF = m_pServerFont[ nLevel ];
470 [ - + ]: 354411 : if( !pSF )
471 : 0 : return sal_False;
472 : :
473 : 354411 : nGlyphIndex &= GF_IDXMASK;
474 : 354411 : const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex );
475 [ + - ]: 354411 : rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() );
476 : 354411 : return sal_True;
477 : : }
478 : :
479 : : // ---------------------------------------------------------------------------
480 : :
481 : 2401 : sal_Bool SvpSalGraphics::GetGlyphOutline( sal_GlyphId nGlyphIndex, B2DPolyPolygon& rPolyPoly )
482 : : {
483 : 2401 : int nLevel = nGlyphIndex >> GF_FONTSHIFT;
484 [ - + ]: 2401 : if( nLevel >= MAX_FALLBACK )
485 : 0 : return sal_False;
486 : :
487 : 2401 : const ServerFont* pSF = m_pServerFont[ nLevel ];
488 [ - + ]: 2401 : if( !pSF )
489 : 0 : return sal_False;
490 : :
491 : 2401 : nGlyphIndex &= GF_IDXMASK;
492 [ + + ]: 2401 : if( pSF->GetGlyphOutline( nGlyphIndex, rPolyPoly ) )
493 : 2263 : return sal_True;
494 : :
495 : 2401 : return sal_False;
496 : : }
497 : :
498 : : // ---------------------------------------------------------------------------
499 : :
500 : 983543 : SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel )
501 : : {
502 : 983543 : GenericSalLayout* pLayout = NULL;
503 : :
504 [ + - ]: 983543 : if( m_pServerFont[ nFallbackLevel ] )
505 [ + - ]: 983543 : pLayout = new ServerFontLayout( *m_pServerFont[ nFallbackLevel ] );
506 : :
507 : 983543 : return pLayout;
508 : : }
509 : :
510 : : // ---------------------------------------------------------------------------
511 : :
512 : 152598 : void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout )
513 : : {
514 : : // iterate over all glyphs in the layout
515 : 152598 : Point aPos;
516 : : sal_GlyphId nGlyphIndex;
517 [ + - ]: 152598 : SvpGlyphPeer& rGlyphPeer = SvpGlyphCache::GetInstance().GetPeer();
518 [ + - ][ + + ]: 2091392 : for( int nStart = 0; rSalLayout.GetNextGlyphs( 1, &nGlyphIndex, aPos, nStart ); )
519 : : {
520 : 1938794 : int nLevel = nGlyphIndex >> GF_FONTSHIFT;
521 : : DBG_ASSERT( nLevel < MAX_FALLBACK, "SvpGDI: invalid glyph fallback level" );
522 : 1938794 : ServerFont* pSF = m_pServerFont[ nLevel ];
523 [ - + ]: 1938794 : if( !pSF )
524 : 0 : continue;
525 : :
526 : : // get the glyph's alpha mask and adjust the drawing position
527 : 1938794 : nGlyphIndex &= GF_IDXMASK;
528 : 1938794 : B2IPoint aDstPoint( aPos.X(), aPos.Y() );
529 : : BitmapDeviceSharedPtr aAlphaMask
530 [ + - ]: 1938794 : = rGlyphPeer.GetGlyphBmp( *pSF, nGlyphIndex, m_eTextFmt, aDstPoint );
531 [ + + ]: 1938794 : if( !aAlphaMask ) // ignore empty glyphs
532 : 166793 : continue;
533 : :
534 : : // blend text color into target using the glyph's mask
535 [ + - ][ + - ]: 1772001 : const B2IBox aSrcRect( B2ITuple(0,0), aAlphaMask->getSize() );
536 [ + - ][ + - ]: 1772001 : const B2IBox aClipRect( aDstPoint, aAlphaMask->getSize() );
537 : :
538 [ + - ]: 1772001 : SvpSalGraphics::ClipUndoHandle aUndo( this );
539 [ + - ][ + - ]: 1772001 : if( !isClippedSetup( aClipRect, aUndo ) )
540 : : m_aDevice->drawMaskedColor( m_aTextColor, aAlphaMask,
541 [ + - ]: 1772001 : aSrcRect, aDstPoint, m_aClipMap );
542 [ + - ][ + - ]: 1938794 : }
[ + + ][ + + ]
543 : 152598 : }
544 : :
545 : : // ===========================================================================
546 : :
547 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|