Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / generic / print / genpspgraphics.cxx
blobbeedfaa40dee1ecfa7c96fedc6a594edd256a849
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <vector>
24 #include <sal/types.h>
26 // for mmap etc.
27 #if defined( UNX )
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/mman.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #endif
35 #include <comphelper/string.hxx>
36 #include <i18nlangtag/mslangid.hxx>
37 #include <vcl/bmpacc.hxx>
38 #include <vcl/jobdata.hxx>
39 #include <vcl/printerinfomanager.hxx>
40 #include <vcl/settings.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/sysdata.hxx>
44 #include "fontsubset.hxx"
45 #include "generic/geninst.h"
46 #include "generic/genpspgraphics.h"
47 #include "generic/glyphcache.hxx"
48 #include "generic/printergfx.hxx"
49 #include "impfont.hxx"
50 #include "langboost.hxx"
51 #include "outfont.hxx"
52 #include "PhysicalFontCollection.hxx"
53 #include "PhysicalFontFace.hxx"
54 #include "salbmp.hxx"
55 #include "salprn.hxx"
57 #include <config_graphite.h>
58 #if ENABLE_GRAPHITE
59 #include <graphite_layout.hxx>
60 #include <graphite_serverfont.hxx>
61 #endif
63 using namespace psp;
65 // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer ---------------
67 class SalPrinterBmp : public psp::PrinterBmp
69 private:
70 BitmapBuffer* mpBmpBuffer;
72 FncGetPixel mpFncGetPixel;
73 Scanline mpScanAccess;
74 sal_PtrDiff mnScanOffset;
76 sal_uInt32 ColorOf (BitmapColor& rColor) const;
77 sal_uInt8 GrayOf (BitmapColor& rColor) const;
79 public:
81 SalPrinterBmp (BitmapBuffer* pBitmap);
82 virtual ~SalPrinterBmp ();
83 virtual sal_uInt32 GetPaletteColor (sal_uInt32 nIdx) const SAL_OVERRIDE;
84 virtual sal_uInt32 GetPaletteEntryCount () const SAL_OVERRIDE;
85 virtual sal_uInt32 GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const SAL_OVERRIDE;
86 virtual sal_uInt8 GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const SAL_OVERRIDE;
87 virtual sal_uInt8 GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const SAL_OVERRIDE;
88 virtual sal_uInt32 GetWidth () const SAL_OVERRIDE;
89 virtual sal_uInt32 GetHeight() const SAL_OVERRIDE;
90 virtual sal_uInt32 GetDepth () const SAL_OVERRIDE;
93 SalPrinterBmp::SalPrinterBmp (BitmapBuffer* pBuffer)
94 : mpBmpBuffer(pBuffer)
96 assert(mpBmpBuffer && "SalPrinterBmp::SalPrinterBmp () can't acquire Bitmap");
98 // calibrate scanline buffer
99 if( BMP_SCANLINE_ADJUSTMENT( mpBmpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
101 mpScanAccess = mpBmpBuffer->mpBits;
102 mnScanOffset = mpBmpBuffer->mnScanlineSize;
104 else
106 mpScanAccess = mpBmpBuffer->mpBits
107 + (mpBmpBuffer->mnHeight - 1) * mpBmpBuffer->mnScanlineSize;
108 mnScanOffset = - mpBmpBuffer->mnScanlineSize;
111 // request read access to the pixels
112 switch( BMP_SCANLINE_FORMAT( mpBmpBuffer->mnFormat ) )
114 case BMP_FORMAT_1BIT_MSB_PAL:
115 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL; break;
116 case BMP_FORMAT_1BIT_LSB_PAL:
117 mpFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_LSB_PAL; break;
118 case BMP_FORMAT_4BIT_MSN_PAL:
119 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_MSN_PAL; break;
120 case BMP_FORMAT_4BIT_LSN_PAL:
121 mpFncGetPixel = BitmapReadAccess::GetPixelFor_4BIT_LSN_PAL; break;
122 case BMP_FORMAT_8BIT_PAL:
123 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_PAL; break;
124 case BMP_FORMAT_8BIT_TC_MASK:
125 mpFncGetPixel = BitmapReadAccess::GetPixelFor_8BIT_TC_MASK; break;
126 case BMP_FORMAT_16BIT_TC_MSB_MASK:
127 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_MSB_MASK; break;
128 case BMP_FORMAT_16BIT_TC_LSB_MASK:
129 mpFncGetPixel = BitmapReadAccess::GetPixelFor_16BIT_TC_LSB_MASK; break;
130 case BMP_FORMAT_24BIT_TC_BGR:
131 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_BGR; break;
132 case BMP_FORMAT_24BIT_TC_RGB:
133 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_RGB; break;
134 case BMP_FORMAT_24BIT_TC_MASK:
135 mpFncGetPixel = BitmapReadAccess::GetPixelFor_24BIT_TC_MASK; break;
136 case BMP_FORMAT_32BIT_TC_ABGR:
137 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ABGR; break;
138 case BMP_FORMAT_32BIT_TC_ARGB:
139 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_ARGB; break;
140 case BMP_FORMAT_32BIT_TC_BGRA:
141 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_BGRA; break;
142 case BMP_FORMAT_32BIT_TC_RGBA:
143 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_RGBA; break;
144 case BMP_FORMAT_32BIT_TC_MASK:
145 mpFncGetPixel = BitmapReadAccess::GetPixelFor_32BIT_TC_MASK; break;
147 default:
148 OSL_FAIL("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format");
149 mpFncGetPixel = NULL;
150 break;
154 SalPrinterBmp::~SalPrinterBmp ()
158 sal_uInt32
159 SalPrinterBmp::GetWidth () const
161 return mpBmpBuffer->mnWidth;
164 sal_uInt32
165 SalPrinterBmp::GetHeight () const
167 return mpBmpBuffer->mnHeight;
170 sal_uInt32
171 SalPrinterBmp::GetDepth () const
173 sal_uInt32 nDepth;
175 switch (mpBmpBuffer->mnBitCount)
177 case 1:
178 nDepth = 1;
179 break;
181 case 4:
182 case 8:
183 nDepth = 8;
184 break;
186 case 16:
187 case 24:
188 case 32:
189 nDepth = 24;
190 break;
192 default:
193 nDepth = 1;
194 OSL_FAIL("Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()");
195 break;
198 return nDepth;
201 sal_uInt32
202 SalPrinterBmp::ColorOf (BitmapColor& rColor) const
204 if (rColor.IsIndex())
205 return ColorOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
206 else
207 return ((rColor.GetBlue()) & 0x000000ff)
208 | ((rColor.GetGreen() << 8) & 0x0000ff00)
209 | ((rColor.GetRed() << 16) & 0x00ff0000);
212 sal_uInt8
213 SalPrinterBmp::GrayOf (BitmapColor& rColor) const
215 if (rColor.IsIndex())
216 return GrayOf (mpBmpBuffer->maPalette[rColor.GetIndex()]);
217 else
218 return ( rColor.GetBlue() * 28UL
219 + rColor.GetGreen() * 151UL
220 + rColor.GetRed() * 77UL ) >> 8;
223 sal_uInt32
224 SalPrinterBmp::GetPaletteEntryCount () const
226 return mpBmpBuffer->maPalette.GetEntryCount ();
229 sal_uInt32
230 SalPrinterBmp::GetPaletteColor (sal_uInt32 nIdx) const
232 return ColorOf (mpBmpBuffer->maPalette[nIdx]);
235 sal_uInt32
236 SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const
238 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
239 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
241 return ColorOf (aColor);
244 sal_uInt8
245 SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const
247 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
248 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
250 return GrayOf (aColor);
253 sal_uInt8
254 SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const
256 Scanline pScan = mpScanAccess + nRow * mnScanOffset;
257 BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask);
259 if (aColor.IsIndex())
260 return aColor.GetIndex();
261 else
262 return 0;
265 /*******************************************************
266 * GenPspGraphics *
267 *******************************************************/
269 GenPspGraphics::GenPspGraphics()
270 : m_pJobData( NULL ),
271 m_pPrinterGfx( NULL ),
272 m_bFontVertical( false ),
273 m_pInfoPrinter( NULL )
275 for( int i = 0; i < MAX_FALLBACK; i++ )
276 m_pServerFont[i] = NULL;
279 void GenPspGraphics::Init(psp::JobData* pJob, psp::PrinterGfx* pGfx,
280 SalInfoPrinter* pInfoPrinter)
282 m_pJobData = pJob;
283 m_pPrinterGfx = pGfx;
284 m_pInfoPrinter = pInfoPrinter;
285 SetLayout( SalLayoutFlags::NONE );
288 GenPspGraphics::~GenPspGraphics()
290 ReleaseFonts();
293 void GenPspGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY )
295 if (m_pJobData != NULL)
297 int x = m_pJobData->m_aContext.getRenderResolution();
299 rDPIX = x;
300 rDPIY = x;
304 sal_uInt16 GenPspGraphics::GetBitCount() const
306 return m_pPrinterGfx->GetBitCount();
309 long GenPspGraphics::GetGraphicsWidth() const
311 return 0;
314 void GenPspGraphics::ResetClipRegion()
316 m_pPrinterGfx->ResetClipRegion();
319 bool GenPspGraphics::setClipRegion( const vcl::Region& i_rClip )
321 // TODO: support polygonal clipregions here
322 RectangleVector aRectangles;
323 i_rClip.GetRegionRectangles(aRectangles);
324 m_pPrinterGfx->BeginSetClipRegion(aRectangles.size());
326 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
328 const long nW(aRectIter->GetWidth());
330 if(nW)
332 const long nH(aRectIter->GetHeight());
334 if(nH)
336 m_pPrinterGfx->UnionClipRegion(
337 aRectIter->Left(),
338 aRectIter->Top(),
340 nH);
345 m_pPrinterGfx->EndSetClipRegion();
347 //m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
349 //ImplRegionInfo aInfo;
350 //long nX, nY, nW, nH;
351 //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
352 //while( bRegionRect )
354 // if ( nW && nH )
355 // {
356 // m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
357 // }
358 // bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
360 //m_pPrinterGfx->EndSetClipRegion();
361 return true;
364 void GenPspGraphics::SetLineColor()
366 m_pPrinterGfx->SetLineColor ();
369 void GenPspGraphics::SetLineColor( SalColor nSalColor )
371 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
372 SALCOLOR_GREEN (nSalColor),
373 SALCOLOR_BLUE (nSalColor));
374 m_pPrinterGfx->SetLineColor (aColor);
377 void GenPspGraphics::SetFillColor()
379 m_pPrinterGfx->SetFillColor ();
382 void GenPspGraphics::SetFillColor( SalColor nSalColor )
384 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
385 SALCOLOR_GREEN (nSalColor),
386 SALCOLOR_BLUE (nSalColor));
387 m_pPrinterGfx->SetFillColor (aColor);
390 void GenPspGraphics::SetROPLineColor( SalROPColor )
392 DBG_ASSERT( false, "Error: PrinterGfx::SetROPLineColor() not implemented" );
395 void GenPspGraphics::SetROPFillColor( SalROPColor )
397 DBG_ASSERT( false, "Error: PrinterGfx::SetROPFillColor() not implemented" );
400 void GenPspGraphics::SetXORMode( bool bSet, bool )
402 (void)bSet;
403 DBG_ASSERT( !bSet, "Error: PrinterGfx::SetXORMode() not implemented" );
406 void GenPspGraphics::drawPixel( long nX, long nY )
408 m_pPrinterGfx->DrawPixel (Point(nX, nY));
411 void GenPspGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
413 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
414 SALCOLOR_GREEN (nSalColor),
415 SALCOLOR_BLUE (nSalColor));
416 m_pPrinterGfx->DrawPixel (Point(nX, nY), aColor);
419 void GenPspGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
421 m_pPrinterGfx->DrawLine (Point(nX1, nY1), Point(nX2, nY2));
424 void GenPspGraphics::drawRect( long nX, long nY, long nDX, long nDY )
426 m_pPrinterGfx->DrawRect (Rectangle(Point(nX, nY), Size(nDX, nDY)));
429 void GenPspGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
431 m_pPrinterGfx->DrawPolyLine (nPoints, reinterpret_cast<Point const *>(pPtAry));
434 void GenPspGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
436 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
437 m_pPrinterGfx->DrawPolygon (nPoints, reinterpret_cast<Point const *>(pPtAry));
440 void GenPspGraphics::drawPolyPolygon( sal_uInt32 nPoly,
441 const sal_uInt32 *pPoints,
442 PCONSTSALPOINT *pPtAry )
444 m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, reinterpret_cast<const Point**>(pPtAry));
447 bool GenPspGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
449 // TODO: implement and advertise OutDevSupport_B2DDraw support
450 return false;
453 bool GenPspGraphics::drawPolyLine(
454 const basegfx::B2DPolygon&,
455 double /*fTranspareny*/,
456 const basegfx::B2DVector& /*rLineWidths*/,
457 basegfx::B2DLineJoin /*eJoin*/,
458 com::sun::star::drawing::LineCap /*eLineCap*/)
460 // TODO: a PS printer can draw B2DPolyLines almost directly
461 return false;
464 bool GenPspGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
466 m_pPrinterGfx->DrawPolyLineBezier (nPoints, reinterpret_cast<Point const *>(pPtAry), pFlgAry);
467 return true;
470 bool GenPspGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
472 m_pPrinterGfx->DrawPolygonBezier (nPoints, reinterpret_cast<Point const *>(pPtAry), pFlgAry);
473 return true;
476 bool GenPspGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly,
477 const sal_uInt32* pPoints,
478 const SalPoint* const* pPtAry,
479 const sal_uInt8* const* pFlgAry )
481 // Point must be equal to SalPoint! see vcl/inc/salgtype.hxx
482 m_pPrinterGfx->DrawPolyPolygonBezier (nPoly, pPoints, reinterpret_cast<Point const * const *>(pPtAry), (sal_uInt8**)pFlgAry);
483 return true;
486 void GenPspGraphics::invert( sal_uInt32,
487 const SalPoint*,
488 SalInvert )
490 DBG_ASSERT( false, "Error: PrinterGfx::Invert() not implemented" );
493 bool GenPspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
495 return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize );
498 void GenPspGraphics::copyBits( const SalTwoRect&,
499 SalGraphics* )
501 OSL_FAIL( "Error: PrinterGfx::CopyBits() not implemented" );
504 void GenPspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 )
506 OSL_FAIL( "Error: PrinterGfx::CopyArea() not implemented" );
509 void GenPspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
511 Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY),
512 Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
513 Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY),
514 Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight));
516 BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(BITMAP_READ_ACCESS);
518 SalPrinterBmp aBmp (pBuffer);
519 m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp);
521 const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, BITMAP_READ_ACCESS);
524 void GenPspGraphics::drawBitmap( const SalTwoRect&,
525 const SalBitmap&,
526 const SalBitmap& )
528 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap");
531 void GenPspGraphics::drawBitmap( const SalTwoRect&,
532 const SalBitmap&,
533 SalColor )
535 OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent color");
538 void GenPspGraphics::drawMask( const SalTwoRect&,
539 const SalBitmap &,
540 SalColor )
542 OSL_FAIL("Error: PrinterGfx::DrawMask() not implemented");
545 SalBitmap* GenPspGraphics::getBitmap( long, long, long, long )
547 DBG_WARNING ("Warning: PrinterGfx::GetBitmap() not implemented");
548 return NULL;
551 SalColor GenPspGraphics::getPixel( long, long )
553 OSL_FAIL("Warning: PrinterGfx::GetPixel() not implemented");
554 return 0;
557 void GenPspGraphics::invert(long,long,long,long,SalInvert)
559 OSL_FAIL("Warning: PrinterGfx::Invert() not implemented");
562 class ImplPspFontData : public PhysicalFontFace
564 private:
565 enum { PSPFD_MAGIC = 0xb5bf01f0 };
566 sal_IntPtr mnFontId;
568 public:
569 ImplPspFontData( const psp::FastPrintFontInfo& );
570 virtual sal_IntPtr GetFontId() const SAL_OVERRIDE { return mnFontId; }
571 virtual PhysicalFontFace* Clone() const SAL_OVERRIDE { return new ImplPspFontData( *this ); }
572 virtual ImplFontEntry* CreateFontInstance( FontSelectPattern& ) const SAL_OVERRIDE;
575 ImplPspFontData::ImplPspFontData( const psp::FastPrintFontInfo& rInfo )
576 : PhysicalFontFace( GenPspGraphics::Info2DevFontAttributes(rInfo), PSPFD_MAGIC ),
577 mnFontId( rInfo.m_nID )
580 ImplFontEntry* ImplPspFontData::CreateFontInstance( FontSelectPattern& rFSD ) const
582 ImplServerFontEntry* pEntry = new ImplServerFontEntry( rFSD );
583 return pEntry;
586 class PspFontLayout : public GenericSalLayout
588 public:
589 PspFontLayout( ::psp::PrinterGfx& );
590 virtual bool LayoutText( ImplLayoutArgs& ) SAL_OVERRIDE;
591 virtual void InitFont() const SAL_OVERRIDE;
592 virtual void DrawText( SalGraphics& ) const SAL_OVERRIDE;
593 private:
594 ::psp::PrinterGfx& mrPrinterGfx;
595 sal_IntPtr mnFontID;
596 int mnFontHeight;
597 int mnFontWidth;
598 bool mbVertical;
599 bool mbArtItalic;
600 bool mbArtBold;
603 PspFontLayout::PspFontLayout( ::psp::PrinterGfx& rGfx )
604 : mrPrinterGfx( rGfx )
606 mnFontID = mrPrinterGfx.GetFontID();
607 mnFontHeight = mrPrinterGfx.GetFontHeight();
608 mnFontWidth = mrPrinterGfx.GetFontWidth();
609 mbVertical = mrPrinterGfx.GetFontVertical();
610 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
611 mbArtBold = mrPrinterGfx.GetArtificialBold();
614 bool PspFontLayout::LayoutText( ImplLayoutArgs& rArgs )
616 mbVertical = bool(rArgs.mnFlags & SalLayoutFlags::Vertical);
618 long nUnitsPerPixel = 1;
619 sal_GlyphId aOldGlyphId( GF_DROPPED);
620 long nGlyphWidth = 0;
621 int nCharPos = -1;
622 Point aNewPos( 0, 0 );
623 GlyphItem aPrevItem;
624 rtl_TextEncoding aFontEnc = mrPrinterGfx.GetFontMgr().getFontEncoding( mnFontID );
626 Reserve(rArgs.mnLength);
628 for(;;)
630 bool bRightToLeft;
631 if( !rArgs.GetNextPos( &nCharPos, &bRightToLeft ) )
632 break;
634 sal_Unicode cChar = rArgs.mpStr[ nCharPos ];
635 if( bRightToLeft )
636 cChar = GetMirroredChar( cChar );
637 // symbol font aliasing: 0x0020-0x00ff -> 0xf020 -> 0xf0ff
638 if( aFontEnc == RTL_TEXTENCODING_SYMBOL )
639 if( cChar < 256 )
640 cChar += 0xf000;
641 sal_GlyphId aGlyphId( cChar); // printer glyphs = unicode
643 // update fallback_runs if needed
644 psp::CharacterMetric aMetric;
645 // coverity[callee_ptr_arith]
646 mrPrinterGfx.GetFontMgr().getMetrics( mnFontID, cChar, cChar, &aMetric, mbVertical );
647 if( aMetric.width == -1 && aMetric.height == -1 )
648 rArgs.NeedFallback( nCharPos, bRightToLeft );
650 // finish previous glyph
651 if( aOldGlyphId != GF_DROPPED )
652 AppendGlyph( aPrevItem );
653 aOldGlyphId = aGlyphId;
654 aNewPos.X() += nGlyphWidth;
656 // prepare GlyphItem for appending it in next round
657 nUnitsPerPixel = mrPrinterGfx.GetCharWidth( cChar, cChar, &nGlyphWidth );
658 int nGlyphFlags = bRightToLeft ? GlyphItem::IS_RTL_GLYPH : 0;
659 aGlyphId |= GF_ISCHAR;
660 aPrevItem = GlyphItem( nCharPos, aGlyphId, aNewPos, nGlyphFlags, nGlyphWidth );
663 // append last glyph item if any
664 if( aOldGlyphId != GF_DROPPED )
665 AppendGlyph( aPrevItem );
667 SetOrientation( mrPrinterGfx.GetFontAngle() );
668 SetUnitsPerPixel( nUnitsPerPixel );
669 return (aOldGlyphId != GF_DROPPED);
672 class PspServerFontLayout : public ServerFontLayout
674 public:
675 PspServerFontLayout( psp::PrinterGfx&, ServerFont& rFont, const ImplLayoutArgs& rArgs );
677 virtual void InitFont() const SAL_OVERRIDE;
678 const sal_Unicode* getTextPtr() const { return maText.getStr() - mnMinCharPos; }
679 int getMinCharPos() const { return mnMinCharPos; }
680 int getMaxCharPos() const { return mnMinCharPos+maText.getLength()-1; }
681 private:
682 ::psp::PrinterGfx& mrPrinterGfx;
683 sal_IntPtr mnFontID;
684 int mnFontHeight;
685 int mnFontWidth;
686 bool mbVertical;
687 bool mbArtItalic;
688 bool mbArtBold;
689 OUString maText;
690 int mnMinCharPos;
693 PspServerFontLayout::PspServerFontLayout( ::psp::PrinterGfx& rGfx, ServerFont& rFont, const ImplLayoutArgs& rArgs )
694 : ServerFontLayout( rFont ),
695 mrPrinterGfx( rGfx )
697 mnFontID = mrPrinterGfx.GetFontID();
698 mnFontHeight = mrPrinterGfx.GetFontHeight();
699 mnFontWidth = mrPrinterGfx.GetFontWidth();
700 mbVertical = mrPrinterGfx.GetFontVertical();
701 mbArtItalic = mrPrinterGfx.GetArtificialItalic();
702 mbArtBold = mrPrinterGfx.GetArtificialBold();
703 maText = OUString( rArgs.mpStr + rArgs.mnMinCharPos, rArgs.mnEndCharPos - rArgs.mnMinCharPos+1 );
704 mnMinCharPos = rArgs.mnMinCharPos;
707 void PspServerFontLayout::InitFont() const
709 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
710 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
713 static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout )
715 const int nMaxGlyphs = 200;
716 sal_GlyphId aGlyphAry[ nMaxGlyphs ];
717 DeviceCoordinate aWidthAry[ nMaxGlyphs ];
718 sal_Int32 aIdxAry [ nMaxGlyphs ];
719 sal_Unicode aUnicodes[ nMaxGlyphs ];
720 int aCharPosAry [ nMaxGlyphs ];
722 Point aPos;
723 long nUnitsPerPixel = rLayout.GetUnitsPerPixel();
724 const sal_Unicode* pText = NULL;
725 int nMinCharPos = 0;
726 int nMaxCharPos = 0;
727 if (bIsPspServerFontLayout)
729 const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout);
730 #if ENABLE_GRAPHITE
731 const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout);
732 #endif
733 if (pPspLayout)
735 pText = pPspLayout->getTextPtr();
736 nMinCharPos = pPspLayout->getMinCharPos();
737 nMaxCharPos = pPspLayout->getMaxCharPos();
739 #if ENABLE_GRAPHITE
740 else if (pGrLayout)
743 #endif
745 for( int nStart = 0;; )
747 int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : NULL );
748 if( !nGlyphCount )
749 break;
751 DeviceCoordinate nXOffset = 0;
752 for( int i = 0; i < nGlyphCount; ++i )
754 nXOffset += aWidthAry[ i ];
755 aIdxAry[ i ] = nXOffset / nUnitsPerPixel;
756 sal_GlyphId aGlyphId = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK);
757 if( pText )
758 aUnicodes[i] = (aCharPosAry[i] >= nMinCharPos && aCharPosAry[i] <= nMaxCharPos) ? pText[ aCharPosAry[i] ] : 0;
759 else
760 aUnicodes[i] = (aGlyphAry[i] & GF_ISCHAR) ? aGlyphId : 0;
761 aGlyphAry[i] = aGlyphId;
764 rGfx.DrawGlyphs( aPos, aGlyphAry, aUnicodes, nGlyphCount, aIdxAry );
768 void PspFontLayout::InitFont() const
770 mrPrinterGfx.SetFont( mnFontID, mnFontHeight, mnFontWidth,
771 mnOrientation, mbVertical, mbArtItalic, mbArtBold );
774 void PspFontLayout::DrawText( SalGraphics& ) const
776 DrawPrinterLayout( *this, mrPrinterGfx, false );
779 void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
781 // print complex text
782 DrawPrinterLayout( rLayout, *m_pPrinterGfx, true );
785 const FontCharMapPtr GenPspGraphics::GetFontCharMap() const
787 if( !m_pServerFont[0] )
788 return NULL;
790 const FontCharMapPtr pFCMap = m_pServerFont[0]->GetFontCharMap();
791 return pFCMap;
794 bool GenPspGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
796 if (!m_pServerFont[0])
797 return false;
798 return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities);
801 sal_uInt16 GenPspGraphics::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
803 // release all fonts that are to be overridden
804 for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
806 if( m_pServerFont[i] != NULL )
808 // old server side font is no longer referenced
809 GlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] );
810 m_pServerFont[i] = NULL;
814 // return early if there is no new font
815 if( !pEntry )
816 return 0;
818 sal_IntPtr nID = pEntry->mpFontData ? pEntry->mpFontData->GetFontId() : 0;
820 // determine which font attributes need to be emulated
821 bool bArtItalic = false;
822 bool bArtBold = false;
823 if( pEntry->GetSlant() == ITALIC_OBLIQUE || pEntry->GetSlant() == ITALIC_NORMAL )
825 FontItalic eItalic = m_pPrinterGfx->GetFontMgr().getFontItalic( nID );
826 if( eItalic != ITALIC_NORMAL && eItalic != ITALIC_OBLIQUE )
827 bArtItalic = true;
829 int nWeight = (int)pEntry->GetWeight();
830 int nRealWeight = (int)m_pPrinterGfx->GetFontMgr().getFontWeight( nID );
831 if( nRealWeight <= (int)WEIGHT_MEDIUM && nWeight > (int)WEIGHT_MEDIUM )
833 bArtBold = true;
836 // also set the serverside font for layouting
837 m_bFontVertical = pEntry->mbVertical;
838 if( pEntry->mpFontData )
840 // requesting a font provided by builtin rasterizer
841 ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
842 if( pServerFont != NULL )
844 if( pServerFont->TestFont() )
845 m_pServerFont[ nFallbackLevel ] = pServerFont;
846 else
847 GlyphCache::GetInstance().UncacheFont( *pServerFont );
851 // set the printer font
852 return m_pPrinterGfx->SetFont( nID,
853 pEntry->mnHeight,
854 pEntry->mnWidth,
855 pEntry->mnOrientation,
856 pEntry->mbVertical,
857 bArtItalic,
858 bArtBold
862 void GenPspGraphics::SetTextColor( SalColor nSalColor )
864 psp::PrinterColor aColor (SALCOLOR_RED (nSalColor),
865 SALCOLOR_GREEN (nSalColor),
866 SALCOLOR_BLUE (nSalColor));
867 m_pPrinterGfx->SetTextColor (aColor);
870 bool GenPspGraphics::AddTempDevFont( PhysicalFontCollection*, const OUString&,const OUString& )
872 return false;
875 void GenPspGraphics::GetDevFontList( PhysicalFontCollection *pFontCollection )
877 ::std::list< psp::fontID > aList;
878 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
879 rMgr.getFontList( aList );
881 ::std::list< psp::fontID >::iterator it;
882 psp::FastPrintFontInfo aInfo;
883 for (it = aList.begin(); it != aList.end(); ++it)
884 if (rMgr.getFontFastInfo (*it, aInfo))
885 AnnounceFonts( pFontCollection, aInfo );
887 // register platform specific font substitutions if available
888 SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
891 void GenPspGraphics::ClearDevFontCache()
893 GlyphCache::GetInstance().ClearFontCache();
896 void GenPspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int )
898 const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
899 psp::PrintFontInfo aInfo;
901 if (rMgr.getFontInfo (m_pPrinterGfx->GetFontID(), aInfo))
903 ImplDevFontAttributes aDFA = Info2DevFontAttributes( aInfo );
904 static_cast<ImplFontAttributes&>(*pMetric) = aDFA;
905 pMetric->mbDevice = aDFA.mbDevice;
906 pMetric->mbScalableFont = true;
908 pMetric->mnOrientation = m_pPrinterGfx->GetFontAngle();
909 pMetric->mnSlant = 0;
911 sal_Int32 nTextHeight = m_pPrinterGfx->GetFontHeight();
912 sal_Int32 nTextWidth = m_pPrinterGfx->GetFontWidth();
913 if( ! nTextWidth )
914 nTextWidth = nTextHeight;
916 pMetric->mnWidth = nTextWidth;
917 pMetric->mnAscent = ( aInfo.m_nAscend * nTextHeight + 500 ) / 1000;
918 pMetric->mnDescent = ( aInfo.m_nDescend * nTextHeight + 500 ) / 1000;
919 pMetric->mnIntLeading = ( aInfo.m_nLeading * nTextHeight + 500 ) / 1000;
920 pMetric->mnExtLeading = 0;
924 bool GenPspGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
926 const int nLevel = aGlyphId >> GF_FONTSHIFT;
927 if( nLevel >= MAX_FALLBACK )
928 return false;
930 ServerFont* pSF = m_pServerFont[ nLevel ];
931 if( !pSF )
932 return false;
934 aGlyphId &= GF_IDXMASK;
935 const GlyphMetric& rGM = pSF->GetGlyphMetric( aGlyphId );
936 rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() );
937 return true;
940 bool GenPspGraphics::GetGlyphOutline( sal_GlyphId aGlyphId,
941 ::basegfx::B2DPolyPolygon& rB2DPolyPoly )
943 const int nLevel = aGlyphId >> GF_FONTSHIFT;
944 if( nLevel >= MAX_FALLBACK )
945 return false;
947 ServerFont* pSF = m_pServerFont[ nLevel ];
948 if( !pSF )
949 return false;
951 aGlyphId &= GF_IDXMASK;
952 if( pSF->GetGlyphOutline( aGlyphId, rB2DPolyPoly ) )
953 return true;
955 return false;
958 SalLayout* GenPspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
960 // workaround for printers not handling glyph indexing for non-TT fonts
961 int nFontId = m_pPrinterGfx->GetFontID();
962 if( psp::fonttype::TrueType != psp::PrintFontManager::get().getFontType( nFontId ) )
963 rArgs.mnFlags |= SalLayoutFlags::DisableGlyphProcessing;
964 else if( nFallbackLevel > 0 )
965 rArgs.mnFlags &= ~SalLayoutFlags::DisableGlyphProcessing;
967 GenericSalLayout* pLayout = NULL;
969 if( m_pServerFont[ nFallbackLevel ]
970 && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
972 #if ENABLE_GRAPHITE
973 // Is this a Graphite font?
974 if (GraphiteServerFontLayout::IsGraphiteEnabledFont(*m_pServerFont[nFallbackLevel]))
976 pLayout = new GraphiteServerFontLayout(*m_pServerFont[nFallbackLevel]);
978 else
979 #endif
980 pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs );
982 else
983 pLayout = new PspFontLayout( *m_pPrinterGfx );
985 return pLayout;
988 bool GenPspGraphics::CreateFontSubset(
989 const OUString& rToFile,
990 const PhysicalFontFace* pFont,
991 const sal_GlyphId* pGlyphIds,
992 const sal_uInt8* pEncoding,
993 sal_Int32* pWidths,
994 int nGlyphCount,
995 FontSubsetInfo& rInfo
998 // in this context the pFont->GetFontId() is a valid PSP
999 // font since they are the only ones left after the PDF
1000 // export has filtered its list of subsettable fonts (for
1001 // which this method was created). The correct way would
1002 // be to have the GlyphCache search for the PhysicalFontFace pFont
1003 psp::fontID aFont = pFont->GetFontId();
1005 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1006 bool bSuccess = rMgr.createFontSubset( rInfo,
1007 aFont,
1008 rToFile,
1009 pGlyphIds,
1010 pEncoding,
1011 pWidths,
1012 nGlyphCount );
1013 return bSuccess;
1016 const Ucs2SIntMap* GenPspGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded, std::set<sal_Unicode> const** ppPriority)
1018 // in this context the pFont->GetFontId() is a valid PSP
1019 // font since they are the only ones left after the PDF
1020 // export has filtered its list of subsettable fonts (for
1021 // which this method was created). The correct way would
1022 // be to have the GlyphCache search for the PhysicalFontFace pFont
1023 psp::fontID aFont = pFont->GetFontId();
1024 return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded, ppPriority );
1027 void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
1028 bool bVertical,
1029 Int32Vector& rWidths,
1030 Ucs2UIntMap& rUnicodeEnc )
1032 // in this context the pFont->GetFontId() is a valid PSP
1033 // font since they are the only ones left after the PDF
1034 // export has filtered its list of subsettable fonts (for
1035 // which this method was created). The correct way would
1036 // be to have the GlyphCache search for the PhysicalFontFace pFont
1037 psp::fontID aFont = pFont->GetFontId();
1038 GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1041 const Ucs2SIntMap* GenPspGraphics::DoGetFontEncodingVector( fontID aFont, const Ucs2OStrMap** pNonEncoded, std::set<sal_Unicode> const** ppPriority)
1043 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1045 psp::PrintFontInfo aFontInfo;
1046 if( ! rMgr.getFontInfo( aFont, aFontInfo ) )
1048 if( pNonEncoded )
1049 *pNonEncoded = NULL;
1050 return NULL;
1053 return rMgr.getEncodingMap( aFont, pNonEncoded, ppPriority );
1056 void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont,
1057 bool bVertical,
1058 Int32Vector& rWidths,
1059 Ucs2UIntMap& rUnicodeEnc )
1061 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1062 rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
1065 ImplDevFontAttributes GenPspGraphics::Info2DevFontAttributes( const psp::FastPrintFontInfo& rInfo )
1067 ImplDevFontAttributes aDFA;
1068 aDFA.SetFamilyName( rInfo.m_aFamilyName );
1069 aDFA.SetStyleName( rInfo.m_aStyleName );
1070 aDFA.SetFamilyType( rInfo.m_eFamilyStyle );
1071 aDFA.SetWeight( rInfo.m_eWeight );
1072 aDFA.SetItalic( rInfo.m_eItalic );
1073 aDFA.SetWidthType( rInfo.m_eWidth );
1074 aDFA.SetPitch( rInfo.m_ePitch );
1075 aDFA.SetSymbolFlag( (rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL) );
1076 aDFA.mbSubsettable = rInfo.m_bSubsettable;
1077 aDFA.mbEmbeddable = rInfo.m_bEmbeddable;
1079 switch( rInfo.m_eType )
1081 case psp::fonttype::TrueType:
1082 aDFA.mnQuality = 512;
1083 aDFA.mbDevice = false;
1084 break;
1085 case psp::fonttype::Type1:
1086 aDFA.mnQuality = 0;
1087 aDFA.mbDevice = false;
1088 break;
1089 default:
1090 aDFA.mnQuality = 0;
1091 aDFA.mbDevice = false;
1092 break;
1095 aDFA.mbOrientation = true;
1097 // add font family name aliases
1098 ::std::list< OUString >::const_iterator it = rInfo.m_aAliases.begin();
1099 bool bHasMapNames = false;
1100 for(; it != rInfo.m_aAliases.end(); ++it )
1102 if( bHasMapNames )
1103 aDFA.maMapNames += OUString(';');
1104 aDFA.maMapNames += *it;
1105 bHasMapNames = true;
1108 #if OSL_DEBUG_LEVEL > 2
1109 if( bHasMapNames )
1111 OString aOrigName(OUStringToOString(aDFA.GetFamilyName(), osl_getThreadTextEncoding()));
1112 OString aAliasNames(OUStringToOString(aDFA.GetAliasNames(), osl_getThreadTextEncoding()));
1113 SAL_INFO( "vcl.fonts", "using alias names " << aAliasNames.getStr() << " for font family " << aOrigName.getStr() );
1115 #endif
1117 return aDFA;
1120 namespace vcl
1122 const char* getLangBoost()
1124 const char* pLangBoost;
1125 const LanguageType eLang = Application::GetSettings().GetUILanguageTag().getLanguageType();
1126 if (eLang == LANGUAGE_JAPANESE)
1127 pLangBoost = "jan";
1128 else if (MsLangId::isKorean(eLang))
1129 pLangBoost = "kor";
1130 else if (MsLangId::isSimplifiedChinese(eLang))
1131 pLangBoost = "zhs";
1132 else if (MsLangId::isTraditionalChinese(eLang))
1133 pLangBoost = "zht";
1134 else
1135 pLangBoost = NULL;
1136 return pLangBoost;
1140 void GenPspGraphics::AnnounceFonts( PhysicalFontCollection* pFontCollection, const psp::FastPrintFontInfo& aInfo )
1142 int nQuality = 0;
1144 if( aInfo.m_eType == psp::fonttype::TrueType )
1146 // asian type 1 fonts are not known
1147 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1148 OString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) );
1149 int nPos = aFileName.lastIndexOf( '_' );
1150 if( nPos == -1 || aFileName[nPos+1] == '.' )
1151 nQuality += 5;
1152 else
1154 static const char* pLangBoost = NULL;
1155 static bool bOnce = true;
1156 if( bOnce )
1158 bOnce = false;
1159 pLangBoost = vcl::getLangBoost();
1162 if( pLangBoost )
1163 if( aFileName.copy( nPos+1, 3 ).equalsIgnoreAsciiCase( pLangBoost ) )
1164 nQuality += 10;
1168 ImplPspFontData* pFD = new ImplPspFontData( aInfo );
1169 pFD->mnQuality += nQuality;
1170 pFontCollection->Add( pFD );
1173 bool GenPspGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& )
1175 return false;
1178 bool GenPspGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& )
1180 return false;
1183 bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&,
1184 const SalBitmap&,
1185 const SalBitmap& )
1187 return false;
1190 bool GenPspGraphics::drawTransformedBitmap(
1191 const basegfx::B2DPoint& rNull,
1192 const basegfx::B2DPoint& rX,
1193 const basegfx::B2DPoint& rY,
1194 const SalBitmap& rSourceBitmap,
1195 const SalBitmap* pAlphaBitmap)
1197 // here direct support for transformed bitmaps can be implemented
1198 (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
1199 return false;
1202 bool GenPspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 )
1204 return false;
1207 SystemGraphicsData GenPspGraphics::GetGraphicsData() const
1209 return SystemGraphicsData();
1212 bool GenPspGraphics::SupportsCairo() const
1214 return false;
1217 cairo::SurfaceSharedPtr GenPspGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& /*rSurface*/) const
1219 return cairo::SurfaceSharedPtr();
1222 cairo::SurfaceSharedPtr GenPspGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int /*x*/, int /*y*/, int /*width*/, int /*height*/) const
1224 return cairo::SurfaceSharedPtr();
1227 cairo::SurfaceSharedPtr GenPspGraphics::CreateBitmapSurface(const OutputDevice& /*rRefDevice*/, const BitmapSystemData& /*rData*/, const Size& /*rSize*/) const
1229 return cairo::SurfaceSharedPtr();
1232 css::uno::Any GenPspGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& /*rSurface*/, const basegfx::B2ISize& /*rSize*/) const
1234 return css::uno::Any();
1237 SystemFontData GenPspGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
1239 return SystemFontData();
1242 bool GenPspGraphics::supportsOperation( OutDevSupportType ) const
1244 return false;
1247 void GenPspGraphics::DoFreeEmbedFontData( const void* pData, long nLen )
1249 #if defined( UNX )
1250 if( pData )
1251 munmap( const_cast<void *>(pData), nLen );
1252 #else
1253 (void)nLen;
1254 rtl_freeMemory( (void *)pData );
1255 #endif
1258 const void* GenPspGraphics::DoGetEmbedFontData( psp::fontID aFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, size_t nLen, FontSubsetInfo& rInfo, long* pDataLen )
1261 psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
1263 psp::PrintFontInfo aFontInfo;
1264 if( ! rMgr.getFontInfo( aFont, aFontInfo ) )
1265 return NULL;
1267 // fill in font info
1268 rInfo.m_nAscent = aFontInfo.m_nAscend;
1269 rInfo.m_nDescent = aFontInfo.m_nDescend;
1270 rInfo.m_aPSName = rMgr.getPSName( aFont );
1272 int xMin, yMin, xMax, yMax;
1273 rMgr.getFontBoundingBox( aFont, xMin, yMin, xMax, yMax );
1275 std::vector<psp::CharacterMetric> aMetrics(nLen);
1276 sal_Ucs aUnicodes[nLen];
1277 if( aFontInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL && aFontInfo.m_eType == psp::fonttype::Type1 )
1279 for (size_t i = 0; i < nLen; ++i)
1280 aUnicodes[i] = pUnicodes[i] < 0x0100 ? pUnicodes[i] + 0xf000 : pUnicodes[i];
1281 pUnicodes = aUnicodes;
1283 if (!rMgr.getMetrics(aFont, pUnicodes, nLen, aMetrics.data()))
1284 return NULL;
1286 OString aSysPath = rMgr.getFontFileSysPath( aFont );
1288 #if defined( UNX )
1289 int fd = open( aSysPath.getStr(), O_RDONLY );
1290 if( fd < 0 )
1291 return NULL;
1292 struct stat aStat;
1293 if( fstat( fd, &aStat ) )
1295 close( fd );
1296 return NULL;
1298 void* pFile = mmap( NULL, aStat.st_size, PROT_READ, MAP_SHARED, fd, 0 );
1299 close( fd );
1300 if( pFile == MAP_FAILED )
1301 return NULL;
1302 *pDataLen = aStat.st_size;
1303 #else
1304 // FIXME: test me ! ...
1305 OUString aURL;
1306 if( osl::File::getFileURLFromSystemPath( OStringToOUString( aSysPath, osl_getThreadTextEncoding() ), aURL ) != osl::File::E_None )
1307 return NULL;
1308 osl::File aFile( aURL );
1309 if( aFile.open( osl_File_OpenFlag_Read | osl_File_OpenFlag_NoLock ) != osl::File::E_None )
1310 return NULL;
1312 osl::DirectoryItem aItem;
1313 osl::DirectoryItem::get( aURL, aItem );
1314 osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileSize );
1315 aItem.getFileStatus( aFileStatus );
1317 void *pFile = rtl_allocateMemory( aFileStatus.getFileSize() );
1318 sal_uInt64 nRead = 0;
1319 aFile.read( pFile, aFileStatus.getFileSize(), nRead );
1320 *pDataLen = (long) nRead;
1321 #endif
1323 rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) );
1324 rInfo.m_nCapHeight = yMax; // Well ...
1326 for (size_t i = 0; i < nLen; ++i)
1327 pWidths[i] = (aMetrics[i].width > 0 ? aMetrics[i].width : 0);
1329 switch( aFontInfo.m_eType )
1331 case psp::fonttype::TrueType:
1332 rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
1333 break;
1334 case psp::fonttype::Type1: {
1335 const bool bPFA = *static_cast<unsigned char*>(pFile) < 0x80;
1336 rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB;
1338 break;
1339 default:
1340 DoFreeEmbedFontData( pFile, *pDataLen );
1341 return NULL;
1344 return pFile;
1347 void GenPspGraphics::FreeEmbedFontData( const void* pData, long nLen )
1349 DoFreeEmbedFontData( pData, nLen );
1352 const void* GenPspGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, size_t nLen, FontSubsetInfo& rInfo, long* pDataLen )
1354 // in this context the pFont->GetFontId() is a valid PSP
1355 // font since they are the only ones left after the PDF
1356 // export has filtered its list of subsettable fonts (for
1357 // which this method was created). The correct way would
1358 // be to have the GlyphCache search for the PhysicalFontFace pFont
1359 psp::fontID aFont = pFont->GetFontId();
1360 return DoGetEmbedFontData(aFont, pUnicodes, pWidths, nLen, rInfo, pDataLen);
1363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */