namespace LivingVillage.Desktop open System module ChineseText = type SceneKind = | VillageScene | Waterway | WhiteWallHome | StoneBridgeScene | BambooGrove | VegetableGardenScene type DayNightKind = | DayTime | NightTime type MenuHeadingKind = | MainMenuHeading | SettingsHeading | ControlsHeading type StatusHeadingKind = | StatusHeading | ReadyStatus | PausedStatus type ChineseCopy = { SceneTitle: string Ready: string } type TextLayout = { Lines: string list MissingGlyphs: char list } let sceneLabel scene = match scene with | VillageScene -> "江南水乡" | Waterway -> "水道" | WhiteWallHome -> "白墙黛瓦民居" | StoneBridgeScene -> "石桥" | BambooGrove -> "竹林" | VegetableGardenScene -> "菜圃" let dayNightLabel time = match time with | DayTime -> "白天" | NightTime -> "夜晚" let menuHeading heading = match heading with | MainMenuHeading -> "主菜单" | SettingsHeading -> "设置" | ControlsHeading -> "操作说明" let statusHeading status = match status with | StatusHeading -> "状态" | ReadyStatus -> "准备就绪" | PausedStatus -> "已暂停" let copy : ChineseCopy = { SceneTitle = "江南水乡" Ready = "准备就绪" } let requiredUiLabels : string list = [ "江南水乡" "水道" "白墙黛瓦民居" "石桥" "竹林" "菜圃" "白天" "夜晚" "主菜单" "设置" "操作说明" "状态" "准备就绪" "已暂停" "继续游戏" "开始新游戏" "读取存档" "退出" "移动" "互动" "对话" "观察" "需求" "年鉴" "关系" "暂停" "速度" "保存" "读取" "菜单或关闭" "选择" "确认" "村庄" "饥饿" "精力" "社交" "金钱" "最紧迫" "无记录" "交易" "交易成功" "交易失败" "报价" "总价" "进入民居" "离开民居" "民居内景" "请选择对话方式" "对话完成" "对话失败" "年鉴已打开" ] let layoutText (maxWidth: int) (supported: Set) (text: string) : TextLayout = let width = max 1 maxWidth let normalized, missing = text |> Seq.fold (fun (characters, missingGlyphs) character -> if Set.contains character supported then character :: characters, missingGlyphs else '□' :: characters, character :: missingGlyphs) ([], []) { Lines = normalized |> List.rev |> List.chunkBySize width |> List.map (fun line -> new String(Array.ofList line)) MissingGlyphs = List.rev missing }