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 10cdf0e10cSrcweir * 11*c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 <math.h> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "psputil.hxx" 30cdf0e10cSrcweir #include "glyphset.hxx" 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "printergfx.hxx" 33cdf0e10cSrcweir #include "vcl/fontmanager.hxx" 34cdf0e10cSrcweir #include "vcl/helper.hxx" 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "osl/thread.h" 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include "sal/alloca.h" 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace psp ; 41cdf0e10cSrcweir 42cdf0e10cSrcweir namespace psp { 43cdf0e10cSrcweir /* 44cdf0e10cSrcweir container for a font and its helper fonts: 45cdf0e10cSrcweir 1st font is the font substitute e.g. helvetica substitutes arial on the printer 46cdf0e10cSrcweir 2nd is the font itself 47cdf0e10cSrcweir 3rd is a fallback font, usually a font with unicode glyph repertoir (e.g. andale) 48cdf0e10cSrcweir symbol fonts (adobe-fontspecific) may need special glyphmapping 49cdf0e10cSrcweir (symbol page vc. latin page) 50cdf0e10cSrcweir */ 51cdf0e10cSrcweir class Font3 52cdf0e10cSrcweir { 53cdf0e10cSrcweir private: 54cdf0e10cSrcweir 55cdf0e10cSrcweir #define Font3Size 3 56cdf0e10cSrcweir 57cdf0e10cSrcweir fontID mpFont [Font3Size]; 58cdf0e10cSrcweir bool mbSymbol; 59cdf0e10cSrcweir 60cdf0e10cSrcweir public: 61cdf0e10cSrcweir 62cdf0e10cSrcweir fontID GetFont (int nIdx) const 63cdf0e10cSrcweir { return nIdx < Font3Size ? mpFont[nIdx] : -1 ; } 64cdf0e10cSrcweir bool IsSymbolFont () const 65cdf0e10cSrcweir { return mbSymbol; } 66cdf0e10cSrcweir 67cdf0e10cSrcweir Font3 (const PrinterGfx &rGfx); 68cdf0e10cSrcweir ~Font3 () {} 69cdf0e10cSrcweir }; 70cdf0e10cSrcweir 71cdf0e10cSrcweir Font3::Font3(const PrinterGfx &rGfx) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir mpFont[0] = rGfx.getFontSubstitute(); 74cdf0e10cSrcweir mpFont[1] = rGfx.GetFontID(); 75cdf0e10cSrcweir mpFont[2] = rGfx.getFallbackID(); 76cdf0e10cSrcweir // mpFont[2] = rGfx.GetFontID(); 77cdf0e10cSrcweir 78cdf0e10cSrcweir PrintFontManager &rMgr = PrintFontManager::get(); 79cdf0e10cSrcweir mbSymbol = mpFont[1] != -1 ? 80cdf0e10cSrcweir rMgr.getFontEncoding(mpFont[1]) == RTL_TEXTENCODING_SYMBOL : false; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir } // namespace psp 84cdf0e10cSrcweir 85cdf0e10cSrcweir static int getVerticalDeltaAngle( sal_Unicode nChar ) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir int nAngle = 0; 88cdf0e10cSrcweir if( ( nChar >= 0x1100 && nChar < 0x11fa ) || 89cdf0e10cSrcweir ( nChar >= 0x3000 && nChar < 0xfb00 ) || 90cdf0e10cSrcweir ( nChar >= 0xfe20 && nChar < 0xfe70 ) || 91cdf0e10cSrcweir ( nChar >= 0xff00 && nChar < 0xff64 ) 92cdf0e10cSrcweir ) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir /* #i52932# remember: 95cdf0e10cSrcweir nChar == 0x2010 || nChar == 0x2015 96cdf0e10cSrcweir nChar == 0x2016 || nChar == 0x2026 97cdf0e10cSrcweir 98cdf0e10cSrcweir are nAngle = 0 also, but already handled in the first if 99cdf0e10cSrcweir */ 100cdf0e10cSrcweir if( ( nChar >= 0x3008 && nChar < 0x3019 && nChar != 0x3012 ) || 101cdf0e10cSrcweir nChar == 0xff3b || nChar == 0xff3d || 102cdf0e10cSrcweir (nChar >= 0xff6b && nChar < 0xff64 ) || 103cdf0e10cSrcweir nChar == 0xffe3 104cdf0e10cSrcweir ) 105cdf0e10cSrcweir nAngle = 0; 106cdf0e10cSrcweir else if( nChar == 0x30fc ) 107cdf0e10cSrcweir nAngle = -900; 108cdf0e10cSrcweir else 109cdf0e10cSrcweir nAngle = 900; 110cdf0e10cSrcweir } 111cdf0e10cSrcweir return nAngle; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir void 115cdf0e10cSrcweir PrinterGfx::PSUploadPS1Font (sal_Int32 nFontID) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir std::list< sal_Int32 >::iterator aFont; 118cdf0e10cSrcweir // already in the document header ? 119cdf0e10cSrcweir for (aFont = maPS1Font.begin(); aFont != maPS1Font.end(); ++aFont ) 120cdf0e10cSrcweir if( nFontID == *aFont ) 121cdf0e10cSrcweir return; 122cdf0e10cSrcweir 123cdf0e10cSrcweir // no occurrenc yet, mark for download 124cdf0e10cSrcweir // add the fontid to the list 125cdf0e10cSrcweir maPS1Font.push_back (nFontID); 126cdf0e10cSrcweir } 127cdf0e10cSrcweir 128cdf0e10cSrcweir /* 129cdf0e10cSrcweir * implement text handling printer routines, 130cdf0e10cSrcweir */ 131cdf0e10cSrcweir 132cdf0e10cSrcweir sal_uInt16 133cdf0e10cSrcweir PrinterGfx::SetFont( 134cdf0e10cSrcweir sal_Int32 nFontID, 135cdf0e10cSrcweir sal_Int32 nHeight, 136cdf0e10cSrcweir sal_Int32 nWidth, 137cdf0e10cSrcweir sal_Int32 nAngle, 138cdf0e10cSrcweir bool bVertical, 139cdf0e10cSrcweir bool bArtItalic, 140cdf0e10cSrcweir bool bArtBold 141cdf0e10cSrcweir ) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir // font and encoding will be set by drawText again immediately 144cdf0e10cSrcweir // before PSShowText 145cdf0e10cSrcweir mnFontID = nFontID; 146cdf0e10cSrcweir maVirtualStatus.maFont = rtl::OString(); 147cdf0e10cSrcweir maVirtualStatus.maEncoding = RTL_TEXTENCODING_DONTKNOW; 148cdf0e10cSrcweir maVirtualStatus.mnTextHeight = nHeight; 149cdf0e10cSrcweir maVirtualStatus.mnTextWidth = nWidth; 150cdf0e10cSrcweir maVirtualStatus.mbArtItalic = bArtItalic; 151cdf0e10cSrcweir maVirtualStatus.mbArtBold = bArtBold; 152cdf0e10cSrcweir mnTextAngle = nAngle; 153cdf0e10cSrcweir mbTextVertical = bVertical; 154cdf0e10cSrcweir 155cdf0e10cSrcweir return 0; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir 158cdf0e10cSrcweir sal_uInt16 159cdf0e10cSrcweir PrinterGfx::SetFallbackFont ( sal_Int32 nFontID ) 160cdf0e10cSrcweir { 161cdf0e10cSrcweir mnFallbackID = nFontID; 162cdf0e10cSrcweir return 0; 163cdf0e10cSrcweir } 164cdf0e10cSrcweir 165cdf0e10cSrcweir void PrinterGfx::drawGlyphs( 166cdf0e10cSrcweir const Point& rPoint, 167cdf0e10cSrcweir sal_uInt32* pGlyphIds, 168cdf0e10cSrcweir sal_Unicode* pUnicodes, 169cdf0e10cSrcweir sal_Int16 nLen, 170cdf0e10cSrcweir sal_Int32* pDeltaArray 171cdf0e10cSrcweir ) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir 174cdf0e10cSrcweir // draw the string 175cdf0e10cSrcweir // search for a glyph set matching the set font 176cdf0e10cSrcweir std::list< GlyphSet >::iterator aIter; 177cdf0e10cSrcweir for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); aIter++) 178cdf0e10cSrcweir if ( ((*aIter).GetFontID() == mnFontID) 179cdf0e10cSrcweir && ((*aIter).IsVertical() == mbTextVertical)) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir (*aIter).DrawGlyphs (*this, rPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray); 182cdf0e10cSrcweir break; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir // not found ? create a new one 186cdf0e10cSrcweir if (aIter == maPS3Font.end()) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir maPS3Font.push_back (GlyphSet(mnFontID, mbTextVertical)); 189cdf0e10cSrcweir maPS3Font.back().DrawGlyphs (*this, rPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray); 190cdf0e10cSrcweir } 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir void PrinterGfx::DrawGlyphs( 194cdf0e10cSrcweir const Point& rPoint, 195cdf0e10cSrcweir sal_GlyphId* pGlyphIds, 196cdf0e10cSrcweir sal_Unicode* pUnicodes, 197cdf0e10cSrcweir sal_Int16 nLen, 198cdf0e10cSrcweir sal_Int32* pDeltaArray 199cdf0e10cSrcweir ) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir if( nLen <= 0 ) 202cdf0e10cSrcweir return; 203cdf0e10cSrcweir 204cdf0e10cSrcweir if ( !mrFontMgr.isFontDownloadingAllowed( mnFontID ) ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir LicenseWarning(rPoint, pUnicodes, nLen, pDeltaArray); 207cdf0e10cSrcweir return; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir if( mrFontMgr.getFontType( mnFontID ) != fonttype::TrueType ) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir DrawText( rPoint, pUnicodes, nLen, pDeltaArray ); 213cdf0e10cSrcweir return; 214cdf0e10cSrcweir } 215cdf0e10cSrcweir 216cdf0e10cSrcweir // move and rotate the user coordinate system 217cdf0e10cSrcweir // avoid the gsave/grestore for the simple cases since it allows 218cdf0e10cSrcweir // reuse of the current font if it hasn't changed 219cdf0e10cSrcweir sal_Int32 nCurrentTextAngle = mnTextAngle; 220cdf0e10cSrcweir Point aPoint( rPoint ); 221cdf0e10cSrcweir 222cdf0e10cSrcweir if (nCurrentTextAngle != 0) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir PSGSave (); 225cdf0e10cSrcweir PSTranslate (rPoint); 226cdf0e10cSrcweir PSRotate (nCurrentTextAngle); 227cdf0e10cSrcweir mnTextAngle = 0; 228cdf0e10cSrcweir aPoint = Point( 0, 0 ); 229cdf0e10cSrcweir } 230cdf0e10cSrcweir 231cdf0e10cSrcweir if( mbTextVertical ) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir // vertical glyphs can have an additional rotation ... sigh. 234cdf0e10cSrcweir // so break up text in chunks of normal glyphs and print out 235cdf0e10cSrcweir // specially rotated glyphs extra 236cdf0e10cSrcweir sal_uInt32* pTempGlyphIds = (sal_uInt32*)alloca(sizeof(sal_Int32)*nLen); 237cdf0e10cSrcweir sal_Int32* pTempDelta = (sal_Int32*)alloca(sizeof(sal_Int32)*nLen); 238cdf0e10cSrcweir sal_Unicode* pTempUnicodes = (sal_Unicode*)alloca(sizeof(sal_Unicode)*nLen); 239cdf0e10cSrcweir sal_Int16 nTempLen = 0; 240cdf0e10cSrcweir sal_Int32 nTempFirstDelta = 0; 241cdf0e10cSrcweir Point aRotPoint; 242cdf0e10cSrcweir sal_Int32 nTextHeight = maVirtualStatus.mnTextHeight; 243cdf0e10cSrcweir sal_Int32 nTextWidth = maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight; 244cdf0e10cSrcweir sal_Int32 nAscend = mrFontMgr.getFontAscend( mnFontID ); 245cdf0e10cSrcweir sal_Int32 nDescend = mrFontMgr.getFontDescend( mnFontID ); 246cdf0e10cSrcweir 247cdf0e10cSrcweir nDescend = nDescend * nTextHeight / 1000; 248cdf0e10cSrcweir nAscend = nAscend * nTextHeight / 1000; 249cdf0e10cSrcweir 250cdf0e10cSrcweir for( sal_Int16 i = 0; i < nLen; i++ ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir const sal_GlyphId nRot = pGlyphIds[i] & GF_ROTMASK; 253cdf0e10cSrcweir if( nRot == GF_NONE ) 254cdf0e10cSrcweir { 255cdf0e10cSrcweir pTempUnicodes[nTempLen] = pUnicodes[i]; 256cdf0e10cSrcweir pTempGlyphIds[nTempLen] = pGlyphIds[i]; 257cdf0e10cSrcweir if( nTempLen > 0 ) 258cdf0e10cSrcweir pTempDelta[nTempLen-1] = pDeltaArray[i-1]-nTempFirstDelta; 259cdf0e10cSrcweir else 260cdf0e10cSrcweir { 261cdf0e10cSrcweir // the first element in pDeltaArray shows 262cdf0e10cSrcweir // the offset of the second character 263cdf0e10cSrcweir // so if the first glyph is normal 264cdf0e10cSrcweir // then we do not need to move the delta indices 265cdf0e10cSrcweir // else we have to move them down by one and 266cdf0e10cSrcweir // recalculate aPoint and all deltas 267cdf0e10cSrcweir if( i != 0 ) 268cdf0e10cSrcweir nTempFirstDelta = pDeltaArray[ i-1 ]; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir nTempLen++; 271cdf0e10cSrcweir } 272cdf0e10cSrcweir else 273cdf0e10cSrcweir { 274cdf0e10cSrcweir sal_Int32 nOffset = i > 0 ? pDeltaArray[i-1] : 0; 275cdf0e10cSrcweir sal_Int32 nRotAngle = 0; 276cdf0e10cSrcweir switch( nRot ) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir case GF_ROTR: 279cdf0e10cSrcweir nRotAngle = 2700; 280cdf0e10cSrcweir aRotPoint = Point( -nAscend*nTextWidth/nTextHeight, -nDescend*nTextWidth/nTextHeight - nOffset ); 281cdf0e10cSrcweir break; 282cdf0e10cSrcweir case GF_VERT: 283cdf0e10cSrcweir nRotAngle = 1800; 284cdf0e10cSrcweir aRotPoint = Point( -nOffset, (nAscend+nDescend) ); 285cdf0e10cSrcweir break; 286cdf0e10cSrcweir case GF_ROTL: 287cdf0e10cSrcweir nRotAngle = 900; 288cdf0e10cSrcweir aRotPoint = Point( -nDescend*nTextWidth/nTextHeight, nOffset + nAscend*nTextWidth/nTextHeight ); 289cdf0e10cSrcweir break; 290cdf0e10cSrcweir } 291cdf0e10cSrcweir sal_GlyphId nRotGlyphId = pGlyphIds[i]; 292cdf0e10cSrcweir sal_Unicode nRotUnicode = pUnicodes[i]; 293cdf0e10cSrcweir sal_Int32 nRotDelta = 0; 294cdf0e10cSrcweir 295cdf0e10cSrcweir // transform matrix to new individual direction 296cdf0e10cSrcweir PSGSave (); 297cdf0e10cSrcweir GraphicsStatus aSaveStatus = maVirtualStatus; 298cdf0e10cSrcweir if( nRot != 2 ) // switch font aspect 299cdf0e10cSrcweir { 300cdf0e10cSrcweir maVirtualStatus.mnTextWidth = nTextHeight; 301cdf0e10cSrcweir maVirtualStatus.mnTextHeight = nTextWidth; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir if( aPoint.X() || aPoint.Y() ) 304cdf0e10cSrcweir PSTranslate( aPoint ); 305cdf0e10cSrcweir PSRotate (nRotAngle); 306cdf0e10cSrcweir // draw the rotated glyph 307cdf0e10cSrcweir drawGlyphs( aRotPoint, &nRotGlyphId, &nRotUnicode, 1, &nRotDelta ); 308cdf0e10cSrcweir 309cdf0e10cSrcweir // restore previous state 310cdf0e10cSrcweir maVirtualStatus = aSaveStatus; 311cdf0e10cSrcweir PSGRestore(); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir } 314cdf0e10cSrcweir 315cdf0e10cSrcweir pGlyphIds = pTempGlyphIds; 316cdf0e10cSrcweir pUnicodes = pTempUnicodes; 317cdf0e10cSrcweir pDeltaArray = pTempDelta; 318cdf0e10cSrcweir nLen = nTempLen; 319cdf0e10cSrcweir 320cdf0e10cSrcweir aPoint.X() += nTempFirstDelta; 321cdf0e10cSrcweir } 322cdf0e10cSrcweir 323cdf0e10cSrcweir if( nLen > 0 ) 324cdf0e10cSrcweir drawGlyphs( aPoint, pGlyphIds, pUnicodes, nLen, pDeltaArray ); 325cdf0e10cSrcweir 326cdf0e10cSrcweir // restore the user coordinate system 327cdf0e10cSrcweir if (nCurrentTextAngle != 0) 328cdf0e10cSrcweir { 329cdf0e10cSrcweir PSGRestore (); 330cdf0e10cSrcweir mnTextAngle = nCurrentTextAngle; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir } 333cdf0e10cSrcweir 334cdf0e10cSrcweir void 335cdf0e10cSrcweir PrinterGfx::DrawText ( 336cdf0e10cSrcweir const Point& rPoint, 337cdf0e10cSrcweir const sal_Unicode* pStr, 338cdf0e10cSrcweir sal_Int16 nLen, 339cdf0e10cSrcweir const sal_Int32* pDeltaArray 340cdf0e10cSrcweir ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir fontID nRestoreFont = mnFontID; 343cdf0e10cSrcweir 344cdf0e10cSrcweir // setup font[substitutes] and map the string into the symbol area in case of 345cdf0e10cSrcweir // symbol font 346cdf0e10cSrcweir Font3 aFont(*this); 347cdf0e10cSrcweir sal_Unicode *pEffectiveStr; 348cdf0e10cSrcweir if ( aFont.IsSymbolFont() ) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir pEffectiveStr = (sal_Unicode*)alloca(nLen * sizeof(pStr[0])); 351cdf0e10cSrcweir for (int i = 0; i < nLen; i++) 352cdf0e10cSrcweir pEffectiveStr[i] = pStr[i] < 256 ? pStr[i] + 0xF000 : pStr[i]; 353cdf0e10cSrcweir } 354cdf0e10cSrcweir else 355cdf0e10cSrcweir { 356cdf0e10cSrcweir pEffectiveStr = const_cast<sal_Unicode*>(pStr); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir 359cdf0e10cSrcweir fontID *pFontMap = (fontID*) alloca(nLen * sizeof(fontID)); 360cdf0e10cSrcweir sal_Int32 *pCharWidth = (sal_Int32*) alloca(nLen * sizeof(sal_Int32)); 361cdf0e10cSrcweir 362cdf0e10cSrcweir for( int n = 0; n < nLen; n++ ) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir CharacterMetric aBBox; 365cdf0e10cSrcweir pFontMap[n] = getCharMetric (aFont, pEffectiveStr[n], &aBBox); 366cdf0e10cSrcweir pCharWidth[n] = getCharWidth (mbTextVertical, pEffectiveStr[n], &aBBox); 367cdf0e10cSrcweir } 368cdf0e10cSrcweir 369cdf0e10cSrcweir // setup a new delta array, use virtual resolution of 1000 370cdf0e10cSrcweir sal_Int32* pNewDeltaArray = (sal_Int32*)alloca( sizeof( sal_Int32 )*nLen ); 371cdf0e10cSrcweir if ( pDeltaArray != 0) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir for (int i = 0; i < nLen - 1; i++) 374cdf0e10cSrcweir pNewDeltaArray[i] = 1000 * pDeltaArray[i]; 375cdf0e10cSrcweir pNewDeltaArray[nLen - 1] = 0; 376cdf0e10cSrcweir } 377cdf0e10cSrcweir else 378cdf0e10cSrcweir { 379cdf0e10cSrcweir pNewDeltaArray[0] = pCharWidth[0]; 380cdf0e10cSrcweir for (int i = 1; i < nLen; i++) 381cdf0e10cSrcweir pNewDeltaArray[i] = pNewDeltaArray[i-1] + pCharWidth[i]; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir 384cdf0e10cSrcweir // move and rotate the user coordinate system 385cdf0e10cSrcweir // avoid the gsave/grestore for the simple cases since it allows 386cdf0e10cSrcweir // reuse of the current font if it hasn't changed 387cdf0e10cSrcweir sal_Int32 nCurrentTextAngle = mnTextAngle; 388cdf0e10cSrcweir sal_Int32 nCurrentPointX; 389cdf0e10cSrcweir sal_Int32 nCurrentPointY; 390cdf0e10cSrcweir 391cdf0e10cSrcweir if (nCurrentTextAngle != 0) 392cdf0e10cSrcweir { 393cdf0e10cSrcweir PSGSave (); 394cdf0e10cSrcweir PSTranslate (rPoint); 395cdf0e10cSrcweir PSRotate (nCurrentTextAngle); 396cdf0e10cSrcweir mnTextAngle = 0; 397cdf0e10cSrcweir 398cdf0e10cSrcweir nCurrentPointX = 0; 399cdf0e10cSrcweir nCurrentPointY = 0; 400cdf0e10cSrcweir } 401cdf0e10cSrcweir else 402cdf0e10cSrcweir { 403cdf0e10cSrcweir nCurrentPointX = rPoint.X(); 404cdf0e10cSrcweir nCurrentPointY = rPoint.Y(); 405cdf0e10cSrcweir } 406cdf0e10cSrcweir 407cdf0e10cSrcweir // draw the string 408cdf0e10cSrcweir sal_Int32 nDelta = 0; 409cdf0e10cSrcweir for (int nTo = 0; nTo < nLen; ) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir int nFrom = nTo; 412cdf0e10cSrcweir fontID nFont = pFontMap[ nFrom ]; 413cdf0e10cSrcweir 414cdf0e10cSrcweir while ((nTo < nLen) && (nFont == pFontMap[nTo])) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir pNewDeltaArray[ nTo ] = (sal_Int32)(((0.5 + pNewDeltaArray[ nTo ]) / 1000.0) - nDelta); 417cdf0e10cSrcweir nTo++ ; 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir SetFont( nFont, 421cdf0e10cSrcweir maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth, 422cdf0e10cSrcweir mnTextAngle, 423cdf0e10cSrcweir mbTextVertical, 424cdf0e10cSrcweir maVirtualStatus.mbArtItalic, 425cdf0e10cSrcweir maVirtualStatus.mbArtBold 426cdf0e10cSrcweir ); 427cdf0e10cSrcweir 428cdf0e10cSrcweir if (mbTextVertical) 429cdf0e10cSrcweir { 430cdf0e10cSrcweir drawVerticalizedText( 431cdf0e10cSrcweir Point(nCurrentPointX + nDelta, nCurrentPointY), 432cdf0e10cSrcweir pEffectiveStr + nFrom, nTo - nFrom, 433cdf0e10cSrcweir pNewDeltaArray + nFrom ); 434cdf0e10cSrcweir } 435cdf0e10cSrcweir else 436cdf0e10cSrcweir { 437cdf0e10cSrcweir drawText( 438cdf0e10cSrcweir Point(nCurrentPointX + nDelta, nCurrentPointY), 439cdf0e10cSrcweir pEffectiveStr + nFrom, nTo - nFrom, 440cdf0e10cSrcweir pDeltaArray == NULL ? NULL : pNewDeltaArray + nFrom ); 441cdf0e10cSrcweir } 442cdf0e10cSrcweir nDelta += pNewDeltaArray[ nTo - 1 ]; 443cdf0e10cSrcweir } 444cdf0e10cSrcweir 445cdf0e10cSrcweir // restore the user coordinate system 446cdf0e10cSrcweir if (nCurrentTextAngle != 0) 447cdf0e10cSrcweir { 448cdf0e10cSrcweir PSGRestore (); 449cdf0e10cSrcweir mnTextAngle = nCurrentTextAngle; 450cdf0e10cSrcweir } 451cdf0e10cSrcweir 452cdf0e10cSrcweir // restore the original font settings 453cdf0e10cSrcweir SetFont( nRestoreFont, 454cdf0e10cSrcweir maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth, 455cdf0e10cSrcweir mnTextAngle, mbTextVertical, 456cdf0e10cSrcweir maVirtualStatus.mbArtItalic, 457cdf0e10cSrcweir maVirtualStatus.mbArtBold 458cdf0e10cSrcweir ); 459cdf0e10cSrcweir } 460cdf0e10cSrcweir 461cdf0e10cSrcweir void PrinterGfx::drawVerticalizedText( 462cdf0e10cSrcweir const Point& rPoint, 463cdf0e10cSrcweir const sal_Unicode* pStr, 464cdf0e10cSrcweir sal_Int16 nLen, 465cdf0e10cSrcweir const sal_Int32* pDeltaArray 466cdf0e10cSrcweir ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir sal_Int32* pDelta = (sal_Int32*)alloca( nLen * sizeof(sal_Int32) ); 469cdf0e10cSrcweir 470cdf0e10cSrcweir int nTextScale = maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight; 471cdf0e10cSrcweir int nNormalAngle = mnTextAngle; 472cdf0e10cSrcweir int nDeltaAngle, nLastPos = 0; 473cdf0e10cSrcweir 474cdf0e10cSrcweir double fSin = sin( -2.0*M_PI*nNormalAngle/3600 ); 475cdf0e10cSrcweir double fCos = cos( -2.0*M_PI*nNormalAngle/3600 ); 476cdf0e10cSrcweir 477cdf0e10cSrcweir PrintFontManager &rMgr = PrintFontManager::get(); 478cdf0e10cSrcweir PrintFontInfo aInfo; 479cdf0e10cSrcweir rMgr.getFontInfo( mnFontID, aInfo ); 480cdf0e10cSrcweir 481cdf0e10cSrcweir bool* pGsubFlags = (bool*)alloca( nLen * sizeof(bool) ); 482cdf0e10cSrcweir rMgr.hasVerticalSubstitutions( mnFontID, pStr, nLen, pGsubFlags ); 483cdf0e10cSrcweir 484cdf0e10cSrcweir Point aPoint( rPoint ); 485cdf0e10cSrcweir for( int i = 0; i < nLen; ) 486cdf0e10cSrcweir { 487cdf0e10cSrcweir while( ( nDeltaAngle = getVerticalDeltaAngle( pStr[i] ) ) == 0 && i < nLen ) 488cdf0e10cSrcweir i++; 489cdf0e10cSrcweir if( i <= nLen && i > nLastPos ) 490cdf0e10cSrcweir { 491cdf0e10cSrcweir for( int n = nLastPos; n < i; n++ ) 492cdf0e10cSrcweir pDelta[n] = pDeltaArray[n] - (aPoint.X() - rPoint.X() ); 493cdf0e10cSrcweir 494cdf0e10cSrcweir SetFont( mnFontID, 495cdf0e10cSrcweir maVirtualStatus.mnTextHeight, maVirtualStatus.mnTextWidth, 496cdf0e10cSrcweir nNormalAngle, mbTextVertical, 497cdf0e10cSrcweir maVirtualStatus.mbArtItalic, 498cdf0e10cSrcweir maVirtualStatus.mbArtBold ); 499cdf0e10cSrcweir drawText( aPoint, pStr + nLastPos, i - nLastPos, pDelta + nLastPos ); 500cdf0e10cSrcweir 501cdf0e10cSrcweir aPoint.X() = (sal_Int32)(rPoint.X() + ((double)pDeltaArray[i-1] * fCos)); 502cdf0e10cSrcweir aPoint.Y() = (sal_Int32)(rPoint.Y() + ((double)pDeltaArray[i-1] * fSin)); 503cdf0e10cSrcweir } 504cdf0e10cSrcweir if( i < nLen ) 505cdf0e10cSrcweir { 506cdf0e10cSrcweir int nOldWidth = maVirtualStatus.mnTextWidth; 507cdf0e10cSrcweir int nOldHeight = maVirtualStatus.mnTextHeight; 508cdf0e10cSrcweir SetFont( mnFontID, 509cdf0e10cSrcweir nTextScale, 510cdf0e10cSrcweir maVirtualStatus.mnTextHeight, 511cdf0e10cSrcweir nNormalAngle + nDeltaAngle, 512cdf0e10cSrcweir mbTextVertical, 513cdf0e10cSrcweir maVirtualStatus.mbArtItalic, 514cdf0e10cSrcweir maVirtualStatus.mbArtBold ); 515cdf0e10cSrcweir 516cdf0e10cSrcweir double nA = nTextScale * aInfo.m_nAscend / 1000.0; 517cdf0e10cSrcweir double nD = nTextScale * aInfo.m_nDescend / 1000.0; 518cdf0e10cSrcweir double fStretch = (double)maVirtualStatus.mnTextWidth / maVirtualStatus.mnTextHeight; 519cdf0e10cSrcweir if( !pGsubFlags[i] ) 520cdf0e10cSrcweir nD *= fStretch; 521cdf0e10cSrcweir 522cdf0e10cSrcweir Point aPos( aPoint ); 523cdf0e10cSrcweir switch( nDeltaAngle ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir case +900: 526cdf0e10cSrcweir aPos.X() += (sal_Int32)(+nA * fCos + nD * fSin); 527cdf0e10cSrcweir aPos.Y() += (sal_Int32)(-nA * fSin + nD * fCos); 528cdf0e10cSrcweir break; 529cdf0e10cSrcweir case -900: 530cdf0e10cSrcweir aPos.X() += (sal_Int32)(+nA * fSin + nD * fCos); 531cdf0e10cSrcweir aPos.Y() += (sal_Int32)(-(nTextScale*fStretch - nD) * fCos); 532cdf0e10cSrcweir break; 533cdf0e10cSrcweir } 534cdf0e10cSrcweir drawText( aPos, pStr+i, 1, NULL ); 535cdf0e10cSrcweir if( i < nLen-1 && pDeltaArray ) 536cdf0e10cSrcweir { 537cdf0e10cSrcweir aPoint.X() = (sal_Int32)(rPoint.X() + ((double)pDeltaArray[i] * fCos)); 538cdf0e10cSrcweir aPoint.Y() = (sal_Int32)(rPoint.Y() + ((double)pDeltaArray[i] * fSin)); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir // swap text width/height again 542cdf0e10cSrcweir SetFont( mnFontID, 543cdf0e10cSrcweir nOldHeight, 544cdf0e10cSrcweir nOldWidth, 545cdf0e10cSrcweir nNormalAngle, 546cdf0e10cSrcweir mbTextVertical, 547cdf0e10cSrcweir maVirtualStatus.mbArtItalic, 548cdf0e10cSrcweir maVirtualStatus.mbArtBold ); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir i++; 551cdf0e10cSrcweir nLastPos = i; 552cdf0e10cSrcweir } 553cdf0e10cSrcweir mnTextAngle = nNormalAngle; 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir void 557cdf0e10cSrcweir PrinterGfx::LicenseWarning(const Point& rPoint, const sal_Unicode* pStr, 558cdf0e10cSrcweir sal_Int16 nLen, const sal_Int32* pDeltaArray) 559cdf0e10cSrcweir { 560cdf0e10cSrcweir // treat it like a builtin font in case a user has that font also in the 561cdf0e10cSrcweir // printer. This is not so unlikely as it may seem; no print embedding 562cdf0e10cSrcweir // licensed fonts are often used (or so they say) in companies: 563cdf0e10cSrcweir // they are installed on displays and printers, but get not embedded in 564cdf0e10cSrcweir // they are installed on displays and printers, but get not embedded in 565cdf0e10cSrcweir // print files or documents because they are not licensed for use outside 566cdf0e10cSrcweir // the company. 567cdf0e10cSrcweir rtl::OString aMessage( "The font " ); 568cdf0e10cSrcweir aMessage += rtl::OUStringToOString( mrFontMgr.getPSName(mnFontID), 569cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ); 570cdf0e10cSrcweir aMessage += " could not be downloaded\nbecause its license does not allow for that"; 571cdf0e10cSrcweir PSComment( aMessage.getStr() ); 572cdf0e10cSrcweir 573cdf0e10cSrcweir rtl::OString aFontName = rtl::OUStringToOString( 574cdf0e10cSrcweir mrFontMgr.getPSName(mnFontID), 575cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US); 576cdf0e10cSrcweir PSSetFont (aFontName, RTL_TEXTENCODING_ISO_8859_1); 577cdf0e10cSrcweir 578cdf0e10cSrcweir sal_Size nSize = 4 * nLen; 579cdf0e10cSrcweir sal_uChar* pBuffer = (sal_uChar*)alloca (nSize* sizeof(sal_uChar)); 580cdf0e10cSrcweir 581cdf0e10cSrcweir ConverterFactory* pCvt = GetConverterFactory (); 582cdf0e10cSrcweir nSize = pCvt->Convert (pStr, nLen, pBuffer, nSize, RTL_TEXTENCODING_ISO_8859_1); 583cdf0e10cSrcweir 584cdf0e10cSrcweir PSMoveTo (rPoint); 585cdf0e10cSrcweir PSShowText (pBuffer, nLen, nSize, pDeltaArray); 586cdf0e10cSrcweir } 587cdf0e10cSrcweir 588cdf0e10cSrcweir void 589cdf0e10cSrcweir PrinterGfx::drawText( 590cdf0e10cSrcweir const Point& rPoint, 591cdf0e10cSrcweir const sal_Unicode* pStr, 592cdf0e10cSrcweir sal_Int16 nLen, 593cdf0e10cSrcweir const sal_Int32* pDeltaArray 594cdf0e10cSrcweir ) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir if (!(nLen > 0)) 597cdf0e10cSrcweir return; 598cdf0e10cSrcweir 599cdf0e10cSrcweir fonttype::type eType = mrFontMgr.getFontType (mnFontID); 600cdf0e10cSrcweir 601cdf0e10cSrcweir if (eType == fonttype::Type1) 602cdf0e10cSrcweir PSUploadPS1Font (mnFontID); 603cdf0e10cSrcweir 604cdf0e10cSrcweir if ( eType == fonttype::TrueType 605cdf0e10cSrcweir && !mrFontMgr.isFontDownloadingAllowed(mnFontID)) 606cdf0e10cSrcweir { 607cdf0e10cSrcweir LicenseWarning(rPoint, pStr, nLen, pDeltaArray); 608cdf0e10cSrcweir return; 609cdf0e10cSrcweir } 610cdf0e10cSrcweir 611cdf0e10cSrcweir if( mrFontMgr.getUseOnlyFontEncoding( mnFontID ) ) 612cdf0e10cSrcweir { 613cdf0e10cSrcweir GlyphSet aGSet( mnFontID, mbTextVertical ); 614cdf0e10cSrcweir aGSet.DrawText( *this, rPoint, pStr, nLen, pDeltaArray ); 615cdf0e10cSrcweir return; 616cdf0e10cSrcweir } 617cdf0e10cSrcweir 618cdf0e10cSrcweir // search for a glyph set matching the set font 619cdf0e10cSrcweir std::list< GlyphSet >::iterator aIter; 620cdf0e10cSrcweir for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); aIter++) 621cdf0e10cSrcweir if ( ((*aIter).GetFontID() == mnFontID) 622cdf0e10cSrcweir && ((*aIter).IsVertical() == mbTextVertical)) 623cdf0e10cSrcweir { 624cdf0e10cSrcweir (*aIter).DrawText (*this, rPoint, pStr, nLen, pDeltaArray); 625cdf0e10cSrcweir break; 626cdf0e10cSrcweir } 627cdf0e10cSrcweir 628cdf0e10cSrcweir // not found ? create a new one 629cdf0e10cSrcweir if (aIter == maPS3Font.end()) 630cdf0e10cSrcweir { 631cdf0e10cSrcweir maPS3Font.push_back (GlyphSet(mnFontID, mbTextVertical)); 632cdf0e10cSrcweir maPS3Font.back().DrawText (*this, rPoint, pStr, nLen, pDeltaArray); 633cdf0e10cSrcweir } 634cdf0e10cSrcweir } 635cdf0e10cSrcweir 636cdf0e10cSrcweir int 637cdf0e10cSrcweir PrinterGfx::getCharWidth (sal_Bool b_vert, sal_Unicode n_char, CharacterMetric *p_bbox) 638cdf0e10cSrcweir { 639cdf0e10cSrcweir b_vert = b_vert && (getVerticalDeltaAngle(n_char) != 0); 640cdf0e10cSrcweir int w = b_vert ? p_bbox->height : p_bbox->width; 641cdf0e10cSrcweir w *= maVirtualStatus.mnTextWidth ? maVirtualStatus.mnTextWidth : maVirtualStatus.mnTextHeight; 642cdf0e10cSrcweir return w; 643cdf0e10cSrcweir } 644cdf0e10cSrcweir 645cdf0e10cSrcweir fontID 646cdf0e10cSrcweir PrinterGfx::getCharMetric (const Font3 &rFont, sal_Unicode n_char, CharacterMetric *p_bbox) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir p_bbox->width = -1; 649cdf0e10cSrcweir p_bbox->height = -1; 650cdf0e10cSrcweir 651cdf0e10cSrcweir for (fontID n = 0; n < 3; n++) 652cdf0e10cSrcweir { 653cdf0e10cSrcweir fontID n_font = rFont.GetFont(n); 654cdf0e10cSrcweir if (n_font != -1) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir if( mbStrictSO52Compatibility ) 657cdf0e10cSrcweir { 658cdf0e10cSrcweir fonttype::type eType = mrFontMgr.getFontType( n_font ); 659cdf0e10cSrcweir if( (eType == fonttype::Builtin || eType == fonttype::Type1) ) 660cdf0e10cSrcweir { 661cdf0e10cSrcweir // note: any character exchanged here MUST also be changed 662cdf0e10cSrcweir // in the compatibility ISO encoding vector in the prolog 663cdf0e10cSrcweir // in printerjob.cxx 664cdf0e10cSrcweir sal_Unicode aRepl = 0; 665cdf0e10cSrcweir if( n_char == 0x2d ) 666cdf0e10cSrcweir aRepl = 0x2212; 667cdf0e10cSrcweir else if( n_char == 0x27 ) 668cdf0e10cSrcweir aRepl = 0x2019; 669cdf0e10cSrcweir /* 670cdf0e10cSrcweir additional characters that may need backwards compatibility: 671cdf0e10cSrcweir ISO5589 StdEnc Unicode suggested n_char -> aRepl 672cdf0e10cSrcweir 0264 0302 0x00B4 0x00B4 (acute) -> 0x2019 (quiteright) 673cdf0e10cSrcweir 0246 - 0x00A6 0x00A6 (brokenbar) -> 0x007C (bar) 674cdf0e10cSrcweir 0225 0267 0x0095 0x0095 () -> 0x2022 (bullet) 675cdf0e10cSrcweir 0140 0301 0x0060 0x0060 (grave) -> ? 676cdf0e10cSrcweir */ 677cdf0e10cSrcweir if( aRepl ) 678cdf0e10cSrcweir { 679cdf0e10cSrcweir mrFontMgr.getMetrics( n_font, aRepl, aRepl, p_bbox ); 680cdf0e10cSrcweir if (p_bbox->width >= 0 && p_bbox->height >= 0) 681cdf0e10cSrcweir return n_font; 682cdf0e10cSrcweir } 683cdf0e10cSrcweir } 684cdf0e10cSrcweir } 685cdf0e10cSrcweir mrFontMgr.getMetrics( n_font, n_char, n_char, p_bbox ); 686cdf0e10cSrcweir } 687cdf0e10cSrcweir if (p_bbox->width >= 0 && p_bbox->height >= 0) 688cdf0e10cSrcweir return n_font; 689cdf0e10cSrcweir } 690cdf0e10cSrcweir if (n_char != '?') 691cdf0e10cSrcweir return getCharMetric (rFont, '?', p_bbox); 692cdf0e10cSrcweir 693cdf0e10cSrcweir return rFont.GetFont(0) != -1 ? rFont.GetFont(0) : rFont.GetFont(1); 694cdf0e10cSrcweir } 695cdf0e10cSrcweir 696cdf0e10cSrcweir fontID 697cdf0e10cSrcweir PrinterGfx::getFontSubstitute () const 698cdf0e10cSrcweir { 699cdf0e10cSrcweir if( mpFontSubstitutes ) 700cdf0e10cSrcweir { 701cdf0e10cSrcweir ::std::hash_map< fontID, fontID >::const_iterator it = 702cdf0e10cSrcweir mpFontSubstitutes->find( mnFontID ); 703cdf0e10cSrcweir if( it != mpFontSubstitutes->end() ) 704cdf0e10cSrcweir return it->second; 705cdf0e10cSrcweir } 706cdf0e10cSrcweir 707cdf0e10cSrcweir return -1; 708cdf0e10cSrcweir } 709cdf0e10cSrcweir 710cdf0e10cSrcweir sal_Int32 711cdf0e10cSrcweir PrinterGfx::GetCharWidth (sal_Unicode nFrom, sal_Unicode nTo, long *pWidthArray) 712cdf0e10cSrcweir { 713cdf0e10cSrcweir Font3 aFont(*this); 714cdf0e10cSrcweir if (aFont.IsSymbolFont() && (nFrom < 256) && (nTo < 256)) 715cdf0e10cSrcweir { 716cdf0e10cSrcweir nFrom += 0xF000; 717cdf0e10cSrcweir nTo += 0xF000; 718cdf0e10cSrcweir } 719cdf0e10cSrcweir 720cdf0e10cSrcweir for( int n = 0; n < (nTo - nFrom + 1); n++ ) 721cdf0e10cSrcweir { 722cdf0e10cSrcweir CharacterMetric aBBox; 723cdf0e10cSrcweir getCharMetric (aFont, n + nFrom, &aBBox); 724cdf0e10cSrcweir pWidthArray[n] = getCharWidth (mbTextVertical, n + nFrom, &aBBox); 725cdf0e10cSrcweir } 726cdf0e10cSrcweir 727cdf0e10cSrcweir // returned metrics have postscript precision 728cdf0e10cSrcweir return 1000; 729cdf0e10cSrcweir } 730cdf0e10cSrcweir 731cdf0e10cSrcweir const ::std::list< KernPair >& PrinterGfx::getKernPairs( bool bVertical ) const 732cdf0e10cSrcweir { 733cdf0e10cSrcweir /* 734cdf0e10cSrcweir * Note: this is only a 80% solution: if a font is only 735cdf0e10cSrcweir * partially substituted in a string due to missing glyphs 736cdf0e10cSrcweir * the results may not be perfect; the more so the more the 737cdf0e10cSrcweir * substitution differs from the original metricwise. But 738cdf0e10cSrcweir * vcl only asks for KernPairs for each font once and NOT 739cdf0e10cSrcweir * in a string context this is the best we can do. 740cdf0e10cSrcweir * In future the kerning should be done on a per string basis. 741cdf0e10cSrcweir */ 742cdf0e10cSrcweir fontID nFont = mnFontID; 743cdf0e10cSrcweir if( mpFontSubstitutes ) 744cdf0e10cSrcweir { 745cdf0e10cSrcweir ::std::hash_map< fontID, fontID >::const_iterator it = 746cdf0e10cSrcweir mpFontSubstitutes->find( mnFontID ); 747cdf0e10cSrcweir if( it != mpFontSubstitutes->end() ) 748cdf0e10cSrcweir nFont = it->second; 749cdf0e10cSrcweir } 750cdf0e10cSrcweir return mrFontMgr.getKernPairs( nFont, bVertical ); 751cdf0e10cSrcweir } 752cdf0e10cSrcweir 753cdf0e10cSrcweir /* 754cdf0e10cSrcweir * advanced glyph handling 755cdf0e10cSrcweir */ 756cdf0e10cSrcweir 757cdf0e10cSrcweir sal_Bool 758cdf0e10cSrcweir PrinterGfx::GetGlyphBoundRect (sal_Unicode /*c*/, Rectangle& /*rOutRect*/) 759cdf0e10cSrcweir { 760cdf0e10cSrcweir return 0; 761cdf0e10cSrcweir } 762cdf0e10cSrcweir 763cdf0e10cSrcweir sal_uInt32 764cdf0e10cSrcweir PrinterGfx::GetGlyphOutline (sal_Unicode /*c*/, 765cdf0e10cSrcweir sal_uInt16 **/*ppPolySizes*/, Point **/*ppPoints*/, sal_uInt8 **/*ppFlags*/) 766cdf0e10cSrcweir { 767cdf0e10cSrcweir return 0; 768cdf0e10cSrcweir } 769cdf0e10cSrcweir 770cdf0e10cSrcweir /* 771cdf0e10cSrcweir * spool the converted truetype fonts to the page header after the page body is 772cdf0e10cSrcweir * complete 773cdf0e10cSrcweir * for Type1 fonts spool additional reencoding vectors that are necessary to access the 774cdf0e10cSrcweir * whole font 775cdf0e10cSrcweir */ 776cdf0e10cSrcweir 777cdf0e10cSrcweir void 778cdf0e10cSrcweir PrinterGfx::OnEndPage () 779cdf0e10cSrcweir { 780cdf0e10cSrcweir } 781cdf0e10cSrcweir 782cdf0e10cSrcweir void 783cdf0e10cSrcweir PrinterGfx::OnEndJob () 784cdf0e10cSrcweir { 785cdf0e10cSrcweir maPS3Font.clear(); 786cdf0e10cSrcweir maPS1Font.clear(); 787cdf0e10cSrcweir } 788cdf0e10cSrcweir 789cdf0e10cSrcweir void 790cdf0e10cSrcweir PrinterGfx::writeResources( osl::File* pFile, std::list< rtl::OString >& rSuppliedFonts, std::list< rtl::OString >& rNeededFonts ) 791cdf0e10cSrcweir { 792cdf0e10cSrcweir // write all type 1 fonts 793cdf0e10cSrcweir std::list< sal_Int32 >::iterator aFont; 794cdf0e10cSrcweir // already in the document header ? 795cdf0e10cSrcweir for (aFont = maPS1Font.begin(); aFont != maPS1Font.end(); ++aFont) 796cdf0e10cSrcweir { 797cdf0e10cSrcweir const rtl::OString& rSysPath (mrFontMgr.getFontFileSysPath(*aFont) ); 798cdf0e10cSrcweir rtl::OUString aUNCPath; 799cdf0e10cSrcweir osl::File::getFileURLFromSystemPath (OStringToOUString (rSysPath, osl_getThreadTextEncoding()), aUNCPath); 800cdf0e10cSrcweir osl::File aFontFile (aUNCPath); 801cdf0e10cSrcweir 802cdf0e10cSrcweir // provide the pfb or pfa font as a (pfa-)font resource 803cdf0e10cSrcweir rtl::OString aPostScriptName = 804cdf0e10cSrcweir rtl::OUStringToOString ( mrFontMgr.getPSName(*aFont), 805cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ); 806cdf0e10cSrcweir 807cdf0e10cSrcweir WritePS (pFile, "%%BeginResource: font "); 808cdf0e10cSrcweir WritePS (pFile, aPostScriptName.getStr()); 809cdf0e10cSrcweir WritePS (pFile, "\n"); 810cdf0e10cSrcweir 811cdf0e10cSrcweir osl::File::RC nError = aFontFile.open (OpenFlag_Read); 812cdf0e10cSrcweir if (nError == osl::File::E_None) 813cdf0e10cSrcweir { 814cdf0e10cSrcweir convertPfbToPfa (aFontFile, *pFile); 815cdf0e10cSrcweir aFontFile.close (); 816cdf0e10cSrcweir 817cdf0e10cSrcweir pFile->setPos(osl_Pos_Current, -1); 818cdf0e10cSrcweir char lastchar = '\n'; 819cdf0e10cSrcweir sal_uInt64 uBytes(1); 820cdf0e10cSrcweir pFile->read((void *)(&lastchar), uBytes, uBytes); 821cdf0e10cSrcweir if (lastchar != '\n') 822cdf0e10cSrcweir WritePS (pFile, "\n"); 823cdf0e10cSrcweir } 824cdf0e10cSrcweir WritePS (pFile, "%%EndResource\n"); 825cdf0e10cSrcweir rSuppliedFonts.push_back( aPostScriptName ); 826cdf0e10cSrcweir } 827cdf0e10cSrcweir 828cdf0e10cSrcweir // write glyphsets and reencodings 829cdf0e10cSrcweir std::list< GlyphSet >::iterator aIter; 830cdf0e10cSrcweir for (aIter = maPS3Font.begin(); aIter != maPS3Font.end(); ++aIter) 831cdf0e10cSrcweir { 832cdf0e10cSrcweir if (aIter->GetFontType() == fonttype::TrueType) 833cdf0e10cSrcweir { 834cdf0e10cSrcweir aIter->PSUploadFont (*pFile, *this, mbUploadPS42Fonts ? true : false, rSuppliedFonts ); 835cdf0e10cSrcweir } 836cdf0e10cSrcweir else 837cdf0e10cSrcweir // ( aIter->GetFontType() == fonttype::Type1 838cdf0e10cSrcweir // || aIter->GetFontType() == fonttype::Builtin ) 839cdf0e10cSrcweir { 840cdf0e10cSrcweir aIter->PSUploadEncoding (pFile, *this); 841cdf0e10cSrcweir if( aIter->GetFontType() == fonttype::Builtin ) 842cdf0e10cSrcweir rNeededFonts.push_back( 843cdf0e10cSrcweir rtl::OUStringToOString( 844cdf0e10cSrcweir mrFontMgr.getPSName( aIter->GetFontID() ), 845cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ) ); 846cdf0e10cSrcweir } 847cdf0e10cSrcweir } 848cdf0e10cSrcweir } 849cdf0e10cSrcweir 850cdf0e10cSrcweir bool PrinterGfx::getStrictSO52Compatibility() const 851cdf0e10cSrcweir { 852cdf0e10cSrcweir return mbStrictSO52Compatibility; 853cdf0e10cSrcweir } 854cdf0e10cSrcweir 855cdf0e10cSrcweir void PrinterGfx::setStrictSO52Compatibility( bool bCompat) 856cdf0e10cSrcweir { 857cdf0e10cSrcweir mbStrictSO52Compatibility = bCompat; 858cdf0e10cSrcweir } 859