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