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