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