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