Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "headless/svpgdi.hxx"
30 : : #include "headless/svpbmp.hxx"
31 : :
32 : : #include <vcl/sysdata.hxx>
33 : : #include <basegfx/range/b2drange.hxx>
34 : : #include <basegfx/range/b2ibox.hxx>
35 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
36 : : #include <basegfx/polygon/b2dpolygon.hxx>
37 : : #include <basegfx/polygon/b2dpolygontools.hxx>
38 : : #include <basebmp/scanlineformats.hxx>
39 : :
40 : : #include <tools/debug.hxx>
41 : :
42 : : #if OSL_DEBUG_LEVEL > 2
43 : : #include <basebmp/debug.hxx>
44 : : #include <fstream>
45 : : #include <rtl/strbuf.hxx>
46 : : #include <sys/stat.h>
47 : : #endif
48 : :
49 : : #include <region.h>
50 : : #include <stdio.h>
51 : :
52 : 5670144 : inline void dbgOut( const basebmp::BitmapDeviceSharedPtr&
53 : : #if OSL_DEBUG_LEVEL > 2
54 : : rDevice
55 : : #endif
56 : : )
57 : : {
58 : : #if OSL_DEBUG_LEVEL > 2
59 : : static int dbgStreamNum = 0;
60 : : rtl::OStringBuffer aBuf( 256 );
61 : : aBuf.append( "debug" );
62 : : mkdir( aBuf.getStr(), 0777 );
63 : : aBuf.append( "/" );
64 : : aBuf.append( sal_Int64(reinterpret_cast<sal_IntPtr>(rDevice.get())), 16 );
65 : : mkdir( aBuf.getStr(), 0777 );
66 : : aBuf.append( "/bmp" );
67 : : aBuf.append( sal_Int32(dbgStreamNum++) );
68 : : std::fstream bmpstream( aBuf.getStr(), std::ios::out );
69 : : debugDump( rDevice, bmpstream );
70 : : #endif
71 : 5670144 : }
72 : :
73 : : // ===========================================================================
74 : :
75 : 175520 : bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ )
76 : : {
77 : : // TODO(P3) implement alpha blending
78 : 175520 : return false;
79 : : }
80 : :
81 : 0 : bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
82 : : {
83 : : // TODO(P3) implement alpha blending
84 : 0 : return false;
85 : : }
86 : :
87 : 230885 : SvpSalGraphics::SvpSalGraphics() :
88 : : m_bUseLineColor( true ),
89 : : m_aLineColor( COL_BLACK ),
90 : : m_bUseFillColor( false ),
91 : : m_aFillColor( COL_WHITE ),
92 : : m_aTextColor( COL_BLACK ),
93 : : m_aDrawMode( basebmp::DrawMode_PAINT ),
94 : : m_eTextFmt( basebmp::Format::EIGHT_BIT_GREY ),
95 [ + - ][ + - ]: 230885 : m_bClipSetup( false )
[ + - ][ + - ]
96 : : {
97 [ + + ]: 3925045 : for( int i = 0; i < MAX_FALLBACK; ++i )
98 : 3694160 : m_pServerFont[i] = NULL;
99 : 230885 : }
100 : :
101 [ + - ][ + - ]: 226898 : SvpSalGraphics::~SvpSalGraphics()
[ + - ][ + - ]
102 : : {
103 [ - + ]: 453796 : }
104 : :
105 : 307588 : void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice )
106 : : {
107 : 307588 : m_aOrigDevice = rDevice;
108 : 307588 : ResetClipRegion();
109 : :
110 : : // determine matching bitmap format for masks
111 : 307588 : sal_uInt32 nDeviceFmt = m_aDevice->getScanlineFormat();
112 : : DBG_ASSERT( (nDeviceFmt <= (sal_uInt32)basebmp::Format::MAX), "SVP::setDevice() with invalid bitmap format" );
113 [ + + ]: 307588 : 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 : 294988 : m_eTextFmt = basebmp::Format::EIGHT_BIT_GREY;
124 : 294988 : break;
125 : : default:
126 : 12600 : m_eTextFmt = basebmp::Format::ONE_BIT_LSB_GREY;
127 : 12600 : break;
128 : : }
129 : 307588 : }
130 : :
131 : 2130 : void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
132 : : {
133 : 2130 : rDPIX = rDPIY = 96;
134 : 2130 : }
135 : :
136 : 183000 : sal_uInt16 SvpSalGraphics::GetBitCount() const
137 : : {
138 : 183000 : return SvpElement::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
139 : : }
140 : :
141 : 333 : long SvpSalGraphics::GetGraphicsWidth() const
142 : : {
143 [ + - ]: 333 : if( m_aDevice.get() )
144 : : {
145 [ + - ]: 333 : basegfx::B2IVector aSize = m_aOrigDevice->getSize();
146 : 333 : return aSize.getX();
147 : : }
148 : 333 : return 0;
149 : : }
150 : :
151 : 317370 : void SvpSalGraphics::ResetClipRegion()
152 : : {
153 : 317370 : m_aDevice = m_aOrigDevice;
154 : 317370 : m_aClipMap.reset();
155 : 317370 : m_bClipSetup = true;
156 : 317370 : m_aClipRegion.SetNull();
157 : 317370 : }
158 : :
159 : :
160 : : // verify clip for the whole area is setup
161 : 5322063 : void SvpSalGraphics::ensureClip()
162 : : {
163 [ + + ]: 5322063 : if (m_bClipSetup)
164 : 5322063 : return;
165 : :
166 [ + - ]: 24793 : m_aDevice = m_aOrigDevice;
167 [ + - ]: 24793 : basegfx::B2IVector aSize = m_aDevice->getSize();
168 [ + - ][ + - ]: 24793 : m_aClipMap = basebmp::createBitmapDevice( aSize, false, basebmp::Format::ONE_BIT_MSB_GREY );
[ + - ]
169 [ + - ]: 24793 : m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
170 : :
171 : : // fprintf( stderr, "non rect clip region set with %d rects:\n",
172 : : // (int)m_aClipRegion.GetRectCount() );
173 : : ImplRegionInfo aInfo;
174 : : long nX, nY, nW, nH;
175 [ + - ]: 24793 : bool bRegionRect = m_aClipRegion.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
176 [ + + ]: 131416 : while( bRegionRect )
177 : : {
178 [ + - ][ + - ]: 106623 : if ( nW && nH )
179 : : {
180 [ + - ]: 106623 : basegfx::B2DPolyPolygon aFull;
181 [ + - ][ + - ]: 106623 : aFull.append( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nW, nY+nH ) ) );
[ + - ][ + - ]
182 [ + - ][ + - ]: 106623 : m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), basebmp::DrawMode_PAINT );
183 : : }
184 : : // fprintf( stderr, "\t %ld,%ld %ldx%ld\n", nX, nY, nW, nH );
185 [ + - ]: 106623 : bRegionRect = m_aClipRegion.ImplGetNextRect( aInfo, nX, nY, nW, nH );
186 : : }
187 : 5322063 : m_bClipSetup = true;
188 : : }
189 : :
190 : 2333016 : SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
191 : : {
192 [ + + ]: 2333016 : if( m_aDevice.get() )
193 [ + - ]: 1086 : m_rGfx.m_aDevice = m_aDevice;
194 : 2333016 : }
195 : :
196 : : // setup a clip rectangle -only- iff we have to; if aRange
197 : : // is entirely contained inside an existing clip frame, we
198 : : // will avoid setting up the clip bitmap. Similarly if the
199 : : // range doesn't appear at all we return true to avoid
200 : : // rendering
201 : 2333016 : bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox &aRange, SvpSalGraphics::ClipUndoHandle &rUndo )
202 : : {
203 [ + + ]: 2333016 : if( m_bClipSetup )
204 : 2269400 : return false;
205 : :
206 [ + - ][ - + ]: 63616 : if( m_aClipRegion.IsEmpty() ) // no clipping
207 : 0 : return false;
208 : :
209 : : // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
210 : : // aRange.getMinX(), aRange.getMinY(),
211 : : // (int)aRange.getWidth(), (int)aRange.getHeight() );
212 : :
213 : : // first see if aRange is purely internal to one of the clip regions
214 : : Rectangle aRect( Point( aRange.getMinX(), aRange.getMinY() ),
215 [ + - ][ + - ]: 63616 : Size( aRange.getWidth(), aRange.getHeight() ) );
[ + - ][ + - ]
[ + - ]
216 : :
217 : : // then see if we are overlapping with just one
218 : 63616 : int nHit = 0;
219 [ + - ][ + - ]: 63616 : Rectangle aIterRect, aHitRect;
220 [ + - ]: 63616 : RegionHandle aHnd = m_aClipRegion.BeginEnumRects();
221 [ + - ][ + + ]: 337916 : while( m_aClipRegion.GetNextEnumRect( aHnd, aIterRect ) )
222 : : {
223 [ + - ][ + + ]: 274300 : if( aIterRect.IsOver( aRect ) )
224 : : {
225 : 18264 : aHitRect = aIterRect;
226 : 18264 : nHit++;
227 : : }
228 : : }
229 [ + - ]: 63616 : m_aClipRegion.EndEnumRects (aHnd);
230 : :
231 [ + + ]: 63616 : if( nHit == 0 ) // rendering outside any clipping region
232 : : {
233 : : // fprintf (stderr, "denegerate case detected ...\n");
234 : 45553 : return true;
235 : : }
236 [ + + ]: 18063 : else if( nHit == 1 ) // common path: rendering against just one clipping region
237 : : {
238 [ + - ][ + + ]: 17902 : if( aHitRect.IsInside( aRect ) )
239 : : {
240 : : // fprintf (stderr, " is inside ! avoid deeper clip ...\n");
241 : 16816 : return false;
242 : : }
243 : : // fprintf (stderr, " operation only overlaps with a single clip zone\n" );
244 [ + - ]: 1086 : rUndo.m_aDevice = m_aDevice;
245 : : m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
246 : 1086 : basegfx::B2IBox (aHitRect.Left(),
247 : 1086 : aHitRect.Top(),
248 : 1086 : aHitRect.Right(),
249 [ + - ][ + - ]: 2172 : aHitRect.Bottom()) );
[ + - ][ + - ]
250 : 1086 : return false;
251 : : }
252 : : // fprintf (stderr, "URK: complex & slow clipping case\n" );
253 : : // horribly slow & complicated case ...
254 : :
255 [ + - ]: 161 : ensureClip();
256 : 2333016 : return false;
257 : : }
258 : :
259 : :
260 : : // Clipping by creating unconditional mask bitmaps is horribly
261 : : // slow so defer it, as much as possible. It is common to get
262 : : // 3 rectangles pushed, and have to create a vast off-screen
263 : : // mask only to destroy it shortly afterwards. That is
264 : : // particularly galling if we render only to a small,
265 : : // well defined rectangular area inside one of these clip
266 : : // rectangles.
267 : : //
268 : : // ensureClipFor() or ensureClip() need to be called before
269 : : // real rendering. FIXME: we should prolly push this down to
270 : : // bitmapdevice instead.
271 : 415321 : bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
272 : : {
273 : 415321 : m_aClipRegion = i_rClip;
274 : 415321 : m_aClipMap.reset();
275 [ + + ]: 415321 : if( i_rClip.IsEmpty() )
276 : 7 : m_bClipSetup = true;
277 : :
278 [ + + ]: 415314 : else if( i_rClip.GetRectCount() == 1 )
279 : : {
280 [ + - ]: 367770 : m_aClipMap.reset();
281 [ + - ]: 367770 : Rectangle aBoundRect( i_rClip.GetBoundRect() );
282 : : m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
283 [ + - ][ + - ]: 367770 : basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
[ + - ][ + - ]
284 : 367770 : m_bClipSetup = true;
285 : : }
286 : : else
287 : 47544 : m_bClipSetup = false;
288 : :
289 : 415321 : return true;
290 : : }
291 : :
292 : 487259 : void SvpSalGraphics::SetLineColor()
293 : : {
294 : 487259 : m_bUseLineColor = false;
295 : 487259 : }
296 : :
297 : 323451 : void SvpSalGraphics::SetLineColor( SalColor nSalColor )
298 : : {
299 : 323451 : m_bUseLineColor = true;
300 : 323451 : m_aLineColor = basebmp::Color( nSalColor );
301 : 323451 : }
302 : :
303 : 7814 : void SvpSalGraphics::SetFillColor()
304 : : {
305 : 7814 : m_bUseFillColor = false;
306 : 7814 : }
307 : :
308 : 3010882 : void SvpSalGraphics::SetFillColor( SalColor nSalColor )
309 : : {
310 : 3010882 : m_bUseFillColor = true;
311 : 3010882 : m_aFillColor = basebmp::Color( nSalColor );
312 : 3010882 : }
313 : :
314 : 232917 : void SvpSalGraphics::SetXORMode( bool bSet, bool )
315 : : {
316 [ + + ]: 232917 : m_aDrawMode = bSet ? basebmp::DrawMode_XOR : basebmp::DrawMode_PAINT;
317 : 232917 : }
318 : :
319 : 0 : void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor )
320 : : {
321 : 0 : m_bUseLineColor = true;
322 [ # # # # ]: 0 : switch( nROPColor )
323 : : {
324 : : case SAL_ROP_0:
325 : 0 : m_aLineColor = basebmp::Color( 0 );
326 : 0 : break;
327 : : case SAL_ROP_1:
328 : 0 : m_aLineColor = basebmp::Color( 0xffffff );
329 : 0 : break;
330 : : case SAL_ROP_INVERT:
331 : 0 : m_aLineColor = basebmp::Color( 0xffffff );
332 : 0 : break;
333 : : }
334 : 0 : }
335 : :
336 : 235 : void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor )
337 : : {
338 : 235 : m_bUseFillColor = true;
339 [ + - - - ]: 235 : switch( nROPColor )
340 : : {
341 : : case SAL_ROP_0:
342 : 235 : m_aFillColor = basebmp::Color( 0 );
343 : 235 : break;
344 : : case SAL_ROP_1:
345 : 0 : m_aFillColor = basebmp::Color( 0xffffff );
346 : 0 : break;
347 : : case SAL_ROP_INVERT:
348 : 0 : m_aFillColor = basebmp::Color( 0xffffff );
349 : 0 : break;
350 : : }
351 : 235 : }
352 : :
353 : 56597 : void SvpSalGraphics::SetTextColor( SalColor nSalColor )
354 : : {
355 : 56597 : m_aTextColor = basebmp::Color( nSalColor );
356 : 56597 : }
357 : :
358 : 405090 : void SvpSalGraphics::drawPixel( long nX, long nY )
359 : : {
360 [ + - ]: 405090 : if( m_bUseLineColor )
361 : : {
362 : 405090 : ensureClip();
363 : : m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
364 : : m_aLineColor,
365 : : m_aDrawMode,
366 : : m_aClipMap
367 [ + - ]: 405090 : );
368 : : }
369 : 405090 : dbgOut( m_aDevice );
370 : 405090 : }
371 : :
372 : 307918 : void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
373 : : {
374 : 307918 : basebmp::Color aColor( nSalColor );
375 [ + - ]: 307918 : ensureClip();
376 : : m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
377 : : aColor,
378 : : m_aDrawMode,
379 : : m_aClipMap
380 [ + - ]: 307918 : );
381 : 307918 : dbgOut( m_aDevice );
382 : 307918 : }
383 : :
384 : 950997 : void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
385 : : {
386 [ + - ]: 950997 : if( m_bUseLineColor )
387 : : {
388 : 950997 : ensureClip(); // FIXME: for ...
389 : : m_aDevice->drawLine( basegfx::B2IPoint( nX1, nY1 ),
390 : : basegfx::B2IPoint( nX2, nY2 ),
391 : : m_aLineColor,
392 : : m_aDrawMode,
393 [ + - ]: 950997 : m_aClipMap );
394 : : }
395 : 950997 : dbgOut( m_aDevice );
396 : 950997 : }
397 : :
398 : 771829 : void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
399 : : {
400 [ + + ][ + - ]: 771829 : if( m_bUseLineColor || m_bUseFillColor )
401 : : {
402 [ + - ][ + - ]: 771829 : basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
403 [ + - ]: 771829 : ensureClip(); // FIXME: for ...
404 [ + + ]: 771829 : if( m_bUseFillColor )
405 : : {
406 [ + - ]: 769138 : basegfx::B2DPolyPolygon aPolyPoly( aRect );
407 [ + - ][ + - ]: 769138 : m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
408 : : }
409 [ + + ]: 771829 : if( m_bUseLineColor )
410 [ + - ][ + - ]: 771829 : m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap );
411 : : }
412 : 771829 : dbgOut( m_aDevice );
413 : 771829 : }
414 : :
415 : 214441 : void SvpSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry )
416 : : {
417 [ + - ][ + - ]: 214441 : if( m_bUseLineColor && nPoints )
418 : : {
419 [ + - ]: 214441 : basegfx::B2DPolygon aPoly;
420 [ + - ]: 214441 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
421 [ + + ]: 1301657 : for( sal_uLong i = 1; i < nPoints; i++ )
422 [ + - ]: 1087216 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
423 [ + - ]: 214441 : aPoly.setClosed( false );
424 [ + - ]: 214441 : ensureClip(); // FIXME: for ...
425 [ + - ][ + - ]: 214441 : m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
426 : : }
427 : 214441 : dbgOut( m_aDevice );
428 : 214441 : }
429 : :
430 : 2645104 : void SvpSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry )
431 : : {
432 [ + + ][ + - ]: 2645104 : if( ( m_bUseLineColor || m_bUseFillColor ) && nPoints )
[ + - ]
433 : : {
434 [ + - ]: 2645104 : basegfx::B2DPolygon aPoly;
435 [ + - ]: 2645104 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
436 [ + + ]: 12551875 : for( sal_uLong i = 1; i < nPoints; i++ )
437 [ + - ]: 9906771 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
438 [ + - ]: 2645104 : ensureClip(); // FIXME: for ...
439 [ + + ]: 2645104 : if( m_bUseFillColor )
440 : : {
441 [ + - ]: 2639762 : aPoly.setClosed( true );
442 [ + - ][ + - ]: 2639762 : m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap );
[ + - ]
443 : : }
444 [ + + ]: 2645104 : if( m_bUseLineColor )
445 : : {
446 [ + - ]: 12229 : aPoly.setClosed( false );
447 [ + - ]: 12229 : m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
448 [ + - ]: 2645104 : }
449 : : }
450 : 2645104 : dbgOut( m_aDevice );
451 : 2645104 : }
452 : :
453 : 26523 : void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
454 : : const sal_uInt32* pPointCounts,
455 : : PCONSTSALPOINT* pPtAry )
456 : : {
457 [ + - ][ + - ]: 26523 : if( ( m_bUseLineColor || m_bUseFillColor ) && nPoly )
[ + - ]
458 : : {
459 [ + - ]: 26523 : basegfx::B2DPolyPolygon aPolyPoly;
460 [ + + ]: 80736 : for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ )
461 : : {
462 : 54213 : sal_uInt32 nPoints = pPointCounts[nPolygon];
463 [ + - ]: 54213 : if( nPoints )
464 : : {
465 : 54213 : PCONSTSALPOINT pPoints = pPtAry[nPolygon];
466 [ + - ]: 54213 : basegfx::B2DPolygon aPoly;
467 [ + - ]: 54213 : aPoly.append( basegfx::B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints );
468 [ + + ]: 334995 : for( sal_uInt32 i = 1; i < nPoints; i++ )
469 [ + - ]: 280782 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) );
470 : :
471 [ + - ][ + - ]: 54213 : aPolyPoly.append( aPoly );
472 : : }
473 : : }
474 [ + - ]: 26523 : ensureClip(); // FIXME: for ...
475 [ + - ]: 26523 : if( m_bUseFillColor )
476 : : {
477 [ + - ]: 26523 : aPolyPoly.setClosed( true );
478 [ + - ]: 26523 : m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
479 : : }
480 [ - + ]: 26523 : if( m_bUseLineColor )
481 : : {
482 [ # # ]: 0 : aPolyPoly.setClosed( false );
483 [ # # ]: 0 : nPoly = aPolyPoly.count();
484 [ # # ]: 0 : for( sal_uInt32 i = 0; i < nPoly; i++ )
485 [ # # ][ # # ]: 0 : m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap );
[ # # ]
486 [ + - ]: 26523 : }
487 : : }
488 : 26523 : dbgOut( m_aDevice );
489 : 26523 : }
490 : :
491 : 0 : bool SvpSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon&, double /*fTransparency*/, const ::basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/ )
492 : : {
493 : : // TODO: implement and advertise OutDevSupport_B2DDraw support
494 : 0 : return false;
495 : : }
496 : :
497 : 0 : sal_Bool SvpSalGraphics::drawPolyLineBezier( sal_uLong,
498 : : const SalPoint*,
499 : : const sal_uInt8* )
500 : : {
501 : 0 : return sal_False;
502 : : }
503 : :
504 : 1494 : sal_Bool SvpSalGraphics::drawPolygonBezier( sal_uLong,
505 : : const SalPoint*,
506 : : const sal_uInt8* )
507 : : {
508 : 1494 : return sal_False;
509 : : }
510 : :
511 : 1830 : sal_Bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
512 : : const sal_uInt32*,
513 : : const SalPoint* const*,
514 : : const sal_uInt8* const* )
515 : : {
516 : 1830 : return sal_False;
517 : : }
518 : :
519 : 0 : bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
520 : : {
521 : : // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
522 : 0 : return false;
523 : : }
524 : :
525 : 399 : void SvpSalGraphics::copyArea( long nDestX,
526 : : long nDestY,
527 : : long nSrcX,
528 : : long nSrcY,
529 : : long nSrcWidth,
530 : : long nSrcHeight,
531 : : sal_uInt16 /*nFlags*/ )
532 : : {
533 [ + - ]: 399 : basegfx::B2IBox aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight );
534 [ + - ]: 399 : basegfx::B2IBox aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight );
535 : : // fprintf( stderr, "copyArea %ld pixels - clip region %d\n",
536 : : // (long)(nSrcWidth * nSrcHeight), m_aClipMap.get() != NULL );
537 [ + - ]: 399 : SvpSalGraphics::ClipUndoHandle aUndo( this );
538 [ + - ][ + - ]: 399 : if( !isClippedSetup( aDestRect, aUndo ) )
539 [ + - ]: 399 : m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
540 [ + - ]: 399 : dbgOut( m_aDevice );
541 : 399 : }
542 : :
543 : 54746 : void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry,
544 : : SalGraphics* pSrcGraphics )
545 : : {
546 : : SvpSalGraphics* pSrc = pSrcGraphics ?
547 [ + + ]: 54746 : static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
548 : : basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
549 : : pPosAry->mnSrcX+pPosAry->mnSrcWidth,
550 [ + - ]: 54746 : pPosAry->mnSrcY+pPosAry->mnSrcHeight );
551 : : basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
552 : : pPosAry->mnDestX+pPosAry->mnDestWidth,
553 [ + - ]: 54746 : pPosAry->mnDestY+pPosAry->mnDestHeight );
554 : :
555 [ + - ]: 54746 : SvpSalGraphics::ClipUndoHandle aUndo( this );
556 [ + - ][ + + ]: 54746 : if( !isClippedSetup( aDestRect, aUndo ) )
557 [ + - ]: 54744 : m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
558 [ + - ]: 54746 : dbgOut( m_aDevice );
559 : 54746 : }
560 : :
561 : 219953 : void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
562 : : const SalBitmap& rSalBitmap )
563 : : {
564 : 219953 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
565 : : basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
566 : : pPosAry->mnSrcX+pPosAry->mnSrcWidth,
567 [ + - ]: 219953 : pPosAry->mnSrcY+pPosAry->mnSrcHeight );
568 : : basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
569 : : pPosAry->mnDestX+pPosAry->mnDestWidth,
570 [ + - ]: 219953 : pPosAry->mnDestY+pPosAry->mnDestHeight );
571 : :
572 [ + - ]: 219953 : SvpSalGraphics::ClipUndoHandle aUndo( this );
573 [ + - ][ + + ]: 219953 : if( !isClippedSetup( aDestRect, aUndo ) )
574 [ + - ]: 203811 : m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
575 [ + - ]: 219953 : dbgOut( m_aDevice );
576 : 219953 : }
577 : :
578 : 0 : void SvpSalGraphics::drawBitmap( const SalTwoRect*,
579 : : const SalBitmap&,
580 : : SalColor )
581 : : {
582 : : // SNI, as in X11 plugin
583 : 0 : }
584 : :
585 : 3085 : void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry,
586 : : const SalBitmap& rSalBitmap,
587 : : const SalBitmap& rTransparentBitmap )
588 : : {
589 : 3085 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
590 : 3085 : const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
591 : : basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
592 : : pPosAry->mnSrcX+pPosAry->mnSrcWidth,
593 [ + - ]: 3085 : pPosAry->mnSrcY+pPosAry->mnSrcHeight );
594 : : basegfx::B2IBox aDestRect( pPosAry->mnDestX, pPosAry->mnDestY,
595 : : pPosAry->mnDestX+pPosAry->mnDestWidth,
596 [ + - ]: 3085 : pPosAry->mnDestY+pPosAry->mnDestHeight );
597 [ + - ]: 3085 : SvpSalGraphics::ClipUndoHandle aUndo( this );
598 [ + - ][ + - ]: 3085 : if( !isClippedSetup( aDestRect, aUndo ) )
599 : 3085 : m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(),
600 [ + - ]: 3085 : aSrcRect, aDestRect, basebmp::DrawMode_PAINT, m_aClipMap );
601 [ + - ]: 3085 : dbgOut( m_aDevice );
602 : 3085 : }
603 : :
604 : 0 : void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry,
605 : : const SalBitmap& rSalBitmap,
606 : : SalColor nMaskColor )
607 : : {
608 : 0 : const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
609 : : basegfx::B2IBox aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY,
610 : : pPosAry->mnSrcX+pPosAry->mnSrcWidth,
611 [ # # ]: 0 : pPosAry->mnSrcY+pPosAry->mnSrcHeight );
612 : 0 : basegfx::B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY );
613 : :
614 : : // BitmapDevice::drawMaskedColor works with 0==transparent,
615 : : // 255==opaque. drawMask() semantic is the other way
616 : : // around. Therefore, invert mask.
617 : : basebmp::BitmapDeviceSharedPtr aCopy =
618 : : cloneBitmapDevice( basegfx::B2IVector( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ),
619 [ # # ]: 0 : rSrc.getBitmap() );
620 : 0 : basebmp::Color aBgColor( COL_WHITE );
621 [ # # ]: 0 : aCopy->clear(aBgColor);
622 : 0 : basebmp::Color aFgColor( COL_BLACK );
623 [ # # ]: 0 : aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, basegfx::B2IPoint() );
624 : :
625 : 0 : basebmp::Color aColor( nMaskColor );
626 [ # # ]: 0 : basegfx::B2IBox aSrcRect2( 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight );
627 [ # # ][ # # ]: 0 : const basegfx::B2IBox aClipRect( aDestPoint, basegfx::B2ITuple( aSrcRect.getWidth(), aSrcRect.getHeight() ) );
[ # # ]
628 : :
629 [ # # ]: 0 : SvpSalGraphics::ClipUndoHandle aUndo( this );
630 [ # # ][ # # ]: 0 : if( !isClippedSetup( aClipRect, aUndo ) )
631 [ # # ]: 0 : m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
632 [ # # ][ # # ]: 0 : dbgOut( m_aDevice );
633 : 0 : }
634 : :
635 : 212773 : SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
636 : : {
637 : : basebmp::BitmapDeviceSharedPtr aCopy =
638 : : cloneBitmapDevice( basegfx::B2IVector( nWidth, nHeight ),
639 [ + - ]: 212773 : m_aDevice );
640 [ + - ]: 212773 : basegfx::B2IBox aSrcRect( nX, nY, nX+nWidth, nY+nHeight );
641 [ + - ]: 212773 : basegfx::B2IBox aDestRect( 0, 0, nWidth, nHeight );
642 : :
643 [ + - ]: 212773 : SvpSalGraphics::ClipUndoHandle aUndo( this );
644 [ + - ][ + + ]: 212773 : if( !isClippedSetup( aDestRect, aUndo ) )
645 [ + - ]: 183364 : aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode_PAINT );
646 : :
647 [ + - ][ + - ]: 212773 : SvpSalBitmap* pBitmap = new SvpSalBitmap();
648 [ + - ]: 212773 : pBitmap->setBitmap( aCopy );
649 [ + - ][ + - ]: 212773 : return pBitmap;
650 : : }
651 : :
652 : 0 : SalColor SvpSalGraphics::getPixel( long nX, long nY )
653 : : {
654 [ # # ]: 0 : basebmp::Color aColor( m_aOrigDevice->getPixel( basegfx::B2IPoint( nX, nY ) ) );
655 : 0 : return aColor.toInt32();
656 : : }
657 : :
658 : 70059 : void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ )
659 : : {
660 : : // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
661 [ + - ][ + - ]: 70059 : basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
662 [ + - ]: 70059 : basegfx::B2DPolyPolygon aPolyPoly( aRect );
663 [ + - ]: 70059 : basegfx::B2IBox aDestRange( nX, nY, nX + nWidth, nY + nHeight );
664 : :
665 [ + - ]: 70059 : SvpSalGraphics::ClipUndoHandle aUndo( this );
666 [ + - ][ + - ]: 70059 : if( !isClippedSetup( aDestRange, aUndo ) )
667 [ + - ]: 70059 : m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR, m_aClipMap );
668 [ + - ][ + - ]: 70059 : dbgOut( m_aDevice );
[ + - ]
669 : 70059 : }
670 : :
671 : 0 : void SvpSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ )
672 : : {
673 : : // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
674 [ # # ]: 0 : basegfx::B2DPolygon aPoly;
675 [ # # ]: 0 : aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
676 [ # # ]: 0 : for( sal_uLong i = 1; i < nPoints; i++ )
677 [ # # ]: 0 : aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
678 [ # # ]: 0 : aPoly.setClosed( true );
679 [ # # ]: 0 : ensureClip(); // FIXME for ...
680 [ # # ][ # # ]: 0 : m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), basebmp::DrawMode_XOR, m_aClipMap );
[ # # ]
681 [ # # ]: 0 : dbgOut( m_aDevice );
682 : 0 : }
683 : :
684 : 0 : sal_Bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
685 : : {
686 : 0 : return sal_False;
687 : : }
688 : :
689 : 0 : SystemFontData SvpSalGraphics::GetSysFontData( int nFallbacklevel ) const
690 : : {
691 : 0 : SystemFontData aSysFontData;
692 : :
693 [ # # ]: 0 : if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
694 [ # # ]: 0 : if (nFallbacklevel < 0 ) nFallbacklevel = 0;
695 : :
696 : 0 : aSysFontData.nSize = sizeof( SystemFontData );
697 : 0 : aSysFontData.nFontId = 0;
698 : 0 : aSysFontData.nFontFlags = 0;
699 : 0 : aSysFontData.bFakeBold = false;
700 : 0 : aSysFontData.bFakeItalic = false;
701 : 0 : aSysFontData.bAntialias = true;
702 : 0 : return aSysFontData;
703 : : }
704 : :
705 : 0 : SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
706 : : {
707 : 0 : return SystemGraphicsData();
708 : : }
709 : :
710 : 11501 : bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const
711 : : {
712 : 11501 : return false;
713 : : }
714 : :
715 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|