sync master with lastest vba changes
[ooovba.git] / psprint / source / printergfx / glyphset.cxx
blob16e4e376434d35e78e426395a25550ea2a0ceb5c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: glyphset.cxx,v $
10 * $Revision: 1.24 $
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>
38 #ifndef __SGI_STL_SET
39 #include <set>
40 #endif
41 #include <map>
42 #include <sal/alloca.h>
43 #include <rtl/ustring.hxx>
44 #include <rtl/strbuf.hxx>
46 #ifndef __SUBFONT_H
47 #define NO_LIST
48 #include <../fontsubset/sft.h>
49 #undef NO_LIST
50 #endif
52 using namespace psp;
53 using namespace rtl;
55 GlyphSet::GlyphSet ()
56 : mnFontID (-1),
57 mbVertical (0),
58 mbUseFontEncoding (false)
61 GlyphSet::GlyphSet (sal_Int32 nFontID, sal_Bool bVertical)
62 : mnFontID (nFontID),
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 ??? */
78 sal_Int32
79 GlyphSet::GetFontID ()
81 return mnFontID;
84 fonttype::type
85 GlyphSet::GetFontType ()
87 return meBaseType;
90 sal_Bool
91 GlyphSet::IsVertical ()
93 return mbVertical;
96 sal_Bool
97 GlyphSet::SetFont (sal_Int32 nFontID, sal_Bool bVertical)
99 if (mnFontID != -1)
100 return sal_False;
102 mnFontID = nFontID;
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);
112 return sal_True;
115 sal_Bool
116 GlyphSet::GetCharID (
117 sal_Unicode nChar,
118 sal_uChar* nOutGlyphID,
119 sal_Int32* nOutGlyphSetID
122 return LookupCharID (nChar, nOutGlyphID, nOutGlyphSetID)
123 || AddCharID (nChar, nOutGlyphID, nOutGlyphSetID);
126 sal_Bool
127 GlyphSet::GetGlyphID (
128 sal_uInt32 nGlyph,
129 sal_Unicode nUnicode,
130 sal_uChar* nOutGlyphID,
131 sal_Int32* nOutGlyphSetID
134 return LookupGlyphID (nGlyph, nOutGlyphID, nOutGlyphSetID)
135 || AddGlyphID (nGlyph, nUnicode, nOutGlyphID, nOutGlyphSetID);
138 sal_Bool
139 GlyphSet::LookupCharID (
140 sal_Unicode nChar,
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;
160 return sal_True;
164 *nOutGlyphSetID = -1;
165 *nOutGlyphID = 0;
166 return sal_False;
169 sal_Bool
170 GlyphSet::LookupGlyphID (
171 sal_uInt32 nGlyph,
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;
191 return sal_True;
195 *nOutGlyphSetID = -1;
196 *nOutGlyphID = 0;
197 return sal_False;
200 sal_uChar
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 );
208 sal_Char nAnsiChar;
209 sal_uInt32 nCvtInfo;
210 sal_Size nCvtChars;
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;
221 sal_uChar
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;
229 return 0;
232 void
233 GlyphSet::AddNotdef (char_map_t &rCharMap)
235 if (rCharMap.size() == 0)
236 rCharMap[0] = 0;
239 void
240 GlyphSet::AddNotdef (glyph_map_t &rGlyphMap)
242 if (rGlyphMap.size() == 0)
243 rGlyphMap[0] = 0;
245 sal_Bool
246 GlyphSet::AddCharID (
247 sal_Unicode nChar,
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);
257 else
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))
272 char_map_t aMap;
273 maCharList.push_back (aMap);
276 // insert a new glyph in the font subset
277 if (nMappedChar)
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;
284 *nOutGlyphSetID = 1;
285 *nOutGlyphID = nMappedChar;
287 else
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];
300 return sal_True;
303 sal_Bool
304 GlyphSet::AddGlyphID (
305 sal_uInt32 nGlyph,
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);
316 else
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))
331 glyph_map_t aMap;
332 maGlyphList.push_back (aMap);
335 // insert a new glyph in the font subset
336 if (nMappedChar)
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;
343 *nOutGlyphSetID = 1;
344 *nOutGlyphID = nMappedChar;
346 else
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];
359 return sal_True;
362 OString
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();
375 else
376 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
378 return maBaseName;
382 OString
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();
395 else
396 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
398 return maBaseName;
402 sal_Int32
403 GlyphSet::GetGlyphSetEncoding (sal_Int32 nGlyphSetID)
405 if (meBaseType == fonttype::TrueType)
406 return RTL_TEXTENCODING_DONTKNOW;
407 else
409 /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */
410 if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL)
411 return RTL_TEXTENCODING_SYMBOL;
412 else
413 return nGlyphSetID == 1 ? RTL_TEXTENCODING_MS_1252
414 : RTL_TEXTENCODING_USER_START + nGlyphSetID;
418 OString
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");
426 else
427 if (nEnc >= RTL_TEXTENCODING_USER_START && nEnc <= RTL_TEXTENCODING_USER_END)
429 return rFontName
430 + OString("Enc")
431 + OString::valueOf ((sal_Int32)(nEnc - RTL_TEXTENCODING_USER_START));
433 else
435 return OString();
439 OString
440 GlyphSet::GetGlyphSetEncodingName (sal_Int32 nGlyphSetID)
442 return GetGlyphSetEncodingName (GetGlyphSetEncoding(nGlyphSetID), maBaseName);
445 void
446 GlyphSet::PSDefineReencodedFont (osl::File* pOutFile, sal_Int32 nGlyphSetID)
448 // only for ps fonts
449 if ((meBaseType != fonttype::Builtin) && (meBaseType != fonttype::Type1))
450 return;
452 sal_Char pEncodingVector [256];
453 sal_Int32 nSize = 0;
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);
470 OString
471 GlyphSet::GetReencodedFontName (rtl_TextEncoding nEnc, const OString &rFontName)
473 if ( nEnc == RTL_TEXTENCODING_MS_1252
474 || nEnc == RTL_TEXTENCODING_ISO_8859_1)
476 return rFontName
477 + OString("-iso1252");
479 else
480 if (nEnc >= RTL_TEXTENCODING_USER_START && nEnc <= RTL_TEXTENCODING_USER_END)
482 return rFontName
483 + OString("-enc")
484 + OString::valueOf ((sal_Int32)(nEnc - RTL_TEXTENCODING_USER_START));
486 else
488 return OString();
492 OString
493 GlyphSet::GetReencodedFontName (sal_Int32 nGlyphSetID)
495 return GetReencodedFontName (GetGlyphSetEncoding(nGlyphSetID), maBaseName);
498 void GlyphSet::DrawGlyphs(
499 PrinterGfx& rGfx,
500 const Point& rPoint,
501 const sal_uInt32* pGlyphIds,
502 const sal_Unicode* pUnicodes,
503 sal_Int16 nLen,
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;
528 sal_Int32 nChar;
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)
548 break;
549 else
550 nChar += 1;
552 pDeltaSubset [nGlyphs] = pDeltaArray[nChar] - nOffset;
554 nGlyphs += 1;
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);
568 void
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);
575 else
576 ImplDrawText (rGfx, rPoint, pStr, nLen, pDeltaArray);
579 void
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() );
591 return;
594 int nChar;
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)
611 nGlyphs++;
612 else
613 break;
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);
621 nChar += nGlyphs;
625 void
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 );
636 return;
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;
661 sal_Int32 nChar;
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)
681 break;
682 else
683 nChar += 1;
685 pDeltaSubset [nGlyphs] = pDeltaArray[nChar] - nOffset;
687 nGlyphs += 1;
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);
701 sal_Bool
702 GlyphSet::PSUploadEncoding(osl::File* pOutFile, PrinterGfx &rGfx)
704 // only for ps fonts
705 if ((meBaseType != fonttype::Builtin) && (meBaseType != fonttype::Type1))
706 return sal_False;
707 if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL)
708 return sal_False;
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++)
717 ++nGlyphSetID;
719 if (nGlyphSetID == 1) // latin1 page uses global reencoding table
721 PSDefineReencodedFont (pOutFile, nGlyphSetID);
722 continue;
724 if ((*aGlyphSet).size() == 0) // empty set, doesn't need reencoding
726 continue;
729 // create reencoding table
731 sal_Char pEncodingVector [256];
732 sal_Int32 nSize = 0;
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();
749 ++aUnsortedGlyph)
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();
759 ++aSortedGlyph)
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);
768 else
769 nSize += psp::appendStr (".notdef", pEncodingVector + nSize );
770 nSize += psp::appendStr (" ", pEncodingVector + nSize);
771 // flush line
772 if (nSize >= 70)
774 nSize += psp::appendStr ("\n", pEncodingVector + nSize);
775 psp::WritePS (pOutFile, pEncodingVector);
776 nSize = 0;
780 nSize += psp::appendStr ("] def\n", pEncodingVector + nSize);
781 psp::WritePS (pOutFile, pEncodingVector);
783 PSDefineReencodedFont (pOutFile, nGlyphSetID);
786 return sal_True;
789 sal_Bool
790 GlyphSet::PSUploadFont (osl::File& rOutFile, PrinterGfx &rGfx, bool bAsType42, std::list< OString >& rSuppliedFonts )
792 // only for truetype fonts
793 if (meBaseType != fonttype::TrueType)
794 return sal_False;
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)
801 return sal_False;
802 FILE* pTmpFile = tmpfile();
803 if (pTmpFile == NULL)
804 return sal_False;
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)
822 continue;
824 // loop thru all the chars in the subset
825 char_map_t::const_iterator aChar;
826 sal_Int32 n = 0;
827 for (aChar = (*aCharSet).begin(); aChar != (*aCharSet).end(); aChar++)
829 pUChars [n] = (*aChar).first;
830 pEncoding [n] = (*aChar).second;
831 n++;
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() );
840 if( bAsType42 )
841 CreateT42FromTTGlyphs (pTTFont, pTmpFile, aCharSetName.getStr(),
842 pTTGlyphMapping, pEncoding, (*aCharSet).size() );
843 else
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)
859 continue;
861 // loop thru all the glyphs in the subset
862 glyph_map_t::const_iterator aGlyph;
863 sal_Int32 n = 0;
864 for (aGlyph = (*aGlyphSet).begin(); aGlyph != (*aGlyphSet).end(); aGlyph++)
866 pTTGlyphMapping [n] = (*aGlyph).first;
867 pEncoding [n] = (*aGlyph).second;
868 n++;
871 // create the current subset
872 OString aGlyphSetName = GetGlyphSetName(nGlyphSetID);
873 fprintf( pTmpFile, "%%%%BeginResource: font %s\n", aGlyphSetName.getStr() );
874 if( bAsType42 )
875 CreateT42FromTTGlyphs (pTTFont, pTmpFile, aGlyphSetName.getStr(),
876 pTTGlyphMapping, pEncoding, (*aGlyphSet).size() );
877 else
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
886 rewind(pTmpFile);
887 fflush(pTmpFile);
889 sal_uChar pBuffer[0x2000];
890 sal_uInt64 nIn;
891 sal_uInt64 nOut;
894 nIn = fread(pBuffer, 1, sizeof(pBuffer), pTmpFile);
895 rOutFile.write (pBuffer, nIn, nOut);
897 while ((nIn == nOut) && !feof(pTmpFile));
899 // cleanup
900 CloseTTFont (pTTFont);
901 fclose (pTmpFile);
903 return sal_True;