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 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 }