From 8fc9ae35edb211c4290b288441cd17ae3c6bc24b Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:06:01 +0100 Subject: [PATCH 1/3] docs(ui): record native TrueType sizing constraints Record the version-matched outline scale and the installed Java provider rounding behavior. Keep the remaining raster work explicit so an oversampling adjustment cannot be mistaken for native pixel parity. --- .../0095-share-native-ui-programs-and-resources.pr.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md b/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md index 4253fb15..a17d357e 100644 --- a/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md +++ b/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md @@ -74,6 +74,12 @@ Disabling coverage selection makes the binding-refresh regression fail. The target native font uses cmap format 4. Supplementary format-12 behavior has synthetic coverage and still needs matching native controls. Complete TrueType raster appearance and native font-type aliases remain open. +Static instructions from Bedrock 1.26.60.5 scale TrueType outlines by the target render height divided by the hhea ascent/descent range. +Java 26.3 rounds the FreeType EM pixel size after multiplying the provider size by its oversample value. +For the matched MinecraftTen font and target height 64, native scaling corresponds to about 51.61 EM pixels; the current Java provider requests 77. +Reducing oversampling alone would still round the requested size to 52, so this change cannot establish pixel parity. +These results identify a sizing difference; they do not validate a replacement rasterizer. + Dynamic domain text uses the same native palette as ordinary labels. Help regressions cover translated components and exported program round trips. From d526bb836a1cee827bd9972e78716fb9409a8a6b Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:29:33 +0100 Subject: [PATCH 2/3] fix(ui): draw solid nine-slice interiors Preserve nonempty native UI regions whose UV endpoints coincide. The version-matched 2x2 Black texture uses this layout, and dropping its center exposed the world through the background. Fold the correction and regression into the owning renderer patch. The full build passes, and an installed 180-second replay retains the scene payload while matching the sampled native background and 63 bitmap glyph masks across GUI scales. --- ...0029-share-native-ui-scene-rendering.patch | 56 ++++++++++++++++--- ...0029-share-native-ui-scene-rendering.pr.md | 10 +++- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.patch b/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.patch index 2a82e1b2..7000b72d 100644 --- a/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.patch +++ b/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.patch @@ -1,4 +1,4 @@ -From 0e8dda882ad4bd0256d97d5c10903ec8374719aa Mon Sep 17 00:00:00 2001 +From 4cd6d773025e44ce7880b029a34ce10ea8c9073a Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sun, 18 Oct 2026 16:55:36 +0200 Subject: [PATCH] feat(ui): share native scene rendering and GUI actors @@ -844,6 +844,14 @@ Terminate label component traversal at NUL across styled runs. Native 1.26.60.5 paints only the prefix and ignores formatting changes after the terminator. Apply the same prefix to intrinsic measurement without changing tooltip paragraph normalization. + +Draw nonempty nine-slice destinations even when their UV endpoints coincide. +The bundled Bedrock 1.26.60.5 Black texture is 2x2 with one-pixel borders +and a 2x2 base. Its center stretches one texture point; dropping equal UV +endpoints leaves the screen interior transparent. Existing native captures +paint that background black. Keep empty destinations and non-finite region +rejection separate. A draw-boundary regression uses this native layout and +also verifies that a zero-width destination emits no graphics calls. --- .../bedrock/ViaFabricPlusBedrock.java | 4 + .../appearance/BedrockBoneAnimation.java | 3 + @@ -901,7 +909,7 @@ changing tooltip paragraph normalization. .../screen/ui/NativeUiHurtPayload.java | 22 + .../bedrock/screen/ui/NativeUiImageCache.java | 229 ++++ .../screen/ui/NativeUiImageRegions.java | 132 +++ - .../bedrock/screen/ui/NativeUiImages.java | 192 ++++ + .../bedrock/screen/ui/NativeUiImages.java | 193 ++++ .../bedrock/screen/ui/NativeUiInput.java | 248 ++++ .../screen/ui/NativeUiInputRouter.java | 72 ++ .../screen/ui/NativeUiJpegTexture.java | 83 ++ @@ -952,7 +960,7 @@ changing tooltip paragraph normalization. .../bedrock/screen/ui/NativeUiFontTest.java | 148 +++ .../screen/ui/NativeUiImageCacheTest.java | 142 +++ .../screen/ui/NativeUiImageRegionsTest.java | 217 ++++ - .../bedrock/screen/ui/NativeUiImagesTest.java | 137 +++ + .../bedrock/screen/ui/NativeUiImagesTest.java | 166 +++ .../screen/ui/NativeUiInputRouterTest.java | 125 ++ .../bedrock/screen/ui/NativeUiInputTest.java | 200 ++++ .../screen/ui/NativeUiJpegTextureTest.java | 83 ++ @@ -972,7 +980,7 @@ changing tooltip paragraph normalization. .../screen/ui/NativeUiViewportTest.java | 95 ++ .../native-scrollbar-visibility.json | 162 +++ .../resources/native-ui/scissor-2225.json | 622 ++++++++++ - 127 files changed, 14941 insertions(+), 37 deletions(-) + 127 files changed, 14971 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/viaversion/viafabricplus/bedrock/appearance/BedrockGuiActorAppearance.java create mode 100644 src/main/java/com/viaversion/viafabricplus/bedrock/injection/access/IBedrockGuiActorRenderer.java create mode 100644 src/main/java/com/viaversion/viafabricplus/bedrock/injection/access/IBedrockGuiScissor.java @@ -5922,10 +5930,10 @@ index 0000000..3f3e908 +} diff --git a/src/main/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImages.java b/src/main/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImages.java new file mode 100644 -index 0000000..0712aea +index 0000000..b106fad --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImages.java -@@ -0,0 +1,192 @@ +@@ -0,0 +1,193 @@ +/* + * This file is part of ViaFabricPlus Bedrock - https://github.com/ViaVersionAddons/viafabricplus-bedrock + * Copyright (C) 2026 ViaVersion and contributors @@ -6108,7 +6116,8 @@ index 0000000..0712aea + for (final var region : NativeUiImageRegions.regions(node, box.bounds(), animations.source(node, image.width, image.height))) { + final int x0 = Math.round(Math.min(region.x0(), region.x1())), x1 = Math.round(Math.max(region.x0(), region.x1())); + final int y0 = Math.round(Math.min(region.y0(), region.y1())), y1 = Math.round(Math.max(region.y0(), region.y1())); -+ if (x0 == x1 || y0 == y1 || region.u0() == region.u1() || region.v0() == region.v1()) continue; ++ // Native solid nine-slices can stretch a single texture point across a nonempty region. ++ if (x0 == x1 || y0 == y1) continue; + final boolean reverseX = region.x0() > region.x1(), reverseY = region.y0() > region.y1(); + graphics.innerBlit(RenderPipelines.GUI_TEXTURED, image.id, x0, x1, y0, y1, + (reverseX ? region.u1() : region.u0()) / image.width, (reverseX ? region.u0() : region.u1()) / image.width, @@ -12939,10 +12948,10 @@ index 0000000..d0b8045 +} diff --git a/src/test/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImagesTest.java b/src/test/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImagesTest.java new file mode 100644 -index 0000000..d4e9931 +index 0000000..b8db9b4 --- /dev/null +++ b/src/test/java/com/viaversion/viafabricplus/bedrock/screen/ui/NativeUiImagesTest.java -@@ -0,0 +1,137 @@ +@@ -0,0 +1,166 @@ +/* + * This file is part of ViaFabricPlus Bedrock - https://github.com/ViaVersionAddons/viafabricplus-bedrock + * Copyright (C) 2026 ViaVersion and contributors @@ -12958,6 +12967,9 @@ index 0000000..d4e9931 +import java.util.List; +import java.util.Optional; +import net.minecraft.client.Minecraft; ++import net.minecraft.client.gui.GuiGraphicsExtractor; ++import net.minecraft.client.renderer.RenderPipelines; ++import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.resources.Resource; +import net.minecraft.server.packs.resources.ResourceManager; @@ -12970,6 +12982,32 @@ index 0000000..d4e9931 +import static org.mockito.Mockito.*; + +final class NativeUiImagesTest { ++ @Test ++ void drawsNineSliceInteriorsThatSampleOneTexturePointButSkipsEmptyDestinations() { ++ // The native 1.26.60.5 Black texture is 2x2 with one-pixel borders and a 2x2 base. ++ final JsonObject properties = new JsonObject(); ++ properties.addProperty("texture", texture(0)); ++ properties.addProperty("nineslice_size", 1); ++ final var node = new NativeUiScene.Node("background", "image", properties, List.of(), Integer.MIN_VALUE); ++ final var id = Identifier.parse(texture(0)); ++ final var graphics = mock(GuiGraphicsExtractor.class); ++ final var animations = new NativeUiAnimations(); ++ try (final var images = spy(new NativeUiImages())) { ++ doReturn(new NativeUiImages.Image(id, 2, 2, null)).when(images).image(node); ++ final var bounds = new NativeUiLayout.Rect(0, 0, 640, 360); ++ final var box = new NativeUiLayout.Box(node, bounds, bounds, new NativeUiLayout.Size(2, 2), bounds, 0, List.of()); ++ images.draw(graphics, box, 0xFFFFFFFF, animations); ++ verify(graphics).innerBlit(RenderPipelines.GUI_TEXTURED, id, 1, 639, 1, 359, ++ .5F, .5F, .5F, .5F, 0xFFFFFFFF); ++ ++ clearInvocations(graphics); ++ final var empty = new NativeUiLayout.Rect(0, 0, 0, 360); ++ images.draw(graphics, new NativeUiLayout.Box(node, empty, bounds, new NativeUiLayout.Size(2, 2), empty, 0, List.of()), ++ 0xFFFFFFFF, animations); ++ verifyNoInteractions(graphics); ++ } ++ } ++ + @ParameterizedTest + @CsvSource({"16,12", "963,5916"}) + void retainsFrameStripsAcrossMetadataEvictionAndSourceReload(final int width, final int height) throws Exception { diff --git a/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.pr.md b/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.pr.md index 1fef1902..bc2784de 100644 --- a/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.pr.md +++ b/patches/viafabricplus-bedrock/upstreamable/0029-share-native-ui-scene-rendering.pr.md @@ -74,8 +74,16 @@ The installed control matrix matches all 63 selected bitmap masks across the fou Tooltips retain their separate CR/CRLF normalization. The [shared program](../../viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md) selects whole-string font fallbacks before rendering. +Nine-slice regions draw when their destination has area, including regions that sample a single texture point. +Bedrock 1.26.60.5 uses this layout for its opaque 2×2 Black texture with one-pixel borders. +The draw regression fails with the previous UV filter and also checks that an empty destination emits no graphics calls. +The installed add-on matches all 266,072 sampled background pixels at 1280 × 720 and native UI scale 2. +Java GUI scales 1, 2, 3, and return to 1 retain that match and all 63 selected bitmap glyph masks. +The background comparison excludes text bounds and the separate action button. +The complete 180-second replay preserves the source scene payload and verifies the installed add-on bytes. + Other TrueType families, glyph raster appearance, native font-type aliases, and complete screen appearance remain open. -Backgrounds, action appearance, and complete column placement remain open. +Other background layouts, action appearance, and complete column placement remain open. Unanchored manual-grid cells use their grid origins. The regression uses the native four-row armor shape, which previously shifted down and overlapped the main inventory. From 5171bd72ed63833b15c7574ff5fbfea42f3f3963 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:56:58 +0100 Subject: [PATCH 3/3] docs(ui): record verified native glyph raster controls Distinguish native base metrics from the doubled raster scale. Record 36 original-instruction cache controls that match the installed STB rasterizer, along with the fixture boundaries and the provider and GPU work still required. --- ...5-share-native-ui-programs-and-resources.pr.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md b/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md index a17d357e..4958f348 100644 --- a/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md +++ b/patches/viabedrock/upstreamable/0095-share-native-ui-programs-and-resources.pr.md @@ -74,11 +74,18 @@ Disabling coverage selection makes the binding-refresh regression fail. The target native font uses cmap format 4. Supplementary format-12 behavior has synthetic coverage and still needs matching native controls. Complete TrueType raster appearance and native font-type aliases remain open. -Static instructions from Bedrock 1.26.60.5 scale TrueType outlines by the target render height divided by the hhea ascent/descent range. +Bedrock 1.26.60.5 derives the base TrueType scale from the target render height and hhea ascent/descent range. +Its glyph cache doubles that scale for 2×2 oversampling and retains fractional packed metrics. Java 26.3 rounds the FreeType EM pixel size after multiplying the provider size by its oversample value. -For the matched MinecraftTen font and target height 64, native scaling corresponds to about 51.61 EM pixels; the current Java provider requests 77. -Reducing oversampling alone would still round the requested size to 52, so this change cannot establish pixel parity. -These results identify a sizing difference; they do not validate a replacement rasterizer. +For MinecraftTen at target height 64, the native base scale corresponds to about 51.61 EM pixels and the raster scale to 103.23. +The current Java provider requests 77. Changing oversampling alone does not reproduce the native raster path. + +Original initializer, glyph lookup, outline, rectangle, raster, and filter instructions supply 36 CPU cache controls. +All cache pixels and packed metrics match the installed LWJGL 3.4.3 STB rasterizer. +The controls cover six glyphs at heights 32, 64, and 96 for MinecraftTen and an additional curved-outline font. +The fixture supplies atlas placement and external allocation, memory, and rounding interfaces. +It does not execute cache I/O, GPU upload, shaders, or complete native screens. +A replacement provider still needs bounded font validation, resource lifecycle checks, and native GPU comparisons. Dynamic domain text uses the same native palette as ordinary labels. Help regressions cover translated components and exported program round trips.