| 188 | } |
| 189 | |
| 190 | void DrawFontTab() |
| 191 | { |
| 192 | // ── Face picker ──────────────────────────────────────────────── |
| 193 | // A single shipping font set; this picks which face the |
| 194 | // size/stretch/spacing sliders below tune. |
| 195 | ImGui::Text("Face:"); |
| 196 | for (int r = 0; r < 5; r++) |
| 197 | { |
| 198 | if (r > 0) |
| 199 | ImGui::SameLine(); |
| 200 | bool active = (s_currentRole == r); |
| 201 | if (active) |
| 202 | ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.6f, 0.9f, 1.0f)); |
| 203 | if (ImGui::Button(kRoleNames[r])) |
| 204 | s_currentRole = r; |
| 205 | if (active) |
| 206 | ImGui::PopStyleColor(); |
| 207 | } |
| 208 | ImGui::Separator(); |
| 209 | |
| 210 | // ── Sliders for the selected face ───────────────────────────── |
| 211 | LoadTuningIfNeeded(); |
| 212 | auto& role = s_tuning.roles[s_currentRole]; |
| 213 | |
| 214 | ImGui::Text("%s - %s (alias %s)", kRoleNames[s_currentRole], role.prefix, role.alias ? role.alias : "(none)"); |
| 215 | |
| 216 | bool changed = false; |
| 217 | changed |= ImGui::SliderInt("renderPx", &role.renderPx, 8, 128); |
| 218 | changed |= ImGui::SliderFloat("widthScale", &role.widthScale, 0.3f, 1.6f, "%.3f"); |
| 219 | changed |= ImGui::SliderFloat("baseline", &role.baselineOffset, -16.0f, 16.0f, "%.1f px"); |
| 220 | changed |= ImGui::SliderFloat("bold", &role.syntheticBold, -2.0f, 4.0f, "%.1f px"); |
| 221 | changed |= ImGui::SliderFloat("spacing", &role.letterSpacing, -4.0f, 8.0f, "%.1f px"); |
| 222 | if (changed) |
| 223 | { |
| 224 | SetFontMappingTuning(role.prefix, role.renderPx, role.widthScale, role.baselineOffset, role.syntheticBold, |
| 225 | role.letterSpacing, nullptr); |
| 226 | if (role.alias) |
| 227 | SetFontMappingTuning(role.alias, role.renderPx, role.widthScale, role.baselineOffset, role.syntheticBold, |
| 228 | role.letterSpacing, nullptr); |
| 229 | } |
| 230 | ImGui::Separator(); |
| 231 | |
| 232 | if (ImGui::Button("Dump font table to log")) |
| 233 | { |
| 234 | LOG_INFO(Graphics, "\n{}", DumpFontTable()); |
| 235 | } |
| 236 | |
| 237 | ImGui::Separator(); |
| 238 | ImGui::TextUnformatted("License plates"); |
| 239 | LicensePlateTextTuning plate = GetLicensePlateTextTuning(); |
| 240 | bool plateChanged = false; |
| 241 | plateChanged |= ImGui::SliderFloat("plate width", &plate.widthScale, 0.30f, 1.20f, "%.3f"); |
| 242 | plateChanged |= ImGui::SliderFloat("plate x offset", &plate.horizontalOffset, -5.00f, 1.00f, "%.2f em"); |
| 243 | plateChanged |= ImGui::SliderFloat("plate y offset", &plate.verticalOffset, -1.00f, 2.00f, "%.2f em"); |
| 244 | plateChanged |= ImGui::SliderFloat("plate surface offset", &plate.surfaceOffset, 0.000f, 0.050f, "%.3f m"); |
| 245 | plateChanged |= ImGui::SliderFloat("plate softness", &plate.softness, 0.000f, 0.050f, "%.3f em"); |
| 246 | if (plateChanged) |
| 247 | SetLicensePlateTextTuning(plate); |
no test coverage detected