1*c82f2877SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*c82f2877SAndrew Rist * distributed with this work for additional information 6*c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*c82f2877SAndrew Rist * "License"); you may not use this file except in compliance 9*c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at 10*c82f2877SAndrew Rist * 11*c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*c82f2877SAndrew Rist * 13*c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*c82f2877SAndrew Rist * software distributed under the License is distributed on an 15*c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*c82f2877SAndrew Rist * KIND, either express or implied. See the License for the 17*c82f2877SAndrew Rist * specific language governing permissions and limitations 18*c82f2877SAndrew Rist * under the License. 19*c82f2877SAndrew Rist * 20*c82f2877SAndrew Rist *************************************************************/ 21*c82f2877SAndrew Rist 22*c82f2877SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "glyphset.hxx" 28cdf0e10cSrcweir #include "psputil.hxx" 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include "sft.hxx" 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "printergfx.hxx" 33cdf0e10cSrcweir #include "fontsubset.hxx" 34cdf0e10cSrcweir #include "vcl/fontmanager.hxx" 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "osl/thread.h" 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include "sal/alloca.h" 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include "rtl/ustring.hxx" 41cdf0e10cSrcweir #include "rtl/strbuf.hxx" 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include <set> 44cdf0e10cSrcweir #include <map> 45cdf0e10cSrcweir #include <algorithm> 46cdf0e10cSrcweir 47cdf0e10cSrcweir using namespace vcl; 48cdf0e10cSrcweir using namespace psp; 49cdf0e10cSrcweir using namespace rtl; 50cdf0e10cSrcweir 51cdf0e10cSrcweir GlyphSet::GlyphSet () 52cdf0e10cSrcweir : mnFontID (-1), 53cdf0e10cSrcweir mbVertical (0), 54cdf0e10cSrcweir mbUseFontEncoding (false) 55cdf0e10cSrcweir {} 56cdf0e10cSrcweir 57cdf0e10cSrcweir GlyphSet::GlyphSet (sal_Int32 nFontID, sal_Bool bVertical) 58cdf0e10cSrcweir : mnFontID (nFontID), 59cdf0e10cSrcweir mbVertical (bVertical) 60cdf0e10cSrcweir { 61cdf0e10cSrcweir PrintFontManager &rMgr = PrintFontManager::get(); 62cdf0e10cSrcweir meBaseType = rMgr.getFontType (mnFontID); 63cdf0e10cSrcweir maBaseName = OUStringToOString (rMgr.getPSName(mnFontID), 64cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US); 65cdf0e10cSrcweir mnBaseEncoding = rMgr.getFontEncoding(mnFontID); 66cdf0e10cSrcweir mbUseFontEncoding = rMgr.getUseOnlyFontEncoding(mnFontID); 67cdf0e10cSrcweir } 68cdf0e10cSrcweir 69cdf0e10cSrcweir GlyphSet::~GlyphSet () 70cdf0e10cSrcweir { 71cdf0e10cSrcweir /* FIXME delete the glyphlist ??? */ 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir sal_Int32 75cdf0e10cSrcweir GlyphSet::GetFontID () 76cdf0e10cSrcweir { 77cdf0e10cSrcweir return mnFontID; 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir fonttype::type 81cdf0e10cSrcweir GlyphSet::GetFontType () 82cdf0e10cSrcweir { 83cdf0e10cSrcweir return meBaseType; 84cdf0e10cSrcweir } 85cdf0e10cSrcweir 86cdf0e10cSrcweir sal_Bool 87cdf0e10cSrcweir GlyphSet::IsVertical () 88cdf0e10cSrcweir { 89cdf0e10cSrcweir return mbVertical; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir sal_Bool 93cdf0e10cSrcweir GlyphSet::SetFont (sal_Int32 nFontID, sal_Bool bVertical) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir if (mnFontID != -1) 96cdf0e10cSrcweir return sal_False; 97cdf0e10cSrcweir 98cdf0e10cSrcweir mnFontID = nFontID; 99cdf0e10cSrcweir mbVertical = bVertical; 100cdf0e10cSrcweir 101cdf0e10cSrcweir PrintFontManager &rMgr = PrintFontManager::get(); 102cdf0e10cSrcweir meBaseType = rMgr.getFontType (mnFontID); 103cdf0e10cSrcweir maBaseName = OUStringToOString (rMgr.getPSName(mnFontID), 104cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US); 105cdf0e10cSrcweir mnBaseEncoding = rMgr.getFontEncoding(mnFontID); 106cdf0e10cSrcweir mbUseFontEncoding = rMgr.getUseOnlyFontEncoding(mnFontID); 107cdf0e10cSrcweir 108cdf0e10cSrcweir return sal_True; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir sal_Bool 112cdf0e10cSrcweir GlyphSet::GetCharID ( 113cdf0e10cSrcweir sal_Unicode nChar, 114cdf0e10cSrcweir sal_uChar* nOutGlyphID, 115cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 116cdf0e10cSrcweir ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir return LookupCharID (nChar, nOutGlyphID, nOutGlyphSetID) 119cdf0e10cSrcweir || AddCharID (nChar, nOutGlyphID, nOutGlyphSetID); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir sal_Bool 123cdf0e10cSrcweir GlyphSet::GetGlyphID ( 124cdf0e10cSrcweir sal_uInt32 nGlyph, 125cdf0e10cSrcweir sal_Unicode nUnicode, 126cdf0e10cSrcweir sal_uChar* nOutGlyphID, 127cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 128cdf0e10cSrcweir ) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir return LookupGlyphID (nGlyph, nOutGlyphID, nOutGlyphSetID) 131cdf0e10cSrcweir || AddGlyphID (nGlyph, nUnicode, nOutGlyphID, nOutGlyphSetID); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir sal_Bool 135cdf0e10cSrcweir GlyphSet::LookupCharID ( 136cdf0e10cSrcweir sal_Unicode nChar, 137cdf0e10cSrcweir sal_uChar* nOutGlyphID, 138cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 139cdf0e10cSrcweir ) 140cdf0e10cSrcweir { 141cdf0e10cSrcweir char_list_t::iterator aGlyphSet; 142cdf0e10cSrcweir sal_Int32 nGlyphSetID; 143cdf0e10cSrcweir 144cdf0e10cSrcweir // loop thru all the font subsets 145cdf0e10cSrcweir for (aGlyphSet = maCharList.begin(), nGlyphSetID = 1; 146cdf0e10cSrcweir aGlyphSet != maCharList.end(); 147cdf0e10cSrcweir ++aGlyphSet, nGlyphSetID++) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir // check every subset if it contains the queried unicode char 150cdf0e10cSrcweir char_map_t::const_iterator aGlyph = (*aGlyphSet).find (nChar); 151cdf0e10cSrcweir if (aGlyph != (*aGlyphSet).end()) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir // success: found the unicode char, return the glyphid and the glyphsetid 154cdf0e10cSrcweir *nOutGlyphSetID = nGlyphSetID; 155cdf0e10cSrcweir *nOutGlyphID = (*aGlyph).second; 156cdf0e10cSrcweir return sal_True; 157cdf0e10cSrcweir } 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir *nOutGlyphSetID = -1; 161cdf0e10cSrcweir *nOutGlyphID = 0; 162cdf0e10cSrcweir return sal_False; 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir sal_Bool 166cdf0e10cSrcweir GlyphSet::LookupGlyphID ( 167cdf0e10cSrcweir sal_uInt32 nGlyph, 168cdf0e10cSrcweir sal_uChar* nOutGlyphID, 169cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 170cdf0e10cSrcweir ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir glyph_list_t::iterator aGlyphSet; 173cdf0e10cSrcweir sal_Int32 nGlyphSetID; 174cdf0e10cSrcweir 175cdf0e10cSrcweir // loop thru all the font subsets 176cdf0e10cSrcweir for (aGlyphSet = maGlyphList.begin(), nGlyphSetID = 1; 177cdf0e10cSrcweir aGlyphSet != maGlyphList.end(); 178cdf0e10cSrcweir ++aGlyphSet, nGlyphSetID++) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir // check every subset if it contains the queried unicode char 181cdf0e10cSrcweir glyph_map_t::const_iterator aGlyph = (*aGlyphSet).find (nGlyph); 182cdf0e10cSrcweir if (aGlyph != (*aGlyphSet).end()) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir // success: found the glyph id, return the mapped glyphid and the glyphsetid 185cdf0e10cSrcweir *nOutGlyphSetID = nGlyphSetID; 186cdf0e10cSrcweir *nOutGlyphID = (*aGlyph).second; 187cdf0e10cSrcweir return sal_True; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir *nOutGlyphSetID = -1; 192cdf0e10cSrcweir *nOutGlyphID = 0; 193cdf0e10cSrcweir return sal_False; 194cdf0e10cSrcweir } 195cdf0e10cSrcweir 196cdf0e10cSrcweir sal_uChar 197cdf0e10cSrcweir GlyphSet::GetAnsiMapping (sal_Unicode nUnicodeChar) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir static rtl_UnicodeToTextConverter aConverter = 200cdf0e10cSrcweir rtl_createUnicodeToTextConverter(RTL_TEXTENCODING_MS_1252); 201cdf0e10cSrcweir static rtl_UnicodeToTextContext aContext = 202cdf0e10cSrcweir rtl_createUnicodeToTextContext( aConverter ); 203cdf0e10cSrcweir 204cdf0e10cSrcweir sal_Char nAnsiChar; 205cdf0e10cSrcweir sal_uInt32 nCvtInfo; 206cdf0e10cSrcweir sal_Size nCvtChars; 207cdf0e10cSrcweir const sal_uInt32 nCvtFlags = RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR 208cdf0e10cSrcweir | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR; 209cdf0e10cSrcweir 210cdf0e10cSrcweir sal_Size nSize = rtl_convertUnicodeToText( aConverter, aContext, 211cdf0e10cSrcweir &nUnicodeChar, 1, &nAnsiChar, 1, 212cdf0e10cSrcweir nCvtFlags, &nCvtInfo, &nCvtChars ); 213cdf0e10cSrcweir 214cdf0e10cSrcweir return nSize == 1 ? (sal_uChar)nAnsiChar : (sal_uChar)0; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir sal_uChar 218cdf0e10cSrcweir GlyphSet::GetSymbolMapping (sal_Unicode nUnicodeChar) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir if (0x0000 < nUnicodeChar && nUnicodeChar < 0x0100) 221cdf0e10cSrcweir return (sal_uChar)nUnicodeChar; 222cdf0e10cSrcweir if (0xf000 < nUnicodeChar && nUnicodeChar < 0xf100) 223cdf0e10cSrcweir return (sal_uChar)nUnicodeChar; 224cdf0e10cSrcweir 225cdf0e10cSrcweir return 0; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir void 229cdf0e10cSrcweir GlyphSet::AddNotdef (char_map_t &rCharMap) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir if (rCharMap.size() == 0) 232cdf0e10cSrcweir rCharMap[0] = 0; 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir void 236cdf0e10cSrcweir GlyphSet::AddNotdef (glyph_map_t &rGlyphMap) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir if (rGlyphMap.size() == 0) 239cdf0e10cSrcweir rGlyphMap[0] = 0; 240cdf0e10cSrcweir } 241cdf0e10cSrcweir sal_Bool 242cdf0e10cSrcweir GlyphSet::AddCharID ( 243cdf0e10cSrcweir sal_Unicode nChar, 244cdf0e10cSrcweir sal_uChar* nOutGlyphID, 245cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 246cdf0e10cSrcweir ) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir sal_uChar nMappedChar; 249cdf0e10cSrcweir 250cdf0e10cSrcweir // XXX important: avoid to reencode type1 symbol fonts 251cdf0e10cSrcweir if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL) 252cdf0e10cSrcweir nMappedChar = GetSymbolMapping (nChar); 253cdf0e10cSrcweir else 254cdf0e10cSrcweir nMappedChar = GetAnsiMapping (nChar); 255cdf0e10cSrcweir 256cdf0e10cSrcweir // create an empty glyphmap that is reserved for iso1252 encoded glyphs 257cdf0e10cSrcweir // (or -- unencoded -- symbol glyphs) and a second map that takes any other 258cdf0e10cSrcweir if (maCharList.empty()) 259cdf0e10cSrcweir { 260cdf0e10cSrcweir char_map_t aMap, aMapp; 261cdf0e10cSrcweir 262cdf0e10cSrcweir maCharList.push_back (aMap); 263cdf0e10cSrcweir maCharList.push_back (aMapp); 264cdf0e10cSrcweir } 265cdf0e10cSrcweir // if the last map is full, create a new one 266cdf0e10cSrcweir if ((!nMappedChar) && (maCharList.back().size() == 255)) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir char_map_t aMap; 269cdf0e10cSrcweir maCharList.push_back (aMap); 270cdf0e10cSrcweir } 271cdf0e10cSrcweir 272cdf0e10cSrcweir // insert a new glyph in the font subset 273cdf0e10cSrcweir if (nMappedChar) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir // always put iso1252 chars into the first map, map them on itself 276cdf0e10cSrcweir char_map_t& aGlyphSet = maCharList.front(); 277cdf0e10cSrcweir AddNotdef (aGlyphSet); 278cdf0e10cSrcweir 279cdf0e10cSrcweir aGlyphSet [nChar] = nMappedChar; 280cdf0e10cSrcweir *nOutGlyphSetID = 1; 281cdf0e10cSrcweir *nOutGlyphID = nMappedChar; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir else 284cdf0e10cSrcweir { 285cdf0e10cSrcweir // other chars are just appended to the list 286cdf0e10cSrcweir char_map_t& aGlyphSet = maCharList.back(); 287cdf0e10cSrcweir AddNotdef (aGlyphSet); 288cdf0e10cSrcweir 289cdf0e10cSrcweir int nSize = aGlyphSet.size(); 290cdf0e10cSrcweir 291cdf0e10cSrcweir aGlyphSet [nChar] = nSize; 292cdf0e10cSrcweir *nOutGlyphSetID = maCharList.size(); 293cdf0e10cSrcweir *nOutGlyphID = aGlyphSet [nChar]; 294cdf0e10cSrcweir } 295cdf0e10cSrcweir 296cdf0e10cSrcweir return sal_True; 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir sal_Bool 300cdf0e10cSrcweir GlyphSet::AddGlyphID ( 301cdf0e10cSrcweir sal_uInt32 nGlyph, 302cdf0e10cSrcweir sal_Unicode nUnicode, 303cdf0e10cSrcweir sal_uChar* nOutGlyphID, 304cdf0e10cSrcweir sal_Int32* nOutGlyphSetID 305cdf0e10cSrcweir ) 306cdf0e10cSrcweir { 307cdf0e10cSrcweir sal_uChar nMappedChar; 308cdf0e10cSrcweir 309cdf0e10cSrcweir // XXX important: avoid to reencode type1 symbol fonts 310cdf0e10cSrcweir if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL) 311cdf0e10cSrcweir nMappedChar = GetSymbolMapping (nUnicode); 312cdf0e10cSrcweir else 313cdf0e10cSrcweir nMappedChar = GetAnsiMapping (nUnicode); 314cdf0e10cSrcweir 315cdf0e10cSrcweir // create an empty glyphmap that is reserved for iso1252 encoded glyphs 316cdf0e10cSrcweir // (or -- unencoded -- symbol glyphs) and a second map that takes any other 317cdf0e10cSrcweir if (maGlyphList.empty()) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir glyph_map_t aMap, aMapp; 320cdf0e10cSrcweir 321cdf0e10cSrcweir maGlyphList.push_back (aMap); 322cdf0e10cSrcweir maGlyphList.push_back (aMapp); 323cdf0e10cSrcweir } 324cdf0e10cSrcweir // if the last map is full, create a new one 325cdf0e10cSrcweir if ((!nMappedChar) && (maGlyphList.back().size() == 255)) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir glyph_map_t aMap; 328cdf0e10cSrcweir maGlyphList.push_back (aMap); 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir // insert a new glyph in the font subset 332cdf0e10cSrcweir if (nMappedChar) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir // always put iso1252 chars into the first map, map them on itself 335cdf0e10cSrcweir glyph_map_t& aGlyphSet = maGlyphList.front(); 336cdf0e10cSrcweir AddNotdef (aGlyphSet); 337cdf0e10cSrcweir 338cdf0e10cSrcweir aGlyphSet [nGlyph] = nMappedChar; 339cdf0e10cSrcweir *nOutGlyphSetID = 1; 340cdf0e10cSrcweir *nOutGlyphID = nMappedChar; 341cdf0e10cSrcweir } 342cdf0e10cSrcweir else 343cdf0e10cSrcweir { 344cdf0e10cSrcweir // other chars are just appended to the list 345cdf0e10cSrcweir glyph_map_t& aGlyphSet = maGlyphList.back(); 346cdf0e10cSrcweir AddNotdef (aGlyphSet); 347cdf0e10cSrcweir 348cdf0e10cSrcweir int nSize = aGlyphSet.size(); 349cdf0e10cSrcweir 350cdf0e10cSrcweir aGlyphSet [nGlyph] = nSize; 351cdf0e10cSrcweir *nOutGlyphSetID = maGlyphList.size(); 352cdf0e10cSrcweir *nOutGlyphID = aGlyphSet [nGlyph]; 353cdf0e10cSrcweir } 354cdf0e10cSrcweir 355cdf0e10cSrcweir return sal_True; 356cdf0e10cSrcweir } 357cdf0e10cSrcweir 358cdf0e10cSrcweir OString 359cdf0e10cSrcweir GlyphSet::GetCharSetName (sal_Int32 nGlyphSetID) 360cdf0e10cSrcweir { 361cdf0e10cSrcweir if (meBaseType == fonttype::TrueType) 362cdf0e10cSrcweir { 363cdf0e10cSrcweir OStringBuffer aSetName( maBaseName.getLength() + 32 ); 364cdf0e10cSrcweir aSetName.append( maBaseName ); 365cdf0e10cSrcweir aSetName.append( "FID" ); 366cdf0e10cSrcweir aSetName.append( mnFontID ); 367cdf0e10cSrcweir aSetName.append( mbVertical ? "VCSet" : "HCSet" ); 368cdf0e10cSrcweir aSetName.append( nGlyphSetID ); 369cdf0e10cSrcweir return aSetName.makeStringAndClear(); 370cdf0e10cSrcweir } 371cdf0e10cSrcweir else 372cdf0e10cSrcweir /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */ 373cdf0e10cSrcweir { 374cdf0e10cSrcweir return maBaseName; 375cdf0e10cSrcweir } 376cdf0e10cSrcweir } 377cdf0e10cSrcweir 378cdf0e10cSrcweir OString 379cdf0e10cSrcweir GlyphSet::GetGlyphSetName (sal_Int32 nGlyphSetID) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir if (meBaseType == fonttype::TrueType) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir OStringBuffer aSetName( maBaseName.getLength() + 32 ); 384cdf0e10cSrcweir aSetName.append( maBaseName ); 385cdf0e10cSrcweir aSetName.append( "FID" ); 386cdf0e10cSrcweir aSetName.append( mnFontID ); 387cdf0e10cSrcweir aSetName.append( mbVertical ? "VGSet" : "HGSet" ); 388cdf0e10cSrcweir aSetName.append( nGlyphSetID ); 389cdf0e10cSrcweir return aSetName.makeStringAndClear(); 390cdf0e10cSrcweir } 391cdf0e10cSrcweir else 392cdf0e10cSrcweir /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */ 393cdf0e10cSrcweir { 394cdf0e10cSrcweir return maBaseName; 395cdf0e10cSrcweir } 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir sal_Int32 399cdf0e10cSrcweir GlyphSet::GetGlyphSetEncoding (sal_Int32 nGlyphSetID) 400cdf0e10cSrcweir { 401cdf0e10cSrcweir if (meBaseType == fonttype::TrueType) 402cdf0e10cSrcweir return RTL_TEXTENCODING_DONTKNOW; 403cdf0e10cSrcweir else 404cdf0e10cSrcweir { 405cdf0e10cSrcweir /* (meBaseType == fonttype::Type1 || meBaseType == fonttype::Builtin) */ 406cdf0e10cSrcweir if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL) 407cdf0e10cSrcweir return RTL_TEXTENCODING_SYMBOL; 408cdf0e10cSrcweir else 409cdf0e10cSrcweir return nGlyphSetID == 1 ? RTL_TEXTENCODING_MS_1252 410cdf0e10cSrcweir : RTL_TEXTENCODING_USER_START + nGlyphSetID; 411cdf0e10cSrcweir } 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414cdf0e10cSrcweir OString 415cdf0e10cSrcweir GlyphSet::GetGlyphSetEncodingName (rtl_TextEncoding nEnc, const OString &rFontName) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir if ( nEnc == RTL_TEXTENCODING_MS_1252 418cdf0e10cSrcweir || nEnc == RTL_TEXTENCODING_ISO_8859_1) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir return OString("ISO1252Encoding"); 421cdf0e10cSrcweir } 422cdf0e10cSrcweir else 423cdf0e10cSrcweir if (nEnc >= RTL_TEXTENCODING_USER_START && nEnc <= RTL_TEXTENCODING_USER_END) 424cdf0e10cSrcweir { 425cdf0e10cSrcweir return rFontName 426cdf0e10cSrcweir + OString("Enc") 427cdf0e10cSrcweir + OString::valueOf ((sal_Int32)(nEnc - RTL_TEXTENCODING_USER_START)); 428cdf0e10cSrcweir } 429cdf0e10cSrcweir else 430cdf0e10cSrcweir { 431cdf0e10cSrcweir return OString(); 432cdf0e10cSrcweir } 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir OString 436cdf0e10cSrcweir GlyphSet::GetGlyphSetEncodingName (sal_Int32 nGlyphSetID) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir return GetGlyphSetEncodingName (GetGlyphSetEncoding(nGlyphSetID), maBaseName); 439cdf0e10cSrcweir } 440cdf0e10cSrcweir 441cdf0e10cSrcweir void 442cdf0e10cSrcweir GlyphSet::PSDefineReencodedFont (osl::File* pOutFile, sal_Int32 nGlyphSetID) 443cdf0e10cSrcweir { 444cdf0e10cSrcweir // only for ps fonts 445cdf0e10cSrcweir if ((meBaseType != fonttype::Builtin) && (meBaseType != fonttype::Type1)) 446cdf0e10cSrcweir return; 447cdf0e10cSrcweir 448cdf0e10cSrcweir sal_Char pEncodingVector [256]; 449cdf0e10cSrcweir sal_Int32 nSize = 0; 450cdf0e10cSrcweir 451cdf0e10cSrcweir nSize += psp::appendStr ("(", pEncodingVector + nSize); 452cdf0e10cSrcweir nSize += psp::appendStr (GetReencodedFontName(nGlyphSetID), 453cdf0e10cSrcweir pEncodingVector + nSize); 454cdf0e10cSrcweir nSize += psp::appendStr (") cvn (", pEncodingVector + nSize); 455cdf0e10cSrcweir nSize += psp::appendStr (maBaseName.getStr(), 456cdf0e10cSrcweir pEncodingVector + nSize); 457cdf0e10cSrcweir nSize += psp::appendStr (") cvn ", pEncodingVector + nSize); 458cdf0e10cSrcweir nSize += psp::appendStr (GetGlyphSetEncodingName(nGlyphSetID), 459cdf0e10cSrcweir pEncodingVector + nSize); 460cdf0e10cSrcweir nSize += psp::appendStr (" psp_definefont\n", 461cdf0e10cSrcweir pEncodingVector + nSize); 462cdf0e10cSrcweir 463cdf0e10cSrcweir psp::WritePS (pOutFile, pEncodingVector); 464cdf0e10cSrcweir } 465cdf0e10cSrcweir 466cdf0e10cSrcweir OString 467cdf0e10cSrcweir GlyphSet::GetReencodedFontName (rtl_TextEncoding nEnc, const OString &rFontName) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir if ( nEnc == RTL_TEXTENCODING_MS_1252 470cdf0e10cSrcweir || nEnc == RTL_TEXTENCODING_ISO_8859_1) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir return rFontName 473cdf0e10cSrcweir + OString("-iso1252"); 474cdf0e10cSrcweir } 475cdf0e10cSrcweir else 476cdf0e10cSrcweir if (nEnc >= RTL_TEXTENCODING_USER_START && nEnc <= RTL_TEXTENCODING_USER_END) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir return rFontName 479cdf0e10cSrcweir + OString("-enc") 480cdf0e10cSrcweir + OString::valueOf ((sal_Int32)(nEnc - RTL_TEXTENCODING_USER_START)); 481cdf0e10cSrcweir } 482cdf0e10cSrcweir else 483cdf0e10cSrcweir { 484cdf0e10cSrcweir return OString(); 485cdf0e10cSrcweir } 486cdf0e10cSrcweir } 487cdf0e10cSrcweir 488cdf0e10cSrcweir OString 489cdf0e10cSrcweir GlyphSet::GetReencodedFontName (sal_Int32 nGlyphSetID) 490cdf0e10cSrcweir { 491cdf0e10cSrcweir return GetReencodedFontName (GetGlyphSetEncoding(nGlyphSetID), maBaseName); 492cdf0e10cSrcweir } 493cdf0e10cSrcweir 494cdf0e10cSrcweir void GlyphSet::DrawGlyphs( 495cdf0e10cSrcweir PrinterGfx& rGfx, 496cdf0e10cSrcweir const Point& rPoint, 497cdf0e10cSrcweir const sal_uInt32* pGlyphIds, 498cdf0e10cSrcweir const sal_Unicode* pUnicodes, 499cdf0e10cSrcweir sal_Int16 nLen, 500cdf0e10cSrcweir const sal_Int32* pDeltaArray ) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir sal_uChar *pGlyphID = (sal_uChar*)alloca (nLen * sizeof(sal_uChar)); 503cdf0e10cSrcweir sal_Int32 *pGlyphSetID = (sal_Int32*)alloca (nLen * sizeof(sal_Int32)); 504cdf0e10cSrcweir std::set< sal_Int32 > aGlyphSet; 505cdf0e10cSrcweir 506cdf0e10cSrcweir // convert unicode to font glyph id and font subset 507cdf0e10cSrcweir for (int nChar = 0; nChar < nLen; nChar++) 508cdf0e10cSrcweir { 509cdf0e10cSrcweir GetGlyphID (pGlyphIds[nChar], pUnicodes[nChar], pGlyphID + nChar, pGlyphSetID + nChar); 510cdf0e10cSrcweir aGlyphSet.insert (pGlyphSetID[nChar]); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir 513cdf0e10cSrcweir // loop over all glyph sets to detect substrings that can be xshown together 514cdf0e10cSrcweir // without changing the postscript font 515cdf0e10cSrcweir sal_Int32 *pDeltaSubset = (sal_Int32*)alloca (nLen * sizeof(sal_Int32)); 516cdf0e10cSrcweir sal_uChar *pGlyphSubset = (sal_uChar*)alloca (nLen * sizeof(sal_uChar)); 517cdf0e10cSrcweir 518cdf0e10cSrcweir std::set< sal_Int32 >::iterator aSet; 519cdf0e10cSrcweir for (aSet = aGlyphSet.begin(); aSet != aGlyphSet.end(); ++aSet) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir Point aPoint = rPoint; 522cdf0e10cSrcweir sal_Int32 nOffset = 0; 523cdf0e10cSrcweir sal_Int32 nGlyphs = 0; 524cdf0e10cSrcweir sal_Int32 nChar; 525cdf0e10cSrcweir 526cdf0e10cSrcweir // get offset to first glyph 527cdf0e10cSrcweir for (nChar = 0; (nChar < nLen) && (pGlyphSetID[nChar] != *aSet); nChar++) 528cdf0e10cSrcweir { 529cdf0e10cSrcweir nOffset = pDeltaArray [nChar]; 530cdf0e10cSrcweir } 531cdf0e10cSrcweir 532cdf0e10cSrcweir // loop over all chars to extract those that share the current glyph set 533cdf0e10cSrcweir for (nChar = 0; nChar < nLen; nChar++) 534cdf0e10cSrcweir { 535cdf0e10cSrcweir if (pGlyphSetID[nChar] == *aSet) 536cdf0e10cSrcweir { 537cdf0e10cSrcweir pGlyphSubset [nGlyphs] = pGlyphID [nChar]; 538cdf0e10cSrcweir // the offset to the next glyph is determined by the glyph in 539cdf0e10cSrcweir // front of the next glyph with the same glyphset id 540cdf0e10cSrcweir // most often, this will be the current glyph 541cdf0e10cSrcweir while ((nChar + 1) < nLen) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir if (pGlyphSetID[nChar + 1] == *aSet) 544cdf0e10cSrcweir break; 545cdf0e10cSrcweir else 546cdf0e10cSrcweir nChar += 1; 547cdf0e10cSrcweir } 548cdf0e10cSrcweir pDeltaSubset [nGlyphs] = pDeltaArray[nChar] - nOffset; 549cdf0e10cSrcweir 550cdf0e10cSrcweir nGlyphs += 1; 551cdf0e10cSrcweir } 552cdf0e10cSrcweir } 553cdf0e10cSrcweir 554cdf0e10cSrcweir // show the text using the PrinterGfx text api 555cdf0e10cSrcweir aPoint.Move (nOffset, 0); 556cdf0e10cSrcweir 557cdf0e10cSrcweir OString aGlyphSetName(GetGlyphSetName(*aSet)); 558cdf0e10cSrcweir rGfx.PSSetFont (aGlyphSetName, GetGlyphSetEncoding(*aSet)); 559cdf0e10cSrcweir rGfx.PSMoveTo (aPoint); 560cdf0e10cSrcweir rGfx.PSShowText (pGlyphSubset, nGlyphs, nGlyphs, nGlyphs > 1 ? pDeltaSubset : NULL); 561cdf0e10cSrcweir } 562cdf0e10cSrcweir } 563cdf0e10cSrcweir 564cdf0e10cSrcweir void 565cdf0e10cSrcweir GlyphSet::DrawText (PrinterGfx &rGfx, const Point& rPoint, 566cdf0e10cSrcweir const sal_Unicode* pStr, sal_Int16 nLen, const sal_Int32* pDeltaArray) 567cdf0e10cSrcweir { 568cdf0e10cSrcweir // dispatch to the impl method 569cdf0e10cSrcweir if (pDeltaArray == NULL) 570cdf0e10cSrcweir ImplDrawText (rGfx, rPoint, pStr, nLen); 571cdf0e10cSrcweir else 572cdf0e10cSrcweir ImplDrawText (rGfx, rPoint, pStr, nLen, pDeltaArray); 573cdf0e10cSrcweir } 574cdf0e10cSrcweir 575cdf0e10cSrcweir void 576cdf0e10cSrcweir GlyphSet::ImplDrawText (PrinterGfx &rGfx, const Point& rPoint, 577cdf0e10cSrcweir const sal_Unicode* pStr, sal_Int16 nLen) 578cdf0e10cSrcweir { 579cdf0e10cSrcweir rGfx.PSMoveTo (rPoint); 580cdf0e10cSrcweir 581cdf0e10cSrcweir if( mbUseFontEncoding ) 582cdf0e10cSrcweir { 583cdf0e10cSrcweir OString aPSName( OUStringToOString( rGfx.GetFontMgr().getPSName( mnFontID ), RTL_TEXTENCODING_ISO_8859_1 ) ); 584cdf0e10cSrcweir OString aBytes( OUStringToOString( OUString( pStr, nLen ), mnBaseEncoding ) ); 585cdf0e10cSrcweir rGfx.PSSetFont( aPSName, mnBaseEncoding ); 586cdf0e10cSrcweir rGfx.PSShowText( (const unsigned char*)aBytes.getStr(), nLen, aBytes.getLength() ); 587cdf0e10cSrcweir return; 588cdf0e10cSrcweir } 589cdf0e10cSrcweir 590cdf0e10cSrcweir int nChar; 591cdf0e10cSrcweir sal_uChar *pGlyphID = (sal_uChar*)alloca (nLen * sizeof(sal_uChar)); 592cdf0e10cSrcweir sal_Int32 *pGlyphSetID = (sal_Int32*)alloca (nLen * sizeof(sal_Int32)); 593cdf0e10cSrcweir 594cdf0e10cSrcweir // convert unicode to glyph id and char set (font subset) 595cdf0e10cSrcweir for (nChar = 0; nChar < nLen; nChar++) 596cdf0e10cSrcweir GetCharID (pStr[nChar], pGlyphID + nChar, pGlyphSetID + nChar); 597cdf0e10cSrcweir 598cdf0e10cSrcweir // loop over the string to draw subsequent pieces of chars 599cdf0e10cSrcweir // with the same postscript font 600cdf0e10cSrcweir for (nChar = 0; nChar < nLen; /* atend */) 601cdf0e10cSrcweir { 602cdf0e10cSrcweir sal_Int32 nGlyphSetID = pGlyphSetID [nChar]; 603cdf0e10cSrcweir sal_Int32 nGlyphs = 1; 604cdf0e10cSrcweir for (int nNextChar = nChar + 1; nNextChar < nLen; nNextChar++) 605cdf0e10cSrcweir { 606cdf0e10cSrcweir if (pGlyphSetID[nNextChar] == nGlyphSetID) 607cdf0e10cSrcweir nGlyphs++; 608cdf0e10cSrcweir else 609cdf0e10cSrcweir break; 610cdf0e10cSrcweir } 611cdf0e10cSrcweir 612cdf0e10cSrcweir // show the text using the PrinterGfx text api 613cdf0e10cSrcweir OString aGlyphSetName(GetCharSetName(nGlyphSetID)); 614cdf0e10cSrcweir rGfx.PSSetFont (aGlyphSetName, GetGlyphSetEncoding(nGlyphSetID)); 615cdf0e10cSrcweir rGfx.PSShowText (pGlyphID + nChar, nGlyphs, nGlyphs); 616cdf0e10cSrcweir 617cdf0e10cSrcweir nChar += nGlyphs; 618cdf0e10cSrcweir } 619cdf0e10cSrcweir } 620cdf0e10cSrcweir 621cdf0e10cSrcweir void 622cdf0e10cSrcweir GlyphSet::ImplDrawText (PrinterGfx &rGfx, const Point& rPoint, 623cdf0e10cSrcweir const sal_Unicode* pStr, sal_Int16 nLen, const sal_Int32* pDeltaArray) 624cdf0e10cSrcweir { 625cdf0e10cSrcweir if( mbUseFontEncoding ) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir OString aPSName( OUStringToOString( rGfx.GetFontMgr().getPSName( mnFontID ), RTL_TEXTENCODING_ISO_8859_1 ) ); 628cdf0e10cSrcweir OString aBytes( OUStringToOString( OUString( pStr, nLen ), mnBaseEncoding ) ); 629cdf0e10cSrcweir rGfx.PSMoveTo( rPoint ); 630cdf0e10cSrcweir rGfx.PSSetFont( aPSName, mnBaseEncoding ); 631cdf0e10cSrcweir rGfx.PSShowText( (const unsigned char*)aBytes.getStr(), nLen, aBytes.getLength(), pDeltaArray ); 632cdf0e10cSrcweir return; 633cdf0e10cSrcweir } 634cdf0e10cSrcweir 635cdf0e10cSrcweir sal_uChar *pGlyphID = (sal_uChar*)alloca (nLen * sizeof(sal_uChar)); 636cdf0e10cSrcweir sal_Int32 *pGlyphSetID = (sal_Int32*)alloca (nLen * sizeof(sal_Int32)); 637cdf0e10cSrcweir std::set< sal_Int32 > aGlyphSet; 638cdf0e10cSrcweir 639cdf0e10cSrcweir // convert unicode to font glyph id and font subset 640cdf0e10cSrcweir for (int nChar = 0; nChar < nLen; nChar++) 641cdf0e10cSrcweir { 642cdf0e10cSrcweir GetCharID (pStr[nChar], pGlyphID + nChar, pGlyphSetID + nChar); 643cdf0e10cSrcweir aGlyphSet.insert (pGlyphSetID[nChar]); 644cdf0e10cSrcweir } 645cdf0e10cSrcweir 646cdf0e10cSrcweir // loop over all glyph sets to detect substrings that can be xshown together 647cdf0e10cSrcweir // without changing the postscript font 648cdf0e10cSrcweir sal_Int32 *pDeltaSubset = (sal_Int32*)alloca (nLen * sizeof(sal_Int32)); 649cdf0e10cSrcweir sal_uChar *pGlyphSubset = (sal_uChar*)alloca (nLen * sizeof(sal_uChar)); 650cdf0e10cSrcweir 651cdf0e10cSrcweir std::set< sal_Int32 >::iterator aSet; 652cdf0e10cSrcweir for (aSet = aGlyphSet.begin(); aSet != aGlyphSet.end(); ++aSet) 653cdf0e10cSrcweir { 654cdf0e10cSrcweir Point aPoint = rPoint; 655cdf0e10cSrcweir sal_Int32 nOffset = 0; 656cdf0e10cSrcweir sal_Int32 nGlyphs = 0; 657cdf0e10cSrcweir sal_Int32 nChar; 658cdf0e10cSrcweir 659cdf0e10cSrcweir // get offset to first glyph 660cdf0e10cSrcweir for (nChar = 0; (nChar < nLen) && (pGlyphSetID[nChar] != *aSet); nChar++) 661cdf0e10cSrcweir { 662cdf0e10cSrcweir nOffset = pDeltaArray [nChar]; 663cdf0e10cSrcweir } 664cdf0e10cSrcweir 665cdf0e10cSrcweir // loop over all chars to extract those that share the current glyph set 666cdf0e10cSrcweir for (nChar = 0; nChar < nLen; nChar++) 667cdf0e10cSrcweir { 668cdf0e10cSrcweir if (pGlyphSetID[nChar] == *aSet) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir pGlyphSubset [nGlyphs] = pGlyphID [nChar]; 671cdf0e10cSrcweir // the offset to the next glyph is determined by the glyph in 672cdf0e10cSrcweir // front of the next glyph with the same glyphset id 673cdf0e10cSrcweir // most often, this will be the current glyph 674cdf0e10cSrcweir while ((nChar + 1) < nLen) 675cdf0e10cSrcweir { 676cdf0e10cSrcweir if (pGlyphSetID[nChar + 1] == *aSet) 677cdf0e10cSrcweir break; 678cdf0e10cSrcweir else 679cdf0e10cSrcweir nChar += 1; 680cdf0e10cSrcweir } 681cdf0e10cSrcweir pDeltaSubset [nGlyphs] = pDeltaArray[nChar] - nOffset; 682cdf0e10cSrcweir 683cdf0e10cSrcweir nGlyphs += 1; 684cdf0e10cSrcweir } 685cdf0e10cSrcweir } 686cdf0e10cSrcweir 687cdf0e10cSrcweir // show the text using the PrinterGfx text api 688cdf0e10cSrcweir aPoint.Move (nOffset, 0); 689cdf0e10cSrcweir 690cdf0e10cSrcweir OString aGlyphSetName(GetCharSetName(*aSet)); 691cdf0e10cSrcweir rGfx.PSSetFont (aGlyphSetName, GetGlyphSetEncoding(*aSet)); 692cdf0e10cSrcweir rGfx.PSMoveTo (aPoint); 693cdf0e10cSrcweir rGfx.PSShowText (pGlyphSubset, nGlyphs, nGlyphs, nGlyphs > 1 ? pDeltaSubset : NULL); 694cdf0e10cSrcweir } 695cdf0e10cSrcweir } 696cdf0e10cSrcweir 697cdf0e10cSrcweir sal_Bool 698cdf0e10cSrcweir GlyphSet::PSUploadEncoding(osl::File* pOutFile, PrinterGfx &rGfx) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir // only for ps fonts 701cdf0e10cSrcweir if ((meBaseType != fonttype::Builtin) && (meBaseType != fonttype::Type1)) 702cdf0e10cSrcweir return sal_False; 703cdf0e10cSrcweir if (mnBaseEncoding == RTL_TEXTENCODING_SYMBOL) 704cdf0e10cSrcweir return sal_False; 705cdf0e10cSrcweir 706cdf0e10cSrcweir PrintFontManager &rMgr = rGfx.GetFontMgr(); 707cdf0e10cSrcweir 708cdf0e10cSrcweir // loop thru all the font subsets 709cdf0e10cSrcweir sal_Int32 nGlyphSetID = 0; 710cdf0e10cSrcweir char_list_t::iterator aGlyphSet; 711cdf0e10cSrcweir for (aGlyphSet = maCharList.begin(); aGlyphSet != maCharList.end(); aGlyphSet++) 712cdf0e10cSrcweir { 713cdf0e10cSrcweir ++nGlyphSetID; 714cdf0e10cSrcweir 715cdf0e10cSrcweir if (nGlyphSetID == 1) // latin1 page uses global reencoding table 716cdf0e10cSrcweir { 717cdf0e10cSrcweir PSDefineReencodedFont (pOutFile, nGlyphSetID); 718cdf0e10cSrcweir continue; 719cdf0e10cSrcweir } 720cdf0e10cSrcweir if ((*aGlyphSet).size() == 0) // empty set, doesn't need reencoding 721cdf0e10cSrcweir { 722cdf0e10cSrcweir continue; 723cdf0e10cSrcweir } 724cdf0e10cSrcweir 725cdf0e10cSrcweir // create reencoding table 726cdf0e10cSrcweir 727cdf0e10cSrcweir sal_Char pEncodingVector [256]; 728cdf0e10cSrcweir sal_Int32 nSize = 0; 729cdf0e10cSrcweir 730cdf0e10cSrcweir nSize += psp::appendStr ("/", 731cdf0e10cSrcweir pEncodingVector + nSize); 732cdf0e10cSrcweir nSize += psp::appendStr (GetGlyphSetEncodingName(nGlyphSetID), 733cdf0e10cSrcweir pEncodingVector + nSize); 734cdf0e10cSrcweir nSize += psp::appendStr (" [ ", 735cdf0e10cSrcweir pEncodingVector + nSize); 736cdf0e10cSrcweir 737cdf0e10cSrcweir // need a list of glyphs, sorted by glyphid 738cdf0e10cSrcweir typedef std::map< sal_uInt8, sal_Unicode > ps_mapping_t; 739cdf0e10cSrcweir typedef ps_mapping_t::value_type ps_value_t; 740cdf0e10cSrcweir ps_mapping_t aSortedGlyphSet; 741cdf0e10cSrcweir 742cdf0e10cSrcweir char_map_t::const_iterator aUnsortedGlyph; 743cdf0e10cSrcweir for (aUnsortedGlyph = (*aGlyphSet).begin(); 744cdf0e10cSrcweir aUnsortedGlyph != (*aGlyphSet).end(); 745cdf0e10cSrcweir ++aUnsortedGlyph) 746cdf0e10cSrcweir { 747cdf0e10cSrcweir aSortedGlyphSet.insert(ps_value_t((*aUnsortedGlyph).second, 748cdf0e10cSrcweir (*aUnsortedGlyph).first)); 749cdf0e10cSrcweir } 750cdf0e10cSrcweir 751cdf0e10cSrcweir ps_mapping_t::const_iterator aSortedGlyph; 752cdf0e10cSrcweir // loop thru all the glyphs in the subset 753cdf0e10cSrcweir for (aSortedGlyph = (aSortedGlyphSet).begin(); 754cdf0e10cSrcweir aSortedGlyph != (aSortedGlyphSet).end(); 755cdf0e10cSrcweir ++aSortedGlyph) 756cdf0e10cSrcweir { 757cdf0e10cSrcweir nSize += psp::appendStr ("/", 758cdf0e10cSrcweir pEncodingVector + nSize); 759cdf0e10cSrcweir 760cdf0e10cSrcweir std::list< OString > aName( rMgr.getAdobeNameFromUnicode((*aSortedGlyph).second) ); 761cdf0e10cSrcweir 762cdf0e10cSrcweir if( aName.begin() != aName.end() ) 763cdf0e10cSrcweir nSize += psp::appendStr ( aName.front(), pEncodingVector + nSize); 764cdf0e10cSrcweir else 765cdf0e10cSrcweir nSize += psp::appendStr (".notdef", pEncodingVector + nSize ); 766cdf0e10cSrcweir nSize += psp::appendStr (" ", pEncodingVector + nSize); 767cdf0e10cSrcweir // flush line 768cdf0e10cSrcweir if (nSize >= 70) 769cdf0e10cSrcweir { 770cdf0e10cSrcweir nSize += psp::appendStr ("\n", pEncodingVector + nSize); 771cdf0e10cSrcweir psp::WritePS (pOutFile, pEncodingVector); 772cdf0e10cSrcweir nSize = 0; 773cdf0e10cSrcweir } 774cdf0e10cSrcweir } 775cdf0e10cSrcweir 776cdf0e10cSrcweir nSize += psp::appendStr ("] def\n", pEncodingVector + nSize); 777cdf0e10cSrcweir psp::WritePS (pOutFile, pEncodingVector); 778cdf0e10cSrcweir 779cdf0e10cSrcweir PSDefineReencodedFont (pOutFile, nGlyphSetID); 780cdf0e10cSrcweir } 781cdf0e10cSrcweir 782cdf0e10cSrcweir return sal_True; 783cdf0e10cSrcweir } 784cdf0e10cSrcweir 785cdf0e10cSrcweir struct EncEntry 786cdf0e10cSrcweir { 787cdf0e10cSrcweir sal_uChar aEnc; 788cdf0e10cSrcweir long aGID; 789cdf0e10cSrcweir 790cdf0e10cSrcweir EncEntry() : aEnc( 0 ), aGID( 0 ) {} 791cdf0e10cSrcweir 792cdf0e10cSrcweir bool operator<( const EncEntry& rRight ) const 793cdf0e10cSrcweir { return aEnc < rRight.aEnc; } 794cdf0e10cSrcweir }; 795cdf0e10cSrcweir 796cdf0e10cSrcweir static void CreatePSUploadableFont( TrueTypeFont* pSrcFont, FILE* pTmpFile, 797cdf0e10cSrcweir const char* pGlyphSetName, int nGlyphCount, 798cdf0e10cSrcweir /*const*/ sal_uInt16* pRequestedGlyphs, /*const*/ sal_uChar* pEncoding, 799cdf0e10cSrcweir bool bAllowType42, bool /*bAllowCID*/ ) 800cdf0e10cSrcweir { 801cdf0e10cSrcweir // match the font-subset to the printer capabilities 802cdf0e10cSrcweir // TODO: allow CFF for capable printers 803cdf0e10cSrcweir int nTargetMask = FontSubsetInfo::TYPE1_PFA | FontSubsetInfo::TYPE3_FONT; 804cdf0e10cSrcweir if( bAllowType42 ) 805cdf0e10cSrcweir nTargetMask |= FontSubsetInfo::TYPE42_FONT; 806cdf0e10cSrcweir 807cdf0e10cSrcweir std::vector< EncEntry > aSorted( nGlyphCount, EncEntry() ); 808cdf0e10cSrcweir for( int i = 0; i < nGlyphCount; i++ ) 809cdf0e10cSrcweir { 810cdf0e10cSrcweir aSorted[i].aEnc = pEncoding[i]; 811cdf0e10cSrcweir aSorted[i].aGID = pRequestedGlyphs[i]; 812cdf0e10cSrcweir } 813cdf0e10cSrcweir 814cdf0e10cSrcweir std::stable_sort( aSorted.begin(), aSorted.end() ); 815cdf0e10cSrcweir 816cdf0e10cSrcweir std::vector< sal_uChar > aEncoding( nGlyphCount ); 817cdf0e10cSrcweir std::vector< long > aRequestedGlyphs( nGlyphCount ); 818cdf0e10cSrcweir 819cdf0e10cSrcweir for( int i = 0; i < nGlyphCount; i++ ) 820cdf0e10cSrcweir { 821cdf0e10cSrcweir aEncoding[i] = aSorted[i].aEnc; 822cdf0e10cSrcweir aRequestedGlyphs[i] = aSorted[i].aGID; 823cdf0e10cSrcweir } 824cdf0e10cSrcweir 825cdf0e10cSrcweir FontSubsetInfo aInfo; 826cdf0e10cSrcweir aInfo.LoadFont( pSrcFont ); 827cdf0e10cSrcweir 828cdf0e10cSrcweir aInfo.CreateFontSubset( nTargetMask, pTmpFile, pGlyphSetName, 829cdf0e10cSrcweir &aRequestedGlyphs[0], &aEncoding[0], nGlyphCount, NULL ); 830cdf0e10cSrcweir } 831cdf0e10cSrcweir 832cdf0e10cSrcweir sal_Bool 833cdf0e10cSrcweir GlyphSet::PSUploadFont (osl::File& rOutFile, PrinterGfx &rGfx, bool bAllowType42, std::list< OString >& rSuppliedFonts ) 834cdf0e10cSrcweir { 835cdf0e10cSrcweir // only for truetype fonts 836cdf0e10cSrcweir if (meBaseType != fonttype::TrueType) 837cdf0e10cSrcweir return sal_False; 838cdf0e10cSrcweir 839cdf0e10cSrcweir TrueTypeFont *pTTFont; 840cdf0e10cSrcweir OString aTTFileName (rGfx.GetFontMgr().getFontFileSysPath(mnFontID)); 841cdf0e10cSrcweir int nFace = rGfx.GetFontMgr().getFontFaceNumber(mnFontID); 842cdf0e10cSrcweir sal_Int32 nSuccess = OpenTTFontFile(aTTFileName.getStr(), nFace < 0 ? 0 : nFace, &pTTFont); 843cdf0e10cSrcweir if (nSuccess != SF_OK) 844cdf0e10cSrcweir return sal_False; 845cdf0e10cSrcweir FILE* pTmpFile = tmpfile(); 846cdf0e10cSrcweir if (pTmpFile == NULL) 847cdf0e10cSrcweir return sal_False; 848cdf0e10cSrcweir 849cdf0e10cSrcweir // array of unicode source characters 850cdf0e10cSrcweir sal_Unicode pUChars[256]; 851cdf0e10cSrcweir 852cdf0e10cSrcweir // encoding vector maps character encoding to the ordinal number 853cdf0e10cSrcweir // of the glyph in the output file 854cdf0e10cSrcweir sal_uChar pEncoding[256]; 855cdf0e10cSrcweir sal_uInt16 pTTGlyphMapping[256]; 856cdf0e10cSrcweir const bool bAllowCID = false; // TODO: nPSLanguageLevel>=3 857cdf0e10cSrcweir 858cdf0e10cSrcweir // loop thru all the font subsets 859cdf0e10cSrcweir sal_Int32 nCharSetID; 860cdf0e10cSrcweir char_list_t::iterator aCharSet; 861cdf0e10cSrcweir for (aCharSet = maCharList.begin(), nCharSetID = 1; 862cdf0e10cSrcweir aCharSet != maCharList.end(); 863cdf0e10cSrcweir ++aCharSet, nCharSetID++) 864cdf0e10cSrcweir { 865cdf0e10cSrcweir if ((*aCharSet).size() == 0) 866cdf0e10cSrcweir continue; 867cdf0e10cSrcweir 868cdf0e10cSrcweir // loop thru all the chars in the subset 869cdf0e10cSrcweir char_map_t::const_iterator aChar; 870cdf0e10cSrcweir sal_Int32 n = 0; 871cdf0e10cSrcweir for (aChar = (*aCharSet).begin(); aChar != (*aCharSet).end(); aChar++) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir pUChars [n] = (*aChar).first; 874cdf0e10cSrcweir pEncoding [n] = (*aChar).second; 875cdf0e10cSrcweir n++; 876cdf0e10cSrcweir } 877cdf0e10cSrcweir // create a mapping from the unicode chars to the char encoding in 878cdf0e10cSrcweir // source TrueType font 879cdf0e10cSrcweir MapString (pTTFont, pUChars, (*aCharSet).size(), pTTGlyphMapping, mbVertical); 880cdf0e10cSrcweir 881cdf0e10cSrcweir // create the current subset 882cdf0e10cSrcweir OString aCharSetName = GetCharSetName(nCharSetID); 883cdf0e10cSrcweir fprintf( pTmpFile, "%%%%BeginResource: font %s\n", aCharSetName.getStr() ); 884cdf0e10cSrcweir CreatePSUploadableFont( pTTFont, pTmpFile, aCharSetName.getStr(), (*aCharSet).size(), 885cdf0e10cSrcweir pTTGlyphMapping, pEncoding, bAllowType42, bAllowCID ); 886cdf0e10cSrcweir fprintf( pTmpFile, "%%%%EndResource\n" ); 887cdf0e10cSrcweir rSuppliedFonts.push_back( aCharSetName ); 888cdf0e10cSrcweir } 889cdf0e10cSrcweir 890cdf0e10cSrcweir // loop thru all the font glyph subsets 891cdf0e10cSrcweir sal_Int32 nGlyphSetID; 892cdf0e10cSrcweir glyph_list_t::iterator aGlyphSet; 893cdf0e10cSrcweir for (aGlyphSet = maGlyphList.begin(), nGlyphSetID = 1; 894cdf0e10cSrcweir aGlyphSet != maGlyphList.end(); 895cdf0e10cSrcweir ++aGlyphSet, nGlyphSetID++) 896cdf0e10cSrcweir { 897cdf0e10cSrcweir if ((*aGlyphSet).size() == 0) 898cdf0e10cSrcweir continue; 899cdf0e10cSrcweir 900cdf0e10cSrcweir // loop thru all the glyphs in the subset 901cdf0e10cSrcweir glyph_map_t::const_iterator aGlyph; 902cdf0e10cSrcweir sal_Int32 n = 0; 903cdf0e10cSrcweir for (aGlyph = (*aGlyphSet).begin(); aGlyph != (*aGlyphSet).end(); aGlyph++) 904cdf0e10cSrcweir { 905cdf0e10cSrcweir pTTGlyphMapping [n] = (*aGlyph).first; 906cdf0e10cSrcweir pEncoding [n] = (*aGlyph).second; 907cdf0e10cSrcweir n++; 908cdf0e10cSrcweir } 909cdf0e10cSrcweir 910cdf0e10cSrcweir // create the current subset 911cdf0e10cSrcweir OString aGlyphSetName = GetGlyphSetName(nGlyphSetID); 912cdf0e10cSrcweir fprintf( pTmpFile, "%%%%BeginResource: font %s\n", aGlyphSetName.getStr() ); 913cdf0e10cSrcweir CreatePSUploadableFont( pTTFont, pTmpFile, aGlyphSetName.getStr(), (*aGlyphSet).size(), 914cdf0e10cSrcweir pTTGlyphMapping, pEncoding, bAllowType42, bAllowCID ); 915cdf0e10cSrcweir fprintf( pTmpFile, "%%%%EndResource\n" ); 916cdf0e10cSrcweir rSuppliedFonts.push_back( aGlyphSetName ); 917cdf0e10cSrcweir } 918cdf0e10cSrcweir 919cdf0e10cSrcweir // copy the file into the page header 920cdf0e10cSrcweir rewind(pTmpFile); 921cdf0e10cSrcweir fflush(pTmpFile); 922cdf0e10cSrcweir 923cdf0e10cSrcweir sal_uChar pBuffer[0x2000]; 924cdf0e10cSrcweir sal_uInt64 nIn; 925cdf0e10cSrcweir sal_uInt64 nOut; 926cdf0e10cSrcweir do 927cdf0e10cSrcweir { 928cdf0e10cSrcweir nIn = fread(pBuffer, 1, sizeof(pBuffer), pTmpFile); 929cdf0e10cSrcweir rOutFile.write (pBuffer, nIn, nOut); 930cdf0e10cSrcweir } 931cdf0e10cSrcweir while ((nIn == nOut) && !feof(pTmpFile)); 932cdf0e10cSrcweir 933cdf0e10cSrcweir // cleanup 934cdf0e10cSrcweir CloseTTFont (pTTFont); 935cdf0e10cSrcweir fclose (pTmpFile); 936cdf0e10cSrcweir 937cdf0e10cSrcweir return sal_True; 938cdf0e10cSrcweir } 939