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