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: glyphset.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 <osl/thread.h>
34 #include <glyphset.hxx>
35 #include <psputil.hxx>
36 #include <psprint/printergfx.hxx>
37 #include <psprint/fontmanager.hxx>
42 #include <sal/alloca.h>
43 #include <rtl/ustring.hxx>
44 #include <rtl/strbuf.hxx>
48 #include <../fontsubset/sft.h>
58 mbUseFontEncoding (false)
61 GlyphSet::GlyphSet (sal_Int32 nFontID
, sal_Bool bVertical
)
63 mbVertical (bVertical
)
65 PrintFontManager
&rMgr
= PrintFontManager::get();
66 meBaseType
= rMgr
.getFontType (mnFontID
);
67 maBaseName
= OUStringToOString (rMgr
.getPSName(mnFontID
),
68 RTL_TEXTENCODING_ASCII_US
);
69 mnBaseEncoding
= rMgr
.getFontEncoding(mnFontID
);
70 mbUseFontEncoding
= rMgr
.getUseOnlyFontEncoding(mnFontID
);
73 GlyphSet::~GlyphSet ()
75 /* FIXME delete the glyphlist ??? */
79 GlyphSet::GetFontID ()
85 GlyphSet::GetFontType ()
91 GlyphSet::IsVertical ()
97 GlyphSet::SetFont (sal_Int32 nFontID
, sal_Bool bVertical
)
103 mbVertical
= bVertical
;
105 PrintFontManager
&rMgr
= PrintFontManager::get();
106 meBaseType
= rMgr
.getFontType (mnFontID
);
107 maBaseName
= OUStringToOString (rMgr
.getPSName(mnFontID
),
108 RTL_TEXTENCODING_ASCII_US
);
109 mnBaseEncoding
= rMgr
.getFontEncoding(mnFontID
);
110 mbUseFontEncoding
= rMgr
.getUseOnlyFontEncoding(mnFontID
);
116 GlyphSet::GetCharID (
118 sal_uChar
* nOutGlyphID
,
119 sal_Int32
* nOutGlyphSetID
122 return LookupCharID (nChar
, nOutGlyphID
, nOutGlyphSetID
)
123 || AddCharID (nChar
, nOutGlyphID
, nOutGlyphSetID
);
127 GlyphSet::GetGlyphID (
129 sal_Unicode nUnicode
,
130 sal_uChar
* nOutGlyphID
,
131 sal_Int32
* nOutGlyphSetID
134 return LookupGlyphID (nGlyph
, nOutGlyphID
, nOutGlyphSetID
)
135 || AddGlyphID (nGlyph
, nUnicode
, nOutGlyphID
, nOutGlyphSetID
);
139 GlyphSet::LookupCharID (
141 sal_uChar
* nOutGlyphID
,
142 sal_Int32
* nOutGlyphSetID
145 char_list_t::iterator aGlyphSet
;
146 sal_Int32 nGlyphSetID
;
148 // loop thru all the font subsets
149 for (aGlyphSet
= maCharList
.begin(), nGlyphSetID
= 1;
150 aGlyphSet
!= maCharList
.end();
151 ++aGlyphSet
, nGlyphSetID
++)
153 // check every subset if it contains the queried unicode char
154 char_map_t::const_iterator aGlyph
= (*aGlyphSet
).find (nChar
);
155 if (aGlyph
!= (*aGlyphSet
).end())
157 // success: found the unicode char, return the glyphid and the glyphsetid
158 *nOutGlyphSetID
= nGlyphSetID
;
159 *nOutGlyphID
= (*aGlyph
).second
;
164 *nOutGlyphSetID
= -1;
170 GlyphSet::LookupGlyphID (
172 sal_uChar
* nOutGlyphID
,
173 sal_Int32
* nOutGlyphSetID
176 glyph_list_t::iterator aGlyphSet
;
177 sal_Int32 nGlyphSetID
;
179 // loop thru all the font subsets
180 for (aGlyphSet
= maGlyphList
.begin(), nGlyphSetID
= 1;
181 aGlyphSet
!= maGlyphList
.end();
182 ++aGlyphSet
, nGlyphSetID
++)
184 // check every subset if it contains the queried unicode char
185 glyph_map_t::const_iterator aGlyph
= (*aGlyphSet
).find (nGlyph
);
186 if (aGlyph
!= (*aGlyphSet
).end())
188 // success: found the glyph id, return the mapped glyphid and the glyphsetid
189 *nOutGlyphSetID
= nGlyphSetID
;
190 *nOutGlyphID
= (*aGlyph
).second
;
195 *nOutGlyphSetID
= -1;
201 GlyphSet::GetAnsiMapping (sal_Unicode nUnicodeChar
)
203 static rtl_UnicodeToTextConverter aConverter
=
204 rtl_createUnicodeToTextConverter(RTL_TEXTENCODING_MS_1252
);
205 static rtl_UnicodeToTextContext aContext
=
206 rtl_createUnicodeToTextContext( aConverter
);
211 const sal_uInt32 nCvtFlags
= RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
212 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
;
214 sal_Size nSize
= rtl_convertUnicodeToText( aConverter
, aContext
,
215 &nUnicodeChar
, 1, &nAnsiChar
, 1,
216 nCvtFlags
, &nCvtInfo
, &nCvtChars
);
218 return nSize
== 1 ? (sal_uChar
)nAnsiChar
: (sal_uChar
)0;
222 GlyphSet::GetSymbolMapping (sal_Unicode nUnicodeChar
)
224 if (0x0000 < nUnicodeChar
&& nUnicodeChar
< 0x0100)
225 return (sal_uChar
)nUnicodeChar
;
226 if (0xf000 < nUnicodeChar
&& nUnicodeChar
< 0xf100)
227 return (sal_uChar
)nUnicodeChar
;
233 GlyphSet::AddNotdef (char_map_t
&rCharMap
)
235 if (rCharMap
.size() == 0)
240 GlyphSet::AddNotdef (glyph_map_t
&rGlyphMap
)
242 if (rGlyphMap
.size() == 0)
246 GlyphSet::AddCharID (
248 sal_uChar
* nOutGlyphID
,
249 sal_Int32
* nOutGlyphSetID
252 sal_uChar nMappedChar
;
254 // XXX important: avoid to reencode type1 symbol fonts
255 if (mnBaseEncoding
== RTL_TEXTENCODING_SYMBOL
)
256 nMappedChar
= GetSymbolMapping (nChar
);
258 nMappedChar
= GetAnsiMapping (nChar
);
260 // create an empty glyphmap that is reserved for iso1252 encoded glyphs
261 // (or -- unencoded -- symbol glyphs) and a second map that takes any other
262 if (maCharList
.empty())
264 char_map_t aMap
, aMapp
;
266 maCharList
.push_back (aMap
);
267 maCharList
.push_back (aMapp
);
269 // if the last map is full, create a new one
270 if ((!nMappedChar
) && (maCharList
.back().size() == 255))
273 maCharList
.push_back (aMap
);
276 // insert a new glyph in the font subset
279 // always put iso1252 chars into the first map, map them on itself
280 char_map_t
& aGlyphSet
= maCharList
.front();
281 AddNotdef (aGlyphSet
);
283 aGlyphSet
[nChar
] = nMappedChar
;
285 *nOutGlyphID
= nMappedChar
;
289 // other chars are just appended to the list
290 char_map_t
& aGlyphSet
= maCharList
.back();
291 AddNotdef (aGlyphSet
);
293 int nSize
= aGlyphSet
.size();
295 aGlyphSet
[nChar
] = nSize
;
296 *nOutGlyphSetID
= maCharList
.size();
297 *nOutGlyphID
= aGlyphSet
[nChar
];
304 GlyphSet::AddGlyphID (
306 sal_Unicode nUnicode
,
307 sal_uChar
* nOutGlyphID
,
308 sal_Int32
* nOutGlyphSetID
311 sal_uChar nMappedChar
;
313 // XXX important: avoid to reencode type1 symbol fonts
314 if (mnBaseEncoding
== RTL_TEXTENCODING_SYMBOL
)
315 nMappedChar
= GetSymbolMapping (nUnicode
);
317 nMappedChar
= GetAnsiMapping (nUnicode
);
319 // create an empty glyphmap that is reserved for iso1252 encoded glyphs
320 // (or -- unencoded -- symbol glyphs) and a second map that takes any other
321 if (maGlyphList
.empty())
323 glyph_map_t aMap
, aMapp
;
325 maGlyphList
.push_back (aMap
);
326 maGlyphList
.push_back (aMapp
);
328 // if the last map is full, create a new one
329 if ((!nMappedChar
) && (maGlyphList
.back().size() == 255))
332 maGlyphList
.push_back (aMap
);
335 // insert a new glyph in the font subset
338 // always put iso1252 chars into the first map, map them on itself
339 glyph_map_t
& aGlyphSet
= maGlyphList
.front();
340 AddNotdef (aGlyphSet
);
342 aGlyphSet
[nGlyph
] = nMappedChar
;
344 *nOutGlyphID
= nMappedChar
;
348 // other chars are just appended to the list
349 glyph_map_t
& aGlyphSet
= maGlyphList
.back();
350 AddNotdef (aGlyphSet
);
352 int nSize
= aGlyphSet
.size();
354 aGlyphSet
[nGlyph
] = nSize
;
355 *nOutGlyphSetID
= maGlyphList
.size();
356 *nOutGlyphID
= aGlyphSet
[nGlyph
];
363 GlyphSet::GetCharSetName (sal_Int32 nGlyphSetID
)
365 if (meBaseType
== fonttype::TrueType
)
367 OStringBuffer
aSetName( maBaseName
.getLength() + 32 );
368 aSetName
.append( maBaseName
);
369 aSetName
.append( "FID" );
370 aSetName
.append( mnFontID
);
371 aSetName
.append( mbVertical
? "VCSet" : "HCSet" );
372 aSetName
.append( nGlyphSetID
);
373 return aSetName
.makeStringAndClear();
376 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
383 GlyphSet::GetGlyphSetName (sal_Int32 nGlyphSetID
)
385 if (meBaseType
== fonttype::TrueType
)
387 OStringBuffer
aSetName( maBaseName
.getLength() + 32 );
388 aSetName
.append( maBaseName
);
389 aSetName
.append( "FID" );
390 aSetName
.append( mnFontID
);
391 aSetName
.append( mbVertical
? "VGSet" : "HGSet" );
392 aSetName
.append( nGlyphSetID
);
393 return aSetName
.makeStringAndClear();
396 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
403 GlyphSet::GetGlyphSetEncoding (sal_Int32 nGlyphSetID
)
405 if (meBaseType
== fonttype::TrueType
)
406 return RTL_TEXTENCODING_DONTKNOW
;
409 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
410 if (mnBaseEncoding
== RTL_TEXTENCODING_SYMBOL
)
411 return RTL_TEXTENCODING_SYMBOL
;
413 return nGlyphSetID
== 1 ? RTL_TEXTENCODING_MS_1252
414 : RTL_TEXTENCODING_USER_START
+ nGlyphSetID
;
419 GlyphSet::GetGlyphSetEncodingName (rtl_TextEncoding nEnc
, const OString
&rFontName
)
421 if ( nEnc
== RTL_TEXTENCODING_MS_1252
422 || nEnc
== RTL_TEXTENCODING_ISO_8859_1
)
424 return OString("ISO1252Encoding");
427 if (nEnc
>= RTL_TEXTENCODING_USER_START
&& nEnc
<= RTL_TEXTENCODING_USER_END
)
431 + OString::valueOf ((sal_Int32
)(nEnc
- RTL_TEXTENCODING_USER_START
));
440 GlyphSet::GetGlyphSetEncodingName (sal_Int32 nGlyphSetID
)
442 return GetGlyphSetEncodingName (GetGlyphSetEncoding(nGlyphSetID
), maBaseName
);
446 GlyphSet::PSDefineReencodedFont (osl::File
* pOutFile
, sal_Int32 nGlyphSetID
)
449 if ((meBaseType
!= fonttype::Builtin
) && (meBaseType
!= fonttype::Type1
))
452 sal_Char pEncodingVector
[256];
455 nSize
+= psp::appendStr ("(", pEncodingVector
+ nSize
);
456 nSize
+= psp::appendStr (GetReencodedFontName(nGlyphSetID
),
457 pEncodingVector
+ nSize
);
458 nSize
+= psp::appendStr (") cvn (", pEncodingVector
+ nSize
);
459 nSize
+= psp::appendStr (maBaseName
.getStr(),
460 pEncodingVector
+ nSize
);
461 nSize
+= psp::appendStr (") cvn ", pEncodingVector
+ nSize
);
462 nSize
+= psp::appendStr (GetGlyphSetEncodingName(nGlyphSetID
),
463 pEncodingVector
+ nSize
);
464 nSize
+= psp::appendStr (" psp_definefont\n",
465 pEncodingVector
+ nSize
);
467 psp::WritePS (pOutFile
, pEncodingVector
);
471 GlyphSet::GetReencodedFontName (rtl_TextEncoding nEnc
, const OString
&rFontName
)
473 if ( nEnc
== RTL_TEXTENCODING_MS_1252
474 || nEnc
== RTL_TEXTENCODING_ISO_8859_1
)
477 + OString("-iso1252");
480 if (nEnc
>= RTL_TEXTENCODING_USER_START
&& nEnc
<= RTL_TEXTENCODING_USER_END
)
484 + OString::valueOf ((sal_Int32
)(nEnc
- RTL_TEXTENCODING_USER_START
));
493 GlyphSet::GetReencodedFontName (sal_Int32 nGlyphSetID
)
495 return GetReencodedFontName (GetGlyphSetEncoding(nGlyphSetID
), maBaseName
);
498 void GlyphSet::DrawGlyphs(
501 const sal_uInt32
* pGlyphIds
,
502 const sal_Unicode
* pUnicodes
,
504 const sal_Int32
* pDeltaArray
)
506 sal_uChar
*pGlyphID
= (sal_uChar
*)alloca (nLen
* sizeof(sal_uChar
));
507 sal_Int32
*pGlyphSetID
= (sal_Int32
*)alloca (nLen
* sizeof(sal_Int32
));
508 std::set
< sal_Int32
> aGlyphSet
;
510 // convert unicode to font glyph id and font subset
511 for (int nChar
= 0; nChar
< nLen
; nChar
++)
513 GetGlyphID (pGlyphIds
[nChar
], pUnicodes
[nChar
], pGlyphID
+ nChar
, pGlyphSetID
+ nChar
);
514 aGlyphSet
.insert (pGlyphSetID
[nChar
]);
517 // loop over all glyph sets to detect substrings that can be xshown together
518 // without changing the postscript font
519 sal_Int32
*pDeltaSubset
= (sal_Int32
*)alloca (nLen
* sizeof(sal_Int32
));
520 sal_uChar
*pGlyphSubset
= (sal_uChar
*)alloca (nLen
* sizeof(sal_uChar
));
522 std::set
< sal_Int32
>::iterator aSet
;
523 for (aSet
= aGlyphSet
.begin(); aSet
!= aGlyphSet
.end(); ++aSet
)
525 Point aPoint
= rPoint
;
526 sal_Int32 nOffset
= 0;
527 sal_Int32 nGlyphs
= 0;
530 // get offset to first glyph
531 for (nChar
= 0; (nChar
< nLen
) && (pGlyphSetID
[nChar
] != *aSet
); nChar
++)
533 nOffset
= pDeltaArray
[nChar
];
536 // loop over all chars to extract those that share the current glyph set
537 for (nChar
= 0; nChar
< nLen
; nChar
++)
539 if (pGlyphSetID
[nChar
] == *aSet
)
541 pGlyphSubset
[nGlyphs
] = pGlyphID
[nChar
];
542 // the offset to the next glyph is determined by the glyph in
543 // front of the next glyph with the same glyphset id
544 // most often, this will be the current glyph
545 while ((nChar
+ 1) < nLen
)
547 if (pGlyphSetID
[nChar
+ 1] == *aSet
)
552 pDeltaSubset
[nGlyphs
] = pDeltaArray
[nChar
] - nOffset
;
558 // show the text using the PrinterGfx text api
559 aPoint
.Move (nOffset
, 0);
561 OString
aGlyphSetName(GetGlyphSetName(*aSet
));
562 rGfx
.PSSetFont (aGlyphSetName
, GetGlyphSetEncoding(*aSet
));
563 rGfx
.PSMoveTo (aPoint
);
564 rGfx
.PSShowText (pGlyphSubset
, nGlyphs
, nGlyphs
, nGlyphs
> 1 ? pDeltaSubset
: NULL
);
569 GlyphSet::DrawText (PrinterGfx
&rGfx
, const Point
& rPoint
,
570 const sal_Unicode
* pStr
, sal_Int16 nLen
, const sal_Int32
* pDeltaArray
)
572 // dispatch to the impl method
573 if (pDeltaArray
== NULL
)
574 ImplDrawText (rGfx
, rPoint
, pStr
, nLen
);
576 ImplDrawText (rGfx
, rPoint
, pStr
, nLen
, pDeltaArray
);
580 GlyphSet::ImplDrawText (PrinterGfx
&rGfx
, const Point
& rPoint
,
581 const sal_Unicode
* pStr
, sal_Int16 nLen
)
583 rGfx
.PSMoveTo (rPoint
);
585 if( mbUseFontEncoding
)
587 OString
aPSName( OUStringToOString( rGfx
.GetFontMgr().getPSName( mnFontID
), RTL_TEXTENCODING_ISO_8859_1
) );
588 OString
aBytes( OUStringToOString( OUString( pStr
, nLen
), mnBaseEncoding
) );
589 rGfx
.PSSetFont( aPSName
, mnBaseEncoding
);
590 rGfx
.PSShowText( (const unsigned char*)aBytes
.getStr(), nLen
, aBytes
.getLength() );
595 sal_uChar
*pGlyphID
= (sal_uChar
*)alloca (nLen
* sizeof(sal_uChar
));
596 sal_Int32
*pGlyphSetID
= (sal_Int32
*)alloca (nLen
* sizeof(sal_Int32
));
598 // convert unicode to glyph id and char set (font subset)
599 for (nChar
= 0; nChar
< nLen
; nChar
++)
600 GetCharID (pStr
[nChar
], pGlyphID
+ nChar
, pGlyphSetID
+ nChar
);
602 // loop over the string to draw subsequent pieces of chars
603 // with the same postscript font
604 for (nChar
= 0; nChar
< nLen
; /* atend */)
606 sal_Int32 nGlyphSetID
= pGlyphSetID
[nChar
];
607 sal_Int32 nGlyphs
= 1;
608 for (int nNextChar
= nChar
+ 1; nNextChar
< nLen
; nNextChar
++)
610 if (pGlyphSetID
[nNextChar
] == nGlyphSetID
)
616 // show the text using the PrinterGfx text api
617 OString
aGlyphSetName(GetCharSetName(nGlyphSetID
));
618 rGfx
.PSSetFont (aGlyphSetName
, GetGlyphSetEncoding(nGlyphSetID
));
619 rGfx
.PSShowText (pGlyphID
+ nChar
, nGlyphs
, nGlyphs
);
626 GlyphSet::ImplDrawText (PrinterGfx
&rGfx
, const Point
& rPoint
,
627 const sal_Unicode
* pStr
, sal_Int16 nLen
, const sal_Int32
* pDeltaArray
)
629 if( mbUseFontEncoding
)
631 OString
aPSName( OUStringToOString( rGfx
.GetFontMgr().getPSName( mnFontID
), RTL_TEXTENCODING_ISO_8859_1
) );
632 OString
aBytes( OUStringToOString( OUString( pStr
, nLen
), mnBaseEncoding
) );
633 rGfx
.PSMoveTo( rPoint
);
634 rGfx
.PSSetFont( aPSName
, mnBaseEncoding
);
635 rGfx
.PSShowText( (const unsigned char*)aBytes
.getStr(), nLen
, aBytes
.getLength(), pDeltaArray
);
639 sal_uChar
*pGlyphID
= (sal_uChar
*)alloca (nLen
* sizeof(sal_uChar
));
640 sal_Int32
*pGlyphSetID
= (sal_Int32
*)alloca (nLen
* sizeof(sal_Int32
));
641 std::set
< sal_Int32
> aGlyphSet
;
643 // convert unicode to font glyph id and font subset
644 for (int nChar
= 0; nChar
< nLen
; nChar
++)
646 GetCharID (pStr
[nChar
], pGlyphID
+ nChar
, pGlyphSetID
+ nChar
);
647 aGlyphSet
.insert (pGlyphSetID
[nChar
]);
650 // loop over all glyph sets to detect substrings that can be xshown together
651 // without changing the postscript font
652 sal_Int32
*pDeltaSubset
= (sal_Int32
*)alloca (nLen
* sizeof(sal_Int32
));
653 sal_uChar
*pGlyphSubset
= (sal_uChar
*)alloca (nLen
* sizeof(sal_uChar
));
655 std::set
< sal_Int32
>::iterator aSet
;
656 for (aSet
= aGlyphSet
.begin(); aSet
!= aGlyphSet
.end(); ++aSet
)
658 Point aPoint
= rPoint
;
659 sal_Int32 nOffset
= 0;
660 sal_Int32 nGlyphs
= 0;
663 // get offset to first glyph
664 for (nChar
= 0; (nChar
< nLen
) && (pGlyphSetID
[nChar
] != *aSet
); nChar
++)
666 nOffset
= pDeltaArray
[nChar
];
669 // loop over all chars to extract those that share the current glyph set
670 for (nChar
= 0; nChar
< nLen
; nChar
++)
672 if (pGlyphSetID
[nChar
] == *aSet
)
674 pGlyphSubset
[nGlyphs
] = pGlyphID
[nChar
];
675 // the offset to the next glyph is determined by the glyph in
676 // front of the next glyph with the same glyphset id
677 // most often, this will be the current glyph
678 while ((nChar
+ 1) < nLen
)
680 if (pGlyphSetID
[nChar
+ 1] == *aSet
)
685 pDeltaSubset
[nGlyphs
] = pDeltaArray
[nChar
] - nOffset
;
691 // show the text using the PrinterGfx text api
692 aPoint
.Move (nOffset
, 0);
694 OString
aGlyphSetName(GetCharSetName(*aSet
));
695 rGfx
.PSSetFont (aGlyphSetName
, GetGlyphSetEncoding(*aSet
));
696 rGfx
.PSMoveTo (aPoint
);
697 rGfx
.PSShowText (pGlyphSubset
, nGlyphs
, nGlyphs
, nGlyphs
> 1 ? pDeltaSubset
: NULL
);
702 GlyphSet::PSUploadEncoding(osl::File
* pOutFile
, PrinterGfx
&rGfx
)
705 if ((meBaseType
!= fonttype::Builtin
) && (meBaseType
!= fonttype::Type1
))
707 if (mnBaseEncoding
== RTL_TEXTENCODING_SYMBOL
)
710 PrintFontManager
&rMgr
= rGfx
.GetFontMgr();
712 // loop thru all the font subsets
713 sal_Int32 nGlyphSetID
= 0;
714 char_list_t::iterator aGlyphSet
;
715 for (aGlyphSet
= maCharList
.begin(); aGlyphSet
!= maCharList
.end(); aGlyphSet
++)
719 if (nGlyphSetID
== 1) // latin1 page uses global reencoding table
721 PSDefineReencodedFont (pOutFile
, nGlyphSetID
);
724 if ((*aGlyphSet
).size() == 0) // empty set, doesn't need reencoding
729 // create reencoding table
731 sal_Char pEncodingVector
[256];
734 nSize
+= psp::appendStr ("/",
735 pEncodingVector
+ nSize
);
736 nSize
+= psp::appendStr (GetGlyphSetEncodingName(nGlyphSetID
),
737 pEncodingVector
+ nSize
);
738 nSize
+= psp::appendStr (" [ ",
739 pEncodingVector
+ nSize
);
741 // need a list of glyphs, sorted by glyphid
742 typedef std::map
< sal_uInt8
, sal_Unicode
> ps_mapping_t
;
743 typedef ps_mapping_t::value_type ps_value_t
;
744 ps_mapping_t aSortedGlyphSet
;
746 char_map_t::const_iterator aUnsortedGlyph
;
747 for (aUnsortedGlyph
= (*aGlyphSet
).begin();
748 aUnsortedGlyph
!= (*aGlyphSet
).end();
751 aSortedGlyphSet
.insert(ps_value_t((*aUnsortedGlyph
).second
,
752 (*aUnsortedGlyph
).first
));
755 ps_mapping_t::const_iterator aSortedGlyph
;
756 // loop thru all the glyphs in the subset
757 for (aSortedGlyph
= (aSortedGlyphSet
).begin();
758 aSortedGlyph
!= (aSortedGlyphSet
).end();
761 nSize
+= psp::appendStr ("/",
762 pEncodingVector
+ nSize
);
764 std::list
< OString
> aName( rMgr
.getAdobeNameFromUnicode((*aSortedGlyph
).second
) );
766 if( aName
.begin() != aName
.end() )
767 nSize
+= psp::appendStr ( aName
.front(), pEncodingVector
+ nSize
);
769 nSize
+= psp::appendStr (".notdef", pEncodingVector
+ nSize
);
770 nSize
+= psp::appendStr (" ", pEncodingVector
+ nSize
);
774 nSize
+= psp::appendStr ("\n", pEncodingVector
+ nSize
);
775 psp::WritePS (pOutFile
, pEncodingVector
);
780 nSize
+= psp::appendStr ("] def\n", pEncodingVector
+ nSize
);
781 psp::WritePS (pOutFile
, pEncodingVector
);
783 PSDefineReencodedFont (pOutFile
, nGlyphSetID
);
790 GlyphSet::PSUploadFont (osl::File
& rOutFile
, PrinterGfx
&rGfx
, bool bAsType42
, std::list
< OString
>& rSuppliedFonts
)
792 // only for truetype fonts
793 if (meBaseType
!= fonttype::TrueType
)
796 TrueTypeFont
*pTTFont
;
797 OString
aTTFileName (rGfx
.GetFontMgr().getFontFileSysPath(mnFontID
));
798 int nFace
= rGfx
.GetFontMgr().getFontFaceNumber(mnFontID
);
799 sal_Int32 nSuccess
= OpenTTFontFile(aTTFileName
.getStr(), nFace
< 0 ? 0 : nFace
, &pTTFont
);
800 if (nSuccess
!= SF_OK
)
802 FILE* pTmpFile
= tmpfile();
803 if (pTmpFile
== NULL
)
806 // array of unicode source characters
807 sal_Unicode pUChars
[256];
809 // encoding vector maps character encoding to the ordinal number
810 // of the glyph in the output file
811 sal_uChar pEncoding
[256];
812 sal_uInt16 pTTGlyphMapping
[256];
814 // loop thru all the font subsets
815 sal_Int32 nCharSetID
;
816 char_list_t::iterator aCharSet
;
817 for (aCharSet
= maCharList
.begin(), nCharSetID
= 1;
818 aCharSet
!= maCharList
.end();
819 ++aCharSet
, nCharSetID
++)
821 if ((*aCharSet
).size() == 0)
824 // loop thru all the chars in the subset
825 char_map_t::const_iterator aChar
;
827 for (aChar
= (*aCharSet
).begin(); aChar
!= (*aCharSet
).end(); aChar
++)
829 pUChars
[n
] = (*aChar
).first
;
830 pEncoding
[n
] = (*aChar
).second
;
833 // create a mapping from the unicode chars to the char encoding in
834 // source TrueType font
835 MapString (pTTFont
, pUChars
, (*aCharSet
).size(), pTTGlyphMapping
, mbVertical
);
837 // create the current subset
838 OString aCharSetName
= GetCharSetName(nCharSetID
);
839 fprintf( pTmpFile
, "%%%%BeginResource: font %s\n", aCharSetName
.getStr() );
841 CreateT42FromTTGlyphs (pTTFont
, pTmpFile
, aCharSetName
.getStr(),
842 pTTGlyphMapping
, pEncoding
, (*aCharSet
).size() );
844 CreateT3FromTTGlyphs (pTTFont
, pTmpFile
, aCharSetName
.getStr(),
845 pTTGlyphMapping
, pEncoding
, (*aCharSet
).size(),
846 0 /* 0 = horizontal, 1 = vertical */ );
847 fprintf( pTmpFile
, "%%%%EndResource\n" );
848 rSuppliedFonts
.push_back( aCharSetName
);
851 // loop thru all the font glyph subsets
852 sal_Int32 nGlyphSetID
;
853 glyph_list_t::iterator aGlyphSet
;
854 for (aGlyphSet
= maGlyphList
.begin(), nGlyphSetID
= 1;
855 aGlyphSet
!= maGlyphList
.end();
856 ++aGlyphSet
, nGlyphSetID
++)
858 if ((*aGlyphSet
).size() == 0)
861 // loop thru all the glyphs in the subset
862 glyph_map_t::const_iterator aGlyph
;
864 for (aGlyph
= (*aGlyphSet
).begin(); aGlyph
!= (*aGlyphSet
).end(); aGlyph
++)
866 pTTGlyphMapping
[n
] = (*aGlyph
).first
;
867 pEncoding
[n
] = (*aGlyph
).second
;
871 // create the current subset
872 OString aGlyphSetName
= GetGlyphSetName(nGlyphSetID
);
873 fprintf( pTmpFile
, "%%%%BeginResource: font %s\n", aGlyphSetName
.getStr() );
875 CreateT42FromTTGlyphs (pTTFont
, pTmpFile
, aGlyphSetName
.getStr(),
876 pTTGlyphMapping
, pEncoding
, (*aGlyphSet
).size() );
878 CreateT3FromTTGlyphs (pTTFont
, pTmpFile
, aGlyphSetName
.getStr(),
879 pTTGlyphMapping
, pEncoding
, (*aGlyphSet
).size(),
880 0 /* 0 = horizontal, 1 = vertical */ );
881 fprintf( pTmpFile
, "%%%%EndResource\n" );
882 rSuppliedFonts
.push_back( aGlyphSetName
);
885 // copy the file into the page header
889 sal_uChar pBuffer
[0x2000];
894 nIn
= fread(pBuffer
, 1, sizeof(pBuffer
), pTmpFile
);
895 rOutFile
.write (pBuffer
, nIn
, nOut
);
897 while ((nIn
== nOut
) && !feof(pTmpFile
));
900 CloseTTFont (pTTFont
);