1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <sys/mman.h> 35 #include <sys/stat.h> 36 #include <sys/types.h> 37 38 #include "unx/pspgraphics.h" 39 40 #include "vcl/jobdata.hxx" 41 #include "vcl/printerinfomanager.hxx" 42 #include "vcl/bmpacc.hxx" 43 #include "vcl/svapp.hxx" 44 #include "vcl/sysdata.hxx" 45 46 #include "printergfx.hxx" 47 #include "salbmp.hxx" 48 #include "glyphcache.hxx" 49 #include "impfont.hxx" 50 #include "outfont.hxx" 51 #include "fontsubset.hxx" 52 #include "salprn.hxx" 53 #include "region.h" 54 55 #ifdef ENABLE_GRAPHITE 56 #include <graphite_layout.hxx> 57 #include <graphite_serverfont.hxx> 58 #endif 59 60 using namespace psp; 61 using namespace rtl; 62 63 // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer --------------- 64 65 class SalPrinterBmp : public psp::PrinterBmp 66 { 67 private: 68 BitmapBuffer* mpBmpBuffer; 69 70 FncGetPixel mpFncGetPixel; 71 Scanline mpScanAccess; 72 sal_PtrDiff mnScanOffset; 73 74 sal_uInt32 ColorOf (BitmapColor& rColor) const; 75 sal_uInt8 GrayOf (BitmapColor& rColor) const; 76 77 SalPrinterBmp (); 78 79 public: 80 81 SalPrinterBmp (BitmapBuffer* pBitmap); 82 virtual ~SalPrinterBmp (); 83 virtual sal_uInt32 GetPaletteColor (sal_uInt32 nIdx) const; 84 virtual sal_uInt32 GetPaletteEntryCount () const; 85 virtual sal_uInt32 GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const; 86 virtual sal_uInt8 GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const; 87 virtual sal_uInt8 GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const; 88 virtual sal_uInt32 GetWidth () const; 89 virtual sal_uInt32 GetHeight() const; 90 virtual sal_uInt32 GetDepth () const; 91 }; 92 93 SalPrinterBmp::SalPrinterBmp (BitmapBuffer* pBuffer) : 94 mpBmpBuffer (pBuffer) 95 { 96 DBG_ASSERT (mpBmpBuffer, "SalPrinterBmp::SalPrinterBmp () can't acquire Bitmap"); 97 98 // calibrate scanline buffer 99 if( BMP_SCANLINE_ADJUSTMENT( mpBmpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) 100 { 101 mpScanAccess = mpBmpBuffer->mpBits; 102 mnScanOffset = mpBmpBuffer->mnScanlineSize; 103 } 104 else 105 { 106 mpScanAccess = mpBmpBuffer->mpBits 107 + (mpBmpBuffer->mnHeight - 1) * mpBmpBuffer->mnScanlineSize; 108 mnScanOffset = - mpBmpBuffer->mnScanlineSize; 109 } 110 111 // request read access to the pixels 112 switch( BMP_SCANLINE_FORMAT( mpBmpBuffer->mnFormat ) ) 113 { 114 case BMP_FORMAT_1BIT_MSB_PAL: 115 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL; break; 116 case BMP_FORMAT_1BIT_LSB_PAL: 117 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_LSB_PAL; break; 118 case BMP_FORMAT_4BIT_MSN_PAL: 119 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_MSN_PAL; break; 120 case BMP_FORMAT_4BIT_LSN_PAL: 121 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_LSN_PAL; break; 122 case BMP_FORMAT_8BIT_PAL: 123 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_PAL; break; 124 case BMP_FORMAT_8BIT_TC_MASK: 125 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_TC_MASK; break; 126 case BMP_FORMAT_16BIT_TC_MSB_MASK: 127 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_MSB_MASK; break; 128 case BMP_FORMAT_16BIT_TC_LSB_MASK: 129 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_LSB_MASK; break; 130 case BMP_FORMAT_24BIT_TC_BGR: 131 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_BGR; break; 132 case BMP_FORMAT_24BIT_TC_RGB: 133 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_RGB; break; 134 case BMP_FORMAT_24BIT_TC_MASK: 135 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_MASK; break; 136 case BMP_FORMAT_32BIT_TC_ABGR: 137 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ABGR; break; 138 case BMP_FORMAT_32BIT_TC_ARGB: 139 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ARGB; break; 140 case BMP_FORMAT_32BIT_TC_BGRA: 141 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_BGRA; break; 142 case BMP_FORMAT_32BIT_TC_RGBA: 143 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_RGBA; break; 144 case BMP_FORMAT_32BIT_TC_MASK: 145 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_MASK; break; 146 147 default: 148 DBG_ERROR("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format"); 149 break; 150 } 151 } 152 153 SalPrinterBmp::~SalPrinterBmp () 154 { 155 } 156 157 sal_uInt32 158 SalPrinterBmp::GetWidth () const 159 { 160 return mpBmpBuffer->mnWidth; 161 } 162 163 sal_uInt32 164 SalPrinterBmp::GetHeight () const 165 { 166 return mpBmpBuffer->mnHeight; 167 } 168 169 sal_uInt32 170 SalPrinterBmp::GetDepth () const 171 { 172 sal_uInt32 nDepth; 173 174 switch (mpBmpBuffer->mnBitCount) 175 { 176 case 1: 177 nDepth = 1; 178 break; 179 180 case 4: 181 case 8: 182 nDepth = 8; 183 break; 184 185 case 16: 186 case 24: 187 case 32: 188 nDepth = 24; 189 break; 190 191 default: 192 nDepth = 1; 193 DBG_ERROR ("Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()"); 194 break; 195 } 196 197 return nDepth; 198 } 199 200 sal_uInt32 201 SalPrinterBmp::ColorOf (BitmapColor& rColor) const 202 { 203 if (rColor.IsIndex()) 204 return ColorOf (mpBmpBuffer->maPalette[rColor.GetIndex()]); 205 else 206 return ((rColor.GetBlue()) & 0x000000ff) 207 | ((rColor.GetGreen() << 8) & 0x0000ff00) 208 | ((rColor.GetRed() << 16) & 0x00ff0000); 209 } 210 211 sal_uInt8 212 SalPrinterBmp::GrayOf (BitmapColor& rColor) const 213 { 214 if (rColor.IsIndex()) 215 return GrayOf (mpBmpBuffer->maPalette[rColor.GetIndex()]); 216 else 217 return ( rColor.GetBlue() * 28UL 218 + rColor.GetGreen() * 151UL 219 + rColor.GetRed() * 77UL ) >> 8; 220 } 221 222 sal_uInt32 223 SalPrinterBmp::GetPaletteEntryCount () const 224 { 225 return mpBmpBuffer->maPalette.GetEntryCount (); 226 } 227 228 sal_uInt32 229 SalPrinterBmp::GetPaletteColor (sal_uInt32 nIdx) const 230 { 231 return ColorOf (mpBmpBuffer->maPalette[nIdx]); 232 } 233 234 sal_uInt32 235 SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const 236 { 237 Scanline pScan = mpScanAccess + nRow * mnScanOffset; 238 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); 239 240 return ColorOf (aColor); 241 } 242 243 sal_uInt8 244 SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const 245 { 246 Scanline pScan = mpScanAccess + nRow * mnScanOffset; 247 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); 248 249 return GrayOf (aColor); 250 } 251 252 sal_uInt8 253 SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const 254 { 255 Scanline pScan = mpScanAccess + nRow * mnScanOffset; 256 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); 257 258 if (aColor.IsIndex()) 259 return aColor.GetIndex(); 260 else 261 return 0; 262 } 263 264 /******************************************************* 265 * PspGraphics * 266 *******************************************************/ 267 268 PspGraphics::~PspGraphics() 269 { 270 ReleaseFonts(); 271 } 272 273 void PspGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) 274 { 275 if (m_pJobData != NULL) 276 { 277 int x = m_pJobData->m_aContext.getRenderResolution(); 278 279 rDPIX = x; 280 rDPIY = x; 281 } 282 } 283 284 sal_uInt16 PspGraphics::GetBitCount() 285 { 286 return m_pPrinterGfx->GetBitCount(); 287 } 288 289 long PspGraphics::GetGraphicsWidth() const 290 { 291 return 0; 292 } 293 294 void PspGraphics::ResetClipRegion() 295 { 296 m_pPrinterGfx->ResetClipRegion(); 297 } 298 299 bool PspGraphics::setClipRegion( const Region& i_rClip ) 300 { 301 // TODO: support polygonal clipregions here 302 m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() ); 303 304 ImplRegionInfo aInfo; 305 long nX, nY, nW, nH; 306 bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH ); 307 while( bRegionRect ) 308 { 309 if ( nW && nH ) 310 { 311 m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH ); 312 } 313 bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH ); 314 } 315 m_pPrinterGfx->EndSetClipRegion(); 316 return true; 317 } 318 319 void PspGraphics::SetLineColor() 320 { 321 m_pPrinterGfx->SetLineColor (); 322 } 323 324 void PspGraphics::SetLineColor( SalColor nSalColor ) 325 { 326 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor), 327 SALCOLOR_GREEN (nSalColor), 328 SALCOLOR_BLUE (nSalColor)); 329 m_pPrinterGfx->SetLineColor (aColor); 330 } 331 332 void PspGraphics::SetFillColor() 333 { 334 m_pPrinterGfx->SetFillColor (); 335 } 336 337 void PspGraphics::SetFillColor( SalColor nSalColor ) 338 { 339 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor), 340 SALCOLOR_GREEN (nSalColor), 341 SALCOLOR_BLUE (nSalColor)); 342 m_pPrinterGfx->SetFillColor (aColor); 343 } 344 345 void PspGraphics::SetROPLineColor( SalROPColor ) 346 { 347 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPLineColor() not implemented" ); 348 } 349 350 void PspGraphics::SetROPFillColor( SalROPColor ) 351 { 352 DBG_ASSERT( 0, "Error: PrinterGfx::SetROPFillColor() not implemented" ); 353 } 354 355 void PspGraphics::SetXORMode( bool bSet, bool ) 356 { 357 (void)bSet; 358 DBG_ASSERT( !bSet, "Error: PrinterGfx::SetXORMode() not implemented" ); 359 } 360 361 void PspGraphics::drawPixel( long nX, long nY ) 362 { 363 m_pPrinterGfx->DrawPixel (Point(nX, nY)); 364 } 365 366 void PspGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) 367 { 368 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor), 369 SALCOLOR_GREEN (nSalColor), 370 SALCOLOR_BLUE (nSalColor)); 371 m_pPrinterGfx->DrawPixel (Point(nX, nY), aColor); 372 } 373 374 void PspGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) 375 { 376 m_pPrinterGfx->DrawLine (Point(nX1, nY1), Point(nX2, nY2)); 377 } 378 379 void PspGraphics::drawRect( long nX, long nY, long nDX, long nDY ) 380 { 381 m_pPrinterGfx->DrawRect (Rectangle(Point(nX, nY), Size(nDX, nDY))); 382 } 383 384 void PspGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry ) 385 { 386 m_pPrinterGfx->DrawPolyLine (nPoints, (Point*)pPtAry); 387 } 388 389 void PspGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry ) 390 { 391 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx 392 m_pPrinterGfx->DrawPolygon (nPoints, (Point*)pPtAry); 393 } 394 395 void PspGraphics::drawPolyPolygon( sal_uInt32 nPoly, 396 const sal_uInt32 *pPoints, 397 PCONSTSALPOINT *pPtAry ) 398 { 399 m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, (const Point**)pPtAry); 400 } 401 402 bool PspGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ ) 403 { 404 // TODO: implement and advertise OutDevSupport_B2DDraw support 405 return false; 406 } 407 408 bool PspGraphics::drawPolyLine( const basegfx::B2DPolygon&, double /*fTranspareny*/, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/) 409 { 410 // TODO: a PS printer can draw B2DPolyLines almost directly 411 return false; 412 } 413 414 sal_Bool PspGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) 415 { 416 m_pPrinterGfx->DrawPolyLineBezier (nPoints, (Point*)pPtAry, pFlgAry); 417 return sal_True; 418 } 419 420 sal_Bool PspGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) 421 { 422 m_pPrinterGfx->DrawPolygonBezier (nPoints, (Point*)pPtAry, pFlgAry); 423 return sal_True; 424 } 425 426 sal_Bool PspGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, 427 const sal_uInt32* pPoints, 428 const SalPoint* const* pPtAry, 429 const sal_uInt8* const* pFlgAry ) 430 { 431 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx 432 m_pPrinterGfx->DrawPolyPolygonBezier (nPoly, pPoints, (Point**)pPtAry, (sal_uInt8**)pFlgAry); 433 return sal_True; 434 } 435 436 void PspGraphics::invert( sal_uLong, 437 const SalPoint*, 438 SalInvert ) 439 { 440 DBG_ASSERT( 0, "Error: PrinterGfx::Invert() not implemented" ); 441 } 442 sal_Bool PspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize ) 443 { 444 return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize ); 445 } 446 447 void PspGraphics::copyBits( const SalTwoRect*, 448 SalGraphics* ) 449 { 450 DBG_ERROR( "Error: PrinterGfx::CopyBits() not implemented" ); 451 } 452 453 void PspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 ) 454 { 455 DBG_ERROR( "Error: PrinterGfx::CopyArea() not implemented" ); 456 } 457 458 void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) 459 { 460 Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY), 461 Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight)); 462 Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY), 463 Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight)); 464 465 BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True); 466 467 SalPrinterBmp aBmp (pBuffer); 468 m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp); 469 470 const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True); 471 } 472 473 void PspGraphics::drawBitmap( const SalTwoRect*, 474 const SalBitmap&, 475 const SalBitmap& ) 476 { 477 DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent bitmap"); 478 } 479 480 void PspGraphics::drawBitmap( const SalTwoRect*, 481 const SalBitmap&, 482 SalColor ) 483 { 484 DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent color"); 485 } 486 487 void PspGraphics::drawMask( const SalTwoRect*, 488 const SalBitmap &, 489 SalColor ) 490 { 491 DBG_ERROR("Error: PrinterGfx::DrawMask() not implemented"); 492 } 493 494 SalBitmap* PspGraphics::getBitmap( long, long, long, long ) 495 { 496 DBG_WARNING ("Warning: PrinterGfx::GetBitmap() not implemented"); 497 return NULL; 498 } 499 500 SalColor PspGraphics::getPixel( long, long ) 501 { 502 DBG_ERROR ("Warning: PrinterGfx::GetPixel() not implemented"); 503 return 0; 504 } 505 506 void PspGraphics::invert(long,long,long,long,SalInvert) 507 { 508 DBG_ERROR ("Warning: PrinterGfx::Invert() not implemented"); 509 } 510 511 //========================================================================== 512 513 class ImplPspFontData : public ImplFontData 514 { 515 private: 516 enum { PSPFD_MAGIC = 0xb5bf01f0 }; 517 sal_IntPtr mnFontId; 518 519 public: 520 ImplPspFontData( const psp::FastPrintFontInfo& ); 521 virtual sal_IntPtr GetFontId() const { return mnFontId; } 522 virtual ImplFontData* Clone() const { return new ImplPspFontData( *this ); } 523 virtual ImplFontEntry* CreateFontInstance( ImplFontSelectData& ) const; 524 static bool CheckFontData( const ImplFontData& r ) { return r.CheckMagic( PSPFD_MAGIC ); } 525 }; 526 527 //-------------------------------------------------------------------------- 528 529 ImplPspFontData::ImplPspFontData( const psp::FastPrintFontInfo& rInfo ) 530 : ImplFontData( PspGraphics::Info2DevFontAttributes(rInfo), PSPFD_MAGIC ), 531 mnFontId( rInfo.m_nID ) 532 {} 533 534 //-------------------------------------------------------------------------- 535 536 ImplFontEntry* ImplPspFontData::CreateFontInstance( ImplFontSelectData& rFSD ) const 537 { 538 ImplServerFontEntry* pEntry = new ImplServerFontEntry( rFSD ); 539 return pEntry; 540 } 541 542 //========================================================================== 543 544 class PspFontLayout : public GenericSalLayout 545 { 546 public: 547 PspFontLayout( ::psp::PrinterGfx& ); 548 virtual bool LayoutText( ImplLayoutArgs& ); 549 virtual void InitFont() const; 550 virtual void DrawText( SalGraphics& ) const; 551 private: 552 ::psp::PrinterGfx& mrPrinterGfx; 553 sal_IntPtr mnFontID; 554 int mnFontHeight; 555 int mnFontWidth; 556 bool mbVertical; 557 bool mbArtItalic; 558 bool mbArtBold; 559 }; 560 561 //-------------------------------------------------------------------------- 562 563 PspFontLayout::PspFontLayout( ::psp::PrinterGfx& rGfx ) 564 : mrPrinterGfx( rGfx ) 565 { 566 mnFontID = mrPrinterGfx.GetFontID(); 567 mnFontHeight = mrPrinterGfx.GetFontHeight(); 568 mnFontWidth = mrPrinterGfx.GetFontWidth(); 569 mbVertical = mrPrinterGfx.GetFontVertical(); 570 mbArtItalic = mrPrinterGfx.GetArtificialItalic(); 571 mbArtBold = mrPrinterGfx.GetArtificialBold(); 572 } 573 574 //-------------------------------------------------------------------------- 575 576 bool PspFontLayout::LayoutText( ImplLayoutArgs& rArgs ) 577 { 578 mbVertical = ((rArgs.mnFlags & SAL_LAYOUT_VERTICAL) != 0); 579 580 long nUnitsPerPixel = 1; 581 int nOldGlyphId = -1; 582 long nGlyphWidth = 0; 583 int nCharPos = -1; 584 Point aNewPos( 0, 0 ); 585 GlyphItem aPrevItem; 586 rtl_TextEncoding aFontEnc = mrPrinterGfx.GetFontMgr().getFontEncoding( mnFontID ); 587 for(;;) 588 { 589 bool bRightToLeft; 590 if( !rArgs.GetNextPos( &nCharPos, &bRightToLeft ) ) 591 break; 592 593 sal_Unicode cChar = rArgs.mpStr[ nCharPos ]; 594 if( bRightToLeft ) 595 cChar = GetMirroredChar( cChar ); 596 // symbol font aliasing: 0x0020-0x00ff -> 0xf020 -> 0xf0ff 597 if( aFontEnc == RTL_TEXTENCODING_SYMBOL ) 598 if( cChar < 256 ) 599 cChar += 0xf000; 600 int nGlyphIndex = cChar; // printer glyphs = unicode 601 602 // update fallback_runs if needed 603 psp::CharacterMetric aMetric; 604 mrPrinterGfx.GetFontMgr().getMetrics( mnFontID, cChar, cChar, &aMetric, mbVertical ); 605 if( aMetric.width == -1 && aMetric.height == -1 ) 606 rArgs.NeedFallback( nCharPos, bRightToLeft ); 607 608 // apply pair kerning to prev glyph if requested 609 if( SAL_LAYOUT_KERNING_PAIRS & rArgs.mnFlags ) 610 { 611 if( nOldGlyphId > 0 ) 612 { 613 const std::list< KernPair >& rKernPairs = mrPrinterGfx.getKernPairs(mbVertical); 614 for( std::list< KernPair >::const_iterator it = rKernPairs.begin(); 615 it != rKernPairs.end(); ++it ) 616 { 617 if( it->first == nOldGlyphId && it->second == nGlyphIndex ) 618 { 619 int nTextScale = mrPrinterGfx.GetFontWidth(); 620 if( ! nTextScale ) 621 nTextScale = mrPrinterGfx.GetFontHeight(); 622 int nKern = (mbVertical ? it->kern_y : it->kern_x) * nTextScale; 623 nGlyphWidth += nKern; 624 aPrevItem.mnNewWidth = nGlyphWidth; 625 break; 626 } 627 } 628 } 629 } 630 631 // finish previous glyph 632 if( nOldGlyphId >= 0 ) 633 AppendGlyph( aPrevItem ); 634 nOldGlyphId = nGlyphIndex; 635 aNewPos.X() += nGlyphWidth; 636 637 // prepare GlyphItem for appending it in next round 638 nUnitsPerPixel = mrPrinterGfx.GetCharWidth( cChar, cChar, &nGlyphWidth ); 639 int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0; 640 nGlyphIndex |= GF_ISCHAR; 641 aPrevItem = GlyphItem( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth ); 642 } 643 644 // append last glyph item if any 645 if( nOldGlyphId >= 0 ) 646 AppendGlyph( aPrevItem ); 647 648 SetOrientation( mrPrinterGfx.GetFontAngle() ); 649 SetUnitsPerPixel( nUnitsPerPixel ); 650 return (nOldGlyphId >= 0); 651 } 652 653 class PspServerFontLayout : public ServerFontLayout 654 { 655 public: 656 PspServerFontLayout( psp::PrinterGfx&, ServerFont& rFont, const ImplLayoutArgs& rArgs ); 657 658 virtual void InitFont() const; 659 const sal_Unicode* getTextPtr() const { return maText.getStr() - mnMinCharPos; } 660 int getMinCharPos() const { return mnMinCharPos; } 661 int getMaxCharPos() const { return mnMinCharPos+maText.getLength()-1; } 662 private: 663 ::psp::PrinterGfx& mrPrinterGfx; 664 sal_IntPtr mnFontID; 665 int mnFontHeight; 666 int mnFontWidth; 667 bool mbVertical; 668 bool mbArtItalic; 669 bool mbArtBold; 670 rtl::OUString maText; 671 int mnMinCharPos; 672 }; 673 674 PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx& rGfx, ServerFont& rFont, const ImplLayoutArgs& rArgs ) 675 : ServerFontLayout( rFont ), 676 mrPrinterGfx( rGfx ) 677 { 678 mnFontID = mrPrinterGfx.GetFontID(); 679 mnFontHeight = mrPrinterGfx.GetFontHeight(); 680 mnFontWidth = mrPrinterGfx.GetFontWidth(); 681 mbVertical = mrPrinterGfx.GetFontVertical(); 682 mbArtItalic = mrPrinterGfx.GetArtificialItalic(); 683 mbArtBold = mrPrinterGfx.GetArtificialBold(); 684 maText = OUString( rArgs.mpStr + rArgs.mnMinCharPos, rArgs.mnEndCharPos - rArgs.mnMinCharPos+1 ); 685 mnMinCharPos = rArgs.mnMinCharPos; 686 } 687 688 void PspServerFontLayout::InitFont() const 689 { 690 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth, 691 mnOrientation, mbVertical, mbArtItalic, mbArtBold ); 692 } 693 694 //-------------------------------------------------------------------------- 695 696 static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout ) 697 { 698 const int nMaxGlyphs = 200; 699 sal_uInt32 aGlyphAry[ nMaxGlyphs ]; // TODO: use sal_GlyphId 700 sal_Int32 aWidthAry[ nMaxGlyphs ]; 701 sal_Int32 aIdxAry [ nMaxGlyphs ]; 702 sal_Unicode aUnicodes[ nMaxGlyphs ]; 703 int aCharPosAry [ nMaxGlyphs ]; 704 705 Point aPos; 706 long nUnitsPerPixel = rLayout.GetUnitsPerPixel(); 707 const sal_Unicode* pText = NULL; 708 int nMinCharPos = 0; 709 int nMaxCharPos = 0; 710 if (bIsPspServerFontLayout) 711 { 712 const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout); 713 #ifdef ENABLE_GRAPHITE 714 const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout); 715 #endif 716 if (pPspLayout) 717 { 718 pText = pPspLayout->getTextPtr(); 719 nMinCharPos = pPspLayout->getMinCharPos(); 720 nMaxCharPos = pPspLayout->getMaxCharPos(); 721 } 722 #ifdef ENABLE_GRAPHITE 723 else if (pGrLayout) 724 { 725 #if 0 // HACK: disabled for now due to #i114460#, see #desc12 there 726 // TODO: get rid of glyph->string mapping altogether for printing 727 // TODO: fix GraphiteServerFontLayout's returned aCharPosAry 728 // TODO: fix PrinterGfx's caching? 729 pText = pGrLayout->getTextPtr(); 730 nMinCharPos = pGrLayout->getMinCharPos(); 731 nMaxCharPos = pGrLayout->getMaxCharPos(); 732 #endif 733 } 734 #endif 735 } 736 for( int nStart = 0;; ) 737 { 738 int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : NULL ); 739 if( !nGlyphCount ) 740 break; 741 742 sal_Int32 nXOffset = 0; 743 for( int i = 0; i < nGlyphCount; ++i ) 744 { 745 nXOffset += aWidthAry[ i ]; 746 aIdxAry[ i ] = nXOffset / nUnitsPerPixel; 747 sal_Int32 nGlyphIdx = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK); 748 if( pText ) 749 aUnicodes[i] = (aCharPosAry[i] >= nMinCharPos && aCharPosAry[i] <= nMaxCharPos) ? pText[ aCharPosAry[i] ] : 0; 750 else 751 aUnicodes[i] = (aGlyphAry[i] & GF_ISCHAR) ? nGlyphIdx : 0; 752 aGlyphAry[i] = nGlyphIdx; 753 } 754 755 rGfx.DrawGlyphs( aPos, (sal_uInt32 *)aGlyphAry, aUnicodes, nGlyphCount, aIdxAry ); 756 } 757 } 758 759 //-------------------------------------------------------------------------- 760 761 void PspFontLayout::InitFont() const 762 { 763 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth, 764 mnOrientation, mbVertical, mbArtItalic, mbArtBold ); 765 } 766 767 //-------------------------------------------------------------------------- 768 769 void PspFontLayout::DrawText( SalGraphics& ) const 770 { 771 DrawPrinterLayout( *this, mrPrinterGfx, false ); 772 } 773 774 void PspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) 775 { 776 // print complex text 777 DrawPrinterLayout( rLayout, *m_pPrinterGfx, true ); 778 } 779 780 const ImplFontCharMap* PspGraphics::GetImplFontCharMap() const 781 { 782 if( !m_pServerFont[0] ) 783 return NULL; 784 785 const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap(); 786 return pIFCMap; 787 } 788 789 sal_uInt16 PspGraphics::SetFont( ImplFontSelectData *pEntry, int nFallbackLevel ) 790 { 791 // release all fonts that are to be overridden 792 for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) 793 { 794 if( m_pServerFont[i] != NULL ) 795 { 796 // old server side font is no longer referenced 797 GlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] ); 798 m_pServerFont[i] = NULL; 799 } 800 } 801 802 // return early if there is no new font 803 if( !pEntry ) 804 return 0; 805 806 sal_IntPtr nID = pEntry->mpFontData ? pEntry->mpFontData->GetFontId() : 0; 807 808 // determine which font attributes need to be emulated 809 bool bArtItalic = false; 810 bool bArtBold = false; 811 if( pEntry->meItalic == ITALIC_OBLIQUE || pEntry->meItalic == ITALIC_NORMAL ) 812 { 813 psp::italic::type eItalic = m_pPrinterGfx->GetFontMgr().getFontItalic( nID ); 814 if( eItalic != psp::italic::Italic && eItalic != psp::italic::Oblique ) 815 bArtItalic = true; 816 } 817 int nWeight = (int)pEntry->meWeight; 818 int nRealWeight = (int)m_pPrinterGfx->GetFontMgr().getFontWeight( nID ); 819 if( nRealWeight <= (int)psp::weight::Medium && nWeight > (int)WEIGHT_MEDIUM ) 820 { 821 bArtBold = true; 822 } 823 824 // also set the serverside font for layouting 825 m_bFontVertical = pEntry->mbVertical; 826 if( pEntry->mpFontData ) 827 { 828 // requesting a font provided by builtin rasterizer 829 ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry ); 830 if( pServerFont != NULL ) 831 { 832 if( pServerFont->TestFont() ) 833 m_pServerFont[ nFallbackLevel ] = pServerFont; 834 else 835 GlyphCache::GetInstance().UncacheFont( *pServerFont ); 836 } 837 } 838 839 // set the printer font 840 return m_pPrinterGfx->SetFont( nID, 841 pEntry->mnHeight, 842 pEntry->mnWidth, 843 pEntry->mnOrientation, 844 pEntry->mbVertical, 845 bArtItalic, 846 bArtBold 847 ); 848 } 849 850 void PspGraphics::SetTextColor( SalColor nSalColor ) 851 { 852 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor), 853 SALCOLOR_GREEN (nSalColor), 854 SALCOLOR_BLUE (nSalColor)); 855 m_pPrinterGfx->SetTextColor (aColor); 856 } 857 858 bool PspGraphics::AddTempDevFont( ImplDevFontList*, const String&,const String& ) 859 { 860 return false; 861 } 862 863 void RegisterFontSubstitutors( ImplDevFontList* ); 864 865 void PspGraphics::GetDevFontList( ImplDevFontList *pList ) 866 { 867 ::std::list< psp::fontID > aList; 868 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 869 rMgr.getFontList( aList, m_pJobData->m_pParser, m_pInfoPrinter->m_bCompatMetrics ); 870 871 ::std::list< psp::fontID >::iterator it; 872 psp::FastPrintFontInfo aInfo; 873 for (it = aList.begin(); it != aList.end(); ++it) 874 if (rMgr.getFontFastInfo (*it, aInfo)) 875 AnnounceFonts( pList, aInfo ); 876 877 // register platform specific font substitutions if available 878 if( rMgr.hasFontconfig() ) 879 RegisterFontSubstitutors( pList ); 880 } 881 882 void PspGraphics::GetDevFontSubstList( OutputDevice* pOutDev ) 883 { 884 const psp::PrinterInfo& rInfo = psp::PrinterInfoManager::get().getPrinterInfo( m_pJobData->m_aPrinterName ); 885 if( rInfo.m_bPerformFontSubstitution ) 886 { 887 for( std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator it = rInfo.m_aFontSubstitutes.begin(); it != rInfo.m_aFontSubstitutes.end(); ++it ) 888 pOutDev->ImplAddDevFontSubstitute( it->first, it->second, FONT_SUBSTITUTE_ALWAYS ); 889 } 890 } 891 892 void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int ) 893 { 894 const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 895 psp::PrintFontInfo aInfo; 896 897 if (rMgr.getFontInfo (m_pPrinterGfx->GetFontID(), aInfo)) 898 { 899 ImplDevFontAttributes aDFA = Info2DevFontAttributes( aInfo ); 900 static_cast<ImplFontAttributes&>(*pMetric) = aDFA; 901 pMetric->mbDevice = aDFA.mbDevice; 902 pMetric->mbScalableFont = true; 903 904 pMetric->mnOrientation = m_pPrinterGfx->GetFontAngle(); 905 pMetric->mnSlant = 0; 906 907 sal_Int32 nTextHeight = m_pPrinterGfx->GetFontHeight(); 908 sal_Int32 nTextWidth = m_pPrinterGfx->GetFontWidth(); 909 if( ! nTextWidth ) 910 nTextWidth = nTextHeight; 911 912 pMetric->mnWidth = nTextWidth; 913 pMetric->mnAscent = ( aInfo.m_nAscend * nTextHeight + 500 ) / 1000; 914 pMetric->mnDescent = ( aInfo.m_nDescend * nTextHeight + 500 ) / 1000; 915 pMetric->mnIntLeading = ( aInfo.m_nLeading * nTextHeight + 500 ) / 1000; 916 pMetric->mnExtLeading = 0; 917 } 918 } 919 920 sal_uLong PspGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData *pKernPairs ) 921 { 922 const ::std::list< ::psp::KernPair >& rPairs( m_pPrinterGfx->getKernPairs() ); 923 sal_uLong nHavePairs = rPairs.size(); 924 if( pKernPairs && nPairs ) 925 { 926 ::std::list< ::psp::KernPair >::const_iterator it; 927 unsigned int i; 928 int nTextScale = m_pPrinterGfx->GetFontWidth(); 929 if( ! nTextScale ) 930 nTextScale = m_pPrinterGfx->GetFontHeight(); 931 for( i = 0, it = rPairs.begin(); i < nPairs && i < nHavePairs; i++, ++it ) 932 { 933 pKernPairs[i].mnChar1 = it->first; 934 pKernPairs[i].mnChar2 = it->second; 935 pKernPairs[i].mnKern = it->kern_x * nTextScale / 1000; 936 } 937 938 } 939 return nHavePairs; 940 } 941 942 sal_Bool PspGraphics::GetGlyphBoundRect( long nGlyphIndex, Rectangle& rRect ) 943 { 944 int nLevel = nGlyphIndex >> GF_FONTSHIFT; 945 if( nLevel >= MAX_FALLBACK ) 946 return sal_False; 947 948 ServerFont* pSF = m_pServerFont[ nLevel ]; 949 if( !pSF ) 950 return sal_False; 951 952 nGlyphIndex &= ~GF_FONTMASK; 953 const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex ); 954 rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() ); 955 return sal_True; 956 } 957 958 sal_Bool PspGraphics::GetGlyphOutline( long nGlyphIndex, 959 ::basegfx::B2DPolyPolygon& rB2DPolyPoly ) 960 { 961 int nLevel = nGlyphIndex >> GF_FONTSHIFT; 962 if( nLevel >= MAX_FALLBACK ) 963 return sal_False; 964 965 ServerFont* pSF = m_pServerFont[ nLevel ]; 966 if( !pSF ) 967 return sal_False; 968 969 nGlyphIndex &= ~GF_FONTMASK; 970 if( pSF->GetGlyphOutline( nGlyphIndex, rB2DPolyPoly ) ) 971 return sal_True; 972 973 return sal_False; 974 } 975 976 SalLayout* PspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) 977 { 978 // workaround for printers not handling glyph indexing for non-TT fonts 979 int nFontId = m_pPrinterGfx->GetFontID(); 980 if( psp::fonttype::TrueType != psp::PrintFontManager::get().getFontType( nFontId ) ) 981 rArgs.mnFlags |= SAL_LAYOUT_DISABLE_GLYPH_PROCESSING; 982 else if( nFallbackLevel > 0 ) 983 rArgs.mnFlags &= ~SAL_LAYOUT_DISABLE_GLYPH_PROCESSING; 984 985 GenericSalLayout* pLayout = NULL; 986 987 if( m_pServerFont[ nFallbackLevel ] 988 && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) ) 989 { 990 #ifdef ENABLE_GRAPHITE 991 // Is this a Graphite font? 992 if (GraphiteFontAdaptor::IsGraphiteEnabledFont(*m_pServerFont[nFallbackLevel])) 993 { 994 sal_Int32 xdpi, ydpi; 995 GetResolution(xdpi, ydpi); 996 GraphiteFontAdaptor * pGrfont = new GraphiteFontAdaptor( *m_pServerFont[nFallbackLevel], xdpi, ydpi); 997 if (!pGrfont) return NULL; 998 pLayout = new GraphiteServerFontLayout(pGrfont); 999 } 1000 else 1001 #endif 1002 pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs ); 1003 } 1004 else 1005 pLayout = new PspFontLayout( *m_pPrinterGfx ); 1006 1007 return pLayout; 1008 } 1009 1010 //-------------------------------------------------------------------------- 1011 1012 sal_Bool PspGraphics::CreateFontSubset( 1013 const rtl::OUString& rToFile, 1014 const ImplFontData* pFont, 1015 sal_Int32* pGlyphIDs, 1016 sal_uInt8* pEncoding, 1017 sal_Int32* pWidths, 1018 int nGlyphCount, 1019 FontSubsetInfo& rInfo 1020 ) 1021 { 1022 // in this context the pFont->GetFontId() is a valid PSP 1023 // font since they are the only ones left after the PDF 1024 // export has filtered its list of subsettable fonts (for 1025 // which this method was created). The correct way would 1026 // be to have the GlyphCache search for the ImplFontData pFont 1027 psp::fontID aFont = pFont->GetFontId(); 1028 1029 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1030 bool bSuccess = rMgr.createFontSubset( rInfo, 1031 aFont, 1032 rToFile, 1033 pGlyphIDs, 1034 pEncoding, 1035 pWidths, 1036 nGlyphCount ); 1037 return bSuccess; 1038 } 1039 1040 //-------------------------------------------------------------------------- 1041 1042 const void* PspGraphics::GetEmbedFontData( const ImplFontData* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ) 1043 { 1044 // in this context the pFont->GetFontId() is a valid PSP 1045 // font since they are the only ones left after the PDF 1046 // export has filtered its list of subsettable fonts (for 1047 // which this method was created). The correct way would 1048 // be to have the GlyphCache search for the ImplFontData pFont 1049 psp::fontID aFont = pFont->GetFontId(); 1050 return PspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen ); 1051 } 1052 1053 //-------------------------------------------------------------------------- 1054 1055 void PspGraphics::FreeEmbedFontData( const void* pData, long nLen ) 1056 { 1057 PspGraphics::DoFreeEmbedFontData( pData, nLen ); 1058 } 1059 1060 //-------------------------------------------------------------------------- 1061 1062 const Ucs2SIntMap* PspGraphics::GetFontEncodingVector( const ImplFontData* pFont, const Ucs2OStrMap** pNonEncoded ) 1063 { 1064 // in this context the pFont->GetFontId() is a valid PSP 1065 // font since they are the only ones left after the PDF 1066 // export has filtered its list of subsettable fonts (for 1067 // which this method was created). The correct way would 1068 // be to have the GlyphCache search for the ImplFontData pFont 1069 psp::fontID aFont = pFont->GetFontId(); 1070 return PspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded ); 1071 } 1072 1073 //-------------------------------------------------------------------------- 1074 1075 void PspGraphics::GetGlyphWidths( const ImplFontData* pFont, 1076 bool bVertical, 1077 Int32Vector& rWidths, 1078 Ucs2UIntMap& rUnicodeEnc ) 1079 { 1080 // in this context the pFont->GetFontId() is a valid PSP 1081 // font since they are the only ones left after the PDF 1082 // export has filtered its list of subsettable fonts (for 1083 // which this method was created). The correct way would 1084 // be to have the GlyphCache search for the ImplFontData pFont 1085 psp::fontID aFont = pFont->GetFontId(); 1086 PspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); 1087 } 1088 1089 1090 // static helpers of PspGraphics 1091 1092 const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ) 1093 { 1094 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1095 1096 psp::PrintFontInfo aFontInfo; 1097 if( ! rMgr.getFontInfo( aFont, aFontInfo ) ) 1098 return NULL; 1099 1100 // fill in font info 1101 rInfo.m_nAscent = aFontInfo.m_nAscend; 1102 rInfo.m_nDescent = aFontInfo.m_nDescend; 1103 rInfo.m_aPSName = rMgr.getPSName( aFont ); 1104 1105 int xMin, yMin, xMax, yMax; 1106 rMgr.getFontBoundingBox( aFont, xMin, yMin, xMax, yMax ); 1107 1108 psp::CharacterMetric aMetrics[256]; 1109 sal_Ucs aUnicodes[256]; 1110 if( aFontInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL && aFontInfo.m_eType == psp::fonttype::Type1 ) 1111 { 1112 for( int i = 0; i < 256; i++ ) 1113 aUnicodes[i] = pUnicodes[i] < 0x0100 ? pUnicodes[i] + 0xf000 : pUnicodes[i]; 1114 pUnicodes = aUnicodes; 1115 } 1116 if( ! rMgr.getMetrics( aFont, pUnicodes, 256, aMetrics ) ) 1117 return NULL; 1118 1119 OString aSysPath = rMgr.getFontFileSysPath( aFont ); 1120 struct stat aStat; 1121 if( stat( aSysPath.getStr(), &aStat ) ) 1122 return NULL; 1123 int fd = open( aSysPath.getStr(), O_RDONLY ); 1124 if( fd < 0 ) 1125 return NULL; 1126 void* pFile = mmap( NULL, aStat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 1127 close( fd ); 1128 if( pFile == MAP_FAILED ) 1129 return NULL; 1130 1131 *pDataLen = aStat.st_size; 1132 1133 rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) ); 1134 rInfo.m_nCapHeight = yMax; // Well ... 1135 1136 for( int i = 0; i < 256; i++ ) 1137 pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0); 1138 1139 switch( aFontInfo.m_eType ) 1140 { 1141 case psp::fonttype::TrueType: 1142 rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; 1143 break; 1144 case psp::fonttype::Type1: { 1145 const bool bPFA = ((*(unsigned char*)pFile) < 0x80); 1146 rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB; 1147 } 1148 break; 1149 default: 1150 return NULL; 1151 } 1152 1153 return pFile; 1154 } 1155 1156 void PspGraphics::DoFreeEmbedFontData( const void* pData, long nLen ) 1157 { 1158 if( pData ) 1159 munmap( (char*)pData, nLen ); 1160 } 1161 1162 const Ucs2SIntMap* PspGraphics::DoGetFontEncodingVector( fontID aFont, const Ucs2OStrMap** pNonEncoded ) 1163 { 1164 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1165 1166 psp::PrintFontInfo aFontInfo; 1167 if( ! rMgr.getFontInfo( aFont, aFontInfo ) ) 1168 { 1169 if( pNonEncoded ) 1170 *pNonEncoded = NULL; 1171 return NULL; 1172 } 1173 1174 return rMgr.getEncodingMap( aFont, pNonEncoded ); 1175 } 1176 1177 void PspGraphics::DoGetGlyphWidths( psp::fontID aFont, 1178 bool bVertical, 1179 Int32Vector& rWidths, 1180 Ucs2UIntMap& rUnicodeEnc ) 1181 { 1182 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1183 rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); 1184 } 1185 // ---------------------------------------------------------------------------- 1186 1187 FontWidth PspGraphics::ToFontWidth (psp::width::type eWidth) 1188 { 1189 switch (eWidth) 1190 { 1191 case psp::width::UltraCondensed: return WIDTH_ULTRA_CONDENSED; 1192 case psp::width::ExtraCondensed: return WIDTH_EXTRA_CONDENSED; 1193 case psp::width::Condensed: return WIDTH_CONDENSED; 1194 case psp::width::SemiCondensed: return WIDTH_SEMI_CONDENSED; 1195 case psp::width::Normal: return WIDTH_NORMAL; 1196 case psp::width::SemiExpanded: return WIDTH_SEMI_EXPANDED; 1197 case psp::width::Expanded: return WIDTH_EXPANDED; 1198 case psp::width::ExtraExpanded: return WIDTH_EXTRA_EXPANDED; 1199 case psp::width::UltraExpanded: return WIDTH_ULTRA_EXPANDED; 1200 case psp::width::Unknown: return WIDTH_DONTKNOW; 1201 default: 1202 DBG_ERROR( "unknown width mapping" ); 1203 break; 1204 } 1205 return WIDTH_DONTKNOW; 1206 } 1207 1208 FontWeight PspGraphics::ToFontWeight (psp::weight::type eWeight) 1209 { 1210 switch (eWeight) 1211 { 1212 case psp::weight::Thin: return WEIGHT_THIN; 1213 case psp::weight::UltraLight: return WEIGHT_ULTRALIGHT; 1214 case psp::weight::Light: return WEIGHT_LIGHT; 1215 case psp::weight::SemiLight: return WEIGHT_SEMILIGHT; 1216 case psp::weight::Normal: return WEIGHT_NORMAL; 1217 case psp::weight::Medium: return WEIGHT_MEDIUM; 1218 case psp::weight::SemiBold: return WEIGHT_SEMIBOLD; 1219 case psp::weight::Bold: return WEIGHT_BOLD; 1220 case psp::weight::UltraBold: return WEIGHT_ULTRABOLD; 1221 case psp::weight::Black: return WEIGHT_BLACK; 1222 case psp::weight::Unknown: return WEIGHT_DONTKNOW; 1223 default: 1224 DBG_ERROR( "unknown weight mapping" ); 1225 break; 1226 } 1227 return WEIGHT_DONTKNOW; 1228 } 1229 1230 FontPitch PspGraphics::ToFontPitch (psp::pitch::type ePitch) 1231 { 1232 switch (ePitch) 1233 { 1234 case psp::pitch::Fixed: return PITCH_FIXED; 1235 case psp::pitch::Variable: return PITCH_VARIABLE; 1236 case psp::pitch::Unknown: return PITCH_DONTKNOW; 1237 default: 1238 DBG_ERROR( "unknown pitch mapping" ); 1239 break; 1240 } 1241 return PITCH_DONTKNOW; 1242 } 1243 1244 FontItalic PspGraphics::ToFontItalic (psp::italic::type eItalic) 1245 { 1246 switch (eItalic) 1247 { 1248 case psp::italic::Upright: return ITALIC_NONE; 1249 case psp::italic::Oblique: return ITALIC_OBLIQUE; 1250 case psp::italic::Italic: return ITALIC_NORMAL; 1251 case psp::italic::Unknown: return ITALIC_DONTKNOW; 1252 default: 1253 DBG_ERROR( "unknown italic mapping" ); 1254 break; 1255 } 1256 return ITALIC_DONTKNOW; 1257 } 1258 1259 FontFamily PspGraphics::ToFontFamily (psp::family::type eFamily) 1260 { 1261 switch (eFamily) 1262 { 1263 case psp::family::Decorative: return FAMILY_DECORATIVE; 1264 case psp::family::Modern: return FAMILY_MODERN; 1265 case psp::family::Roman: return FAMILY_ROMAN; 1266 case psp::family::Script: return FAMILY_SCRIPT; 1267 case psp::family::Swiss: return FAMILY_SWISS; 1268 case psp::family::System: return FAMILY_SYSTEM; 1269 case psp::family::Unknown: return FAMILY_DONTKNOW; 1270 default: 1271 DBG_ERROR( "unknown family mapping" ); 1272 break; 1273 } 1274 return FAMILY_DONTKNOW; 1275 } 1276 1277 ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintFontInfo& rInfo ) 1278 { 1279 ImplDevFontAttributes aDFA; 1280 aDFA.maName = rInfo.m_aFamilyName; 1281 aDFA.maStyleName = rInfo.m_aStyleName; 1282 aDFA.meFamily = ToFontFamily (rInfo.m_eFamilyStyle); 1283 aDFA.meWeight = ToFontWeight (rInfo.m_eWeight); 1284 aDFA.meItalic = ToFontItalic (rInfo.m_eItalic); 1285 aDFA.meWidthType = ToFontWidth (rInfo.m_eWidth); 1286 aDFA.mePitch = ToFontPitch (rInfo.m_ePitch); 1287 aDFA.mbSymbolFlag = (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL); 1288 aDFA.mbSubsettable = rInfo.m_bSubsettable; 1289 aDFA.mbEmbeddable = rInfo.m_bEmbeddable; 1290 1291 switch( rInfo.m_eType ) 1292 { 1293 case psp::fonttype::Builtin: 1294 aDFA.mnQuality = 1024; 1295 aDFA.mbDevice = true; 1296 break; 1297 case psp::fonttype::TrueType: 1298 aDFA.mnQuality = 512; 1299 aDFA.mbDevice = false; 1300 break; 1301 case psp::fonttype::Type1: 1302 aDFA.mnQuality = 0; 1303 aDFA.mbDevice = false; 1304 break; 1305 default: 1306 aDFA.mnQuality = 0; 1307 aDFA.mbDevice = false; 1308 break; 1309 } 1310 1311 aDFA.mbOrientation = true; 1312 1313 // add font family name aliases 1314 ::std::list< OUString >::const_iterator it = rInfo.m_aAliases.begin(); 1315 bool bHasMapNames = false; 1316 for(; it != rInfo.m_aAliases.end(); ++it ) 1317 { 1318 if( bHasMapNames ) 1319 aDFA.maMapNames.Append( ';' ); 1320 aDFA.maMapNames.Append( (*it).getStr() ); 1321 bHasMapNames = true; 1322 } 1323 1324 #if OSL_DEBUG_LEVEL > 2 1325 if( bHasMapNames ) 1326 { 1327 ByteString aOrigName( aDFA.maName, osl_getThreadTextEncoding() ); 1328 ByteString aAliasNames( aDFA.maMapNames, osl_getThreadTextEncoding() ); 1329 fprintf( stderr, "using alias names \"%s\" for font family \"%s\"\n", 1330 aAliasNames.GetBuffer(), aOrigName.GetBuffer() ); 1331 } 1332 #endif 1333 1334 return aDFA; 1335 } 1336 1337 // ----------------------------------------------------------------------- 1338 1339 void PspGraphics::AnnounceFonts( ImplDevFontList* pFontList, const psp::FastPrintFontInfo& aInfo ) 1340 { 1341 int nQuality = 0; 1342 1343 if( aInfo.m_eType == psp::fonttype::TrueType ) 1344 { 1345 // asian type 1 fonts are not known 1346 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1347 ByteString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) ); 1348 int nPos = aFileName.SearchBackward( '_' ); 1349 if( nPos == STRING_NOTFOUND || aFileName.GetChar( nPos+1 ) == '.' ) 1350 nQuality += 5; 1351 else 1352 { 1353 static const char* pLangBoost = NULL; 1354 static bool bOnce = true; 1355 if( bOnce ) 1356 { 1357 bOnce = false; 1358 const LanguageType aLang = Application::GetSettings().GetUILanguage(); 1359 switch( aLang ) 1360 { 1361 case LANGUAGE_JAPANESE: 1362 pLangBoost = "jan"; 1363 break; 1364 case LANGUAGE_CHINESE: 1365 case LANGUAGE_CHINESE_SIMPLIFIED: 1366 case LANGUAGE_CHINESE_SINGAPORE: 1367 pLangBoost = "zhs"; 1368 break; 1369 case LANGUAGE_CHINESE_TRADITIONAL: 1370 case LANGUAGE_CHINESE_HONGKONG: 1371 case LANGUAGE_CHINESE_MACAU: 1372 pLangBoost = "zht"; 1373 break; 1374 case LANGUAGE_KOREAN: 1375 case LANGUAGE_KOREAN_JOHAB: 1376 pLangBoost = "kor"; 1377 break; 1378 } 1379 } 1380 1381 if( pLangBoost ) 1382 if( aFileName.Copy( nPos+1, 3 ).EqualsIgnoreCaseAscii( pLangBoost ) ) 1383 nQuality += 10; 1384 } 1385 } 1386 1387 ImplPspFontData* pFD = new ImplPspFontData( aInfo ); 1388 pFD->mnQuality += nQuality; 1389 pFontList->Add( pFD ); 1390 } 1391 1392 bool PspGraphics::filterText( const String& rOrig, String& rNewText, xub_StrLen nIndex, xub_StrLen& rLen, xub_StrLen& rCutStart, xub_StrLen& rCutStop ) 1393 { 1394 if( ! m_pPhoneNr ) 1395 return false; 1396 1397 rCutStop = rCutStart = STRING_NOTFOUND; 1398 1399 #define FAX_PHONE_TOKEN "@@#" 1400 #define FAX_PHONE_TOKEN_LENGTH 3 1401 #define FAX_END_TOKEN "@@" 1402 #define FAX_END_TOKEN_LENGTH 2 1403 1404 bool bRet = false; 1405 bool bStarted = false; 1406 bool bStopped = false; 1407 sal_uInt16 nPos; 1408 sal_uInt16 nStart = 0; 1409 sal_uInt16 nStop = rLen; 1410 String aPhone = rOrig.Copy( nIndex, rLen ); 1411 1412 if( ! m_bPhoneCollectionActive ) 1413 { 1414 if( ( nPos = aPhone.SearchAscii( FAX_PHONE_TOKEN ) ) != STRING_NOTFOUND ) 1415 { 1416 nStart = nPos; 1417 m_bPhoneCollectionActive = true; 1418 m_aPhoneCollection.Erase(); 1419 bRet = true; 1420 bStarted = true; 1421 } 1422 } 1423 if( m_bPhoneCollectionActive ) 1424 { 1425 bRet = true; 1426 nPos = bStarted ? nStart + FAX_PHONE_TOKEN_LENGTH : 0; 1427 if( ( nPos = aPhone.SearchAscii( FAX_END_TOKEN, nPos ) ) != STRING_NOTFOUND ) 1428 { 1429 m_bPhoneCollectionActive = false; 1430 nStop = nPos + FAX_END_TOKEN_LENGTH; 1431 bStopped = true; 1432 } 1433 int nTokenStart = nStart + (bStarted ? FAX_PHONE_TOKEN_LENGTH : 0); 1434 int nTokenStop = nStop - (bStopped ? FAX_END_TOKEN_LENGTH : 0); 1435 m_aPhoneCollection += aPhone.Copy( nTokenStart, nTokenStop - nTokenStart ); 1436 if( ! m_bPhoneCollectionActive ) 1437 { 1438 m_pPhoneNr->AppendAscii( "<Fax#>" ); 1439 m_pPhoneNr->Append( m_aPhoneCollection ); 1440 m_pPhoneNr->AppendAscii( "</Fax#>" ); 1441 m_aPhoneCollection.Erase(); 1442 } 1443 } 1444 if( m_aPhoneCollection.Len() > 1024 ) 1445 { 1446 m_bPhoneCollectionActive = false; 1447 m_aPhoneCollection.Erase(); 1448 bRet = false; 1449 } 1450 1451 if( bRet && m_bSwallowFaxNo ) 1452 { 1453 rLen -= nStop - nStart; 1454 rCutStart = nStart+nIndex; 1455 rCutStop = nStop+nIndex; 1456 if( rCutStart ) 1457 rNewText = rOrig.Copy( 0, rCutStart ); 1458 rNewText += rOrig.Copy( rCutStop ); 1459 } 1460 1461 return bRet && m_bSwallowFaxNo; 1462 } 1463 1464 bool PspGraphics::drawAlphaBitmap( const SalTwoRect&, 1465 const SalBitmap&, 1466 const SalBitmap& ) 1467 { 1468 return false; 1469 } 1470 1471 bool PspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 ) 1472 { 1473 return false; 1474 } 1475 1476 SystemGraphicsData PspGraphics::GetGraphicsData() const 1477 { 1478 SystemGraphicsData aRes; 1479 aRes.nSize = sizeof(aRes); 1480 aRes.hDrawable = 0; 1481 aRes.pRenderFormat = 0; 1482 return aRes; 1483 } 1484 1485 SystemFontData PspGraphics::GetSysFontData( int nFallbacklevel ) const 1486 { 1487 SystemFontData aSysFontData; 1488 1489 if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1; 1490 if (nFallbacklevel < 0 ) nFallbacklevel = 0; 1491 1492 aSysFontData.nSize = sizeof( SystemFontData ); 1493 aSysFontData.nFontId = 0; 1494 aSysFontData.nFontFlags = 0; 1495 aSysFontData.bFakeBold = false; 1496 aSysFontData.bFakeItalic = false; 1497 aSysFontData.bAntialias = true; 1498 return aSysFontData; 1499 } 1500 1501 bool PspGraphics::supportsOperation( OutDevSupportType ) const 1502 { 1503 return false; 1504 } 1505