diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index f3a7335b96..fa543cd921 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -481,6 +481,12 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi } else if (c == SCC_BIGFONT) { state.SetFontSize(FS_LARGE); } else { +#ifndef WITH_ICU + /* Filter out text direction characters that shouldn't be drawn, and + * will not be handled in the fallback non ICU case because they are + * mostly needed for RTL languages which need more ICU support. */ + if (IsTextDirectionChar(c)) continue; +#endif buff += AppendToBuffer(buff, buffer_last, c); continue; } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index b96001186a..4d8c451966 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -348,7 +348,7 @@ struct NewGRFInspectWindow : Window { offset -= this->vscroll->GetPosition(); if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; - ::DrawString(r.left + LEFT_OFFSET, r.right + RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); + ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); } virtual void DrawWidget(const Rect &r, int widget) const diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index ec85264c5e..54c028dc0e 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1445,6 +1445,9 @@ static void ShowStationBuilder(Window *parent) struct BuildSignalWindow : public PickerWindowBase { private: + Dimension sig_sprite_size; ///< Maximum size of signal GUI sprites. + int sig_sprite_bottom_offset; ///< Maximum extent of signal GUI sprite from reference point towards bottom. + /** * Draw dynamic a signal-sprite in a button in the signal GUI * Draw the sprite +1px to the right and down if the button is lowered @@ -1454,26 +1457,17 @@ private: */ void DrawSignalSprite(byte widget_index, SpriteID image) const { - /* Next get the actual sprite so we can calculate the right offsets. */ - const Sprite *sprite = GetSprite(image, ST_NORMAL); - - /* For the x offset we want the sprite to be centered, so undo the offset - * for sprite drawing and add half of the sprite's width. For the y offset - * we want the sprite to be aligned on the bottom, so again we undo the - * offset for sprite drawing and assume it is the bottom of the sprite. */ - int sprite_center_x_offset = UnScaleByZoom(sprite->x_offs + sprite->width / 2, ZOOM_LVL_GUI); - int sprite_bottom_y_offset = UnScaleByZoom(sprite->height + sprite->y_offs, ZOOM_LVL_GUI); - - /* Next we want to know where on the window to draw. Calculate the center - * and the bottom of the area to draw. */ + Point offset; + Dimension sprite_size = GetSpriteSize(image, &offset); const NWidgetBase *widget = this->GetWidget(widget_index); - int widget_center_x = widget->pos_x + widget->current_x / 2; - int widget_bottom_y = widget->pos_y + widget->current_y - 2; + int x = widget->pos_x - offset.x + + (widget->current_x - sprite_size.width + offset.x) / 2; // centered + int y = widget->pos_y - sig_sprite_bottom_offset + WD_IMGBTN_TOP + + (widget->current_y - WD_IMGBTN_TOP - WD_IMGBTN_BOTTOM + sig_sprite_size.height) / 2; // aligned to bottom - /* Finally we draw the signal. */ DrawSprite(image, PAL_NONE, - widget_center_x - sprite_center_x_offset + this->IsWidgetLowered(widget_index), - widget_bottom_y - sprite_bottom_y_offset + this->IsWidgetLowered(widget_index)); + x + this->IsWidgetLowered(widget_index), + y + this->IsWidgetLowered(widget_index)); } public: @@ -1488,6 +1482,37 @@ public: _convert_signal_button = false; } + virtual void OnInit() + { + /* Calculate maximum signal sprite size. */ + this->sig_sprite_size.width = 0; + this->sig_sprite_size.height = 0; + this->sig_sprite_bottom_offset = 0; + const RailtypeInfo *rti = GetRailTypeInfo(_cur_railtype); + for (uint type = SIGTYPE_NORMAL; type < SIGTYPE_END; type++) { + for (uint variant = SIG_ELECTRIC; variant <= SIG_SEMAPHORE; variant++) { + for (uint lowered = 0; lowered < 2; lowered++) { + Point offset; + Dimension sprite_size = GetSpriteSize(rti->gui_sprites.signals[type][variant][lowered], &offset); + this->sig_sprite_bottom_offset = max(this->sig_sprite_bottom_offset, sprite_size.height); + this->sig_sprite_size.width = max(this->sig_sprite_size.width, sprite_size.width - offset.x); + this->sig_sprite_size.height = max(this->sig_sprite_size.height, sprite_size.height - offset.y); + } + } + } + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { + if (widget == WID_BS_DRAG_SIGNALS_DENSITY_LABEL) { + /* Two digits for signals density. */ + size->width = max(size->width, 2 * GetDigitWidth() + padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT); + } else if (IsInsideMM(widget, WID_BS_SEMAPHORE_NORM, WID_BS_ELECTRIC_PBS_OWAY + 1)) { + size->width = max(size->width, this->sig_sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT); + size->height = max(size->height, this->sig_sprite_size.height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM); + } + } + virtual void SetStringParameters(int widget) const { switch (widget) { diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 7297692129..47fbc8bb7d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2524,7 +2524,20 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (t == NULL) return CMD_ERROR; if (flags & DC_EXEC) { - t->growth_rate = (p2 == 0) ? 0 : p2 | TOWN_GROW_RATE_CUSTOM; + if (p2 == 0) { + /* Clear TOWN_GROW_RATE_CUSTOM, UpdateTownGrowRate will determine a proper value */ + t->growth_rate = 0; + } else { + uint old_rate = t->growth_rate & ~TOWN_GROW_RATE_CUSTOM; + if (t->grow_counter >= old_rate) { + /* This also catches old_rate == 0 */ + t->grow_counter = p2; + } else { + /* Scale grow_counter, so half finished houses stay half finished */ + t->grow_counter = t->grow_counter * p2 / old_rate; + } + t->growth_rate = p2 | TOWN_GROW_RATE_CUSTOM; + } UpdateTownGrowRate(t); InvalidateWindowData(WC_TOWN_VIEW, p1); }