diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp --- a/src/core/backup_type.hpp +++ b/src/core/backup_type.hpp @@ -144,4 +144,46 @@ private: const int line; }; +/** + * Class to backup a specific variable and restore it upon destruction of this object to prevent + * stack values going out of scope before resetting the global to its original value. Contrary to + * #Backup this restores the variable automatically and there is no manual option to restore. + */ +template +struct AutoRestoreBackup { + /* + * There is explicitly no only original constructor version, as that would make it possible + * for the new value to go out of scope before this object goes out of scope, thus defeating + * the whole goal and reason for existing of this object. + */ + + /** + * Backup variable and switch to new value. + * @param original Variable to backup. + * @param new_value New value for variable. + */ + AutoRestoreBackup(T &original, T new_value) : original(original), original_value(original) + { + original = new_value; + } + + /** + * Restore the variable upon object destruction. + */ + ~AutoRestoreBackup() + { + this->original = this->original_value; + } + +private: + T &original; + T original_value; + + /* Prevent copy, assignment and allocation on stack. */ + AutoRestoreBackup(const AutoRestoreBackup&) = delete; + AutoRestoreBackup& operator=(AutoRestoreBackup&) = delete; + static void *operator new(std::size_t) = delete; + static void *operator new[](std::size_t) = delete; +}; + #endif /* BACKUP_TYPE_HPP */ diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -547,15 +547,13 @@ public: Axis axis = widget == WID_BDD_X ? AXIS_X : AXIS_Y; if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(96)) / 2; int y = (r.Height() - ScaleSpriteTrad(64)) / 2; int x1 = ScaleSpriteTrad(63); int x2 = ScaleSpriteTrad(31); DrawShipDepotSprite(x + (axis == AXIS_X ? x1 : x2), y + ScaleSpriteTrad(17), axis, DEPOT_PART_NORTH); DrawShipDepotSprite(x + (axis == AXIS_X ? x2 : x1), y + ScaleSpriteTrad(33), axis, DEPOT_PART_SOUTH); - _cur_dpi = old_dpi; } break; } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -2920,10 +2920,9 @@ struct IndustryCargoesWindow : public Wi if (widget != WID_IC_PANEL) return; Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); - DrawPixelInfo tmp_dpi, *old_dpi; + DrawPixelInfo tmp_dpi; if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return; - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int left_pos = ir.left; if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::cargo_field_width) / 2; @@ -2952,8 +2951,6 @@ struct IndustryCargoesWindow : public Wi vpos += row_height; if (vpos >= height) break; } - - _cur_dpi = old_dpi; } /** diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -820,8 +820,7 @@ void QueryString::DrawEditBox(const Wind DrawPixelInfo dpi; if (!FillDrawPixelInfo(&dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &dpi); /* We will take the current widget length as maximum width, with a small * space reserved at the end for the caret to show */ @@ -839,8 +838,6 @@ void QueryString::DrawEditBox(const Wind int caret_width = GetStringBoundingBox("_").width; DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE); } - - _cur_dpi = old_dpi; } /** diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -9,6 +9,7 @@ #include "stdafx.h" #include +#include "core/backup_type.hpp" #include "window_gui.h" #include "window_func.h" #include "random_access_file_type.h" @@ -895,17 +896,13 @@ struct SpriteAlignerWindow : Window { DrawPixelInfo new_dpi; if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) break; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, ZOOM_LVL_GUI); if (this->crosshair) { GfxDrawLine(x, 0, x, ir.Height() - 1, PC_WHITE, 1, 1); GfxDrawLine(0, y, ir.Width() - 1, y, PC_WHITE, 1, 1); } - - _cur_dpi = old_dpi; - break; } diff --git a/src/object_gui.cpp b/src/object_gui.cpp --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -363,8 +363,7 @@ public: DrawPixelInfo tmp_dpi; /* Set up a clipping area for the preview. */ if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; @@ -372,7 +371,6 @@ public: } else { DrawNewObjectTileInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, GB(widget, 16, 16)); } - _cur_dpi = old_dpi; } break; } @@ -390,8 +388,7 @@ public: DrawPixelInfo tmp_dpi; /* Set up a clipping area for the preview. */ if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; @@ -400,7 +397,6 @@ public: DrawNewObjectTileInGUI(r.Width() / 2 - 1, r.Height() - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, std::min(_selected_object_view, spec->views - 1)); } - _cur_dpi = old_dpi; } break; } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1255,28 +1255,24 @@ public: case WID_BRAS_PLATFORM_DIR_X: /* Set up a clipping area for the '/' station preview */ if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2); } - _cur_dpi = old_dpi; } break; case WID_BRAS_PLATFORM_DIR_Y: /* Set up a clipping area for the '\' station preview */ if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3); } - _cur_dpi = old_dpi; } break; @@ -1306,14 +1302,12 @@ public: /* Set up a clipping area for the station preview. */ if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation); } - _cur_dpi = old_dpi; } break; } @@ -1940,12 +1934,10 @@ struct BuildRailDepotWindow : public Pic DrawPixelInfo tmp_dpi; if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); DrawTrainDepotSprite(x, y, widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); - _cur_dpi = old_dpi; } } @@ -2052,12 +2044,10 @@ struct BuildRailWaypointWindow : PickerW DrawPixelInfo tmp_dpi; if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); DrawWaypointSprite(x, y, type, _cur_railtype); - _cur_dpi = old_dpi; } if (!IsStationAvailable(statspec)) { diff --git a/src/road_gui.cpp b/src/road_gui.cpp --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -984,12 +984,10 @@ struct BuildRoadDepotWindow : public Pic DrawPixelInfo tmp_dpi; if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); DrawRoadDepotSprite(x, y, (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype); - _cur_dpi = old_dpi; } } @@ -1119,12 +1117,10 @@ struct BuildRoadStationWindow : public P DrawPixelInfo tmp_dpi; if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); - _cur_dpi = old_dpi; } } diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -8,6 +8,7 @@ /** @file roadveh_gui.cpp GUI for road vehicles. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "roadveh.h" #include "window_gui.h" #include "strings_func.h" @@ -130,13 +131,12 @@ void DrawRoadVehImage(const Vehicle *v, Direction dir = rtl ? DIR_E : DIR_W; const RoadVehicle *u = RoadVehicle::From(v); - DrawPixelInfo tmp_dpi, *old_dpi; + DrawPixelInfo tmp_dpi; int max_width = r.Width(); if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) return; - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int px = rtl ? max_width + skip : -skip; int y = r.Height() / 2; @@ -155,8 +155,6 @@ void DrawRoadVehImage(const Vehicle *v, px += rtl ? -width : width; } - _cur_dpi = old_dpi; - if (v->index == selection) { int height = ScaleSpriteTrad(12); Rect hr = {(rtl ? px : 0), 0, (rtl ? max_width : px) - 1, height - 1}; diff --git a/src/screenshot.cpp b/src/screenshot.cpp --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -8,6 +8,7 @@ /** @file screenshot.cpp The creation of screenshots! */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "fileio_func.h" #include "viewport_func.h" #include "gfx_func.h" @@ -617,7 +618,7 @@ static void CurrentScreenCallback(void * static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, uint n) { Viewport *vp = (Viewport *)userdata; - DrawPixelInfo dpi, *old_dpi; + DrawPixelInfo dpi; int wx, left; /* We are no longer rendering to the screen */ @@ -630,8 +631,7 @@ static void LargeWorldCallback(void *use _screen.pitch = pitch; _screen_disable_anim = true; - old_dpi = _cur_dpi; - _cur_dpi = &dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &dpi); dpi.dst_ptr = buf; dpi.height = n; @@ -655,8 +655,6 @@ static void LargeWorldCallback(void *use ); } - _cur_dpi = old_dpi; - /* Switch back to rendering to the screen */ _screen = old_screen; _screen_disable_anim = old_disable_anim; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -8,6 +8,7 @@ /** @file smallmap_gui.cpp GUI that shows a small map of the world with metadata like owner or height. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "clear_map.h" #include "industry.h" #include "station_map.h" @@ -973,10 +974,7 @@ void SmallMapWindow::DrawMapIndicators() void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi) const { Blitter *blitter = BlitterFactory::GetCurrentBlitter(); - DrawPixelInfo *old_dpi; - - old_dpi = _cur_dpi; - _cur_dpi = dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, dpi); /* Clear it */ GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1, PC_BLACK); @@ -1027,8 +1025,6 @@ void SmallMapWindow::DrawSmallMap(DrawPi /* Draw map indicators */ this->DrawMapIndicators(); - - _cur_dpi = old_dpi; } /** diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -8,6 +8,7 @@ /** @file statusbar_gui.cpp The GUI for the bottom status bar. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "date_func.h" #include "gfx_func.h" #include "news_func.h" @@ -68,10 +69,8 @@ static bool DrawScrollingStatusText(cons int width = GetStringBoundingBox(buffer).width; int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left); - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE); - _cur_dpi = old_dpi; return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0); } diff --git a/src/story_gui.cpp b/src/story_gui.cpp --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -698,8 +698,7 @@ public: DrawPixelInfo tmp_dpi; if (!FillDrawPixelInfo(&tmp_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); /* Draw content (now coordinates given to Draw** are local to the new clipping region). */ fr = fr.Translate(-fr.left, -fr.top); @@ -758,9 +757,6 @@ public: default: NOT_REACHED(); } } - - /* Restore clipping region. */ - _cur_dpi = old_dpi; } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -8,6 +8,7 @@ /** @file textfile_gui.cpp Implementation of textfile window. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "fileio_func.h" #include "fontcache.h" #include "gfx_type.h" @@ -152,8 +153,7 @@ void TextfileWindow::SetupScrollbars(boo DrawPixelInfo new_dpi; if (!FillDrawPixelInfo(&new_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); /* Draw content (now coordinates given to DrawString* are local to the new clipping region). */ fr = fr.Translate(-fr.left, -fr.top); @@ -172,8 +172,6 @@ void TextfileWindow::SetupScrollbars(boo DrawString(-this->hscroll->GetPosition(), fr.right, y_offset, line.text, TC_BLACK, SA_TOP | SA_LEFT, false, FS_MONO); } } - - _cur_dpi = old_dpi; } /* virtual */ void TextfileWindow::OnResize() diff --git a/src/train_gui.cpp b/src/train_gui.cpp --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -96,7 +96,7 @@ void DrawTrainImage(const Train *v, cons bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; - DrawPixelInfo tmp_dpi, *old_dpi; + DrawPixelInfo tmp_dpi; /* Position of highlight box */ int highlight_l = 0; int highlight_r = 0; @@ -104,56 +104,55 @@ void DrawTrainImage(const Train *v, cons if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) return; - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + + int px = rtl ? max_width + skip : -skip; + int y = r.Height() / 2; + bool sel_articulated = false; + bool dragging = (drag_dest != INVALID_VEHICLE); + bool drag_at_end_of_train = (drag_dest == v->index); // Head index is used to mark dragging at end of train. + for (; v != nullptr && (rtl ? px > 0 : px < max_width); v = v->Next()) { + if (dragging && !drag_at_end_of_train && drag_dest == v->index) { + /* Highlight the drag-and-drop destination inside the train. */ + int drag_hlight_width = HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); + px += rtl ? -drag_hlight_width : drag_hlight_width; + } + + Point offset; + int width = Train::From(v)->GetDisplayImageWidth(&offset); - int px = rtl ? max_width + skip : -skip; - int y = r.Height() / 2; - bool sel_articulated = false; - bool dragging = (drag_dest != INVALID_VEHICLE); - bool drag_at_end_of_train = (drag_dest == v->index); // Head index is used to mark dragging at end of train. - for (; v != nullptr && (rtl ? px > 0 : px < max_width); v = v->Next()) { - if (dragging && !drag_at_end_of_train && drag_dest == v->index) { - /* Highlight the drag-and-drop destination inside the train. */ - int drag_hlight_width = HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); - px += rtl ? -drag_hlight_width : drag_hlight_width; - } + if (rtl ? px + width > 0 : px - width < max_width) { + PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); + VehicleSpriteSeq seq; + v->GetImage(dir, image_type, &seq); + seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (v->vehstatus & VS_CRASHED) != 0); + } + + if (!v->IsArticulatedPart()) sel_articulated = false; - Point offset; - int width = Train::From(v)->GetDisplayImageWidth(&offset); + if (v->index == selection) { + /* Set the highlight position */ + highlight_l = rtl ? px - width : px; + highlight_r = rtl ? px - 1 : px + width - 1; + sel_articulated = true; + } else if ((_cursor.vehchain && highlight_r != 0) || sel_articulated) { + if (rtl) { + highlight_l -= width; + } else { + highlight_r += width; + } + } - if (rtl ? px + width > 0 : px - width < max_width) { - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); - VehicleSpriteSeq seq; - v->GetImage(dir, image_type, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (v->vehstatus & VS_CRASHED) != 0); + px += rtl ? -width : width; } - if (!v->IsArticulatedPart()) sel_articulated = false; - - if (v->index == selection) { - /* Set the highlight position */ - highlight_l = rtl ? px - width : px; - highlight_r = rtl ? px - 1 : px + width - 1; - sel_articulated = true; - } else if ((_cursor.vehchain && highlight_r != 0) || sel_articulated) { - if (rtl) { - highlight_l -= width; - } else { - highlight_r += width; - } + if (dragging && drag_at_end_of_train) { + /* Highlight the drag-and-drop destination at the end of the train. */ + HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); } - - px += rtl ? -width : width; } - if (dragging && drag_at_end_of_train) { - /* Highlight the drag-and-drop destination at the end of the train. */ - HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); - } - - _cur_dpi = old_dpi; - if (highlight_l != highlight_r) { /* Draw the highlight. Now done after drawing all the engines, as * the next engine after the highlight could overlap it. */ diff --git a/src/viewport.cpp b/src/viewport.cpp --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -61,6 +61,7 @@ */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "landscape.h" #include "viewport_func.h" #include "station_base.h" @@ -1726,9 +1727,6 @@ static void ViewportDrawStrings(ZoomLeve void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &_vd.dpi; - _vd.dpi.zoom = vp->zoom; int mask = ScaleByZoom(-1, vp->zoom); @@ -1738,13 +1736,14 @@ void ViewportDoDraw(const Viewport *vp, _vd.dpi.height = (bottom - top) & mask; _vd.dpi.left = left & mask; _vd.dpi.top = top & mask; - _vd.dpi.pitch = old_dpi->pitch; + _vd.dpi.pitch = _cur_dpi->pitch; _vd.last_child = nullptr; int x = UnScaleByZoom(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; int y = UnScaleByZoom(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; - _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top); + _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(_cur_dpi->dst_ptr, x - _cur_dpi->left, y - _cur_dpi->top); + AutoRestoreBackup dpi_backup(_cur_dpi, &_vd.dpi); ViewportAddLandscape(); ViewportAddVehicles(&_vd.dpi); @@ -1786,8 +1785,6 @@ void ViewportDoDraw(const Viewport *vp, ViewportDrawStrings(zoom, &_vd.string_sprites_to_draw); } - _cur_dpi = old_dpi; - _vd.string_sprites_to_draw.clear(); _vd.tile_sprites_to_draw.clear(); _vd.parent_sprites_to_draw.clear(); diff --git a/src/widget.cpp b/src/widget.cpp --- a/src/widget.cpp +++ b/src/widget.cpp @@ -8,6 +8,7 @@ /** @file widget.cpp Handling of the default/simple widgets. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "company_func.h" #include "window_gui.h" #include "viewport_func.h" @@ -2009,8 +2010,7 @@ NWidgetCore *NWidgetMatrix::GetWidgetFro bool rtl = _current_text_dir == TD_RTL; DrawPixelInfo tmp_dpi; if (!FillDrawPixelInfo(&tmp_dpi, this->pos_x + (rtl ? this->pip_post : this->pip_pre), this->pos_y + this->pip_pre, this->current_x - this->pip_pre - this->pip_post, this->current_y - this->pip_pre - this->pip_post)) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); /* Get the appropriate offsets so we can draw the right widgets. */ NWidgetCore *child = dynamic_cast(this->head); @@ -2043,9 +2043,6 @@ NWidgetCore *NWidgetMatrix::GetWidgetFro child->Draw(w); } } - - /* Restore the clipping area. */ - _cur_dpi = old_dpi; } /** @@ -2847,8 +2844,7 @@ void NWidgetLeaf::Draw(const Window *w) new_dpi.left += this->pos_x; new_dpi.top += this->pos_y; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); Rect r = this->GetCurrentRect(); @@ -2962,8 +2958,6 @@ void NWidgetLeaf::Draw(const Window *w) if (this->IsDisabled()) { GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } - - _cur_dpi = old_dpi; } /** diff --git a/src/window.cpp b/src/window.cpp --- a/src/window.cpp +++ b/src/window.cpp @@ -980,9 +980,8 @@ static void DrawOverlappedWindow(Window */ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) { - DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo bk; - _cur_dpi = &bk; + AutoRestoreBackup dpi_backup(_cur_dpi, &bk); for (Window *w : Window::IterateFromBack()) { if (MayBeShown(w) && @@ -994,7 +993,6 @@ void DrawOverlappedWindowForAll(int left DrawOverlappedWindow(w, std::max(left, w->left), std::max(top, w->top), std::min(right, w->left + w->width), std::min(bottom, w->top + w->height)); } } - _cur_dpi = old_dpi; } /**