diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
index 3cb3b6e58d..b34fea0ab8 100644
--- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
+++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
@@ -1536,6 +1536,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
@@ -4256,6 +4257,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
index 01e5f4cdcf..0ff6e619f9 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
@@ -4192,6 +4192,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
index 09979cc70d..3b266c1187 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
@@ -6783,6 +6783,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
index f39992e561..b1d3b8c843 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
@@ -4192,6 +4192,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
index f306ea47a8..f2acec7386 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
@@ -6783,6 +6783,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
index ec5501941c..64b97bb329 100644
--- a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
@@ -4192,6 +4192,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
index ab1e6323b4..e9869c5fa7 100644
--- a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
@@ -6783,6 +6783,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
index ece17c694b..65be416f6e 100644
--- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
@@ -1298,6 +1298,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
@@ -3632,6 +3633,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
index 5095ac8daf..ba49f6ae77 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
@@ -3605,6 +3605,7 @@
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
index 37a26459ad..c085b2be67 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
@@ -5742,6 +5742,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
index 7bba693ea0..e515e324c4 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
@@ -3605,6 +3605,7 @@
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
index 3aca368313..c90974b0bd 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
@@ -5742,6 +5742,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
index d87a2c6b30..ffde936749 100644
--- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
@@ -1428,6 +1428,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
@@ -3915,6 +3916,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
index 362f606fc3..ba36467f62 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
@@ -3838,6 +3838,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
index aff3a83586..eda89f1f30 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
@@ -6177,6 +6177,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
index 749721c053..b827596c36 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
@@ -3838,6 +3838,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
index 51b3a61ef4..6f023e54eb 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
@@ -6177,6 +6177,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
index fd798e166b..a826c12273 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
@@ -3838,6 +3838,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
index 34d86a5981..61af027e21 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
@@ -6177,6 +6177,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
index 5124f343a0..d005922265 100644
--- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
+++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
@@ -1317,6 +1317,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
@@ -3731,6 +3732,7 @@ set_source_files_properties(
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp"
"../../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
+ "../../../../../modules/juce_graphics/detail/juce_FontRendering.h"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.cpp"
"../../../../../modules/juce_graphics/detail/juce_JustifiedText.h"
"../../../../../modules/juce_graphics/detail/juce_Ranges.cpp"
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
index 7bdae2b474..493194c2ca 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
@@ -3703,6 +3703,7 @@
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
index e2b2ae7128..411ac23e1a 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
@@ -5904,6 +5904,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
index e078b98bca..1a12c83b52 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
@@ -3703,6 +3703,7 @@
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
index 72137bc336..f5ea375726 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
@@ -5904,6 +5904,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
index ddb3226564..268b3a802b 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
@@ -2321,6 +2321,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
index b905c3eb80..eea8d5fd9c 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
@@ -3378,6 +3378,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
index 032e8b26d1..bc48609e33 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
@@ -2321,6 +2321,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
index 2002ae4ce0..2e78f840cc 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
@@ -3378,6 +3378,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
index 178e108b13..c4293cfbb7 100644
--- a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
@@ -2321,6 +2321,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
index 429e2dba2a..bacc4cf870 100644
--- a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
@@ -3378,6 +3378,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
index 1e17611272..6cd4632f81 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
@@ -3950,6 +3950,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
index b49dbe5342..f708909554 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -6336,6 +6336,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
index 3471196cf2..d86cd8fce9 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
@@ -3950,6 +3950,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
index 8ee7fb450a..64bfd1fea2 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -6336,6 +6336,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
index 449708e266..6df360926e 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
@@ -3950,6 +3950,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
index b5f724a331..6c6c1f0f36 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -6336,6 +6336,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
index 88d40eeeea..c34cf471c9 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
@@ -3679,6 +3679,7 @@
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
index 6d9ac51f1c..f9064cd7e0 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
@@ -5871,6 +5871,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
index b82eeca909..65ba80ef58 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
@@ -3679,6 +3679,7 @@
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
index 1312acb8f0..85573c7bd9 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
@@ -5871,6 +5871,9 @@
JUCE Modules\juce_graphics\contexts
+
+ JUCE Modules\juce_graphics\detail
+
JUCE Modules\juce_graphics\detail
diff --git a/modules/juce_graphics/detail/juce_FontRendering.h b/modules/juce_graphics/detail/juce_FontRendering.h
new file mode 100644
index 0000000000..e9ff114114
--- /dev/null
+++ b/modules/juce_graphics/detail/juce_FontRendering.h
@@ -0,0 +1,67 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE framework.
+ Copyright (c) Raw Material Software Limited
+
+ JUCE is an open source framework subject to commercial or open source
+ licensing.
+
+ By downloading, installing, or using the JUCE framework, or combining the
+ JUCE framework with any other source code, object code, content or any other
+ copyrightable work, you agree to the terms of the JUCE End User Licence
+ Agreement, and all incorporated terms including the JUCE Privacy Policy and
+ the JUCE Website Terms of Service, as applicable, which will bind you. If you
+ do not agree to the terms of these agreements, we will not license the JUCE
+ framework to you, and you must discontinue the installation or download
+ process and cease use of the JUCE framework.
+
+ JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
+ JUCE Privacy Policy: https://juce.com/juce-privacy-policy
+ JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
+
+ Or:
+
+ You may also use this code under the terms of the AGPLv3:
+ https://www.gnu.org/licenses/agpl-3.0.en.html
+
+ THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
+ WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
+
+ ==============================================================================
+*/
+
+namespace juce::detail
+{
+
+struct FontRendering
+{
+ FontRendering() = delete;
+
+ /*
+ Returns the total height of this font, in pixels, subject to the ascent and descent override
+ values.
+
+ If no ascent or descent override is set, this will return the same value as getHeight().
+ */
+ static float getEffectiveHeight (const Font& font)
+ {
+ const auto ptr = font.getTypefacePtr();
+
+ if (ptr == nullptr)
+ return font.getHeight();
+
+ const auto original = ptr->getMetrics (font.getMetricsKind()).heightToPoints;
+ const auto actual = font.getHeightToPointsFactor();
+
+ const auto sanity = 1e-6 < original && original < 1e6 && actual < 1e6;
+
+ if (! sanity)
+ return font.getHeight();
+
+ return font.getHeight() * actual / original;
+ }
+};
+
+} // namespace juce::detail
diff --git a/modules/juce_graphics/fonts/juce_Font.h b/modules/juce_graphics/fonts/juce_Font.h
index 6adefaa41a..4925e91b5f 100644
--- a/modules/juce_graphics/fonts/juce_Font.h
+++ b/modules/juce_graphics/fonts/juce_Font.h
@@ -659,12 +659,19 @@ public:
*/
Native getNativeDetails() const;
+ /* @internal
+ The factor by which a JUCE font height should be multiplied in order to convert to a font
+ size in points.
+
+ May be inf if the font ascent and descent overrides have both been set to 0!
+ */
+ float getHeightToPointsFactor() const;
+
private:
//==============================================================================
static bool compare (const Font&, const Font&) noexcept;
void dupeInternalIfShared();
- float getHeightToPointsFactor() const;
friend struct GraphicsFontHelpers;
diff --git a/modules/juce_graphics/juce_graphics.h b/modules/juce_graphics/juce_graphics.h
index 033a2893ba..a27ddbd554 100644
--- a/modules/juce_graphics/juce_graphics.h
+++ b/modules/juce_graphics/juce_graphics.h
@@ -148,6 +148,7 @@ namespace juce
#include "fonts/juce_TextLayout.h"
#include "contexts/juce_LowLevelGraphicsContext.h"
#include "images/juce_ScaledImage.h"
+#include "detail/juce_FontRendering.h"
#include "native/juce_RenderingHelpers.h"
#include "contexts/juce_LowLevelGraphicsSoftwareRenderer.h"
#include "effects/juce_ImageEffectFilter.h"
diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h
index 8fd08de53a..5289b8669a 100644
--- a/modules/juce_graphics/native/juce_RenderingHelpers.h
+++ b/modules/juce_graphics/native/juce_RenderingHelpers.h
@@ -203,7 +203,7 @@ public:
{
return cache.get (Key { font, glyphNumber }, [] (const auto& key)
{
- auto fontHeight = key.font.getHeight();
+ auto fontHeight = detail::FontRendering::getEffectiveHeight (key.font);
auto typeface = key.font.getTypefacePtr();
return typeface->getLayersForGlyph (key.font.getMetricsKind(),
key.glyph,
@@ -2660,7 +2660,7 @@ protected:
return std::tuple (cache.get (f, i), drawPos);
}
- const auto fontHeight = stack->font.getHeight();
+ const auto fontHeight = detail::FontRendering::getEffectiveHeight (stack->font);
const auto fontTransform = AffineTransform::scale (fontHeight * stack->font.getHorizontalScale(),
fontHeight).followedBy (t);
const auto fullTransform = stack->transform.getTransformWith (fontTransform);