Bump version to 4.1-6
[LibreOffice.git] / vcl / generic / print / text_gfx.cxx
blob841a9db7a3557821e8c296b74ff14ca33f43b9d1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <math.h>
23 #include "psputil.hxx"
24 #include "glyphset.hxx"
26 #include "generic/printergfx.hxx"
27 #include "vcl/fontmanager.hxx"
28 #include "vcl/helper.hxx"
30 #include "osl/thread.h"
32 #include "sal/alloca.h"
34 using namespace psp ;
36 namespace psp {
38 container for a font and its helper fonts:
39 1st font is the font substitute e.g. helvetica substitutes arial on the printer
40 2nd is the font itself
41 3rd is a fallback font, usually a font with unicode glyph repertoir (e.g. andale)
42 symbol fonts (adobe-fontspecific) may need special glyphmapping
43 (symbol page vc. latin page)
45 class Font3
47 private:
49 #define Font3Size 3
51 fontID mpFont [Font3Size];
52 bool mbSymbol;
54 public:
56 fontID GetFont (int nIdx) const
57 { return nIdx < Font3Size ? mpFont[nIdx] : -1 ; }
58 bool IsSymbolFont () const
59 { return mbSymbol; }
61 Font3 (const PrinterGfx &rGfx);
62 ~Font3 () {}
65 Font3::Font3(const PrinterGfx &rGfx)
67 mpFont[0] = rGfx.getFontSubstitute();
68 mpFont[1] = rGfx.GetFontID();
69 mpFont[2] = rGfx.getFallbackID();
70 // mpFont[2] = rGfx.GetFontID();
72 PrintFontManager &rMgr = PrintFontManager::get();
73 mbSymbol = mpFont[1] != -1 ?
74 rMgr.getFontEncoding(mpFont[1]) == RTL_TEXTENCODING_SYMBOL : false;
77 } // namespace psp
79 static int getVerticalDeltaAngle( sal_Unicode nChar )
81 int nRotation = GetVerticalFlags(nChar);
82 if (nRotation == GF_ROTR)
83 return -900;
84 if (nRotation == GF_ROTL)
85 return 900;
86 return 0;
89 void
90 PrinterGfx::PSUploadPS1Font (sal_Int32 nFontID)
92 std::list< sal_Int32 >::iterator aFont;
93 // already in the document header ?
94 for (aFont = maPS1Font.begin(); aFont != maPS1Font.end(); ++aFont )
95 if( nFontID == *aFont )
96 return;
98 // no occurrenc yet, mark for download
99 // add the fontid to the list
100 maPS1Font.push_back (nFontID);
104 * implement text handling printer routines,
107 sal_uInt16
108 PrinterGfx::SetFont(
109 sal_Int32 nFontID,
110 sal_Int32 nHeight,
111 sal_Int32 nWidth,
112 sal_Int32 nAngle,
113 bool bVertical,
114 bool bArtItalic,
115 bool bArtBold
118 // font and encoding will be set by drawText again immediately
119 // before PSShowText
120 mnFontID = nFontID;
121 maVirtualStatus.maFont = OString();
122 maVirtualStatus.maEncoding = RTL_TEXTENCODING_DONTKNOW;
123 maVirtualStatus.mnTextHeight = nHeight;
124 maVirtualStatus.mnTextWidth = nWidth;
125 maVirtualStatus.mbArtItalic = bArtItalic;
126 maVirtualStatus.mbArtBold = bArtBold;
127 mnTextAngle = nAngle;
128 mbTextVertical = bVertical;
130 return 0;
133 void PrinterGfx::drawGlyphs(
134 const Point& rPoint,
135 sal_uInt32* pGlyphIds,
136 sal_Unicode* pUnicodes,
137 sal_Int16 nLen,
138 sal_Int32* pDeltaArray
142 // draw the string
143 // search for a glyph set matching the set font
144 std::list< GlyphSet >::iterator aIter;
145 for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); ++aIter)
146 if ( ((*aIter).GetFontID() == mnFontID)
147 && ((*aIter).IsVertical() == mbTextVertical))
149 (*aIter).DrawGlyphs (*this, rPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray);
150 break;
153 // not found ? create a new one
154 if (aIter == maPS3Font.end())
156 maPS3Font.push_back (GlyphSet(mnFontID, mbTextVertical));
157 maPS3Font.back().DrawGlyphs (*this, rPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray);
161 void PrinterGfx::DrawGlyphs(
162 const Point& rPoint,
163 sal_GlyphId* pGlyphIds,
164 sal_Unicode* pUnicodes,
165 sal_Int16 nLen,
166 sal_Int32* pDeltaArray
169 if( nLen <= 0 )
170 return;
172 if ( !mrFontMgr.isFontDownloadingAllowedForPrinting( mnFontID ) )
174 LicenseWarning(rPoint, pUnicodes, nLen, pDeltaArray);
175 return;
178 if( mrFontMgr.getFontType( mnFontID ) != fonttype::TrueType )
180 DrawText( rPoint, pUnicodes, nLen, pDeltaArray );
181 return;
184 // move and rotate the user coordinate system
185 // avoid the gsave/grestore for the simple cases since it allows
186 // reuse of the current font if it hasn't changed
187 sal_Int32 nCurrentTextAngle = mnTextAngle;
188 Point aPoint( rPoint );
190 if (nCurrentTextAngle != 0)
192 PSGSave ();
193 PSTranslate (rPoint);
194 PSRotate (nCurrentTextAngle);
195 mnTextAngle = 0;
196 aPoint = Point( 0, 0 );
199 if( mbTextVertical )
201 // vertical glyphs can have an additional rotation ... sigh.
202 // so break up text in chunks of normal glyphs and print out
203 // specially rotated glyphs extra
204 sal_uInt32* pTempGlyphIds = (sal_uInt32*)alloca(sizeof(sal_Int32)*nLen);
205 sal_Int32* pTempDelta = (sal_Int32*)alloca(sizeof(sal_Int32)*nLen);
206 sal_Unicode* pTempUnicodes = (sal_Unicode*)alloca(sizeof(sal_Unicode)*nLen);
207 sal_Int16 nTempLen = 0;
208 sal_Int32 nTempFirstDelta = 0;
209 Point aRotPoint;
210 sal_Int32 nTextHeight = maVirtualStatus.mnTextHeight;
211 sal_Int32 nTextWidth = maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight;
212 sal_Int32 nAscend = mrFontMgr.getFontAscend( mnFontID );
213 sal_Int32 nDescend = mrFontMgr.getFontDescend( mnFontID );
215 nDescend = nDescend * nTextHeight / 1000;
216 nAscend = nAscend * nTextHeight / 1000;
218 for( sal_Int16 i = 0; i < nLen; i++ )
220 const sal_GlyphId nRot = pGlyphIds[i] & GF_ROTMASK;
221 if( nRot == GF_NONE )
223 pTempUnicodes[nTempLen] = pUnicodes[i];
224 pTempGlyphIds[nTempLen] = pGlyphIds[i];
225 if( nTempLen > 0 )
226 pTempDelta[nTempLen-1] = pDeltaArray[i-1]-nTempFirstDelta;
227 else
229 // the first element in pDeltaArray shows
230 // the offset of the second character
231 // so if the first glyph is normal
232 // then we do not need to move the delta indices
233 // else we have to move them down by one and
234 // recalculate aPoint and all deltas
235 if( i != 0 )
236 nTempFirstDelta = pDeltaArray[ i-1 ];
238 nTempLen++;
240 else
242 sal_Int32 nOffset = i > 0 ? pDeltaArray[i-1] : 0;
243 sal_Int32 nRotAngle = 0;
244 switch( nRot )
246 case GF_ROTR:
247 nRotAngle = 2700;
248 aRotPoint = Point( -nAscend*nTextWidth/nTextHeight, -nDescend*nTextWidth/nTextHeight - nOffset );
249 break;
250 case GF_VERT:
251 nRotAngle = 1800;
252 aRotPoint = Point( -nOffset, (nAscend+nDescend) );
253 break;
254 case GF_ROTL:
255 nRotAngle = 900;
256 aRotPoint = Point( -nDescend*nTextWidth/nTextHeight, nOffset + nAscend*nTextWidth/nTextHeight );
257 break;
259 sal_GlyphId nRotGlyphId = pGlyphIds[i];
260 sal_Unicode nRotUnicode = pUnicodes[i];
261 sal_Int32 nRotDelta = 0;
263 // transform matrix to new individual direction
264 PSGSave ();
265 GraphicsStatus aSaveStatus = maVirtualStatus;
266 if( nRot != 2 ) // switch font aspect
268 maVirtualStatus.mnTextWidth = nTextHeight;
269 maVirtualStatus.mnTextHeight = nTextWidth;
271 if( aPoint.X() || aPoint.Y() )
272 PSTranslate( aPoint );
273 PSRotate (nRotAngle);
274 // draw the rotated glyph
275 drawGlyphs( aRotPoint, &nRotGlyphId, &nRotUnicode, 1, &nRotDelta );
277 // restore previous state
278 maVirtualStatus = aSaveStatus;
279 PSGRestore();
283 pGlyphIds = pTempGlyphIds;
284 pUnicodes = pTempUnicodes;
285 pDeltaArray = pTempDelta;
286 nLen = nTempLen;
288 aPoint.X() += nTempFirstDelta;
291 if( nLen > 0 )
292 drawGlyphs( aPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray );
294 // restore the user coordinate system
295 if (nCurrentTextAngle != 0)
297 PSGRestore ();
298 mnTextAngle = nCurrentTextAngle;
302 void
303 PrinterGfx::DrawText (
304 const Point& rPoint,
305 const sal_Unicode* pStr,
306 sal_Int16 nLen,
307 const sal_Int32* pDeltaArray
310 fontID nRestoreFont = mnFontID;
312 // setup font[substitutes] and map the string into the symbol area in case of
313 // symbol font
314 Font3 aFont(*this);
315 sal_Unicode *pEffectiveStr;
316 if ( aFont.IsSymbolFont() )
318 pEffectiveStr = (sal_Unicode*)alloca(nLen * sizeof(pStr[0]));
319 for (int i = 0; i < nLen; i++)
320 pEffectiveStr[i] = pStr[i] < 256 ? pStr[i] + 0xF000 : pStr[i];
322 else
324 pEffectiveStr = const_cast<sal_Unicode*>(pStr);
327 fontID *pFontMap = (fontID*) alloca(nLen * sizeof(fontID));
328 sal_Int32 *pCharWidth = (sal_Int32*) alloca(nLen * sizeof(sal_Int32));
330 for( int n = 0; n < nLen; n++ )
332 CharacterMetric aBBox;
333 pFontMap[n] = getCharMetric (aFont, pEffectiveStr[n], &aBBox);
334 pCharWidth[n] = getCharWidth (mbTextVertical, pEffectiveStr[n], &aBBox);
337 // setup a new delta array, use virtual resolution of 1000
338 sal_Int32* pNewDeltaArray = (sal_Int32*)alloca( sizeof( sal_Int32 )*nLen );
339 if ( pDeltaArray != 0)
341 for (int i = 0; i < nLen - 1; i++)
342 pNewDeltaArray[i] = 1000 * pDeltaArray[i];
343 pNewDeltaArray[nLen - 1] = 0;
345 else
347 pNewDeltaArray[0] = pCharWidth[0];
348 for (int i = 1; i < nLen; i++)
349 pNewDeltaArray[i] = pNewDeltaArray[i-1] + pCharWidth[i];
352 // move and rotate the user coordinate system
353 // avoid the gsave/grestore for the simple cases since it allows
354 // reuse of the current font if it hasn't changed
355 sal_Int32 nCurrentTextAngle = mnTextAngle;
356 sal_Int32 nCurrentPointX;
357 sal_Int32 nCurrentPointY;
359 if (nCurrentTextAngle != 0)
361 PSGSave ();
362 PSTranslate (rPoint);
363 PSRotate (nCurrentTextAngle);
364 mnTextAngle = 0;
366 nCurrentPointX = 0;
367 nCurrentPointY = 0;
369 else
371 nCurrentPointX = rPoint.X();
372 nCurrentPointY = rPoint.Y();
375 // draw the string
376 sal_Int32 nDelta = 0;
377 for (int nTo = 0; nTo < nLen; )
379 int nFrom = nTo;
380 fontID nFont = pFontMap[ nFrom ];
382 while ((nTo < nLen) && (nFont == pFontMap[nTo]))
384 pNewDeltaArray[ nTo ] = (sal_Int32)(((0.5 + pNewDeltaArray[ nTo ]) / 1000.0) - nDelta);
385 nTo++ ;
388 SetFont( nFont,
389 maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth,
390 mnTextAngle,
391 mbTextVertical,
392 maVirtualStatus.mbArtItalic,
393 maVirtualStatus.mbArtBold
396 if (mbTextVertical)
398 drawVerticalizedText(
399 Point(nCurrentPointX + nDelta, nCurrentPointY),
400 pEffectiveStr + nFrom, nTo - nFrom,
401 pNewDeltaArray + nFrom );
403 else
405 drawText(
406 Point(nCurrentPointX + nDelta, nCurrentPointY),
407 pEffectiveStr + nFrom, nTo - nFrom,
408 pDeltaArray == NULL ? NULL : pNewDeltaArray + nFrom );
410 nDelta += pNewDeltaArray[ nTo - 1 ];
413 // restore the user coordinate system
414 if (nCurrentTextAngle != 0)
416 PSGRestore ();
417 mnTextAngle = nCurrentTextAngle;
420 // restore the original font settings
421 SetFont( nRestoreFont,
422 maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth,
423 mnTextAngle, mbTextVertical,
424 maVirtualStatus.mbArtItalic,
425 maVirtualStatus.mbArtBold
429 void PrinterGfx::drawVerticalizedText(
430 const Point& rPoint,
431 const sal_Unicode* pStr,
432 sal_Int16 nLen,
433 const sal_Int32* pDeltaArray
436 sal_Int32* pDelta = (sal_Int32*)alloca( nLen * sizeof(sal_Int32) );
438 int nTextScale = maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight;
439 int nNormalAngle = mnTextAngle;
440 int nDeltaAngle, nLastPos = 0;
442 double fSin = sin( -2.0*M_PI*nNormalAngle/3600 );
443 double fCos = cos( -2.0*M_PI*nNormalAngle/3600 );
445 PrintFontManager &rMgr = PrintFontManager::get();
446 PrintFontInfo aInfo;
447 rMgr.getFontInfo( mnFontID, aInfo );
449 bool* pGsubFlags = (bool*)alloca( nLen * sizeof(bool) );
450 rMgr.hasVerticalSubstitutions( mnFontID, pStr, nLen, pGsubFlags );
452 Point aPoint( rPoint );
453 for( int i = 0; i < nLen; )
455 while( ( nDeltaAngle = getVerticalDeltaAngle( pStr[i] ) ) == 0 && i < nLen )
456 i++;
457 if( i <= nLen && i > nLastPos )
459 for( int n = nLastPos; n < i; n++ )
460 pDelta[n] = pDeltaArray[n] - (aPoint.X() - rPoint.X() );
462 SetFont( mnFontID,
463 maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth,
464 nNormalAngle, mbTextVertical,
465 maVirtualStatus.mbArtItalic,
466 maVirtualStatus.mbArtBold );
467 drawText( aPoint, pStr + nLastPos, i - nLastPos, pDelta + nLastPos );
469 aPoint.X() = (sal_Int32)(rPoint.X() + ((double)pDeltaArray[i-1] * fCos));
470 aPoint.Y() = (sal_Int32)(rPoint.Y() + ((double)pDeltaArray[i-1] * fSin));
472 if( i < nLen )
474 int nOldWidth = maVirtualStatus.mnTextWidth;
475 int nOldHeight = maVirtualStatus.mnTextHeight;
476 SetFont( mnFontID,
477 nTextScale,
478 maVirtualStatus.mnTextHeight,
479 nNormalAngle + nDeltaAngle,
480 mbTextVertical,
481 maVirtualStatus.mbArtItalic,
482 maVirtualStatus.mbArtBold );
484 double nA = nTextScale * aInfo.m_nAscend / 1000.0;
485 double nD = nTextScale * aInfo.m_nDescend / 1000.0;
486 double fStretch = (double)maVirtualStatus.mnTextWidth / maVirtualStatus.mnTextHeight;
487 if( !pGsubFlags[i] )
488 nD *= fStretch;
490 Point aPos( aPoint );
491 switch( nDeltaAngle )
493 case +900:
494 aPos.X() += (sal_Int32)(+nA * fCos + nD * fSin);
495 aPos.Y() += (sal_Int32)(-nA * fSin + nD * fCos);
496 break;
497 case -900:
498 aPos.X() += (sal_Int32)(+nA * fSin + nD * fCos);
499 aPos.Y() += (sal_Int32)(-(nTextScale*fStretch - nD) * fCos);
500 break;
502 drawText( aPos, pStr+i, 1, NULL );
503 if( i < nLen-1 && pDeltaArray )
505 aPoint.X() = (sal_Int32)(rPoint.X() + ((double)pDeltaArray[i] * fCos));
506 aPoint.Y() = (sal_Int32)(rPoint.Y() + ((double)pDeltaArray[i] * fSin));
509 // swap text width/height again
510 SetFont( mnFontID,
511 nOldHeight,
512 nOldWidth,
513 nNormalAngle,
514 mbTextVertical,
515 maVirtualStatus.mbArtItalic,
516 maVirtualStatus.mbArtBold );
518 i++;
519 nLastPos = i;
521 mnTextAngle = nNormalAngle;
524 void
525 PrinterGfx::LicenseWarning(const Point& rPoint, const sal_Unicode* pStr,
526 sal_Int16 nLen, const sal_Int32* pDeltaArray)
528 // treat it like a builtin font in case a user has that font also in the
529 // printer. This is not so unlikely as it may seem; no print embedding
530 // licensed fonts are often used (or so they say) in companies:
531 // they are installed on displays and printers, but get not embedded in
532 // print files or documents because they are not licensed for use outside
533 // the company.
534 OString aMessage( "The font " );
535 aMessage += OUStringToOString( mrFontMgr.getPSName(mnFontID),
536 RTL_TEXTENCODING_ASCII_US );
537 aMessage += " could not be downloaded\nbecause its license does not allow for that";
538 PSComment( aMessage.getStr() );
540 OString aFontName = OUStringToOString(
541 mrFontMgr.getPSName(mnFontID),
542 RTL_TEXTENCODING_ASCII_US);
543 PSSetFont (aFontName, RTL_TEXTENCODING_ISO_8859_1);
545 sal_Size nSize = 4 * nLen;
546 sal_uChar* pBuffer = (sal_uChar*)alloca (nSize* sizeof(sal_uChar));
548 ConverterFactory &rCvt = GetConverterFactory ();
549 nSize = rCvt.Convert (pStr, nLen, pBuffer, nSize, RTL_TEXTENCODING_ISO_8859_1);
551 PSMoveTo (rPoint);
552 PSShowText (pBuffer, nLen, nSize, pDeltaArray);
555 void
556 PrinterGfx::drawText(
557 const Point& rPoint,
558 const sal_Unicode* pStr,
559 sal_Int16 nLen,
560 const sal_Int32* pDeltaArray
563 if (!(nLen > 0))
564 return;
566 fonttype::type eType = mrFontMgr.getFontType (mnFontID);
568 if (eType == fonttype::Type1)
569 PSUploadPS1Font (mnFontID);
571 if ( eType == fonttype::TrueType
572 && !mrFontMgr.isFontDownloadingAllowedForPrinting(mnFontID))
574 LicenseWarning(rPoint, pStr, nLen, pDeltaArray);
575 return;
578 if( mrFontMgr.getUseOnlyFontEncoding( mnFontID ) )
580 GlyphSet aGSet( mnFontID, mbTextVertical );
581 aGSet.DrawText( *this, rPoint, pStr, nLen, pDeltaArray );
582 return;
585 // search for a glyph set matching the set font
586 std::list< GlyphSet >::iterator aIter;
587 for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); ++aIter)
588 if ( ((*aIter).GetFontID() == mnFontID)
589 && ((*aIter).IsVertical() == mbTextVertical))
591 (*aIter).DrawText (*this, rPoint, pStr, nLen, pDeltaArray);
592 break;
595 // not found ? create a new one
596 if (aIter == maPS3Font.end())
598 maPS3Font.push_back (GlyphSet(mnFontID, mbTextVertical));
599 maPS3Font.back().DrawText (*this, rPoint, pStr, nLen, pDeltaArray);
604 PrinterGfx::getCharWidth (sal_Bool b_vert, sal_Unicode n_char, CharacterMetric *p_bbox)
606 b_vert = b_vert && (getVerticalDeltaAngle(n_char) != 0);
607 int w = b_vert ? p_bbox->height : p_bbox->width;
608 w *= maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight;
609 return w;
612 fontID
613 PrinterGfx::getCharMetric (const Font3 &rFont, sal_Unicode n_char, CharacterMetric *p_bbox)
615 p_bbox->width = -1;
616 p_bbox->height = -1;
618 for (fontID n = 0; n < 3; n++)
620 fontID n_font = rFont.GetFont(n);
621 if (n_font != -1)
622 mrFontMgr.getMetrics( n_font, n_char, n_char, p_bbox );
623 if (p_bbox->width >= 0 && p_bbox->height >= 0)
624 return n_font;
626 if (n_char != '?')
627 return getCharMetric (rFont, '?', p_bbox);
629 return rFont.GetFont(0) != -1 ? rFont.GetFont(0) : rFont.GetFont(1);
632 fontID
633 PrinterGfx::getFontSubstitute () const
635 if( mpFontSubstitutes )
637 ::boost::unordered_map< fontID, fontID >::const_iterator it =
638 mpFontSubstitutes->find( mnFontID );
639 if( it != mpFontSubstitutes->end() )
640 return it->second;
643 return -1;
646 sal_Int32
647 PrinterGfx::GetCharWidth (sal_Unicode nFrom, sal_Unicode nTo, long *pWidthArray)
649 Font3 aFont(*this);
650 if (aFont.IsSymbolFont() && (nFrom < 256) && (nTo < 256))
652 nFrom += 0xF000;
653 nTo += 0xF000;
656 for( int n = 0; n < (nTo - nFrom + 1); n++ )
658 CharacterMetric aBBox;
659 getCharMetric (aFont, n + nFrom, &aBBox);
660 pWidthArray[n] = getCharWidth (mbTextVertical, n + nFrom, &aBBox);
663 // returned metrics have postscript precision
664 return 1000;
667 const ::std::list< KernPair >& PrinterGfx::getKernPairs( bool bVertical ) const
670 * Note: this is only a 80% solution: if a font is only
671 * partially substituted in a string due to missing glyphs
672 * the results may not be perfect; the more so the more the
673 * substitution differs from the original metricwise. But
674 * vcl only asks for KernPairs for each font once and NOT
675 * in a string context this is the best we can do.
676 * In future the kerning should be done on a per string basis.
678 fontID nFont = mnFontID;
679 if( mpFontSubstitutes )
681 ::boost::unordered_map< fontID, fontID >::const_iterator it =
682 mpFontSubstitutes->find( mnFontID );
683 if( it != mpFontSubstitutes->end() )
684 nFont = it->second;
686 return mrFontMgr.getKernPairs( nFont, bVertical );
690 * spool the converted truetype fonts to the page header after the page body is
691 * complete
692 * for Type1 fonts spool additional reencoding vectors that are necessary to access the
693 * whole font
696 void
697 PrinterGfx::OnEndPage ()
701 void
702 PrinterGfx::OnEndJob ()
704 maPS3Font.clear();
705 maPS1Font.clear();
708 void
709 PrinterGfx::writeResources( osl::File* pFile, std::list< OString >& rSuppliedFonts, std::list< OString >& rNeededFonts )
711 // write all type 1 fonts
712 std::list< sal_Int32 >::iterator aFont;
713 // already in the document header ?
714 for (aFont = maPS1Font.begin(); aFont != maPS1Font.end(); ++aFont)
716 const OString& rSysPath (mrFontMgr.getFontFileSysPath(*aFont) );
717 OUString aUNCPath;
718 osl::File::getFileURLFromSystemPath (OStringToOUString (rSysPath, osl_getThreadTextEncoding()), aUNCPath);
719 osl::File aFontFile (aUNCPath);
721 // provide the pfb or pfa font as a (pfa-)font resource
722 OString aPostScriptName =
723 OUStringToOString ( mrFontMgr.getPSName(*aFont),
724 RTL_TEXTENCODING_ASCII_US );
726 WritePS (pFile, "%%BeginResource: font ");
727 WritePS (pFile, aPostScriptName.getStr());
728 WritePS (pFile, "\n");
730 osl::File::RC nError = aFontFile.open(osl_File_OpenFlag_Read);
731 if (nError == osl::File::E_None)
733 convertPfbToPfa (aFontFile, *pFile);
734 aFontFile.close ();
736 char lastchar = '\n';
738 if (pFile->setPos(osl_Pos_Current, -1) == osl::FileBase::E_None)
740 sal_uInt64 uBytes(1);
741 pFile->read((void *)(&lastchar), uBytes, uBytes);
744 if (lastchar != '\n')
745 WritePS (pFile, "\n");
747 WritePS (pFile, "%%EndResource\n");
748 rSuppliedFonts.push_back( aPostScriptName );
751 // write glyphsets and reencodings
752 std::list< GlyphSet >::iterator aIter;
753 for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); ++aIter)
755 if (aIter->GetFontType() == fonttype::TrueType)
757 aIter->PSUploadFont (*pFile, *this, mbUploadPS42Fonts ? true : false, rSuppliedFonts );
759 else
760 // ( aIter->GetFontType() == fonttype::Type1
761 // || aIter->GetFontType() == fonttype::Builtin )
763 aIter->PSUploadEncoding (pFile, *this);
764 if( aIter->GetFontType() == fonttype::Builtin )
765 rNeededFonts.push_back(
766 OUStringToOString(
767 mrFontMgr.getPSName( aIter->GetFontID() ),
768 RTL_TEXTENCODING_ASCII_US ) );
772 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */