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