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