Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / MapWindow / MapCanvas.cpp
blob014f810e486d5cabb8a5fb76bdeaa30114ef6b68
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "MapCanvas.hpp"
25 #include "Screen/Canvas.hpp"
26 #include "Projection/WindowProjection.hpp"
27 #include "Asset.hpp"
28 #include "Screen/Layout.hpp"
29 #include "Math/Screen.hpp"
30 #include "Geo/SearchPointVector.hpp"
32 void
33 MapCanvas::DrawLine(GeoPoint a, GeoPoint b)
35 if (!clip.ClipLine(a, b))
36 return;
38 RasterPoint pts[2];
39 pts[0] = projection.GeoToScreen(a);
40 pts[1] = projection.GeoToScreen(b);
42 canvas.DrawLine(pts[0], pts[1]);
45 void
46 MapCanvas::DrawLineWithOffset(GeoPoint a, GeoPoint b)
48 if (!clip.ClipLine(a, b))
49 return;
51 RasterPoint pts[3];
52 pts[0] = projection.GeoToScreen(a);
53 pts[1] = projection.GeoToScreen(b);
54 ScreenClosestPoint(pts[0], pts[1], pts[0], &pts[2], Layout::Scale(20));
55 canvas.DrawLine(pts[2], pts[1]);
59 void
60 MapCanvas::DrawCircle(const GeoPoint &center, fixed radius)
62 RasterPoint screen_center = projection.GeoToScreen(center);
63 unsigned screen_radius = projection.GeoToScreenDistance(radius);
64 canvas.DrawCircle(screen_center.x, screen_center.y, screen_radius);
67 void
68 MapCanvas::Project(const Projection &projection,
69 const SearchPointVector &points, RasterPoint *screen)
71 for (auto it = points.begin(); it != points.end(); ++it)
72 *screen++ = projection.GeoToScreen(it->GetLocation());
75 static void
76 UpdateBounds(PixelRect &bounds, const RasterPoint &pt)
78 if (pt.x < bounds.left)
79 bounds.left = pt.x;
80 if (pt.x >= bounds.right)
81 bounds.right = pt.x + 1;
82 if (pt.y < bounds.top)
83 bounds.top = pt.y;
84 if (pt.y >= bounds.bottom)
85 bounds.bottom = pt.y + 1;
88 bool
89 MapCanvas::IsVisible(const Canvas &canvas,
90 const RasterPoint *screen, unsigned num)
92 PixelRect bounds;
93 bounds.left = 0x7fff;
94 bounds.top = 0x7fff;
95 bounds.right = -1;
96 bounds.bottom = -1;
98 for (unsigned i = 0; i < num; ++i)
99 UpdateBounds(bounds, screen[i]);
101 return bounds.left < (int)canvas.GetWidth() && bounds.right >= 0 &&
102 bounds.top < (int)canvas.GetHeight() && bounds.bottom >= 0;
105 bool
106 MapCanvas::PreparePolygon(const SearchPointVector &points)
108 unsigned num_points = points.size();
109 if (num_points < 3)
110 return false;
112 /* copy all SearchPointVector elements to geo_points */
113 geo_points.GrowDiscard(num_points * 3);
114 for (unsigned i = 0; i < num_points; ++i)
115 geo_points[i] = points[i].GetLocation();
117 /* clip them */
118 num_raster_points = clip.ClipPolygon(geo_points.begin(),
119 geo_points.begin(), num_points);
120 if (num_raster_points < 3)
121 /* it's completely outside the screen */
122 return false;
124 /* project all GeoPoints to screen coordinates */
125 raster_points.GrowDiscard(num_raster_points);
126 for (unsigned i = 0; i < num_raster_points; ++i)
127 raster_points[i] = projection.GeoToScreen(geo_points[i]);
129 return IsVisible(raster_points.begin(), num_raster_points);
132 void
133 MapCanvas::DrawPrepared()
135 /* draw it all */
136 canvas.DrawPolygon(raster_points.begin(), num_raster_points);