1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: text_gfx.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_psprint.hxx"
33 #include <psprint/printergfx.hxx>
34 #include <psprint/fontmanager.hxx>
35 #include <psprint/helper.hxx>
36 #include "psputil.hxx"
37 #include <glyphset.hxx>
38 #include <osl/thread.h>
39 #include <sal/alloca.h>
46 container for a font and its helper fonts:
47 1st font is the font substitute e.g. helvetica substitutes arial on the printer
48 2nd is the font itself
49 3rd is a fallback font, usually a font with unicode glyph repertoir (e.g. andale)
50 symbol fonts (adobe-fontspecific) may need special glyphmapping
51 (symbol page vc. latin page)
59 fontID mpFont
[Font3Size
];
64 fontID
GetFont (int nIdx
) const
65 { return nIdx
< Font3Size
? mpFont
[nIdx
] : -1 ; }
66 bool IsSymbolFont () const
69 Font3 (const PrinterGfx
&rGfx
);
73 Font3::Font3(const PrinterGfx
&rGfx
)
75 mpFont
[0] = rGfx
.getFontSubstitute();
76 mpFont
[1] = rGfx
.GetFontID();
77 mpFont
[2] = rGfx
.getFallbackID();
78 // mpFont[2] = rGfx.GetFontID();
80 PrintFontManager
&rMgr
= PrintFontManager::get();
81 mbSymbol
= mpFont
[1] != -1 ?
82 rMgr
.getFontEncoding(mpFont
[1]) == RTL_TEXTENCODING_SYMBOL
: false;
87 static int getVerticalDeltaAngle( sal_Unicode nChar
)
90 if( ( nChar
>= 0x1100 && nChar
< 0x11fa ) ||
91 ( nChar
>= 0x3000 && nChar
< 0xfb00 ) ||
92 ( nChar
>= 0xfe20 && nChar
< 0xfe70 ) ||
93 ( nChar
>= 0xff00 && nChar
< 0xff64 )
97 nChar == 0x2010 || nChar == 0x2015
98 nChar == 0x2016 || nChar == 0x2026
100 are nAngle = 0 also, but already handled in the first if
102 if( ( nChar
>= 0x3008 && nChar
< 0x3019 && nChar
!= 0x3012 ) ||
103 nChar
== 0xff3b || nChar
== 0xff3d ||
104 (nChar
>= 0xff6b && nChar
< 0xff64 ) ||
108 else if( nChar
== 0x30fc )
117 PrinterGfx::PSUploadPS1Font (sal_Int32 nFontID
)
119 std::list
< sal_Int32
>::iterator aFont
;
120 // already in the document header ?
121 for (aFont
= maPS1Font
.begin(); aFont
!= maPS1Font
.end(); ++aFont
)
122 if( nFontID
== *aFont
)
125 // no occurrenc yet, mark for download
126 // add the fontid to the list
127 maPS1Font
.push_back (nFontID
);
131 * implement text handling printer routines,
145 // font and encoding will be set by drawText again immediately
148 maVirtualStatus
.maFont
= rtl::OString();
149 maVirtualStatus
.maEncoding
= RTL_TEXTENCODING_DONTKNOW
;
150 maVirtualStatus
.mnTextHeight
= nHeight
;
151 maVirtualStatus
.mnTextWidth
= nWidth
;
152 maVirtualStatus
.mbArtItalic
= bArtItalic
;
153 maVirtualStatus
.mbArtBold
= bArtBold
;
154 mnTextAngle
= nAngle
;
155 mbTextVertical
= bVertical
;
161 PrinterGfx::SetFallbackFont ( sal_Int32 nFontID
)
163 mnFallbackID
= nFontID
;
167 void PrinterGfx::drawGlyphs(
169 sal_uInt32
* pGlyphIds
,
170 sal_Unicode
* pUnicodes
,
172 sal_Int32
* pDeltaArray
177 // search for a glyph set matching the set font
178 std::list
< GlyphSet
>::iterator aIter
;
179 for (aIter
= maPS3Font
.begin(); aIter
!= maPS3Font
.end(); aIter
++)
180 if ( ((*aIter
).GetFontID() == mnFontID
)
181 && ((*aIter
).IsVertical() == mbTextVertical
))
183 (*aIter
).DrawGlyphs (*this, rPoint
, pGlyphIds
, pUnicodes
, nLen
, pDeltaArray
);
187 // not found ? create a new one
188 if (aIter
== maPS3Font
.end())
190 maPS3Font
.push_back (GlyphSet(mnFontID
, mbTextVertical
));
191 maPS3Font
.back().DrawGlyphs (*this, rPoint
, pGlyphIds
, pUnicodes
, nLen
, pDeltaArray
);
195 void PrinterGfx::DrawGlyphs(
197 sal_uInt32
* pGlyphIds
,
198 sal_Unicode
* pUnicodes
,
200 sal_Int32
* pDeltaArray
206 if ( !mrFontMgr
.isFontDownloadingAllowed( mnFontID
) )
208 LicenseWarning(rPoint
, pUnicodes
, nLen
, pDeltaArray
);
212 if( mrFontMgr
.getFontType( mnFontID
) != fonttype::TrueType
)
214 DrawText( rPoint
, pUnicodes
, nLen
, pDeltaArray
);
218 // move and rotate the user coordinate system
219 // avoid the gsave/grestore for the simple cases since it allows
220 // reuse of the current font if it hasn't changed
221 sal_Int32 nCurrentTextAngle
= mnTextAngle
;
222 Point
aPoint( rPoint
);
224 if (nCurrentTextAngle
!= 0)
227 PSTranslate (rPoint
);
228 PSRotate (nCurrentTextAngle
);
230 aPoint
= Point( 0, 0 );
235 // vertical glyphs can have an additional rotation ... sigh.
236 // so break up text in chunks of normal glyphs and print out
237 // specially rotated glyphs extra
238 sal_uInt32
* pTempGlyphIds
= (sal_uInt32
*)alloca(sizeof(sal_Int32
)*nLen
);
239 sal_Int32
* pTempDelta
= (sal_Int32
*)alloca(sizeof(sal_Int32
)*nLen
);
240 sal_Unicode
* pTempUnicodes
= (sal_Unicode
*)alloca(sizeof(sal_Unicode
)*nLen
);
241 sal_Int16 nTempLen
= 0;
242 sal_Int32 nTempFirstDelta
= 0;
244 sal_Int32 nTextHeight
= maVirtualStatus
.mnTextHeight
;
245 sal_Int32 nTextWidth
= maVirtualStatus
.mnTextWidth
? maVirtualStatus
.mnTextWidth
: maVirtualStatus
.mnTextHeight
;
246 sal_Int32 nAscend
= mrFontMgr
.getFontAscend( mnFontID
);
247 sal_Int32 nDescend
= mrFontMgr
.getFontDescend( mnFontID
);
249 nDescend
= nDescend
* nTextHeight
/ 1000;
250 nAscend
= nAscend
* nTextHeight
/ 1000;
252 for( sal_Int16 i
= 0; i
< nLen
; i
++ )
254 sal_Int32 nRot
= ((pGlyphIds
[i
] >> 24) & 3);
257 pTempUnicodes
[nTempLen
] = pUnicodes
[i
];
258 pTempGlyphIds
[nTempLen
] = pGlyphIds
[i
];
260 pTempDelta
[nTempLen
-1] = pDeltaArray
[i
-1]-nTempFirstDelta
;
263 // the first element in pDeltaArray shows
264 // the offset of the second character
265 // so if the first glyph is normal
266 // then we do not need to move the delta indices
267 // else we have to move them down by one and
268 // recalculate aPoint and all deltas
270 nTempFirstDelta
= pDeltaArray
[ i
-1 ];
276 sal_Int32 nOffset
= i
> 0 ? pDeltaArray
[i
-1] : 0;
277 sal_Int32 nRotAngle
= 0;
282 aRotPoint
= Point( -nAscend
*nTextWidth
/nTextHeight
, -nDescend
*nTextWidth
/nTextHeight
- nOffset
);
286 aRotPoint
= Point( -nOffset
, (nAscend
+nDescend
) );
290 aRotPoint
= Point( -nDescend
*nTextWidth
/nTextHeight
, nOffset
+ nAscend
*nTextWidth
/nTextHeight
);
293 sal_uInt32 nRotGlyphId
= pGlyphIds
[i
];
294 sal_Unicode nRotUnicode
= pUnicodes
[i
];
295 sal_Int32 nRotDelta
= 0;
297 // transform matrix to new individual direction
299 GraphicsStatus aSaveStatus
= maVirtualStatus
;
300 if( nRot
!= 2 ) // switch font aspect
302 maVirtualStatus
.mnTextWidth
= nTextHeight
;
303 maVirtualStatus
.mnTextHeight
= nTextWidth
;
305 if( aPoint
.X() || aPoint
.Y() )
306 PSTranslate( aPoint
);
307 PSRotate (nRotAngle
);
308 // draw the rotated glyph
309 drawGlyphs( aRotPoint
, &nRotGlyphId
, &nRotUnicode
, 1, &nRotDelta
);
311 // restore previous state
312 maVirtualStatus
= aSaveStatus
;
317 pGlyphIds
= pTempGlyphIds
;
318 pUnicodes
= pTempUnicodes
;
319 pDeltaArray
= pTempDelta
;
322 aPoint
.X() += nTempFirstDelta
;
326 drawGlyphs( aPoint
, pGlyphIds
, pUnicodes
, nLen
, pDeltaArray
);
328 // restore the user coordinate system
329 if (nCurrentTextAngle
!= 0)
332 mnTextAngle
= nCurrentTextAngle
;
337 PrinterGfx::DrawText (
339 const sal_Unicode
* pStr
,
341 const sal_Int32
* pDeltaArray
344 fontID nRestoreFont
= mnFontID
;
346 // setup font[substitutes] and map the string into the symbol area in case of
349 sal_Unicode
*pEffectiveStr
;
350 if ( aFont
.IsSymbolFont() )
352 pEffectiveStr
= (sal_Unicode
*)alloca(nLen
* sizeof(pStr
[0]));
353 for (int i
= 0; i
< nLen
; i
++)
354 pEffectiveStr
[i
] = pStr
[i
] < 256 ? pStr
[i
] + 0xF000 : pStr
[i
];
358 pEffectiveStr
= const_cast<sal_Unicode
*>(pStr
);
361 fontID
*pFontMap
= (fontID
*) alloca(nLen
* sizeof(fontID
));
362 sal_Int32
*pCharWidth
= (sal_Int32
*) alloca(nLen
* sizeof(sal_Int32
));
364 for( int n
= 0; n
< nLen
; n
++ )
366 CharacterMetric aBBox
;
367 pFontMap
[n
] = getCharMetric (aFont
, pEffectiveStr
[n
], &aBBox
);
368 pCharWidth
[n
] = getCharWidth (mbTextVertical
, pEffectiveStr
[n
], &aBBox
);
371 // setup a new delta array, use virtual resolution of 1000
372 sal_Int32
* pNewDeltaArray
= (sal_Int32
*)alloca( sizeof( sal_Int32
)*nLen
);
373 if ( pDeltaArray
!= 0)
375 for (int i
= 0; i
< nLen
- 1; i
++)
376 pNewDeltaArray
[i
] = 1000 * pDeltaArray
[i
];
377 pNewDeltaArray
[nLen
- 1] = 0;
381 pNewDeltaArray
[0] = pCharWidth
[0];
382 for (int i
= 1; i
< nLen
; i
++)
383 pNewDeltaArray
[i
] = pNewDeltaArray
[i
-1] + pCharWidth
[i
];
386 // move and rotate the user coordinate system
387 // avoid the gsave/grestore for the simple cases since it allows
388 // reuse of the current font if it hasn't changed
389 sal_Int32 nCurrentTextAngle
= mnTextAngle
;
390 sal_Int32 nCurrentPointX
;
391 sal_Int32 nCurrentPointY
;
393 if (nCurrentTextAngle
!= 0)
396 PSTranslate (rPoint
);
397 PSRotate (nCurrentTextAngle
);
405 nCurrentPointX
= rPoint
.X();
406 nCurrentPointY
= rPoint
.Y();
410 sal_Int32 nDelta
= 0;
411 for (int nTo
= 0; nTo
< nLen
; )
414 fontID nFont
= pFontMap
[ nFrom
];
416 while ((nTo
< nLen
) && (nFont
== pFontMap
[nTo
]))
418 pNewDeltaArray
[ nTo
] = (sal_Int32
)(((0.5 + pNewDeltaArray
[ nTo
]) / 1000.0) - nDelta
);
423 maVirtualStatus
.mnTextHeight
, maVirtualStatus
.mnTextWidth
,
426 maVirtualStatus
.mbArtItalic
,
427 maVirtualStatus
.mbArtBold
432 drawVerticalizedText(
433 Point(nCurrentPointX
+ nDelta
, nCurrentPointY
),
434 pEffectiveStr
+ nFrom
, nTo
- nFrom
,
435 pNewDeltaArray
+ nFrom
);
440 Point(nCurrentPointX
+ nDelta
, nCurrentPointY
),
441 pEffectiveStr
+ nFrom
, nTo
- nFrom
,
442 pDeltaArray
== NULL
? NULL
: pNewDeltaArray
+ nFrom
);
444 nDelta
+= pNewDeltaArray
[ nTo
- 1 ];
447 // restore the user coordinate system
448 if (nCurrentTextAngle
!= 0)
451 mnTextAngle
= nCurrentTextAngle
;
454 // restore the original font settings
455 SetFont( nRestoreFont
,
456 maVirtualStatus
.mnTextHeight
, maVirtualStatus
.mnTextWidth
,
457 mnTextAngle
, mbTextVertical
,
458 maVirtualStatus
.mbArtItalic
,
459 maVirtualStatus
.mbArtBold
463 void PrinterGfx::drawVerticalizedText(
465 const sal_Unicode
* pStr
,
467 const sal_Int32
* pDeltaArray
470 sal_Int32
* pDelta
= (sal_Int32
*)alloca( nLen
* sizeof(sal_Int32
) );
472 int nTextScale
= maVirtualStatus
.mnTextWidth
? maVirtualStatus
.mnTextWidth
: maVirtualStatus
.mnTextHeight
;
473 int nNormalAngle
= mnTextAngle
;
474 int nDeltaAngle
, nLastPos
= 0;
476 double fSin
= sin( -2.0*M_PI
*nNormalAngle
/3600 );
477 double fCos
= cos( -2.0*M_PI
*nNormalAngle
/3600 );
479 PrintFontManager
&rMgr
= PrintFontManager::get();
481 rMgr
.getFontInfo( mnFontID
, aInfo
);
483 bool* pGsubFlags
= (bool*)alloca( nLen
* sizeof(bool) );
484 rMgr
.hasVerticalSubstitutions( mnFontID
, pStr
, nLen
, pGsubFlags
);
486 Point
aPoint( rPoint
);
487 for( int i
= 0; i
< nLen
; )
489 while( ( nDeltaAngle
= getVerticalDeltaAngle( pStr
[i
] ) ) == 0 && i
< nLen
)
491 if( i
<= nLen
&& i
> nLastPos
)
493 for( int n
= nLastPos
; n
< i
; n
++ )
494 pDelta
[n
] = pDeltaArray
[n
] - (aPoint
.X() - rPoint
.X() );
497 maVirtualStatus
.mnTextHeight
, maVirtualStatus
.mnTextWidth
,
498 nNormalAngle
, mbTextVertical
,
499 maVirtualStatus
.mbArtItalic
,
500 maVirtualStatus
.mbArtBold
);
501 drawText( aPoint
, pStr
+ nLastPos
, i
- nLastPos
, pDelta
+ nLastPos
);
503 aPoint
.X() = (sal_Int32
)(rPoint
.X() + ((double)pDeltaArray
[i
-1] * fCos
));
504 aPoint
.Y() = (sal_Int32
)(rPoint
.Y() + ((double)pDeltaArray
[i
-1] * fSin
));
508 int nOldWidth
= maVirtualStatus
.mnTextWidth
;
509 int nOldHeight
= maVirtualStatus
.mnTextHeight
;
512 maVirtualStatus
.mnTextHeight
,
513 nNormalAngle
+ nDeltaAngle
,
515 maVirtualStatus
.mbArtItalic
,
516 maVirtualStatus
.mbArtBold
);
518 double nA
= nTextScale
* aInfo
.m_nAscend
/ 1000.0;
519 double nD
= nTextScale
* aInfo
.m_nDescend
/ 1000.0;
520 double fStretch
= (double)maVirtualStatus
.mnTextWidth
/ maVirtualStatus
.mnTextHeight
;
524 Point
aPos( aPoint
);
525 switch( nDeltaAngle
)
528 aPos
.X() += (sal_Int32
)(+nA
* fCos
+ nD
* fSin
);
529 aPos
.Y() += (sal_Int32
)(-nA
* fSin
+ nD
* fCos
);
532 aPos
.X() += (sal_Int32
)(+nA
* fSin
+ nD
* fCos
);
533 aPos
.Y() += (sal_Int32
)(-(nTextScale
*fStretch
- nD
) * fCos
);
536 drawText( aPos
, pStr
+i
, 1, NULL
);
537 if( i
< nLen
-1 && pDeltaArray
)
539 aPoint
.X() = (sal_Int32
)(rPoint
.X() + ((double)pDeltaArray
[i
] * fCos
));
540 aPoint
.Y() = (sal_Int32
)(rPoint
.Y() + ((double)pDeltaArray
[i
] * fSin
));
543 // swap text width/height again
549 maVirtualStatus
.mbArtItalic
,
550 maVirtualStatus
.mbArtBold
);
555 mnTextAngle
= nNormalAngle
;
559 PrinterGfx::LicenseWarning(const Point
& rPoint
, const sal_Unicode
* pStr
,
560 sal_Int16 nLen
, const sal_Int32
* pDeltaArray
)
562 // treat it like a builtin font in case a user has that font also in the
563 // printer. This is not so unlikely as it may seem; no print embedding
564 // licensed fonts are often used (or so they say) in companies:
565 // they are installed on displays and printers, but get not embedded in
566 // they are installed on displays and printers, but get not embedded in
567 // print files or documents because they are not licensed for use outside
569 rtl::OString
aMessage( "The font " );
570 aMessage
+= rtl::OUStringToOString( mrFontMgr
.getPSName(mnFontID
),
571 RTL_TEXTENCODING_ASCII_US
);
572 aMessage
+= " could not be downloaded\nbecause its license does not allow for that";
573 PSComment( aMessage
.getStr() );
575 rtl::OString aFontName
= rtl::OUStringToOString(
576 mrFontMgr
.getPSName(mnFontID
),
577 RTL_TEXTENCODING_ASCII_US
);
578 PSSetFont (aFontName
, RTL_TEXTENCODING_ISO_8859_1
);
580 sal_Size nSize
= 4 * nLen
;
581 sal_uChar
* pBuffer
= (sal_uChar
*)alloca (nSize
* sizeof(sal_uChar
));
583 ConverterFactory
* pCvt
= GetConverterFactory ();
584 nSize
= pCvt
->Convert (pStr
, nLen
, pBuffer
, nSize
, RTL_TEXTENCODING_ISO_8859_1
);
587 PSShowText (pBuffer
, nLen
, nSize
, pDeltaArray
);
591 PrinterGfx::drawText(
593 const sal_Unicode
* pStr
,
595 const sal_Int32
* pDeltaArray
601 fonttype::type eType
= mrFontMgr
.getFontType (mnFontID
);
603 if (eType
== fonttype::Type1
)
604 PSUploadPS1Font (mnFontID
);
606 if ( eType
== fonttype::TrueType
607 && !mrFontMgr
.isFontDownloadingAllowed(mnFontID
))
609 LicenseWarning(rPoint
, pStr
, nLen
, pDeltaArray
);
613 if( mrFontMgr
.getUseOnlyFontEncoding( mnFontID
) )
615 GlyphSet
aGSet( mnFontID
, mbTextVertical
);
616 aGSet
.DrawText( *this, rPoint
, pStr
, nLen
, pDeltaArray
);
620 // search for a glyph set matching the set font
621 std::list
< GlyphSet
>::iterator aIter
;
622 for (aIter
= maPS3Font
.begin(); aIter
!= maPS3Font
.end(); aIter
++)
623 if ( ((*aIter
).GetFontID() == mnFontID
)
624 && ((*aIter
).IsVertical() == mbTextVertical
))
626 (*aIter
).DrawText (*this, rPoint
, pStr
, nLen
, pDeltaArray
);
630 // not found ? create a new one
631 if (aIter
== maPS3Font
.end())
633 maPS3Font
.push_back (GlyphSet(mnFontID
, mbTextVertical
));
634 maPS3Font
.back().DrawText (*this, rPoint
, pStr
, nLen
, pDeltaArray
);
639 PrinterGfx::getCharWidth (sal_Bool b_vert
, sal_Unicode n_char
, CharacterMetric
*p_bbox
)
641 b_vert
= b_vert
&& (getVerticalDeltaAngle(n_char
) != 0);
642 int w
= b_vert
? p_bbox
->height
: p_bbox
->width
;
643 w
*= maVirtualStatus
.mnTextWidth
? maVirtualStatus
.mnTextWidth
: maVirtualStatus
.mnTextHeight
;
648 PrinterGfx::getCharMetric (const Font3
&rFont
, sal_Unicode n_char
, CharacterMetric
*p_bbox
)
653 for (fontID n
= 0; n
< 3; n
++)
655 fontID n_font
= rFont
.GetFont(n
);
658 if( mbStrictSO52Compatibility
)
660 fonttype::type eType
= mrFontMgr
.getFontType( n_font
);
661 if( (eType
== fonttype::Builtin
|| eType
== fonttype::Type1
) )
663 // note: any character exchanged here MUST also be changed
664 // in the compatibility ISO encoding vector in the prolog
666 sal_Unicode aRepl
= 0;
669 else if( n_char
== 0x27 )
672 additional characters that may need backwards compatibility:
673 ISO5589 StdEnc Unicode suggested n_char -> aRepl
674 0264 0302 0x00B4 0x00B4 (acute) -> 0x2019 (quiteright)
675 0246 - 0x00A6 0x00A6 (brokenbar) -> 0x007C (bar)
676 0225 0267 0x0095 0x0095 () -> 0x2022 (bullet)
677 0140 0301 0x0060 0x0060 (grave) -> ?
681 mrFontMgr
.getMetrics( n_font
, aRepl
, aRepl
, p_bbox
);
682 if (p_bbox
->width
>= 0 && p_bbox
->height
>= 0)
687 mrFontMgr
.getMetrics( n_font
, n_char
, n_char
, p_bbox
);
689 if (p_bbox
->width
>= 0 && p_bbox
->height
>= 0)
693 return getCharMetric (rFont
, '?', p_bbox
);
695 return rFont
.GetFont(0) != -1 ? rFont
.GetFont(0) : rFont
.GetFont(1);
699 PrinterGfx::getFontSubstitute () const
701 if( mpFontSubstitutes
)
703 ::std::hash_map
< fontID
, fontID
>::const_iterator it
=
704 mpFontSubstitutes
->find( mnFontID
);
705 if( it
!= mpFontSubstitutes
->end() )
713 PrinterGfx::GetCharWidth (sal_Unicode nFrom
, sal_Unicode nTo
, long *pWidthArray
)
716 if (aFont
.IsSymbolFont() && (nFrom
< 256) && (nTo
< 256))
722 for( int n
= 0; n
< (nTo
- nFrom
+ 1); n
++ )
724 CharacterMetric aBBox
;
725 getCharMetric (aFont
, n
+ nFrom
, &aBBox
);
726 pWidthArray
[n
] = getCharWidth (mbTextVertical
, n
+ nFrom
, &aBBox
);
729 // returned metrics have postscript precision
733 const ::std::list
< KernPair
>& PrinterGfx::getKernPairs( bool bVertical
) const
736 * Note: this is only a 80% solution: if a font is only
737 * partially substituted in a string due to missing glyphs
738 * the results may not be perfect; the more so the more the
739 * substitution differs from the original metricwise. But
740 * vcl only asks for KernPairs for each font once and NOT
741 * in a string context this is the best we can do.
742 * In future the kerning should be done on a per string basis.
744 fontID nFont
= mnFontID
;
745 if( mpFontSubstitutes
)
747 ::std::hash_map
< fontID
, fontID
>::const_iterator it
=
748 mpFontSubstitutes
->find( mnFontID
);
749 if( it
!= mpFontSubstitutes
->end() )
752 return mrFontMgr
.getKernPairs( nFont
, bVertical
);
756 * advanced glyph handling
760 PrinterGfx::GetGlyphBoundRect (sal_Unicode
/*c*/, Rectangle
& /*rOutRect*/)
766 PrinterGfx::GetGlyphOutline (sal_Unicode
/*c*/,
767 sal_uInt16
**/
*ppPolySizes*/
, Point
**/
*ppPoints*/
, sal_uInt8
**/
*ppFlags*/
)
773 * spool the converted truetype fonts to the page header after the page body is
775 * for Type1 fonts spool additional reencoding vectors that are necessary to access the
780 PrinterGfx::OnEndPage ()
785 PrinterGfx::OnEndJob ()
792 PrinterGfx::writeResources( osl::File
* pFile
, std::list
< rtl::OString
>& rSuppliedFonts
, std::list
< rtl::OString
>& rNeededFonts
)
794 // write all type 1 fonts
795 std::list
< sal_Int32
>::iterator aFont
;
796 // already in the document header ?
797 for (aFont
= maPS1Font
.begin(); aFont
!= maPS1Font
.end(); ++aFont
)
799 const rtl::OString
& rSysPath (mrFontMgr
.getFontFileSysPath(*aFont
) );
800 rtl::OUString aUNCPath
;
801 osl::File::getFileURLFromSystemPath (OStringToOUString (rSysPath
, osl_getThreadTextEncoding()), aUNCPath
);
802 osl::File
aFontFile (aUNCPath
);
804 // provide the pfb or pfa font as a (pfa-)font resource
805 rtl::OString aPostScriptName
=
806 rtl::OUStringToOString ( mrFontMgr
.getPSName(*aFont
),
807 RTL_TEXTENCODING_ASCII_US
);
809 WritePS (pFile
, "%%BeginResource: font ");
810 WritePS (pFile
, aPostScriptName
.getStr());
811 WritePS (pFile
, "\n");
813 osl::File::RC nError
= aFontFile
.open (OpenFlag_Read
);
814 if (nError
== osl::File::E_None
)
816 convertPfbToPfa (aFontFile
, *pFile
);
819 pFile
->setPos(osl_Pos_Current
, -1);
820 char lastchar
= '\n';
821 sal_uInt64
uBytes(1);
822 pFile
->read((void *)(&lastchar
), uBytes
, uBytes
);
823 if (lastchar
!= '\n')
824 WritePS (pFile
, "\n");
826 WritePS (pFile
, "%%EndResource\n");
827 rSuppliedFonts
.push_back( aPostScriptName
);
830 // write glyphsets and reencodings
831 std::list
< GlyphSet
>::iterator aIter
;
832 for (aIter
= maPS3Font
.begin(); aIter
!= maPS3Font
.end(); ++aIter
)
834 if (aIter
->GetFontType() == fonttype::TrueType
)
836 aIter
->PSUploadFont (*pFile
, *this, mbUploadPS42Fonts
? true : false, rSuppliedFonts
);
839 // ( aIter->GetFontType() == fonttype::Type1
840 // || aIter->GetFontType() == fonttype::Builtin )
842 aIter
->PSUploadEncoding (pFile
, *this);
843 if( aIter
->GetFontType() == fonttype::Builtin
)
844 rNeededFonts
.push_back(
845 rtl::OUStringToOString(
846 mrFontMgr
.getPSName( aIter
->GetFontID() ),
847 RTL_TEXTENCODING_ASCII_US
) );
852 bool PrinterGfx::getStrictSO52Compatibility() const
854 return mbStrictSO52Compatibility
;
857 void PrinterGfx::setStrictSO52Compatibility( bool bCompat
)
859 mbStrictSO52Compatibility
= bCompat
;