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 <vcl/settings.hxx>
21 #include <vcl/outdev.hxx>
22 #include <vcl/decoview.hxx>
23 #include <vcl/window.hxx>
24 #include <vcl/ctrl.hxx>
25 
26 constexpr auto BUTTON_DRAW_FLATTEST = DrawButtonFlags::Flat |
27                                  DrawButtonFlags::Pressed |
28                                  DrawButtonFlags::Checked |
29                                  DrawButtonFlags::Highlight;
30 
31 using namespace std;
32 
33 namespace {
34 
AdjustRectToSquare(tools::Rectangle & rRect)35 tools::Long AdjustRectToSquare( tools::Rectangle &rRect )
36 {
37     const tools::Long nWidth = rRect.GetWidth();
38     const tools::Long nHeight = rRect.GetHeight();
39     tools::Long nSide = std::min( nWidth, nHeight );
40 
41     if ( nSide && !(nSide & 1) )
42     {
43         // we prefer an odd size
44         --nSide;
45     }
46 
47     // Make the rectangle a square
48     rRect.SetSize( Size( nSide, nSide ) );
49 
50     // and place it at the center of the original rectangle
51     rRect.Move( (nWidth-nSide)/2, (nHeight-nSide)/2 );
52 
53     return nSide;
54 }
55 
ImplDrawSymbol(OutputDevice * pDev,tools::Rectangle nRect,const SymbolType eType)56 void ImplDrawSymbol( OutputDevice* pDev, tools::Rectangle nRect, const SymbolType eType  )
57 {
58     const tools::Long nSide = AdjustRectToSquare( nRect );
59 
60     if ( !nSide ) return;
61     if ( nSide==1 )
62     {
63         pDev->DrawPixel( Point( nRect.Left(), nRect.Top() ) );
64         return;
65     }
66 
67     // Precalculate some values
68     const tools::Long n2 = nSide/2;
69     const tools::Long n4 = (n2+1)/2;
70     const tools::Long n8 = (n4+1)/2;
71     const tools::Long n16 = (n8+1)/2;
72     const Point aCenter = nRect.Center();
73 
74     switch ( eType )
75     {
76         case SymbolType::ARROW_UP:
77             pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
78             for ( tools::Long i=1; i <= n2; ++i )
79             {
80                 nRect.AdjustTop( 1 );
81                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
82                                 Point( aCenter.X()+i, nRect.Top() ) );
83                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Top() ) );
84                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Top() ) );
85             }
86             pDev->DrawRect( tools::Rectangle( aCenter.X()-n8, nRect.Top()+1,
87                                        aCenter.X()+n8, nRect.Bottom() ) );
88             break;
89 
90         case SymbolType::ARROW_DOWN:
91             pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
92             for ( tools::Long i=1; i <= n2; ++i )
93             {
94                 nRect.AdjustBottom( -1 );
95                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
96                                 Point( aCenter.X()+i, nRect.Bottom() ) );
97                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Bottom() ) );
98                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Bottom() ) );
99             }
100             pDev->DrawRect( tools::Rectangle( aCenter.X()-n8, nRect.Top(),
101                                        aCenter.X()+n8, nRect.Bottom()-1 ) );
102             break;
103 
104         case SymbolType::ARROW_LEFT:
105             pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
106             for ( tools::Long i=1; i <= n2; ++i )
107             {
108                 nRect.AdjustLeft( 1 );
109                 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-i ),
110                                 Point( nRect.Left(), aCenter.Y()+i ) );
111                 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y()-i ) );
112                 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y()+i ) );
113             }
114             pDev->DrawRect( tools::Rectangle( nRect.Left()+1, aCenter.Y()-n8,
115                                        nRect.Right(), aCenter.Y()+n8 ) );
116             break;
117 
118         case SymbolType::ARROW_RIGHT:
119             pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
120             for ( tools::Long i=1; i <= n2; ++i )
121             {
122                 nRect.AdjustRight( -1 );
123                 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-i ),
124                                 Point( nRect.Right(), aCenter.Y()+i ) );
125                 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y()-i ) );
126                 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y()+i ) );
127             }
128             pDev->DrawRect( tools::Rectangle( nRect.Left(), aCenter.Y()-n8,
129                                        nRect.Right()-1, aCenter.Y()+n8 ) );
130             break;
131 
132         case SymbolType::SPIN_UP:
133             nRect.AdjustTop(n4 );
134             pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
135             for ( tools::Long i=1; i <= n2; ++i )
136             {
137                 nRect.AdjustTop( 1 );
138                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
139                                 Point( aCenter.X()+i, nRect.Top() ) );
140                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Top() ) );
141                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Top() ) );
142             }
143             break;
144 
145         case SymbolType::SPIN_DOWN:
146             nRect.AdjustBottom( -n4 );
147             pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
148             for ( tools::Long i=1; i <= n2; ++i )
149             {
150                 nRect.AdjustBottom( -1 );
151                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
152                                 Point( aCenter.X()+i, nRect.Bottom() ) );
153                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Bottom() ) );
154                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Bottom() ) );
155             }
156             break;
157 
158         case SymbolType::SPIN_LEFT:
159         case SymbolType::FIRST:
160         case SymbolType::PREV:
161         {
162             nRect.AdjustLeft(n4 );
163             if ( eType==SymbolType::FIRST )
164             {
165                 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
166                                 Point( nRect.Left(), nRect.Bottom() ) );
167                 nRect.AdjustLeft( 1 );
168             }
169 
170             tools::Polygon aTriangle(3);
171             aTriangle.SetPoint(Point(nRect.Left() + n2,  aCenter.Y() - n2), 0);
172             aTriangle.SetPoint(Point(nRect.Left(), aCenter.Y()), 1);
173             aTriangle.SetPoint(Point(nRect.Left() + n2, aCenter.Y() + n2), 2);
174 
175             pDev->Push(PushFlags::LINECOLOR);
176             pDev->SetLineColor();
177             pDev->DrawPolygon(aTriangle);
178             pDev->Pop();
179 
180             break;
181         }
182 
183         case SymbolType::SPIN_RIGHT:
184         case SymbolType::LAST:
185         case SymbolType::NEXT:
186         case SymbolType::PLAY:
187         {
188             nRect.AdjustRight( -n4 );
189             if ( eType==SymbolType::LAST )
190             {
191                 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
192                                 Point( nRect.Right(), nRect.Bottom() ) );
193                 nRect.AdjustRight( -1 );
194             }
195 
196             tools::Polygon aTriangle(3);
197             aTriangle.SetPoint(Point(nRect.Right() - n2,  aCenter.Y() - n2), 0);
198             aTriangle.SetPoint(Point(nRect.Right(), aCenter.Y()), 1);
199             aTriangle.SetPoint(Point(nRect.Right() - n2, aCenter.Y() + n2), 2);
200 
201             pDev->Push(PushFlags::LINECOLOR);
202             pDev->SetLineColor();
203             pDev->DrawPolygon(aTriangle);
204             pDev->Pop();
205             break;
206         }
207 
208         case SymbolType::PAGEUP:
209             pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
210             pDev->DrawPixel( Point( aCenter.X(), nRect.Top()+n2 ) );
211             for ( tools::Long i=1; i < n2; ++i )
212             {
213                 nRect.AdjustTop( 1 );
214                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
215                                 Point( aCenter.X()+i, nRect.Top() ) );
216                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Top() ) );
217                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Top() ) );
218                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top()+n2 ),
219                                 Point( aCenter.X()+i, nRect.Top()+n2 ) );
220                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Top()+n2 ) );
221                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Top()+n2 ) );
222             }
223             break;
224 
225         case SymbolType::PAGEDOWN:
226             pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
227             pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom()-n2 ) );
228             for ( tools::Long i=1; i < n2; ++i )
229             {
230                 nRect.AdjustBottom( -1 );
231                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
232                                 Point( aCenter.X()+i, nRect.Bottom() ) );
233                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Bottom() ) );
234                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Bottom() ) );
235                 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom()-n2 ),
236                                 Point( aCenter.X()+i, nRect.Bottom()-n2 ) );
237                 pDev->DrawPixel( Point( aCenter.X()-i, nRect.Bottom()-n2 ) );
238                 pDev->DrawPixel( Point( aCenter.X()+i, nRect.Bottom()-n2 ) );
239             }
240             break;
241 
242         case SymbolType::RADIOCHECKMARK:
243             {
244                 // Midpoint circle algorithm
245                 tools::Long x = 0;
246                 tools::Long y = n2;
247                 tools::Long p = 1 - n2;
248                 // Draw central line
249                 pDev->DrawLine( Point( aCenter.X(), aCenter.Y()-y ),
250                                 Point( aCenter.X(), aCenter.Y()+y ) );
251                 while ( x<y )
252                 {
253                     if ( p>=0 )
254                     {
255                         // Draw vertical lines close to sides
256                         pDev->DrawLine( Point( aCenter.X()+y, aCenter.Y()-x ),
257                                         Point( aCenter.X()+y, aCenter.Y()+x ) );
258                         pDev->DrawLine( Point( aCenter.X()-y, aCenter.Y()-x ),
259                                         Point( aCenter.X()-y, aCenter.Y()+x ) );
260                         --y;
261                         p -= 2*y;
262                     }
263                     ++x;
264                     p += 2*x+1;
265                     // Draw vertical lines close to center
266                     pDev->DrawLine( Point( aCenter.X()-x, aCenter.Y()-y ),
267                                     Point( aCenter.X()-x, aCenter.Y()+y ) );
268                     pDev->DrawLine( Point( aCenter.X()+x, aCenter.Y()-y ),
269                                     Point( aCenter.X()+x, aCenter.Y()+y ) );
270                 }
271             }
272             break;
273 
274         case SymbolType::STOP:
275             pDev->DrawRect( nRect );
276             break;
277 
278         case SymbolType::CLOSE:
279             pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
280                             Point( nRect.Right(), nRect.Bottom() ) );
281             pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
282                             Point( nRect.Right(), nRect.Top() ) );
283             for ( tools::Long i=1; i<n8; ++i )
284             {
285                 pDev->DrawLine( Point( nRect.Left()+i, nRect.Top() ),
286                                 Point( nRect.Right(), nRect.Bottom()-i ) );
287                 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+i ),
288                                 Point( nRect.Right()-i, nRect.Bottom() ) );
289                 pDev->DrawLine( Point( nRect.Left()+i, nRect.Bottom() ),
290                                 Point( nRect.Right(), nRect.Top()+i ) );
291                 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-i ),
292                                 Point( nRect.Right()-i, nRect.Top() ) );
293             }
294             break;
295 
296         case SymbolType::CHECKMARK:
297             {
298                 tools::Long n3 = nSide/3;
299                 nRect.AdjustTop( -(n3/2) );
300                 nRect.AdjustBottom( -(n3/2) );
301                 // #106953# never mirror checkmarks
302                 if ( pDev->HasMirroredGraphics() && pDev->IsRTLEnabled() )
303                 {
304                     // Draw a mirrored checkmark so that it looks "normal" in a
305                     // mirrored graphics device (double mirroring!)
306                     pDev->DrawLine( Point( nRect.Right(), nRect.Bottom()-n3 ),
307                                     Point( nRect.Right()-n3, nRect.Bottom() ) );
308                     pDev->DrawLine( Point( nRect.Right()-n3, nRect.Bottom() ),
309                                     Point( nRect.Left(), nRect.Top()+n3 ) );
310                     nRect.AdjustTop( 1 );
311                     nRect.AdjustBottom( 1 );
312                     pDev->DrawLine( Point( nRect.Right(), nRect.Bottom()-n3 ),
313                                     Point( nRect.Right()-n3, nRect.Bottom() ) );
314                     pDev->DrawLine( Point( nRect.Right()-n3, nRect.Bottom() ),
315                                     Point( nRect.Left(), nRect.Top()+n3 ) );
316                 }
317                 else
318                 {
319                     pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-n3 ),
320                                     Point( nRect.Left()+n3, nRect.Bottom() ) );
321                     pDev->DrawLine( Point( nRect.Left()+n3, nRect.Bottom() ),
322                                     Point( nRect.Right(), nRect.Top()+n3 ) );
323                     nRect.AdjustTop( 1 );
324                     nRect.AdjustBottom( 1 );
325                     pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-n3 ),
326                                     Point( nRect.Left()+n3, nRect.Bottom() ) );
327                     pDev->DrawLine( Point( nRect.Left()+n3, nRect.Bottom() ),
328                                     Point( nRect.Right(), nRect.Top()+n3 ) );
329                 }
330             }
331             break;
332 
333         case SymbolType::FLOAT:
334             nRect.AdjustRight( -n4 );
335             nRect.AdjustTop(n4+1 );
336             pDev->DrawRect( tools::Rectangle( nRect.Left(), nRect.Top(),
337                                        nRect.Right(), nRect.Top()+n8 ) );
338             pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
339                             Point( nRect.Left(), nRect.Bottom() ) );
340             pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
341                             Point( nRect.Right(), nRect.Bottom() ) );
342             pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
343                             Point( nRect.Right(), nRect.Bottom() ) );
344             nRect.AdjustRight(n4 );
345             nRect.AdjustTop( -(n4+1) );
346             nRect.AdjustLeft(n4 );
347             nRect.AdjustBottom( -(n4+1) );
348             pDev->DrawRect( tools::Rectangle( nRect.Left(), nRect.Top(),
349                                        nRect.Right(), nRect.Top()+n8 ) );
350             pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
351                             Point( nRect.Left(), nRect.Bottom() ) );
352             pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
353                             Point( nRect.Right(), nRect.Bottom() ) );
354             pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
355                             Point( nRect.Right(), nRect.Bottom() ) );
356             break;
357 
358         case SymbolType::DOCK:
359             pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
360                             Point( nRect.Right(), nRect.Top() ) );
361             pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
362                             Point( nRect.Left(), nRect.Bottom() ) );
363             pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
364                             Point( nRect.Right(), nRect.Bottom() ) );
365             pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
366                             Point( nRect.Right(), nRect.Bottom() ) );
367             break;
368 
369         case SymbolType::HIDE:
370             pDev->DrawRect( tools::Rectangle( nRect.Left()+n8, nRect.Bottom()-n8,
371                                        nRect.Right()-n8, nRect.Bottom() ) );
372             break;
373 
374         case SymbolType::PLUS:
375             pDev->DrawRect( tools::Rectangle( nRect.Left(), aCenter.Y()-n16,
376                                               nRect.Right(), aCenter.Y()+n16 ) );
377             pDev->DrawRect( tools::Rectangle( aCenter.X()-n16, nRect.Top(),
378                                               aCenter.X()+n16, nRect.Bottom() ) );
379             break;
380         case SymbolType::DONTKNOW:
381         case SymbolType::IMAGE:
382         case SymbolType::HELP: break;
383     }
384 }
385 
ImplDrawDPILineRect(OutputDevice * const pDev,tools::Rectangle & rRect,const Color * const pColor,const bool bRound=false)386 void ImplDrawDPILineRect( OutputDevice *const pDev, tools::Rectangle& rRect,
387                           const Color *const pColor, const bool bRound = false )
388 {
389     tools::Long nLineWidth = pDev->GetDPIX()/300;
390     tools::Long nLineHeight = pDev->GetDPIY()/300;
391     if ( !nLineWidth )
392         nLineWidth = 1;
393     if ( !nLineHeight )
394         nLineHeight = 1;
395 
396     if ( pColor )
397     {
398         if ( (nLineWidth == 1) && (nLineHeight == 1) )
399         {
400             pDev->SetLineColor( *pColor );
401             if( bRound )
402             {
403                 pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()), Point( rRect.Right()-1, rRect.Top()) );
404                 pDev->DrawLine( Point( rRect.Left()+1, rRect.Bottom()), Point( rRect.Right()-1, rRect.Bottom()) );
405                 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+1), Point( rRect.Left(), rRect.Bottom()-1) );
406                 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+1), Point( rRect.Right(), rRect.Bottom()-1) );
407             }
408             else
409             {
410                 pDev->SetFillColor();
411                 pDev->DrawRect( rRect );
412             }
413         }
414         else
415         {
416             const tools::Long nWidth = rRect.GetWidth();
417             const tools::Long nHeight = rRect.GetHeight();
418             pDev->SetLineColor();
419             pDev->SetFillColor( *pColor );
420             pDev->DrawRect( tools::Rectangle( rRect.TopLeft(), Size( nWidth, nLineHeight ) ) );
421             pDev->DrawRect( tools::Rectangle( rRect.TopLeft(), Size( nLineWidth, nHeight ) ) );
422             pDev->DrawRect( tools::Rectangle( Point( rRect.Left(), rRect.Bottom()-nLineHeight ),
423                                        Size( nWidth, nLineHeight ) ) );
424             pDev->DrawRect( tools::Rectangle( Point( rRect.Right()-nLineWidth, rRect.Top() ),
425                                        Size( nLineWidth, nHeight ) ) );
426         }
427     }
428 
429     rRect.AdjustLeft(nLineWidth );
430     rRect.AdjustTop(nLineHeight );
431     rRect.AdjustRight( -nLineWidth );
432     rRect.AdjustBottom( -nLineHeight );
433 }
434 
ImplDraw2ColorFrame(OutputDevice * const pDev,tools::Rectangle & rRect,const Color & rLeftTopColor,const Color & rRightBottomColor)435 void ImplDraw2ColorFrame( OutputDevice *const pDev, tools::Rectangle& rRect,
436                           const Color& rLeftTopColor, const Color& rRightBottomColor )
437 {
438     pDev->SetLineColor( rLeftTopColor );
439     pDev->DrawLine( rRect.TopLeft(), rRect.BottomLeft() );
440     pDev->DrawLine( rRect.TopLeft(), rRect.TopRight() );
441     pDev->SetLineColor( rRightBottomColor );
442     pDev->DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
443     pDev->DrawLine( rRect.TopRight(), rRect.BottomRight() );
444 
445     // reduce drawing area
446     rRect.AdjustLeft( 1 );
447     rRect.AdjustTop( 1 );
448     rRect.AdjustRight( -1 );
449     rRect.AdjustBottom( -1 );
450 }
451 
ImplDrawButton(OutputDevice * const pDev,tools::Rectangle aFillRect,const DrawButtonFlags nStyle)452 void ImplDrawButton( OutputDevice *const pDev, tools::Rectangle aFillRect,
453                      const DrawButtonFlags nStyle )
454 {
455     const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
456 
457     if ( (nStyle & DrawButtonFlags::Mono) ||
458          (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) )
459     {
460         const Color aBlackColor(COL_BLACK);
461 
462         if ( nStyle & DrawButtonFlags::Default )
463         {
464             // default selection shows a wider border
465             ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
466         }
467 
468         ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
469 
470         Size aBrdSize(pDev->GetButtonBorderSize());
471 
472         pDev->SetLineColor();
473         pDev->SetFillColor( aBlackColor );
474         const tools::Rectangle aOrigFillRect(aFillRect);
475         if ( nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked) )
476         {
477             // shrink fill rect
478             aFillRect.AdjustLeft(aBrdSize.Width() );
479             aFillRect.AdjustTop(aBrdSize.Height() );
480             // draw top and left borders (aOrigFillRect-aFillRect)
481             pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
482                                        aOrigFillRect.Right(), aFillRect.Top()-1 ) );
483             pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
484                                        aFillRect.Left()-1, aOrigFillRect.Bottom() ) );
485         }
486         else
487         {
488             // shrink fill rect
489             aFillRect.AdjustRight( -(aBrdSize.Width()) );
490             aFillRect.AdjustBottom( -(aBrdSize.Height()) );
491             // draw bottom and right borders (aOrigFillRect-aFillRect)
492             pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aFillRect.Bottom()+1,
493                                        aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
494             pDev->DrawRect( tools::Rectangle( aFillRect.Right()+1, aOrigFillRect.Top(),
495                                        aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
496         }
497 
498         // Hack: in monochrome mode on printers we like to have grey buttons
499         pDev->SetFillColor(pDev->GetMonochromeButtonColor());
500         pDev->DrawRect( aFillRect );
501     }
502     else
503     {
504         if ( nStyle & DrawButtonFlags::Default )
505         {
506             const Color aDefBtnColor = rStyleSettings.GetDarkShadowColor();
507             ImplDrawDPILineRect( pDev, aFillRect, &aDefBtnColor );
508         }
509 
510         if ( nStyle & DrawButtonFlags::NoLeftLightBorder )
511         {
512             pDev->SetLineColor( rStyleSettings.GetLightBorderColor() );
513             pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Top() ),
514                             Point( aFillRect.Left(), aFillRect.Bottom() ) );
515             aFillRect.AdjustLeft( 1 );
516         }
517 
518         Color aColor1;
519         Color aColor2;
520         if ( nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked) )
521         {
522             aColor1 = rStyleSettings.GetDarkShadowColor();
523             aColor2 = rStyleSettings.GetLightColor();
524         }
525         else
526         {
527             if ( nStyle & DrawButtonFlags::NoLightBorder )
528                 aColor1 = rStyleSettings.GetLightBorderColor();
529             else
530                 aColor1 = rStyleSettings.GetLightColor();
531             if ( (nStyle & BUTTON_DRAW_FLATTEST) == DrawButtonFlags::Flat )
532                 aColor2 = rStyleSettings.GetShadowColor();
533             else
534                 aColor2 = rStyleSettings.GetDarkShadowColor();
535         }
536 
537         ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
538 
539         if ( (nStyle & BUTTON_DRAW_FLATTEST) != DrawButtonFlags::Flat )
540         {
541             if ( nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked) )
542             {
543                 aColor1 = rStyleSettings.GetShadowColor();
544                 aColor2 = rStyleSettings.GetLightBorderColor();
545             }
546             else
547             {
548                 if ( nStyle & DrawButtonFlags::NoLightBorder )
549                     aColor1 = rStyleSettings.GetLightColor();
550                 else
551                     aColor1 = rStyleSettings.GetLightBorderColor();
552                 aColor2 = rStyleSettings.GetShadowColor();
553             }
554             ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
555         }
556 
557         pDev->SetLineColor();
558         if ( nStyle & (DrawButtonFlags::Checked | DrawButtonFlags::DontKnow) )
559             pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
560         else
561             pDev->SetFillColor( rStyleSettings.GetFaceColor() );
562         pDev->DrawRect( aFillRect );
563     }
564 }
565 
ImplDrawFrame(OutputDevice * const pDev,tools::Rectangle & rRect,const StyleSettings & rStyleSettings,DrawFrameStyle nStyle,DrawFrameFlags nFlags)566 void ImplDrawFrame( OutputDevice *const pDev, tools::Rectangle& rRect,
567                     const StyleSettings& rStyleSettings, DrawFrameStyle nStyle, DrawFrameFlags nFlags )
568 {
569     vcl::Window * pWin = pDev->GetOwnerWindow();
570 
571     const bool bMenuStyle(nFlags & DrawFrameFlags::Menu);
572 
573     // UseFlatBorders disables 3D style for all frames except menus
574     // menus may use different border colors (eg on XP)
575     // normal frames will be drawn using the shadow color
576     // whereas window frame borders will use black
577     bool bFlatBorders = !bMenuStyle && rStyleSettings.GetUseFlatBorders();
578 
579     // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
580     // will not affect frame windows (like dropdowns)
581     if( bFlatBorders && pWin && pWin->GetType() == WindowType::BORDERWINDOW && (pWin != pWin->ImplGetFrameWindow()) )
582     {
583         // check for formcontrol, i.e., a control without NWF enabled
584         Control *const pControl = dynamic_cast< Control* >( pWin->GetWindow( GetWindowType::Client ) );
585         if( !pControl || !pControl->IsNativeWidgetEnabled() )
586             bFlatBorders = false;
587     }
588 
589     const bool bNoDraw(nFlags & DrawFrameFlags::NoDraw);
590 
591     if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
592          (pDev->GetOutDevType() == OUTDEV_PRINTER) ||
593          bFlatBorders )
594         nFlags |= DrawFrameFlags::Mono;
595 
596     if( nStyle != DrawFrameStyle::NWF &&
597         pWin && pWin->IsNativeControlSupported(ControlType::Frame, ControlPart::Border) )
598     {
599         tools::Long nControlFlags = static_cast<tools::Long>(nStyle);
600         nControlFlags |= static_cast<tools::Long>(nFlags);
601         nControlFlags |= static_cast<tools::Long>(pWin->GetType() == WindowType::BORDERWINDOW ?
602                                            DrawFrameFlags::BorderWindowBorder : DrawFrameFlags::NONE);
603         ImplControlValue aControlValue( nControlFlags );
604 
605         tools::Rectangle aBound, aContent;
606         tools::Rectangle aNatRgn( rRect );
607         if( pWin->GetNativeControlRegion(ControlType::Frame, ControlPart::Border,
608             aNatRgn, ControlState::NONE, aControlValue, aBound, aContent) )
609         {
610             // if bNoDraw is true then don't call the drawing routine
611             // but just update the target rectangle
612             if( bNoDraw ||
613                 pWin->GetOutDev()->DrawNativeControl( ControlType::Frame, ControlPart::Border, aBound, ControlState::ENABLED,
614                                          aControlValue, OUString()) )
615             {
616                 rRect = aContent;
617                 return;
618             }
619         }
620     }
621 
622     if ( nFlags & DrawFrameFlags::Mono )
623     {
624         // no round corners for window frame borders
625         const bool bRound = bFlatBorders && !(nFlags & DrawFrameFlags::WindowBorder);
626 
627         if ( bNoDraw )
628         {
629             ImplDrawDPILineRect( pDev, rRect, nullptr, bRound );
630         }
631         else
632         {
633             Color aColor = bRound ? rStyleSettings.GetShadowColor()
634                                   : pDev->GetSettings().GetStyleSettings().GetMonoColor();
635             // when the MonoColor wasn't set, check face color
636             if (
637                 (bRound && aColor.IsDark()) ||
638                 (
639                   (aColor == COL_BLACK) &&
640                   pDev->GetSettings().GetStyleSettings().GetFaceColor().IsDark()
641                 )
642                )
643             {
644                 aColor = COL_WHITE;
645             }
646             ImplDrawDPILineRect( pDev, rRect, &aColor, bRound );
647         }
648     }
649     else
650     {
651         if ( bNoDraw )
652         {
653             switch ( nStyle )
654             {
655                 case DrawFrameStyle::In:
656                 case DrawFrameStyle::Out:
657                     rRect.AdjustLeft( 1 );
658                     rRect.AdjustTop( 1 );
659                     rRect.AdjustRight( -1 );
660                     rRect.AdjustBottom( -1 );
661                     break;
662 
663                 case DrawFrameStyle::Group:
664                 case DrawFrameStyle::DoubleIn:
665                 case DrawFrameStyle::DoubleOut:
666                     rRect.AdjustLeft(2 );
667                     rRect.AdjustTop(2 );
668                     rRect.AdjustRight( -2 );
669                     rRect.AdjustBottom( -2 );
670                     break;
671 
672                 case DrawFrameStyle::NWF:
673                     // enough space for the native rendering
674                     rRect.AdjustLeft(4 );
675                     rRect.AdjustTop(4 );
676                     rRect.AdjustRight( -4 );
677                     rRect.AdjustBottom( -4 );
678                     break;
679                 default: break;
680             }
681         }
682         else
683         {
684             switch ( nStyle )
685             {
686                 case DrawFrameStyle::Group:
687                     pDev->SetFillColor();
688                     pDev->SetLineColor( rStyleSettings.GetLightColor() );
689                     pDev->DrawRect( tools::Rectangle( rRect.Left()+1, rRect.Top()+1,
690                                             rRect.Right(), rRect.Bottom() ) );
691                     pDev->SetLineColor( rStyleSettings.GetShadowColor() );
692                     pDev->DrawRect( tools::Rectangle( rRect.Left(), rRect.Top(),
693                                             rRect.Right()-1, rRect.Bottom()-1 ) );
694 
695                     // adjust target rectangle
696                     rRect.AdjustLeft(2 );
697                     rRect.AdjustTop(2 );
698                     rRect.AdjustRight( -2 );
699                     rRect.AdjustBottom( -2 );
700                     break;
701 
702                 case DrawFrameStyle::In:
703                     ImplDraw2ColorFrame( pDev, rRect,
704                                          rStyleSettings.GetShadowColor(),
705                                          rStyleSettings.GetLightColor() );
706                     break;
707 
708                 case DrawFrameStyle::Out:
709                     ImplDraw2ColorFrame( pDev, rRect,
710                                          rStyleSettings.GetLightColor(),
711                                          rStyleSettings.GetShadowColor() );
712                     break;
713 
714                 case DrawFrameStyle::DoubleIn:
715                     if( bFlatBorders )
716                     {
717                         // no 3d effect
718                         ImplDraw2ColorFrame( pDev, rRect,
719                                              rStyleSettings.GetShadowColor(),
720                                              rStyleSettings.GetShadowColor() );
721                         ImplDraw2ColorFrame( pDev, rRect,
722                                              rStyleSettings.GetFaceColor(),
723                                              rStyleSettings.GetFaceColor() );
724                     }
725                     else
726                     {
727                         ImplDraw2ColorFrame( pDev, rRect,
728                                              rStyleSettings.GetShadowColor(),
729                                              rStyleSettings.GetLightColor() );
730                         ImplDraw2ColorFrame( pDev, rRect,
731                                              rStyleSettings.GetDarkShadowColor(),
732                                              rStyleSettings.GetLightBorderColor() );
733                     }
734                     break;
735 
736                 case DrawFrameStyle::DoubleOut:
737                     if( bMenuStyle )
738                     {
739                         ImplDraw2ColorFrame( pDev, rRect,
740                                              rStyleSettings.GetMenuBorderColor(),
741                                              rStyleSettings.GetDarkShadowColor() );
742                         if ( !rStyleSettings.GetUseFlatMenus() )
743                         {
744                             ImplDraw2ColorFrame( pDev, rRect,
745                                                  rStyleSettings.GetLightColor(),
746                                                  rStyleSettings.GetShadowColor() );
747                         }
748                     }
749                     else
750                     {
751                         ImplDraw2ColorFrame( pDev, rRect,
752                                              bFlatBorders ? // no 3d effect
753                                              rStyleSettings.GetDarkShadowColor() :
754                                              rStyleSettings.GetLightBorderColor(),
755                                              rStyleSettings.GetDarkShadowColor() );
756                         ImplDraw2ColorFrame( pDev, rRect,
757                                              rStyleSettings.GetLightColor(),
758                                              rStyleSettings.GetShadowColor() );
759                     }
760                     break;
761 
762                 case DrawFrameStyle::NWF:
763                     // no rendering, just enough space for the native rendering
764                     rRect.AdjustLeft(4 );
765                     rRect.AdjustTop(4 );
766                     rRect.AdjustRight( -4 );
767                     rRect.AdjustBottom( -4 );
768                     break;
769                 default: break;
770             }
771         }
772     }
773 }
774 
775 } // end anonymous namespace
776 
DecorationView(OutputDevice * pOutDev)777 DecorationView::DecorationView(OutputDevice* pOutDev) :
778     mpOutDev(pOutDev)
779 {}
780 
DrawSymbol(const tools::Rectangle & rRect,SymbolType eType,const Color & rColor,DrawSymbolFlags nStyle)781 void DecorationView::DrawSymbol( const tools::Rectangle& rRect, SymbolType eType,
782                                  const Color& rColor, DrawSymbolFlags nStyle )
783 {
784     const StyleSettings&    rStyleSettings  = mpOutDev->GetSettings().GetStyleSettings();
785     const tools::Rectangle         aRect           = mpOutDev->LogicToPixel( rRect );
786     const Color             aOldLineColor   = mpOutDev->GetLineColor();
787     const Color             aOldFillColor   = mpOutDev->GetFillColor();
788     const bool              bOldMapMode     = mpOutDev->IsMapModeEnabled();
789     Color                   nColor(rColor);
790     mpOutDev->EnableMapMode( false );
791 
792     if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
793          (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
794         nStyle |= DrawSymbolFlags::Mono;
795 
796     if ( nStyle & DrawSymbolFlags::Mono )
797     {
798         // Monochrome: set color to black if enabled, to gray if disabled
799         nColor = ( nStyle & DrawSymbolFlags::Disable ) ? COL_GRAY : COL_BLACK;
800     }
801     else
802     {
803         if ( nStyle & DrawSymbolFlags::Disable )
804         {
805             // Draw shifted and brighter symbol for embossed look
806             mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
807             mpOutDev->SetFillColor( rStyleSettings.GetLightColor() );
808             ImplDrawSymbol( mpOutDev, aRect + Point(1, 1) , eType );
809             nColor = rStyleSettings.GetShadowColor();
810         }
811     }
812 
813     // Set selected color and draw the symbol
814     mpOutDev->SetLineColor( nColor );
815     mpOutDev->SetFillColor( nColor );
816     ImplDrawSymbol( mpOutDev, aRect, eType );
817 
818     // Restore previous settings
819     mpOutDev->SetLineColor( aOldLineColor );
820     mpOutDev->SetFillColor( aOldFillColor );
821     mpOutDev->EnableMapMode( bOldMapMode );
822 }
823 
DrawFrame(const tools::Rectangle & rRect,const Color & rLeftTopColor,const Color & rRightBottomColor)824 void DecorationView::DrawFrame( const tools::Rectangle& rRect,
825                                 const Color& rLeftTopColor,
826                                 const Color& rRightBottomColor )
827 {
828     tools::Rectangle   aRect         = mpOutDev->LogicToPixel( rRect );
829     const Color aOldLineColor = mpOutDev->GetLineColor();
830     const bool  bOldMapMode   = mpOutDev->IsMapModeEnabled();
831     mpOutDev->EnableMapMode( false );
832     ImplDraw2ColorFrame( mpOutDev, aRect, rLeftTopColor, rRightBottomColor );
833     mpOutDev->SetLineColor( aOldLineColor );
834     mpOutDev->EnableMapMode( bOldMapMode );
835 }
836 
DrawHighlightFrame(const tools::Rectangle & rRect,DrawHighlightFrameStyle nStyle)837 void DecorationView::DrawHighlightFrame( const tools::Rectangle& rRect,
838                                          DrawHighlightFrameStyle nStyle )
839 {
840     const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
841     Color aLightColor = rStyleSettings.GetLightColor();
842     Color aShadowColor = rStyleSettings.GetShadowColor();
843 
844     if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
845          (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
846     {
847         aLightColor = COL_BLACK;
848         aShadowColor = COL_BLACK;
849     }
850     else
851     {
852         Wallpaper aBackground = mpOutDev->GetBackground();
853         if ( aBackground.IsBitmap() || aBackground.IsGradient() )
854         {
855             aLightColor = rStyleSettings.GetFaceColor();
856             aShadowColor = COL_BLACK;
857         }
858         else
859         {
860             Color aBackColor = aBackground.GetColor();
861             if ( (aLightColor.GetColorError( aBackColor ) < 96) ||
862                  (aShadowColor.GetColorError( aBackColor ) < 96) )
863             {
864                 aLightColor = COL_WHITE;
865                 aShadowColor = COL_BLACK;
866 
867                 if ( aLightColor.GetColorError( aBackColor ) < 96 )
868                     aLightColor.DecreaseLuminance( 64 );
869                 if ( aShadowColor.GetColorError( aBackColor ) < 96 )
870                     aShadowColor.IncreaseLuminance( 64 );
871             }
872         }
873     }
874 
875     if ( nStyle == DrawHighlightFrameStyle::In )
876     {
877         Color aTempColor = aLightColor;
878         aLightColor = aShadowColor;
879         aShadowColor = aTempColor;
880     }
881 
882     DrawFrame( rRect, aLightColor, aShadowColor );
883 }
884 
DrawFrame(const tools::Rectangle & rRect,DrawFrameStyle nStyle,DrawFrameFlags nFlags)885 tools::Rectangle DecorationView::DrawFrame( const tools::Rectangle& rRect, DrawFrameStyle nStyle, DrawFrameFlags nFlags )
886 {
887     tools::Rectangle   aRect = rRect;
888     bool        bOldMap = mpOutDev->IsMapModeEnabled();
889     if ( bOldMap )
890     {
891         aRect = mpOutDev->LogicToPixel( aRect );
892         mpOutDev->EnableMapMode( false );
893     }
894 
895     if ( !rRect.IsEmpty() )
896     {
897         if ( nFlags & DrawFrameFlags::NoDraw )
898              ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle, nFlags );
899         else
900         {
901              Color aOldLineColor  = mpOutDev->GetLineColor();
902              Color aOldFillColor  = mpOutDev->GetFillColor();
903              ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle, nFlags );
904              mpOutDev->SetLineColor( aOldLineColor );
905              mpOutDev->SetFillColor( aOldFillColor );
906         }
907     }
908 
909     if ( bOldMap )
910     {
911         mpOutDev->EnableMapMode( bOldMap );
912         aRect = mpOutDev->PixelToLogic( aRect );
913     }
914 
915     return aRect;
916 }
917 
DrawButton(const tools::Rectangle & rRect,DrawButtonFlags nStyle)918 tools::Rectangle DecorationView::DrawButton( const tools::Rectangle& rRect, DrawButtonFlags nStyle )
919 {
920     if ( rRect.IsEmpty() )
921     {
922         return rRect;
923     }
924 
925     tools::Rectangle aRect = rRect;
926     const bool bOldMap = mpOutDev->IsMapModeEnabled();
927 
928     if ( bOldMap )
929     {
930         aRect = mpOutDev->LogicToPixel( aRect );
931         mpOutDev->EnableMapMode( false );
932     }
933 
934     const Color aOldLineColor = mpOutDev->GetLineColor();
935     const Color aOldFillColor = mpOutDev->GetFillColor();
936     ImplDrawButton( mpOutDev, aRect, nStyle );
937     mpOutDev->SetLineColor( aOldLineColor );
938     mpOutDev->SetFillColor( aOldFillColor );
939 
940     // keep border free, although it is used at default representation
941     aRect.AdjustLeft( 1 );
942     aRect.AdjustTop( 1 );
943     aRect.AdjustRight( -1 );
944     aRect.AdjustBottom( -1 );
945 
946     if ( nStyle & DrawButtonFlags::NoLightBorder )
947     {
948         aRect.AdjustLeft( 1 );
949         aRect.AdjustTop( 1 );
950     }
951     else if ( nStyle & DrawButtonFlags::NoLeftLightBorder )
952     {
953         aRect.AdjustLeft( 1 );
954     }
955 
956     if ( nStyle & DrawButtonFlags::Pressed )
957     {
958         if ( (aRect.GetHeight() > 10) && (aRect.GetWidth() > 10) )
959         {
960             aRect.AdjustLeft(4 );
961             aRect.AdjustTop(4 );
962             aRect.AdjustRight( -1 );
963             aRect.AdjustBottom( -1 );
964         }
965         else
966         {
967             aRect.AdjustLeft(3 );
968             aRect.AdjustTop(3 );
969             aRect.AdjustRight( -2 );
970             aRect.AdjustBottom( -2 );
971         }
972     }
973     else if ( nStyle & DrawButtonFlags::Checked )
974     {
975         aRect.AdjustLeft(3 );
976         aRect.AdjustTop(3 );
977         aRect.AdjustRight( -2 );
978         aRect.AdjustBottom( -2 );
979     }
980     else
981     {
982         aRect.AdjustLeft(2 );
983         aRect.AdjustTop(2 );
984         aRect.AdjustRight( -3 );
985         aRect.AdjustBottom( -3 );
986     }
987 
988     if ( bOldMap )
989     {
990         mpOutDev->EnableMapMode( bOldMap );
991         aRect = mpOutDev->PixelToLogic( aRect );
992     }
993 
994     return aRect;
995 }
996 
DrawSeparator(const Point & rStart,const Point & rStop,bool bVertical)997 void DecorationView::DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical )
998 {
999     Point aStart( rStart ), aStop( rStop );
1000     const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
1001     vcl::Window *const pWin = mpOutDev->GetOwnerWindow();
1002     if(pWin)
1003     {
1004         ControlPart nPart = ( bVertical ? ControlPart::SeparatorVert : ControlPart::SeparatorHorz );
1005         bool nativeSupported = pWin->IsNativeControlSupported( ControlType::Fixedline, nPart );
1006         ImplControlValue    aValue;
1007         tools::Rectangle aRect(rStart,rStop);
1008         if(nativeSupported && pWin->GetOutDev()->DrawNativeControl(ControlType::Fixedline,nPart,aRect,ControlState::NONE,aValue,OUString()))
1009             return;
1010     }
1011 
1012     mpOutDev->Push( PushFlags::LINECOLOR );
1013     if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
1014         mpOutDev->SetLineColor( COL_BLACK );
1015     else
1016         mpOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
1017 
1018     mpOutDev->DrawLine( aStart, aStop );
1019     if ( !(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) )
1020     {
1021         mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
1022         if( bVertical )
1023         {
1024             aStart.AdjustX( 1 );
1025             aStop.AdjustX( 1 );
1026         }
1027         else
1028         {
1029             aStart.AdjustY( 1 );
1030             aStop.AdjustY( 1 );
1031         }
1032         mpOutDev->DrawLine( aStart, aStop );
1033     }
1034     mpOutDev->Pop();
1035 }
1036 
DrawHandle(const tools::Rectangle & rRect)1037 void DecorationView::DrawHandle(const tools::Rectangle& rRect)
1038 {
1039     const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
1040 
1041     Size aOutputSize = rRect.GetSize();
1042 
1043     mpOutDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
1044     mpOutDev->SetFillColor(rStyleSettings.GetDarkShadowColor());
1045 
1046     const sal_Int32 nNumberOfPoints = 3;
1047 
1048     tools::Long nHalfWidth = aOutputSize.Width() / 2.0f;
1049 
1050     float fDistance = aOutputSize.Height();
1051     fDistance /= (nNumberOfPoints + 1);
1052 
1053     tools::Long nRadius = aOutputSize.Width();
1054     nRadius /= (nNumberOfPoints + 2);
1055 
1056     for (tools::Long i = 1; i <= nNumberOfPoints; i++)
1057     {
1058         tools::Rectangle aLocation(nHalfWidth - nRadius,
1059                               round(fDistance * i) - nRadius,
1060                               nHalfWidth + nRadius,
1061                               round(fDistance * i) + nRadius);
1062         mpOutDev->DrawEllipse(aLocation);
1063     }
1064 }
1065 
1066 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1067