1
0
mirror of https://github.com/OpenTTD/OpenTTD.git synced 2025-08-19 20:49:11 +00:00

Compare commits

...

6 Commits

Author SHA1 Message Date
b4b2fad8e0 Fix #12648: Ensure all uses of std::filesystem::path use native encoding. (#12650)
std::filesystem::path does not expect UTF-8 strings, so they must be converted to native format first (and back to utf-8 after.)
2024-06-09 10:23:47 +01:00
fce9361bf2 Change: Position caret on left or right of glyph depending on language direction. 2024-06-09 09:57:20 +01:00
5cd81a980e Codechange: Store both left and right glyph positions in a run.
This also allows the end of a run to be known without using an extra position entry.
2024-06-09 09:57:20 +01:00
80ddcb9d7d Codechange: Move GetCharPosInString/GetCharAtPosition to gfx_layout.
These functions are related more to layouting than graphics.
2024-06-09 09:57:20 +01:00
bbbf2b5282 Codechange: Return read-only span instead of vector from layout run functions. 2024-06-09 09:57:20 +01:00
translators
6bf214af6e Update: Translations from eints
vietnamese: 3 changes by KhoiCanDev
polish: 13 changes by pAter-exe
2024-06-09 04:41:27 +00:00
19 changed files with 149 additions and 135 deletions

View File

@@ -17,6 +17,7 @@
#include "string_func.h"
#include "strings_func.h"
#include "gfx_func.h"
#include "gfx_layout.h"
#include "settings_type.h"
#include "console_func.h"
#include "rev.h"
@@ -348,10 +349,10 @@ struct IConsoleWindow : Window
{
int delta = std::min<int>(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
Point p1 = GetCharPosInString(_iconsole_cmdline.buf, from, FS_NORMAL);
Point p2 = from != to ? GetCharPosInString(_iconsole_cmdline.buf, to, FS_NORMAL) : p1;
const auto p1 = GetCharPosInString(_iconsole_cmdline.buf, from, FS_NORMAL);
const auto p2 = from != to ? GetCharPosInString(_iconsole_cmdline.buf, to, FS_NORMAL) : p1;
Rect r = {this->line_offset + delta + p1.x, this->height - this->line_height, this->line_offset + delta + p2.x, this->height};
Rect r = {this->line_offset + delta + p1.left, this->height - this->line_height, this->line_offset + delta + p2.right, this->height};
return r;
}

View File

@@ -489,7 +489,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] c
_tar_list[this->subdir][filename] = std::string{};
std::string filename_base = std::filesystem::path(filename).filename().string();
std::string filename_base = FS2OTTD(std::filesystem::path(OTTD2FS(filename)).filename());
SimplifyFileName(filename_base);
TarHeader th;

View File

@@ -386,7 +386,7 @@ void ReconsiderGameScriptLanguage()
{
if (_current_data == nullptr) return;
std::string language = _current_language->file.stem().string();
std::string language = FS2OTTD(_current_language->file.stem());
for (auto &p : _current_data->compiled_strings) {
if (p.language == language) {
_current_data->cur_language = &p;

View File

@@ -605,9 +605,9 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
/* Not a valid glyph (empty) */
if (glyph == 0xFFFF) continue;
int begin_x = positions[i].x + left - offset_x;
int end_x = positions[i + 1].x + left - offset_x - 1;
int top = positions[i].y + y;
int begin_x = positions[i].left + left - offset_x;
int end_x = positions[i].right + left - offset_x;
int top = positions[i].top + y;
/* Truncated away. */
if (truncation && (begin_x < min_x || end_x > max_x)) continue;
@@ -895,39 +895,6 @@ Dimension GetStringListBoundingBox(std::span<const StringID> list, FontSize font
return d;
}
/**
* Get the leading corner of a character in a single-line string relative
* to the start of the string.
* @param str String containing the character.
* @param ch Pointer to the character in the string.
* @param start_fontsize Font size to start the text with.
* @return Upper left corner of the glyph associated with the character.
*/
Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
{
/* Ensure "ch" is inside "str" or at the exact end. */
assert(ch >= str.data() && (ch - str.data()) <= static_cast<ptrdiff_t>(str.size()));
auto it_ch = str.begin() + (ch - str.data());
Layouter layout(str, INT32_MAX, start_fontsize);
return layout.GetCharPosition(it_ch);
}
/**
* Get the character from a string that is drawn at a specific position.
* @param str String to test.
* @param x Position relative to the start of the string.
* @param start_fontsize Font size to start the text with.
* @return Index of the character position or -1 if there is no character at the position.
*/
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize)
{
if (x < 0) return -1;
Layouter layout(str, INT32_MAX, start_fontsize);
return layout.GetCharAtPosition(x, 0);
}
/**
* Draw single character horizontally centered around (x,y)
* @param c Character (glyph) to draw

View File

@@ -142,8 +142,6 @@ int GetStringLineCount(StringID str, int maxw);
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion);
void LoadStringWidthTable(bool monospace = false);
Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL);
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL);
void DrawDirtyBlocks();
void AddDirtyBlock(int left, int top, int right, int bottom);

View File

@@ -225,7 +225,7 @@ static bool IsConsumedFormattingCode(char32_t ch)
* @return Upper left corner of the character relative to the start of the string.
* @note Will only work right for single-line strings.
*/
Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
ParagraphLayouter::Position Layouter::GetCharPosition(std::string_view::const_iterator ch) const
{
const auto &line = this->front();
@@ -245,8 +245,8 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
}
/* Initial position, returned if character not found. */
const Point initial_position = {_current_text_dir == TD_LTR ? 0 : line->GetWidth(), 0};
const Point *position = &initial_position;
const ParagraphLayouter::Position initial_position = Point{_current_text_dir == TD_LTR ? 0 : line->GetWidth(), 0};
const ParagraphLayouter::Position *position = &initial_position;
/* We couldn't find the code point index. */
if (str != ch) return *position;
@@ -303,8 +303,8 @@ ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const
/* Not a valid glyph (empty). */
if (glyphs[i] == 0xFFFF) continue;
int begin_x = positions[i].x;
int end_x = positions[i + 1].x;
int begin_x = positions[i].left;
int end_x = positions[i].right + 1;
if (IsInsideMM(x, begin_x, end_x)) {
/* Found our glyph, now convert to UTF-8 string index. */
@@ -409,3 +409,36 @@ void Layouter::ReduceLineCache()
if (linecache->size() > 4096) ResetLineCache();
}
}
/**
* Get the leading corner of a character in a single-line string relative
* to the start of the string.
* @param str String containing the character.
* @param ch Pointer to the character in the string.
* @param start_fontsize Font size to start the text with.
* @return Upper left corner of the glyph associated with the character.
*/
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
{
/* Ensure "ch" is inside "str" or at the exact end. */
assert(ch >= str.data() && (ch - str.data()) <= static_cast<ptrdiff_t>(str.size()));
auto it_ch = str.begin() + (ch - str.data());
Layouter layout(str, INT32_MAX, start_fontsize);
return layout.GetCharPosition(it_ch);
}
/**
* Get the character from a string that is drawn at a specific position.
* @param str String to test.
* @param x Position relative to the start of the string.
* @param start_fontsize Font size to start the text with.
* @return Index of the character position or -1 if there is no character at the position.
*/
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize)
{
if (x < 0) return -1;
Layouter layout(str, INT32_MAX, start_fontsize);
return layout.GetCharAtPosition(x, 0);
}

View File

@@ -90,16 +90,29 @@ class ParagraphLayouter {
public:
virtual ~ParagraphLayouter() = default;
/** Position of a glyph within a VisualRun. */
class Position {
public:
int16_t left; ///< Left-most position of glyph.
int16_t right; ///< Right-most position of glyph.
int16_t top; ///< Top-most position of glyph.
constexpr inline Position(int16_t left, int16_t right, int16_t top) : left(left), right(right), top(top) { }
/** Conversion from a single point to a Position. */
constexpr inline Position(const Point &pt) : left(pt.x), right(pt.x), top(pt.y) { }
};
/** Visual run contains data about the bit of text with the same font. */
class VisualRun {
public:
virtual ~VisualRun() = default;
virtual const Font *GetFont() const = 0;
virtual int GetGlyphCount() const = 0;
virtual const std::vector<GlyphID> &GetGlyphs() const = 0;
virtual const std::vector<Point> &GetPositions() const = 0;
virtual std::span<const GlyphID> GetGlyphs() const = 0;
virtual std::span<const Position> GetPositions() const = 0;
virtual int GetLeading() const = 0;
virtual const std::vector<int> &GetGlyphToCharMap() const = 0;
virtual std::span<const int> GetGlyphToCharMap() const = 0;
};
/** A single line worth of VisualRuns. */
@@ -176,7 +189,7 @@ public:
Layouter(std::string_view str, int maxw = INT32_MAX, FontSize fontsize = FS_NORMAL);
Dimension GetBounds();
Point GetCharPosition(std::string_view::const_iterator ch) const;
ParagraphLayouter::Position GetCharPosition(std::string_view::const_iterator ch) const;
ptrdiff_t GetCharAtPosition(int x, size_t line_index) const;
static void Initialize();
@@ -185,4 +198,7 @@ public:
static void ReduceLineCache();
};
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL);
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL);
#endif /* GFX_LAYOUT_H */

View File

@@ -40,7 +40,7 @@ public:
/** Visual run contains data about the bit of text with the same font. */
class FallbackVisualRun : public ParagraphLayouter::VisualRun {
std::vector<GlyphID> glyphs; ///< The glyphs we're drawing.
std::vector<Point> positions; ///< The positions of the glyphs.
std::vector<Position> positions; ///< The positions of the glyphs.
std::vector<int> glyph_to_char; ///< The char index of the glyphs.
Font *font; ///< The font used to layout these.
@@ -49,10 +49,10 @@ public:
FallbackVisualRun(Font *font, const char32_t *chars, int glyph_count, int char_offset, int x);
const Font *GetFont() const override { return this->font; }
int GetGlyphCount() const override { return static_cast<int>(this->glyphs.size()); }
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
const std::vector<Point> &GetPositions() const override { return this->positions; }
std::span<const GlyphID> GetGlyphs() const override { return this->glyphs; }
std::span<const Position> GetPositions() const override { return this->positions; }
int GetLeading() const override { return this->GetFont()->fc->GetHeight(); }
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
std::span<const int> GetGlyphToCharMap() const override { return this->glyph_to_char; }
};
/** A single line worth of VisualRuns. */
@@ -116,25 +116,22 @@ FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const
this->glyphs.reserve(char_count);
this->glyph_to_char.reserve(char_count);
/* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */
this->positions.reserve(char_count + 1);
this->positions.reserve(char_count);
int advance = x;
for (int i = 0; i < char_count; i++) {
const GlyphID &glyph_id = this->glyphs.emplace_back(font->fc->MapCharToGlyph(chars[i]));
int x_advance = font->fc->GetGlyphWidth(glyph_id);
if (isbuiltin) {
this->positions.emplace_back(advance, font->fc->GetAscender()); // Apply sprite font's ascender.
this->positions.emplace_back(advance, advance + x_advance - 1, font->fc->GetAscender()); // Apply sprite font's ascender.
} else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) {
this->positions.emplace_back(advance, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
this->positions.emplace_back(advance, advance + x_advance - 1, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
} else {
this->positions.emplace_back(advance, 0); // No ascender adjustment.
this->positions.emplace_back(advance, advance + x_advance - 1, 0); // No ascender adjustment.
}
advance += font->fc->GetGlyphWidth(glyph_id);
advance += x_advance;
this->glyph_to_char.push_back(char_offset + i);
}
/* End-of-run position. */
this->positions.emplace_back(advance, 0);
}
/**
@@ -165,7 +162,9 @@ int FallbackParagraphLayout::FallbackLine::GetWidth() const
* the last run gives us the end of the line and thus the width.
*/
const auto &run = this->GetVisualRun(this->CountRuns() - 1);
return run.GetPositions().back().x;
const auto &positions = run.GetPositions();
if (positions.empty()) return 0;
return positions.back().right + 1;
}
/**

View File

@@ -45,7 +45,7 @@ public:
std::vector<GlyphID> glyphs; ///< The glyphs of the run. Valid after Shape() is called.
std::vector<int> advance; ///< The advance (width) of the glyphs. Valid after Shape() is called.
std::vector<int> glyph_to_char; ///< The mapping from glyphs to characters. Valid after Shape() is called.
std::vector<Point> positions; ///< The positions of the glyphs. Valid after Shape() is called.
std::vector<ParagraphLayouter::Position> positions; ///< The positions of the glyphs. Valid after Shape() is called.
int total_advance = 0; ///< The total advance of the run. Valid after Shape() is called.
ICURun(int start, int length, UBiDiLevel level, UScriptCode script = USCRIPT_UNKNOWN, Font *font = nullptr) : start(start), length(length), level(level), script(script), font(font) {}
@@ -62,7 +62,7 @@ public:
class ICUVisualRun : public ParagraphLayouter::VisualRun {
private:
std::vector<GlyphID> glyphs;
std::vector<Point> positions;
std::vector<Position> positions;
std::vector<int> glyph_to_char;
int total_advance;
@@ -71,9 +71,9 @@ public:
public:
ICUVisualRun(const ICURun &run, int x);
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
const std::vector<Point> &GetPositions() const override { return this->positions; }
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
std::span<const GlyphID> GetGlyphs() const override { return this->glyphs; }
std::span<const Position> GetPositions() const override { return this->positions; }
std::span<const int> GetGlyphToCharMap() const override { return this->glyph_to_char; }
const Font *GetFont() const override { return this->font; }
int GetLeading() const override { return this->font->fc->GetHeight(); }
@@ -136,8 +136,8 @@ ICUParagraphLayout::ICUVisualRun::ICUVisualRun(const ICURun &run, int x) :
this->positions.reserve(run.positions.size());
/* Copy positions, moving x coordinate by x offset. */
for (const Point &pt : run.positions) {
this->positions.emplace_back(pt.x + x, pt.y);
for (const auto &pos : run.positions) {
this->positions.emplace_back(pos.left + x, pos.right + x, pos.top);
}
}
@@ -179,7 +179,7 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
/* Reserve space, as we already know the size. */
this->glyphs.reserve(glyph_count);
this->glyph_to_char.reserve(glyph_count);
this->positions.reserve(glyph_count + 1);
this->positions.reserve(glyph_count);
this->advance.reserve(glyph_count);
/* Prepare the glyphs/position. ICUVisualRun will give the position an offset if needed. */
@@ -189,14 +189,13 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
this->glyphs.push_back(glyph);
this->positions.emplace_back(advance, (this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
x_advance = this->font->fc->GetGlyphWidth(glyph);
this->glyphs.push_back(glyph);
this->positions.emplace_back(advance, advance + x_advance - 1, (this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
} else {
this->glyphs.push_back(glyph_info[i].codepoint);
this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].y_offset / FONT_SCALE);
x_advance = glyph_pos[i].x_advance / FONT_SCALE;
this->glyphs.push_back(glyph_info[i].codepoint);
this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].x_offset / FONT_SCALE + advance + x_advance - 1, glyph_pos[i].y_offset / FONT_SCALE);
}
this->glyph_to_char.push_back(glyph_info[i].cluster);
@@ -204,9 +203,6 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
advance += x_advance;
}
/* End-of-run position. */
this->positions.emplace_back(advance, 0);
/* Track the total advancement we made. */
this->total_advance = advance;

View File

@@ -647,7 +647,7 @@ STR_UNITS_PERIODS :{NUM}{NBSP}okre
# Common window strings
STR_LIST_FILTER_TITLE :{BLACK}Filtr:
STR_LIST_FILTER_OSKTITLE :{BLACK}Wpisz jedno lub więcej słów kluczowych, aby przefiltrować listę
STR_LIST_FILTER_OSKTITLE :{BLACK}Wpisz jedno lub więcej słów, aby przefiltrować listę
STR_LIST_FILTER_TOOLTIP :{BLACK}Wpisz jedno lub więcej słów kluczowych, aby przefiltrować listę
STR_TOOLTIP_GROUP_ORDER :{BLACK}Wybierz kolejność grupowania
@@ -690,7 +690,7 @@ STR_BUTTON_OK :{BLACK}OK
# On screen keyboard window
STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ .
STR_OSK_KEYBOARD_LAYOUT_CAPS :~!@#$%^&*()_+|QWERTYUIOP{{}}ASDFGHJKL:" ZXCVBNM<>? .
STR_OSK_KEYBOARD_LAYOUT_CAPS :~!@#$%^&*()_+|QWERTYUIOP{{}}ASDFGHJKL:" ZXCVBNM<>? .
# Measurement tooltip
STR_MEASURE_LENGTH :{BLACK}Długość: {NUM}
@@ -1009,7 +1009,7 @@ STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Pokaż s
# Graph key window
STR_GRAPH_KEY_CAPTION :{WHITE}Legenda do wykresów firm
STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Kliknij tutaj aby wł./wył. wyświetlanie danych firmy na wykresie
STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Kliknij tutaj, aby przełączyć wyświetlanie wykresu firmy
# Company league window
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Ranking firm
@@ -3120,7 +3120,7 @@ STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG}
STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Średni czas podróży: {UNITS_DAYS_OR_SECONDS}
# Base for station construction window(s)
STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Podświetlaj zasięg
STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Podświetlanie zasięgu
STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Wył.
STR_STATION_BUILD_COVERAGE_ON :{BLACK}Wł.
STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nie podświetlaj zasięgu projektowanej stacji
@@ -3173,8 +3173,8 @@ STR_WAYPOINT_CAPTION :{WHITE}Posterun
STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Wybór stacji
STR_STATION_BUILD_ORIENTATION :{BLACK}Ukierunkowanie
STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Wybierz ukierunkowanie stacji
STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Ilość peronów
STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Wybierz ilość peronów na stacji
STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Liczba peronów
STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Wybierz liczbę peronów stacji
STR_STATION_BUILD_PLATFORM_LENGTH :{BLACK}Długość peronu
STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP :{BLACK}Wybierz długość stacji
STR_STATION_BUILD_DRAG_DROP :{BLACK}Przeciągnij i upuść
@@ -3643,12 +3643,12 @@ STR_SAVELOAD_SAVE_SCENARIO :{WHITE}Zapisz s
STR_SAVELOAD_LOAD_SCENARIO :{WHITE}Wczytaj scenariusz
STR_SAVELOAD_LOAD_HEIGHTMAP :{WHITE}Wczytaj mapę wysokości
STR_SAVELOAD_SAVE_HEIGHTMAP :{WHITE}Zapisz mapę wysokości
STR_SAVELOAD_HOME_BUTTON :{BLACK}Kliknij tutaj aby przejść do domyślnego katalogu
STR_SAVELOAD_HOME_BUTTON :{BLACK}Kliknij tutaj, aby przejść do domyślnego katalogu zapisów
STR_SAVELOAD_BYTES_FREE :{BLACK}{BYTES} wolnego miejsca
STR_SAVELOAD_LIST_TOOLTIP :{BLACK}Lista napędów, katalogów i zapisanych gier
STR_SAVELOAD_EDITBOX_TOOLTIP :{BLACK}Obecnie zaznaczona nazwa dla zapisanej gry
STR_SAVELOAD_EDITBOX_TOOLTIP :{BLACK}Obecnie wybrana nazwa dla zapisywanej gry
STR_SAVELOAD_DELETE_BUTTON :{BLACK}Usuń
STR_SAVELOAD_DELETE_TOOLTIP :{BLACK}Skasuj zaznaczoną zapisaną grę
STR_SAVELOAD_DELETE_TOOLTIP :{BLACK}Usuń zaznaczony zapis gry
STR_SAVELOAD_SAVE_BUTTON :{BLACK}Zapisz
STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}Zapisz bieżącą grę używając wybranej nazwy
STR_SAVELOAD_LOAD_BUTTON :{BLACK}Wczytaj
@@ -3664,7 +3664,7 @@ STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Czy na
STR_SAVELOAD_DIRECTORY :{STRING} (folder)
STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (folder nadrzędny)
STR_SAVELOAD_OSKTITLE :{BLACK}Wprowadź nazwę pod jaką zapisać grę
STR_SAVELOAD_OSKTITLE :{BLACK}Wprowadź nazwę dla zapisywanej gry
# World generation
STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Tworzenie świata
@@ -4627,9 +4627,9 @@ STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}Pokaż l
###length VEHICLE_TYPES
STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Kliknij, aby zatrzymać wszystkie pociągi w hali warsztatów
STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Kliknij aby zatrzymać wszystkie pojazdy w zajezdni
STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Kliknij aby zatrzymać wszystkie statki w stoczni
STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Kliknij aby zatrzymać wszystkie samoloty w hangarze
STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Kliknij, aby zatrzymać wszystkie pojazdy w zajezdni
STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Kliknij, aby zatrzymać wszystkie statki w stoczni
STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Kliknij, aby zatrzymać wszystkie samoloty w hangarze
###length VEHICLE_TYPES
STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Kliknij, aby uruchomić wszystkie pociągi z warsztatów

View File

@@ -310,8 +310,8 @@ STR_BUTTON_CANCEL :{BLACK}Thôi
STR_BUTTON_OK :{BLACK}Đồng ý
# On screen keyboard window
STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ .
STR_OSK_KEYBOARD_LAYOUT_CAPS :~!@#$%^&*()_+|QWERTYUIOP{{}}ASDFGHJKL:" ZXCVBNM<>? .
STR_OSK_KEYBOARD_LAYOUT :`1234567890-= qwertyuiop[]asdfghjkl;'#\zxcvbnm,./ .
STR_OSK_KEYBOARD_LAYOUT_CAPS :¬!"£$%^&*()_+ QWERTYUIOP{{}}ASDFGHJKL:@~|ZXCVBNM<>? .
# Measurement tooltip
STR_MEASURE_LENGTH :{BLACK}Chiều dài: {NUM}
@@ -1498,7 +1498,7 @@ STR_CONFIG_SETTING_TIMEKEEPING_UNITS_CALENDAR :Lịch
STR_CONFIG_SETTING_TIMEKEEPING_UNITS_WALLCLOCK :Đồng hồ tính giờ
STR_CONFIG_SETTING_MINUTES_PER_YEAR :Số phút tính cho mỗi năm: {STRING}
STR_CONFIG_SETTING_MINUTES_PER_YEAR_HELPTEXT :Chọn số phút trong mỗi lịch năm. Mặc định là 12 phút/năm. Đặt bằng 0 để ngưng lịch thời gian. Tuỳ chọn này sẽ không ảnh hưởng đến việc giả lập kinh tế trong trò chơi, và nó chỉ sẵn có khi sử dụng đồng hồ giữ nhịp
STR_CONFIG_SETTING_MINUTES_PER_YEAR_HELPTEXT :Chọn số phút tương ứng với một năm trong trò chơi. Mặc định là 12 phút. Đặt bằng 0 để ngưng đọng thời gian. Tăng giá trị này có thể làm chậm việc ra mắt những mẫu phương tiện, nhà cửa, và những cơ sở hạ tầng khác. Giá trị này không làm ảnh hưởng tới tốc độ của phương tiện hoặc nền kinh tế trong trò chơi, ngoại trừ lạm phát. Thiết lập này chỉ được dùng khi sử dụng đồng hồ tính giờ
STR_CONFIG_SETTING_MINUTES_PER_YEAR_VALUE :{NUM}
###setting-zero-is-special

View File

@@ -12,6 +12,7 @@
#include "landscape.h"
#include "error.h"
#include "gui.h"
#include "gfx_layout.h"
#include "command_func.h"
#include "company_func.h"
#include "town.h"
@@ -901,10 +902,10 @@ Rect QueryString::GetBoundingRect(const Window *w, WidgetID wid, const char *fro
r = ScrollEditBoxTextRect(r, *tb);
/* Get location of first and last character. */
Point p1 = GetCharPosInString(tb->buf, from, FS_NORMAL);
Point p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1;
const auto p1 = GetCharPosInString(tb->buf, from, FS_NORMAL);
const auto p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1;
return { Clamp(r.left + p1.x, r.left, r.right), r.top, Clamp(r.left + p2.x, r.left, r.right), r.bottom };
return { Clamp(r.left + p1.left, r.left, r.right), r.top, Clamp(r.left + p2.right, r.left, r.right), r.bottom };
}
/**

View File

@@ -578,7 +578,7 @@ int openttd_main(std::span<char * const> arguments)
if (mgo.opt != nullptr) {
_file_to_saveload.name = mgo.opt;
std::string extension = std::filesystem::path(_file_to_saveload.name).extension().string();
std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(_file_to_saveload.name)).extension());
auto [ft, _] = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, extension);
if (ft == FIOS_TYPE_INVALID) {
std::tie(ft, _) = FiosGetScenarioListCallback(SLO_LOAD, _file_to_saveload.name, extension);
@@ -612,7 +612,7 @@ int openttd_main(std::span<char * const> arguments)
return ret;
}
std::string extension = std::filesystem::path(mgo.opt).extension().string();
std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(mgo.opt)).extension());
auto [_, title] = FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, extension);
_load_check_data.Clear();

View File

@@ -71,7 +71,7 @@ public:
class CoreTextVisualRun : public ParagraphLayouter::VisualRun {
private:
std::vector<GlyphID> glyphs;
std::vector<Point> positions;
std::vector<Position> positions;
std::vector<int> glyph_to_char;
int total_advance = 0;
@@ -81,9 +81,9 @@ public:
CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff);
CoreTextVisualRun(CoreTextVisualRun &&other) = default;
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
const std::vector<Point> &GetPositions() const override { return this->positions; }
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
std::span<const GlyphID> GetGlyphs() const override { return this->glyphs; }
std::span<const Position> GetPositions() const override { return this->positions; }
std::span<const int> GetGlyphToCharMap() const override { return this->glyph_to_char; }
const Font *GetFont() const override { return this->font; }
int GetLeading() const override { return this->font->fc->GetHeight(); }
@@ -241,7 +241,9 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
CGPoint pts[this->glyphs.size()];
CTRunGetPositions(run, CFRangeMake(0, 0), pts);
this->positions.reserve(this->glyphs.size() + 1);
CGSize advs[this->glyphs.size()];
CTRunGetAdvances(run, CFRangeMake(0, 0), advs);
this->positions.reserve(this->glyphs.size());
/* Convert glyph array to our data type. At the same time, substitute
* the proper glyphs for our private sprite glyphs. */
@@ -251,15 +253,13 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END && (gl[i] == 0 || gl[i] == 3)) {
/* A glyph of 0 indidicates not found, while apparently 3 is what char 0xFFFC maps to. */
this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
this->positions.emplace_back(pts[i].x, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
this->positions.emplace_back(pts[i].x, pts[i].x + advs[i].width - 1, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
} else {
this->glyphs[i] = gl[i];
this->positions.emplace_back(pts[i].x, pts[i].y);
this->positions.emplace_back(pts[i].x, pts[i].x + advs[i].width - 1, pts[i].y);
}
}
this->total_advance = (int)std::ceil(CTRunGetTypographicBounds(run, CFRangeMake(0, 0), nullptr, nullptr, nullptr));
/* End-of-run position. */
this->positions.emplace_back(this->positions.front().x + this->total_advance, 0);
}
/**

View File

@@ -74,7 +74,7 @@ public:
class UniscribeVisualRun : public ParagraphLayouter::VisualRun {
private:
std::vector<GlyphID> glyphs;
std::vector<Point> positions;
std::vector<Position> positions;
std::vector<WORD> char_to_glyph;
int start_pos;
@@ -88,9 +88,9 @@ public:
UniscribeVisualRun(const UniscribeRun &range, int x);
UniscribeVisualRun(UniscribeVisualRun &&other) noexcept;
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
const std::vector<Point> &GetPositions() const override { return this->positions; }
const std::vector<int> &GetGlyphToCharMap() const override;
std::span<const GlyphID> GetGlyphs() const override { return this->glyphs; }
std::span<const Position> GetPositions() const override { return this->positions; }
std::span<const int> GetGlyphToCharMap() const override;
const Font *GetFont() const override { return this->font; }
int GetLeading() const override { return this->font->fc->GetHeight(); }
@@ -474,16 +474,15 @@ int UniscribeParagraphLayout::UniscribeLine::GetWidth() const
UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(const UniscribeRun &range, int x) : glyphs(range.ft_glyphs), char_to_glyph(range.char_to_glyph), start_pos(range.pos), total_advance(range.total_advance), font(range.font)
{
this->num_glyphs = (int)glyphs.size();
this->positions.reserve(this->num_glyphs + 1);
this->positions.reserve(this->num_glyphs);
int advance = x;
for (int i = 0; i < this->num_glyphs; i++) {
this->positions.emplace_back(range.offsets[i].du + advance, range.offsets[i].dv);
int x_advance = range.advances[i];
this->positions.emplace_back(range.offsets[i].du + advance - 1, range.offsets[i].du + advance + x_advance, range.offsets[i].dv);
advance += range.advances[i];
advance += x_advance;
}
/* End-of-run position. */
this->positions.emplace_back(advance, 0);
}
UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(UniscribeVisualRun&& other) noexcept
@@ -493,7 +492,7 @@ UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(UniscribeVisual
{
}
const std::vector<int> &UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() const
std::span<const int> UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() const
{
if (this->glyph_to_char.empty()) {
this->glyph_to_char.resize(this->GetGlyphCount());

View File

@@ -245,7 +245,7 @@ static bool _ValidateSignatureFile(const std::string &filename)
return false;
}
std::string dirname = std::filesystem::path(filename).parent_path().string();
std::string dirname = FS2OTTD(std::filesystem::path(OTTD2FS(filename)).parent_path());
for (auto &signature : signatures["files"]) {
const std::string sig_filename = dirname + PATHSEPCHAR + signature["filename"].get<std::string>();

View File

@@ -1904,7 +1904,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
{
/* Current language pack */
size_t len = 0;
std::unique_ptr<LanguagePack, LanguagePackDeleter> lang_pack(reinterpret_cast<LanguagePack *>(ReadFileToMem(lang->file.string(), len, 1U << 20).release()));
std::unique_ptr<LanguagePack, LanguagePackDeleter> lang_pack(reinterpret_cast<LanguagePack *>(ReadFileToMem(FS2OTTD(lang->file), len, 1U << 20).release()));
if (!lang_pack) return false;
/* End of read data (+ terminating zero added in ReadFileToMem()) */
@@ -1953,7 +1953,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
_current_language = lang;
_current_text_dir = (TextDirection)_current_language->text_dir;
_config_language_file = _current_language->file.filename().string();
_config_language_file = FS2OTTD(_current_language->file.filename());
SetCurrentGrfLangID(_current_language->newgrflangid);
#ifdef _WIN32
@@ -2079,13 +2079,13 @@ static void FillLanguageList(const std::string &path)
if (dir_entry.path().extension() != ".lng") continue;
LanguageMetadata lmd;
lmd.file = FS2OTTD(dir_entry.path());
lmd.file = dir_entry.path();
/* Check whether the file is of the correct version */
if (!GetLanguageFileHeader(lmd.file.string(), &lmd)) {
Debug(misc, 3, "{} is not a valid language file", lmd.file);
if (!GetLanguageFileHeader(FS2OTTD(lmd.file), &lmd)) {
Debug(misc, 3, "{} is not a valid language file", FS2OTTD(lmd.file));
} else if (GetLanguage(lmd.newgrflangid) != nullptr) {
Debug(misc, 3, "{}'s language ID is already known", lmd.file);
Debug(misc, 3, "{}'s language ID is already known", FS2OTTD(lmd.file));
} else {
_languages.push_back(lmd);
}
@@ -2119,7 +2119,7 @@ void InitializeLanguagePacks()
/* We are trying to find a default language. The priority is by
* configuration file, local environment and last, if nothing found,
* English. */
if (_config_language_file == lng.file.filename()) {
if (_config_language_file == FS2OTTD(lng.file.filename())) {
chosen_language = &lng;
break;
}
@@ -2139,7 +2139,7 @@ void InitializeLanguagePacks()
chosen_language = (language_fallback != nullptr) ? language_fallback : en_GB_fallback;
}
if (!ReadLanguagePack(chosen_language)) UserError("Can't read language pack '{}'", chosen_language->file);
if (!ReadLanguagePack(chosen_language)) UserError("Can't read language pack '{}'", FS2OTTD(chosen_language->file));
}
/**

View File

@@ -258,7 +258,7 @@ void SurveyConfiguration(nlohmann::json &survey)
{
survey["network"] = _networking ? (_network_server ? "server" : "client") : "no";
if (_current_language != nullptr) {
survey["language"]["filename"] = _current_language->file.filename().string();
survey["language"]["filename"] = FS2OTTD(_current_language->file.filename());
survey["language"]["name"] = _current_language->name;
survey["language"]["isocode"] = _current_language->isocode;
}

View File

@@ -14,6 +14,7 @@
#include "strings_func.h"
#include "gfx_type.h"
#include "gfx_func.h"
#include "gfx_layout.h"
#include "window_func.h"
#include "core/alloc_func.hpp"
@@ -308,15 +309,18 @@ void Textbuf::UpdateWidth()
/** Update pixel position of the caret. */
void Textbuf::UpdateCaretPosition()
{
this->caretxoffs = this->chars > 1 ? GetCharPosInString(this->buf, this->buf + this->caretpos, FS_NORMAL).x : 0;
const auto pos = GetCharPosInString(this->buf, this->buf + this->caretpos, FS_NORMAL);
this->caretxoffs = _current_text_dir == TD_LTR ? pos.left : pos.right;
}
/** Update pixel positions of the marked text area. */
void Textbuf::UpdateMarkedText()
{
if (this->markend != 0) {
this->markxoffs = GetCharPosInString(this->buf, this->buf + this->markpos, FS_NORMAL).x;
this->marklength = GetCharPosInString(this->buf, this->buf + this->markend, FS_NORMAL).x - this->markxoffs;
const auto pos = GetCharPosInString(this->buf, this->buf + this->markpos, FS_NORMAL);
const auto end = GetCharPosInString(this->buf, this->buf + this->markend, FS_NORMAL);
this->markxoffs = std::min(pos.left, end.left);
this->marklength = std::max(pos.right, end.right) - this->markxoffs;
} else {
this->markxoffs = this->marklength = 0;
}