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 int nGlyphIndex = 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 == nGlyphIndex ) 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 = nGlyphIndex; 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 nGlyphIndex |= GF_ISCHAR; 608 aPrevItem = GlyphItem( nCharPos, nGlyphIndex, 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_Int32 nGlyphIdx = 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) ? nGlyphIdx : 0; 693 aGlyphAry[i] = nGlyphIdx; 694 } 695 696 rGfx.DrawGlyphs( aPos, (sal_uInt32 *)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 sal_Bool PspGraphics::GetGlyphBoundRect( long nGlyphIndex, Rectangle& rRect ) 878 { 879 int nLevel = nGlyphIndex >> GF_FONTSHIFT; 880 if( nLevel >= MAX_FALLBACK ) 881 return sal_False; 882 883 ServerFont* pSF = m_pServerFont[ nLevel ]; 884 if( !pSF ) 885 return sal_False; 886 887 nGlyphIndex &= ~GF_FONTMASK; 888 const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex ); 889 rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() ); 890 return sal_True; 891 } 892 893 sal_Bool PspGraphics::GetGlyphOutline( long nGlyphIndex, 894 ::basegfx::B2DPolyPolygon& rB2DPolyPoly ) 895 { 896 int nLevel = nGlyphIndex >> 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 nGlyphIndex &= ~GF_FONTMASK; 905 if( pSF->GetGlyphOutline( nGlyphIndex, rB2DPolyPoly ) ) 906 return sal_True; 907 908 return sal_False; 909 } 910 911 SalLayout* PspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) 912 { 913 // workaround for printers not handling glyph indexing for non-TT fonts 914 int nFontId = m_pPrinterGfx->GetFontID(); 915 if( psp::fonttype::TrueType != psp::PrintFontManager::get().getFontType( nFontId ) ) 916 rArgs.mnFlags |= SAL_LAYOUT_DISABLE_GLYPH_PROCESSING; 917 else if( nFallbackLevel > 0 ) 918 rArgs.mnFlags &= ~SAL_LAYOUT_DISABLE_GLYPH_PROCESSING; 919 920 GenericSalLayout* pLayout = NULL; 921 922 if( m_pServerFont[ nFallbackLevel ] 923 && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) ) 924 pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs ); 925 else 926 pLayout = new PspFontLayout( *m_pPrinterGfx ); 927 928 return pLayout; 929 } 930 931 //-------------------------------------------------------------------------- 932 933 sal_Bool PspGraphics::CreateFontSubset( 934 const rtl::OUString& rToFile, 935 const ImplFontData* pFont, 936 sal_Int32* pGlyphIDs, 937 sal_uInt8* pEncoding, 938 sal_Int32* pWidths, 939 int nGlyphCount, 940 FontSubsetInfo& rInfo 941 ) 942 { 943 // in this context the pFont->GetFontId() is a valid PSP 944 // font since they are the only ones left after the PDF 945 // export has filtered its list of subsettable fonts (for 946 // which this method was created). The correct way would 947 // be to have the GlyphCache search for the ImplFontData pFont 948 psp::fontID aFont = pFont->GetFontId(); 949 950 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 951 bool bSuccess = rMgr.createFontSubset( rInfo, 952 aFont, 953 rToFile, 954 pGlyphIDs, 955 pEncoding, 956 pWidths, 957 nGlyphCount ); 958 return bSuccess; 959 } 960 961 //-------------------------------------------------------------------------- 962 963 const void* PspGraphics::GetEmbedFontData( const ImplFontData* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ) 964 { 965 // in this context the pFont->GetFontId() is a valid PSP 966 // font since they are the only ones left after the PDF 967 // export has filtered its list of subsettable fonts (for 968 // which this method was created). The correct way would 969 // be to have the GlyphCache search for the ImplFontData pFont 970 psp::fontID aFont = pFont->GetFontId(); 971 return PspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen ); 972 } 973 974 //-------------------------------------------------------------------------- 975 976 void PspGraphics::FreeEmbedFontData( const void* pData, long nLen ) 977 { 978 PspGraphics::DoFreeEmbedFontData( pData, nLen ); 979 } 980 981 //-------------------------------------------------------------------------- 982 983 const Ucs2SIntMap* PspGraphics::GetFontEncodingVector( const ImplFontData* pFont, const Ucs2OStrMap** pNonEncoded ) 984 { 985 // in this context the pFont->GetFontId() is a valid PSP 986 // font since they are the only ones left after the PDF 987 // export has filtered its list of subsettable fonts (for 988 // which this method was created). The correct way would 989 // be to have the GlyphCache search for the ImplFontData pFont 990 psp::fontID aFont = pFont->GetFontId(); 991 return PspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded ); 992 } 993 994 //-------------------------------------------------------------------------- 995 996 void PspGraphics::GetGlyphWidths( const ImplFontData* pFont, 997 bool bVertical, 998 Int32Vector& rWidths, 999 Ucs2UIntMap& rUnicodeEnc ) 1000 { 1001 // in this context the pFont->GetFontId() is a valid PSP 1002 // font since they are the only ones left after the PDF 1003 // export has filtered its list of subsettable fonts (for 1004 // which this method was created). The correct way would 1005 // be to have the GlyphCache search for the ImplFontData pFont 1006 psp::fontID aFont = pFont->GetFontId(); 1007 PspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); 1008 } 1009 1010 // static helpers of PspGraphics 1011 1012 const void* PspGraphics::DoGetEmbedFontData( fontID aFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ) 1013 { 1014 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1015 1016 psp::PrintFontInfo aFontInfo; 1017 if( ! rMgr.getFontInfo( aFont, aFontInfo ) ) 1018 return NULL; 1019 1020 // fill in font info 1021 rInfo.m_nAscent = aFontInfo.m_nAscend; 1022 rInfo.m_nDescent = aFontInfo.m_nDescend; 1023 rInfo.m_aPSName = rMgr.getPSName( aFont ); 1024 1025 int xMin, yMin, xMax, yMax; 1026 rMgr.getFontBoundingBox( aFont, xMin, yMin, xMax, yMax ); 1027 1028 psp::CharacterMetric aMetrics[256]; 1029 sal_Ucs aUnicodes[256]; 1030 if( aFontInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL && aFontInfo.m_eType == psp::fonttype::Type1 ) 1031 { 1032 for( int i = 0; i < 256; i++ ) 1033 aUnicodes[i] = pUnicodes[i] < 0x0100 ? pUnicodes[i] + 0xf000 : pUnicodes[i]; 1034 pUnicodes = aUnicodes; 1035 } 1036 if( ! rMgr.getMetrics( aFont, pUnicodes, 256, aMetrics ) ) 1037 return NULL; 1038 1039 OString aSysPath = rMgr.getFontFileSysPath( aFont ); 1040 struct stat aStat; 1041 if( stat( aSysPath.getStr(), &aStat ) ) 1042 return NULL; 1043 int fd = open( aSysPath.getStr(), O_RDONLY ); 1044 if( fd < 0 ) 1045 return NULL; 1046 void* pFile = mmap( NULL, aStat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 1047 close( fd ); 1048 if( pFile == MAP_FAILED ) 1049 return NULL; 1050 1051 *pDataLen = aStat.st_size; 1052 1053 rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) ); 1054 rInfo.m_nCapHeight = yMax; // Well ... 1055 1056 for( int i = 0; i < 256; i++ ) 1057 pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0); 1058 1059 switch( aFontInfo.m_eType ) 1060 { 1061 case psp::fonttype::TrueType: 1062 rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; 1063 break; 1064 case psp::fonttype::Type1: { 1065 const bool bPFA = ((*(unsigned char*)pFile) < 0x80); 1066 rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB; 1067 } 1068 break; 1069 default: 1070 return NULL; 1071 } 1072 1073 return pFile; 1074 } 1075 1076 void PspGraphics::DoFreeEmbedFontData( const void* pData, long nLen ) 1077 { 1078 if( pData ) 1079 munmap( (char*)pData, nLen ); 1080 } 1081 1082 const Ucs2SIntMap* PspGraphics::DoGetFontEncodingVector( fontID aFont, const Ucs2OStrMap** pNonEncoded ) 1083 { 1084 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1085 1086 psp::PrintFontInfo aFontInfo; 1087 if( ! rMgr.getFontInfo( aFont, aFontInfo ) ) 1088 { 1089 if( pNonEncoded ) 1090 *pNonEncoded = NULL; 1091 return NULL; 1092 } 1093 1094 return rMgr.getEncodingMap( aFont, pNonEncoded ); 1095 } 1096 1097 void PspGraphics::DoGetGlyphWidths( psp::fontID aFont, 1098 bool bVertical, 1099 Int32Vector& rWidths, 1100 Ucs2UIntMap& rUnicodeEnc ) 1101 { 1102 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1103 rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); 1104 } 1105 1106 // ---------------------------------------------------------------------------- 1107 1108 FontWidth PspGraphics::ToFontWidth (psp::width::type eWidth) 1109 { 1110 switch (eWidth) 1111 { 1112 case psp::width::UltraCondensed: return WIDTH_ULTRA_CONDENSED; 1113 case psp::width::ExtraCondensed: return WIDTH_EXTRA_CONDENSED; 1114 case psp::width::Condensed: return WIDTH_CONDENSED; 1115 case psp::width::SemiCondensed: return WIDTH_SEMI_CONDENSED; 1116 case psp::width::Normal: return WIDTH_NORMAL; 1117 case psp::width::SemiExpanded: return WIDTH_SEMI_EXPANDED; 1118 case psp::width::Expanded: return WIDTH_EXPANDED; 1119 case psp::width::ExtraExpanded: return WIDTH_EXTRA_EXPANDED; 1120 case psp::width::UltraExpanded: return WIDTH_ULTRA_EXPANDED; 1121 default: break; 1122 } 1123 return WIDTH_DONTKNOW; 1124 } 1125 1126 FontWeight PspGraphics::ToFontWeight (psp::weight::type eWeight) 1127 { 1128 switch (eWeight) 1129 { 1130 case psp::weight::Thin: return WEIGHT_THIN; 1131 case psp::weight::UltraLight: return WEIGHT_ULTRALIGHT; 1132 case psp::weight::Light: return WEIGHT_LIGHT; 1133 case psp::weight::SemiLight: return WEIGHT_SEMILIGHT; 1134 case psp::weight::Normal: return WEIGHT_NORMAL; 1135 case psp::weight::Medium: return WEIGHT_MEDIUM; 1136 case psp::weight::SemiBold: return WEIGHT_SEMIBOLD; 1137 case psp::weight::Bold: return WEIGHT_BOLD; 1138 case psp::weight::UltraBold: return WEIGHT_ULTRABOLD; 1139 case psp::weight::Black: return WEIGHT_BLACK; 1140 default: break; 1141 } 1142 return WEIGHT_DONTKNOW; 1143 } 1144 1145 FontPitch PspGraphics::ToFontPitch (psp::pitch::type ePitch) 1146 { 1147 switch (ePitch) 1148 { 1149 case psp::pitch::Fixed: return PITCH_FIXED; 1150 case psp::pitch::Variable: return PITCH_VARIABLE; 1151 default: break; 1152 } 1153 return PITCH_DONTKNOW; 1154 } 1155 1156 FontItalic PspGraphics::ToFontItalic (psp::italic::type eItalic) 1157 { 1158 switch (eItalic) 1159 { 1160 case psp::italic::Upright: return ITALIC_NONE; 1161 case psp::italic::Oblique: return ITALIC_OBLIQUE; 1162 case psp::italic::Italic: return ITALIC_NORMAL; 1163 default: break; 1164 } 1165 return ITALIC_DONTKNOW; 1166 } 1167 1168 FontFamily PspGraphics::ToFontFamily (psp::family::type eFamily) 1169 { 1170 switch (eFamily) 1171 { 1172 case psp::family::Decorative: return FAMILY_DECORATIVE; 1173 case psp::family::Modern: return FAMILY_MODERN; 1174 case psp::family::Roman: return FAMILY_ROMAN; 1175 case psp::family::Script: return FAMILY_SCRIPT; 1176 case psp::family::Swiss: return FAMILY_SWISS; 1177 case psp::family::System: return FAMILY_SYSTEM; 1178 default: break; 1179 } 1180 return FAMILY_DONTKNOW; 1181 } 1182 1183 ImplDevFontAttributes PspGraphics::Info2DevFontAttributes( const psp::FastPrintFontInfo& rInfo ) 1184 { 1185 ImplDevFontAttributes aDFA; 1186 aDFA.maName = rInfo.m_aFamilyName; 1187 aDFA.maStyleName = rInfo.m_aStyleName; 1188 aDFA.meFamily = ToFontFamily (rInfo.m_eFamilyStyle); 1189 aDFA.meWeight = ToFontWeight (rInfo.m_eWeight); 1190 aDFA.meItalic = ToFontItalic (rInfo.m_eItalic); 1191 aDFA.meWidthType = ToFontWidth (rInfo.m_eWidth); 1192 aDFA.mePitch = ToFontPitch (rInfo.m_ePitch); 1193 aDFA.mbSymbolFlag = (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL); 1194 1195 switch( rInfo.m_eType ) 1196 { 1197 case psp::fonttype::Builtin: 1198 aDFA.mnQuality = 1024; 1199 aDFA.mbDevice = true; 1200 aDFA.mbSubsettable = false; 1201 aDFA.mbEmbeddable = false; 1202 break; 1203 case psp::fonttype::TrueType: 1204 aDFA.mnQuality = 512; 1205 aDFA.mbDevice = false; 1206 aDFA.mbSubsettable = true; 1207 aDFA.mbEmbeddable = false; 1208 break; 1209 case psp::fonttype::Type1: 1210 aDFA.mnQuality = 0; 1211 aDFA.mbDevice = false; 1212 aDFA.mbSubsettable = false; 1213 aDFA.mbEmbeddable = true; 1214 break; 1215 default: 1216 aDFA.mnQuality = 0; 1217 aDFA.mbDevice = false; 1218 aDFA.mbSubsettable = false; 1219 aDFA.mbEmbeddable = false; 1220 break; 1221 } 1222 1223 aDFA.mbOrientation = true; 1224 1225 // add font family name aliases 1226 ::std::list< OUString >::const_iterator it = rInfo.m_aAliases.begin(); 1227 bool bHasMapNames = false; 1228 for(; it != rInfo.m_aAliases.end(); ++it ) 1229 { 1230 if( bHasMapNames ) 1231 aDFA.maMapNames.Append( ';' ); 1232 aDFA.maMapNames.Append( (*it).getStr() ); 1233 bHasMapNames = true; 1234 } 1235 1236 #if OSL_DEBUG_LEVEL > 2 1237 if( bHasMapNames ) 1238 { 1239 ByteString aOrigName( aDFA.maName, osl_getThreadTextEncoding() ); 1240 ByteString aAliasNames( aDFA.maMapNames, osl_getThreadTextEncoding() ); 1241 fprintf( stderr, "using alias names \"%s\" for font family \"%s\"\n", 1242 aAliasNames.GetBuffer(), aOrigName.GetBuffer() ); 1243 } 1244 #endif 1245 1246 return aDFA; 1247 } 1248 1249 // ----------------------------------------------------------------------- 1250 1251 void PspGraphics::AnnounceFonts( ImplDevFontList* pFontList, const psp::FastPrintFontInfo& aInfo ) 1252 { 1253 int nQuality = 0; 1254 1255 if( aInfo.m_eType == psp::fonttype::TrueType ) 1256 { 1257 // asian type 1 fonts are not known 1258 psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); 1259 ByteString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) ); 1260 int nPos = aFileName.SearchBackward( '_' ); 1261 if( nPos == STRING_NOTFOUND || aFileName.GetChar( nPos+1 ) == '.' ) 1262 nQuality += 5; 1263 else 1264 { 1265 static const char* pLangBoost = NULL; 1266 static bool bOnce = true; 1267 if( bOnce ) 1268 { 1269 bOnce = false; 1270 const LanguageType aLang = Application::GetSettings().GetUILanguage(); 1271 switch( aLang ) 1272 { 1273 case LANGUAGE_JAPANESE: 1274 pLangBoost = "jan"; 1275 break; 1276 case LANGUAGE_CHINESE: 1277 case LANGUAGE_CHINESE_SIMPLIFIED: 1278 case LANGUAGE_CHINESE_SINGAPORE: 1279 pLangBoost = "zhs"; 1280 break; 1281 case LANGUAGE_CHINESE_TRADITIONAL: 1282 case LANGUAGE_CHINESE_HONGKONG: 1283 case LANGUAGE_CHINESE_MACAU: 1284 pLangBoost = "zht"; 1285 break; 1286 case LANGUAGE_KOREAN: 1287 case LANGUAGE_KOREAN_JOHAB: 1288 pLangBoost = "kor"; 1289 break; 1290 } 1291 } 1292 1293 if( pLangBoost ) 1294 if( aFileName.Copy( nPos+1, 3 ).EqualsIgnoreCaseAscii( pLangBoost ) ) 1295 nQuality += 10; 1296 } 1297 } 1298 1299 ImplPspFontData* pFD = new ImplPspFontData( aInfo ); 1300 pFD->mnQuality += nQuality; 1301 pFontList->Add( pFD ); 1302 } 1303 1304 bool PspGraphics::filterText( const String& rOrig, String& rNewText, xub_StrLen nIndex, xub_StrLen& rLen, xub_StrLen& rCutStart, xub_StrLen& rCutStop ) 1305 { 1306 if( ! m_pPhoneNr ) 1307 return false; 1308 1309 rCutStop = rCutStart = STRING_NOTFOUND; 1310 1311 #define FAX_PHONE_TOKEN "@@#" 1312 #define FAX_PHONE_TOKEN_LENGTH 3 1313 #define FAX_END_TOKEN "@@" 1314 #define FAX_END_TOKEN_LENGTH 2 1315 1316 bool bRet = false; 1317 bool bStarted = false; 1318 bool bStopped = false; 1319 sal_uInt16 nPos; 1320 sal_uInt16 nStart = 0; 1321 sal_uInt16 nStop = rLen; 1322 String aPhone = rOrig.Copy( nIndex, rLen ); 1323 1324 if( ! m_bPhoneCollectionActive ) 1325 { 1326 if( ( nPos = aPhone.SearchAscii( FAX_PHONE_TOKEN ) ) != STRING_NOTFOUND ) 1327 { 1328 nStart = nPos; 1329 m_bPhoneCollectionActive = true; 1330 m_aPhoneCollection.Erase(); 1331 bRet = true; 1332 bStarted = true; 1333 } 1334 } 1335 if( m_bPhoneCollectionActive ) 1336 { 1337 bRet = true; 1338 nPos = bStarted ? nStart + FAX_PHONE_TOKEN_LENGTH : 0; 1339 if( ( nPos = aPhone.SearchAscii( FAX_END_TOKEN, nPos ) ) != STRING_NOTFOUND ) 1340 { 1341 m_bPhoneCollectionActive = false; 1342 nStop = nPos + FAX_END_TOKEN_LENGTH; 1343 bStopped = true; 1344 } 1345 int nTokenStart = nStart + (bStarted ? FAX_PHONE_TOKEN_LENGTH : 0); 1346 int nTokenStop = nStop - (bStopped ? FAX_END_TOKEN_LENGTH : 0); 1347 m_aPhoneCollection += aPhone.Copy( nTokenStart, nTokenStop - nTokenStart ); 1348 if( ! m_bPhoneCollectionActive ) 1349 { 1350 m_pPhoneNr->AppendAscii( "<Fax#>" ); 1351 m_pPhoneNr->Append( m_aPhoneCollection ); 1352 m_pPhoneNr->AppendAscii( "</Fax#>" ); 1353 m_aPhoneCollection.Erase(); 1354 } 1355 } 1356 if( m_aPhoneCollection.Len() > 1024 ) 1357 { 1358 m_bPhoneCollectionActive = false; 1359 m_aPhoneCollection.Erase(); 1360 bRet = false; 1361 } 1362 1363 if( bRet && m_bSwallowFaxNo ) 1364 { 1365 rLen -= nStop - nStart; 1366 rCutStart = nStart+nIndex; 1367 rCutStop = nStop+nIndex; 1368 if( rCutStart ) 1369 rNewText = rOrig.Copy( 0, rCutStart ); 1370 rNewText += rOrig.Copy( rCutStop ); 1371 } 1372 1373 return bRet && m_bSwallowFaxNo; 1374 } 1375 1376 SystemFontData PspGraphics::GetSysFontData( int nFallbacklevel ) const 1377 { 1378 SystemFontData aSysFontData; 1379 1380 if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1; 1381 if (nFallbacklevel < 0 ) nFallbacklevel = 0; 1382 1383 aSysFontData.nSize = sizeof( SystemFontData ); 1384 aSysFontData.nFontId = 0; 1385 aSysFontData.nFontFlags = 0; 1386 aSysFontData.bFakeBold = false; 1387 aSysFontData.bFakeItalic = false; 1388 aSysFontData.bAntialias = true; 1389 return aSysFontData; 1390 } 1391 1392 SystemGraphicsData PspGraphics::GetGraphicsData() const 1393 { 1394 SystemGraphicsData aRes; 1395 aRes.nSize = sizeof(aRes); 1396 aRes.hDrawable = 0; 1397 aRes.pRenderFormat = 0; 1398 return aRes; 1399 } 1400 1401