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