Merge remote-tracking branch 'origin/master' into jgrpp
# Conflicts: # src/string.cpp
This commit is contained in:
@@ -208,6 +208,7 @@ class FreeTypeFontCache : public FontCache {
|
||||
private:
|
||||
FT_Face face; ///< The font face associated with this font.
|
||||
int req_size; ///< Requested font size.
|
||||
int used_size; ///< Used font size.
|
||||
|
||||
typedef SmallMap<uint32, SmallPair<size_t, const void*> > FontTable; ///< Table with font table cache
|
||||
FontTable font_tables; ///< Cached font tables.
|
||||
@@ -241,6 +242,7 @@ private:
|
||||
public:
|
||||
FreeTypeFontCache(FontSize fs, FT_Face face, int pixels);
|
||||
~FreeTypeFontCache();
|
||||
virtual int GetFontSize() const { return this->used_size; }
|
||||
virtual SpriteID GetUnicodeGlyph(WChar key) { return this->parent->GetUnicodeGlyph(key); }
|
||||
virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); }
|
||||
|
||||
@@ -295,6 +297,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels)
|
||||
pixels = Clamp(min(head->Lowest_Rec_PPEM, 20) + diff, scaled_height, MAX_FONT_SIZE);
|
||||
}
|
||||
}
|
||||
this->used_size = pixels;
|
||||
|
||||
FT_Error err = FT_Set_Pixel_Sizes(this->face, 0, pixels);
|
||||
if (err != FT_Err_Ok) {
|
||||
|
@@ -68,6 +68,12 @@ public:
|
||||
*/
|
||||
inline int GetUnitsPerEM() const { return this->units_per_em; }
|
||||
|
||||
/**
|
||||
* Get the nominal font size of the font.
|
||||
* @return The nominal font size.
|
||||
*/
|
||||
virtual int GetFontSize() const { return this->height; }
|
||||
|
||||
/**
|
||||
* Get the SpriteID mapped to the given key
|
||||
* @param key The key to get the sprite for.
|
||||
|
@@ -25,6 +25,10 @@
|
||||
#include "os/windows/string_uniscribe.h"
|
||||
#endif /* WITH_UNISCRIBE */
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
#include "os/macosx/string_osx.h"
|
||||
#endif
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
||||
@@ -670,7 +674,7 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi
|
||||
} else {
|
||||
/* Line is new, layout it */
|
||||
FontState old_state = state;
|
||||
#if defined(WITH_ICU_LAYOUT) || defined(WITH_UNISCRIBE)
|
||||
#if defined(WITH_ICU_LAYOUT) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA)
|
||||
const char *old_str = str;
|
||||
#endif
|
||||
|
||||
@@ -698,6 +702,16 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
if (line.layout == NULL) {
|
||||
GetLayouter<CoreTextParagraphLayoutFactory>(line, str, state);
|
||||
if (line.layout == NULL) {
|
||||
state = old_state;
|
||||
str = old_str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (line.layout == NULL) {
|
||||
GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
|
||||
}
|
||||
@@ -841,6 +855,9 @@ void Layouter::ResetFontCache(FontSize size)
|
||||
#if defined(WITH_UNISCRIBE)
|
||||
UniscribeResetScriptCache(size);
|
||||
#endif
|
||||
#if defined(WITH_COCOA)
|
||||
MacOSResetScriptCache(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2797,36 +2797,36 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD
|
||||
# Framerate display window
|
||||
STR_FRAMERATE_CAPTION :{WHITE}Broj sličica
|
||||
STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x)
|
||||
STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Stopa simulacije: {STRING}
|
||||
STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Stopa simulacije: {STRING}
|
||||
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Broj otkucaja igre simuliranih u sekundi.
|
||||
STR_FRAMERATE_RATE_BLITTER :{WHITE}Broj sličica u sekundi: {STRING}
|
||||
STR_FRAMERATE_RATE_BLITTER :{BLACK}Broj sličica u sekundi: {STRING}
|
||||
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Broj sličica videa prikayanih u sekundi.
|
||||
STR_FRAMERATE_SPEED_FACTOR :{WHITE}Trenutni faktor brzine igre: {DECIMAL}x
|
||||
STR_FRAMERATE_SPEED_FACTOR :{BLACK}Trenutni faktor brzine igre: {DECIMAL}x
|
||||
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Koliko brzo se igra izvodi trenutno u usporedbi sa očekivanom brzinom u uobičajenoj simulaciji.
|
||||
STR_FRAMERATE_CURRENT :{WHITE}Trenutno
|
||||
STR_FRAMERATE_AVERAGE :{WHITE}Prosječno
|
||||
STR_FRAMERATE_DATA_POINTS :{WHITE}Podaci bazirani na {COMMA} mjerama
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} sličica/s
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} sličica/s
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} sličica/s
|
||||
STR_FRAMERATE_DATA_POINTS :{BLACK}Podaci bazirani na {COMMA} mjerama
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} sličica/s
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} sličica/s
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} sličica/s
|
||||
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms
|
||||
STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMERATE_GAMELOOP :{WHITE}Zbroj petlji igre:
|
||||
STR_FRAMERATE_GL_ECONOMY :{WHITE} Korištenje tereta:
|
||||
STR_FRAMERATE_GL_TRAINS :{WHITE} Otkucaji vlakova:
|
||||
STR_FRAMERATE_GL_ROADVEHS :{WHITE} Otkucaji cestovnih vozila:
|
||||
STR_FRAMERATE_GL_SHIPS :{WHITE} Otkucaji brodova:
|
||||
STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Otkucaji aviona:
|
||||
STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Otkucaji svijeta:
|
||||
STR_FRAMERATE_GL_LINKGRAPH :Odmak linka grafikona
|
||||
STR_FRAMERATE_DRAWING :{WHITE}Prikaz grafike:
|
||||
STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Prikazi svijeta:
|
||||
STR_FRAMERATE_VIDEO :{WHITE}Video izlaz:
|
||||
STR_FRAMERATE_SOUND :{WHITE}Miksanje zvukova:
|
||||
STR_FRAMERATE_GAMELOOP :{BLACK}Zbroj petlji igre:
|
||||
STR_FRAMERATE_GL_ECONOMY :{BLACK} Korištenje tereta:
|
||||
STR_FRAMERATE_GL_TRAINS :{BLACK} Otkucaji vlakova:
|
||||
STR_FRAMERATE_GL_ROADVEHS :{BLACK} Otkucaji cestovnih vozila:
|
||||
STR_FRAMERATE_GL_SHIPS :{BLACK} Otkucaji brodova:
|
||||
STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Otkucaji aviona:
|
||||
STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Otkucaji svijeta:
|
||||
STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Odmak linka grafikona:
|
||||
STR_FRAMERATE_DRAWING :{BLACK}Prikaz grafike:
|
||||
STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Prikazi svijeta:
|
||||
STR_FRAMERATE_VIDEO :{BLACK}Video izlaz:
|
||||
STR_FRAMERATE_SOUND :{BLACK}Miksanje zvukova:
|
||||
############ End of leave-in-this-order
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMETIME_CAPTION_GAMELOOP :Petlja igre
|
||||
@@ -2866,6 +2866,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalji
|
||||
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Nema dostupnih informacija.
|
||||
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING}
|
||||
STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING}
|
||||
STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtriraj niz:
|
||||
|
||||
STR_SAVELOAD_OSKTITLE :{BLACK}Upiši ime za spremanje igre
|
||||
|
||||
|
@@ -2731,36 +2731,36 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD
|
||||
# Framerate display window
|
||||
STR_FRAMERATE_CAPTION :{WHITE}Frame rate
|
||||
STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x)
|
||||
STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Velocità simulazione: {STRING}
|
||||
STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Velocità simulazione: {STRING}
|
||||
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Numero di cicli di simulazione della partita in un secondo
|
||||
STR_FRAMERATE_RATE_BLITTER :{WHITE}Frame rate grafica: {STRING}
|
||||
STR_FRAMERATE_RATE_BLITTER :{BLACK}Frame rate grafica: {STRING}
|
||||
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Numero di fotogrammi video renderizzati in un secondo
|
||||
STR_FRAMERATE_SPEED_FACTOR :{WHITE}Fattore di velocità corrente della partita: {DECIMAL}x
|
||||
STR_FRAMERATE_SPEED_FACTOR :{BLACK}Fattore di velocità corrente della partita: {DECIMAL}x
|
||||
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Prestazioni correnti della partita, confrontate con le prestazioni attese alla velocità di giorno normale.
|
||||
STR_FRAMERATE_CURRENT :{WHITE}Corrente
|
||||
STR_FRAMERATE_AVERAGE :{WHITE}Media
|
||||
STR_FRAMERATE_DATA_POINTS :{WHITE}Dati basati su {COMMA} misurazioni
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} frame/s
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} frame/s
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} frame/s
|
||||
STR_FRAMERATE_DATA_POINTS :{BLACK}Dati basati su {COMMA} misurazioni
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frame/s
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frame/s
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frame/s
|
||||
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms
|
||||
STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMERATE_GAMELOOP :{WHITE}Totale ciclo simulazione:
|
||||
STR_FRAMERATE_GL_ECONOMY :{WHITE} Gestione carichi:
|
||||
STR_FRAMERATE_GL_TRAINS :{WHITE} Aggiornamento treni:
|
||||
STR_FRAMERATE_GL_ROADVEHS :{WHITE} Aggiornamento automezzi:
|
||||
STR_FRAMERATE_GL_SHIPS :{WHITE} Aggiornamento navi:
|
||||
STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Aggiornamento aeromobili:
|
||||
STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Aggiornamento mondo:
|
||||
STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Ritardo grafo di distribuzione:
|
||||
STR_FRAMERATE_DRAWING :{WHITE}Renderizzazione grafica:
|
||||
STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Visuali mondo:
|
||||
STR_FRAMERATE_VIDEO :{WHITE}Output video:
|
||||
STR_FRAMERATE_SOUND :{WHITE}Missaggio suoni:
|
||||
STR_FRAMERATE_GAMELOOP :{BLACK}Totale ciclo simulazione:
|
||||
STR_FRAMERATE_GL_ECONOMY :{BLACK} Gestione carichi:
|
||||
STR_FRAMERATE_GL_TRAINS :{BLACK} Aggiornamento treni:
|
||||
STR_FRAMERATE_GL_ROADVEHS :{BLACK} Aggiornamento automezzi:
|
||||
STR_FRAMERATE_GL_SHIPS :{BLACK} Aggiornamento navi:
|
||||
STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Aggiornamento aeromobili:
|
||||
STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Aggiornamento mondo:
|
||||
STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Ritardo grafo di distribuzione:
|
||||
STR_FRAMERATE_DRAWING :{BLACK}Renderizzazione grafica:
|
||||
STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Visuali mondo:
|
||||
STR_FRAMERATE_VIDEO :{BLACK}Output video:
|
||||
STR_FRAMERATE_SOUND :{BLACK}Missaggio suoni:
|
||||
############ End of leave-in-this-order
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMETIME_CAPTION_GAMELOOP :Ciclo simulazione
|
||||
@@ -2800,6 +2800,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Dettagli
|
||||
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Informazioni non disponibili
|
||||
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING}
|
||||
STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING}
|
||||
STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro:
|
||||
|
||||
STR_SAVELOAD_OSKTITLE :{BLACK}Inserire un nome per il salvataggio
|
||||
|
||||
|
@@ -1833,8 +1833,8 @@ STR_LIVERY_TRUCK :Veículo de Mer
|
||||
STR_LIVERY_PASSENGER_SHIP :Barco de Passageiros
|
||||
STR_LIVERY_FREIGHT_SHIP :Barco Cargueiro
|
||||
STR_LIVERY_HELICOPTER :Helicóptero
|
||||
STR_LIVERY_SMALL_PLANE :Aeronave de Pequenas Dimensões
|
||||
STR_LIVERY_LARGE_PLANE :Aeronave de Grandes Dimensões
|
||||
STR_LIVERY_SMALL_PLANE :Avião de Pequenas Dimensões
|
||||
STR_LIVERY_LARGE_PLANE :Avião de Grandes Dimensões
|
||||
STR_LIVERY_PASSENGER_TRAM :Eléctrico de Passageiros
|
||||
STR_LIVERY_FREIGHT_TRAM :Eléctrico de Mercadorias
|
||||
|
||||
|
@@ -475,6 +475,7 @@ STR_ABOUT_MENU_SCREENSHOT :屏幕截图
|
||||
STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :高清截图
|
||||
STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :默认缩放模式下的屏幕截图
|
||||
STR_ABOUT_MENU_GIANT_SCREENSHOT :全地图截图
|
||||
STR_ABOUT_MENU_SHOW_FRAMERATE :显示帧率
|
||||
STR_ABOUT_MENU_ABOUT_OPENTTD :关于 'OpenTTD'
|
||||
STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite 对齐
|
||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :切换边界框
|
||||
@@ -650,6 +651,7 @@ STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLA
|
||||
STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}--
|
||||
STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM}
|
||||
STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------
|
||||
STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}没有可用的音乐包
|
||||
STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}"
|
||||
STR_MUSIC_TRACK :{TINY_FONT}{BLACK}音轨
|
||||
STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}乐曲主题
|
||||
@@ -812,6 +814,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC
|
||||
STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(总裁)
|
||||
|
||||
STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} 赞助了城镇 {TOWN} 的建设!
|
||||
STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}一个名叫{TOWN}的城镇刚刚成立了!
|
||||
|
||||
STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}新 {STRING} 正在 {TOWN} 加紧建设!
|
||||
STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}新 {STRING} 即将落户 {TOWN}!
|
||||
@@ -1336,7 +1339,9 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :设置缩略地
|
||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :绿色
|
||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :深绿色
|
||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :紫色
|
||||
STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :鼠标右键移动地图,鼠标指针不跟随移动
|
||||
STR_CONFIG_SETTING_SCROLLMODE_RMB :鼠标右键移动地图
|
||||
STR_CONFIG_SETTING_SCROLLMODE_LMB :鼠标左键移动地图
|
||||
STR_CONFIG_SETTING_SMOOTH_SCROLLING :平滑视角滚动: {STRING}
|
||||
STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :设置在缩略图上点击或者发出转到特定目标的命令时主视角的转换方式,如果“打开”本选项,视角平缓滚动,“关闭”时直接跳转到目标位置
|
||||
STR_CONFIG_SETTING_MEASURE_TOOLTIP :建设时显示测量数据:{STRING}
|
||||
@@ -1368,6 +1373,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :按住Command
|
||||
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :按住Ctrl键 点击
|
||||
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :关闭
|
||||
|
||||
STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :右键关闭窗口: {STRING}
|
||||
STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :使用在窗口内按右键关闭该窗口,本功能与右键工具提示不能共存!
|
||||
|
||||
STR_CONFIG_SETTING_AUTOSAVE :自动保存: {STRING}
|
||||
STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :选择自动存档时间间隔
|
||||
@@ -1603,7 +1610,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :游戏开局时
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :每 {STRING}{NBSP}天刷新一次分配图
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :指定每次计算货物分配图之间的时间。由于每次重新计算只会处理一个货物分配图元件,因此本设定不代表“每若干日重新计算整个货物分配图”。{}如果此设定赋值越小,則系统需要使用更多处理器时间计算货物分配图。相反,如果此设定赋值越大,則货物被派往新路线所需的时间越长。
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME :容许系统用 {STRING}{NBSP}天时间刷新货物分配图
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :當刷新货物分配图时,系统會衍生一条线程。本设定的值即为线程的持续时间。{}这设定赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,这设定赋值越大,則货物分配功能需要较长时间反映线路网変动的影晌。
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :当刷新货物分配图时,系统会创建一条线程。此处设定的数值即该线程的持续时间。{}赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,赋值越大,则货物分配功能需要较长时间反映线路网变动的影晌。
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :手动
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :不对称
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :对称
|
||||
@@ -1612,7 +1619,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :假设有交通
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MAIL :邮件分配方式:{STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的邮件数量與乙站往甲站的邮件数量大致相同。“不对称”指任何一站往另一站的邮件数量皆由系统随意决定。“手动”指系统不会自动分配邮件的目的地。
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :装甲货物分配方式:{STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :“装甲货物”包括溫带场景的“贵重品”、寒带场景的“金块”及沙漠场景的“钻石”。使用 NewGRF 可能会改変以上设置。{} 假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的货物数量與乙站往甲站的装甲货物数量大致相同。“不对称”指任何一站往另一站的装甲货物数量皆由系统随意决定。“手动”指系统不会自动分配装甲货物的目的地。{} 建议在溫带及沙漠场景使用“对称”,因为银行之间会相互发送贵重品或钻石;在寒带则应使用“不对称”,因为银行不会把金块送回金矿。
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :“装甲货物”包括温带场景的“贵重品”、寒带场景的“金块”及沙漠场景的“钻石”。使用 NewGRF 可能会改变以上设置。{} 假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的货物数量与乙站往甲站的装甲货物数量大致相同。“不对称”指任何一站往另一站的装甲货物数量皆由系统随意决定。“手动”指系统不会自动分配装甲货物的目的地。{} 建议在温带及沙漠场景使用“对称”,因为银行之间会相互发送贵重品或钻石;在寒带则应使用“不对称”,因为银行不会把金块送回金矿。
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :其他货物分配方式:{STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :如为此设置赋值“不对称”,则任何一站往另一站的货物数量皆由系统随意决定。如为此设置赋值“手动”,则系统不会依据交通路线分配货物的目的地。
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :分配精确度:{STRING}
|
||||
@@ -2255,7 +2262,7 @@ STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}无法
|
||||
|
||||
STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}缺失图形组
|
||||
STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD 需要基础图形组用以绘制界面。您是否希望 OpenTTD 下载并安装以下图形组?
|
||||
STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}是的,下载之
|
||||
STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}好,开始下载
|
||||
STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}不,退出OpenTTD
|
||||
|
||||
# Transparency settings window
|
||||
@@ -2685,7 +2692,19 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD
|
||||
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 OpenTTD 团队
|
||||
|
||||
# Framerate display window
|
||||
STR_FRAMERATE_CAPTION :{WHITE}帧率
|
||||
STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x)
|
||||
STR_FRAMERATE_RATE_BLITTER :{BLACK}帧率:{STRING}
|
||||
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}每秒渲染更新的图像帧。
|
||||
STR_FRAMERATE_SPEED_FACTOR :{BLACK}当前游戏速度:{DECIMAL}x
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} fps
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} fps
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} fps
|
||||
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMERATE_VIDEO :{BLACK}视频输出:
|
||||
STR_FRAMERATE_SOUND :{BLACK}混响:
|
||||
############ End of leave-in-this-order
|
||||
############ Leave those lines in this order!!
|
||||
############ End of leave-in-this-order
|
||||
@@ -2713,6 +2732,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}游戏
|
||||
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}无可用信息
|
||||
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING}
|
||||
STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING}
|
||||
STR_SAVELOAD_FILTER_TITLE :{BLACK}过滤字串:
|
||||
|
||||
STR_SAVELOAD_OSKTITLE :{BLACK}为存档命名
|
||||
|
||||
@@ -3366,6 +3386,7 @@ STR_GROUP_RENAME_CAPTION :{BLACK}重命
|
||||
|
||||
STR_GROUP_PROFIT_THIS_YEAR :今年利润:
|
||||
STR_GROUP_PROFIT_LAST_YEAR :去年利润
|
||||
STR_GROUP_OCCUPANCY :当前使用量:
|
||||
STR_GROUP_OCCUPANCY_VALUE :{NUM}%
|
||||
|
||||
# Build vehicle window
|
||||
@@ -3534,7 +3555,10 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :磁悬浮机车
|
||||
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER}{}运行费用:{CURRENCY_LONG}/年{}运载能力: {CARGO_LONG}
|
||||
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牵引力:{6:FORCE}{}运行费用{4:CURRENCY_LONG}/年{}运载能力:{5:CARGO_LONG}
|
||||
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}运载能力:{CARGO_LONG}{}运行成本:{CURRENCY_LONG} /年
|
||||
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}飞机类型:{STRING}{}运载能力:{CARGO_LONG}, {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年
|
||||
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}售价: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机类型: {STRING}{}运载能力: {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年
|
||||
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}购买费用: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机种类: {STRING} 最大航程: {COMMA} 格{}装载量: {CARGO_LONG}, {CARGO_LONG}{}运行费用: {CURRENCY_LONG}/年
|
||||
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}售价: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机类型: {STRING} 续航里程: {COMMA} 格{}运载能力: {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年
|
||||
|
||||
# Autoreplace window
|
||||
STR_REPLACE_VEHICLES_WHITE :{WHITE}更新 {STRING} - {STRING}
|
||||
@@ -4475,6 +4499,7 @@ STR_BASESOUNDS_WIN_DESCRIPTION :Transport Tycoo
|
||||
STR_BASESOUNDS_NONE_DESCRIPTION :一个空的音效包.
|
||||
STR_BASEMUSIC_WIN_DESCRIPTION :Transport Tycoon Deluxe(运输大亨Windows豪华版)的原版音乐包
|
||||
STR_BASEMUSIC_DOS_DESCRIPTION :运输大亨DOS豪华版原版音乐。
|
||||
STR_BASEMUSIC_TTO_DESCRIPTION :原版运输大亨(DOS版及地图编辑器扩展)音乐。
|
||||
STR_BASEMUSIC_NONE_DESCRIPTION :一个没有实际内容的音乐包.
|
||||
|
||||
##id 0x2000
|
||||
|
@@ -925,6 +925,7 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sudafrican
|
||||
STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizada...
|
||||
STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiano (GEL)
|
||||
STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraní (IRR)
|
||||
STR_GAME_OPTIONS_CURRENCY_RUB :Nuevo Rublo Ruso (RUB)
|
||||
############ end of currency region
|
||||
|
||||
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vehículos de carretera
|
||||
@@ -1602,10 +1603,10 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ninguna
|
||||
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Multiplicador inicial del tamaño de ciudad: {STRING}
|
||||
STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Tamaño medio de las ciudades en relación a los pueblos normales al comienzo de la partida
|
||||
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar el grafo de distribución cada {STRING}{NBSP}día{P 0:2 "" s}
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos del grafo de distribución consecutivos. Esta opción se refiere a los cálculos para cada uno de los componentes del grafo, por lo cual fijar un valor no quiere decir que el grafo completo se actualizará tras ese número de días. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular el grafo de distribución. Cuanto mayor sea, más tardará el grafo de distribución en adaptarse a nuevas rutas
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo del grafo de distribución
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del grafo de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Actualizar el gráfico de distribución cada {STRING}{NBSP}día{P 0:2 "" s}
|
||||
STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Periodo de tiempo entre cálculos del gráfico de distribución consecutivos. Esta opción se refiere a los cálculos para cada uno de los componentes del gráfico, por lo cual fijar un valor no quiere decir que el gráfico completo se actualizará tras ese número de días. Cuanto menor sea, mayor tiempo de CPU será necesario para calcular el gráfico de distribución. Cuanto mayor sea, más tardará el gráfico de distribución en adaptarse a nuevas rutas.
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{NBSP}día{P 0:2 "" s} para el cálculo del gráfico de distribución
|
||||
STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del gráfico de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas.
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimétrico
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simétrico
|
||||
@@ -1618,7 +1619,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La clase de car
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otras clases de carga: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que se pueden mover cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para estos tipos de carga.
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisión de la distribución: {STRING}
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Este valor determina el tiempo de CPU empleado en calcular el grafo de distribución. Si es demasiado elevado puede producir ralentización en el juego. Si es demasiado bajo la distribución puede ser poco precisa, causando que ocasionalmente se produzcan errores en los lugares a los que va la carga
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Este valor determina el tiempo de CPU empleado en calcular el gráfico de distribución. Si es demasiado elevado puede producir ralentización en el juego. Si es demasiado bajo la distribución puede ser poco precisa, causando que ocasionalmente se produzcan errores en los lugares a los que va la carga.
|
||||
STR_CONFIG_SETTING_DEMAND_DISTANCE :Efecto de la distancia en la demanda: {STRING}
|
||||
STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Si se fija a un valor superior a 0, la distancia entre la estación origen A de cierta carga y un posible destino B afectará a la cantidad de carga que se enviará de A a B. Cuanto más lejos esté B de A, menos carga se enviará. Cuanto mayor sea el valor de esta opción, menos carga se enviará a estaciones distantes en favor de estaciones cercanas
|
||||
STR_CONFIG_SETTING_DEMAND_SIZE :Cantidad de carga a devolver en modo simétrico: {STRING}
|
||||
@@ -1863,7 +1864,7 @@ STR_FACE_FACECODE :{BLACK}Cara del
|
||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Ver y/o asignar número de cara de presidente
|
||||
STR_FACE_FACECODE_CAPTION :{WHITE}Ver y/o asignar número de cara de presidente
|
||||
STR_FACE_FACECODE_SET :{WHITE}Nuevo código de cara ha sido asignado
|
||||
STR_FACE_FACECODE_ERR :{WHITE}No se puede asignar número de cara de presidente - ¡debe ser un número entre 0 y 4,294,967,295!
|
||||
STR_FACE_FACECODE_ERR :{WHITE}No se puede asignar número de cara de presidente - ¡Ha de ser un número entre 0 y 4,294,967,295!
|
||||
STR_FACE_SAVE :{BLACK}Guardar
|
||||
STR_FACE_SAVE_TOOLTIP :{BLACK}Guardar cara favorita
|
||||
STR_FACE_SAVE_DONE :{WHITE}Esta cara ha sido guardada como tu favorita en el fichero de configuración
|
||||
@@ -2689,14 +2690,25 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD
|
||||
|
||||
# Framerate display window
|
||||
STR_FRAMERATE_CAPTION :{WHITE}Fotogramas por segundo - FPS
|
||||
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Número de fotogramas renderizados por segundo.
|
||||
STR_FRAMERATE_CURRENT :{WHITE}Actual
|
||||
STR_FRAMERATE_AVERAGE :{WHITE}Medio
|
||||
STR_FRAMERATE_DATA_POINTS :{WHITE}Datos basados en {COMMA} medidas
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms
|
||||
STR_FRAMERATE_DATA_POINTS :{BLACK}Datos basados en {COMMA} medidas
|
||||
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms
|
||||
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms
|
||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s
|
||||
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s
|
||||
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s
|
||||
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms
|
||||
STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMERATE_DRAWING :{BLACK}Renderizado gráfico:
|
||||
############ End of leave-in-this-order
|
||||
############ Leave those lines in this order!!
|
||||
STR_FRAMETIME_CAPTION_DRAWING :Renderizado gráfico
|
||||
STR_FRAMETIME_CAPTION_VIDEO :Salida de vídeo
|
||||
STR_FRAMETIME_CAPTION_SOUND :Mezcla de sonido
|
||||
############ End of leave-in-this-order
|
||||
|
||||
|
||||
@@ -2722,6 +2734,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles
|
||||
STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible
|
||||
STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING}
|
||||
STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING}
|
||||
STR_SAVELOAD_FILTER_TITLE :{BLACK}Patrón de filtrado:
|
||||
|
||||
STR_SAVELOAD_OSKTITLE :{BLACK}Introduce un nombre para el juego guardado
|
||||
|
||||
@@ -4001,7 +4014,7 @@ STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La vent
|
||||
|
||||
# AI configuration window
|
||||
STR_AI_CONFIG_CAPTION :{WHITE}Configuración de Scripts de Juego / IA
|
||||
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de Juego que será cargada en la próxima partida
|
||||
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de Juego que será cargado en la próxima partida
|
||||
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IAs que serán cargadas en la próxima partida
|
||||
STR_AI_CONFIG_HUMAN_PLAYER :Jugador Humano
|
||||
STR_AI_CONFIG_RANDOM_AI :IA aleatoria
|
||||
@@ -4240,6 +4253,7 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta
|
||||
STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... carretera en la dirección incorrecta
|
||||
STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... las estaciones de autobús de paso no pueden tener esquinas
|
||||
STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... las estaciones de autobús de paso no pueden tener intersecciones
|
||||
STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... carretera de un solo sentido o bloqueada
|
||||
|
||||
# Station destruction related errors
|
||||
STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No se puede retirar parte de la estación...
|
||||
@@ -4484,13 +4498,15 @@ STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}No se pu
|
||||
STR_DESKTOP_SHORTCUT_COMMENT :Un juego de simulación basado en Transport Tycoon Deluxe
|
||||
|
||||
# Translatable descriptions in media/baseset/*.ob* files
|
||||
STR_BASEGRAPHICS_DOS_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión DOS.
|
||||
STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión DOS (Alemán).
|
||||
STR_BASEGRAPHICS_WIN_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe versión Windows.
|
||||
STR_BASESOUNDS_DOS_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe versión DOS.
|
||||
STR_BASESOUNDS_WIN_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe versión Windows.
|
||||
STR_BASEGRAPHICS_DOS_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión DOS.
|
||||
STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión DOS (Alemán).
|
||||
STR_BASEGRAPHICS_WIN_DESCRIPTION :Gráficos originales de Transport Tycoon Deluxe, versión Windows.
|
||||
STR_BASESOUNDS_DOS_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe, versión DOS.
|
||||
STR_BASESOUNDS_WIN_DESCRIPTION :Sonidos originales de Transport Tycoon Deluxe, versión Windows.
|
||||
STR_BASESOUNDS_NONE_DESCRIPTION :Un conjunto de sonidos vacío.
|
||||
STR_BASEMUSIC_WIN_DESCRIPTION :Música original de Transport Tycoon Deluxe versión Windows.
|
||||
STR_BASEMUSIC_WIN_DESCRIPTION :Música original de Transport Tycoon Deluxe, versión Windows.
|
||||
STR_BASEMUSIC_DOS_DESCRIPTION :Música original de Transport Tycoon Deluxe, versión DOS.
|
||||
STR_BASEMUSIC_TTO_DESCRIPTION :Música original de Transport Tycoon (Original/Editor de Mundos), versión DOS.
|
||||
STR_BASEMUSIC_NONE_DESCRIPTION :Un conjunto de música vacío.
|
||||
|
||||
##id 0x2000
|
||||
|
@@ -22,13 +22,9 @@
|
||||
#include "../debug.h"
|
||||
#include "../base_media_base.h"
|
||||
|
||||
#define Rect OTTDRect
|
||||
#define Point OTTDPoint
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#undef Rect
|
||||
#undef Point
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
|
450
src/os/macosx/string_osx.cpp
Normal file
450
src/os/macosx/string_osx.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file string_osx.cpp Functions related to localized text support on OSX. */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#include "string_osx.h"
|
||||
#include "../../string_func.h"
|
||||
#include "../../strings_func.h"
|
||||
#include "../../table/control_codes.h"
|
||||
#include "../../fontcache.h"
|
||||
#include "macos.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
||||
/** Cached current locale. */
|
||||
static CFLocaleRef _osx_locale = NULL;
|
||||
/** CoreText cache for font information, cleared when OTTD changes fonts. */
|
||||
static CTFontRef _font_cache[FS_END];
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for doing layouts with CoreText.
|
||||
*/
|
||||
class CoreTextParagraphLayout : public ParagraphLayouter {
|
||||
private:
|
||||
const CoreTextParagraphLayoutFactory::CharType *text_buffer;
|
||||
ptrdiff_t length;
|
||||
const FontMap& font_map;
|
||||
|
||||
CTTypesetterRef typesetter;
|
||||
|
||||
CFIndex cur_offset = 0; ///< Offset from the start of the current run from where to output.
|
||||
|
||||
public:
|
||||
/** Visual run contains data about the bit of text with the same font. */
|
||||
class CoreTextVisualRun : public ParagraphLayouter::VisualRun {
|
||||
private:
|
||||
std::vector<GlyphID> glyphs;
|
||||
std::vector<float> positions;
|
||||
std::vector<int> glyph_to_char;
|
||||
|
||||
int total_advance = 0;
|
||||
Font *font;
|
||||
|
||||
public:
|
||||
CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff);
|
||||
|
||||
virtual const GlyphID *GetGlyphs() const { return &this->glyphs[0]; }
|
||||
virtual const float *GetPositions() const { return &this->positions[0]; }
|
||||
virtual const int *GetGlyphToCharMap() const { return &this->glyph_to_char[0]; }
|
||||
|
||||
virtual const Font *GetFont() const { return this->font; }
|
||||
virtual int GetLeading() const { return this->font->fc->GetHeight(); }
|
||||
virtual int GetGlyphCount() const { return (int)this->glyphs.size(); }
|
||||
int GetAdvance() const { return this->total_advance; }
|
||||
};
|
||||
|
||||
/** A single line worth of VisualRuns. */
|
||||
class CoreTextLine : public AutoDeleteSmallVector<CoreTextVisualRun *, 4>, public ParagraphLayouter::Line {
|
||||
public:
|
||||
CoreTextLine(CTLineRef line, const FontMap &fontMapping, const CoreTextParagraphLayoutFactory::CharType *buff)
|
||||
{
|
||||
CFArrayRef runs = CTLineGetGlyphRuns(line);
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(runs); i++) {
|
||||
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, i);
|
||||
|
||||
/* Extract font information for this run. */
|
||||
CFRange chars = CTRunGetStringRange(run);
|
||||
FontMap::const_iterator map = fontMapping.Begin();
|
||||
while (map < fontMapping.End() - 1 && map->first <= chars.location) map++;
|
||||
|
||||
*this->Append() = new CoreTextVisualRun(run, map->second, buff);
|
||||
}
|
||||
CFRelease(line);
|
||||
}
|
||||
|
||||
virtual int GetLeading() const;
|
||||
virtual int GetWidth() const;
|
||||
virtual int CountRuns() const { return this->Length(); }
|
||||
virtual const VisualRun *GetVisualRun(int run) const { return *this->Get(run); }
|
||||
|
||||
int GetInternalCharLength(WChar c) const
|
||||
{
|
||||
/* CoreText uses UTF-16 internally which means we need to account for surrogate pairs. */
|
||||
return c >= 0x010000U ? 2 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
CoreTextParagraphLayout(CTTypesetterRef typesetter, const CoreTextParagraphLayoutFactory::CharType *buffer, ptrdiff_t len, const FontMap &fontMapping) : text_buffer(buffer), length(len), font_map(fontMapping), typesetter(typesetter)
|
||||
{
|
||||
this->Reflow();
|
||||
}
|
||||
|
||||
virtual ~CoreTextParagraphLayout()
|
||||
{
|
||||
CFRelease(this->typesetter);
|
||||
}
|
||||
|
||||
virtual void Reflow()
|
||||
{
|
||||
this->cur_offset = 0;
|
||||
}
|
||||
|
||||
virtual const Line *NextLine(int max_width);
|
||||
};
|
||||
|
||||
|
||||
/** Get the width of an encoded sprite font character. */
|
||||
static CGFloat SpriteFontGetWidth(void *ref_con)
|
||||
{
|
||||
FontSize fs = (FontSize)((size_t)ref_con >> 24);
|
||||
WChar c = (WChar)((size_t)ref_con & 0xFFFFFF);
|
||||
|
||||
return GetGlyphWidth(fs, c);
|
||||
}
|
||||
|
||||
static CTRunDelegateCallbacks _sprite_font_callback = {
|
||||
kCTRunDelegateCurrentVersion, NULL, NULL, NULL,
|
||||
&SpriteFontGetWidth
|
||||
};
|
||||
|
||||
/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping)
|
||||
{
|
||||
if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL;
|
||||
|
||||
/* Can't layout an empty string. */
|
||||
ptrdiff_t length = buff_end - buff;
|
||||
if (length == 0) return NULL;
|
||||
|
||||
/* Can't layout our in-built sprite fonts. */
|
||||
for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) {
|
||||
if (i->second->fc->IsBuiltInFont()) return NULL;
|
||||
}
|
||||
|
||||
/* Make attributed string with embedded font information. */
|
||||
CFMutableAttributedStringRef str = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
|
||||
CFAttributedStringBeginEditing(str);
|
||||
|
||||
CFStringRef base = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull);
|
||||
CFAttributedStringReplaceString(str, CFRangeMake(0, 0), base);
|
||||
CFRelease(base);
|
||||
|
||||
/* Apply font and colour ranges to our string. This is important to make sure
|
||||
* that we get proper glyph boundaries on style changes. */
|
||||
int last = 0;
|
||||
for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) {
|
||||
if (i->first - last == 0) continue;
|
||||
|
||||
if (_font_cache[i->second->fc->GetSize()] == NULL) {
|
||||
/* Cache font information. */
|
||||
CFStringRef font_name = CFStringCreateWithCString(kCFAllocatorDefault, i->second->fc->GetFontName(), kCFStringEncodingUTF8);
|
||||
_font_cache[i->second->fc->GetSize()] = CTFontCreateWithName(font_name, i->second->fc->GetFontSize(), NULL);
|
||||
CFRelease(font_name);
|
||||
}
|
||||
CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTFontAttributeName, _font_cache[i->second->fc->GetSize()]);
|
||||
|
||||
CGColorRef color = CGColorCreateGenericGray((uint8)i->second->colour / 255.0f, 1.0f); // We don't care about the real colours, just that they are different.
|
||||
CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTForegroundColorAttributeName, color);
|
||||
CGColorRelease(color);
|
||||
|
||||
/* Install a size callback for our special sprite glyphs. */
|
||||
for (ssize_t c = last; c < i->first; c++) {
|
||||
if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) {
|
||||
CTRunDelegateRef del = CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i->second->fc->GetSize() << 24)));
|
||||
CFAttributedStringSetAttribute(str, CFRangeMake(c, 1), kCTRunDelegateAttributeName, del);
|
||||
CFRelease(del);
|
||||
}
|
||||
}
|
||||
|
||||
last = i->first;
|
||||
}
|
||||
CFAttributedStringEndEditing(str);
|
||||
|
||||
/* Create and return typesetter for the string. */
|
||||
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(str);
|
||||
CFRelease(str);
|
||||
|
||||
return typesetter != NULL ? new CoreTextParagraphLayout(typesetter, buff, length, fontMapping) : NULL;
|
||||
}
|
||||
|
||||
/* virtual */ const CoreTextParagraphLayout::Line *CoreTextParagraphLayout::NextLine(int max_width)
|
||||
{
|
||||
if (this->cur_offset >= this->length) return NULL;
|
||||
|
||||
/* Get line break position, trying word breaking first and breaking somewhere if that doesn't work. */
|
||||
CFIndex len = CTTypesetterSuggestLineBreak(this->typesetter, this->cur_offset, max_width);
|
||||
if (len <= 0) len = CTTypesetterSuggestClusterBreak(this->typesetter, this->cur_offset, max_width);
|
||||
|
||||
/* Create line. */
|
||||
CTLineRef line = CTTypesetterCreateLine(this->typesetter, CFRangeMake(this->cur_offset, len));
|
||||
this->cur_offset += len;
|
||||
|
||||
return line != NULL ? new CoreTextLine(line, this->font_map, this->text_buffer) : NULL;
|
||||
}
|
||||
|
||||
CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff) : font(font)
|
||||
{
|
||||
this->glyphs.resize(CTRunGetGlyphCount(run));
|
||||
|
||||
/* Query map of glyphs to source string index. */
|
||||
CFIndex map[this->glyphs.size()];
|
||||
CTRunGetStringIndices(run, CFRangeMake(0, 0), map);
|
||||
|
||||
this->glyph_to_char.resize(this->glyphs.size());
|
||||
for (size_t i = 0; i < this->glyph_to_char.size(); i++) this->glyph_to_char[i] = (int)map[i];
|
||||
|
||||
CGPoint pts[this->glyphs.size()];
|
||||
CTRunGetPositions(run, CFRangeMake(0, 0), pts);
|
||||
this->positions.resize(this->glyphs.size() * 2 + 2);
|
||||
|
||||
/* Convert glyph array to our data type. At the same time, substitute
|
||||
* the proper glyphs for our private sprite glyphs. */
|
||||
CGGlyph gl[this->glyphs.size()];
|
||||
CTRunGetGlyphs(run, CFRangeMake(0, 0), gl);
|
||||
for (size_t i = 0; i < this->glyphs.size(); i++) {
|
||||
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) {
|
||||
this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
|
||||
this->positions[i * 2 + 0] = pts[i].x;
|
||||
this->positions[i * 2 + 1] = font->fc->GetAscender() - font->fc->GetGlyph(this->glyphs[i])->height - 1; // Align sprite glyphs to font baseline.
|
||||
} else {
|
||||
this->glyphs[i] = gl[i];
|
||||
this->positions[i * 2 + 0] = pts[i].x;
|
||||
this->positions[i * 2 + 1] = pts[i].y;
|
||||
}
|
||||
}
|
||||
this->total_advance = (int)CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
|
||||
this->positions[this->glyphs.size() * 2] = this->positions[0] + this->total_advance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the line.
|
||||
* @return The maximum height of the line.
|
||||
*/
|
||||
int CoreTextParagraphLayout::CoreTextLine::GetLeading() const
|
||||
{
|
||||
int leading = 0;
|
||||
for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) {
|
||||
leading = max(leading, (*run)->GetLeading());
|
||||
}
|
||||
|
||||
return leading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of this line.
|
||||
* @return The width of the line.
|
||||
*/
|
||||
int CoreTextParagraphLayout::CoreTextLine::GetWidth() const
|
||||
{
|
||||
if (this->Length() == 0) return 0;
|
||||
|
||||
int total_width = 0;
|
||||
for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) {
|
||||
total_width += (*run)->GetAdvance();
|
||||
}
|
||||
|
||||
return total_width;
|
||||
}
|
||||
|
||||
|
||||
/** Delete CoreText font reference for a specific font size. */
|
||||
void MacOSResetScriptCache(FontSize size)
|
||||
{
|
||||
if (_font_cache[size] != NULL) {
|
||||
CFRelease(_font_cache[size]);
|
||||
_font_cache[size] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Store current language locale as a CoreFounation locale. */
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code)
|
||||
{
|
||||
if (!MacOSVersionIsAtLeast(10, 5, 0)) return;
|
||||
|
||||
if (_osx_locale != NULL) CFRelease(_osx_locale);
|
||||
|
||||
CFStringRef iso = CFStringCreateWithCString(kCFAllocatorNull, iso_code, kCFStringEncodingUTF8);
|
||||
_osx_locale = CFLocaleCreate(kCFAllocatorDefault, iso);
|
||||
CFRelease(iso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two strings using case insensitive natural sort.
|
||||
*
|
||||
* @param s1 First string to compare.
|
||||
* @param s2 Second string to compare.
|
||||
* @return 1 if s1 < s2, 2 if s1 == s2, 3 if s1 > s2, or 0 if not supported by the OS.
|
||||
*/
|
||||
int MacOSStringCompare(const char *s1, const char *s2)
|
||||
{
|
||||
static bool supported = MacOSVersionIsAtLeast(10, 5, 0);
|
||||
if (!supported) return 0;
|
||||
|
||||
CFStringCompareFlags flags = kCFCompareCaseInsensitive | kCFCompareNumerically | kCFCompareLocalized | kCFCompareWidthInsensitive | kCFCompareForcedOrdering;
|
||||
|
||||
CFStringRef cf1 = CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8);
|
||||
CFStringRef cf2 = CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8);
|
||||
|
||||
CFComparisonResult res = CFStringCompareWithOptionsAndLocale(cf1, cf2, CFRangeMake(0, CFStringGetLength(cf1)), flags, _osx_locale);
|
||||
|
||||
CFRelease(cf1);
|
||||
CFRelease(cf2);
|
||||
|
||||
return (int)res + 2;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ void OSXStringIterator::SetString(const char *s)
|
||||
{
|
||||
const char *string_base = s;
|
||||
|
||||
this->utf16_to_utf8.clear();
|
||||
this->str_info.clear();
|
||||
this->cur_pos = 0;
|
||||
|
||||
/* CoreText operates on UTF-16, thus we have to convert the input string.
|
||||
* To be able to return proper offsets, we have to create a mapping at the same time. */
|
||||
std::vector<UniChar> utf16_str; ///< UTF-16 copy of the string.
|
||||
while (*s != '\0') {
|
||||
size_t idx = s - string_base;
|
||||
|
||||
WChar c = Utf8Consume(&s);
|
||||
if (c < 0x10000) {
|
||||
utf16_str.push_back((UniChar)c);
|
||||
} else {
|
||||
/* Make a surrogate pair. */
|
||||
utf16_str.push_back((UniChar)(0xD800 + ((c - 0x10000) >> 10)));
|
||||
utf16_str.push_back((UniChar)(0xDC00 + ((c - 0x10000) & 0x3FF)));
|
||||
this->utf16_to_utf8.push_back(idx);
|
||||
}
|
||||
this->utf16_to_utf8.push_back(idx);
|
||||
}
|
||||
this->utf16_to_utf8.push_back(s - string_base);
|
||||
|
||||
/* Query CoreText for word and cluster break information. */
|
||||
this->str_info.resize(utf16_to_utf8.size());
|
||||
|
||||
if (utf16_str.size() > 0) {
|
||||
CFStringRef str = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &utf16_str[0], utf16_str.size(), kCFAllocatorNull);
|
||||
|
||||
/* Get cluster breaks. */
|
||||
for (CFIndex i = 0; i < CFStringGetLength(str); ) {
|
||||
CFRange r = CFStringGetRangeOfComposedCharactersAtIndex(str, i);
|
||||
this->str_info[r.location].char_stop = true;
|
||||
|
||||
i += r.length;
|
||||
}
|
||||
|
||||
/* Get word breaks. */
|
||||
CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, str, CFRangeMake(0, CFStringGetLength(str)), kCFStringTokenizerUnitWordBoundary, _osx_locale);
|
||||
|
||||
CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
|
||||
while ((tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) != kCFStringTokenizerTokenNone) {
|
||||
/* Skip tokens that are white-space or punctuation tokens. */
|
||||
if ((tokenType & kCFStringTokenizerTokenHasNonLettersMask) != kCFStringTokenizerTokenHasNonLettersMask) {
|
||||
CFRange r = CFStringTokenizerGetCurrentTokenRange(tokenizer);
|
||||
this->str_info[r.location].word_stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(tokenizer);
|
||||
CFRelease(str);
|
||||
}
|
||||
|
||||
/* End-of-string is always a valid stopping point. */
|
||||
this->str_info.back().char_stop = true;
|
||||
this->str_info.back().word_stop = true;
|
||||
}
|
||||
|
||||
/* virtual */ size_t OSXStringIterator::SetCurPosition(size_t pos)
|
||||
{
|
||||
/* Convert incoming position to an UTF-16 string index. */
|
||||
size_t utf16_pos = 0;
|
||||
for (size_t i = 0; i < this->utf16_to_utf8.size(); i++) {
|
||||
if (this->utf16_to_utf8[i] == pos) {
|
||||
utf16_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanitize in case we get a position inside a grapheme cluster. */
|
||||
while (utf16_pos > 0 && !this->str_info[utf16_pos].char_stop) utf16_pos--;
|
||||
this->cur_pos = utf16_pos;
|
||||
|
||||
return this->utf16_to_utf8[this->cur_pos];
|
||||
}
|
||||
|
||||
/* virtual */ size_t OSXStringIterator::Next(IterType what)
|
||||
{
|
||||
assert(this->cur_pos <= this->utf16_to_utf8.size());
|
||||
assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD);
|
||||
|
||||
if (this->cur_pos == this->utf16_to_utf8.size()) return END;
|
||||
|
||||
do {
|
||||
this->cur_pos++;
|
||||
} while (this->cur_pos < this->utf16_to_utf8.size() && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop));
|
||||
|
||||
return this->cur_pos == this->utf16_to_utf8.size() ? END : this->utf16_to_utf8[this->cur_pos];
|
||||
}
|
||||
|
||||
/* virtual */ size_t OSXStringIterator::Prev(IterType what)
|
||||
{
|
||||
assert(this->cur_pos <= this->utf16_to_utf8.size());
|
||||
assert(what == StringIterator::ITER_CHARACTER || what == StringIterator::ITER_WORD);
|
||||
|
||||
if (this->cur_pos == 0) return END;
|
||||
|
||||
do {
|
||||
this->cur_pos--;
|
||||
} while (this->cur_pos > 0 && (what == ITER_WORD ? !this->str_info[this->cur_pos].word_stop : !this->str_info[this->cur_pos].char_stop));
|
||||
|
||||
return this->utf16_to_utf8[this->cur_pos];
|
||||
}
|
||||
|
||||
/* static */ StringIterator *OSXStringIterator::Create()
|
||||
{
|
||||
if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL;
|
||||
|
||||
return new OSXStringIterator();
|
||||
}
|
||||
|
||||
#else
|
||||
void MacOSResetScriptCache(FontSize size) {}
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code) {}
|
||||
|
||||
int MacOSStringCompare(const char *s1, const char *s2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ StringIterator *OSXStringIterator::Create()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */
|
90
src/os/macosx/string_osx.h
Normal file
90
src/os/macosx/string_osx.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file string_osx.h Functions related to localized text support on OSX. */
|
||||
|
||||
#ifndef STRING_OSX_H
|
||||
#define STRING_OSX_H
|
||||
|
||||
#include "../../gfx_layout.h"
|
||||
#include "../../string_base.h"
|
||||
#include <vector>
|
||||
|
||||
/** String iterator using CoreText as a backend. */
|
||||
class OSXStringIterator : public StringIterator {
|
||||
/** Break info for a character. */
|
||||
struct CharInfo {
|
||||
bool word_stop : 1; ///< Code point is suitable as a word break.
|
||||
bool char_stop : 1; ///< Code point is the start of a grapheme cluster, i.e. a "character".
|
||||
};
|
||||
|
||||
std::vector<CharInfo> str_info; ///< Break information for each code point.
|
||||
std::vector<size_t> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
|
||||
|
||||
size_t cur_pos; ///< Current iteration position.
|
||||
|
||||
public:
|
||||
virtual void SetString(const char *s);
|
||||
virtual size_t SetCurPosition(size_t pos);
|
||||
virtual size_t Next(IterType what);
|
||||
virtual size_t Prev(IterType what);
|
||||
|
||||
static StringIterator *Create();
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class to construct a new #CoreTextParagraphLayout.
|
||||
*/
|
||||
class CoreTextParagraphLayoutFactory {
|
||||
public:
|
||||
/** Helper for GetLayouter, to get the right type. */
|
||||
typedef UniChar CharType;
|
||||
/** Helper for GetLayouter, to get whether the layouter supports RTL. */
|
||||
static const bool SUPPORTS_RTL = true;
|
||||
|
||||
/**
|
||||
* Get the actual ParagraphLayout for the given buffer.
|
||||
* @param buff The begin of the buffer.
|
||||
* @param buff_end The location after the last element in the buffer.
|
||||
* @param fontMapping THe mapping of the fonts.
|
||||
* @return The ParagraphLayout instance.
|
||||
*/
|
||||
static ParagraphLayouter *GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping);
|
||||
|
||||
/**
|
||||
* Append a wide character to the internal buffer.
|
||||
* @param buff The buffer to append to.
|
||||
* @param buffer_last The end of the buffer.
|
||||
* @param c The character to add.
|
||||
* @return The number of buffer spaces that were used.
|
||||
*/
|
||||
static size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c)
|
||||
{
|
||||
if (c >= 0x010000U) {
|
||||
/* Character is encoded using surrogates in UTF-16. */
|
||||
if (buff + 1 <= buffer_last) {
|
||||
buff[0] = (CharType)(((c - 0x010000U) >> 10) + 0xD800);
|
||||
buff[1] = (CharType)(((c - 0x010000U) & 0x3FF) + 0xDC00);
|
||||
} else {
|
||||
/* Not enough space in buffer. */
|
||||
*buff = 0;
|
||||
}
|
||||
return 2;
|
||||
} else {
|
||||
*buff = (CharType)(c & 0xFFFF);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void MacOSResetScriptCache(FontSize size);
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code);
|
||||
int MacOSStringCompare(const char *s1, const char *s2);
|
||||
|
||||
#endif /* STRING_OSX_H */
|
@@ -195,6 +195,7 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b
|
||||
for (int i = 0; i < range.len; i++) {
|
||||
if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) {
|
||||
range.ft_glyphs[range.char_to_glyph[i]] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
|
||||
range.offsets[range.char_to_glyph[i]].dv = range.font->fc->GetAscender() - range.font->fc->GetGlyph(range.ft_glyphs[range.char_to_glyph[i]])->height - 1; // Align sprite glyphs to font baseline.
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -363,7 +363,7 @@ private:
|
||||
class ScriptEventCompanyAskMerger : public ScriptEvent {
|
||||
public:
|
||||
/**
|
||||
* @param owner The company that can be bough.
|
||||
* @param owner The company that can be bought.
|
||||
* @param value The value/costs of buying the company.
|
||||
*/
|
||||
ScriptEventCompanyAskMerger(Owner owner, int32 value) :
|
||||
|
@@ -33,6 +33,10 @@
|
||||
#include "os/windows/string_uniscribe.h"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_COCOA)
|
||||
#include "os/macosx/string_osx.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ICU_SORT
|
||||
/* Required by strnatcmp. */
|
||||
#include <unicode/ustring.h>
|
||||
@@ -679,6 +683,11 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
|
||||
if (res != 0) return res - 2; // Convert to normal C return values.
|
||||
#endif
|
||||
|
||||
#if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN)
|
||||
int res = MacOSStringCompare(s1, s2);
|
||||
if (res != 0) return res - 2; // Convert to normal C return values.
|
||||
#endif
|
||||
|
||||
/* Do a manual natural sort comparison if ICU is missing or if we cannot create a collator. */
|
||||
return _strnatcmpIntl(s1, s2);
|
||||
}
|
||||
@@ -951,9 +960,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN)
|
||||
/* static */ StringIterator *StringIterator::Create()
|
||||
{
|
||||
StringIterator *i = OSXStringIterator::Create();
|
||||
if (i != NULL) return i;
|
||||
|
||||
return new DefaultStringIterator();
|
||||
}
|
||||
#else
|
||||
/* static */ StringIterator *StringIterator::Create()
|
||||
{
|
||||
return new DefaultStringIterator();
|
||||
}
|
||||
#endif /* defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) */
|
||||
|
||||
#endif
|
||||
|
@@ -2051,6 +2051,11 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
|
||||
Win32SetCurrentLocaleName(_current_language->isocode);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
extern void MacOSSetCurrentLocaleName(const char *iso_code);
|
||||
MacOSSetCurrentLocaleName(_current_language->isocode);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ICU_SORT
|
||||
/* Delete previous collator. */
|
||||
if (_current_collator != NULL) {
|
||||
@@ -2394,7 +2399,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
|
||||
/* Update the font with cache */
|
||||
LoadStringWidthTable(searcher->Monospace());
|
||||
|
||||
#if !defined(WITH_ICU_LAYOUT) && !defined(WITH_UNISCRIBE)
|
||||
#if !defined(WITH_ICU_LAYOUT) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA)
|
||||
/*
|
||||
* For right-to-left languages we need the ICU library. If
|
||||
* we do not have support for that library we warn the user
|
||||
|
Reference in New Issue
Block a user