1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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"
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)
51 fontID mpFont
[Font3Size
];
56 fontID
GetFont (int nIdx
) const
57 { return nIdx
< Font3Size
? mpFont
[nIdx
] : -1 ; }
58 bool IsSymbolFont () const
61 Font3 (const PrinterGfx
&rGfx
);
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;
79 static int getVerticalDeltaAngle( sal_Unicode nChar
)
81 int nRotation
= GetVerticalFlags(nChar
);
82 if (nRotation
== GF_ROTR
)
84 if (nRotation
== GF_ROTL
)
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
)
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,
118 // font and encoding will be set by drawText again immediately
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
;
133 void PrinterGfx::drawGlyphs(
135 sal_uInt32
* pGlyphIds
,
136 sal_Unicode
* pUnicodes
,
138 sal_Int32
* pDeltaArray
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
);
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(
163 sal_GlyphId
* pGlyphIds
,
164 sal_Unicode
* pUnicodes
,
166 sal_Int32
* pDeltaArray
172 if ( !mrFontMgr
.isFontDownloadingAllowedForPrinting( mnFontID
) )
174 LicenseWarning(rPoint
, pUnicodes
, nLen
, pDeltaArray
);
178 if( mrFontMgr
.getFontType( mnFontID
) != fonttype::TrueType
)
180 DrawText( rPoint
, pUnicodes
, nLen
, pDeltaArray
);
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)
193 PSTranslate (rPoint
);
194 PSRotate (nCurrentTextAngle
);
196 aPoint
= Point( 0, 0 );
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;
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
];
226 pTempDelta
[nTempLen
-1] = pDeltaArray
[i
-1]-nTempFirstDelta
;
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
236 nTempFirstDelta
= pDeltaArray
[ i
-1 ];
242 sal_Int32 nOffset
= i
> 0 ? pDeltaArray
[i
-1] : 0;
243 sal_Int32 nRotAngle
= 0;
248 aRotPoint
= Point( -nAscend
*nTextWidth
/nTextHeight
, -nDescend
*nTextWidth
/nTextHeight
- nOffset
);
252 aRotPoint
= Point( -nOffset
, (nAscend
+nDescend
) );
256 aRotPoint
= Point( -nDescend
*nTextWidth
/nTextHeight
, nOffset
+ nAscend
*nTextWidth
/nTextHeight
);
259 sal_GlyphId nRotGlyphId
= pGlyphIds
[i
];
260 sal_Unicode nRotUnicode
= pUnicodes
[i
];
261 sal_Int32 nRotDelta
= 0;
263 // transform matrix to new individual direction
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
;
283 pGlyphIds
= pTempGlyphIds
;
284 pUnicodes
= pTempUnicodes
;
285 pDeltaArray
= pTempDelta
;
288 aPoint
.X() += nTempFirstDelta
;
292 drawGlyphs( aPoint
, pGlyphIds
, pUnicodes
, nLen
, pDeltaArray
);
294 // restore the user coordinate system
295 if (nCurrentTextAngle
!= 0)
298 mnTextAngle
= nCurrentTextAngle
;
303 PrinterGfx::DrawText (
305 const sal_Unicode
* pStr
,
307 const sal_Int32
* pDeltaArray
310 fontID nRestoreFont
= mnFontID
;
312 // setup font[substitutes] and map the string into the symbol area in case of
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
];
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;
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)
362 PSTranslate (rPoint
);
363 PSRotate (nCurrentTextAngle
);
371 nCurrentPointX
= rPoint
.X();
372 nCurrentPointY
= rPoint
.Y();
376 sal_Int32 nDelta
= 0;
377 for (int nTo
= 0; nTo
< nLen
; )
380 fontID nFont
= pFontMap
[ nFrom
];
382 while ((nTo
< nLen
) && (nFont
== pFontMap
[nTo
]))
384 pNewDeltaArray
[ nTo
] = (sal_Int32
)(((0.5 + pNewDeltaArray
[ nTo
]) / 1000.0) - nDelta
);
389 maVirtualStatus
.mnTextHeight
, maVirtualStatus
.mnTextWidth
,
392 maVirtualStatus
.mbArtItalic
,
393 maVirtualStatus
.mbArtBold
398 drawVerticalizedText(
399 Point(nCurrentPointX
+ nDelta
, nCurrentPointY
),
400 pEffectiveStr
+ nFrom
, nTo
- nFrom
,
401 pNewDeltaArray
+ nFrom
);
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)
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(
431 const sal_Unicode
* pStr
,
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();
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
)
457 if( i
<= nLen
&& i
> nLastPos
)
459 for( int n
= nLastPos
; n
< i
; n
++ )
460 pDelta
[n
] = pDeltaArray
[n
] - (aPoint
.X() - rPoint
.X() );
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
));
474 int nOldWidth
= maVirtualStatus
.mnTextWidth
;
475 int nOldHeight
= maVirtualStatus
.mnTextHeight
;
478 maVirtualStatus
.mnTextHeight
,
479 nNormalAngle
+ nDeltaAngle
,
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
;
490 Point
aPos( aPoint
);
491 switch( nDeltaAngle
)
494 aPos
.X() += (sal_Int32
)(+nA
* fCos
+ nD
* fSin
);
495 aPos
.Y() += (sal_Int32
)(-nA
* fSin
+ nD
* fCos
);
498 aPos
.X() += (sal_Int32
)(+nA
* fSin
+ nD
* fCos
);
499 aPos
.Y() += (sal_Int32
)(-(nTextScale
*fStretch
- nD
) * fCos
);
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
515 maVirtualStatus
.mbArtItalic
,
516 maVirtualStatus
.mbArtBold
);
521 mnTextAngle
= nNormalAngle
;
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
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
);
552 PSShowText (pBuffer
, nLen
, nSize
, pDeltaArray
);
556 PrinterGfx::drawText(
558 const sal_Unicode
* pStr
,
560 const sal_Int32
* pDeltaArray
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
);
578 if( mrFontMgr
.getUseOnlyFontEncoding( mnFontID
) )
580 GlyphSet
aGSet( mnFontID
, mbTextVertical
);
581 aGSet
.DrawText( *this, rPoint
, pStr
, nLen
, pDeltaArray
);
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
);
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
;
613 PrinterGfx::getCharMetric (const Font3
&rFont
, sal_Unicode n_char
, CharacterMetric
*p_bbox
)
618 for (fontID n
= 0; n
< 3; n
++)
620 fontID n_font
= rFont
.GetFont(n
);
622 mrFontMgr
.getMetrics( n_font
, n_char
, n_char
, p_bbox
);
623 if (p_bbox
->width
>= 0 && p_bbox
->height
>= 0)
627 return getCharMetric (rFont
, '?', p_bbox
);
629 return rFont
.GetFont(0) != -1 ? rFont
.GetFont(0) : rFont
.GetFont(1);
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() )
647 PrinterGfx::GetCharWidth (sal_Unicode nFrom
, sal_Unicode nTo
, long *pWidthArray
)
650 if (aFont
.IsSymbolFont() && (nFrom
< 256) && (nTo
< 256))
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
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() )
686 return mrFontMgr
.getKernPairs( nFont
, bVertical
);
690 * spool the converted truetype fonts to the page header after the page body is
692 * for Type1 fonts spool additional reencoding vectors that are necessary to access the
697 PrinterGfx::OnEndPage ()
702 PrinterGfx::OnEndJob ()
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
) );
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
);
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
);
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(
767 mrFontMgr
.getPSName( aIter
->GetFontID() ),
768 RTL_TEXTENCODING_ASCII_US
) );
772 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */