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