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