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