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