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 : #include "headless/svpgdi.hxx"
21 : #include "headless/svpbmp.hxx"
22 : #include "saldatabasic.hxx"
23 :
24 : #include <vcl/sysdata.hxx>
25 : #include <basegfx/range/b2drange.hxx>
26 : #include <basegfx/range/b2ibox.hxx>
27 : #include <basegfx/polygon/b2dpolypolygon.hxx>
28 : #include <basegfx/polygon/b2dpolygon.hxx>
29 : #include <basegfx/polygon/b2dpolygontools.hxx>
30 : #include <basebmp/scanlineformats.hxx>
31 :
32 : #if OSL_DEBUG_LEVEL > 2
33 : #include <basebmp/debug.hxx>
34 : #include <fstream>
35 : #include <rtl/strbuf.hxx>
36 : #include <sys/stat.h>
37 : #endif
38 :
39 : #include <stdio.h>
40 :
41 9795703 : inline void dbgOut( const basebmp::BitmapDeviceSharedPtr&
42 : #if OSL_DEBUG_LEVEL > 2
43 : rDevice
44 : #endif
45 : )
46 : {
47 : #if OSL_DEBUG_LEVEL > 2
48 : static int dbgStreamNum = 0;
49 : OStringBuffer aBuf( 256 );
50 : aBuf.append( "debug" );
51 : mkdir( aBuf.getStr(), 0777 );
52 : aBuf.append( "/" );
53 : aBuf.append( sal_Int64(reinterpret_cast<sal_IntPtr>(rDevice.get())), 16 );
54 : mkdir( aBuf.getStr(), 0777 );
55 : aBuf.append( "/bmp" );
56 : aBuf.append( sal_Int32(dbgStreamNum++) );
57 : std::fstream bmpstream( aBuf.getStr(), std::ios::out );
58 : debugDump( rDevice, bmpstream );
59 : #endif
60 9795703 : }
61 :
62 : #ifndef IOS
63 :
64 211722 : bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ )
65 : {
66 : // TODO(P3) implement alpha blending
67 211722 : return false;
68 : }
69 :
70 34 : bool SvpSalGraphics::drawTransformedBitmap(
71 : const basegfx::B2DPoint& rNull,
72 : const basegfx::B2DPoint& rX,
73 : const basegfx::B2DPoint& rY,
74 : const SalBitmap& rSourceBitmap,
75 : const SalBitmap* pAlphaBitmap)
76 : {
77 : // here direct support for transformed bitmaps can be impemented
78 : (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
79 34 : return false;
80 : }
81 :
82 32 : bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
83 : {
84 : // TODO(P3) implement alpha blending
85 32 : return false;
86 : }
87 :
88 628432 : SvpSalGraphics::SvpSalGraphics() :
89 : m_bUseLineColor( true ),
90 : m_aLineColor( COL_BLACK ),
91 : m_bUseFillColor( false ),
92 : m_aFillColor( COL_WHITE ),
93 : m_aDrawMode( basebmp::DrawMode_PAINT ),
94 : m_aTextColor( COL_BLACK ),
95 : m_eTextFmt( basebmp::FORMAT_EIGHT_BIT_GREY ),
96 628432 : m_bClipSetup( false )
97 : {
98 10683344 : for( int i = 0; i < MAX_FALLBACK; ++i )
99 10054912 : m_pServerFont[i] = NULL;
100 628432 : }
101 :
102 1255288 : SvpSalGraphics::~SvpSalGraphics()
103 : {
104 1255288 : }
105 :
106 721655 : void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice )
107 : {
108 721655 : m_aOrigDevice = rDevice;
109 721655 : ResetClipRegion();
110 :
111 : // determine matching bitmap format for masks
112 721655 : basebmp::Format nDeviceFmt = m_aDevice ? m_aDevice->getScanlineFormat() : basebmp::FORMAT_EIGHT_BIT_GREY;
113 721655 : switch( nDeviceFmt )
114 : {
115 : case basebmp::FORMAT_EIGHT_BIT_GREY:
116 : case basebmp::FORMAT_SIXTEEN_BIT_LSB_TC_MASK:
117 : case basebmp::FORMAT_SIXTEEN_BIT_MSB_TC_MASK:
118 : case basebmp::FORMAT_TWENTYFOUR_BIT_TC_MASK:
119 : case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
120 : case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
121 : case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
122 : case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
123 700987 : m_eTextFmt = basebmp::FORMAT_EIGHT_BIT_GREY;
124 700987 : break;
125 : default:
126 20668 : m_eTextFmt = basebmp::FORMAT_ONE_BIT_LSB_GREY;
127 20668 : break;
128 : }
129 721655 : }
130 :
131 : #endif
132 :
133 6124 : void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
134 : {
135 6124 : rDPIX = rDPIY = 96;
136 6124 : }
137 :
138 : #ifndef IOS
139 :
140 409459 : sal_uInt16 SvpSalGraphics::GetBitCount() const
141 : {
142 409459 : return SvpSalBitmap::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
143 : }
144 :
145 469 : long SvpSalGraphics::GetGraphicsWidth() const
146 : {
147 469 : if( m_aDevice.get() )
148 : {
149 469 : basegfx::B2IVector aSize = m_aOrigDevice->getSize();
150 469 : return aSize.getX();
151 : }
152 0 : return 0;
153 : }
154 :
155 732506 : void SvpSalGraphics::ResetClipRegion()
156 : {
157 732506 : m_aDevice = m_aOrigDevice;
158 732506 : m_aClipMap.reset();
159 732506 : m_bClipSetup = true;
160 732506 : m_aClipRegion.SetNull();
161 732506 : }
162 :
163 : // verify clip for the whole area is setup
164 9358608 : void SvpSalGraphics::ensureClip()
165 : {
166 9358608 : if (m_bClipSetup)
167 18689201 : return;
168 :
169 28015 : m_aDevice = m_aOrigDevice;
170 28015 : basegfx::B2IVector aSize = m_aDevice->getSize();
171 28015 : m_aClipMap = basebmp::createClipDevice( aSize );
172 :
173 56030 : RectangleVector aRectangles;
174 28015 : m_aClipRegion.GetRegionRectangles(aRectangles);
175 :
176 134698 : for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
177 : {
178 106683 : const long nW(aRectIter->GetWidth());
179 106683 : if(nW)
180 : {
181 106683 : const long nH(aRectIter->GetHeight());
182 :
183 106683 : if(nH)
184 : {
185 106683 : basegfx::B2DPolyPolygon aFull;
186 :
187 : aFull.append(
188 : basegfx::tools::createPolygonFromRect(
189 : basegfx::B2DRectangle(
190 106683 : aRectIter->Left(),
191 106683 : aRectIter->Top(),
192 106683 : aRectIter->Left() + nW,
193 426732 : aRectIter->Top() + nH)));
194 106683 : m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), basebmp::DrawMode_PAINT);
195 : }
196 : }
197 : }
198 56030 : m_bClipSetup = true;
199 : }
200 :
201 7924998 : SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
202 : {
203 3962499 : if( m_aDevice.get() )
204 594 : m_rGfx.m_aDevice = m_aDevice;
205 3962499 : }
206 :
207 : // setup a clip rectangle -only- iff we have to; if aRange
208 : // is entirely contained inside an existing clip frame, we
209 : // will avoid setting up the clip bitmap. Similarly if the
210 : // range doesn't appear at all we return true to avoid
211 : // rendering
212 3962499 : bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox &aRange, SvpSalGraphics::ClipUndoHandle &rUndo )
213 : {
214 3962499 : if( m_bClipSetup )
215 3929690 : return false;
216 :
217 32809 : if( m_aClipRegion.IsEmpty() ) // no clipping
218 0 : return false;
219 :
220 : // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
221 : // aRange.getMinX(), aRange.getMinY(),
222 : // (int)aRange.getWidth(), (int)aRange.getHeight() );
223 :
224 : // first see if aRange is purely internal to one of the clip regions
225 65618 : Rectangle aRect( Point( aRange.getMinX(), aRange.getMinY() ),
226 98427 : Size( aRange.getWidth(), aRange.getHeight() ) );
227 :
228 : // then see if we are overlapping with just one
229 32809 : int nHit = 0;
230 32809 : Rectangle aHitRect;
231 32809 : RectangleVector aRectangles;
232 32809 : m_aClipRegion.GetRegionRectangles(aRectangles);
233 163450 : for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
234 : {
235 130641 : if( aRectIter->IsOver( aRect ) )
236 : {
237 10905 : aHitRect = *aRectIter;
238 10905 : nHit++;
239 : }
240 : }
241 :
242 32809 : if( nHit == 0 ) // rendering outside any clipping region
243 : {
244 : // fprintf (stderr, "denegerate case detected ...\n");
245 22314 : return true;
246 : }
247 10495 : else if( nHit == 1 ) // common path: rendering against just one clipping region
248 : {
249 10281 : if( aHitRect.IsInside( aRect ) )
250 : {
251 : // fprintf (stderr, " is inside ! avoid deeper clip ...\n");
252 9687 : return false;
253 : }
254 : // fprintf (stderr, " operation only overlaps with a single clip zone\n" );
255 594 : rUndo.m_aDevice = m_aDevice;
256 2970 : m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
257 594 : basegfx::B2IBox (aHitRect.Left(),
258 594 : aHitRect.Top(),
259 594 : aHitRect.Right() + 1,
260 1188 : aHitRect.Bottom() + 1) );
261 594 : return false;
262 : }
263 : // fprintf (stderr, "URK: complex & slow clipping case\n" );
264 : // horribly slow & complicated case ...
265 :
266 214 : ensureClip();
267 214 : return false;
268 : }
269 :
270 : // Clipping by creating unconditional mask bitmaps is horribly
271 : // slow so defer it, as much as possible. It is common to get
272 : // 3 rectangles pushed, and have to create a vast off-screen
273 : // mask only to destroy it shortly afterwards. That is
274 : // particularly galling if we render only to a small,
275 : // well defined rectangular area inside one of these clip
276 : // rectangles.
277 :
278 : // ensureClipFor() or ensureClip() need to be called before
279 : // real rendering. FIXME: we should prolly push this down to
280 : // bitmapdevice instead.
281 1005100 : bool SvpSalGraphics::setClipRegion( const vcl::Region& i_rClip )
282 : {
283 1005100 : m_aClipRegion = i_rClip;
284 1005100 : m_aClipMap.reset();
285 1005100 : if( i_rClip.IsEmpty() )
286 : {
287 0 : m_bClipSetup = true;
288 0 : return true;
289 : }
290 :
291 1005100 : RectangleVector aRectangles;
292 1005100 : i_rClip.GetRegionRectangles(aRectangles);
293 :
294 1005100 : if(1 == aRectangles.size())
295 : {
296 962871 : m_aClipMap.reset();
297 :
298 962871 : const Rectangle& aBoundRect = aRectangles[0];
299 4814355 : m_aDevice = basebmp::subsetBitmapDevice(
300 : m_aOrigDevice,
301 4814355 : basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right() + 1,aBoundRect.Bottom() + 1) );
302 :
303 962871 : m_bClipSetup = true;
304 : }
305 : else
306 42229 : m_bClipSetup = false;
307 :
308 1005100 : return true;
309 : }
310 :
311 923290 : void SvpSalGraphics::SetLineColor()
312 : {
313 923290 : m_bUseLineColor = false;
314 923290 : }
315 :
316 925545 : void SvpSalGraphics::SetLineColor( SalColor nSalColor )
317 : {
318 925545 : m_bUseLineColor = true;
319 925545 : m_aLineColor = basebmp::Color( nSalColor );
320 925545 : }
321 :
322 9474 : void SvpSalGraphics::SetFillColor()
323 : {
324 9474 : m_bUseFillColor = false;
325 9474 : }
326 :
327 3878003 : void SvpSalGraphics::SetFillColor( SalColor nSalColor )
328 : {
329 3878003 : m_bUseFillColor = true;
330 3878003 : m_aFillColor = basebmp::Color( nSalColor );
331 3878003 : }
332 :
333 633992 : void SvpSalGraphics::SetXORMode( bool bSet, bool )
334 : {
335 633992 : m_aDrawMode = bSet ? basebmp::DrawMode_XOR : basebmp::DrawMode_PAINT;
336 633992 : }
337 :
338 0 : void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor )
339 : {
340 0 : m_bUseLineColor = true;
341 0 : switch( nROPColor )
342 : {
343 : case SAL_ROP_0:
344 0 : m_aLineColor = basebmp::Color( 0 );
345 0 : break;
346 : case SAL_ROP_1:
347 0 : m_aLineColor = basebmp::Color( 0xffffff );
348 0 : break;
349 : case SAL_ROP_INVERT:
350 0 : m_aLineColor = basebmp::Color( 0xffffff );
351 0 : break;
352 : }
353 0 : }
354 :
355 0 : void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor )
356 : {
357 0 : m_bUseFillColor = true;
358 0 : switch( nROPColor )
359 : {
360 : case SAL_ROP_0:
361 0 : m_aFillColor = basebmp::Color( 0 );
362 0 : break;
363 : case SAL_ROP_1:
364 0 : m_aFillColor = basebmp::Color( 0xffffff );
365 0 : break;
366 : case SAL_ROP_INVERT:
367 0 : m_aFillColor = basebmp::Color( 0xffffff );
368 0 : break;
369 : }
370 0 : }
371 :
372 173229 : void SvpSalGraphics::drawPixel( long nX, long nY )
373 : {
374 173229 : if( m_bUseLineColor )
375 : {
376 173229 : ensureClip();
377 : m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
378 : m_aLineColor,
379 : m_aDrawMode,
380 : m_aClipMap
381 173229 : );
382 : }
383 173229 : dbgOut( m_aDevice );
384 173229 : }
385 :
386 1166846 : void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
387 : {
388 1166846 : basebmp::Color aColor( nSalColor );
389 1166846 : ensureClip();
390 : m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
391 : aColor,
392 : m_aDrawMode,
393 : m_aClipMap
394 1166846 : );
395 1166846 : dbgOut( m_aDevice );
396 1166846 : }
397 :
398 3330173 : void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
399 : {
400 3330173 : if( m_bUseLineColor )
401 : {
402 3330173 : ensureClip(); // FIXME: for ...
403 : m_aDevice->drawLine( basegfx::B2IPoint( nX1, nY1 ),
404 : basegfx::B2IPoint( nX2, nY2 ),
405 : m_aLineColor,
406 : m_aDrawMode,
407 3330173 : m_aClipMap );
408 : }
409 3330173 : dbgOut( m_aDevice );
410 3330173 : }
411 :
412 1324793 : void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
413 : {
414 1324793 : if ((m_bUseLineColor || m_bUseFillColor) && m_aDevice)
415 : {
416 1324793 : basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
417 1324793 : ensureClip(); // FIXME: for ...
418 1324793 : if( m_bUseFillColor )
419 : {
420 1322825 : basegfx::B2DPolyPolygon aPolyPoly( aRect );
421 1322825 : m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
422 : }
423 1324793 : if( m_bUseLineColor )
424 8803 : m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap );
425 : }
426 1324793 : dbgOut( m_aDevice );
427 1324793 : }
428 :
429 235942 : void SvpSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
430 : {
431 235942 : if (m_bUseLineColor && nPoints && m_aDevice)
432 : {
433 235942 : basegfx::B2DPolygon aPoly;
434 235942 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
435 1010409 : for( sal_uLong i = 1; i < nPoints; i++ )
436 774467 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
437 235942 : aPoly.setClosed( false );
438 235942 : ensureClip(); // FIXME: for ...
439 235942 : m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
440 : }
441 235942 : dbgOut( m_aDevice );
442 235942 : }
443 :
444 3125008 : void SvpSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
445 : {
446 3125008 : if ((m_bUseLineColor || m_bUseFillColor) && nPoints && m_aDevice)
447 : {
448 3125008 : basegfx::B2DPolygon aPoly;
449 3125008 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
450 14090794 : for( sal_uLong i = 1; i < nPoints; i++ )
451 10965786 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
452 3125008 : ensureClip(); // FIXME: for ...
453 3125008 : if( m_bUseFillColor )
454 : {
455 3118670 : aPoly.setClosed( true );
456 3118670 : m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap );
457 : }
458 3125008 : if( m_bUseLineColor )
459 : {
460 16205 : aPoly.setClosed( false );
461 16205 : m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
462 3125008 : }
463 : }
464 3125008 : dbgOut( m_aDevice );
465 3125008 : }
466 :
467 2379 : void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
468 : const sal_uInt32* pPointCounts,
469 : PCONSTSALPOINT* pPtAry )
470 : {
471 2379 : if ((m_bUseLineColor || m_bUseFillColor) && nPoly && m_aDevice)
472 : {
473 2379 : basegfx::B2DPolyPolygon aPolyPoly;
474 22023 : for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ )
475 : {
476 19644 : sal_uInt32 nPoints = pPointCounts[nPolygon];
477 19644 : if( nPoints )
478 : {
479 19644 : PCONSTSALPOINT pPoints = pPtAry[nPolygon];
480 19644 : basegfx::B2DPolygon aPoly;
481 19644 : aPoly.append( basegfx::B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints );
482 215746 : for( sal_uInt32 i = 1; i < nPoints; i++ )
483 196102 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) );
484 :
485 19644 : aPolyPoly.append( aPoly );
486 : }
487 : }
488 2379 : ensureClip(); // FIXME: for ...
489 2379 : if( m_bUseFillColor )
490 : {
491 2379 : aPolyPoly.setClosed( true );
492 2379 : m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
493 : }
494 2379 : if( m_bUseLineColor )
495 : {
496 88 : aPolyPoly.setClosed( false );
497 88 : nPoly = aPolyPoly.count();
498 1878 : for( sal_uInt32 i = 0; i < nPoly; i++ )
499 1790 : m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap );
500 2379 : }
501 : }
502 2379 : dbgOut( m_aDevice );
503 2379 : }
504 :
505 0 : bool SvpSalGraphics::drawPolyLine(
506 : const ::basegfx::B2DPolygon&,
507 : double /*fTransparency*/,
508 : const ::basegfx::B2DVector& /*rLineWidths*/,
509 : basegfx::B2DLineJoin /*eJoin*/,
510 : com::sun::star::drawing::LineCap /*eLineCap*/)
511 : {
512 : // TODO: implement and advertise OutDevSupport_B2DDraw support
513 0 : return false;
514 : }
515 :
516 0 : bool SvpSalGraphics::drawPolyLineBezier( sal_uInt32,
517 : const SalPoint*,
518 : const sal_uInt8* )
519 : {
520 0 : return false;
521 : }
522 :
523 11071 : bool SvpSalGraphics::drawPolygonBezier( sal_uInt32,
524 : const SalPoint*,
525 : const sal_uInt8* )
526 : {
527 11071 : return false;
528 : }
529 :
530 1389 : bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
531 : const sal_uInt32*,
532 : const SalPoint* const*,
533 : const sal_uInt8* const* )
534 : {
535 1389 : return false;
536 : }
537 :
538 0 : bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
539 : {
540 : // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
541 0 : return false;
542 : }
543 :
544 1597 : void SvpSalGraphics::copyArea( long nDestX,
545 : long nDestY,
546 : long nSrcX,
547 : long nSrcY,
548 : long nSrcWidth,
549 : long nSrcHeight,
550 : sal_uInt16 /*nFlags*/ )
551 : {
552 1597 : basegfx::B2IBox aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight );
553 1597 : basegfx::B2IBox aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight );
554 : // fprintf( stderr, "copyArea %ld pixels - clip region %d\n",
555 : // (long)(nSrcWidth * nSrcHeight), m_aClipMap.get() != NULL );
556 1597 : SvpSalGraphics::ClipUndoHandle aUndo( this );
557 1597 : if( !isClippedSetup( aDestRect, aUndo ) )
558 1597 : m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
559 1597 : dbgOut( m_aDevice );
560 1597 : }
561 :
562 75741 : void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry,
563 : SalGraphics* pSrcGraphics )
564 : {
565 75741 : if( !m_aDevice.get() )
566 75741 : return;
567 :
568 : SvpSalGraphics* pSrc = pSrcGraphics ?
569 75741 : static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
570 : basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
571 : rPosAry.mnSrcX+rPosAry.mnSrcWidth,
572 75741 : rPosAry.mnSrcY+rPosAry.mnSrcHeight );
573 : basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
574 : rPosAry.mnDestX+rPosAry.mnDestWidth,
575 75741 : rPosAry.mnDestY+rPosAry.mnDestHeight );
576 :
577 75741 : SvpSalGraphics::ClipUndoHandle aUndo( this );
578 75741 : if( !isClippedSetup( aDestRect, aUndo ) )
579 75740 : m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
580 75741 : dbgOut( m_aDevice );
581 : }
582 :
583 235396 : void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
584 : const SalBitmap& rSalBitmap )
585 : {
586 235396 : if( !m_aDevice.get() )
587 235396 : return;
588 :
589 235396 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
590 : basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
591 : rPosAry.mnSrcX+rPosAry.mnSrcWidth,
592 235396 : rPosAry.mnSrcY+rPosAry.mnSrcHeight );
593 : basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
594 : rPosAry.mnDestX+rPosAry.mnDestWidth,
595 235396 : rPosAry.mnDestY+rPosAry.mnDestHeight );
596 :
597 235396 : SvpSalGraphics::ClipUndoHandle aUndo( this );
598 235396 : if( !isClippedSetup( aDestRect, aUndo ) )
599 227644 : m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
600 235396 : dbgOut( m_aDevice );
601 : }
602 :
603 0 : void SvpSalGraphics::drawBitmap( const SalTwoRect&,
604 : const SalBitmap&,
605 : SalColor )
606 : {
607 : // SNI, as in X11 plugin
608 0 : }
609 :
610 19367 : void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
611 : const SalBitmap& rSalBitmap,
612 : const SalBitmap& rTransparentBitmap )
613 : {
614 19367 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
615 19367 : const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
616 : basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
617 : rPosAry.mnSrcX+rPosAry.mnSrcWidth,
618 19367 : rPosAry.mnSrcY+rPosAry.mnSrcHeight );
619 : basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
620 : rPosAry.mnDestX+rPosAry.mnDestWidth,
621 19367 : rPosAry.mnDestY+rPosAry.mnDestHeight );
622 19367 : SvpSalGraphics::ClipUndoHandle aUndo( this );
623 19367 : if (!isClippedSetup(aDestRect, aUndo) && m_aDevice)
624 19315 : m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(),
625 38630 : aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
626 19367 : dbgOut( m_aDevice );
627 19367 : }
628 :
629 0 : void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
630 : const SalBitmap& rSalBitmap,
631 : SalColor nMaskColor )
632 : {
633 0 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
634 : basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
635 : rPosAry.mnSrcX+rPosAry.mnSrcWidth,
636 0 : rPosAry.mnSrcY+rPosAry.mnSrcHeight );
637 0 : basegfx::B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY );
638 :
639 : // BitmapDevice::drawMaskedColor works with 0==transparent,
640 : // 255==opaque. drawMask() semantic is the other way
641 : // around. Therefore, invert mask.
642 : basebmp::BitmapDeviceSharedPtr aCopy =
643 : cloneBitmapDevice( basegfx::B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ),
644 0 : rSrc.getBitmap() );
645 0 : basebmp::Color aBgColor( COL_WHITE );
646 0 : aCopy->clear(aBgColor);
647 0 : basebmp::Color aFgColor( COL_BLACK );
648 0 : aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, basegfx::B2IPoint() );
649 :
650 0 : basebmp::Color aColor( nMaskColor );
651 0 : basegfx::B2IBox aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
652 0 : const basegfx::B2IBox aClipRect( aDestPoint, basegfx::B2ITuple( aSrcRect.getWidth(), aSrcRect.getHeight() ) );
653 :
654 0 : SvpSalGraphics::ClipUndoHandle aUndo( this );
655 0 : if( !isClippedSetup( aClipRect, aUndo ) )
656 0 : m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
657 0 : dbgOut( m_aDevice );
658 0 : }
659 :
660 250977 : SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
661 : {
662 250977 : basebmp::BitmapDeviceSharedPtr aCopy;
663 250977 : if (m_aDevice)
664 501954 : aCopy = cloneBitmapDevice(basegfx::B2IVector(nWidth, nHeight),
665 250977 : m_aDevice);
666 250977 : basegfx::B2IBox aSrcRect( nX, nY, nX+nWidth, nY+nHeight );
667 250977 : basegfx::B2IBox aDestRect( 0, 0, nWidth, nHeight );
668 :
669 501954 : SvpSalGraphics::ClipUndoHandle aUndo( this );
670 250977 : if (!isClippedSetup(aDestRect, aUndo) && aCopy)
671 236568 : aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT );
672 :
673 250977 : SvpSalBitmap* pBitmap = new SvpSalBitmap();
674 250977 : pBitmap->setBitmap( aCopy );
675 501954 : return pBitmap;
676 : }
677 :
678 0 : SalColor SvpSalGraphics::getPixel( long nX, long nY )
679 : {
680 0 : basebmp::Color aColor( m_aOrigDevice->getPixel( basegfx::B2IPoint( nX, nY ) ) );
681 0 : return aColor.toInt32();
682 : }
683 :
684 105208 : void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ )
685 : {
686 : // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
687 105208 : basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
688 210416 : basegfx::B2DPolyPolygon aPolyPoly( aRect );
689 105208 : basegfx::B2IBox aDestRange( nX, nY, nX + nWidth, nY + nHeight );
690 :
691 210416 : SvpSalGraphics::ClipUndoHandle aUndo( this );
692 105208 : if( !isClippedSetup( aDestRange, aUndo ) )
693 105208 : m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR, m_aClipMap );
694 210416 : dbgOut( m_aDevice );
695 105208 : }
696 :
697 24 : void SvpSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ )
698 : {
699 : // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
700 24 : basegfx::B2DPolygon aPoly;
701 24 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
702 168 : for( sal_uLong i = 1; i < nPoints; i++ )
703 144 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
704 24 : aPoly.setClosed( true );
705 24 : ensureClip(); // FIXME for ...
706 24 : m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR, m_aClipMap );
707 24 : dbgOut( m_aDevice );
708 24 : }
709 :
710 : #endif
711 :
712 0 : bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
713 : {
714 0 : return false;
715 : }
716 :
717 : #ifndef IOS
718 :
719 164 : SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
720 : {
721 164 : return SystemGraphicsData();
722 : }
723 :
724 22359 : bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const
725 : {
726 22359 : return false;
727 1125 : }
728 :
729 : #endif
730 :
731 : #ifdef IOS
732 :
733 : void SvpSalGraphics::RefreshRect(float /* lX */, float /* lY */, float /* lWidth */, float /* lHeight */)
734 : {
735 : }
736 :
737 : #endif
738 :
739 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|