update emoji autocorrect entries from po-files
[LibreOffice.git] / vcl / source / outdev / rect.cxx
blob03afdf9893bdebccf82141ea3db4242e496117ba
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <cassert>
22 #include <sal/types.h>
24 #include <tools/poly.hxx>
25 #include <tools/helpers.hxx>
27 #include <vcl/outdev.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/window.hxx>
31 #include "salgdi.hxx"
33 void OutputDevice::DrawRect( const Rectangle& rRect )
35 assert(!is_double_buffered_window());
37 if ( mpMetaFile )
38 mpMetaFile->AddAction( new MetaRectAction( rRect ) );
40 if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
41 return;
43 Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
45 if ( aRect.IsEmpty() )
46 return;
48 aRect.Justify();
50 if ( !mpGraphics && !AcquireGraphics() )
51 return;
53 if ( mbInitClipRegion )
54 InitClipRegion();
56 if ( mbOutputClipped )
57 return;
59 if ( mbInitLineColor )
60 InitLineColor();
62 if ( mbInitFillColor )
63 InitFillColor();
65 mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
67 if( mpAlphaVDev )
68 mpAlphaVDev->DrawRect( rRect );
71 void OutputDevice::DrawRect( const Rectangle& rRect,
72 sal_uLong nHorzRound, sal_uLong nVertRound )
74 assert(!is_double_buffered_window());
76 if ( mpMetaFile )
77 mpMetaFile->AddAction( new MetaRoundRectAction( rRect, nHorzRound, nVertRound ) );
79 if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
80 return;
82 const Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
84 if ( aRect.IsEmpty() )
85 return;
87 nHorzRound = ImplLogicWidthToDevicePixel( nHorzRound );
88 nVertRound = ImplLogicHeightToDevicePixel( nVertRound );
90 // we need a graphics
91 if ( !mpGraphics )
93 if ( !AcquireGraphics() )
94 return;
97 if ( mbInitClipRegion )
98 InitClipRegion();
100 if ( mbOutputClipped )
101 return;
103 if ( mbInitLineColor )
104 InitLineColor();
106 if ( mbInitFillColor )
107 InitFillColor();
109 if ( !nHorzRound && !nVertRound )
111 mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
113 else
115 const Polygon aRoundRectPoly( aRect, nHorzRound, nVertRound );
117 if ( aRoundRectPoly.GetSize() >= 2 )
119 const SalPoint* pPtAry = reinterpret_cast<const SalPoint*>(aRoundRectPoly.GetConstPointAry());
121 if ( !mbFillColor )
122 mpGraphics->DrawPolyLine( aRoundRectPoly.GetSize(), pPtAry, this );
123 else
124 mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry, this );
128 if( mpAlphaVDev )
129 mpAlphaVDev->DrawRect( rRect, nHorzRound, nVertRound );
132 void OutputDevice::Invert( const Rectangle& rRect, sal_uInt16 nFlags )
134 assert(!is_double_buffered_window());
135 if ( !IsDeviceOutputNecessary() )
136 return;
138 Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
140 if ( aRect.IsEmpty() )
141 return;
142 aRect.Justify();
144 // we need a graphics
145 if ( !mpGraphics )
147 if ( !AcquireGraphics() )
148 return;
151 if ( mbInitClipRegion )
152 InitClipRegion();
154 if ( mbOutputClipped )
155 return;
157 SalInvert nSalFlags = 0;
158 if ( nFlags & INVERT_HIGHLIGHT )
159 nSalFlags |= SAL_INVERT_HIGHLIGHT;
160 if ( nFlags & INVERT_50 )
161 nSalFlags |= SAL_INVERT_50;
162 mpGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), nSalFlags, this );
165 void OutputDevice::Invert( const Polygon& rPoly, sal_uInt16 nFlags )
167 assert(!is_double_buffered_window());
168 if ( !IsDeviceOutputNecessary() )
169 return;
171 sal_uInt16 nPoints = rPoly.GetSize();
173 if ( nPoints < 2 )
174 return;
176 Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
178 // we need a graphics
179 if ( !mpGraphics )
181 if ( !AcquireGraphics() )
182 return;
185 if ( mbInitClipRegion )
186 InitClipRegion();
188 if ( mbOutputClipped )
189 return;
191 SalInvert nSalFlags = 0;
192 if ( nFlags & INVERT_HIGHLIGHT )
193 nSalFlags |= SAL_INVERT_HIGHLIGHT;
194 if ( nFlags & INVERT_50 )
195 nSalFlags |= SAL_INVERT_50;
196 const SalPoint* pPtAry = reinterpret_cast<const SalPoint*>(aPoly.GetConstPointAry());
197 mpGraphics->Invert( nPoints, pPtAry, nSalFlags, this );
200 void OutputDevice::DrawCheckered(const Point& rPos, const Size& rSize, sal_uInt32 nLen, Color aStart, Color aEnd)
202 assert(!is_double_buffered_window());
204 const sal_uInt32 nMaxX(rPos.X() + rSize.Width());
205 const sal_uInt32 nMaxY(rPos.Y() + rSize.Height());
207 Push(PushFlags::LINECOLOR|PushFlags::FILLCOLOR);
208 SetLineColor();
210 for(sal_uInt32 x(0), nX(rPos.X()); nX < nMaxX; x++, nX += nLen)
212 const sal_uInt32 nRight(std::min(nMaxX, nX + nLen));
214 for(sal_uInt32 y(0), nY(rPos.Y()); nY < nMaxY; y++, nY += nLen)
216 const sal_uInt32 nBottom(std::min(nMaxY, nY + nLen));
218 SetFillColor((x & 0x0001) ^ (y & 0x0001) ? aStart : aEnd);
219 DrawRect(Rectangle(nX, nY, nRight, nBottom));
223 Pop();
226 void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, DrawGridFlags nFlags )
228 assert(!is_double_buffered_window());
230 Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
231 aDstRect.Intersection( rRect );
233 if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
234 return;
236 if( !mpGraphics && !AcquireGraphics() )
237 return;
239 if( mbInitClipRegion )
240 InitClipRegion();
242 if( mbOutputClipped )
243 return;
245 const long nDistX = std::max( rDist.Width(), 1L );
246 const long nDistY = std::max( rDist.Height(), 1L );
247 long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
248 long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
249 const long nRight = aDstRect.Right();
250 const long nBottom = aDstRect.Bottom();
251 const long nStartX = ImplLogicXToDevicePixel( nX );
252 const long nEndX = ImplLogicXToDevicePixel( nRight );
253 const long nStartY = ImplLogicYToDevicePixel( nY );
254 const long nEndY = ImplLogicYToDevicePixel( nBottom );
255 long nHorzCount = 0L;
256 long nVertCount = 0L;
258 css::uno::Sequence< sal_Int32 > aVertBuf;
259 css::uno::Sequence< sal_Int32 > aHorzBuf;
261 if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::HorzLines ) )
263 aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
264 aVertBuf[ nVertCount++ ] = nStartY;
265 while( ( nY += nDistY ) <= nBottom )
267 aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
271 if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::VertLines ) )
273 aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
274 aHorzBuf[ nHorzCount++ ] = nStartX;
275 while( ( nX += nDistX ) <= nRight )
277 aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
281 if( mbInitLineColor )
282 InitLineColor();
284 if( mbInitFillColor )
285 InitFillColor();
287 const bool bOldMap = mbMap;
288 EnableMapMode( false );
290 if( nFlags & DrawGridFlags::Dots )
292 for( long i = 0L; i < nVertCount; i++ )
294 for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
296 mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
300 else
302 if( nFlags & DrawGridFlags::HorzLines )
304 for( long i = 0L; i < nVertCount; i++ )
306 nY = aVertBuf[ i ];
307 mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
311 if( nFlags & DrawGridFlags::VertLines )
313 for( long i = 0L; i < nHorzCount; i++ )
315 nX = aHorzBuf[ i ];
316 mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
321 EnableMapMode( bOldMap );
323 if( mpAlphaVDev )
324 mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
327 BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
329 BmpMirrorFlags nMirrFlags = BmpMirrorFlags::NONE;
331 if ( rTwoRect.mnDestWidth < 0 )
333 rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
334 rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
335 rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
336 nMirrFlags |= BmpMirrorFlags::Horizontal;
339 if ( rTwoRect.mnDestHeight < 0 )
341 rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
342 rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
343 rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
344 nMirrFlags |= BmpMirrorFlags::Vertical;
347 if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
348 ( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||
349 ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
350 ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
352 const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
353 Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
354 Rectangle aCropRect( aSourceRect );
356 aCropRect.Intersection( Rectangle( Point(), rSizePix ) );
358 if( aCropRect.IsEmpty() )
360 rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
362 else
364 const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
365 const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
367 const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
368 const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
369 const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
370 const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
372 rTwoRect.mnSrcX = aCropRect.Left();
373 rTwoRect.mnSrcY = aCropRect.Top();
374 rTwoRect.mnSrcWidth = aCropRect.GetWidth();
375 rTwoRect.mnSrcHeight = aCropRect.GetHeight();
376 rTwoRect.mnDestX = nDstX1;
377 rTwoRect.mnDestY = nDstY1;
378 rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
379 rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
383 return nMirrFlags;
386 void AdjustTwoRect( SalTwoRect& rTwoRect, const Rectangle& rValidSrcRect )
388 if( ( rTwoRect.mnSrcX < rValidSrcRect.Left() ) || ( rTwoRect.mnSrcX >= rValidSrcRect.Right() ) ||
389 ( rTwoRect.mnSrcY < rValidSrcRect.Top() ) || ( rTwoRect.mnSrcY >= rValidSrcRect.Bottom() ) ||
390 ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rValidSrcRect.Right() ) ||
391 ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rValidSrcRect.Bottom() ) )
393 const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
394 Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
395 Rectangle aCropRect( aSourceRect );
397 aCropRect.Intersection( rValidSrcRect );
399 if( aCropRect.IsEmpty() )
401 rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
403 else
405 const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
406 const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
408 const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
409 const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
410 const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
411 const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
413 rTwoRect.mnSrcX = aCropRect.Left();
414 rTwoRect.mnSrcY = aCropRect.Top();
415 rTwoRect.mnSrcWidth = aCropRect.GetWidth();
416 rTwoRect.mnSrcHeight = aCropRect.GetHeight();
417 rTwoRect.mnDestX = nDstX1;
418 rTwoRect.mnDestY = nDstY1;
419 rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
420 rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */