LibreOffice Module vcl (master) 1
rect.cxx
Go to the documentation of this file.
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 <sal/types.h>
21#include <tools/poly.hxx>
22#include <tools/helpers.hxx>
23
24#include <vcl/metaact.hxx>
25#include <vcl/virdev.hxx>
26
27#include <salgdi.hxx>
28
29#include <cassert>
30
32{
33 sal_uInt16 nPixel = static_cast<sal_uInt16>(PixelToLogic(Size(1, 1)).Width());
34
35 aBorderRect.AdjustLeft(nPixel);
36 aBorderRect.AdjustTop(nPixel);
37
39 DrawRect(aBorderRect);
40
41 aBorderRect.AdjustLeft(-nPixel);
42 aBorderRect.AdjustTop(-nPixel);
43 aBorderRect.AdjustRight(-nPixel);
44 aBorderRect.AdjustBottom(-nPixel);
46
47 DrawRect(aBorderRect);
48}
49
51{
53
54 if ( mpMetaFile )
55 mpMetaFile->AddAction( new MetaRectAction( rRect ) );
56
58 return;
59
61
62 if ( aRect.IsEmpty() )
63 return;
64
65 aRect.Normalize();
66
67 if ( !mpGraphics && !AcquireGraphics() )
68 return;
69 assert(mpGraphics);
70
71 if ( mbInitClipRegion )
73
74 if ( mbOutputClipped )
75 return;
76
77 if ( mbInitLineColor )
79
80 if ( mbInitFillColor )
82
83 mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), *this );
84
85 if( mpAlphaVDev )
86 mpAlphaVDev->DrawRect( rRect );
87}
88
90 sal_uLong nHorzRound, sal_uLong nVertRound )
91{
93
94 if ( mpMetaFile )
95 mpMetaFile->AddAction( new MetaRoundRectAction( rRect, nHorzRound, nVertRound ) );
96
98 return;
99
100 const tools::Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
101
102 if ( aRect.IsEmpty() )
103 return;
104
105 nHorzRound = ImplLogicWidthToDevicePixel( nHorzRound );
106 nVertRound = ImplLogicHeightToDevicePixel( nVertRound );
107
108 // we need a graphics
109 if ( !mpGraphics && !AcquireGraphics() )
110 return;
111 assert(mpGraphics);
112
113 if ( mbInitClipRegion )
115
116 if ( mbOutputClipped )
117 return;
118
119 if ( mbInitLineColor )
121
122 if ( mbInitFillColor )
124
125 if ( !nHorzRound && !nVertRound )
126 {
127 mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), *this );
128 }
129 else
130 {
131 tools::Polygon aRoundRectPoly( aRect, nHorzRound, nVertRound );
132
133 if ( aRoundRectPoly.GetSize() >= 2 )
134 {
135 Point* pPtAry = aRoundRectPoly.GetPointAry();
136
137 if ( !mbFillColor )
138 mpGraphics->DrawPolyLine( aRoundRectPoly.GetSize(), pPtAry, *this );
139 else
140 mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry, *this );
141 }
142 }
143
144 if( mpAlphaVDev )
145 mpAlphaVDev->DrawRect( rRect, nHorzRound, nVertRound );
146}
147
149{
150 assert(!is_double_buffered_window());
152 return;
153
155
156 if ( aRect.IsEmpty() )
157 return;
158 aRect.Normalize();
159
160 // we need a graphics
161 if ( !mpGraphics && !AcquireGraphics() )
162 return;
163 assert(mpGraphics);
164
165 if ( mbInitClipRegion )
167
168 if ( mbOutputClipped )
169 return;
170
171 SalInvert nSalFlags = SalInvert::NONE;
172 if ( nFlags & InvertFlags::N50 )
173 nSalFlags |= SalInvert::N50;
174 if ( nFlags & InvertFlags::TrackFrame )
175 nSalFlags |= SalInvert::TrackFrame;
176 mpGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), nSalFlags, *this );
177}
178
180{
181 assert(!is_double_buffered_window());
183 return;
184
185 sal_uInt16 nPoints = rPoly.GetSize();
186
187 if ( nPoints < 2 )
188 return;
189
190 tools::Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
191
192 // we need a graphics
193 if ( !mpGraphics && !AcquireGraphics() )
194 return;
195 assert(mpGraphics);
196
197 if ( mbInitClipRegion )
199
200 if ( mbOutputClipped )
201 return;
202
203 SalInvert nSalFlags = SalInvert::NONE;
204 if ( nFlags & InvertFlags::N50 )
205 nSalFlags |= SalInvert::N50;
206 if ( nFlags & InvertFlags::TrackFrame )
207 nSalFlags |= SalInvert::TrackFrame;
208 const Point* pPtAry = aPoly.GetConstPointAry();
209 mpGraphics->Invert( nPoints, pPtAry, nSalFlags, *this );
210}
211
212void OutputDevice::DrawCheckered(const Point& rPos, const Size& rSize, sal_uInt32 nLen, Color aStart, Color aEnd)
213{
214 assert(!is_double_buffered_window());
215
216 const sal_uInt32 nMaxX(rPos.X() + rSize.Width());
217 const sal_uInt32 nMaxY(rPos.Y() + rSize.Height());
218
220 SetLineColor();
221
222 for(sal_uInt32 x(0), nX(rPos.X()); nX < nMaxX; x++, nX += nLen)
223 {
224 const sal_uInt32 nRight(std::min(nMaxX, nX + nLen));
225
226 for(sal_uInt32 y(0), nY(rPos.Y()); nY < nMaxY; y++, nY += nLen)
227 {
228 const sal_uInt32 nBottom(std::min(nMaxY, nY + nLen));
229
230 SetFillColor(((x & 0x0001) ^ (y & 0x0001)) ? aStart : aEnd);
231 DrawRect(tools::Rectangle(nX, nY, nRight, nBottom));
232 }
233 }
234
235 Pop();
236}
237
238void OutputDevice::DrawGrid( const tools::Rectangle& rRect, const Size& rDist, DrawGridFlags nFlags )
239{
240 assert(!is_double_buffered_window());
241
243 aDstRect.Intersection( rRect );
244
245 if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
246 return;
247
248 if( !mpGraphics && !AcquireGraphics() )
249 return;
250 assert(mpGraphics);
251
252 if( mbInitClipRegion )
254
255 if( mbOutputClipped )
256 return;
257
258 const tools::Long nDistX = std::max( rDist.Width(), tools::Long(1) );
259 const tools::Long nDistY = std::max( rDist.Height(), tools::Long(1) );
260 tools::Long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
261 tools::Long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
262 const tools::Long nRight = aDstRect.Right();
263 const tools::Long nBottom = aDstRect.Bottom();
264 const tools::Long nStartX = ImplLogicXToDevicePixel( nX );
265 const tools::Long nEndX = ImplLogicXToDevicePixel( nRight );
266 const tools::Long nStartY = ImplLogicYToDevicePixel( nY );
267 const tools::Long nEndY = ImplLogicYToDevicePixel( nBottom );
268 tools::Long nHorzCount = 0;
269 tools::Long nVertCount = 0;
270
271 std::vector< sal_Int32 > aVertBuf;
272 std::vector< sal_Int32 > aHorzBuf;
273
274 if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::HorzLines ) )
275 {
276 aVertBuf.resize( aDstRect.GetHeight() / nDistY + 2 );
277 aVertBuf[ nVertCount++ ] = nStartY;
278 while( ( nY += nDistY ) <= nBottom )
279 {
280 aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
281 }
282 }
283
284 if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::VertLines ) )
285 {
286 aHorzBuf.resize( aDstRect.GetWidth() / nDistX + 2 );
287 aHorzBuf[ nHorzCount++ ] = nStartX;
288 while( ( nX += nDistX ) <= nRight )
289 {
290 aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
291 }
292 }
293
294 if( mbInitLineColor )
296
297 if( mbInitFillColor )
299
300 const bool bOldMap = mbMap;
301 EnableMapMode( false );
302
303 if( nFlags & DrawGridFlags::Dots )
304 {
305 for( tools::Long i = 0; i < nVertCount; i++ )
306 {
307 for( tools::Long j = 0, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
308 {
309 mpGraphics->DrawPixel( aHorzBuf[ j ], Y, *this );
310 }
311 }
312 }
313 else
314 {
315 if( nFlags & DrawGridFlags::HorzLines )
316 {
317 for( tools::Long i = 0; i < nVertCount; i++ )
318 {
319 nY = aVertBuf[ i ];
320 mpGraphics->DrawLine( nStartX, nY, nEndX, nY, *this );
321 }
322 }
323
324 if( nFlags & DrawGridFlags::VertLines )
325 {
326 for( tools::Long i = 0; i < nHorzCount; i++ )
327 {
328 nX = aHorzBuf[ i ];
329 mpGraphics->DrawLine( nX, nStartY, nX, nEndY, *this );
330 }
331 }
332 }
333
334 EnableMapMode( bOldMap );
335
336 if( mpAlphaVDev )
337 mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
338}
339
340BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
341{
343
344 if ( rTwoRect.mnDestWidth < 0 )
345 {
346 rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
347 rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
348 rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
349 nMirrFlags |= BmpMirrorFlags::Horizontal;
350 }
351
352 if ( rTwoRect.mnDestHeight < 0 )
353 {
354 rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
355 rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
356 rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
357 nMirrFlags |= BmpMirrorFlags::Vertical;
358 }
359
360 if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
361 ( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||
362 ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
363 ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
364 {
365 const tools::Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
366 Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
367 tools::Rectangle aCropRect( aSourceRect );
368
369 aCropRect.Intersection( tools::Rectangle( Point(), rSizePix ) );
370
371 if( aCropRect.IsEmpty() )
372 {
373 rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
374 }
375 else
376 {
377 const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? static_cast<double>( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
378 const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? static_cast<double>( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
379
380 const tools::Long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
381 const tools::Long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
382 const tools::Long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
383 const tools::Long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
384
385 rTwoRect.mnSrcX = aCropRect.Left();
386 rTwoRect.mnSrcY = aCropRect.Top();
387 rTwoRect.mnSrcWidth = aCropRect.GetWidth();
388 rTwoRect.mnSrcHeight = aCropRect.GetHeight();
389 rTwoRect.mnDestX = nDstX1;
390 rTwoRect.mnDestY = nDstY1;
391 rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
392 rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
393 }
394 }
395
396 return nMirrFlags;
397}
398
399void AdjustTwoRect( SalTwoRect& rTwoRect, const tools::Rectangle& rValidSrcRect )
400{
401 if( !(( rTwoRect.mnSrcX < rValidSrcRect.Left() ) || ( rTwoRect.mnSrcX >= rValidSrcRect.Right() ) ||
402 ( rTwoRect.mnSrcY < rValidSrcRect.Top() ) || ( rTwoRect.mnSrcY >= rValidSrcRect.Bottom() ) ||
403 ( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rValidSrcRect.Right() ) ||
404 ( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rValidSrcRect.Bottom() )) )
405 return;
406
407 const tools::Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
408 Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
409 tools::Rectangle aCropRect( aSourceRect );
410
411 aCropRect.Intersection( rValidSrcRect );
412
413 if( aCropRect.IsEmpty() )
414 {
415 rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
416 }
417 else
418 {
419 const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? static_cast<double>( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
420 const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? static_cast<double>( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
421
422 const tools::Long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
423 const tools::Long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
424 const tools::Long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
425 const tools::Long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
426
427 rTwoRect.mnSrcX = aCropRect.Left();
428 rTwoRect.mnSrcY = aCropRect.Top();
429 rTwoRect.mnSrcWidth = aCropRect.GetWidth();
430 rTwoRect.mnSrcHeight = aCropRect.GetHeight();
431 rTwoRect.mnDestX = nDstX1;
432 rTwoRect.mnDestY = nDstY1;
433 rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
434 rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
435 }
436}
437
438/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawGridFlags
InvertFlags
Definition: InvertFlags.hxx:25
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:585
Size GetOutputSize() const
Definition: outdev.hxx:327
virtual void InitClipRegion()
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
Definition: map.cxx:271
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:589
SAL_DLLPRIVATE bool is_double_buffered_window() const
virtual void DrawBorder(tools::Rectangle aBorderRect)
Definition: rect.cxx:31
SAL_DLLPRIVATE void InitLineColor()
Definition: line.cxx:85
bool mbOutputClipped
Definition: outdev.hxx:245
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:334
bool mbFillColor
Definition: outdev.hxx:247
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1110
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:708
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:50
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:185
void DrawCheckered(const Point &rPos, const Size &rSize, sal_uInt32 nLen=8, Color aStart=COL_WHITE, Color aEnd=COL_BLACK)
Fill the given rectangle with checkered rectangles of size nLen x nLen using the colors aStart and aE...
Definition: rect.cxx:212
SAL_DLLPRIVATE void InitFillColor()
Definition: fill.cxx:76
bool mbMap
Definition: outdev.hxx:240
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:288
void Invert(const tools::Rectangle &rRect, InvertFlags nFlags=InvertFlags::NONE)
Definition: rect.cxx:148
void SetLineColor()
Definition: line.cxx:37
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
Definition: map.cxx:280
bool mbInitLineColor
Definition: outdev.hxx:248
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:182
void DrawGrid(const tools::Rectangle &rRect, const Size &rDist, DrawGridFlags nFlags)
Definition: rect.cxx:238
bool mbInitClipRegion
Definition: outdev.hxx:252
void SetFillColor()
Definition: fill.cxx:29
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:481
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:196
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:32
void Pop()
Definition: stack.cxx:91
bool mbLineColor
Definition: outdev.hxx:246
SAL_DLLPRIVATE tools::Long ImplLogicXToDevicePixel(tools::Long nX) const
Convert a logical X coordinate to a device pixel's X coordinate.
Definition: map.cxx:262
bool mbInitFillColor
Definition: outdev.hxx:249
constexpr tools::Long Y() const
constexpr tools::Long X() const
void DrawPixel(tools::Long nX, tools::Long nY, const OutputDevice &rOutDev)
void DrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, const OutputDevice &rOutDev)
void Invert(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, SalInvert nFlags, const OutputDevice &rOutDev)
void DrawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
void DrawPolyLine(sal_uInt32 nPoints, Point const *pPtAry, const OutputDevice &rOutDev)
void DrawPolygon(sal_uInt32 nPoints, const Point *pPtAry, const OutputDevice &rOutDev)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const Point * GetConstPointAry() const
sal_uInt16 GetSize() const
Point * GetPointAry()
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
constexpr ::Color COL_GRAY(0x80, 0x80, 0x80)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
float y
float x
tools::Long FRound(double fVal)
BmpMirrorFlags
int i
long Long
#define Y
BmpMirrorFlags AdjustTwoRect(SalTwoRect &rTwoRect, const Size &rSizePix)
Definition: rect.cxx:340
SalInvert
Definition: salgtype.hxx:73
sal_uIntPtr sal_uLong
#define nPixel
tools::Long mnDestY
Definition: salgtype.hxx:44
tools::Long mnSrcX
Definition: salgtype.hxx:39
tools::Long mnDestWidth
Definition: salgtype.hxx:45
tools::Long mnSrcHeight
Definition: salgtype.hxx:42
tools::Long mnSrcWidth
Definition: salgtype.hxx:41
tools::Long mnSrcY
Definition: salgtype.hxx:40
tools::Long mnDestHeight
Definition: salgtype.hxx:46
tools::Long mnDestX
Definition: salgtype.hxx:43