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