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 : #include <sal/types.h>
20 :
21 : #include <tools/poly.hxx>
22 : #include <tools/helpers.hxx>
23 :
24 : #include <vcl/outdev.hxx>
25 : #include <vcl/virdev.hxx>
26 : #include <vcl/window.hxx>
27 :
28 : #include "salgdi.hxx"
29 :
30 1512986 : void OutputDevice::DrawRect( const Rectangle& rRect )
31 : {
32 1512986 : assert_if_double_buffered_window();
33 :
34 1512986 : if ( mpMetaFile )
35 16450 : mpMetaFile->AddAction( new MetaRectAction( rRect ) );
36 :
37 1512986 : if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
38 40217 : return;
39 :
40 1508464 : Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
41 :
42 1508464 : if ( aRect.IsEmpty() )
43 17712 : return;
44 :
45 1490752 : aRect.Justify();
46 :
47 1490752 : if ( !mpGraphics && !AcquireGraphics() )
48 0 : return;
49 :
50 1490752 : if ( mbInitClipRegion )
51 303951 : InitClipRegion();
52 :
53 1490752 : if ( mbOutputClipped )
54 13461 : return;
55 :
56 1477291 : if ( mbInitLineColor )
57 514770 : InitLineColor();
58 :
59 1477291 : if ( mbInitFillColor )
60 507171 : InitFillColor();
61 :
62 1477291 : mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
63 :
64 1477291 : if( mpAlphaVDev )
65 17962 : mpAlphaVDev->DrawRect( rRect );
66 : }
67 :
68 10978 : void OutputDevice::DrawRect( const Rectangle& rRect,
69 : sal_uLong nHorzRound, sal_uLong nVertRound )
70 : {
71 10978 : assert_if_double_buffered_window();
72 :
73 10978 : if ( mpMetaFile )
74 0 : mpMetaFile->AddAction( new MetaRoundRectAction( rRect, nHorzRound, nVertRound ) );
75 :
76 10978 : if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
77 20084 : return;
78 :
79 936 : const Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
80 :
81 936 : if ( aRect.IsEmpty() )
82 0 : return;
83 :
84 936 : nHorzRound = ImplLogicWidthToDevicePixel( nHorzRound );
85 936 : nVertRound = ImplLogicHeightToDevicePixel( nVertRound );
86 :
87 : // we need a graphics
88 936 : if ( !mpGraphics )
89 : {
90 0 : if ( !AcquireGraphics() )
91 0 : return;
92 : }
93 :
94 936 : if ( mbInitClipRegion )
95 0 : InitClipRegion();
96 :
97 936 : if ( mbOutputClipped )
98 0 : return;
99 :
100 936 : if ( mbInitLineColor )
101 936 : InitLineColor();
102 :
103 936 : if ( mbInitFillColor )
104 936 : InitFillColor();
105 :
106 936 : if ( !nHorzRound && !nVertRound )
107 : {
108 0 : mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
109 : }
110 : else
111 : {
112 936 : const Polygon aRoundRectPoly( aRect, nHorzRound, nVertRound );
113 :
114 936 : if ( aRoundRectPoly.GetSize() >= 2 )
115 : {
116 936 : const SalPoint* pPtAry = reinterpret_cast<const SalPoint*>(aRoundRectPoly.GetConstPointAry());
117 :
118 936 : if ( !mbFillColor )
119 936 : mpGraphics->DrawPolyLine( aRoundRectPoly.GetSize(), pPtAry, this );
120 : else
121 0 : mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry, this );
122 936 : }
123 : }
124 :
125 936 : if( mpAlphaVDev )
126 0 : mpAlphaVDev->DrawRect( rRect, nHorzRound, nVertRound );
127 : }
128 :
129 31 : void OutputDevice::DrawCheckered(const Point& rPos, const Size& rSize, sal_uInt32 nLen, Color aStart, Color aEnd)
130 : {
131 31 : assert_if_double_buffered_window();
132 :
133 31 : const sal_uInt32 nMaxX(rPos.X() + rSize.Width());
134 31 : const sal_uInt32 nMaxY(rPos.Y() + rSize.Height());
135 :
136 31 : Push(PushFlags::LINECOLOR|PushFlags::FILLCOLOR);
137 31 : SetLineColor();
138 :
139 301 : for(sal_uInt32 x(0), nX(rPos.X()); nX < nMaxX; x++, nX += nLen)
140 : {
141 270 : const sal_uInt32 nRight(std::min(nMaxX, nX + nLen));
142 :
143 810 : for(sal_uInt32 y(0), nY(rPos.Y()); nY < nMaxY; y++, nY += nLen)
144 : {
145 540 : const sal_uInt32 nBottom(std::min(nMaxY, nY + nLen));
146 :
147 540 : SetFillColor((x & 0x0001) ^ (y & 0x0001) ? aStart : aEnd);
148 540 : DrawRect(Rectangle(nX, nY, nRight, nBottom));
149 : }
150 : }
151 :
152 31 : Pop();
153 31 : }
154 :
155 2316 : void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, DrawGridFlags nFlags )
156 : {
157 2316 : assert_if_double_buffered_window();
158 :
159 2316 : Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
160 2316 : aDstRect.Intersection( rRect );
161 :
162 2316 : if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
163 0 : return;
164 :
165 2316 : if( !mpGraphics && !AcquireGraphics() )
166 0 : return;
167 :
168 2316 : if( mbInitClipRegion )
169 40 : InitClipRegion();
170 :
171 2316 : if( mbOutputClipped )
172 0 : return;
173 :
174 2316 : const long nDistX = std::max( rDist.Width(), 1L );
175 2316 : const long nDistY = std::max( rDist.Height(), 1L );
176 2316 : long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
177 2316 : long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
178 2316 : const long nRight = aDstRect.Right();
179 2316 : const long nBottom = aDstRect.Bottom();
180 2316 : const long nStartX = ImplLogicXToDevicePixel( nX );
181 2316 : const long nEndX = ImplLogicXToDevicePixel( nRight );
182 2316 : const long nStartY = ImplLogicYToDevicePixel( nY );
183 2316 : const long nEndY = ImplLogicYToDevicePixel( nBottom );
184 2316 : long nHorzCount = 0L;
185 2316 : long nVertCount = 0L;
186 :
187 2316 : css::uno::Sequence< sal_Int32 > aVertBuf;
188 4632 : css::uno::Sequence< sal_Int32 > aHorzBuf;
189 :
190 2316 : if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::HorzLines ) )
191 : {
192 1531 : aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
193 1531 : aVertBuf[ nVertCount++ ] = nStartY;
194 20350 : while( ( nY += nDistY ) <= nBottom )
195 : {
196 17288 : aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
197 : }
198 : }
199 :
200 2316 : if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::VertLines ) )
201 : {
202 1430 : aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
203 1430 : aHorzBuf[ nHorzCount++ ] = nStartX;
204 17179 : while( ( nX += nDistX ) <= nRight )
205 : {
206 14319 : aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
207 : }
208 : }
209 :
210 2316 : if( mbInitLineColor )
211 940 : InitLineColor();
212 :
213 2316 : if( mbInitFillColor )
214 0 : InitFillColor();
215 :
216 2316 : const bool bOldMap = mbMap;
217 2316 : EnableMapMode( false );
218 :
219 2316 : if( nFlags & DrawGridFlags::Dots )
220 : {
221 8775 : for( long i = 0L; i < nVertCount; i++ )
222 : {
223 162236 : for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
224 : {
225 154106 : mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
226 : }
227 : }
228 : }
229 : else
230 : {
231 1671 : if( nFlags & DrawGridFlags::HorzLines )
232 : {
233 11575 : for( long i = 0L; i < nVertCount; i++ )
234 : {
235 10689 : nY = aVertBuf[ i ];
236 10689 : mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
237 : }
238 : }
239 :
240 1671 : if( nFlags & DrawGridFlags::VertLines )
241 : {
242 4307 : for( long i = 0L; i < nHorzCount; i++ )
243 : {
244 3522 : nX = aHorzBuf[ i ];
245 3522 : mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
246 : }
247 : }
248 : }
249 :
250 2316 : EnableMapMode( bOldMap );
251 :
252 2316 : if( mpAlphaVDev )
253 2316 : mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
254 : }
255 :
256 182025 : BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
257 : {
258 182025 : BmpMirrorFlags nMirrFlags = BmpMirrorFlags::NONE;
259 :
260 182025 : if ( rTwoRect.mnDestWidth < 0 )
261 : {
262 0 : rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
263 0 : rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
264 0 : rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
265 0 : nMirrFlags |= BmpMirrorFlags::Horizontal;
266 : }
267 :
268 182025 : if ( rTwoRect.mnDestHeight < 0 )
269 : {
270 0 : rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
271 0 : rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
272 0 : rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
273 0 : nMirrFlags |= BmpMirrorFlags::Vertical;
274 : }
275 :
276 728100 : if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
277 546075 : ( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||
278 546075 : ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
279 182025 : ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
280 : {
281 : const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
282 0 : Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
283 0 : Rectangle aCropRect( aSourceRect );
284 :
285 0 : aCropRect.Intersection( Rectangle( Point(), rSizePix ) );
286 :
287 0 : if( aCropRect.IsEmpty() )
288 : {
289 0 : rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
290 : }
291 : else
292 : {
293 0 : const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
294 0 : const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
295 :
296 0 : const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
297 0 : const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
298 0 : const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
299 0 : const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
300 :
301 0 : rTwoRect.mnSrcX = aCropRect.Left();
302 0 : rTwoRect.mnSrcY = aCropRect.Top();
303 0 : rTwoRect.mnSrcWidth = aCropRect.GetWidth();
304 0 : rTwoRect.mnSrcHeight = aCropRect.GetHeight();
305 0 : rTwoRect.mnDestX = nDstX1;
306 0 : rTwoRect.mnDestY = nDstY1;
307 0 : rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
308 0 : rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
309 : }
310 : }
311 :
312 182025 : return nMirrFlags;
313 : }
314 :
315 93442 : void AdjustTwoRect( SalTwoRect& rTwoRect, const Rectangle& rValidSrcRect )
316 : {
317 373069 : if( ( rTwoRect.mnSrcX < rValidSrcRect.Left() ) || ( rTwoRect.mnSrcX >= rValidSrcRect.Right() ) ||
318 278418 : ( rTwoRect.mnSrcY < rValidSrcRect.Top() ) || ( rTwoRect.mnSrcY >= rValidSrcRect.Bottom() ) ||
319 203193 : ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rValidSrcRect.Right() ) ||
320 16950 : ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rValidSrcRect.Bottom() ) )
321 : {
322 : const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
323 86020 : Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
324 86020 : Rectangle aCropRect( aSourceRect );
325 :
326 86020 : aCropRect.Intersection( rValidSrcRect );
327 :
328 86020 : if( aCropRect.IsEmpty() )
329 : {
330 98 : rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
331 : }
332 : else
333 : {
334 85922 : const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
335 85922 : const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
336 :
337 85922 : const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
338 85922 : const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
339 85922 : const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
340 85922 : const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
341 :
342 85922 : rTwoRect.mnSrcX = aCropRect.Left();
343 85922 : rTwoRect.mnSrcY = aCropRect.Top();
344 85922 : rTwoRect.mnSrcWidth = aCropRect.GetWidth();
345 85922 : rTwoRect.mnSrcHeight = aCropRect.GetHeight();
346 85922 : rTwoRect.mnDestX = nDstX1;
347 85922 : rTwoRect.mnDestY = nDstY1;
348 85922 : rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
349 85922 : rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
350 : }
351 : }
352 94243 : }
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|