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