瀏覽代碼

Update to 20w17a

Signed-off-by: shedaniel <daniel@shedaniel.me>
shedaniel 5 年之前
父節點
當前提交
046cc9f9a7
共有 72 個文件被更改,包括 844 次插入723 次删除
  1. 6 4
      build.gradle
  2. 8 8
      gradle.properties
  3. 4 4
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  4. 4 4
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java
  5. 3 2
      src/main/java/me/shedaniel/rei/api/ClientHelper.java
  6. 2 1
      src/main/java/me/shedaniel/rei/api/DrawableConsumer.java
  7. 4 2
      src/main/java/me/shedaniel/rei/api/EntryStack.java
  8. 5 4
      src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java
  9. 2 1
      src/main/java/me/shedaniel/rei/api/TransferRecipeCategory.java
  10. 9 6
      src/main/java/me/shedaniel/rei/api/widgets/Button.java
  11. 9 6
      src/main/java/me/shedaniel/rei/api/widgets/Label.java
  12. 6 5
      src/main/java/me/shedaniel/rei/api/widgets/Tooltip.java
  13. 5 9
      src/main/java/me/shedaniel/rei/api/widgets/Widgets.java
  14. 5 4
      src/main/java/me/shedaniel/rei/gui/ConfigReloadingScreen.java
  15. 56 52
      src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java
  16. 12 11
      src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java
  17. 20 19
      src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java
  18. 9 7
      src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java
  19. 32 29
      src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java
  20. 14 11
      src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java
  21. 32 41
      src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java
  22. 32 28
      src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java
  23. 5 3
      src/main/java/me/shedaniel/rei/gui/config/entry/NoFilteringEntry.java
  24. 12 9
      src/main/java/me/shedaniel/rei/gui/config/entry/RecipeScreenTypeEntry.java
  25. 13 16
      src/main/java/me/shedaniel/rei/gui/credits/CreditsEntryListWidget.java
  26. 11 8
      src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java
  27. 5 4
      src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeEntry.java
  28. 5 4
      src/main/java/me/shedaniel/rei/gui/subsets/SubsetsMenu.java
  29. 6 5
      src/main/java/me/shedaniel/rei/gui/subsets/entries/EntryStackMenuEntry.java
  30. 9 7
      src/main/java/me/shedaniel/rei/gui/subsets/entries/SubMenuEntry.java
  31. 6 5
      src/main/java/me/shedaniel/rei/gui/toast/CopyRecipeIdentifierToast.java
  32. 20 18
      src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java
  33. 13 8
      src/main/java/me/shedaniel/rei/gui/widget/ClickableLabelWidget.java
  34. 53 48
      src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java
  35. 25 16
      src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java
  36. 9 8
      src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java
  37. 19 14
      src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
  38. 12 11
      src/main/java/me/shedaniel/rei/gui/widget/PanelWidget.java
  39. 10 9
      src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java
  40. 4 3
      src/main/java/me/shedaniel/rei/gui/widget/RecipeArrowWidget.java
  41. 9 9
      src/main/java/me/shedaniel/rei/gui/widget/RecipeChoosePageWidget.java
  42. 7 5
      src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java
  43. 30 30
      src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java
  44. 9 6
      src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
  45. 16 14
      src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java
  46. 5 4
      src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java
  47. 1 1
      src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java
  48. 24 12
      src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java
  49. 18 17
      src/main/java/me/shedaniel/rei/impl/InternalWidgets.java
  50. 20 19
      src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java
  51. 6 4
      src/main/java/me/shedaniel/rei/impl/ScreenHelper.java
  52. 8 7
      src/main/java/me/shedaniel/rei/impl/SearchArgument.java
  53. 4 3
      src/main/java/me/shedaniel/rei/impl/widgets/ArrowWidget.java
  54. 4 3
      src/main/java/me/shedaniel/rei/impl/widgets/BurningFireWidget.java
  55. 31 28
      src/main/java/me/shedaniel/rei/impl/widgets/ButtonWidget.java
  56. 3 2
      src/main/java/me/shedaniel/rei/impl/widgets/DrawableWidget.java
  57. 2 1
      src/main/java/me/shedaniel/rei/impl/widgets/FillRectangleDrawableConsumer.java
  58. 44 38
      src/main/java/me/shedaniel/rei/impl/widgets/LabelWidget.java
  59. 15 12
      src/main/java/me/shedaniel/rei/impl/widgets/PanelWidget.java
  60. 11 9
      src/main/java/me/shedaniel/rei/impl/widgets/TexturedDrawableConsumer.java
  61. 5 3
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  62. 5 4
      src/main/java/me/shedaniel/rei/plugin/beacon/DefaultBeaconBaseCategory.java
  63. 3 3
      src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingCategory.java
  64. 4 4
      src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java
  65. 2 1
      src/main/java/me/shedaniel/rei/plugin/campfire/DefaultCampfireCategory.java
  66. 5 3
      src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java
  67. 8 6
      src/main/java/me/shedaniel/rei/plugin/cooking/DefaultCookingCategory.java
  68. 2 2
      src/main/java/me/shedaniel/rei/plugin/cooking/DefaultCookingDisplay.java
  69. 6 5
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingCategory.java
  70. 6 4
      src/main/java/me/shedaniel/rei/plugin/fuel/DefaultFuelCategory.java
  71. 13 9
      src/main/java/me/shedaniel/rei/plugin/information/DefaultInformationCategory.java
  72. 2 1
      src/main/resources/rei.aw

+ 6 - 4
build.gradle

@@ -53,7 +53,9 @@ dependencies {
     minecraft("com.mojang:minecraft:${project.minecraft_version}")
     mappings("net.fabricmc:yarn:${project.yarn_version}:v2")
     modApi("net.fabricmc:fabric-loader:${project.fabricloader_version}")
-    modApi("net.fabricmc.fabric-api:fabric-api:${project.fabric_api}")
+    modApi("net.fabricmc.fabric-api:fabric-api:${project.fabric_api}") {
+        exclude module: "fabric-biomes-v1"
+    }
     modApi("me.shedaniel.cloth:cloth-events:${cloth_events_version}") {
         transitive = false
     }
@@ -67,9 +69,9 @@ dependencies {
     modCompileOnly("io.github.prospector:modmenu:${modmenu_version}") {
         transitive = false
     }
-    modRuntime("io.github.prospector:modmenu:${modmenu_version}") {
-        transitive = false
-    }
+//    modRuntime("io.github.prospector:modmenu:${modmenu_version}") {
+//        transitive = false
+//    }
     if (includeDep) {
         afterEvaluate {
             def listAdded = new ArrayList(Arrays.asList((api_exculde as String).split(',')))

+ 8 - 8
gradle.properties

@@ -1,13 +1,13 @@
-mod_version=4.1.15-unstable
-supported_version=20w16a
-minecraft_version=20w16a
-yarn_version=20w16a+build.1
+mod_version=4.2.0-unstable
+supported_version=20w17a
+minecraft_version=20w17a
+yarn_version=20w17a+build.2
 fabricloader_version=0.8.2+build.194
-cloth_events_version=2.0.2-unstable
-cloth_config_version=3.3.2-unstable
+cloth_events_version=2.2.0-unstable
+cloth_config_version=4.0.0-unstable
 modmenu_version=1.11.0+build.2
-fabric_api=0.5.11+build.322-1.16
-autoconfig1u=2.0.1
+fabric_api=0.6.2+build.327-1.16
+autoconfig1u=3.0.1-unstable
 api_include=me.shedaniel.cloth:cloth-events,me.shedaniel.cloth:config-2,me.sargunvohra.mcmods:autoconfig1u,org.jetbrains:annotations
 api_exculde=
 #api_include=me.shedaniel.cloth:cloth-events,me.shedaniel.cloth:config-2,me.sargunvohra.mcmods:autoconfig1u,org.jetbrains:annotations,net.fabricmc.fabric-api:fabric-

+ 4 - 4
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -330,10 +330,10 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
             if (!alreadyAdded)
                 screenHooks.cloth_getChildren().add(ScreenHelper.getLastOverlay(true, false));
         });
-        ClothClientHooks.SCREEN_RENDER_POST.register((minecraftClient, screen, i, i1, v) -> {
+        ClothClientHooks.SCREEN_RENDER_POST.register((matrices, minecraftClient, screen, i, i1, v) -> {
             if (shouldReturn(screen))
                 return;
-            ScreenHelper.getLastOverlay().render(i, i1, v);
+            ScreenHelper.getLastOverlay().render(matrices, i, i1, v);
         });
         ClothClientHooks.SCREEN_MOUSE_DRAGGED.register((minecraftClient, screen, v, v1, i, v2, v3) -> {
             if (shouldReturn(screen))
@@ -371,12 +371,12 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
                 return ActionResult.SUCCESS;
             return ActionResult.PASS;
         });
-        ClothClientHooks.SCREEN_LATE_RENDER.register((minecraftClient, screen, i, i1, v) -> {
+        ClothClientHooks.SCREEN_LATE_RENDER.register((matrices, minecraftClient, screen, i, i1, v) -> {
             if (shouldReturn(screen))
                 return;
             if (!ScreenHelper.isOverlayVisible())
                 return;
-            ScreenHelper.getLastOverlay().lateRender(i, i1, v);
+            ScreenHelper.getLastOverlay().lateRender(matrices, i, i1, v);
         });
         ClothClientHooks.SCREEN_KEY_PRESSED.register((minecraftClient, screen, i, i1, i2) -> {
             if (shouldReturn(screen))

+ 4 - 4
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java

@@ -65,7 +65,7 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer {
             ServerSidePacketRegistry.INSTANCE.register(DELETE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
                 ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();
                 if (player.getServer().getPermissionLevel(player.getGameProfile()) < player.getServer().getOpPermissionLevel()) {
-                    player.sendMessage(new TranslatableText("text.rei.no_permission_cheat").formatted(Formatting.RED), false);
+                    player.sendMessage(new TranslatableText("text.rei.no_permission_cheat").method_27692(Formatting.RED), false);
                     return;
                 }
                 if (!player.inventory.getCursorStack().isEmpty())
@@ -74,7 +74,7 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer {
             ServerSidePacketRegistry.INSTANCE.register(CREATE_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
                 ServerPlayerEntity player = (ServerPlayerEntity) packetContext.getPlayer();
                 if (player.getServer().getPermissionLevel(player.getGameProfile()) < player.getServer().getOpPermissionLevel()) {
-                    player.sendMessage(new TranslatableText("text.rei.no_permission_cheat").formatted(Formatting.RED), false);
+                    player.sendMessage(new TranslatableText("text.rei.no_permission_cheat").method_27692(Formatting.RED), false);
                     return;
                 }
                 ItemStack stack = packetByteBuf.readItemStack();
@@ -118,9 +118,9 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer {
                             ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, NOT_ENOUGH_ITEMS_PACKET, buf);
                         }
                     } catch (IllegalStateException e) {
-                        player.sendSystemMessage(new TranslatableText(e.getMessage()).formatted(Formatting.RED));
+                        player.sendSystemMessage(new TranslatableText(e.getMessage()).method_27692(Formatting.RED));
                     } catch (Exception e) {
-                        player.sendSystemMessage(new TranslatableText("error.rei.internal.error", e.getMessage()).formatted(Formatting.RED));
+                        player.sendSystemMessage(new TranslatableText("error.rei.internal.error", e.getMessage()).method_27692(Formatting.RED));
                         e.printStackTrace();
                     }
                 } catch (Exception e) {

+ 3 - 2
src/main/java/me/shedaniel/rei/api/ClientHelper.java

@@ -26,6 +26,7 @@ package me.shedaniel.rei.api;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -129,7 +130,7 @@ public interface ClientHelper {
      * @param item the item to find
      * @return the mod name with blue and italic formatting
      */
-    String getFormattedModFromItem(Item item);
+    Text getFormattedModFromItem(Item item);
     
     /**
      * Gets the formatted mod from an identifier
@@ -137,7 +138,7 @@ public interface ClientHelper {
      * @param identifier the identifier to find
      * @return the mod name with blue and italic formatting
      */
-    String getFormattedModFromIdentifier(Identifier identifier);
+    Text getFormattedModFromIdentifier(Identifier identifier);
     
     /**
      * Gets the mod from an identifier

+ 2 - 1
src/main/java/me/shedaniel/rei/api/DrawableConsumer.java

@@ -24,11 +24,12 @@
 package me.shedaniel.rei.api;
 
 import net.minecraft.client.gui.DrawableHelper;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.NotNull;
 
 /**
  * Consumer of a {@link DrawableHelper} and information of mouse and delta.
  */
 public interface DrawableConsumer {
-    void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta);
+    void render(@NotNull DrawableHelper helper, @NotNull MatrixStack matrices, int mouseX, int mouseY, float delta);
 }

+ 4 - 2
src/main/java/me/shedaniel/rei/api/EntryStack.java

@@ -33,12 +33,14 @@ import me.shedaniel.rei.impl.EmptyEntryStack;
 import me.shedaniel.rei.impl.FluidEntryStack;
 import me.shedaniel.rei.impl.ItemEntryStack;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.nbt.StringNbtReader;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
@@ -248,7 +250,7 @@ public interface EntryStack {
         return null;
     }
     
-    void render(Rectangle bounds, int mouseX, int mouseY, float delta);
+    void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta);
     
     enum Type {
         ITEM,
@@ -266,7 +268,7 @@ public interface EntryStack {
         public static final Settings<Supplier<Boolean>> TOOLTIP_ENABLED = new Settings<>(TRUE);
         public static final Settings<Supplier<Boolean>> TOOLTIP_APPEND_MOD = new Settings<>(TRUE);
         public static final Settings<Supplier<Boolean>> RENDER_COUNTS = new Settings<>(TRUE);
-        public static final Settings<Function<EntryStack, List<String>>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList());
+        public static final Settings<Function<EntryStack, List<Text>>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList());
         public static final Settings<Function<EntryStack, String>> COUNTS = new Settings<>(stack -> null);
         
         private T defaultValue;

+ 5 - 4
src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java

@@ -24,19 +24,20 @@
 package me.shedaniel.rei.api;
 
 import me.shedaniel.math.Rectangle;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.ApiStatus;
 
 @ApiStatus.Internal
 public interface OptimalEntryStack {
-    default void optimisedRenderStart(float delta) {
+    default void optimisedRenderStart(MatrixStack matrices, float delta) {
     }
     
-    default void optimisedRenderBase(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    default void optimisedRenderBase(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
     }
     
-    default void optimisedRenderOverlay(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    default void optimisedRenderOverlay(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
     }
     
-    default void optimisedRenderEnd(float delta) {
+    default void optimisedRenderEnd(MatrixStack matrices, float delta) {
     }
 }

+ 2 - 1
src/main/java/me/shedaniel/rei/api/TransferRecipeCategory.java

@@ -26,11 +26,12 @@ package me.shedaniel.rei.api;
 import it.unimi.dsi.fastutil.ints.IntList;
 import me.shedaniel.math.Rectangle;
 import me.shedaniel.rei.gui.widget.Widget;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.List;
 
 public interface TransferRecipeCategory<T extends RecipeDisplay> extends RecipeCategory<T> {
     @ApiStatus.OverrideOnly
-    void renderRedSlots(List<Widget> widgets, Rectangle bounds, T display, IntList redSlots);
+    void renderRedSlots(MatrixStack matrices, List<Widget> widgets, Rectangle bounds, T display, IntList redSlots);
 }

+ 9 - 6
src/main/java/me/shedaniel/rei/api/widgets/Button.java

@@ -24,10 +24,13 @@
 package me.shedaniel.rei.api.widgets;
 
 import me.shedaniel.math.Point;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.OptionalInt;
+import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -76,12 +79,12 @@ public abstract class Button extends BaseWidget<Button> {
     }
     
     @NotNull
-    public abstract String getText();
+    public abstract Text getText();
     
-    public abstract void setText(@NotNull String text);
+    public abstract void setText(@NotNull Text text);
     
     @NotNull
-    public final Button text(@NotNull String text) {
+    public final Button text(@NotNull Text text) {
         setText(text);
         return this;
     }
@@ -98,12 +101,12 @@ public abstract class Button extends BaseWidget<Button> {
     }
     
     @Nullable
-    public abstract Consumer<Button> getOnRender();
+    public abstract BiConsumer<MatrixStack, Button> getOnRender();
     
-    public abstract void setOnRender(@Nullable Consumer<Button> onRender);
+    public abstract void setOnRender(@Nullable BiConsumer<MatrixStack, Button> onRender);
     
     @NotNull
-    public final Button onRender(@Nullable Consumer<Button> onRender) {
+    public final Button onRender(@Nullable BiConsumer<MatrixStack, Button> onRender) {
         setOnRender(onRender);
         return this;
     }

+ 9 - 6
src/main/java/me/shedaniel/rei/api/widgets/Label.java

@@ -26,9 +26,12 @@ package me.shedaniel.rei.api.widgets;
 import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -100,14 +103,14 @@ public abstract class Label extends WidgetWithBounds {
      * @return the consumer before render, null if not set.
      */
     @Nullable
-    public abstract Consumer<Label> getOnRender();
+    public abstract BiConsumer<MatrixStack, Label> getOnRender();
     
     /**
      * Sets the consumer before render.
      *
      * @param onRender the consumer before render.
      */
-    public abstract void setOnRender(@Nullable Consumer<Label> onRender);
+    public abstract void setOnRender(@Nullable BiConsumer<MatrixStack, Label> onRender);
     
     /**
      * Sets the consumer before render.
@@ -116,7 +119,7 @@ public abstract class Label extends WidgetWithBounds {
      * @return the label itself.
      */
     @NotNull
-    public final Label onRender(@Nullable Consumer<Label> onRender) {
+    public final Label onRender(@Nullable BiConsumer<MatrixStack, Label> onRender) {
         setOnRender(onRender);
         return this;
     }
@@ -291,12 +294,12 @@ public abstract class Label extends WidgetWithBounds {
     }
     
     @NotNull
-    public abstract String getText();
+    public abstract Text getText();
     
-    public abstract void setText(@NotNull String text);
+    public abstract void setText(@NotNull Text text);
     
     @NotNull
-    public final Label text(@NotNull String text) {
+    public final Label text(@NotNull Text text) {
         setText(text);
         return this;
     }

+ 6 - 5
src/main/java/me/shedaniel/rei/api/widgets/Tooltip.java

@@ -26,6 +26,7 @@ package me.shedaniel.rei.api.widgets;
 import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collection;
@@ -34,25 +35,25 @@ import java.util.List;
 public interface Tooltip {
     @SuppressWarnings("deprecation")
     @NotNull
-    static Tooltip create(Point point, Collection<String> texts) {
+    static Tooltip create(Point point, Collection<Text> texts) {
         return QueuedTooltip.create(point, texts);
     }
     
     @SuppressWarnings("deprecation")
     @NotNull
-    static Tooltip create(Point point, String... texts) {
+    static Tooltip create(Point point, Text... texts) {
         return QueuedTooltip.create(point, texts);
     }
     
     @SuppressWarnings("deprecation")
     @NotNull
-    static Tooltip create(Collection<String> texts) {
+    static Tooltip create(Collection<Text> texts) {
         return QueuedTooltip.create(texts);
     }
     
     @SuppressWarnings("deprecation")
     @NotNull
-    static Tooltip create(String... texts) {
+    static Tooltip create(Text... texts) {
         return QueuedTooltip.create(texts);
     }
     
@@ -60,7 +61,7 @@ public interface Tooltip {
     
     int getY();
     
-    List<String> getText();
+    List<Text> getText();
     
     default void queue() {
         REIHelper.getInstance().queueTooltip(this);

+ 5 - 9
src/main/java/me/shedaniel/rei/api/widgets/Widgets.java

@@ -36,6 +36,7 @@ import net.minecraft.client.gui.Drawable;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
@@ -68,11 +69,11 @@ public final class Widgets {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (element instanceof DrawableHelper)
                 ((DrawableHelper) element).setZOffset(getZ());
             if (element instanceof Drawable)
-                ((Drawable) element).render(mouseX, mouseY, delta);
+                ((Drawable) element).render(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -127,12 +128,12 @@ public final class Widgets {
     }
     
     @NotNull
-    public static Label createLabel(@NotNull Point point, @NotNull String text) {
+    public static Label createLabel(@NotNull Point point, @NotNull Text text) {
         return new LabelWidget(point, text);
     }
     
     @NotNull
-    public static Label createClickableLabel(@NotNull Point point, @NotNull String text, @Nullable Consumer<Label> onClick) {
+    public static Label createClickableLabel(@NotNull Point point, @NotNull Text text, @Nullable Consumer<Label> onClick) {
         return new LabelWidget(point, text).clickable().onClick(onClick);
     }
     
@@ -200,11 +201,6 @@ public final class Widgets {
         return EntryWidget.create(point.x, point.y);
     }
     
-    @NotNull
-    public static Button createButton(@NotNull Rectangle bounds, @NotNull String text) {
-        return new ButtonWidget(bounds, text);
-    }
-    
     @NotNull
     public static Button createButton(@NotNull Rectangle bounds, @NotNull Text text) {
         return new ButtonWidget(bounds, text);

+ 5 - 4
src/main/java/me/shedaniel/rei/gui/ConfigReloadingScreen.java

@@ -27,6 +27,7 @@ import me.shedaniel.rei.api.RecipeHelper;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Util;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -46,11 +47,11 @@ public class ConfigReloadingScreen extends Screen {
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
         this.renderDirtBackground(0);
         if (!RecipeHelper.getInstance().arePluginsLoading())
             client.openScreen(parent);
-        this.drawCenteredString(this.textRenderer, I18n.translate("text.rei.config.is.reloading"), this.width / 2, this.height / 2 - 50, 16777215);
+        this.drawCenteredString(matrices, this.textRenderer, I18n.translate("text.rei.config.is.reloading"), this.width / 2, this.height / 2 - 50, 16777215);
         String string_3;
         switch ((int) (Util.getMeasuringTimeMs() / 300L % 4L)) {
             case 0:
@@ -64,8 +65,8 @@ public class ConfigReloadingScreen extends Screen {
             case 2:
                 string_3 = "o o O";
         }
-        this.drawCenteredString(this.textRenderer, string_3, this.width / 2, this.height / 2 - 41, 8421504);
-        super.render(int_1, int_2, float_1);
+        this.drawCenteredString(matrices, this.textRenderer, string_3, this.width / 2, this.height / 2 - 41, 8421504);
+        super.render(matrices, int_1, int_2, float_1);
     }
     
     @Override

+ 56 - 52
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -58,6 +58,8 @@ import net.minecraft.client.world.ClientWorld;
 import net.minecraft.item.ItemStack;
 import net.minecraft.screen.slot.Slot;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.Identifier;
@@ -81,31 +83,32 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     public boolean shouldReInit = false;
     private int tooltipWidth;
     private int tooltipHeight;
-    private List<String> tooltipLines;
-    public final TriConsumer<Integer, Integer, Float> renderTooltipCallback = (x, y, aFloat) -> {
+    private List<Text> tooltipLines;
+    public final TriConsumer<MatrixStack, Point, Float> renderTooltipCallback = (matrices, mouse, aFloat) -> {
         RenderSystem.disableRescaleNormal();
         RenderSystem.disableDepthTest();
-        setZOffset(999);
-        this.fillGradient(x - 3, y - 4, x + tooltipWidth + 3, y - 3, -267386864, -267386864);
-        this.fillGradient(x - 3, y + tooltipHeight + 3, x + tooltipWidth + 3, y + tooltipHeight + 4, -267386864, -267386864);
-        this.fillGradient(x - 3, y - 3, x + tooltipWidth + 3, y + tooltipHeight + 3, -267386864, -267386864);
-        this.fillGradient(x - 4, y - 3, x - 3, y + tooltipHeight + 3, -267386864, -267386864);
-        this.fillGradient(x + tooltipWidth + 3, y - 3, x + tooltipWidth + 4, y + tooltipHeight + 3, -267386864, -267386864);
-        this.fillGradient(x - 3, y - 3 + 1, x - 3 + 1, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
-        this.fillGradient(x + tooltipWidth + 2, y - 3 + 1, x + tooltipWidth + 3, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
-        this.fillGradient(x - 3, y - 3, x + tooltipWidth + 3, y - 3 + 1, 1347420415, 1347420415);
-        this.fillGradient(x - 3, y + tooltipHeight + 2, x + tooltipWidth + 3, y + tooltipHeight + 3, 1344798847, 1344798847);
+        matrices.push();
+        matrices.translate(0, 0, 999);
+        int x = mouse.x;
+        int y = mouse.y;
+        this.fillGradient(matrices, x - 3, y - 4, x + tooltipWidth + 3, y - 3, -267386864, -267386864);
+        this.fillGradient(matrices, x - 3, y + tooltipHeight + 3, x + tooltipWidth + 3, y + tooltipHeight + 4, -267386864, -267386864);
+        this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y + tooltipHeight + 3, -267386864, -267386864);
+        this.fillGradient(matrices, x - 4, y - 3, x - 3, y + tooltipHeight + 3, -267386864, -267386864);
+        this.fillGradient(matrices, x + tooltipWidth + 3, y - 3, x + tooltipWidth + 4, y + tooltipHeight + 3, -267386864, -267386864);
+        this.fillGradient(matrices, x - 3, y - 3 + 1, x - 3 + 1, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
+        this.fillGradient(matrices, x + tooltipWidth + 2, y - 3 + 1, x + tooltipWidth + 3, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
+        this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y - 3 + 1, 1347420415, 1347420415);
+        this.fillGradient(matrices, x - 3, y + tooltipHeight + 2, x + tooltipWidth + 3, y + tooltipHeight + 3, 1344798847, 1344798847);
         int currentY = y;
-        MatrixStack matrixStack_1 = new MatrixStack();
         VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
-        matrixStack_1.translate(0.0D, 0.0D, getZOffset());
-        Matrix4f matrix4f_1 = matrixStack_1.peek().getModel();
+        Matrix4f matrix = matrices.peek().getModel();
         for (int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) {
-            font.draw(tooltipLines.get(lineIndex), x, currentY, -1, true, matrix4f_1, immediate, false, 0, 15728880);
+            font.draw(tooltipLines.get(lineIndex), x, currentY, -1, true, matrix, immediate, false, 0, 15728880);
             currentY += lineIndex == 0 ? 12 : 10;
         }
         immediate.draw();
-        setZOffset(0);
+        matrices.pop();
         RenderSystem.enableDepthTest();
         RenderSystem.enableRescaleNormal();
     };
@@ -195,7 +198,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                             }
                             ConfigManager.getInstance().openConfigScreen(REIHelper.getInstance().getPreviousHandledScreen());
                         })
-                        .onRender(button -> {
+                        .onRender((matrices, button) -> {
                             if (ClientHelper.getInstance().isCheating() && RoughlyEnoughItemsCore.hasOperatorPermission()) {
                                 button.setTint(RoughlyEnoughItemsCore.hasPermissionToUsePackets() ? 721354752 : 1476440063);
                             } else {
@@ -217,10 +220,10 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                                 tooltips += "\n" + I18n.translate("text.rei.cheating_limited_enabled");
                             return tooltips;
                         }),
-                Widgets.createDrawableWidget((helper, mouseX, mouseY, delta) -> {
+                Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
                     helper.setZOffset(helper.getZOffset() + 1);
                     MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
-                    helper.drawTexture(configButtonArea.x + 3, configButtonArea.y + 3, 0, 0, 14, 14);
+                    helper.drawTexture(matrices, configButtonArea.x + 3, configButtonArea.y + 3, 0, 0, 14, 14);
                 })
                 )
         ));
@@ -228,7 +231,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         if (ConfigObject.getInstance().doesShowUtilsButtons()) {
             widgets.add(Widgets.createButton(ConfigObject.getInstance().isLowerConfigButton() ? new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20) : new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 55 : 35, 10, 20, 20), NarratorManager.EMPTY)
                     .onClick(button -> MinecraftClient.getInstance().player.sendChatMessage(ConfigObject.getInstance().getGamemodeCommand().replaceAll("\\{gamemode}", getNextGameMode(Screen.hasShiftDown()).getName())))
-                    .onRender(button -> button.setText(getGameModeShortText(getCurrentGameMode())))
+                    .onRender((matrices, button) -> button.setText(new LiteralText(getGameModeShortText(getCurrentGameMode()))))
                     .focusable(false)
                     .tooltipLine(I18n.translate("text.rei.gamemode_button.tooltip", getGameModeText(getNextGameMode(Screen.hasShiftDown()))))
                     .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)));
@@ -240,17 +243,17 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                         .tooltipLine(I18n.translate("text.rei.weather_button.tooltip", I18n.translate(weather.getTranslateKey())))
                         .focusable(false)
                         .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)));
-                widgets.add(Widgets.createDrawableWidget((helper, mouseX, mouseY, delta) -> {
+                widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
                     MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
                     RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-                    helper.drawTexture(weatherButton.getBounds().x + 3, weatherButton.getBounds().y + 3, weather.getId() * 14, 14, 14, 14);
+                    helper.drawTexture(matrices, weatherButton.getBounds().x + 3, weatherButton.getBounds().y + 3, weather.getId() * 14, 14, 14, 14);
                 }));
                 xxx += ConfigObject.getInstance().isLeftHandSidePanel() ? -25 : 25;
             }
         }
         subsetsButtonBounds = getSubsetsButtonBounds();
         if (ConfigObject.getInstance().isSubsetsEnabled()) {
-            widgets.add(InternalWidgets.wrapLateRenderable(Widgets.createButton(subsetsButtonBounds, ((ClientHelperImpl) ClientHelper.getInstance()).isAprilFools.get() ? I18n.translate("text.rei.tiny_potato") : I18n.translate("text.rei.subsets"))
+            widgets.add(InternalWidgets.wrapLateRenderable(Widgets.createButton(subsetsButtonBounds, ((ClientHelperImpl) ClientHelper.getInstance()).isAprilFools.get() ? new TranslatableText("text.rei.tiny_potato") : new TranslatableText("text.rei.subsets"))
                     .onClick(button -> {
                         if (subsetsMenu == null) {
                             wrappedSubsetsMenu = InternalWidgets.wrapTranslate(InternalWidgets.wrapLateRenderable(this.subsetsMenu = SubsetsMenu.createFromRegistry(new Point(this.subsetsButtonBounds.x, this.subsetsButtonBounds.getMaxY()))), 0, 0, 400);
@@ -263,12 +266,12 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                     })));
         }
         if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
-            widgets.add(Widgets.createClickableLabel(new Point(bounds.x + (bounds.width / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), "", label -> {
+            widgets.add(Widgets.createClickableLabel(new Point(bounds.x + (bounds.width / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), NarratorManager.EMPTY, label -> {
                 ENTRY_LIST_WIDGET.setPage(0);
                 ENTRY_LIST_WIDGET.updateEntriesPosition();
-            }).tooltipLine(I18n.translate("text.rei.go_back_first_page")).focusable(false).onRender(label -> {
+            }).tooltipLine(I18n.translate("text.rei.go_back_first_page")).focusable(false).onRender((matrices, label) -> {
                 label.setClickable(ENTRY_LIST_WIDGET.getTotalPages() > 1);
-                label.setText(String.format("%s/%s", ENTRY_LIST_WIDGET.getPage() + 1, Math.max(ENTRY_LIST_WIDGET.getTotalPages(), 1)));
+                label.setText(new LiteralText(String.format("%s/%s", ENTRY_LIST_WIDGET.getPage() + 1, Math.max(ENTRY_LIST_WIDGET.getTotalPages(), 1))));
             }));
         }
         if (ConfigObject.getInstance().isCraftableFilterEnabled()) {
@@ -282,10 +285,10 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                                 ConfigManager.getInstance().toggleCraftableOnly();
                                 ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
                             })
-                            .onRender(button -> button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 939579655 : 956235776))
+                            .onRender((matrices, button) -> button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 939579655 : 956235776))
                             .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y))
                             .tooltipSupplier(button -> I18n.translate(ConfigManager.getInstance().isCraftableOnlyEnabled() ? "text.rei.showing_craftable" : "text.rei.showing_all")),
-                    Widgets.createDrawableWidget((helper, mouseX, mouseY, delta) -> {
+                    Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
                         itemRenderer.zOffset = helper.getZOffset();
                         itemRenderer.renderGuiItemIcon(icon, area.x + 2, area.y + 2);
                         itemRenderer.zOffset = 0.0F;
@@ -406,7 +409,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         List<ItemStack> currentStacks = ClientHelper.getInstance().getInventoryItemsTypes();
         if (shouldReInit) {
             ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
@@ -424,62 +427,63 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
         }
         if (OverlaySearchField.isSearching) {
-            setZOffset(200);
+            matrices.push();
+            matrices.translate(0, 0, 200f);
             if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen) {
                 HandledScreen<?> handledScreen = (HandledScreen<?>) MinecraftClient.getInstance().currentScreen;
                 int x = handledScreen.x, y = handledScreen.y;
                 for (Slot slot : handledScreen.getScreenHandler().slots)
                     if (!slot.hasStack() || !ENTRY_LIST_WIDGET.canLastSearchTermsBeAppliedTo(EntryStack.create(slot.getStack())))
-                        fillGradient(x + slot.x, y + slot.y, x + slot.x + 16, y + slot.y + 16, -601874400, -601874400);
+                        fillGradient(matrices, x + slot.x, y + slot.y, x + slot.x + 16, y + slot.y + 16, -601874400, -601874400);
             }
-            setZOffset(0);
+            matrices.pop();
         }
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-        this.renderWidgets(mouseX, mouseY, delta);
+        this.renderWidgets(matrices, mouseX, mouseY, delta);
         if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
             HandledScreen<?> handledScreen = (HandledScreen<?>) MinecraftClient.getInstance().currentScreen;
             for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(mouseX - handledScreen.x, mouseY - handledScreen.y)) {
                         String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
-                        TOOLTIPS.add(Tooltip.create(I18n.translate("text.rei.view_recipes_for", collect)));
+                        TOOLTIPS.add(Tooltip.create(new TranslatableText("text.rei.view_recipes_for", collect)));
                         break;
                     }
         }
     }
     
-    public void lateRender(int mouseX, int mouseY, float delta) {
+    public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (ScreenHelper.isOverlayVisible()) {
-            ScreenHelper.getSearchField().laterRender(mouseX, mouseY, delta);
+            ScreenHelper.getSearchField().laterRender(matrices, mouseX, mouseY, delta);
             for (Widget widget : widgets) {
                 if (widget instanceof LateRenderable && wrappedSubsetsMenu != widget)
-                    widget.render(mouseX, mouseY, delta);
+                    widget.render(matrices, mouseX, mouseY, delta);
             }
         }
         if (wrappedSubsetsMenu != null) {
             TOOLTIPS.clear();
-            wrappedSubsetsMenu.render(mouseX, mouseY, delta);
+            wrappedSubsetsMenu.render(matrices, mouseX, mouseY, delta);
         }
         Screen currentScreen = MinecraftClient.getInstance().currentScreen;
         if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
             for (Tooltip tooltip : TOOLTIPS) {
                 if (tooltip != null)
-                    renderTooltip(tooltip);
+                    renderTooltip(matrices, tooltip);
             }
         TOOLTIPS.clear();
     }
     
-    public void renderTooltip(Tooltip tooltip) {
-        renderTooltip(tooltip.getText(), tooltip.getX(), tooltip.getY());
+    public void renderTooltip(MatrixStack matrices, Tooltip tooltip) {
+        renderTooltip(matrices, tooltip.getText(), tooltip.getX(), tooltip.getY());
     }
     
-    public void renderTooltip(List<String> lines, int mouseX, int mouseY) {
+    public void renderTooltip(MatrixStack matrices, List<Text> lines, int mouseX, int mouseY) {
         if (lines.isEmpty())
             return;
-        tooltipWidth = lines.stream().map(font::getStringWidth).max(Integer::compareTo).get();
+        tooltipWidth = lines.stream().map(font::method_27525).max(Integer::compareTo).get();
         tooltipHeight = lines.size() <= 1 ? 8 : lines.size() * 10;
         tooltipLines = lines;
-        ScreenHelper.drawHoveringWidget(mouseX, mouseY, renderTooltipCallback, tooltipWidth, tooltipHeight, 0);
+        ScreenHelper.drawHoveringWidget(matrices, mouseX, mouseY, renderTooltipCallback, tooltipWidth, tooltipHeight, 0);
     }
     
     private boolean hasSameListContent(List<ItemStack> list1, List<ItemStack> list2) {
@@ -493,7 +497,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             TOOLTIPS.add(tooltip);
     }
     
-    public void renderWidgets(int int_1, int int_2, float float_1) {
+    public void renderWidgets(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (!ScreenHelper.isOverlayVisible())
             return;
         if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
@@ -502,15 +506,15 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         }
         for (Widget widget : widgets) {
             if (!(widget instanceof LateRenderable))
-                widget.render(int_1, int_2, float_1);
+                widget.render(matrices, mouseX, mouseY, delta);
         }
     }
     
     @Override
-    public boolean mouseScrolled(double i, double j, double amount) {
+    public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
         if (!ScreenHelper.isOverlayVisible())
             return false;
-        if (wrappedSubsetsMenu != null && wrappedSubsetsMenu.mouseScrolled(i, j, amount))
+        if (wrappedSubsetsMenu != null && wrappedSubsetsMenu.mouseScrolled(mouseX, mouseY, amount))
             return true;
         if (isInside(PointHelper.ofMouse())) {
             if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
@@ -521,15 +525,15 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                 else
                     return false;
                 return true;
-            } else if (ENTRY_LIST_WIDGET.mouseScrolled(i, j, amount))
+            } else if (ENTRY_LIST_WIDGET.mouseScrolled(mouseX, mouseY, amount))
                 return true;
         }
         if (isNotInExclusionZones(PointHelper.getMouseX(), PointHelper.getMouseY())) {
-            if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(i, j, amount))
+            if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(mouseX, mouseY, amount))
                 return true;
         }
         for (Widget widget : widgets)
-            if (widget != ENTRY_LIST_WIDGET && (favoritesListWidget == null || widget != favoritesListWidget) && (wrappedSubsetsMenu == null || widget != wrappedSubsetsMenu) && widget.mouseScrolled(i, j, amount))
+            if (widget != ENTRY_LIST_WIDGET && (favoritesListWidget == null || widget != favoritesListWidget) && (wrappedSubsetsMenu == null || widget != wrappedSubsetsMenu) && widget.mouseScrolled(mouseX, mouseY, amount))
                 return true;
         return false;
     }

+ 12 - 11
src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java

@@ -34,6 +34,7 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.util.Pair;
 import org.jetbrains.annotations.ApiStatus;
@@ -72,33 +73,33 @@ public class OverlaySearchField extends TextFieldWidget {
         }
     }
     
-    public void laterRender(int int_1, int int_2, float float_1) {
+    public void laterRender(MatrixStack matrices, int int_1, int int_2, float float_1) {
         RenderSystem.disableDepthTest();
         setEditableColor(isMain && ContainerScreenOverlay.getEntryListWidget().getAllStacks().isEmpty() && !getText().isEmpty() ? 16733525 : isSearching && isMain ? -852212 : (containsMouse(PointHelper.ofMouse()) || isFocused()) ? (REIHelper.getInstance().isDarkThemeEnabled() ? -17587 : -1) : -6250336);
         setSuggestion(!isFocused() && getText().isEmpty() ? I18n.translate("text.rei.search.field.suggestion") : null);
-        super.render(int_1, int_2, float_1);
+        super.render(matrices, int_1, int_2, float_1);
         RenderSystem.enableDepthTest();
     }
     
     @Override
-    protected void renderSuggestion(int x, int y) {
+    protected void renderSuggestion(MatrixStack matrices, int x, int y) {
         if (containsMouse(PointHelper.ofMouse()) || isFocused())
-            this.font.drawWithShadow(this.font.trimToWidth(this.getSuggestion(), this.getWidth()), x, y, REIHelper.getInstance().isDarkThemeEnabled() ? 0xccddaa3d : 0xddeaeaea);
+            this.font.drawWithShadow(matrices, this.font.method_27523(this.getSuggestion(), this.getWidth()), x, y, REIHelper.getInstance().isDarkThemeEnabled() ? 0xccddaa3d : 0xddeaeaea);
         else
-            this.font.drawWithShadow(this.font.trimToWidth(this.getSuggestion(), this.getWidth()), x, y, -6250336);
+            this.font.drawWithShadow(matrices, this.font.method_27523(this.getSuggestion(), this.getWidth()), x, y, -6250336);
     }
     
     @Override
-    public void renderBorder() {
+    public void renderBorder(MatrixStack matrices) {
         if (isMain && isSearching) {
-            fill(this.getBounds().x - 1, this.getBounds().y - 1, this.getBounds().x + this.getBounds().width + 1, this.getBounds().y + this.getBounds().height + 1, -852212);
+            fill(matrices, this.getBounds().x - 1, this.getBounds().y - 1, this.getBounds().x + this.getBounds().width + 1, this.getBounds().y + this.getBounds().height + 1, -852212);
         } else if (isMain && ContainerScreenOverlay.getEntryListWidget().getAllStacks().isEmpty() && !getText().isEmpty()) {
-            fill(this.getBounds().x - 1, this.getBounds().y - 1, this.getBounds().x + this.getBounds().width + 1, this.getBounds().y + this.getBounds().height + 1, -43691);
+            fill(matrices, this.getBounds().x - 1, this.getBounds().y - 1, this.getBounds().x + this.getBounds().width + 1, this.getBounds().y + this.getBounds().height + 1, -43691);
         } else {
-            super.renderBorder();
+            super.renderBorder(matrices);
             return;
         }
-        fill(this.getBounds().x, this.getBounds().y, this.getBounds().x + this.getBounds().width, this.getBounds().y + this.getBounds().height, -16777216);
+        fill(matrices, this.getBounds().x, this.getBounds().y, this.getBounds().x + this.getBounds().width, this.getBounds().y + this.getBounds().height, -16777216);
     }
     
     public int getManhattanDistance(Point point1, Point point2) {
@@ -172,7 +173,7 @@ public class OverlaySearchField extends TextFieldWidget {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
     }
     
 }

+ 20 - 19
src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java

@@ -38,8 +38,9 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
@@ -104,45 +105,45 @@ public class PreRecipeViewingScreen extends Screen {
         this.children.clear();
         this.widgets.clear();
         this.widgets.add(Widgets.createButton(new Rectangle(width / 2 - 100, height - 40, 200, 20), NarratorManager.EMPTY)
-                .onRender(button -> {
+                .onRender((matrices, button) -> {
                     button.setEnabled(isSet);
-                    button.setText(isSet ? I18n.translate("text.rei.select") : I18n.translate("config.roughlyenoughitems.recipeScreenType.unset"));
+                    button.setText(isSet ? new TranslatableText("text.rei.select") : new TranslatableText("config.roughlyenoughitems.recipeScreenType.unset"));
                 })
                 .onClick(button -> callback.accept(original)));
         this.widgets.add(new ScreenTypeSelection(width / 2 - 200 - 5, height / 2 - 112 / 2 - 10, 0));
-        this.widgets.add(Widgets.createLabel(new Point(width / 2 - 200 - 5 + 104, height / 2 - 112 / 2 + 115), I18n.translate("config.roughlyenoughitems.recipeScreenType.original")).noShadow().color(-1124073473));
+        this.widgets.add(Widgets.createLabel(new Point(width / 2 - 200 - 5 + 104, height / 2 - 112 / 2 + 115), new TranslatableText("config.roughlyenoughitems.recipeScreenType.original")).noShadow().color(-1124073473));
         this.widgets.add(new ScreenTypeSelection(width / 2 + 5, height / 2 - 112 / 2 - 10, 112));
-        this.widgets.add(Widgets.createLabel(new Point(width / 2 + 5 + 104, height / 2 - 112 / 2 + 115), I18n.translate("config.roughlyenoughitems.recipeScreenType.villager")).noShadow().color(-1124073473));
+        this.widgets.add(Widgets.createLabel(new Point(width / 2 + 5 + 104, height / 2 - 112 / 2 + 115), new TranslatableText("config.roughlyenoughitems.recipeScreenType.villager")).noShadow().color(-1124073473));
         this.children.addAll(widgets);
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
         if (this.client.world != null) {
-            this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+            this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
         } else {
-            this.fillGradient(0, 0, this.width, this.height, -16777216, -16777216);
+            this.fillGradient(matrices, 0, 0, this.width, this.height, -16777216, -16777216);
         }
-        this.drawCenteredString(this.textRenderer, this.title.asFormattedString(), this.width / 2, 20, 16777215);
+        this.method_27534(matrices, this.textRenderer, this.title, this.width / 2, 20, 16777215);
         if (showTips) {
             int i = 30;
-            for (String s : this.textRenderer.wrapStringToWidthAsList(I18n.translate("text.rei.recipe_screen_type.selection.sub"), width - 30)) {
-                this.drawCenteredString(this.textRenderer, Formatting.GRAY.toString() + s, width / 2, i, -1);
+            for (Text s : this.textRenderer.wrapStringToWidthAsList(new TranslatableText("text.rei.recipe_screen_type.selection.sub").method_27692(Formatting.GRAY), width - 30)) {
+                this.method_27534(matrices, this.textRenderer, s, width / 2, i, -1);
                 i += 10;
             }
         }
-        super.render(int_1, int_2, float_1);
+        super.render(matrices, int_1, int_2, float_1);
         for (Widget widget : widgets) {
-            widget.render(int_1, int_2, float_1);
+            widget.render(matrices, int_1, int_2, float_1);
         }
         if (isSet) {
             updateFramePosition(float_1);
             int x = (int) (width / 2 - 205 + (210 * frame));
             int y = height / 2 - 112 / 2 - 10;
-            fillGradient(x - 2, y - 4, x - 6 + 208, y - 4 + 2, -1778384897, -1778384897);
-            fillGradient(x - 2, y - 4 + 120 - 2, x - 6 + 208, y - 4 + 120, -1778384897, -1778384897);
-            fillGradient(x - 4, y - 4, x - 4 + 2, y - 4 + 120, -1778384897, -1778384897);
-            fillGradient(x - 4 + 208 - 2, y - 4, x - 4 + 208, y - 4 + 120, -1778384897, -1778384897);
+            fillGradient(matrices, x - 2, y - 4, x - 6 + 208, y - 4 + 2, -1778384897, -1778384897);
+            fillGradient(matrices, x - 2, y - 4 + 120 - 2, x - 6 + 208, y - 4 + 120, -1778384897, -1778384897);
+            fillGradient(matrices, x - 4, y - 4, x - 4 + 2, y - 4 + 120, -1778384897, -1778384897);
+            fillGradient(matrices, x - 4 + 208 - 2, y - 4, x - 4 + 208, y - 4 + 120, -1778384897, -1778384897);
         }
     }
     
@@ -187,9 +188,9 @@ public class PreRecipeViewingScreen extends Screen {
         }
         
         @Override
-        public void render(int i, int i1, float delta) {
+        public void render(MatrixStack matrices, int i, int i1, float delta) {
             MinecraftClient.getInstance().getTextureManager().bindTexture(IDENTIFIER);
-            drawTexture(bounds.x + 4, bounds.y + 4, u, v, 200, 112);
+            drawTexture(matrices, bounds.x + 4, bounds.y + 4, u, v, 200, 112);
         }
         
         @Override

+ 9 - 7
src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java

@@ -77,6 +77,7 @@ public final class RecipeDisplayExporter extends Widget {
     
     @SuppressWarnings("deprecation")
     private void exportRecipe(Rectangle rectangle, List<Widget> widgets) {
+        MatrixStack matrices = new MatrixStack();
         Framebuffer framebuffer = new Framebuffer(rectangle.width * 8, rectangle.height * 8, true, MinecraftClient.IS_SYSTEM_MAC);
         framebuffer.setClearColor(0, 0, 0, 0);
         //        int color = REIHelper.getInstance().isDarkThemeEnabled() ? -13750738 : -3750202;
@@ -120,7 +121,7 @@ public final class RecipeDisplayExporter extends Widget {
         RenderSystem.disableCull();
         RenderSystem.pushLightingAttributes();
         for (Widget widget : widgets) {
-            widget.render(-1, -1, minecraft.getTickDelta());
+            widget.render(matrices, -1, -1, minecraft.getTickDelta());
         }
         {
             ItemStack stack = new ItemStack(Items.OAK_STAIRS);
@@ -136,10 +137,10 @@ public final class RecipeDisplayExporter extends Widget {
             RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA);
             
             RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-            MatrixStack matrixStack = new MatrixStack();
+            matrices.push();
             
-            matrixStack.translate(rectangle.x + 8, rectangle.y + 8, 0);
-            matrixStack.scale(16, -16, 1F);
+            matrices.translate(rectangle.x + 8, rectangle.y + 8, 0);
+            matrices.scale(16, -16, 1F);
             
             boolean disableGuiLight = !model.isSideLit();
             if (disableGuiLight) {
@@ -147,8 +148,9 @@ public final class RecipeDisplayExporter extends Widget {
             }
             
             VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
-            minecraft.getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, matrixStack, immediate, 15728880, OverlayTexture.DEFAULT_UV, model);
+            minecraft.getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, matrices, immediate, 15728880, OverlayTexture.DEFAULT_UV, model);
             immediate.draw();
+            matrices.pop();
             
             RenderSystem.enableDepthTest();
             
@@ -209,8 +211,8 @@ public final class RecipeDisplayExporter extends Widget {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
-    
+    public void render(MatrixStack matrixStack, int mouseY, int i, float f) {
+        
     }
     
     @Override

+ 32 - 29
src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java

@@ -54,6 +54,8 @@ import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
 import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
@@ -255,7 +257,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
                         currentCategoryIndex = categories.size() - 1;
                     ClientHelperImpl.getInstance().openRecipeViewingScreen(categoriesMap, categories.get(currentCategoryIndex).getIdentifier(), ingredientStackToNotice, resultStackToNotice);
                 }).tooltipLine(I18n.translate("text.rei.previous_category")));
-        widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 7), selectedCategory.getCategoryName(), clickableLabelWidget -> {
+        widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 7), new LiteralText(selectedCategory.getCategoryName()), clickableLabelWidget -> {
             ClientHelper.getInstance().executeViewAllRecipesKeyBind();
         }).tooltipLine(I18n.translate("text.rei.view_all_categories")));
         widgets.add(categoryNext = Widgets.createButton(new Rectangle(bounds.getMaxX() - 17, bounds.getY() + 5, 12, 12), new TranslatableText("text.rei.right_arrow"))
@@ -276,11 +278,11 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
                         page = getTotalPages(selectedCategory) - 1;
                     RecipeViewingScreen.this.init();
                 }).tooltipLine(I18n.translate("text.rei.previous_page")));
-        widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 21), "", label -> {
+        widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 21), NarratorManager.EMPTY, label -> {
             RecipeViewingScreen.this.choosePageActivated = true;
             RecipeViewingScreen.this.init();
-        }).onRender(label -> {
-            label.setText(String.format("%d/%d", page + 1, getTotalPages(selectedCategory)));
+        }).onRender((matrices, label) -> {
+            label.setText(new LiteralText(String.format("%d/%d", page + 1, getTotalPages(selectedCategory))));
             label.setClickable(categoriesMap.get(selectedCategory).size() > getRecipesPerPageByHeight());
         }).tooltipSupplier(label -> label.isClickable() ? I18n.translate("text.rei.choose_page") : null));
         widgets.add(recipeNext = Widgets.createButton(new Rectangle(bounds.getMaxX() - 17, bounds.getY() + 19, 12, 12), new TranslatableText("text.rei.right_arrow"))
@@ -321,7 +323,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
             recipeBounds.put(displayBounds, setupDisplay);
             this.widgets.addAll(setupDisplay);
             if (supplier.isPresent() && supplier.get().get(displayBounds) != null)
-                this.widgets.add(InternalWidgets.createAutoCraftingButtonWidget(displayBounds, supplier.get().get(displayBounds), supplier.get().getButtonText(), displaySupplier, setupDisplay, selectedCategory));
+                this.widgets.add(InternalWidgets.createAutoCraftingButtonWidget(displayBounds, supplier.get().get(displayBounds), new LiteralText(supplier.get().getButtonText()), displaySupplier, setupDisplay, selectedCategory));
         }
         if (choosePageActivated)
             recipeChoosePageWidget = new RecipeChoosePageWidget(this, page, getTotalPages(selectedCategory));
@@ -339,7 +341,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
             preWidgets.add(workingStationsBaseWidget = Widgets.createCategoryBase(new Rectangle(xx - 5, yy - 5, 15 + innerWidth * 16, 10 + actualHeight * 16)));
             preWidgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, innerWidth * 16 + 2, actualHeight * 16 + 2)));
             int index = 0;
-            List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
+            List<Text> list = Collections.singletonList(new TranslatableText("text.rei.working_station").method_27692(Formatting.YELLOW));
             xx += (innerWidth - 1) * 16;
             for (List<EntryStack> workingStation : workingStations) {
                 preWidgets.add(new WorkstationSlotWidget(xx, yy, CollectionUtils.map(workingStation, stack -> stack.copy().setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> list))));
@@ -397,34 +399,34 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
-        this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
         for (Widget widget : preWidgets) {
-            widget.render(mouseX, mouseY, delta);
+            widget.render(matrices, mouseX, mouseY, delta);
         }
-        PanelWidget.render(bounds, -1);
+        PanelWidget.render(matrices, bounds, -1);
         if (REIHelper.getInstance().isDarkThemeEnabled()) {
-            fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF404040);
-            fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 30, 0xFF404040);
+            fill(matrices, bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF404040);
+            fill(matrices, bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 30, 0xFF404040);
         } else {
-            fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF9E9E9E);
-            fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, 0xFF9E9E9E);
+            fill(matrices, bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF9E9E9E);
+            fill(matrices, bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, 0xFF9E9E9E);
         }
         for (TabWidget tab : tabs) {
             if (!tab.isSelected())
-                tab.render(mouseX, mouseY, delta);
+                tab.render(matrices, mouseX, mouseY, delta);
         }
-        super.render(mouseX, mouseY, delta);
+        super.render(matrices, mouseX, mouseY, delta);
         for (Widget widget : widgets) {
-            widget.render(mouseX, mouseY, delta);
+            widget.render(matrices, mouseX, mouseY, delta);
         }
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         for (TabWidget tab : tabs) {
             if (tab.isSelected())
-                tab.render(mouseX, mouseY, delta);
+                tab.render(matrices, mouseX, mouseY, delta);
         }
-        ScreenHelper.getLastOverlay().render(mouseX, mouseY, delta);
-        ScreenHelper.getLastOverlay().lateRender(mouseX, mouseY, delta);
+        ScreenHelper.getLastOverlay().render(matrices, mouseX, mouseY, delta);
+        ScreenHelper.getLastOverlay().lateRender(matrices, mouseX, mouseY, delta);
         {
             ModifierKeyCode export = ConfigObject.getInstance().getExportImageKeybind();
             if (export.matchesCurrentKey()) {
@@ -432,16 +434,17 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
                     Rectangle bounds = entry.getKey();
                     setZOffset(470);
                     if (bounds.contains(mouseX, mouseY)) {
-                        fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 1744822402, 1744822402);
-                        String s = I18n.translate("text.rei.release_export", export.getLocalizedName());
-                        MatrixStack matrixStack_1 = new MatrixStack();
+                        fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 1744822402, 1744822402);
+                        Text text = new TranslatableText("text.rei.release_export", export.getLocalizedName());
                         VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
-                        matrixStack_1.translate(0.0D, 0.0D, 480);
-                        Matrix4f matrix4f_1 = matrixStack_1.peek().getModel();
-                        textRenderer.draw(s, bounds.getCenterX() - textRenderer.getStringWidth(s) / 2f, bounds.getCenterY() - 4.5f, 0xff000000, false, matrix4f_1, immediate, false, 0, 15728880);
+                        matrices.push();
+                        matrices.translate(0.0D, 0.0D, 480);
+                        Matrix4f matrix4f = matrices.peek().getModel();
+                        textRenderer.draw(text, bounds.getCenterX() - textRenderer.method_27525(text) / 2f, bounds.getCenterY() - 4.5f, 0xff000000, false, matrix4f, immediate, false, 0, 15728880);
                         immediate.draw();
+                        matrices.pop();
                     } else {
-                        fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 1744830463, 1744830463);
+                        fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 1744830463, 1744830463);
                     }
                     setZOffset(0);
                 }
@@ -449,9 +452,9 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
         }
         if (choosePageActivated) {
             setZOffset(500);
-            this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+            this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
             setZOffset(0);
-            recipeChoosePageWidget.render(mouseX, mouseY, delta);
+            recipeChoosePageWidget.render(matrices, mouseX, mouseY, delta);
         }
     }
     

+ 14 - 11
src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java

@@ -48,7 +48,10 @@ import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
@@ -168,7 +171,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             widgets.add(Widgets.createCategoryBase(new Rectangle(xx - 5, bounds.y + bounds.height - 5, 10 + w * 16, 12 + h * 16)));
             widgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, 2 + w * 16, 2 + h * 16)));
             int index = 0;
-            List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
+            List<Text> list = Collections.singletonList(new TranslatableText("text.rei.working_station").method_27692(Formatting.YELLOW));
             for (List<EntryStack> workingStation : workingStations) {
                 widgets.add(new RecipeViewingScreen.WorkstationSlotWidget(xx, yy, CollectionUtils.map(workingStation, stack -> stack.copy().setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> list))));
                 index++;
@@ -192,7 +195,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
         this.widgets.addAll(setupDisplay);
         Optional<ButtonAreaSupplier> supplier = RecipeHelper.getInstance().getAutoCraftButtonArea(category);
         if (supplier.isPresent() && supplier.get().get(recipeBounds) != null)
-            this.widgets.add(InternalWidgets.createAutoCraftingButtonWidget(recipeBounds, supplier.get().get(recipeBounds), supplier.get().getButtonText(), () -> display, setupDisplay, category));
+            this.widgets.add(InternalWidgets.createAutoCraftingButtonWidget(recipeBounds, supplier.get().get(recipeBounds), new LiteralText(supplier.get().getButtonText()), () -> display, setupDisplay, category));
         
         int index = 0;
         for (RecipeDisplay recipeDisplay : categoryMap.get(category)) {
@@ -207,7 +210,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
                     .containsMousePredicate((button, point) -> {
                         return (button.getBounds().contains(point) && scrollListBounds.contains(point)) || button.isFocused();
                     })
-                    .onRender(button -> button.setEnabled(selectedRecipeIndex != finalIndex)));
+                    .onRender((matrices, button) -> button.setEnabled(selectedRecipeIndex != finalIndex)));
             index++;
         }
         int tabV = isCompactTabs ? 166 : 192;
@@ -243,7 +246,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
                 })
                 .enabled(categories.size() > tabsPerPage));
         
-        this.widgets.add(Widgets.createClickableLabel(new Point(bounds.x + 4 + scrollListBounds.width / 2, bounds.y + 6), categories.get(selectedCategoryIndex).getCategoryName(), label -> {
+        this.widgets.add(Widgets.createClickableLabel(new Point(bounds.x + 4 + scrollListBounds.width / 2, bounds.y + 6), new LiteralText(categories.get(selectedCategoryIndex).getCategoryName()), label -> {
             ClientHelper.getInstance().executeViewAllRecipesKeyBind();
         }).tooltipLine(I18n.translate("text.rei.view_all_categories")).noShadow().color(0xFF404040, 0xFFBBBBBB).hoveredColor(0xFF0041FF, 0xFFFFBD4D));
         
@@ -303,7 +306,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (ConfigObject.getInstance().doesVillagerScreenHavePermanentScrollBar()) {
             scrollBarAlphaFutureTime = System.currentTimeMillis();
             scrollBarAlphaFuture = 0;
@@ -327,32 +330,32 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             }
         }
         scrolling.updatePosition(delta);
-        this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+        this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
         int yOffset = 0;
         for (Widget widget : widgets) {
-            widget.render(mouseX, mouseY, delta);
+            widget.render(matrices, mouseX, mouseY, delta);
         }
-        ScreenHelper.getLastOverlay().render(mouseX, mouseY, delta);
+        ScreenHelper.getLastOverlay().render(matrices, mouseX, mouseY, delta);
         RenderSystem.pushMatrix();
         ScissorsHandler.INSTANCE.scissor(scrolling.getBounds());
         for (Button button : buttonList) {
             button.getBounds().y = scrollListBounds.y + 1 + yOffset - (int) scrolling.scrollAmount;
             if (button.getBounds().getMaxY() > scrollListBounds.getMinY() && button.getBounds().getMinY() < scrollListBounds.getMaxY()) {
-                button.render(mouseX, mouseY, delta);
+                button.render(matrices, mouseX, mouseY, delta);
             }
             yOffset += button.getBounds().height;
         }
         for (int i = 0; i < buttonList.size(); i++) {
             if (buttonList.get(i).getBounds().getMaxY() > scrollListBounds.getMinY() && buttonList.get(i).getBounds().getMinY() < scrollListBounds.getMaxY()) {
                 recipeRenderers.get(i).setZ(1);
-                recipeRenderers.get(i).render(buttonList.get(i).getBounds(), mouseX, mouseY, delta);
+                recipeRenderers.get(i).render(matrices, buttonList.get(i).getBounds(), mouseX, mouseY, delta);
                 Optional.ofNullable(recipeRenderers.get(i).getTooltip(new Point(mouseX, mouseY))).ifPresent(Tooltip::queue);
             }
         }
         scrolling.renderScrollBar(0, scrollBarAlpha);
         ScissorsHandler.INSTANCE.removeLastScissor();
         RenderSystem.popMatrix();
-        ScreenHelper.getLastOverlay().lateRender(mouseX, mouseY, delta);
+        ScreenHelper.getLastOverlay().lateRender(matrices, mouseX, mouseY, delta);
     }
     
     @Override

+ 32 - 41
src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java

@@ -32,8 +32,11 @@ import net.minecraft.client.gui.widget.AbstractButtonWidget;
 import net.minecraft.client.gui.widget.ButtonWidget;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
 import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
 import net.minecraft.util.Lazy;
 import net.minecraft.util.Pair;
 import net.minecraft.util.Util;
@@ -62,15 +65,15 @@ public class WarningAndErrorScreen extends Screen {
         this.parent = parent;
     }
     
-    private void addText(String string) {
-        for (String s : textRenderer.wrapStringToWidthAsList(string, width - 80)) {
+    private void addText(Text string) {
+        for (Text s : textRenderer.wrapStringToWidthAsList(string, width - 80)) {
             listWidget.creditsAddEntry(new TextItem(s));
         }
     }
     
-    private void addLink(String string, String link) {
-        for (String s : textRenderer.wrapStringToWidthAsList(string, width - 80)) {
-            listWidget.creditsAddEntry(new LinkItem(s, link));
+    private void addLink(Text string, String link) {
+        for (Text s : textRenderer.wrapStringToWidthAsList(string, width - 80)) {
+            listWidget.creditsAddEntry(new LinkItem(s.getString(), link));
         }
     }
     
@@ -81,11 +84,11 @@ public class WarningAndErrorScreen extends Screen {
         listWidget.creditsClearEntries();
         listWidget.creditsAddEntry(new EmptyItem());
         if (!RoughlyEnoughItemsState.getWarnings().isEmpty())
-            listWidget.creditsAddEntry(new TextItem("§6Warnings:"));
+            listWidget.creditsAddEntry(new TextItem(new LiteralText("Warnings:").method_27692(Formatting.RED)));
         for (Pair<String, String> pair : RoughlyEnoughItemsState.getWarnings()) {
-            addText(pair.getLeft());
+            addText(new LiteralText(pair.getLeft()));
             if (pair.getRight() != null)
-                addLink(pair.getRight(), pair.getRight());
+                addLink(new LiteralText(pair.getRight()), pair.getRight());
             for (int i = 0; i < 2; i++) {
                 listWidget.creditsAddEntry(new EmptyItem());
             }
@@ -94,11 +97,11 @@ public class WarningAndErrorScreen extends Screen {
             listWidget.creditsAddEntry(new EmptyItem());
         }
         if (!RoughlyEnoughItemsState.getErrors().isEmpty())
-            listWidget.creditsAddEntry(new TextItem("§cErrors:"));
+            listWidget.creditsAddEntry(new TextItem(new LiteralText("Errors:").method_27692(Formatting.RED)));
         for (Pair<String, String> pair : RoughlyEnoughItemsState.getErrors()) {
-            addText(pair.getLeft());
+            addText(new LiteralText(pair.getLeft()));
             if (pair.getRight() != null)
-                addLink(pair.getRight(), pair.getRight());
+                addLink(new LiteralText(pair.getRight()), pair.getRight());
             for (int i = 0; i < 2; i++) {
                 listWidget.creditsAddEntry(new EmptyItem());
             }
@@ -107,7 +110,7 @@ public class WarningAndErrorScreen extends Screen {
             listWidget.max = Math.max(listWidget.max, child.getWidth());
         }
         children.add(buttonExit = new ButtonWidget(width / 2 - 100, height - 26, 200, 20,
-                RoughlyEnoughItemsState.getErrors().isEmpty() ? "Continue" : "Exit",
+                new LiteralText(RoughlyEnoughItemsState.getErrors().isEmpty() ? "Continue" : "Exit"),
                 button -> {
                     if (RoughlyEnoughItemsState.getErrors().isEmpty()) {
                         RoughlyEnoughItemsState.clear();
@@ -126,16 +129,16 @@ public class WarningAndErrorScreen extends Screen {
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
         this.renderDirtBackground(0);
-        this.listWidget.render(int_1, int_2, float_1);
+        this.listWidget.render(matrices, int_1, int_2, float_1);
         if (RoughlyEnoughItemsState.getErrors().isEmpty()) {
-            this.drawCenteredString(this.textRenderer, "Warnings during Roughly Enough Items' initialization", this.width / 2, 16, 16777215);
+            this.drawCenteredString(matrices, this.textRenderer, "Warnings during Roughly Enough Items' initialization", this.width / 2, 16, 16777215);
         } else {
-            this.drawCenteredString(this.textRenderer, "Errors during Roughly Enough Items' initialization", this.width / 2, 16, 16777215);
+            this.drawCenteredString(matrices, this.textRenderer, "Errors during Roughly Enough Items' initialization", this.width / 2, 16, 16777215);
         }
-        super.render(int_1, int_2, float_1);
-        this.buttonExit.render(int_1, int_2, float_1);
+        super.render(matrices, int_1, int_2, float_1);
+        this.buttonExit.render(matrices, int_1, int_2, float_1);
     }
     
     private static class StringEntryListWidget extends DynamicNewSmoothScrollingEntryListWidget<StringItem> {
@@ -191,8 +194,8 @@ public class WarningAndErrorScreen extends Screen {
     
     private static class EmptyItem extends StringItem {
         @Override
-        public void render(int i, int i1, int i2, int i3, int i4, int i5, int i6, boolean b, float v) {
-        
+        public void render(MatrixStack matrixStack, int i, int i1, int i2, int i3, int i4, int i5, int i6, boolean b, float v) {
+            
         }
         
         @Override
@@ -207,19 +210,15 @@ public class WarningAndErrorScreen extends Screen {
     }
     
     private static class TextItem extends StringItem {
-        private String text;
+        private Text text;
         
-        public TextItem(Text textComponent) {
-            this(textComponent.asFormattedString());
-        }
-        
-        public TextItem(String text) {
+        public TextItem(Text text) {
             this.text = text;
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(text, x + 5, y, -1);
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, text, x + 5, y, -1);
         }
         
         @Override
@@ -234,7 +233,7 @@ public class WarningAndErrorScreen extends Screen {
         
         @Override
         public int getWidth() {
-            return MinecraftClient.getInstance().textRenderer.getStringWidth(text) + 10;
+            return MinecraftClient.getInstance().textRenderer.method_27525(text) + 10;
         }
     }
     
@@ -243,27 +242,19 @@ public class WarningAndErrorScreen extends Screen {
         private String link;
         private boolean contains;
         
-        public LinkItem(Text textComponent) {
-            this(textComponent.asFormattedString());
-        }
-        
-        public LinkItem(String text) {
-            this(text, text);
-        }
-        
         public LinkItem(String text, String link) {
             this.text = text;
             this.link = link;
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             contains = mouseX >= x && mouseX <= x + entryWidth && mouseY >= y && mouseY <= y + entryHeight;
             if (contains) {
-                WarningAndErrorScreen.this.renderTooltip("Click to open link.", mouseX, mouseY);
-                MinecraftClient.getInstance().textRenderer.drawWithShadow("§n" + text, x + 5, y, 0xff1fc3ff);
+                WarningAndErrorScreen.this.renderTooltip(matrices, new LiteralText("Click to open link."), mouseX, mouseY);
+                MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, "§n" + text, x + 5, y, 0xff1fc3ff);
             } else {
-                MinecraftClient.getInstance().textRenderer.drawWithShadow(text, x + 5, y, 0xff1fc3ff);
+                MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, text, x + 5, y, 0xff1fc3ff);
             }
         }
         

+ 32 - 28
src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java

@@ -47,7 +47,10 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
@@ -101,28 +104,28 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
     private List<SearchArgument.SearchArguments> lastSearchArguments = Collections.emptyList();
     
     public FilteringEntry(List<EntryStack> configFiltered, List<EntryStack> defaultValue, Consumer<List<EntryStack>> saveConsumer) {
-        super("", false);
+        super(NarratorManager.EMPTY, false);
         this.configFiltered = configFiltered;
         this.defaultValue = defaultValue;
         this.saveConsumer = saveConsumer;
         this.searchField = new OverlaySearchField(0, 0, 0, 0);
         {
-            String selectAllText = I18n.translate("config.roughlyenoughitems.filteredEntries.selectAll");
-            this.selectAllButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(selectAllText) + 10, 20, selectAllText, button -> {
+            Text selectAllText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectAll");
+            this.selectAllButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(selectAllText) + 10, 20, selectAllText, button -> {
                 this.selectionPoint = new Point(-Integer.MAX_VALUE / 2, -Integer.MAX_VALUE / 2);
                 this.secondPoint = new Point(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2);
             });
         }
         {
-            String selectNoneText = I18n.translate("config.roughlyenoughitems.filteredEntries.selectNone");
-            this.selectNoneButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(selectNoneText) + 10, 20, selectNoneText, button -> {
+            Text selectNoneText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectNone");
+            this.selectNoneButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(selectNoneText) + 10, 20, selectNoneText, button -> {
                 this.selectionPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
                 this.secondPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
             });
         }
         {
-            String hideText = I18n.translate("config.roughlyenoughitems.filteredEntries.hide");
-            this.hideButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(hideText) + 10, 20, hideText, button -> {
+            Text hideText = new TranslatableText("config.roughlyenoughitems.filteredEntries.hide");
+            this.hideButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(hideText) + 10, 20, hideText, button -> {
                 for (int i = 0; i < entryStacks.size(); i++) {
                     EntryStack stack = entryStacks.get(i);
                     EntryListEntry entry = entries.get(i);
@@ -135,8 +138,8 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
             });
         }
         {
-            String showText = I18n.translate("config.roughlyenoughitems.filteredEntries.show");
-            this.showButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(showText) + 10, 20, showText, button -> {
+            Text showText = new TranslatableText("config.roughlyenoughitems.filteredEntries.show");
+            this.showButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(showText) + 10, 20, showText, button -> {
                 for (int i = 0; i < entryStacks.size(); i++) {
                     EntryStack stack = entryStacks.get(i);
                     EntryListEntry entry = entries.get(i);
@@ -178,7 +181,7 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
     
     @SuppressWarnings("rawtypes")
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         ClothConfigScreen.ListWidget parent = getParent();
         Rectangle bounds = getBounds();
         if (lastList != parent) {
@@ -210,20 +213,21 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
             if (entry.getBounds().y > bounds.getMaxY())
                 break;
             entry.entry(stack);
-            entry.render(mouseX, mouseY, delta);
+            entry.render(matrices, mouseX, mouseY, delta);
             nextIndex++;
         }
         updatePosition(delta);
         scrolling.renderScrollBar(0xff000000, 1);
-        RenderSystem.translatef(0, 0, 300);
-        this.searchField.laterRender(mouseX, mouseY, delta);
-        this.selectAllButton.render(mouseX, mouseY, delta);
-        this.selectNoneButton.render(mouseX, mouseY, delta);
-        this.hideButton.render(mouseX, mouseY, delta);
-        this.showButton.render(mouseX, mouseY, delta);
-        RenderSystem.translatef(0, 0, -300);
+        matrices.push();
+        matrices.translate(0, 0, 300);
+        this.searchField.laterRender(matrices, mouseX, mouseY, delta);
+        this.selectAllButton.render(matrices, mouseX, mouseY, delta);
+        this.selectNoneButton.render(matrices, mouseX, mouseY, delta);
+        this.hideButton.render(matrices, mouseX, mouseY, delta);
+        this.showButton.render(matrices, mouseX, mouseY, delta);
+        matrices.pop();
         if (tooltip != null) {
-            ScreenHelper.getLastOverlay().renderTooltip(tooltip);
+            ScreenHelper.getLastOverlay().renderTooltip(matrices, tooltip);
         }
     }
     
@@ -404,17 +408,17 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
         }
         
         @Override
-        protected void drawHighlighted(int mouseX, int mouseY, float delta) {
-        
+        protected void drawHighlighted(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
-            super.render(mouseX, mouseY, delta);
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            super.render(matrices, mouseX, mouseY, delta);
             if (isSelected()) {
                 Rectangle bounds = getBounds();
                 RenderSystem.disableDepthTest();
-                fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0x896b70fa, 0x896b70fa);
+                fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0x896b70fa, 0x896b70fa);
                 RenderSystem.enableDepthTest();
             }
         }
@@ -433,17 +437,17 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
         }
         
         @Override
-        protected void drawBackground(int mouseX, int mouseY, float delta) {
+        protected void drawBackground(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (isFiltered()) {
                 Rectangle bounds = getBounds();
                 RenderSystem.disableDepthTest();
-                fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0xffff0000, 0xffff0000);
+                fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0xffff0000, 0xffff0000);
                 RenderSystem.enableDepthTest();
             }
         }
         
         @Override
-        protected void queueTooltip(int mouseX, int mouseY, float delta) {
+        protected void queueTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (searchField.containsMouse(mouseX, mouseY))
                 return;
             Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY));

+ 5 - 3
src/main/java/me/shedaniel/rei/gui/config/entry/NoFilteringEntry.java

@@ -29,6 +29,8 @@ import me.shedaniel.rei.api.EntryStack;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
@@ -43,7 +45,7 @@ public class NoFilteringEntry extends AbstractConfigListEntry<List<EntryStack>>
     private List<EntryStack> configFiltered;
     
     public NoFilteringEntry(List<EntryStack> configFiltered, List<EntryStack> defaultValue, Consumer<List<EntryStack>> saveConsumer) {
-        super("", false);
+        super(NarratorManager.EMPTY, false);
         this.configFiltered = configFiltered;
         this.defaultValue = defaultValue;
         this.saveConsumer = saveConsumer;
@@ -66,9 +68,9 @@ public class NoFilteringEntry extends AbstractConfigListEntry<List<EntryStack>>
     
     @SuppressWarnings("rawtypes")
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         ClothConfigScreen.ListWidget parent = getParent();
-        drawCenteredString(MinecraftClient.getInstance().textRenderer, I18n.translate("config.roughlyenoughitems.filteredEntries.loadWorldFirst"), (parent.right - parent.left) / 2 + parent.left, (parent.bottom - parent.top) / 2 + parent.top - 5, -1);
+        drawCenteredString(matrices, MinecraftClient.getInstance().textRenderer, I18n.translate("config.roughlyenoughitems.filteredEntries.loadWorldFirst"), (parent.right - parent.left) / 2 + parent.left, (parent.bottom - parent.top) / 2 + parent.top - 5, -1);
     }
     
     @Override

+ 12 - 9
src/main/java/me/shedaniel/rei/gui/config/entry/RecipeScreenTypeEntry.java

@@ -31,8 +31,11 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.AbstractButtonWidget;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 
 import java.util.List;
 import java.util.Optional;
@@ -43,7 +46,7 @@ public class RecipeScreenTypeEntry extends TooltipListEntry<RecipeScreenType> {
     private RecipeScreenType type;
     private RecipeScreenType defaultValue;
     private Consumer<RecipeScreenType> save;
-    private AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, "") {
+    private AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, NarratorManager.EMPTY) {
         @Override
         public void onPress() {
             MinecraftClient.getInstance().openScreen(new PreRecipeViewingScreen(getScreen(), type, false, original -> {
@@ -54,15 +57,15 @@ public class RecipeScreenTypeEntry extends TooltipListEntry<RecipeScreenType> {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
-            setMessage(I18n.translate("config.roughlyenoughitems.recipeScreenType.config", type.toString()));
-            super.render(mouseX, mouseY, delta);
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            setMessage(new TranslatableText("config.roughlyenoughitems.recipeScreenType.config", type.toString()));
+            super.render(matrices, mouseX, mouseY, delta);
         }
     };
     private List<Element> children = ImmutableList.of(buttonWidget);
     
     @SuppressWarnings("deprecation")
-    public RecipeScreenTypeEntry(int width, String fieldName, RecipeScreenType type, RecipeScreenType defaultValue, Consumer<RecipeScreenType> save) {
+    public RecipeScreenTypeEntry(int width, Text fieldName, RecipeScreenType type, RecipeScreenType defaultValue, Consumer<RecipeScreenType> save) {
         super(fieldName, null);
         this.width = width;
         this.type = type;
@@ -91,13 +94,13 @@ public class RecipeScreenTypeEntry extends TooltipListEntry<RecipeScreenType> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.buttonWidget.active = this.isEditable();
         this.buttonWidget.y = y;
         this.buttonWidget.x = x + entryWidth / 2 - width / 2;
         this.buttonWidget.setWidth(width);
-        this.buttonWidget.render(mouseX, mouseY, delta);
+        this.buttonWidget.render(matrices, mouseX, mouseY, delta);
     }
 }

+ 13 - 16
src/main/java/me/shedaniel/rei/gui/credits/CreditsEntryListWidget.java

@@ -26,6 +26,7 @@ package me.shedaniel.rei.gui.credits;
 import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.DrawableHelper;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -79,23 +80,19 @@ public class CreditsEntryListWidget extends DynamicNewSmoothScrollingEntryListWi
     }
     
     public static abstract class CreditsItem extends DynamicNewSmoothScrollingEntryListWidget.Entry<CreditsItem> {
-    
+        
     }
     
     public static class TextCreditsItem extends CreditsItem {
-        private String text;
-        
-        public TextCreditsItem(Text textComponent) {
-            this(textComponent.asFormattedString());
-        }
+        private Text text;
         
-        public TextCreditsItem(String text) {
+        public TextCreditsItem(Text text) {
             this.text = text;
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(text, x + 5, y + 5, -1);
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, text, x + 5, y + 5, -1);
         }
         
         @Override
@@ -110,22 +107,22 @@ public class CreditsEntryListWidget extends DynamicNewSmoothScrollingEntryListWi
     }
     
     public static class TranslationCreditsItem extends CreditsItem {
-        private String language;
-        private List<String> translators;
+        private Text language;
+        private List<Text> translators;
         private int maxWidth;
         
-        public TranslationCreditsItem(String language, String translators, int width, int maxWidth) {
+        public TranslationCreditsItem(Text language, Text translators, int width, int maxWidth) {
             this.language = language;
             this.translators = MinecraftClient.getInstance().textRenderer.wrapStringToWidthAsList(translators, width);
             this.maxWidth = maxWidth;
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(language, x + 5, y + 5, -1);
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, language, x + 5, y + 5, -1);
             int yy = y + 5;
-            for (String translator : translators) {
-                MinecraftClient.getInstance().textRenderer.drawWithShadow(translator, x + 5 + maxWidth, yy, -1);
+            for (Text translator : translators) {
+                MinecraftClient.getInstance().textRenderer.method_27517(matrices, translator, x + 5 + maxWidth, yy, -1);
                 yy += 12;
             }
         }

+ 11 - 8
src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java

@@ -33,7 +33,10 @@ import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.text.LiteralText;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Pair;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -103,12 +106,12 @@ public class CreditsScreen extends Screen {
                 } else {
                     int maxWidth = translatorsMapped.stream().mapToInt(pair -> textRenderer.getStringWidth(pair.getLeft())).max().orElse(0) + 5;
                     for (Pair<String, String> pair : translatorsMapped) {
-                        entryListWidget.creditsAddEntry(new TranslationCreditsItem(pair.getLeft(), pair.getRight(), i - maxWidth - 10, maxWidth));
+                        entryListWidget.creditsAddEntry(new TranslationCreditsItem(new TranslatableText(pair.getLeft()), new TranslatableText(pair.getRight()), i - maxWidth - 10, maxWidth));
                     }
                 }
             } else entryListWidget.creditsAddEntry(new TextCreditsItem(new LiteralText(line)));
-        entryListWidget.creditsAddEntry(new TextCreditsItem(new LiteralText("")));
-        children.add(buttonDone = new AbstractPressableButtonWidget(width / 2 - 100, height - 26, 200, 20, I18n.translate("gui.done")) {
+        entryListWidget.creditsAddEntry(new TextCreditsItem(NarratorManager.EMPTY));
+        children.add(buttonDone = new AbstractPressableButtonWidget(width / 2 - 100, height - 26, 200, 20, new TranslatableText("gui.done")) {
             @Override
             public void onPress() {
                 CreditsScreen.this.client.openScreen(parent);
@@ -126,12 +129,12 @@ public class CreditsScreen extends Screen {
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
         this.renderDirtBackground(0);
-        this.entryListWidget.render(int_1, int_2, float_1);
-        this.drawCenteredString(this.textRenderer, I18n.translate("text.rei.credits"), this.width / 2, 16, 16777215);
-        super.render(int_1, int_2, float_1);
-        buttonDone.render(int_1, int_2, float_1);
+        this.entryListWidget.render(matrices, int_1, int_2, float_1);
+        this.drawCenteredString(matrices, this.textRenderer, I18n.translate("text.rei.credits"), this.width / 2, 16, 16777215);
+        super.render(matrices, int_1, int_2, float_1);
+        buttonDone.render(matrices, int_1, int_2, float_1);
     }
     
 }

+ 5 - 4
src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeEntry.java

@@ -32,6 +32,7 @@ import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 import net.minecraft.util.math.MathHelper;
@@ -95,14 +96,14 @@ public class SimpleRecipeEntry extends RecipeEntry {
     }
     
     @Override
-    public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
         int xx = bounds.x + 4, yy = bounds.y + 2;
         int j = 0;
         int itemsPerLine = getItemsPerLine();
         for (Slot entryWidget : inputWidgets) {
             entryWidget.setZ(getZ() + 50);
             entryWidget.getBounds().setLocation(xx, yy);
-            entryWidget.render(mouseX, mouseY, delta);
+            entryWidget.render(matrices, mouseX, mouseY, delta);
             xx += 18;
             j++;
             if (j >= getItemsPerLine() - 2) {
@@ -114,11 +115,11 @@ public class SimpleRecipeEntry extends RecipeEntry {
         xx = bounds.x + 4 + 18 * (getItemsPerLine() - 2);
         yy = bounds.y + getHeight() / 2 - 8;
         MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
-        drawTexture(xx, yy, 0, 28, 18, 18);
+        drawTexture(matrices, xx, yy, 0, 28, 18, 18);
         xx += 18;
         outputWidget.setZ(getZ() + 50);
         outputWidget.getBounds().setLocation(xx, yy);
-        outputWidget.render(mouseX, mouseY, delta);
+        outputWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     @Nullable

+ 5 - 4
src/main/java/me/shedaniel/rei/gui/subsets/SubsetsMenu.java

@@ -42,6 +42,7 @@ import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.impl.EntryRegistryImpl;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemGroup;
 import net.minecraft.item.ItemStack;
@@ -211,11 +212,11 @@ public class SubsetsMenu extends WidgetWithBounds implements LateRenderable {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         Rectangle bounds = getBounds();
         Rectangle innerBounds = getInnerBounds();
-        fill(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), -6250336);
-        fill(innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), -16777216);
+        fill(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), -6250336);
+        fill(matrices, innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), -16777216);
         boolean contains = innerBounds.contains(mouseX, mouseY);
         SubsetsMenuEntry focused = getFocused() instanceof SubsetsMenuEntry ? (SubsetsMenuEntry) getFocused() : null;
         int currentY = (int) (innerBounds.y - scrolling.scrollAmount);
@@ -233,7 +234,7 @@ public class SubsetsMenu extends WidgetWithBounds implements LateRenderable {
             boolean containsMouse = contains && mouseY >= currentY && mouseY < currentY + child.getEntryHeight();
             child.updateInformation(innerBounds.x, currentY, focused == child || containsMouse, containsMouse, rendering, getMaxEntryWidth());
             if (rendering)
-                child.render(mouseX, mouseY, delta);
+                child.render(matrices, mouseX, mouseY, delta);
             currentY += child.getEntryHeight();
         }
         ScissorsHandler.INSTANCE.removeLastScissor();

+ 6 - 5
src/main/java/me/shedaniel/rei/gui/subsets/entries/EntryStackMenuEntry.java

@@ -35,6 +35,7 @@ import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -75,15 +76,15 @@ public class EntryStackMenuEntry extends SubsetsMenuEntry {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (isFiltered()) {
             if (selected) {
-                fill(x, y, x + width, y + 18, -26215);
+                fill(matrices, x, y, x + width, y + 18, -26215);
             } else {
-                fill(x, y, x + width, y + 18, -65536);
+                fill(matrices, x, y, x + width, y + 18, -65536);
             }
         } else if (selected) {
-            fill(x, y, x + width, y + 18, 1174405119);
+            fill(matrices, x, y, x + width, y + 18, 1174405119);
         }
         if (containsMouse && mouseX >= x + (width / 2) - 8 && mouseX <= x + (width / 2) + 8 && mouseY >= y + 1 && mouseY <= y + 17) {
             REIHelper.getInstance().queueTooltip(stack.getTooltip(new Point(mouseX, mouseY)));
@@ -107,7 +108,7 @@ public class EntryStackMenuEntry extends SubsetsMenuEntry {
                 }
             } else if (!RoughlyEnoughItemsCore.isLeftModePressed) clickedLast = false;
         } else clickedLast = false;
-        stack.render(new Rectangle(x + (width / 2) - 8, y + 1, 16, 16), mouseX, mouseY, delta);
+        stack.render(matrices, new Rectangle(x + (width / 2) - 8, y + 1, 16, 16), mouseX, mouseY, delta);
     }
     
     void recalculateFilter(SubsetsMenu menu) {

+ 9 - 7
src/main/java/me/shedaniel/rei/gui/subsets/entries/SubMenuEntry.java

@@ -38,7 +38,9 @@ import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
 import net.minecraft.util.Pair;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
@@ -108,13 +110,13 @@ public class SubMenuEntry extends SubsetsMenuEntry {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         double filteredRatio = getFilteredRatio();
         if (filteredRatio > 0) {
             filteredRatio = filteredRatio * 0.85 + 0.15;
-            fill(x, y, x + width, y + 12, (16711680 | MathHelper.ceil(filteredRatio * 255.0) << 24) + (selected ? 39321 : 0));
+            fill(matrices, x, y, x + width, y + 12, (16711680 | MathHelper.ceil(filteredRatio * 255.0) << 24) + (selected ? 39321 : 0));
         } else if (selected) {
-            fill(x, y, x + width, y + 12, -12237499);
+            fill(matrices, x, y, x + width, y + 12, -12237499);
         }
         if (selected) {
             if (!entries.isEmpty()) {
@@ -123,21 +125,21 @@ public class SubMenuEntry extends SubsetsMenuEntry {
                 menu.menuStartPoint.y = y - 1;
                 List<Rectangle> areas = Lists.newArrayList(ScissorsHandler.INSTANCE.getScissorsAreas());
                 ScissorsHandler.INSTANCE.clearScissors();
-                menu.render(mouseX, mouseY, delta);
+                menu.render(matrices, mouseX, mouseY, delta);
                 for (Rectangle area : areas) {
                     ScissorsHandler.INSTANCE.scissor(area);
                 }
             } else clickedBefore = false;
             if (clickedBefore) {
                 if (rendering && mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + 12 && !entries.isEmpty()) {
-                    REIHelper.getInstance().queueTooltip(Tooltip.create("Click again to filter everything in this group."));
+                    REIHelper.getInstance().queueTooltip(Tooltip.create(new LiteralText("Click again to filter everything in this group.")));
                 } else clickedBefore = false;
             }
         } else clickedBefore = false;
-        font.draw(text, x + 2, y + 2, selected ? 16777215 : 8947848);
+        font.draw(matrices, text, x + 2, y + 2, selected ? 16777215 : 8947848);
         if (!entries.isEmpty()) {
             MinecraftClient.getInstance().getTextureManager().bindTexture(TabWidget.CHEST_GUI_TEXTURE);
-            drawTexture(x + width - 15, y - 2, 0, 28, 18, 18);
+            drawTexture(matrices, x + width - 15, y - 2, 0, 28, 18, 18);
         }
     }
     

+ 6 - 5
src/main/java/me/shedaniel/rei/gui/toast/CopyRecipeIdentifierToast.java

@@ -27,6 +27,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.toast.Toast;
 import net.minecraft.client.toast.ToastManager;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
@@ -49,15 +50,15 @@ public class CopyRecipeIdentifierToast implements Toast {
     }
     
     @Override
-    public Visibility draw(ToastManager toastManager, long var2) {
+    public Visibility draw(MatrixStack matrices, ToastManager toastManager, long var2) {
         toastManager.getGame().getTextureManager().bindTexture(TOASTS_TEX);
         RenderSystem.color3f(1.0F, 1.0F, 1.0F);
-        toastManager.drawTexture(0, 0, 0, 0, 160, 32);
+        toastManager.drawTexture(matrices, 0, 0, 0, 0, 160, 32);
         if (this.subtitle == null) {
-            toastManager.getGame().textRenderer.draw(this.title, 18.0F, 12.0F, 11141120);
+            toastManager.getGame().textRenderer.draw(matrices, this.title, 18.0F, 12.0F, 11141120);
         } else {
-            toastManager.getGame().textRenderer.draw(this.title, 18.0F, 7.0F, 11141120);
-            toastManager.getGame().textRenderer.draw(this.subtitle, 18.0F, 18.0F, -16777216);
+            toastManager.getGame().textRenderer.draw(matrices, this.title, 18.0F, 7.0F, 11141120);
+            toastManager.getGame().textRenderer.draw(matrices, this.subtitle, 18.0F, 18.0F, -16777216);
         }
         
         return var2 - this.startTime < 5000L ? Visibility.SHOW : Visibility.HIDE;

+ 20 - 18
src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java

@@ -30,6 +30,7 @@ import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.widgets.Tooltip;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.text.LiteralText;
 import net.minecraft.text.Text;
@@ -44,10 +45,11 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @see me.shedaniel.rei.api.widgets.Widgets#createButton(me.shedaniel.math.Rectangle, Text)
- * @see me.shedaniel.rei.api.widgets.Widgets#createButton(me.shedaniel.math.Rectangle, String)
  */
 @Deprecated
 @ApiStatus.ScheduledForRemoval
@@ -64,7 +66,7 @@ public abstract class ButtonWidget extends WidgetWithBounds {
     
     protected ButtonWidget(Rectangle rectangle, Text text) {
         this.bounds = Objects.requireNonNull(rectangle);
-        this.text = Objects.requireNonNull(text).asFormattedString();
+        this.text = Objects.requireNonNull(text).getString();
     }
     
     public static ButtonWidget create(Rectangle point, String text, Consumer<ButtonWidget> onClick) {
@@ -125,33 +127,33 @@ public abstract class ButtonWidget extends WidgetWithBounds {
         return int_1;
     }
     
-    protected void renderBackground(int x, int y, int width, int height, int textureOffset) {
+    protected void renderBackground(MatrixStack matrices, int x, int y, int width, int height, int textureOffset) {
         minecraft.getTextureManager().bindTexture(REIHelper.getInstance().isDarkThemeEnabled() ? BUTTON_LOCATION_DARK : BUTTON_LOCATION);
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         RenderSystem.enableBlend();
         RenderSystem.blendFuncSeparate(770, 771, 1, 0);
         RenderSystem.blendFunc(770, 771);
         //Four Corners
-        drawTexture(x, y, getZOffset(), 0, textureOffset * 80, 4, 4, 512, 256);
-        drawTexture(x + width - 4, y, getZOffset(), 252, textureOffset * 80, 4, 4, 512, 256);
-        drawTexture(x, y + height - 4, getZOffset(), 0, textureOffset * 80 + 76, 4, 4, 512, 256);
-        drawTexture(x + width - 4, y + height - 4, getZOffset(), 252, textureOffset * 80 + 76, 4, 4, 512, 256);
+        drawTexture(matrices, x, y, getZOffset(), 0, textureOffset * 80, 4, 4, 512, 256);
+        drawTexture(matrices, x + width - 4, y, getZOffset(), 252, textureOffset * 80, 4, 4, 512, 256);
+        drawTexture(matrices, x, y + height - 4, getZOffset(), 0, textureOffset * 80 + 76, 4, 4, 512, 256);
+        drawTexture(matrices, x + width - 4, y + height - 4, getZOffset(), 252, textureOffset * 80 + 76, 4, 4, 512, 256);
         
         //Sides
-        drawTexture(x + 4, y, getZOffset(), 4, textureOffset * 80, MathHelper.ceil((width - 8) / 2f), 4, 512, 256);
-        drawTexture(x + 4, y + height - 4, getZOffset(), 4, textureOffset * 80 + 76, MathHelper.ceil((width - 8) / 2f), 4, 512, 256);
-        drawTexture(x + 4 + MathHelper.ceil((width - 8) / 2f), y + height - 4, getZOffset(), 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80 + 76, MathHelper.floor((width - 8) / 2f), 4, 512, 256);
-        drawTexture(x + 4 + MathHelper.ceil((width - 8) / 2f), y, getZOffset(), 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80, MathHelper.floor((width - 8) / 2f), 4, 512, 256);
+        drawTexture(matrices, x + 4, y, getZOffset(), 4, textureOffset * 80, MathHelper.ceil((width - 8) / 2f), 4, 512, 256);
+        drawTexture(matrices, x + 4, y + height - 4, getZOffset(), 4, textureOffset * 80 + 76, MathHelper.ceil((width - 8) / 2f), 4, 512, 256);
+        drawTexture(matrices, x + 4 + MathHelper.ceil((width - 8) / 2f), y + height - 4, getZOffset(), 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80 + 76, MathHelper.floor((width - 8) / 2f), 4, 512, 256);
+        drawTexture(matrices, x + 4 + MathHelper.ceil((width - 8) / 2f), y, getZOffset(), 252 - MathHelper.floor((width - 8) / 2f), textureOffset * 80, MathHelper.floor((width - 8) / 2f), 4, 512, 256);
         for (int i = y + 4; i < y + height - 4; i += 76) {
-            drawTexture(x, i, getZOffset(), 0, 4 + textureOffset * 80, MathHelper.ceil(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76), 512, 256);
-            drawTexture(x + MathHelper.ceil(width / 2f), i, getZOffset(), 256 - MathHelper.floor(width / 2f), 4 + textureOffset * 80, MathHelper.floor(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76), 512, 256);
+            drawTexture(matrices, x, i, getZOffset(), 0, 4 + textureOffset * 80, MathHelper.ceil(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76), 512, 256);
+            drawTexture(matrices, x + MathHelper.ceil(width / 2f), i, getZOffset(), 256 - MathHelper.floor(width / 2f), 4 + textureOffset * 80, MathHelper.floor(width / 2f), MathHelper.clamp(y + height - 4 - i, 0, 76), 512, 256);
         }
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
-        renderBackground(x, y, width, height, this.getTextureId(isHovered(mouseX, mouseY)));
+        renderBackground(matrices, x, y, width, height, this.getTextureId(isHovered(mouseX, mouseY)));
         
         int color = 14737632;
         if (!this.enabled) {
@@ -160,13 +162,13 @@ public abstract class ButtonWidget extends WidgetWithBounds {
             color = 16777120;
         }
         
-        this.drawCenteredString(font, getText(), x + width / 2, y + (height - 8) / 2, color);
+        this.drawCenteredString(matrices, font, getText(), x + width / 2, y + (height - 8) / 2, color);
         
         if (getTooltips().isPresent())
             if (!focused && containsMouse(mouseX, mouseY))
-                Tooltip.create(getTooltips().get().split("\n")).queue();
+                Tooltip.create(Stream.of(getTooltips().get().split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
             else if (focused)
-                Tooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n")).queue();
+                Tooltip.create(new Point(x + width / 2, y + height / 2), Stream.of(getTooltips().get().split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
     }
     
     public boolean isHovered(int mouseX, int mouseY) {

+ 13 - 8
src/main/java/me/shedaniel/rei/gui/widget/ClickableLabelWidget.java

@@ -27,9 +27,14 @@ import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @see Widgets#createClickableLabel(Point, String, Consumer)
@@ -43,7 +48,7 @@ public abstract class ClickableLabelWidget extends LabelWidget {
     private int hoveredColor;
     
     @ApiStatus.Internal
-    protected ClickableLabelWidget(Point point, String text) {
+    protected ClickableLabelWidget(Point point, Text text) {
         super(point, text);
         this.hoveredColor = REIHelper.getInstance().isDarkThemeEnabled() ? -1 : 0xFF66FFCC;
     }
@@ -63,7 +68,7 @@ public abstract class ClickableLabelWidget extends LabelWidget {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         int color = getDefaultColor();
         if (isClickable() && isHovered(mouseX, mouseY))
             color = getHoveredColor();
@@ -71,14 +76,14 @@ public abstract class ClickableLabelWidget extends LabelWidget {
         int width = font.getStringWidth(getText());
         if (isCentered()) {
             if (isHasShadows())
-                font.drawWithShadow(getText(), pos.x - width / 2f, pos.y, color);
+                font.method_27517(matrices, text, pos.x - width / 2f, pos.y, color);
             else
-                font.draw(getText(), pos.x - width / 2f, pos.y, color);
+                font.method_27528(matrices, text, pos.x - width / 2f, pos.y, color);
         } else {
             if (isHasShadows())
-                font.drawWithShadow(getText(), pos.x, pos.y, color);
+                font.method_27517(matrices, text, pos.x, pos.y, color);
             else
-                font.draw(getText(), pos.x, pos.y, color);
+                font.method_27528(matrices, text, pos.x, pos.y, color);
         }
         drawTooltips(mouseX, mouseY);
     }
@@ -87,9 +92,9 @@ public abstract class ClickableLabelWidget extends LabelWidget {
     protected void drawTooltips(int mouseX, int mouseY) {
         if (isClickable() && getTooltips().isPresent())
             if (!focused && containsMouse(mouseX, mouseY))
-                Tooltip.create(getTooltips().get().split("\n")).queue();
+                Tooltip.create(Stream.of(getTooltips().get().split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
             else if (focused)
-                Tooltip.create(getLocation(), getTooltips().get().split("\n")).queue();
+                Tooltip.create(getLocation(), Stream.of(getTooltips().get().split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
     }
     
     public int getHoveredColor() {

+ 53 - 48
src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java

@@ -47,6 +47,9 @@ import net.minecraft.client.render.VertexConsumerProvider;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.ItemGroup;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.Matrix4f;
@@ -185,7 +188,7 @@ public class EntryListWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (ConfigObject.getInstance().isEntryListWidgetScrolled()) {
             for (EntryListEntry entry : entries)
                 entry.clearStacks();
@@ -200,7 +203,7 @@ public class EntryListWidget extends WidgetWithBounds {
                 int size = 0;
                 long time = 0;
                 if (sizeForFavorites > 0) {
-                    drawString(font, I18n.translate("text.rei.favorites"), innerBounds.x + 2, (int) (innerBounds.y + 8 - scrolling.scrollAmount), -1);
+                    method_27535(matrices, font, new TranslatableText("text.rei.favorites"), innerBounds.x + 2, (int) (innerBounds.y + 8 - scrolling.scrollAmount), -1);
                     nextIndex += innerBounds.width / entrySize();
                     back1:
                     for (EntryStack stack : favorites) {
@@ -214,7 +217,7 @@ public class EntryListWidget extends WidgetWithBounds {
                                 entry.isFavorites = true;
                                 size++;
                                 long l = System.currentTimeMillis();
-                                entry.render(mouseX, mouseY, delta);
+                                entry.render(matrices, mouseX, mouseY, delta);
                                 time += (System.currentTimeMillis() - l);
                                 nextIndex++;
                                 break;
@@ -241,7 +244,7 @@ public class EntryListWidget extends WidgetWithBounds {
                             if (!entry.getCurrentEntry().isEmpty()) {
                                 size++;
                                 long l = System.nanoTime();
-                                entry.render(mouseX, mouseY, delta);
+                                entry.render(matrices, mouseX, mouseY, delta);
                                 time += (System.nanoTime() - l);
                             }
                             nextIndex++;
@@ -255,18 +258,19 @@ public class EntryListWidget extends WidgetWithBounds {
                 long totalTime = System.nanoTime() - totalTimeStart;
                 int z = getZ();
                 setZ(500);
-                String str = String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size, time / (double) size, totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0]);
-                fillGradient(bounds.x, bounds.y, bounds.x + font.getStringWidth(str) + 2, bounds.y + font.fontHeight + 2, -16777216, -16777216);
-                MatrixStack matrixStack_1 = new MatrixStack();
+                Text debugText = new LiteralText(String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size, time / (double) size, totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0]));
+                fillGradient(matrices, bounds.x, bounds.y, bounds.x + font.method_27525(debugText) + 2, bounds.y + font.fontHeight + 2, -16777216, -16777216);
                 VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
-                matrixStack_1.translate(0.0D, 0.0D, getZ());
-                Matrix4f matrix4f_1 = matrixStack_1.peek().getModel();
-                font.draw(str, bounds.x + 2, bounds.y + 2, -1, false, matrix4f_1, immediate, false, 0, 15728880);
+                matrices.push();
+                matrices.translate(0.0D, 0.0D, getZ());
+                Matrix4f matrix = matrices.peek().getModel();
+                font.draw(debugText, bounds.x + 2, bounds.y + 2, -1, false, matrix, immediate, false, 0, 15728880);
                 immediate.draw();
                 setZ(z);
+                matrices.pop();
             } else {
                 if (sizeForFavorites > 0) {
-                    drawString(font, I18n.translate("text.rei.favorites"), innerBounds.x + 2, (int) (innerBounds.y + 8 - scrolling.scrollAmount), -1);
+                    method_27535(matrices, font, new TranslatableText("text.rei.favorites"), innerBounds.x + 2, (int) (innerBounds.y + 8 - scrolling.scrollAmount), -1);
                     nextIndex += innerBounds.width / entrySize();
                     back1:
                     for (EntryStack stack : favorites) {
@@ -278,7 +282,7 @@ public class EntryListWidget extends WidgetWithBounds {
                             if (notSteppingOnExclusionZones(entry.getBounds().x, entry.getBounds().y, innerBounds)) {
                                 entry.entry(stack);
                                 entry.isFavorites = true;
-                                entry.render(mouseX, mouseY, delta);
+                                entry.render(matrices, mouseX, mouseY, delta);
                                 nextIndex++;
                                 break;
                             } else {
@@ -301,7 +305,7 @@ public class EntryListWidget extends WidgetWithBounds {
                         if (notSteppingOnExclusionZones(entry.getBounds().x, entry.getBounds().y, innerBounds)) {
                             entry.entry(stack);
                             entry.isFavorites = false;
-                            entry.render(mouseX, mouseY, delta);
+                            entry.render(matrices, mouseX, mouseY, delta);
                             nextIndex++;
                             break;
                         } else {
@@ -319,7 +323,7 @@ public class EntryListWidget extends WidgetWithBounds {
                 int size = 0;
                 long time = 0;
                 for (Widget widget : renders) {
-                    widget.render(mouseX, mouseY, delta);
+                    widget.render(matrices, mouseX, mouseY, delta);
                 }
                 long totalTimeStart = System.nanoTime();
                 if (ConfigObject.getInstance().doesFastEntryRendering()) {
@@ -331,33 +335,33 @@ public class EntryListWidget extends WidgetWithBounds {
                         EntryStack first = firstWidget.getCurrentEntry();
                         if (first instanceof OptimalEntryStack) {
                             OptimalEntryStack firstStack = (OptimalEntryStack) first;
-                            firstStack.optimisedRenderStart(delta);
+                            firstStack.optimisedRenderStart(matrices, delta);
                             long l = System.nanoTime();
                             for (EntryListEntry listEntry : list) {
                                 EntryStack currentEntry = listEntry.getCurrentEntry();
                                 currentEntry.setZ(100);
-                                listEntry.drawBackground(mouseX, mouseY, delta);
-                                ((OptimalEntryStack) currentEntry).optimisedRenderBase(listEntry.getInnerBounds(), mouseX, mouseY, delta);
+                                listEntry.drawBackground(matrices, mouseX, mouseY, delta);
+                                ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta);
                                 if (!currentEntry.isEmpty())
                                     size++;
                             }
                             for (EntryListEntry listEntry : list) {
                                 EntryStack currentEntry = listEntry.getCurrentEntry();
-                                ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(listEntry.getInnerBounds(), mouseX, mouseY, delta);
+                                ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta);
                                 if (listEntry.containsMouse(mouseX, mouseY)) {
-                                    listEntry.queueTooltip(mouseX, mouseY, delta);
-                                    listEntry.drawHighlighted(mouseX, mouseY, delta);
+                                    listEntry.queueTooltip(matrices, mouseX, mouseY, delta);
+                                    listEntry.drawHighlighted(matrices, mouseX, mouseY, delta);
                                 }
                             }
                             time += (System.nanoTime() - l);
-                            firstStack.optimisedRenderEnd(delta);
+                            firstStack.optimisedRenderEnd(matrices, delta);
                         } else {
                             for (EntryListEntry listEntry : list) {
                                 if (listEntry.getCurrentEntry().isEmpty())
                                     continue;
                                 size++;
                                 long l = System.nanoTime();
-                                listEntry.render(mouseX, mouseY, delta);
+                                listEntry.render(matrices, mouseX, mouseY, delta);
                                 time += (System.nanoTime() - l);
                             }
                         }
@@ -368,26 +372,27 @@ public class EntryListWidget extends WidgetWithBounds {
                             continue;
                         size++;
                         long l = System.nanoTime();
-                        entry.render(mouseX, mouseY, delta);
+                        entry.render(matrices, mouseX, mouseY, delta);
                         time += (System.nanoTime() - l);
                     }
                 }
                 long totalTime = System.nanoTime() - totalTimeStart;
                 int z = getZ();
                 setZ(500);
-                String str = String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size, time / (double) size, totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0]);
-                int stringWidth = font.getStringWidth(str);
-                fillGradient(Math.min(bounds.x, minecraft.currentScreen.width - stringWidth - 2), bounds.y, bounds.x + stringWidth + 2, bounds.y + font.fontHeight + 2, -16777216, -16777216);
-                MatrixStack matrixStack_1 = new MatrixStack();
+                Text debugText = new LiteralText(String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size, time / (double) size, totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0]));
+                int stringWidth = font.method_27525(debugText);
+                fillGradient(matrices, Math.min(bounds.x, minecraft.currentScreen.width - stringWidth - 2), bounds.y, bounds.x + stringWidth + 2, bounds.y + font.fontHeight + 2, -16777216, -16777216);
                 VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
-                matrixStack_1.translate(0.0D, 0.0D, getZ());
-                Matrix4f matrix4f_1 = matrixStack_1.peek().getModel();
-                font.draw(str, Math.min(bounds.x + 2, minecraft.currentScreen.width - stringWidth), bounds.y + 2, -1, false, matrix4f_1, immediate, false, 0, 15728880);
+                matrices.push();
+                matrices.translate(0.0D, 0.0D, getZ());
+                Matrix4f matrix = matrices.peek().getModel();
+                font.draw(debugText, Math.min(bounds.x + 2, minecraft.currentScreen.width - stringWidth), bounds.y + 2, -1, false, matrix, immediate, false, 0, 15728880);
                 immediate.draw();
                 setZ(z);
+                matrices.pop();
             } else {
                 for (Widget widget : renders) {
-                    widget.render(mouseX, mouseY, delta);
+                    widget.render(matrices, mouseX, mouseY, delta);
                 }
                 if (ConfigObject.getInstance().doesFastEntryRendering()) {
                     for (Map.Entry<? extends Class<? extends EntryStack>, List<EntryListEntry>> entry : entries.stream().collect(Collectors.groupingBy(entryListEntry -> entryListEntry.getCurrentEntry().getClass())).entrySet()) {
@@ -398,27 +403,27 @@ public class EntryListWidget extends WidgetWithBounds {
                         EntryStack first = firstWidget.getCurrentEntry();
                         if (first instanceof OptimalEntryStack) {
                             OptimalEntryStack firstStack = (OptimalEntryStack) first;
-                            firstStack.optimisedRenderStart(delta);
+                            firstStack.optimisedRenderStart(matrices, delta);
                             for (EntryListEntry listEntry : list) {
                                 EntryStack currentEntry = listEntry.getCurrentEntry();
                                 currentEntry.setZ(100);
-                                listEntry.drawBackground(mouseX, mouseY, delta);
-                                ((OptimalEntryStack) currentEntry).optimisedRenderBase(listEntry.getInnerBounds(), mouseX, mouseY, delta);
+                                listEntry.drawBackground(matrices, mouseX, mouseY, delta);
+                                ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta);
                             }
                             for (EntryListEntry listEntry : list) {
                                 EntryStack currentEntry = listEntry.getCurrentEntry();
-                                ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(listEntry.getInnerBounds(), mouseX, mouseY, delta);
+                                ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta);
                                 if (listEntry.containsMouse(mouseX, mouseY)) {
-                                    listEntry.queueTooltip(mouseX, mouseY, delta);
-                                    listEntry.drawHighlighted(mouseX, mouseY, delta);
+                                    listEntry.queueTooltip(matrices, mouseX, mouseY, delta);
+                                    listEntry.drawHighlighted(matrices, mouseX, mouseY, delta);
                                 }
                             }
-                            firstStack.optimisedRenderEnd(delta);
+                            firstStack.optimisedRenderEnd(matrices, delta);
                         } else {
                             for (EntryListEntry listEntry : list) {
                                 if (listEntry.getCurrentEntry().isEmpty())
                                     continue;
-                                listEntry.render(mouseX, mouseY, delta);
+                                listEntry.render(matrices, mouseX, mouseY, delta);
                             }
                         }
                     }
@@ -426,13 +431,13 @@ public class EntryListWidget extends WidgetWithBounds {
                     for (EntryListEntry listEntry : entries) {
                         if (listEntry.getCurrentEntry().isEmpty())
                             continue;
-                        listEntry.render(mouseX, mouseY, delta);
+                        listEntry.render(matrices, mouseX, mouseY, delta);
                     }
                 }
             }
         }
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
-            Tooltip.create(I18n.translate("text.rei.delete_items")).queue();
+            Tooltip.create(new TranslatableText("text.rei.delete_items")).queue();
     }
     
     private int getScrollbarMinX() {
@@ -509,7 +514,7 @@ public class EntryListWidget extends WidgetWithBounds {
                 int skippedFavorites = page * (entries.size() - width);
                 int j = 0;
                 if (skippedFavorites < favorites.size()) {
-                    renders.add(Widgets.createLabel(new Point(innerBounds.x + 2, innerBounds.y + 6), I18n.translate("text.rei.favorites")).leftAligned());
+                    renders.add(Widgets.createLabel(new Point(innerBounds.x + 2, innerBounds.y + 6), new TranslatableText("text.rei.favorites")).leftAligned());
                     j += width;
                 }
                 List<EntryStack> subFavoritesList = favorites.stream().skip(skippedFavorites).limit(Math.max(0, entries.size() - width)).collect(Collectors.toList());
@@ -690,8 +695,8 @@ public class EntryListWidget extends WidgetWithBounds {
         }
         
         @Override
-        public void drawBackground(int mouseX, int mouseY, float delta) {
-            super.drawBackground(mouseX, mouseY, delta);
+        public void drawBackground(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            super.drawBackground(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -700,15 +705,15 @@ public class EntryListWidget extends WidgetWithBounds {
         }
         
         @Override
-        public void drawHighlighted(int mouseX, int mouseY, float delta) {
+        public void drawHighlighted(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (getCurrentEntry().getType() != EntryStack.Type.EMPTY)
-                super.drawHighlighted(mouseX, mouseY, delta);
+                super.drawHighlighted(matrices, mouseX, mouseY, delta);
         }
         
         @Override
-        public void queueTooltip(int mouseX, int mouseY, float delta) {
+        public void queueTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (!ClientHelper.getInstance().isCheating() || minecraft.player.inventory.getCursorStack().isEmpty()) {
-                super.queueTooltip(mouseX, mouseY, delta);
+                super.queueTooltip(matrices, mouseX, mouseY, delta);
             }
         }
         

+ 25 - 16
src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java

@@ -37,14 +37,21 @@ import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 public class EntryWidget extends Slot {
     
@@ -271,16 +278,16 @@ public class EntryWidget extends Slot {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
-        drawBackground(mouseX, mouseY, delta);
-        drawCurrentEntry(mouseX, mouseY, delta);
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        drawBackground(matrices, mouseX, mouseY, delta);
+        drawCurrentEntry(matrices, mouseX, mouseY, delta);
         
         boolean highlighted = containsMouse(mouseX, mouseY);
         if (hasTooltips() && highlighted) {
-            queueTooltip(mouseX, mouseY, delta);
+            queueTooltip(matrices, mouseX, mouseY, delta);
         }
         if (hasHighlight() && highlighted) {
-            drawHighlighted(mouseX, mouseY, delta);
+            drawHighlighted(matrices, mouseX, mouseY, delta);
         }
     }
     
@@ -292,28 +299,30 @@ public class EntryWidget extends Slot {
         return highlight;
     }
     
-    protected void drawBackground(int mouseX, int mouseY, float delta) {
+    protected void drawBackground(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (background) {
             minecraft.getTextureManager().bindTexture(REIHelper.getInstance().isDarkThemeEnabled() ? RECIPE_GUI_DARK : RECIPE_GUI);
-            drawTexture(bounds.x, bounds.y, 0, 222, bounds.width, bounds.height);
+            drawTexture(matrices, bounds.x, bounds.y, 0, 222, bounds.width, bounds.height);
         }
     }
     
-    protected void drawCurrentEntry(int mouseX, int mouseY, float delta) {
+    protected void drawCurrentEntry(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         EntryStack entry = getCurrentEntry();
         entry.setZ(100);
-        entry.render(getInnerBounds(), mouseX, mouseY, delta);
+        entry.render(matrices, getInnerBounds(), mouseX, mouseY, delta);
     }
     
-    protected void queueTooltip(int mouseX, int mouseY, float delta) {
+    protected void queueTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY));
         if (tooltip != null) {
             if (interactableFavorites && ConfigObject.getInstance().doDisplayFavoritesTooltip() && !ConfigObject.getInstance().getFavoriteKeyCode().isUnknown()) {
-                String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName();
+                String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName().getString();
                 if (reverseFavoritesAction())
-                    tooltip.getText().addAll(Arrays.asList(I18n.translate("text.rei.remove_favorites_tooltip", name).split("\n")));
+                    tooltip.getText().addAll(Stream.of(I18n.translate("text.rei.remove_favorites_tooltip", name).split("\n"))
+                            .map(LiteralText::new).collect(Collectors.toList()));
                 else
-                    tooltip.getText().addAll(Arrays.asList(I18n.translate("text.rei.favorites_tooltip", name).split("\n")));
+                    tooltip.getText().addAll(Stream.of(I18n.translate("text.rei.favorites_tooltip", name).split("\n"))
+                            .map(LiteralText::new).collect(Collectors.toList()));
             }
             tooltip.queue();
         }
@@ -324,13 +333,13 @@ public class EntryWidget extends Slot {
         return getCurrentEntry().getTooltip(point);
     }
     
-    protected void drawHighlighted(int mouseX, int mouseY, float delta) {
+    protected void drawHighlighted(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         RenderSystem.disableDepthTest();
         RenderSystem.colorMask(true, true, true, false);
         int color = REIHelper.getInstance().isDarkThemeEnabled() ? -1877929711 : -2130706433;
         setZ(300);
         Rectangle bounds = getInnerBounds();
-        fillGradient(bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), color, color);
+        fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), color, color);
         setZ(0);
         RenderSystem.colorMask(true, true, true, true);
         RenderSystem.enableDepthTest();

+ 9 - 8
src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java

@@ -39,7 +39,8 @@ import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -99,7 +100,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (bounds.isEmpty())
             return;
         for (EntryListEntry entry : entries)
@@ -119,7 +120,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
                     break back;
                 if (notSteppingOnExclusionZones(entry.getBounds().x, entry.getBounds().y, innerBounds)) {
                     entry.entry(stack);
-                    entry.render(mouseX, mouseY, delta);
+                    entry.render(matrices, mouseX, mouseY, delta);
                     nextIndex++;
                     break;
                 } else {
@@ -132,7 +133,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
         scrolling.renderScrollBar();
         ScissorsHandler.INSTANCE.removeLastScissor();
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
-            Tooltip.create(I18n.translate("text.rei.delete_items")).queue();
+            Tooltip.create(new TranslatableText("text.rei.delete_items")).queue();
     }
     
     @Override
@@ -271,9 +272,9 @@ public class FavoritesListWidget extends WidgetWithBounds {
         }
         
         @Override
-        protected void drawHighlighted(int mouseX, int mouseY, float delta) {
+        protected void drawHighlighted(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (!getCurrentEntry().isEmpty())
-                super.drawHighlighted(mouseX, mouseY, delta);
+                super.drawHighlighted(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -282,9 +283,9 @@ public class FavoritesListWidget extends WidgetWithBounds {
         }
         
         @Override
-        public void queueTooltip(int mouseX, int mouseY, float delta) {
+        public void queueTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (!ClientHelper.getInstance().isCheating() || minecraft.player.inventory.getCursorStack().isEmpty()) {
-                super.queueTooltip(mouseX, mouseY, delta);
+                super.queueTooltip(matrices, mouseX, mouseY, delta);
             }
         }
         

+ 19 - 14
src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java

@@ -29,6 +29,9 @@ import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -37,6 +40,8 @@ import java.util.List;
 import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @see Widgets#createLabel(Point, String)
@@ -47,26 +52,26 @@ import java.util.function.Supplier;
 public class LabelWidget extends WidgetWithBounds {
     
     private Point pos;
-    private String text;
+    protected Text text;
     private int defaultColor;
     private boolean hasShadows = true;
     private boolean centered = true;
     private Supplier<String> tooltipSupplier;
     
     @ApiStatus.Internal
-    public LabelWidget(Point point, String text) {
+    public LabelWidget(Point point, Text text) {
         this.pos = point;
         this.text = text;
         this.defaultColor = REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : -1;
     }
     
     public static LabelWidget create(Point point, String text) {
-        return new LabelWidget(point, text);
+        return new LabelWidget(point, new LiteralText(text));
     }
     
     public static ClickableLabelWidget createClickable(Point point, String text, Consumer<ClickableLabelWidget> onClicked) {
         ClickableLabelWidget[] widget = {null};
-        widget[0] = new ClickableLabelWidget(point, text) {
+        widget[0] = new ClickableLabelWidget(point, new LiteralText(text)) {
             @Override
             public void onLabelClicked() {
                 onClicked.accept(widget[0]);
@@ -132,11 +137,11 @@ public class LabelWidget extends WidgetWithBounds {
     }
     
     public String getText() {
-        return text;
+        return text.getString();
     }
     
     public LabelWidget setText(String text) {
-        this.text = text;
+        this.text = new LiteralText(text);
         return this;
     }
     
@@ -152,7 +157,7 @@ public class LabelWidget extends WidgetWithBounds {
     @NotNull
     @Override
     public Rectangle getBounds() {
-        int width = font.getStringWidth(text);
+        int width = font.method_27525(text);
         Point pos = getLocation();
         if (isCentered())
             return new Rectangle(pos.x - width / 2 - 1, pos.y - 5, width + 2, 14);
@@ -165,25 +170,25 @@ public class LabelWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
-        int width = font.getStringWidth(text);
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        int width = font.method_27525(text);
         Point pos = getLocation();
         if (isCentered()) {
             if (hasShadows)
-                font.drawWithShadow(text, pos.x - width / 2f, pos.y, defaultColor);
+                font.method_27517(matrices, text, pos.x - width / 2f, pos.y, defaultColor);
             else
-                font.draw(text, pos.x - width / 2f, pos.y, defaultColor);
+                font.method_27528(matrices, text, pos.x - width / 2f, pos.y, defaultColor);
         } else {
             if (hasShadows)
-                font.drawWithShadow(text, pos.x, pos.y, defaultColor);
+                font.method_27517(matrices, text, pos.x, pos.y, defaultColor);
             else
-                font.draw(text, pos.x, pos.y, defaultColor);
+                font.method_27528(matrices, text, pos.x, pos.y, defaultColor);
         }
     }
     
     protected void drawTooltips(int mouseX, int mouseY) {
         if (getTooltips().isPresent())
             if (containsMouse(mouseX, mouseY))
-                Tooltip.create(getTooltips().get().split("\n")).queue();
+                Tooltip.create(Stream.of(getTooltips().get().split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
     }
 }

+ 12 - 11
src/main/java/me/shedaniel/rei/gui/widget/PanelWidget.java

@@ -29,6 +29,7 @@ import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.gui.config.RecipeBorderType;
 import me.shedaniel.rei.gui.config.RecipeScreenType;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -75,7 +76,7 @@ public class PanelWidget extends WidgetWithBounds {
     }
     
     public void render() {
-        render(0, 0, 0);
+        render(new MatrixStack(), 0, 0, 0);
     }
     
     public int getColor() {
@@ -87,7 +88,7 @@ public class PanelWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (!isRendering())
             return;
         float alpha = ((color >> 24) & 0xFF) / 255f;
@@ -101,23 +102,23 @@ public class PanelWidget extends WidgetWithBounds {
         int yTextureOffset = getYTextureOffset();
         
         //Four Corners
-        this.drawTexture(x, y, 106 + xTextureOffset, 124 + yTextureOffset, 4, 4);
-        this.drawTexture(x + width - 4, y, 252 + xTextureOffset, 124 + yTextureOffset, 4, 4);
-        this.drawTexture(x, y + height - 4, 106 + xTextureOffset, 186 + yTextureOffset, 4, 4);
-        this.drawTexture(x + width - 4, y + height - 4, 252 + xTextureOffset, 186 + yTextureOffset, 4, 4);
+        this.drawTexture(matrices, x, y, 106 + xTextureOffset, 124 + yTextureOffset, 4, 4);
+        this.drawTexture(matrices, x + width - 4, y, 252 + xTextureOffset, 124 + yTextureOffset, 4, 4);
+        this.drawTexture(matrices, x, y + height - 4, 106 + xTextureOffset, 186 + yTextureOffset, 4, 4);
+        this.drawTexture(matrices, x + width - 4, y + height - 4, 252 + xTextureOffset, 186 + yTextureOffset, 4, 4);
         
         //Sides
         for (int xx = 4; xx < width - 4; xx += 128) {
             int thisWidth = Math.min(128, width - 4 - xx);
-            this.drawTexture(x + xx, y, 110 + xTextureOffset, 124 + yTextureOffset, thisWidth, 4);
-            this.drawTexture(x + xx, y + height - 4, 110 + xTextureOffset, 186 + yTextureOffset, thisWidth, 4);
+            this.drawTexture(matrices, x + xx, y, 110 + xTextureOffset, 124 + yTextureOffset, thisWidth, 4);
+            this.drawTexture(matrices, x + xx, y + height - 4, 110 + xTextureOffset, 186 + yTextureOffset, thisWidth, 4);
         }
         for (int yy = 4; yy < height - 4; yy += 50) {
             int thisHeight = Math.min(50, height - 4 - yy);
-            this.drawTexture(x, y + yy, 106 + xTextureOffset, 128 + yTextureOffset, 4, thisHeight);
-            this.drawTexture(x + width - 4, y + yy, 252 + xTextureOffset, 128 + yTextureOffset, 4, thisHeight);
+            this.drawTexture(matrices, x, y + yy, 106 + xTextureOffset, 128 + yTextureOffset, 4, thisHeight);
+            this.drawTexture(matrices, x + width - 4, y + yy, 252 + xTextureOffset, 128 + yTextureOffset, 4, thisHeight);
         }
-        fillGradient(x + 4, y + 4, x + width - 4, y + height - 4, getInnerColor(), getInnerColor());
+        fillGradient(matrices, x + 4, y + 4, x + width - 4, y + height - 4, getInnerColor(), getInnerColor());
     }
     
     protected boolean isRendering() {

+ 10 - 9
src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java

@@ -28,6 +28,7 @@ import com.google.common.collect.Lists;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.widgets.Tooltip;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -43,40 +44,40 @@ import java.util.List;
 public class QueuedTooltip implements Tooltip {
     
     private Point location;
-    private List<String> text;
+    private List<Text> text;
     
-    private QueuedTooltip(Point location, Collection<String> text) {
+    private QueuedTooltip(Point location, Collection<Text> text) {
         this.location = location;
         this.text = Lists.newArrayList(text);
     }
     
     @NotNull
-    public static QueuedTooltip create(Point location, List<String> text) {
+    public static QueuedTooltip create(Point location, List<Text> text) {
         return new QueuedTooltip(location, text);
     }
     
     @NotNull
-    public static QueuedTooltip create(Point location, Collection<String> text) {
+    public static QueuedTooltip create(Point location, Collection<Text> text) {
         return new QueuedTooltip(location, text);
     }
     
     @NotNull
-    public static QueuedTooltip create(Point location, String... text) {
+    public static QueuedTooltip create(Point location, Text... text) {
         return QueuedTooltip.create(location, Lists.newArrayList(text));
     }
     
     @NotNull
-    public static QueuedTooltip create(List<String> text) {
+    public static QueuedTooltip create(List<Text> text) {
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     
     @NotNull
-    public static QueuedTooltip create(Collection<String> text) {
+    public static QueuedTooltip create(Collection<Text> text) {
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     
     @NotNull
-    public static QueuedTooltip create(String... text) {
+    public static QueuedTooltip create(Text... text) {
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     
@@ -91,7 +92,7 @@ public class QueuedTooltip implements Tooltip {
     }
     
     @Override
-    public List<String> getText() {
+    public List<Text> getText() {
         return text;
     }
     

+ 4 - 3
src/main/java/me/shedaniel/rei/gui/widget/RecipeArrowWidget.java

@@ -28,6 +28,7 @@ import me.shedaniel.math.Rectangle;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -69,12 +70,12 @@ public class RecipeArrowWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
-        drawTexture(x, y, 106, 91, 24, 17);
+        drawTexture(matrices, x, y, 106, 91, 24, 17);
         if (animated) {
             int width = MathHelper.ceil((System.currentTimeMillis() / (time / 24) % 24d) / 1f);
-            drawTexture(x, y, 82, 91, width, 17);
+            drawTexture(matrices, x, y, 82, 91, width, 17);
         }
     }
     

+ 9 - 9
src/main/java/me/shedaniel/rei/gui/widget/RecipeChoosePageWidget.java

@@ -24,7 +24,6 @@
 package me.shedaniel.rei.gui.widget;
 
 import com.google.common.collect.Lists;
-import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
@@ -33,8 +32,8 @@ import me.shedaniel.rei.api.widgets.Panel;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
@@ -116,11 +115,11 @@ public class RecipeChoosePageWidget extends DraggableWidget {
             }
             
             @Override
-            public void render(int i, int i1, float v) {
-                font.draw(I18n.translate("text.rei.choose_page"), bounds.x + 5, bounds.y + 5, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF404040);
+            public void render(MatrixStack matrices, int i, int i1, float v) {
+                font.method_27528(matrices, new TranslatableText("text.rei.choose_page"), bounds.x + 5, bounds.y + 5, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF404040);
                 String endString = String.format(" /%d", maxPage);
                 int width = font.getStringWidth(endString);
-                font.draw(endString, bounds.x + bounds.width - 5 - width, bounds.y + 22, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF404040);
+                font.draw(matrices, endString, bounds.x + bounds.width - 5 - width, bounds.y + 22, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF404040);
             }
         });
         String endString = String.format(" /%d", maxPage);
@@ -160,12 +159,13 @@ public class RecipeChoosePageWidget extends DraggableWidget {
     }
     
     @Override
-    public void render(int i, int i1, float v) {
-        RenderSystem.translatef(0, 0, 800);
+    public void render(MatrixStack matrices, int i, int i1, float v) {
+        matrices.push();
+        matrices.translate(0, 0, 800);
         for (Widget widget : widgets) {
-            widget.render(i, i1, v);
+            widget.render(matrices, i, i1, v);
         }
-        RenderSystem.translatef(0, 0, -800);
+        matrices.pop();
     }
     
     @Override

+ 7 - 5
src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java

@@ -29,6 +29,8 @@ import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.widgets.Tooltip;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
@@ -104,12 +106,12 @@ public class TabWidget extends WidgetWithBounds {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (shown) {
             minecraft.getTextureManager().bindTexture(REIHelper.getInstance().isDarkThemeEnabled() ? CHEST_GUI_TEXTURE_DARK : CHEST_GUI_TEXTURE);
-            this.drawTexture(bounds.x, bounds.y + 2, u + (selected ? bounds.width : 0), v, bounds.width, (selected ? bounds.height + 2 : bounds.height - 1));
+            this.drawTexture(matrices, bounds.x, bounds.y + 2, u + (selected ? bounds.width : 0), v, bounds.width, (selected ? bounds.height + 2 : bounds.height - 1));
             logo.setZ(100);
-            logo.render(new Rectangle(bounds.getCenterX() - 8, bounds.getCenterY() - 5, 16, 16), mouseX, mouseY, delta);
+            logo.render(matrices, new Rectangle(bounds.getCenterX() - 8, bounds.getCenterY() - 5, 16, 16), mouseX, mouseY, delta);
             if (containsMouse(mouseX, mouseY)) {
                 drawTooltip();
             }
@@ -118,9 +120,9 @@ public class TabWidget extends WidgetWithBounds {
     
     private void drawTooltip() {
         if (this.minecraft.options.advancedItemTooltips)
-            Tooltip.create(categoryName, Formatting.DARK_GRAY.toString() + category.getIdentifier().toString(), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
+            Tooltip.create(new LiteralText(categoryName), new LiteralText(category.getIdentifier().toString()).method_27692(Formatting.DARK_GRAY), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
         else
-            Tooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
+            Tooltip.create(new LiteralText(categoryName), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
     }
     
     @NotNull

+ 30 - 30
src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java

@@ -32,8 +32,10 @@ import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Tickable;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Matrix4f;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -385,6 +387,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
         return Collections.emptyList();
     }
     
+    @Override
     public boolean mouseClicked(double double_1, double double_2, int int_1) {
         if (!this.isVisible()) {
             return false;
@@ -400,8 +403,8 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
                     int_2 -= 4;
                 }
                 
-                String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), this.getWidth());
-                this.moveCursorTo(this.font.trimToWidth(string_1, int_2).length() + this.field_2103, true);
+                String string_1 = this.font.method_27523(this.text.substring(this.field_2103), this.getWidth());
+                this.moveCursorTo(this.font.method_27523(string_1, int_2).length() + this.field_2103, true);
                 return true;
             } else {
                 return false;
@@ -409,24 +412,25 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
         }
     }
     
-    public void renderBorder() {
+    public void renderBorder(MatrixStack matrices) {
         if (this.hasBorder()) {
             if (containsMouse(PointHelper.ofMouse()) || focused)
-                fill(this.bounds.x - 1, this.bounds.y - 1, this.bounds.x + this.bounds.width + 1, this.bounds.y + this.bounds.height + 1, REIHelper.getInstance().isDarkThemeEnabled() ? -17587 : -1);
+                fill(matrices, this.bounds.x - 1, this.bounds.y - 1, this.bounds.x + this.bounds.width + 1, this.bounds.y + this.bounds.height + 1, REIHelper.getInstance().isDarkThemeEnabled() ? -17587 : -1);
             else
-                fill(this.bounds.x - 1, this.bounds.y - 1, this.bounds.x + this.bounds.width + 1, this.bounds.y + this.bounds.height + 1, -6250336);
-            fill(this.bounds.x, this.bounds.y, this.bounds.x + this.bounds.width, this.bounds.y + this.bounds.height, -16777216);
+                fill(matrices, this.bounds.x - 1, this.bounds.y - 1, this.bounds.x + this.bounds.width + 1, this.bounds.y + this.bounds.height + 1, -6250336);
+            fill(matrices, this.bounds.x, this.bounds.y, this.bounds.x + this.bounds.width, this.bounds.y + this.bounds.height, -16777216);
         }
     }
     
-    public void render(int mouseX, int mouseY, float delta) {
+    @Override
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (this.isVisible()) {
-            renderBorder();
+            renderBorder(matrices);
             
             int color = this.editable ? this.editableColor : this.notEditableColor;
             int int_4 = this.cursorMax - this.field_2103;
             int int_5 = this.cursorMin - this.field_2103;
-            String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), this.getWidth());
+            String string_1 = this.font.method_27523(this.text.substring(this.field_2103), this.getWidth());
             boolean boolean_1 = int_4 >= 0 && int_4 <= string_1.length();
             boolean boolean_2 = this.focused && this.focusedTicks / 6 % 2 == 0 && boolean_1;
             int x = this.hasBorder ? this.bounds.x + 4 : this.bounds.x;
@@ -438,7 +442,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
             
             if (!string_1.isEmpty()) {
                 String string_2 = boolean_1 ? string_1.substring(0, int_4) : string_1;
-                int_8 = this.font.drawWithShadow(this.renderTextProvider.apply(string_2, this.field_2103), (float) x, (float) y, color);
+                int_8 = this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_2, this.field_2103), (float) x, (float) y, color);
             }
             
             boolean isCursorInsideText = this.cursorMax < this.text.length() || this.text.length() >= this.getMaxLength();
@@ -451,37 +455,31 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
             int_9--;
             
             if (!string_1.isEmpty() && boolean_1 && int_4 < string_1.length()) {
-                this.font.drawWithShadow(this.renderTextProvider.apply(string_1.substring(int_4), this.cursorMax), (float) int_8, (float) y, color);
+                this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_1.substring(int_4), this.cursorMax), (float) int_8, (float) y, color);
             }
             
             if (!isCursorInsideText && text.isEmpty() && this.suggestion != null) {
-                renderSuggestion(x, y);
+                renderSuggestion(matrices, x, y);
             }
             
             if (boolean_2) {
-                //                if (isCursorInsideText) {
-                fill(int_9 + 1, y, int_9 + 2, y + 9, ((0xFF) << 24) | ((((color >> 16 & 255) / 4) & 0xFF) << 16) | ((((color >> 8 & 255) / 4) & 0xFF) << 8) | ((((color & 255) / 4) & 0xFF)));
-                //                fill(int_9, y, int_9 + 1, y + 9, 0xff343434);
-                fill(int_9, y - 1, int_9 + 1, y + 8, ((0xFF) << 24) | color);
-                //                fill(int_9 - 1, y - 1, int_9, y + 8, 0xffd0d0d0);
-                //                } else {
-                //                                    this.font.drawWithShadow("|", (float) int_9 - 2, (float) y, 0xffd0d0d0);
-                //                }
+                fill(matrices, int_9 + 1, y, int_9 + 2, y + 9, ((0xFF) << 24) | ((((color >> 16 & 255) / 4) & 0xFF) << 16) | ((((color >> 8 & 255) / 4) & 0xFF) << 8) | ((((color & 255) / 4) & 0xFF)));
+                fill(matrices, int_9, y - 1, int_9 + 1, y + 8, ((0xFF) << 24) | color);
             }
             
             // Render selection overlay
             if (int_5 != int_4) {
                 int int_10 = x + this.font.getStringWidth(string_1.substring(0, int_5));
-                this.method_1886(int_9, y - 1, int_10 - 1, y + 9, color);
+                this.renderSelection(matrices, int_9, y - 1, int_10 - 1, y + 9, color);
             }
         }
     }
     
-    protected void renderSuggestion(int x, int y) {
-        this.font.drawWithShadow(this.font.trimToWidth(this.suggestion, this.getWidth()), x, y, -8355712);
+    protected void renderSuggestion(MatrixStack matrices, int x, int y) {
+        this.font.drawWithShadow(matrices, this.font.method_27523(this.suggestion, this.getWidth()), x, y, -8355712);
     }
     
-    protected void method_1886(int x1, int y1, int x2, int y2, int color) {
+    protected void renderSelection(MatrixStack matrices, int x1, int y1, int x2, int y2, int color) {
         int tmp;
         if (x1 < x2) {
             tmp = x1;
@@ -513,11 +511,12 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
         RenderSystem.disableAlphaTest();
         RenderSystem.blendFuncSeparate(770, 771, 1, 0);
         RenderSystem.shadeModel(7425);
+        Matrix4f matrix = matrices.peek().getModel();
         buffer.begin(7, VertexFormats.POSITION_COLOR);
-        buffer.vertex(x1, y2, getZOffset() + 50d).color(r, g, b, 120).next();
-        buffer.vertex(x2, y2, getZOffset() + 50d).color(r, g, b, 120).next();
-        buffer.vertex(x2, y1, getZOffset() + 50d).color(r, g, b, 120).next();
-        buffer.vertex(x1, y1, getZOffset() + 50d).color(r, g, b, 120).next();
+        buffer.vertex(matrix, x1, y2, getZOffset() + 50f).color(r, g, b, 120).next();
+        buffer.vertex(matrix, x2, y2, getZOffset() + 50f).color(r, g, b, 120).next();
+        buffer.vertex(matrix, x2, y1, getZOffset() + 50f).color(r, g, b, 120).next();
+        buffer.vertex(matrix, x1, y1, getZOffset() + 50f).color(r, g, b, 120).next();
         tessellator.draw();
         RenderSystem.shadeModel(7424);
         RenderSystem.disableBlend();
@@ -561,6 +560,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
         this.notEditableColor = int_1;
     }
     
+    @Override
     public boolean changeFocus(boolean boolean_1) {
         if (this.visible && this.editable) {
             this.setFocused(!this.focused);
@@ -596,10 +596,10 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable {
             }
             
             int int_3 = this.getWidth();
-            String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), int_3);
+            String string_1 = this.font.method_27523(this.text.substring(this.field_2103), int_3);
             int int_4 = string_1.length() + this.field_2103;
             if (this.cursorMin == this.field_2103) {
-                this.field_2103 -= this.font.trimToWidth(this.text, int_3, true).length();
+                this.field_2103 -= this.font.method_27524(this.text, int_3, true).length();
             }
             
             if (this.cursorMin > int_4) {

+ 9 - 6
src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java

@@ -48,10 +48,13 @@ import net.fabricmc.loader.api.metadata.ModMetadata;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
 import net.minecraft.network.PacketByteBuf;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
@@ -99,19 +102,19 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
     }
     
     @Override
-    public String getFormattedModFromItem(Item item) {
+    public Text getFormattedModFromItem(Item item) {
         String mod = getModFromItem(item);
         if (mod.isEmpty())
-            return "";
-        return Formatting.BLUE.toString() + Formatting.ITALIC.toString() + mod;
+            return NarratorManager.EMPTY;
+        return new LiteralText(mod).method_27695(Formatting.BLUE, Formatting.ITALIC);
     }
     
     @Override
-    public String getFormattedModFromIdentifier(Identifier identifier) {
+    public Text getFormattedModFromIdentifier(Identifier identifier) {
         String mod = getModFromIdentifier(identifier);
         if (mod.isEmpty())
-            return "";
-        return Formatting.BLUE.toString() + Formatting.ITALIC.toString() + mod;
+            return NarratorManager.EMPTY;
+        return new LiteralText(mod).method_27695(Formatting.BLUE, Formatting.ITALIC);
     }
     
     @Override

+ 16 - 14
src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java

@@ -58,9 +58,11 @@ import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.widget.AbstractButtonWidget;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
 import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.InputUtil;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -100,19 +102,19 @@ public class ConfigManagerImpl implements ConfigManager {
         guiRegistry.registerPredicateProvider((i13n, field, config, defaults, guiProvider) -> {
             if (field.isAnnotationPresent(ConfigEntry.Gui.Excluded.class))
                 return Collections.emptyList();
-            KeyCodeEntry entry = ConfigEntryBuilder.create().startModifierKeyCodeField(i13n, getUnsafely(field, config, ModifierKeyCode.unknown())).setModifierDefaultValue(() -> getUnsafely(field, defaults)).setModifierSaveConsumer(newValue -> setUnsafely(field, config, newValue)).build();
+            KeyCodeEntry entry = ConfigEntryBuilder.create().startModifierKeyCodeField(new TranslatableText(i13n), getUnsafely(field, config, ModifierKeyCode.unknown())).setModifierDefaultValue(() -> getUnsafely(field, defaults)).setModifierSaveConsumer(newValue -> setUnsafely(field, config, newValue)).build();
             entry.setAllowMouse(false);
             return Collections.singletonList(entry);
         }, field -> field.getType() == ModifierKeyCode.class);
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> {
             ConfigObjectImpl.UsePercentage bounds = field.getAnnotation(ConfigObjectImpl.UsePercentage.class);
-            return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(i13n, MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> {
+            return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(new TranslatableText(i13n), MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> {
                 Utils.setUnsafely(field, config, newValue / 100d);
-            }).setTextGetter(integer -> String.format("Size: %d%%", integer)).build());
+            }).setTextGetter(integer -> new LiteralText(String.format("Size: %d%%", integer))).build());
         }, (field) -> field.getType() == Double.TYPE || field.getType() == Double.class, ConfigObjectImpl.UsePercentage.class);
         
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
-                        Collections.singletonList(new RecipeScreenTypeEntry(220, i13n, getUnsafely(field, config, RecipeScreenType.UNSET), getUnsafely(field, defaults), type -> setUnsafely(field, config, type)))
+                        Collections.singletonList(new RecipeScreenTypeEntry(220, new TranslatableText(i13n), getUnsafely(field, config, RecipeScreenType.UNSET), getUnsafely(field, defaults), type -> setUnsafely(field, config, type)))
                 , (field) -> field.getType() == RecipeScreenType.class, ConfigObjectImpl.UseSpecialRecipeTypeScreen.class);
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
                         REIHelper.getInstance().getPreviousHandledScreen() == null || MinecraftClient.getInstance().getNetworkHandler() == null || MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() == null ?
@@ -160,11 +162,11 @@ public class ConfigManagerImpl implements ConfigManager {
             provider.setOptionFunction((baseI13n, field) -> field.isAnnotationPresent(ConfigObjectImpl.DontApplyFieldName.class) ? baseI13n : String.format("%s.%s", baseI13n, field.getName()));
             provider.setCategoryFunction((baseI13n, categoryName) -> String.format("%s.%s", baseI13n, categoryName));
             provider.setBuildFunction(builder -> {
-                builder.getOrCreateCategory("config.roughlyenoughitems.!general").addEntry(new TooltipListEntry<Object>(I18n.translate("config.roughlyenoughitems.smooth_scrolling"), null) {
+                builder.getOrCreateCategory(new TranslatableText("config.roughlyenoughitems.!general")).addEntry(new TooltipListEntry<Object>(new TranslatableText("config.roughlyenoughitems.smooth_scrolling"), null) {
                     int width = 220;
                     private AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, this.getFieldName()) {
                         public void onPress() {
-                            Screen screen = ClothConfigInitializer.getConfigBuilder().setTitle("Smooth Scrolling Settings").build();
+                            Screen screen = ClothConfigInitializer.getConfigBuilder().setTitle(new LiteralText("Smooth Scrolling Settings")).build();
                             MinecraftClient.getInstance().openScreen(screen);
                         }
                     };
@@ -185,31 +187,31 @@ public class ConfigManagerImpl implements ConfigManager {
                         return this.children;
                     }
                     
-                    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-                        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+                    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+                        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
                         Window window = MinecraftClient.getInstance().getWindow();
                         this.buttonWidget.active = this.isEditable();
                         this.buttonWidget.y = y;
                         this.buttonWidget.x = x + entryWidth / 2 - this.width / 2;
                         this.buttonWidget.setWidth(this.width);
-                        this.buttonWidget.render(mouseX, mouseY, delta);
+                        this.buttonWidget.render(matrices, mouseX, mouseY, delta);
                     }
                 });
                 return builder.setAfterInitConsumer(screen -> {
                     if (MinecraftClient.getInstance().getNetworkHandler() != null && MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() != null) {
-                        ((ScreenHooks) screen).cloth_addButton(new net.minecraft.client.gui.widget.ButtonWidget(4, 4, 100, 20, I18n.translate("text.rei.reload_config"), buttonWidget -> {
+                        ((ScreenHooks) screen).cloth_addButton(new net.minecraft.client.gui.widget.ButtonWidget(4, 4, 100, 20, new TranslatableText("text.rei.reload_config"), buttonWidget -> {
                             RoughlyEnoughItemsCore.syncRecipes(null);
                         }) {
                             @Override
-                            public void render(int int_1, int int_2, float float_1) {
+                            public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                                 if (RecipeHelper.getInstance().arePluginsLoading()) {
                                     MinecraftClient.getInstance().openScreen(new ConfigReloadingScreen(MinecraftClient.getInstance().currentScreen));
                                 } else
-                                    super.render(int_1, int_2, float_1);
+                                    super.render(matrices, mouseX, mouseY, delta);
                             }
                         });
                     }
-                    ((ScreenHooks) screen).cloth_addButton(new ButtonWidget(screen.width - 104, 4, 100, 20, I18n.translate("text.rei.credits"), button -> {
+                    ((ScreenHooks) screen).cloth_addButton(new ButtonWidget(screen.width - 104, 4, 100, 20, new TranslatableText("text.rei.credits"), button -> {
                         MinecraftClient.getInstance().openScreen(new CreditsScreen(screen));
                     }));
                 }).setSavingRunnable(() -> {

+ 5 - 4
src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java

@@ -27,6 +27,7 @@ import me.shedaniel.math.Point;
 import me.shedaniel.math.Rectangle;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.widgets.Tooltip;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
@@ -63,7 +64,7 @@ public class EmptyEntryStack implements EntryStack {
     
     @Override
     public void setFloatingAmount(double amount) {
-    
+        
     }
     
     @Override
@@ -113,7 +114,7 @@ public class EmptyEntryStack implements EntryStack {
     
     @Override
     public void setZ(int z) {
-    
+        
     }
     
     @Override
@@ -142,8 +143,8 @@ public class EmptyEntryStack implements EntryStack {
     }
     
     @Override
-    public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
-    
+    public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
+        
     }
     
     @Override

+ 1 - 1
src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java

@@ -163,7 +163,7 @@ public class EntryRegistryImpl implements EntryRegistry {
         if (afterStack != null) {
             int index = getStacksList().size();
             for (int i = index - 1; i >= 0; i--) {
-                if (getStacksList().get(i).equalsAll(afterStack)) {
+                if (getStacksList().get(i).equalsIgnoreAmount(afterStack)) {
                     index = i + 1;
                     break;
                 }

+ 24 - 12
src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java

@@ -38,16 +38,25 @@ import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.texture.Sprite;
 import net.minecraft.client.texture.SpriteAtlasTexture;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.fluid.Fluids;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Matrix4f;
 import net.minecraft.util.registry.Registry;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @ApiStatus.Internal
 public class FluidEntryStack extends AbstractEntryStack {
@@ -103,7 +112,7 @@ public class FluidEntryStack extends AbstractEntryStack {
     
     @Override
     public void setFloatingAmount(double amount) {
-        this.amount = amount == IGNORE_AMOUNT ? IGNORE_AMOUNT :  Math.max(amount, 0);
+        this.amount = amount == IGNORE_AMOUNT ? IGNORE_AMOUNT : Math.max(amount, 0);
         if (isEmpty()) {
             fluid = Fluids.EMPTY;
         }
@@ -194,18 +203,20 @@ public class FluidEntryStack extends AbstractEntryStack {
     public Tooltip getTooltip(Point point) {
         if (!get(Settings.TOOLTIP_ENABLED).get() || isEmpty())
             return null;
-        List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetEntryStackName(this));
+        List<Text> toolTip = Lists.newArrayList(new LiteralText(SearchArgument.tryGetEntryStackName(this)));
         if (amount >= 0) {
             String amountTooltip = get(Settings.Fluid.AMOUNT_TOOLTIP).apply(this);
             if (amountTooltip != null)
-                toolTip.addAll(Arrays.asList(amountTooltip.split("\n")));
+                toolTip.addAll(Stream.of(amountTooltip.split("\n")).map(LiteralText::new).collect(Collectors.toList()));
         }
         toolTip.addAll(get(Settings.TOOLTIP_APPEND_EXTRA).apply(this));
         if (get(Settings.TOOLTIP_APPEND_MOD).get() && ConfigObject.getInstance().shouldAppendModNames()) {
-            final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));
+            Identifier id = Registry.FLUID.getId(fluid);
+            final Text modString = ClientHelper.getInstance().getFormattedModFromIdentifier(id);
+            final String modId = ClientHelper.getInstance().getModFromIdentifier(id);
             boolean alreadyHasMod = false;
-            for (String s : toolTip)
-                if (s.equalsIgnoreCase(modString)) {
+            for (Text s : toolTip)
+                if (s.asString().equalsIgnoreCase(modId)) {
                     alreadyHasMod = true;
                     break;
                 }
@@ -217,7 +228,7 @@ public class FluidEntryStack extends AbstractEntryStack {
     
     @SuppressWarnings("deprecation")
     @Override
-    public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
         if (get(Settings.RENDER).get()) {
             Pair<Sprite, Integer> pair = getOrLoadSprite(getFluid());
             if (pair != null) {
@@ -230,11 +241,12 @@ public class FluidEntryStack extends AbstractEntryStack {
                 MinecraftClient.getInstance().getTextureManager().bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX);
                 Tessellator tess = Tessellator.getInstance();
                 BufferBuilder bb = tess.getBuffer();
+                Matrix4f matrix = matrices.peek().getModel();
                 bb.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-                bb.vertex(bounds.getMaxX(), bounds.y, getZ()).texture(sprite.getMaxU(), sprite.getMinV()).color(r, g, b, a).next();
-                bb.vertex(bounds.x, bounds.y, getZ()).texture(sprite.getMinU(), sprite.getMinV()).color(r, g, b, a).next();
-                bb.vertex(bounds.x, bounds.getMaxY(), getZ()).texture(sprite.getMinU(), sprite.getMaxV()).color(r, g, b, a).next();
-                bb.vertex(bounds.getMaxX(), bounds.getMaxY(), getZ()).texture(sprite.getMaxU(), sprite.getMaxV()).color(r, g, b, a).next();
+                bb.vertex(matrix, bounds.getMaxX(), bounds.y, getZ()).texture(sprite.getMaxU(), sprite.getMinV()).color(r, g, b, a).next();
+                bb.vertex(matrix, bounds.x, bounds.y, getZ()).texture(sprite.getMinU(), sprite.getMinV()).color(r, g, b, a).next();
+                bb.vertex(matrix, bounds.x, bounds.getMaxY(), getZ()).texture(sprite.getMinU(), sprite.getMaxV()).color(r, g, b, a).next();
+                bb.vertex(matrix, bounds.getMaxX(), bounds.getMaxY(), getZ()).texture(sprite.getMaxU(), sprite.getMaxV()).color(r, g, b, a).next();
                 tess.draw();
             }
         }

+ 18 - 17
src/main/java/me/shedaniel/rei/impl/InternalWidgets.java

@@ -24,7 +24,6 @@
 package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
-import com.mojang.blaze3d.systems.RenderSystem;
 import it.unimi.dsi.fastutil.ints.IntList;
 import me.shedaniel.math.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
@@ -40,6 +39,8 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import net.minecraft.util.Formatting;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -53,7 +54,7 @@ import java.util.function.Supplier;
 public final class InternalWidgets {
     private InternalWidgets() {}
     
-    public static Widget createAutoCraftingButtonWidget(Rectangle displayBounds, me.shedaniel.math.Rectangle rectangle, String text, Supplier<RecipeDisplay> displaySupplier, List<Widget> setupDisplay, RecipeCategory<?> category) {
+    public static Widget createAutoCraftingButtonWidget(Rectangle displayBounds, Rectangle rectangle, Text text, Supplier<RecipeDisplay> displaySupplier, List<Widget> setupDisplay, RecipeCategory<?> category) {
         HandledScreen<?> handledScreen = REIHelper.getInstance().getPreviousHandledScreen();
         boolean[] visible = {false};
         List<String>[] errorTooltip = new List[]{null};
@@ -72,7 +73,7 @@ public final class InternalWidgets {
                     MinecraftClient.getInstance().openScreen(handledScreen);
                     ScreenHelper.getLastOverlay().init();
                 })
-                .onRender(button -> {
+                .onRender((matrices, button) -> {
                     button.setEnabled(false);
                     List<String> error = null;
                     int color = 0;
@@ -113,7 +114,7 @@ public final class InternalWidgets {
                         error.add("error.rei.no.handlers.applicable");
                     }
                     if ((button.containsMouse(PointHelper.ofMouse()) || button.isFocused()) && category instanceof TransferRecipeCategory && redSlots != null) {
-                        ((TransferRecipeCategory<RecipeDisplay>) category).renderRedSlots(setupDisplay, displayBounds, displaySupplier.get(), redSlots);
+                        ((TransferRecipeCategory<RecipeDisplay>) category).renderRedSlots(matrices, setupDisplay, displayBounds, displaySupplier.get(), redSlots);
                     }
                     errorTooltip[0] = error == null || error.isEmpty() ? null : Lists.newArrayList();
                     if (errorTooltip[0] != null) {
@@ -162,8 +163,8 @@ public final class InternalWidgets {
             }
             
             @Override
-            public void render(int mouseX, int mouseY, float delta) {
-                autoCraftingButton.render(mouseX, mouseY, delta);
+            public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+                autoCraftingButton.render(matrices, mouseX, mouseY, delta);
             }
             
             @Override
@@ -204,10 +205,10 @@ public final class InternalWidgets {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             for (Widget widget : widgets) {
                 widget.setZ(getZ());
-                widget.render(mouseX, mouseY, delta);
+                widget.render(matrices, mouseX, mouseY, delta);
             }
         }
         
@@ -234,9 +235,9 @@ public final class InternalWidgets {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             this.widget.setZ(getZ());
-            this.widget.render(mouseX, mouseY, delta);
+            this.widget.render(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -263,9 +264,9 @@ public final class InternalWidgets {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             this.widget.setZ(getZ());
-            this.widget.render(mouseX, mouseY, delta);
+            this.widget.render(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -301,12 +302,12 @@ public final class InternalWidgets {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
-            RenderSystem.pushMatrix();
-            RenderSystem.translatef(x, y, z);
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            matrices.push();
+            matrices.translate(x, y, z);
             this.widget.setZ(getZ());
-            this.widget.render(mouseX, mouseY, delta);
-            RenderSystem.popMatrix();
+            this.widget.render(matrices, mouseX, mouseY, delta);
+            matrices.pop();
         }
         
         @Override

+ 20 - 19
src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java

@@ -39,6 +39,7 @@ import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.nbt.Tag;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
@@ -54,7 +55,6 @@ import java.util.function.Predicate;
 public class ItemEntryStack extends AbstractEntryStack implements OptimalEntryStack {
     
     private static final Predicate<BakedModel> IS_SIDE_LIT = BakedModel::isSideLit;
-    private static final MatrixStack MATRICES = new MatrixStack();
     
     private ItemStack itemStack;
     
@@ -262,13 +262,14 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
     public Tooltip getTooltip(Point point) {
         if (isEmpty() || !get(Settings.TOOLTIP_ENABLED).get())
             return null;
-        List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true));
+        List<Text> toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true));
         toolTip.addAll(get(Settings.TOOLTIP_APPEND_EXTRA).apply(this));
         if (get(Settings.TOOLTIP_APPEND_MOD).get() && ConfigObject.getInstance().shouldAppendModNames()) {
-            final String modString = ClientHelper.getInstance().getFormattedModFromItem(getItem());
+            final Text modString = ClientHelper.getInstance().getFormattedModFromItem(getItem());
+            final String modId = ClientHelper.getInstance().getModFromItem(getItem());
             boolean alreadyHasMod = false;
-            for (String s : toolTip)
-                if (s.equalsIgnoreCase(modString)) {
+            for (Text s : toolTip)
+                if (s.asString().equalsIgnoreCase(modId)) {
                     alreadyHasMod = true;
                     break;
                 }
@@ -279,23 +280,23 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
     }
     
     @Override
-    public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
-        optimisedRenderStart(delta);
-        optimisedRenderBase(bounds, mouseX, mouseY, delta);
-        optimisedRenderOverlay(bounds, mouseX, mouseY, delta);
-        optimisedRenderEnd(delta);
+    public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
+        optimisedRenderStart(matrices, delta);
+        optimisedRenderBase(matrices, bounds, mouseX, mouseY, delta);
+        optimisedRenderOverlay(matrices, bounds, mouseX, mouseY, delta);
+        optimisedRenderEnd(matrices, delta);
     }
     
     @SuppressWarnings("deprecation")
     @Override
-    public void optimisedRenderStart(float delta) {
+    public void optimisedRenderStart(MatrixStack matrices, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX);
         GlStateManager.enableRescaleNormal();
     }
     
     @SuppressWarnings("deprecation")
     @Override
-    public void optimisedRenderEnd(float delta) {
+    public void optimisedRenderEnd(MatrixStack matrices, float delta) {
         GlStateManager.disableRescaleNormal();
     }
     
@@ -309,29 +310,29 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
     }
     
     @Override
-    public void optimisedRenderBase(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    public void optimisedRenderBase(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
         if (!isEmpty() && get(Settings.RENDER).get()) {
             ItemStack stack = getItemStack();
             ((ItemStackHook) (Object) stack).rei_setRenderEnchantmentGlint(get(Settings.Item.RENDER_ENCHANTMENT_GLINT).get());
-            MATRICES.push();
-            MATRICES.translate(bounds.getCenterX(), bounds.getCenterY(), 100.0F + getZ());
-            MATRICES.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight());
+            matrices.push();
+            matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 100.0F + getZ());
+            matrices.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight());
             VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
             BakedModel model = getModelFromStack(stack);
             boolean bl = !IS_SIDE_LIT.test(model);
             if (bl)
                 GlStateManager.setupGuiFlatDiffuseLighting();
-            MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, MATRICES, immediate, 15728880, OverlayTexture.DEFAULT_UV, model);
+            MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, matrices, immediate, 15728880, OverlayTexture.DEFAULT_UV, model);
             immediate.draw();
             if (bl)
                 GlStateManager.setupGui3dDiffuseLighting();
-            MATRICES.pop();
+            matrices.pop();
             ((ItemStackHook) (Object) stack).rei_setRenderEnchantmentGlint(false);
         }
     }
     
     @Override
-    public void optimisedRenderOverlay(Rectangle bounds, int mouseX, int mouseY, float delta) {
+    public void optimisedRenderOverlay(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
         if (!isEmpty() && get(Settings.RENDER).get()) {
             MinecraftClient.getInstance().getItemRenderer().zOffset = getZ();
             MinecraftClient.getInstance().getItemRenderer().renderGuiItemOverlay(MinecraftClient.getInstance().textRenderer, getItemStack(), bounds.x, bounds.y, get(Settings.RENDER_COUNTS).get() ? get(Settings.COUNTS).apply(this) : "");

+ 6 - 4
src/main/java/me/shedaniel/rei/impl/ScreenHelper.java

@@ -27,6 +27,7 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import me.shedaniel.cloth.hooks.ClothClientHooks;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Executor;
 import me.shedaniel.rei.RoughlyEnoughItemsState;
 import me.shedaniel.rei.api.ConfigManager;
@@ -45,6 +46,7 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.ActionResult;
 import org.apache.logging.log4j.util.TriConsumer;
@@ -167,19 +169,19 @@ public class ScreenHelper implements ClientModInitializer, REIHelper {
         ScreenHelper.lastHandledScreen = lastScreenWithHandler;
     }
     
-    public static void drawHoveringWidget(int x, int y, TriConsumer<Integer, Integer, Float> consumer, int width, int height, float delta) {
+    public static void drawHoveringWidget(MatrixStack matrices, int x, int y, TriConsumer<MatrixStack, Point, Float> consumer, int width, int height, float delta) {
         Window window = MinecraftClient.getInstance().getWindow();
-        drawHoveringWidget(window.getScaledWidth(), window.getScaledHeight(), x, y, consumer, width, height, delta);
+        drawHoveringWidget(matrices, window.getScaledWidth(), window.getScaledHeight(), x, y, consumer, width, height, delta);
     }
     
-    public static void drawHoveringWidget(int screenWidth, int screenHeight, int x, int y, TriConsumer<Integer, Integer, Float> consumer, int width, int height, float delta) {
+    public static void drawHoveringWidget(MatrixStack matrices, int screenWidth, int screenHeight, int x, int y, TriConsumer<MatrixStack, Point, Float> consumer, int width, int height, float delta) {
         int actualX = Math.max(x + 12, 6);
         int actualY = Math.min(y - height / 2, screenHeight - height - 6);
         if (actualX + width > screenWidth)
             actualX -= 24 + width;
         if (actualY < 6)
             actualY += 24;
-        consumer.accept(actualX, actualY, delta);
+        consumer.accept(matrices, new Point(actualX, actualY), delta);
     }
     
     /**

+ 8 - 7
src/main/java/me/shedaniel/rei/impl/SearchArgument.java

@@ -36,6 +36,7 @@ import net.minecraft.client.resource.language.I18n;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
+import net.minecraft.text.LiteralText;
 import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.registry.Registry;
@@ -190,7 +191,7 @@ public class SearchArgument {
             return tryGetFluidName(stack.getFluid());
         Tooltip tooltip = stack.getTooltip(PointHelper.ofMouse());
         if (tooltip != null)
-            return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0);
+            return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0).getString();
         return "";
     }
     
@@ -201,14 +202,14 @@ public class SearchArgument {
             return tryGetFluidName(stack.getFluid());
         Tooltip tooltip = stack.getTooltip(PointHelper.ofMouse());
         if (tooltip != null)
-            return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0);
+            return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0).getString();
         return "";
     }
     
     public static String tryGetEntryStackTooltip(EntryStack stack) {
         Tooltip tooltip = stack.getTooltip(new Point());
         if (tooltip != null)
-            return CollectionUtils.joinToString(tooltip.getText(), "\n");
+            return CollectionUtils.mapAndJoinToString(tooltip.getText(), Text::getString, "\n");
         return "";
     }
     
@@ -219,21 +220,21 @@ public class SearchArgument {
         return CollectionUtils.mapAndJoinToString(id.getPath().split("_"), StringUtils::capitalize, " ");
     }
     
-    public static List<String> tryGetItemStackToolTip(ItemStack itemStack, boolean careAboutAdvanced) {
+    public static List<Text> tryGetItemStackToolTip(ItemStack itemStack, boolean careAboutAdvanced) {
         if (!searchBlacklisted.contains(itemStack.getItem()))
             try {
-                return CollectionUtils.map(itemStack.getTooltip(MinecraftClient.getInstance().player, MinecraftClient.getInstance().options.advancedItemTooltips && careAboutAdvanced ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL), Text::asFormattedString);
+                return itemStack.getTooltip(MinecraftClient.getInstance().player, MinecraftClient.getInstance().options.advancedItemTooltips && careAboutAdvanced ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL);
             } catch (Throwable e) {
                 e.printStackTrace();
                 searchBlacklisted.add(itemStack.getItem());
             }
-        return Collections.singletonList(tryGetItemStackName(itemStack));
+        return Collections.singletonList(new LiteralText(tryGetItemStackName(itemStack)));
     }
     
     public static String tryGetItemStackName(ItemStack stack) {
         if (!searchBlacklisted.contains(stack.getItem()))
             try {
-                return stack.getName().asFormattedString();
+                return stack.getName().getString();
             } catch (Throwable e) {
                 e.printStackTrace();
                 searchBlacklisted.add(stack.getItem());

+ 4 - 3
src/main/java/me/shedaniel/rei/impl/widgets/ArrowWidget.java

@@ -28,6 +28,7 @@ import me.shedaniel.rei.api.widgets.Arrow;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.NotNull;
 
@@ -63,12 +64,12 @@ public final class ArrowWidget extends Arrow {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
-        drawTexture(getX(), getY(), 106, 91, 24, 17);
+        drawTexture(matrices, getX(), getY(), 106, 91, 24, 17);
         if (getAnimationDuration() > 0) {
             int width = MathHelper.ceil((System.currentTimeMillis() / (animationDuration / 24) % 24d) / 1f);
-            drawTexture(getX(), getY(), 82, 91, width, 17);
+            drawTexture(matrices, getX(), getY(), 82, 91, width, 17);
         }
     }
     

+ 4 - 3
src/main/java/me/shedaniel/rei/impl/widgets/BurningFireWidget.java

@@ -28,6 +28,7 @@ import me.shedaniel.rei.api.widgets.BurningFire;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.NotNull;
 
@@ -63,12 +64,12 @@ public final class BurningFireWidget extends BurningFire {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
-        drawTexture(getX(), getY(), 1, 74, 14, 14);
+        drawTexture(matrices, getX(), getY(), 1, 74, 14, 14);
         if (getAnimationDuration() > 0) {
             int height = 14 - MathHelper.ceil((System.currentTimeMillis() / (animationDuration / 14) % 14d) / 1f);
-            drawTexture(getX(), getY() + 14 - height, 82, 77 + (14 - height), 14, height);
+            drawTexture(matrices, getX(), getY() + 14 - height, 82, 77 + (14 - height), 14, height);
         }
     }
     

+ 31 - 28
src/main/java/me/shedaniel/rei/impl/widgets/ButtonWidget.java

@@ -29,12 +29,16 @@ import me.shedaniel.math.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.widgets.Button;
 import me.shedaniel.rei.api.widgets.Tooltip;
+import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.LiteralText;
 import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.Matrix4f;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -42,6 +46,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.OptionalInt;
+import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -53,13 +58,13 @@ public class ButtonWidget extends Button {
     private Rectangle bounds;
     private boolean enabled = true;
     @NotNull
-    private String text;
+    private Text text;
     @Nullable
     private Integer tint;
     @Nullable
     private Consumer<Button> onClick;
     @Nullable
-    private Consumer<Button> onRender;
+    private BiConsumer<MatrixStack, Button> onRender;
     private boolean focusable = false;
     private boolean focused = false;
     @Nullable
@@ -69,11 +74,7 @@ public class ButtonWidget extends Button {
     @Nullable
     private BiFunction<@NotNull Button, @NotNull Point, @NotNull Integer> textureIdFunction;
     
-    public ButtonWidget(me.shedaniel.math.Rectangle rectangle, Text text) {
-        this(rectangle, Objects.requireNonNull(text).asFormattedString());
-    }
-    
-    public ButtonWidget(me.shedaniel.math.Rectangle rectangle, String text) {
+    public ButtonWidget(Rectangle rectangle, Text text) {
         this.bounds = new Rectangle(Objects.requireNonNull(rectangle));
         this.text = Objects.requireNonNull(text);
     }
@@ -110,12 +111,12 @@ public class ButtonWidget extends Button {
     
     @Override
     @NotNull
-    public final String getText() {
+    public final Text getText() {
         return text;
     }
     
     @Override
-    public final void setText(@NotNull String text) {
+    public final void setText(@NotNull Text text) {
         this.text = text;
     }
     
@@ -129,13 +130,14 @@ public class ButtonWidget extends Button {
         this.onClick = onClick;
     }
     
+    @Nullable
     @Override
-    public final @Nullable Consumer<Button> getOnRender() {
+    public final BiConsumer<MatrixStack, Button> getOnRender() {
         return onRender;
     }
     
     @Override
-    public final void setOnRender(@Nullable Consumer<Button> onRender) {
+    public final void setOnRender(BiConsumer<MatrixStack, Button> onRender) {
         this.onRender = onRender;
     }
     
@@ -192,12 +194,12 @@ public class ButtonWidget extends Button {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (onRender != null) {
-            onRender.accept(this);
+            onRender.accept(matrices, this);
         }
         int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
-        renderBackground(x, y, width, height, this.getTextureId(new Point(mouseX, mouseY)));
+        renderBackground(matrices, x, y, width, height, this.getTextureId(new Point(mouseX, mouseY)));
         
         int color = 14737632;
         if (!this.enabled) {
@@ -207,16 +209,16 @@ public class ButtonWidget extends Button {
         }
         
         if (tint != null)
-            fillGradient(x + 1, y + 1, x + width - 1, y + height - 1, tint, tint);
+            fillGradient(matrices, x + 1, y + 1, x + width - 1, y + height - 1, tint, tint);
         
-        this.drawCenteredString(font, getText(), x + width / 2, y + (height - 8) / 2, color);
+        this.method_27534(matrices, font, getText(), x + width / 2, y + (height - 8) / 2, color);
         
         String tooltip = getTooltip();
         if (tooltip != null)
             if (!focused && containsMouse(mouseX, mouseY))
-                Tooltip.create(tooltip.split("\n")).queue();
+                Tooltip.create(CollectionUtils.map(tooltip.split("\n"), LiteralText::new)).queue();
             else if (focused)
-                Tooltip.create(new Point(x + width / 2, y + height / 2), tooltip.split("\n")).queue();
+                Tooltip.create(new Point(x + width / 2, y + height / 2), CollectionUtils.map(tooltip.split("\n"), LiteralText::new)).queue();
     }
     
     protected boolean isFocused(int mouseX, int mouseY) {
@@ -282,7 +284,7 @@ public class ButtonWidget extends Button {
         return 1;
     }
     
-    protected void renderBackground(int x, int y, int width, int height, int textureOffset) {
+    protected void renderBackground(MatrixStack matrices, int x, int y, int width, int height, int textureOffset) {
         minecraft.getTextureManager().bindTexture(REIHelper.getInstance().isDarkThemeEnabled() ? BUTTON_LOCATION_DARK : BUTTON_LOCATION);
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         RenderSystem.enableBlend();
@@ -292,18 +294,19 @@ public class ButtonWidget extends Button {
         // 9 Patch Texture
         
         // Four Corners
-        drawTexture(x, y, getZOffset(), 0, textureOffset * 80, 8, 8, 512, 256);
-        drawTexture(x + width - 8, y, getZOffset(), 248, textureOffset * 80, 8, 8, 512, 256);
-        drawTexture(x, y + height - 8, getZOffset(), 0, textureOffset * 80 + 72, 8, 8, 512, 256);
-        drawTexture(x + width - 8, y + height - 8, getZOffset(), 248, textureOffset * 80 + 72, 8, 8, 512, 256);
+        drawTexture(matrices, x, y, getZOffset(), 0, textureOffset * 80, 8, 8, 512, 256);
+        drawTexture(matrices, x + width - 8, y, getZOffset(), 248, textureOffset * 80, 8, 8, 512, 256);
+        drawTexture(matrices, x, y + height - 8, getZOffset(), 0, textureOffset * 80 + 72, 8, 8, 512, 256);
+        drawTexture(matrices, x + width - 8, y + height - 8, getZOffset(), 248, textureOffset * 80 + 72, 8, 8, 512, 256);
         
+        Matrix4f matrix = matrices.peek().getModel();
         // Sides
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y, y + 8, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80) / 512f, (textureOffset * 80 + 8) / 512f);
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y + height - 8, y + height, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80 + 72) / 512f, (textureOffset * 80 + 80) / 512f);
-        DrawableHelper.drawTexturedQuad(x, x + 8, y + 8, y + height - 8, getZ(), (0) / 256f, (8) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
-        DrawableHelper.drawTexturedQuad(x + width - 8, x + width, y + 8, y + height - 8, getZ(), (248) / 256f, (256) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y, y + 8, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80) / 512f, (textureOffset * 80 + 8) / 512f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y + height - 8, y + height, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80 + 72) / 512f, (textureOffset * 80 + 80) / 512f);
+        DrawableHelper.drawTexturedQuad(matrix, x, x + 8, y + 8, y + height - 8, getZ(), (0) / 256f, (8) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
+        DrawableHelper.drawTexturedQuad(matrix, x + width - 8, x + width, y + 8, y + height - 8, getZ(), (248) / 256f, (256) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
         
         // Center
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y + 8, y + height - 8, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y + 8, y + height - 8, getZ(), (8) / 256f, (248) / 256f, (textureOffset * 80 + 8) / 512f, (textureOffset * 80 + 72) / 512f);
     }
 }

+ 3 - 2
src/main/java/me/shedaniel/rei/impl/widgets/DrawableWidget.java

@@ -26,6 +26,7 @@ package me.shedaniel.rei.impl.widgets;
 import me.shedaniel.rei.api.DrawableConsumer;
 import me.shedaniel.rei.gui.widget.Widget;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collections;
@@ -40,8 +41,8 @@ public final class DrawableWidget extends Widget {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
-        this.drawable.render(this, mouseX, mouseY, delta);
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        this.drawable.render(this, matrices, mouseX, mouseY, delta);
     }
     
     @Override

+ 2 - 1
src/main/java/me/shedaniel/rei/impl/widgets/FillRectangleDrawableConsumer.java

@@ -30,6 +30,7 @@ import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import org.jetbrains.annotations.NotNull;
 
 public final class FillRectangleDrawableConsumer implements DrawableConsumer {
@@ -43,7 +44,7 @@ public final class FillRectangleDrawableConsumer implements DrawableConsumer {
     }
     
     @Override
-    public void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta) {
+    public void render(@NotNull DrawableHelper helper, MatrixStack matrices, int mouseX, int mouseY, float delta) {
         float a = (color >> 24 & 255) / 255.0F;
         float r = (color >> 16 & 255) / 255.0F;
         float g = (color >> 8 & 255) / 255.0F;

+ 44 - 38
src/main/java/me/shedaniel/rei/impl/widgets/LabelWidget.java

@@ -30,14 +30,20 @@ import me.shedaniel.rei.api.widgets.Label;
 import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 public final class LabelWidget extends Label {
     
@@ -51,133 +57,133 @@ public final class LabelWidget extends Label {
     @NotNull private Point point;
     @Nullable private Function<Label, @Nullable String> tooltip;
     @Nullable private Consumer<Label> onClick;
-    @Nullable private Consumer<Label> onRender;
-    @NotNull private String text;
+    @Nullable private BiConsumer<MatrixStack, Label> onRender;
+    @NotNull private Text text;
     
-    public LabelWidget(@NotNull Point point, @NotNull String text) {
+    public LabelWidget(@NotNull Point point, @NotNull Text text) {
         Objects.requireNonNull(this.point = point);
         Objects.requireNonNull(this.text = text);
     }
     
     @Override
-    public boolean isClickable() {
+    public final boolean isClickable() {
         return clickable;
     }
     
     @Override
-    public void setClickable(boolean clickable) {
+    public final void setClickable(boolean clickable) {
         this.clickable = clickable;
     }
     
     @Nullable
     @Override
-    public Consumer<Label> getOnClick() {
+    public final Consumer<Label> getOnClick() {
         return onClick;
     }
     
     @Override
-    public void setOnClick(@Nullable Consumer<Label> onClick) {
+    public final void setOnClick(@Nullable Consumer<Label> onClick) {
         this.onClick = onClick;
     }
     
     @Nullable
     @Override
-    public Consumer<Label> getOnRender() {
+    public final BiConsumer<MatrixStack, Label> getOnRender() {
         return onRender;
     }
     
     @Override
-    public void setOnRender(@Nullable Consumer<Label> onRender) {
+    public final void setOnRender(@Nullable BiConsumer<MatrixStack, Label> onRender) {
         this.onRender = onRender;
     }
     
     @Override
-    public boolean isFocusable() {
+    public final boolean isFocusable() {
         return focusable;
     }
     
     @Override
-    public void setFocusable(boolean focusable) {
+    public final void setFocusable(boolean focusable) {
         this.focusable = focusable;
     }
     
     @Override
     @Nullable
-    public String getTooltip() {
+    public final String getTooltip() {
         if (tooltip == null)
             return null;
         return tooltip.apply(this);
     }
     
     @Override
-    public void setTooltip(@Nullable Function<Label, @Nullable String> tooltip) {
+    public final void setTooltip(@Nullable Function<Label, @Nullable String> tooltip) {
         this.tooltip = tooltip;
     }
     
     @Override
-    public int getHorizontalAlignment() {
+    public final int getHorizontalAlignment() {
         return horizontalAlignment;
     }
     
     @Override
-    public void setHorizontalAlignment(int horizontalAlignment) {
+    public final void setHorizontalAlignment(int horizontalAlignment) {
         this.horizontalAlignment = horizontalAlignment;
     }
     
     @Override
-    public boolean hasShadow() {
+    public final boolean hasShadow() {
         return hasShadow;
     }
     
     @Override
-    public void setShadow(boolean hasShadow) {
+    public final void setShadow(boolean hasShadow) {
         this.hasShadow = hasShadow;
     }
     
     @Override
-    public int getColor() {
+    public final int getColor() {
         return color;
     }
     
     @Override
-    public void setColor(int color) {
+    public final void setColor(int color) {
         this.color = color;
     }
     
     @Override
-    public int getHoveredColor() {
+    public final int getHoveredColor() {
         return hoveredColor;
     }
     
     @Override
-    public void setHoveredColor(int hoveredColor) {
+    public final void setHoveredColor(int hoveredColor) {
         this.hoveredColor = hoveredColor;
     }
     
     @Override
-    public @NotNull Point getPoint() {
+    public final @NotNull Point getPoint() {
         return point;
     }
     
     @Override
-    public void setPoint(@NotNull Point point) {
+    public final void setPoint(@NotNull Point point) {
         this.point = Objects.requireNonNull(point);
     }
     
     @Override
-    public @NotNull String getText() {
+    public final @NotNull Text getText() {
         return text;
     }
     
     @Override
-    public void setText(@NotNull String text) {
+    public final void setText(@NotNull Text text) {
         this.text = Objects.requireNonNull(text);
     }
     
     @NotNull
     @Override
-    public Rectangle getBounds() {
-        int width = font.getStringWidth(text);
+    public final Rectangle getBounds() {
+        int width = font.method_27525(text);
         Point point = getPoint();
         if (getHorizontalAlignment() == LEFT_ALIGNED)
             return new Rectangle(point.x - 1, point.y - 5, width + 2, 14);
@@ -187,42 +193,42 @@ public final class LabelWidget extends Label {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (getOnRender() != null)
-            getOnRender().accept(this);
+            getOnRender().accept(matrices, this);
         int color = getColor();
         if (isClickable() && isHovered(mouseX, mouseY))
             color = getHoveredColor();
         Point pos = getPoint();
-        int width = font.getStringWidth(getText());
+        int width = font.method_27525(getText());
         switch (getHorizontalAlignment()) {
             case LEFT_ALIGNED:
                 if (hasShadow())
-                    font.drawWithShadow(getText(), pos.x, pos.y, color);
+                    font.method_27517(matrices, getText(), pos.x, pos.y, color);
                 else
-                    font.draw(getText(), pos.x, pos.y, color);
+                    font.method_27528(matrices, getText(), pos.x, pos.y, color);
                 break;
             case RIGHT_ALIGNED:
                 if (hasShadow())
-                    font.drawWithShadow(getText(), pos.x - width, pos.y, color);
+                    font.method_27517(matrices, getText(), pos.x - width, pos.y, color);
                 else
-                    font.draw(getText(), pos.x - width, pos.y, color);
+                    font.method_27528(matrices, getText(), pos.x - width, pos.y, color);
                 break;
             case CENTER:
             default:
                 if (hasShadow())
-                    font.drawWithShadow(getText(), pos.x - width / 2f, pos.y, color);
+                    font.method_27517(matrices, getText(), pos.x - width / 2f, pos.y, color);
                 else
-                    font.draw(getText(), pos.x - width / 2f, pos.y, color);
+                    font.method_27528(matrices, getText(), pos.x - width / 2f, pos.y, color);
                 break;
         }
         if (isHovered(mouseX, mouseY)) {
             String tooltip = getTooltip();
             if (tooltip != null) {
                 if (!focused && containsMouse(mouseX, mouseY))
-                    Tooltip.create(tooltip.split("\n")).queue();
+                    Tooltip.create(Stream.of(tooltip.split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
                 else if (focused)
-                    Tooltip.create(point, tooltip.split("\n")).queue();
+                    Tooltip.create(point, Stream.of(tooltip.split("\n")).map(LiteralText::new).collect(Collectors.toList())).queue();
             }
         }
     }

+ 15 - 12
src/main/java/me/shedaniel/rei/impl/widgets/PanelWidget.java

@@ -32,7 +32,9 @@ import me.shedaniel.rei.gui.config.RecipeBorderType;
 import me.shedaniel.rei.gui.config.RecipeScreenType;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.Matrix4f;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -61,10 +63,10 @@ public final class PanelWidget extends Panel {
         this.bounds = Objects.requireNonNull(bounds);
     }
     
-    public static void render(@NotNull Rectangle bounds, int color) {
+    public static void render(MatrixStack matrices, @NotNull Rectangle bounds, int color) {
         TEMP.bounds.setBounds(Objects.requireNonNull(bounds));
         TEMP.color = color;
-        TEMP.render(0, 0, 0);
+        TEMP.render(matrices, 0, 0, 0);
     }
     
     @Deprecated
@@ -126,7 +128,7 @@ public final class PanelWidget extends Panel {
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (!getRendering().test(this))
             return;
         float alpha = ((color >> 24) & 0xFF) / 255f;
@@ -142,19 +144,20 @@ public final class PanelWidget extends Panel {
         // 9 Patch Texture
         
         // Four Corners
-        this.drawTexture(x, y, 106 + xTextureOffset, 124 + yTextureOffset, 8, 8);
-        this.drawTexture(x + width - 8, y, 248 + xTextureOffset, 124 + yTextureOffset, 8, 8);
-        this.drawTexture(x, y + height - 8, 106 + xTextureOffset, 182 + yTextureOffset, 8, 8);
-        this.drawTexture(x + width - 8, y + height - 8, 248 + xTextureOffset, 182 + yTextureOffset, 8, 8);
+        this.drawTexture(matrices, x, y, 106 + xTextureOffset, 124 + yTextureOffset, 8, 8);
+        this.drawTexture(matrices, x + width - 8, y, 248 + xTextureOffset, 124 + yTextureOffset, 8, 8);
+        this.drawTexture(matrices, x, y + height - 8, 106 + xTextureOffset, 182 + yTextureOffset, 8, 8);
+        this.drawTexture(matrices, x + width - 8, y + height - 8, 248 + xTextureOffset, 182 + yTextureOffset, 8, 8);
         
+        Matrix4f matrix = matrices.peek().getModel();
         // Sides
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y, y + 8, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (124 + yTextureOffset) / 256f, (132 + yTextureOffset) / 256f);
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y + height - 8, y + height, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (182 + yTextureOffset) / 256f, (190 + yTextureOffset) / 256f);
-        DrawableHelper.drawTexturedQuad(x, x + 8, y + 8, y + height - 8, getZ(), (106 + xTextureOffset) / 256f, (114 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
-        DrawableHelper.drawTexturedQuad(x + width - 8, x + width, y + 8, y + height - 8, getZ(), (248 + xTextureOffset) / 256f, (256 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y, y + 8, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (124 + yTextureOffset) / 256f, (132 + yTextureOffset) / 256f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y + height - 8, y + height, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (182 + yTextureOffset) / 256f, (190 + yTextureOffset) / 256f);
+        DrawableHelper.drawTexturedQuad(matrix, x, x + 8, y + 8, y + height - 8, getZ(), (106 + xTextureOffset) / 256f, (114 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
+        DrawableHelper.drawTexturedQuad(matrix, x + width - 8, x + width, y + 8, y + height - 8, getZ(), (248 + xTextureOffset) / 256f, (256 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
         
         // Center
-        DrawableHelper.drawTexturedQuad(x + 8, x + width - 8, y + 8, y + height - 8, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
+        DrawableHelper.drawTexturedQuad(matrix, x + 8, x + width - 8, y + 8, y + height - 8, getZ(), (114 + xTextureOffset) / 256f, (248 + xTextureOffset) / 256f, (132 + yTextureOffset) / 256f, (182 + yTextureOffset) / 256f);
     }
     
     @Override

+ 11 - 9
src/main/java/me/shedaniel/rei/impl/widgets/TexturedDrawableConsumer.java

@@ -29,7 +29,9 @@ import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.Matrix4f;
 import org.jetbrains.annotations.NotNull;
 import org.lwjgl.opengl.GL11;
 
@@ -55,23 +57,23 @@ public final class TexturedDrawableConsumer implements DrawableConsumer {
     }
     
     @Override
-    public void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta) {
+    public void render(@NotNull DrawableHelper helper, MatrixStack matrices, int mouseX, int mouseY, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(identifier);
-        innerBlit(x, x + width, y, y + height, helper.getZOffset(), uWidth, vHeight, u, v, textureWidth, textureHeight);
+        innerBlit(matrices.peek().getModel(), x, x + width, y, y + height, helper.getZOffset(), uWidth, vHeight, u, v, textureWidth, textureHeight);
     }
     
-    private static void innerBlit(int xStart, int xEnd, int yStart, int yEnd, int z, int width, int height, float u, float v, int texWidth, int texHeight) {
-        innerBlit(xStart, xEnd, yStart, yEnd, z, u / texWidth, (u + width) / texWidth, v / texHeight, (v + height) / texHeight);
+    private static void innerBlit(Matrix4f matrix, int xStart, int xEnd, int yStart, int yEnd, int z, int width, int height, float u, float v, int texWidth, int texHeight) {
+        innerBlit(matrix, xStart, xEnd, yStart, yEnd, z, u / texWidth, (u + width) / texWidth, v / texHeight, (v + height) / texHeight);
     }
     
-    protected static void innerBlit(int xStart, int xEnd, int yStart, int yEnd, int z, float uStart, float uEnd, float vStart, float vEnd) {
+    protected static void innerBlit(Matrix4f matrix, int xStart, int xEnd, int yStart, int yEnd, int z, float uStart, float uEnd, float vStart, float vEnd) {
         Tessellator tessellator = Tessellator.getInstance();
         BufferBuilder bufferBuilder = tessellator.getBuffer();
         bufferBuilder.begin(GL11.GL_QUADS, VertexFormats.POSITION_TEXTURE);
-        bufferBuilder.vertex(xStart, yEnd, z).texture(uStart, vEnd).next();
-        bufferBuilder.vertex(xEnd, yEnd, z).texture(uEnd, vEnd).next();
-        bufferBuilder.vertex(xEnd, yStart, z).texture(uEnd, vStart).next();
-        bufferBuilder.vertex(xStart, yStart, z).texture(uStart, vStart).next();
+        bufferBuilder.vertex(matrix, xStart, yEnd, z).texture(uStart, vEnd).next();
+        bufferBuilder.vertex(matrix, xEnd, yEnd, z).texture(uEnd, vEnd).next();
+        bufferBuilder.vertex(matrix, xEnd, yStart, z).texture(uEnd, vStart).next();
+        bufferBuilder.vertex(matrix, xStart, yStart, z).texture(uStart, vStart).next();
         tessellator.draw();
     }
 }

+ 5 - 3
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -69,6 +69,7 @@ import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.ingame.*;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.enchantment.Enchantment;
 import net.minecraft.enchantment.EnchantmentHelper;
 import net.minecraft.fluid.Fluid;
@@ -76,6 +77,7 @@ import net.minecraft.item.*;
 import net.minecraft.potion.PotionUtil;
 import net.minecraft.recipe.*;
 import net.minecraft.tag.BlockTags;
+import net.minecraft.text.LiteralText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
@@ -164,9 +166,9 @@ public class DefaultPlugin implements REIPluginV0 {
             private Identifier id = new Identifier("roughlyenoughitems", "textures/gui/kirb.png");
             
             @Override
-            public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+            public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
                 MinecraftClient.getInstance().getTextureManager().bindTexture(id);
-                drawTexturedQuad(bounds.x, bounds.getMaxX(), bounds.y, bounds.getMaxY(), getZOffset(), 0, 1, 0, 1);
+                drawTexturedQuad(matrices.peek().getModel(), bounds.x, bounds.getMaxX(), bounds.y, bounds.getMaxY(), getZOffset(), 0, 1, 0, 1);
             }
             
             @Override
@@ -176,7 +178,7 @@ public class DefaultPlugin implements REIPluginV0 {
             
             @Override
             public @Nullable Tooltip getTooltip(Point point) {
-                return Tooltip.create("Kibby");
+                return Tooltip.create(new LiteralText("Kibby"));
             }
         });
     }

+ 5 - 4
src/main/java/me/shedaniel/rei/plugin/beacon/DefaultBeaconBaseCategory.java

@@ -42,6 +42,7 @@ import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.NotNull;
@@ -75,8 +76,8 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
             }
             
             @Override
-            public void render(Rectangle rectangle, int mouseX, int mouseY, float delta) {
-                MinecraftClient.getInstance().textRenderer.draw(name, rectangle.x + 5, rectangle.y + 6, -1);
+            public void render(MatrixStack matrices, Rectangle rectangle, int mouseX, int mouseY, float delta) {
+                MinecraftClient.getInstance().textRenderer.draw(matrices, name, rectangle.x + 5, rectangle.y + 6, -1);
             }
         };
     }
@@ -152,7 +153,7 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             scrolling.updatePosition(delta);
             Rectangle innerBounds = scrolling.getScissorBounds();
             ScissorsHandler.INSTANCE.scissor(innerBounds);
@@ -163,7 +164,7 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
                         break;
                     Slot widget = widgets.get(index);
                     widget.getBounds().setLocation(bounds.x + 1 + x * 18, (int) (bounds.y + 1 + y * 18 - scrolling.scrollAmount));
-                    widget.render(mouseX, mouseY, delta);
+                    widget.render(matrices, mouseX, mouseY, delta);
                 }
             }
             ScissorsHandler.INSTANCE.removeLastScissor();

+ 3 - 3
src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingCategory.java

@@ -62,11 +62,11 @@ public class DefaultBrewingCategory implements RecipeCategory<DefaultBrewingDisp
         Point startPoint = new Point(bounds.getCenterX() - 52, bounds.getCenterY() - 29);
         List<Widget> widgets = Lists.newArrayList();
         widgets.add(Widgets.createRecipeBase(bounds));
-        widgets.add(Widgets.createDrawableWidget((helper, mouseX, mouseY, delta) -> {
+        widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
             MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
-            helper.drawTexture(startPoint.x, startPoint.y, 0, 108, 103, 59);
+            helper.drawTexture(matrices, startPoint.x, startPoint.y, 0, 108, 103, 59);
             int width = MathHelper.ceil(System.currentTimeMillis() / 250d % 18d);
-            helper.drawTexture(startPoint.x + 44, startPoint.y + 28, 103, 163, width, 4);
+            helper.drawTexture(matrices, startPoint.x + 44, startPoint.y + 28, 103, 163, width, 4);
         }));
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entry(EntryStack.create(Items.BLAZE_POWDER)).disableBackground().markInput());
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 40, startPoint.y + 1)).entries(display.getInputEntries().get(0)).disableBackground().markInput());

+ 4 - 4
src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java

@@ -27,9 +27,9 @@ import com.google.common.collect.Lists;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.RecipeDisplay;
 import me.shedaniel.rei.plugin.DefaultPlugin;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.Ingredient;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
 
@@ -43,14 +43,14 @@ public class DefaultBrewingDisplay implements RecipeDisplay {
     private List<EntryStack> reactant;
     
     public DefaultBrewingDisplay(ItemStack input, Ingredient reactant, ItemStack output) {
-        this.input = EntryStack.create(input).setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.input")));
+        this.input = EntryStack.create(input).setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(new TranslatableText("category.rei.brewing.input").method_27692(Formatting.YELLOW)));
         this.reactant = new ArrayList<>();
         for (ItemStack stack : reactant.getMatchingStacksClient()) {
             EntryStack entryStack = EntryStack.create(stack);
-            entryStack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.reactant")));
+            entryStack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(new TranslatableText("category.rei.brewing.reactant").method_27692(Formatting.YELLOW)));
             this.reactant.add(entryStack);
         }
-        this.output = EntryStack.create(output).setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.brewing.result")));
+        this.output = EntryStack.create(output).setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(new TranslatableText("category.rei.brewing.result").method_27692(Formatting.YELLOW)));
     }
     
     @Override

+ 2 - 1
src/main/java/me/shedaniel/rei/plugin/campfire/DefaultCampfireCategory.java

@@ -33,6 +33,7 @@ import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 
 import java.text.DecimalFormat;
@@ -65,7 +66,7 @@ public class DefaultCampfireCategory implements RecipeCategory<DefaultCampfireDi
         widgets.add(Widgets.createResultSlotBackground(new Point(startPoint.x + 61, startPoint.y + 9)));
         widgets.add(Widgets.createBurningFire(new Point(startPoint.x + 1, startPoint.y + 20)).animationDurationMS(10000));
         widgets.add(Widgets.createLabel(new Point(bounds.x + bounds.width - 5, bounds.y + 5),
-                I18n.translate("category.rei.campfire.time", df.format(cookingTime / 20d))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB));
+                new TranslatableText("category.rei.campfire.time", df.format(cookingTime / 20d))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB));
         widgets.add(Widgets.createArrow(new Point(startPoint.x + 24, startPoint.y + 8)).animationDurationTicks(cookingTime));
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entries(display.getInputEntries().get(0)).markInput());
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 61, startPoint.y + 9)).entries(display.getOutputEntries()).disableBackground().markOutput());

+ 5 - 3
src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java

@@ -36,7 +36,9 @@ import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.ItemConvertible;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 
@@ -71,8 +73,8 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
             }
             
             @Override
-            public void render(Rectangle rectangle, int mouseX, int mouseY, float delta) {
-                MinecraftClient.getInstance().textRenderer.draw(I18n.translate("text.rei.composting.page", recipe.getPage() + 1), rectangle.x + 5, rectangle.y + 6, -1);
+            public void render(MatrixStack matrices, Rectangle rectangle, int mouseX, int mouseY, float delta) {
+                MinecraftClient.getInstance().textRenderer.method_27528(matrices, new TranslatableText("text.rei.composting.page", recipe.getPage() + 1), rectangle.x + 5, rectangle.y + 6, -1);
             }
         };
     }
@@ -91,7 +93,7 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
                 if (entryStack.getType() != EntryStack.Type.EMPTY)
                     for (Map.Entry<ItemConvertible, Float> entry : display.getInputMap().entrySet()) {
                         if (entry.getKey().asItem().equals(entryStack.getItem())) {
-                            entryStack = entryStack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(I18n.translate("text.rei.composting.chance", MathHelper.fastFloor(entry.getValue() * 100))));
+                            entryStack = entryStack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(new TranslatableText("text.rei.composting.chance", MathHelper.fastFloor(entry.getValue() * 100))));
                             break;
                         }
                     }

+ 8 - 6
src/main/java/me/shedaniel/rei/plugin/cooking/DefaultCookingCategory.java

@@ -24,7 +24,6 @@
 package me.shedaniel.rei.plugin.cooking;
 
 import com.google.common.collect.Lists;
-import com.mojang.blaze3d.systems.RenderSystem;
 import it.unimi.dsi.fastutil.ints.IntList;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Rectangle;
@@ -36,6 +35,8 @@ import me.shedaniel.rei.gui.entries.SimpleRecipeEntry;
 import me.shedaniel.rei.gui.widget.Widget;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 
 import java.text.DecimalFormat;
@@ -54,13 +55,14 @@ public class DefaultCookingCategory implements TransferRecipeCategory<DefaultCoo
     }
     
     @Override
-    public void renderRedSlots(List<Widget> widgets, Rectangle bounds, DefaultCookingDisplay display, IntList redSlots) {
+    public void renderRedSlots(MatrixStack matrices, List<Widget> widgets, Rectangle bounds, DefaultCookingDisplay display, IntList redSlots) {
         Point startPoint = new Point(bounds.getCenterX() - 41, bounds.getCenterY() - 27);
-        RenderSystem.translatef(0, 0, 400);
+        matrices.push();
+        matrices.translate(0, 0, 400);
         if (redSlots.contains(0)) {
-            DrawableHelper.fill(startPoint.x + 1, startPoint.y + 1, startPoint.x + 1 + 16, startPoint.y + 1 + 16, 1090453504);
+            DrawableHelper.fill(matrices, startPoint.x + 1, startPoint.y + 1, startPoint.x + 1 + 16, startPoint.y + 1 + 16, 1090453504);
         }
-        RenderSystem.translatef(0, 0, -400);
+        matrices.pop();
     }
     
     @Override
@@ -73,7 +75,7 @@ public class DefaultCookingCategory implements TransferRecipeCategory<DefaultCoo
         widgets.add(Widgets.createResultSlotBackground(new Point(startPoint.x + 61, startPoint.y + 9)));
         widgets.add(Widgets.createBurningFire(new Point(startPoint.x + 1, startPoint.y + 20)).animationDurationMS(10000));
         widgets.add(Widgets.createLabel(new Point(bounds.x + bounds.width - 5, bounds.y + 5),
-                I18n.translate("category.rei.cooking.time&xp", df.format(display.getXp()), df.format(cookingTime / 20d))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB));
+                new TranslatableText("category.rei.cooking.time&xp", df.format(display.getXp()), df.format(cookingTime / 20d))).noShadow().rightAligned().color(0xFF404040, 0xFFBBBBBB));
         widgets.add(Widgets.createArrow(new Point(startPoint.x + 24, startPoint.y + 8)).animationDurationTicks(cookingTime));
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 1, startPoint.y + 1)).entries(display.getInputEntries().get(0)).markInput());
         widgets.add(Widgets.createSlot(new Point(startPoint.x + 61, startPoint.y + 9)).entries(display.getOutputEntries()).disableBackground().markOutput());

+ 2 - 2
src/main/java/me/shedaniel/rei/plugin/cooking/DefaultCookingDisplay.java

@@ -28,10 +28,10 @@ import me.shedaniel.rei.api.TransferRecipeDisplay;
 import me.shedaniel.rei.server.ContainerInfo;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.block.entity.FurnaceBlockEntity;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.Item;
 import net.minecraft.recipe.AbstractCookingRecipe;
 import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
@@ -45,7 +45,7 @@ public abstract class DefaultCookingDisplay implements TransferRecipeDisplay {
     private static List<EntryStack> fuel;
     
     static {
-        fuel = FurnaceBlockEntity.createFuelTimeMap().keySet().stream().map(Item::getStackForRender).map(EntryStack::create).map(e -> e.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("category.rei.smelting.fuel")))).collect(Collectors.toList());
+        fuel = FurnaceBlockEntity.createFuelTimeMap().keySet().stream().map(Item::getStackForRender).map(EntryStack::create).map(e -> e.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(new TranslatableText("category.rei.smelting.fuel").method_27692(Formatting.YELLOW)))).collect(Collectors.toList());
     }
     
     private AbstractCookingRecipe recipe;

+ 6 - 5
src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingCategory.java

@@ -24,7 +24,6 @@
 package me.shedaniel.rei.plugin.crafting;
 
 import com.google.common.collect.Lists;
-import com.mojang.blaze3d.systems.RenderSystem;
 import it.unimi.dsi.fastutil.ints.IntList;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Rectangle;
@@ -40,6 +39,7 @@ import me.shedaniel.rei.server.ContainerInfoHandler;
 import net.minecraft.block.Blocks;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
@@ -94,19 +94,20 @@ public class DefaultCraftingCategory implements TransferRecipeCategory<DefaultCr
     }
     
     @Override
-    public void renderRedSlots(List<Widget> widgets, Rectangle bounds, DefaultCraftingDisplay display, IntList redSlots) {
+    public void renderRedSlots(MatrixStack matrices, List<Widget> widgets, Rectangle bounds, DefaultCraftingDisplay display, IntList redSlots) {
         ContainerInfo<ScreenHandler> info = (ContainerInfo<ScreenHandler>) ContainerInfoHandler.getContainerInfo(getIdentifier(), REIHelper.getInstance().getPreviousHandledScreen().getScreenHandler().getClass());
         if (info == null)
             return;
-        RenderSystem.translatef(0, 0, 400);
+        matrices.push();
+        matrices.translate(0, 0, 400);
         Point startPoint = new Point(bounds.getCenterX() - 58, bounds.getCenterY() - 27);
         int width = info.getCraftingWidth(REIHelper.getInstance().getPreviousHandledScreen().getScreenHandler());
         for (Integer slot : redSlots) {
             int i = slot;
             int x = i % width;
             int y = MathHelper.floor(i / (float) width);
-            DrawableHelper.fill(startPoint.x + 1 + x * 18, startPoint.y + 1 + y * 18, startPoint.x + 1 + x * 18 + 16, startPoint.y + 1 + y * 18 + 16, 0x60ff0000);
+            DrawableHelper.fill(matrices, startPoint.x + 1 + x * 18, startPoint.y + 1 + y * 18, startPoint.x + 1 + x * 18 + 16, startPoint.y + 1 + y * 18 + 16, 0x60ff0000);
         }
-        RenderSystem.translatef(0, 0, -400);
+        matrices.pop();
     }
 }

+ 6 - 4
src/main/java/me/shedaniel/rei/plugin/fuel/DefaultFuelCategory.java

@@ -36,7 +36,9 @@ import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.Items;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.Nullable;
 
@@ -73,7 +75,7 @@ public class DefaultFuelCategory implements RecipeCategory<DefaultFuelDisplay> {
         String burnItems = DECIMAL_FORMAT.format(recipeDisplay.getFuelTime() / 200d);
         List<Widget> widgets = Lists.newArrayList();
         widgets.add(Widgets.createRecipeBase(bounds));
-        widgets.add(Widgets.createLabel(new Point(bounds.x + 26, bounds.getMaxY() - 15), I18n.translate("category.rei.fuel.time.items", burnItems))
+        widgets.add(Widgets.createLabel(new Point(bounds.x + 26, bounds.getMaxY() - 15), new TranslatableText("category.rei.fuel.time.items", burnItems))
                 .color(0xFF404040, 0xFFBBBBBB).noShadow().leftAligned());
         widgets.add(Widgets.createBurningFire(new Point(bounds.x + 6, startPoint.y + 1)).animationDurationTicks(recipeDisplay.getFuelTime()));
         widgets.add(Widgets.createSlot(new Point(bounds.x + 6, startPoint.y + 18)).entries(recipeDisplay.getInputEntries().get(0)).markInput());
@@ -99,11 +101,11 @@ public class DefaultFuelCategory implements RecipeCategory<DefaultFuelDisplay> {
             }
             
             @Override
-            public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+            public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
                 slot.setZ(getZ() + 50);
                 slot.getBounds().setLocation(bounds.x + 4, bounds.y + 2);
-                slot.render(mouseX, mouseY, delta);
-                MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate("category.rei.fuel.time_short.items", burnItems), bounds.x + 25, bounds.y + 8, -1);
+                slot.render(matrices, mouseX, mouseY, delta);
+                MinecraftClient.getInstance().textRenderer.method_27517(matrices, new TranslatableText("category.rei.fuel.time_short.items", burnItems), bounds.x + 25, bounds.y + 8, -1);
             }
         };
     }

+ 13 - 9
src/main/java/me/shedaniel/rei/plugin/information/DefaultInformationCategory.java

@@ -47,6 +47,7 @@ import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.Texts;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.Matrix4f;
@@ -89,8 +90,8 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
             }
             
             @Override
-            public void render(Rectangle rectangle, int mouseX, int mouseY, float delta) {
-                MinecraftClient.getInstance().textRenderer.draw(name.asFormattedString(), rectangle.x + 5, rectangle.y + 6, -1);
+            public void render(MatrixStack matrices, Rectangle rectangle, int mouseX, int mouseY, float delta) {
+                MinecraftClient.getInstance().textRenderer.method_27528(matrices, name, rectangle.x + 5, rectangle.y + 6, -1);
             }
         };
     }
@@ -99,10 +100,13 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
     public EntryStack getLogo() {
         return new RenderingEntry() {
             @Override
-            public void render(Rectangle bounds, int mouseX, int mouseY, float delta) {
+            public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) {
                 MinecraftClient.getInstance().getTextureManager().bindTexture(DefaultPlugin.getDisplayTexture());
-                Matrix4f matrix4f = Matrix4f.translate(-1.2f, -1, 0);
-                DefaultInformationCategory.innerBlit(matrix4f, bounds.getCenterX() - 8, bounds.getCenterX() + 8, bounds.getCenterY() - 8, bounds.getCenterY() + 8, 0, 116f / 256f, (116f + 16f) / 256f, 0f, 16f / 256f);
+                matrices.push();
+                matrices.translate(-1.2f, -1, 0);
+                Matrix4f matrix = matrices.peek().getModel();
+                DefaultInformationCategory.innerBlit(matrix, bounds.getCenterX() - 8, bounds.getCenterX() + 8, bounds.getCenterY() - 8, bounds.getCenterY() + 8, 0, 116f / 256f, (116f + 16f) / 256f, 0f, 16f / 256f);
+                matrices.pop();
             }
         };
     }
@@ -110,7 +114,7 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
     @Override
     public List<Widget> setupDisplay(DefaultInformationDisplay recipeDisplay, me.shedaniel.math.Rectangle bounds) {
         List<Widget> widgets = Lists.newArrayList();
-        widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.y + 3), recipeDisplay.getName().asFormattedString()).noShadow().color(0xFF404040, 0xFFBBBBBB));
+        widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.y + 3), recipeDisplay.getName()).noShadow().color(0xFF404040, 0xFFBBBBBB));
         widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 8, bounds.y + 15)).entries(recipeDisplay.getEntryStacks()).markInput());
         Rectangle rectangle = new Rectangle(bounds.getCenterX() - (bounds.width / 2), bounds.y + 35, bounds.width, bounds.height - 40);
         widgets.add(Widgets.createSlotBase(rectangle));
@@ -154,7 +158,7 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
             for (Text text : texts) {
                 if (!this.texts.isEmpty())
                     this.texts.add(null);
-                this.texts.addAll(Texts.wrapLines(text, bounds.width - 11, MinecraftClient.getInstance().textRenderer, true, false));
+                this.texts.addAll(Texts.wrapLines(text, bounds.width - 11, MinecraftClient.getInstance().textRenderer));
             }
         }
         
@@ -188,14 +192,14 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             scrolling.updatePosition(delta);
             Rectangle innerBounds = scrolling.getScissorBounds();
             ScissorsHandler.INSTANCE.scissor(innerBounds);
             int currentY = (int) -scrolling.scrollAmount + innerBounds.y;
             for (Text text : texts) {
                 if (text != null && currentY + font.fontHeight >= innerBounds.y && currentY <= innerBounds.getMaxY()) {
-                    font.draw(text.asFormattedString(), innerBounds.x + 2, currentY + 2, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF090909);
+                    font.method_27528(matrices, text, innerBounds.x + 2, currentY + 2, REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF090909);
                 }
                 currentY += text == null ? 4 : font.fontHeight;
             }

+ 2 - 1
src/main/resources/rei.aw

@@ -9,4 +9,5 @@ accessible field net/minecraft/client/gui/screen/ingame/HandledScreen y I
 accessible field net/minecraft/client/gui/screen/ingame/HandledScreen backgroundWidth I
 accessible field net/minecraft/client/gui/screen/ingame/HandledScreen backgroundHeight I
 accessible field net/minecraft/client/gui/screen/ingame/HandledScreen focusedSlot Lnet/minecraft/screen/slot/Slot;
-accessible field net/minecraft/client/gui/widget/TexturedButtonWidget texture Lnet/minecraft/util/Identifier;
+accessible field net/minecraft/client/gui/widget/TexturedButtonWidget texture Lnet/minecraft/util/Identifier;
+accessible method net/minecraft/client/gui/DrawableHelper drawTexturedQuad (Lnet/minecraft/util/math/Matrix4f;IIIIIFFFF)V