Freeciv21
Develop your civilization from humble roots to a global empire
renderer.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Louis Moureaux <m_louis30@yahoo.com>
3  *
4  * SPDX-License-Identifier: GPLv3-or-later
5  */
6 
7 #include "renderer.h"
8 
9 #include "map_updates_handler.h"
10 #include "mapview_g.h"
11 #include "views/view_map_common.h"
12 
13 namespace freeciv {
14 
26 renderer::renderer(QObject *parent)
27  : QObject(parent), m_updates(new map_updates_handler(this))
28 {
30  &renderer::unqueue_updates, Qt::QueuedConnection);
31 }
32 
36 void renderer::set_origin(const QPointF &origin)
37 {
38  m_origin = origin;
40  emit repaint_needed(QRect(QPoint(), m_viewport_size));
41 }
42 
47 void renderer::set_scale(double scale)
48 {
49  m_scale = scale;
50 
51  // When zoomed in, we pretend that the canvas is smaller than it actually
52  // is. This makes text look bad, but everything else is drawn correctly.
54  m_viewport_size.height() / m_scale);
55 }
56 
61 {
63 
64  // When zoomed in, we pretend that the canvas is smaller than it actually
65  // is. This makes text look bad, but everything else is drawn correctly.
67  m_viewport_size.height() / m_scale);
68 }
69 
75 void renderer::render(QPainter &painter, const QRegion &region) const
76 {
77  for (const auto &rect : region) {
78  render(painter, rect);
79  }
80 }
81 
88 void renderer::render(QPainter &painter, const QRect &area) const
89 {
90  if (scale() != 1) {
91  painter.setRenderHint(QPainter::SmoothPixmapTransform);
92  }
93 
94  auto mapview_rect =
95  QRectF(area.left() / scale(), area.top() / scale(),
96  area.width() / scale(), area.height() / scale());
97  painter.drawPixmap(area, *mapview.store, mapview_rect);
98 }
99 
104 {
105  const auto rects = update_rects();
106 
107  /* This code "pops" the lists of tile updates off of the static array and
108  * stores them locally. This allows further updates to be queued within
109  * the function itself (namely, within update_map_canvas). */
110  const auto updates = m_updates->list();
111  const auto full = m_updates->full();
112 
113  m_updates->clear();
114 
115  if (!map_is_empty()) {
116  if (full) {
118  emit repaint_needed(QRect(0, 0, mapview.store_width * scale(),
119  mapview.store_height * scale()));
120  } else {
121  QRectF to_update;
122 
123  for (const auto &[tile, upd_types] : updates) {
124  for (const auto &[type, rect] : rects) {
125  if (upd_types & type) {
126  float xl, yt;
127  (void) tile_to_canvas_pos(&xl, &yt, tile);
128  to_update |= rect.translated(xl, yt);
129  }
130  }
131  }
132 
133  if (to_update.intersects(
134  QRectF(0, 0, mapview.width, mapview.height))) {
135  const auto aligned = to_update.toAlignedRect();
136  update_map_canvas(aligned.x(), aligned.y(), aligned.width(),
137  aligned.height());
138 
139  const auto scaled_aligned =
140  QRectF(aligned.x() * scale(), aligned.y() * scale(),
141  aligned.width() * scale(), aligned.height() * scale())
142  .toAlignedRect();
143  emit repaint_needed(scaled_aligned);
144  }
145  }
146  }
147 }
148 
149 } // namespace freeciv
Records regions of the map that should be updated.
bool full() const
Returns true if the whole map should be updated.
void clear()
Clears all pending updates.
auto list() const
Returns the list of pending updates.
void unqueue_updates()
Processes all pending map updates and writes them to the map buffer.
Definition: renderer.cpp:103
void repaint_needed(const QRegion &where)
void set_viewport_size(const QSize &size)
Instructs the renderer to draw a viewport with a different size.
Definition: renderer.cpp:60
QSize m_viewport_size
Definition: renderer.h:53
void set_scale(double scale)
Changes the scale of the rendering (zooms in or out).
Definition: renderer.cpp:47
map_updates_handler * m_updates
Definition: renderer.h:54
QPointF origin
Definition: renderer.h:22
void set_origin(const QPointF &origin)
Changes the origin of the canvas (the point at the top left of the view).
Definition: renderer.cpp:36
void render(QPainter &painter, const QRegion &region) const
Renders the specified region of the visible portion of the map on painter.
Definition: renderer.cpp:75
double m_scale
Definition: renderer.h:52
renderer(QObject *parent=nullptr)
Constructor.
Definition: renderer.cpp:26
QPointF m_origin
Definition: renderer.h:51
bool map_is_empty()
Returns TRUE if we are at a stage of the game where the map has not yet been generated/loaded.
Definition: map.cpp:124
Definition: path.cpp:10
size_t size
Definition: specvec.h:64
Definition: tile.h:42
int height
QPixmap * store
int store_width
int store_height
int width
void set_mapview_origin(float gui_x0, float gui_y0)
Change the mapview origin, clip it, and update everything.
struct view mapview
void map_canvas_resized(int width, int height)
Called if the map in the GUI is resized.
void update_map_canvas(int canvas_x, int canvas_y, int width, int height)
Update (refresh) the map canvas starting at the given tile (in map coordinates) and with the given di...
bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, const tile *ptile)
Finds the canvas coordinates for a map position.
std::map< freeciv::map_updates_handler::update_type, QRectF > update_rects()
Calculates the area covered by each update type.