aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/cc/polyfrost/oneconfig/renderer/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cc/polyfrost/oneconfig/renderer/image')
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/renderer/image/ImageLoader.java190
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/renderer/image/Images.java19
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/renderer/image/SVGs.java52
3 files changed, 261 insertions, 0 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/image/ImageLoader.java b/src/main/java/cc/polyfrost/oneconfig/renderer/image/ImageLoader.java
new file mode 100644
index 0000000..e8861eb
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/renderer/image/ImageLoader.java
@@ -0,0 +1,190 @@
+package cc.polyfrost.oneconfig.renderer.image;
+
+import cc.polyfrost.oneconfig.utils.IOUtils;
+import org.lwjgl.nanovg.NSVGImage;
+import org.lwjgl.nanovg.NanoSVG;
+import org.lwjgl.nanovg.NanoVG;
+import org.lwjgl.stb.STBImage;
+import org.lwjgl.system.MemoryUtil;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+
+/**
+ * Loads images and SVGs from resources into NanoVG.
+ *
+ * @see cc.polyfrost.oneconfig.renderer.RenderManager
+ * @see Images
+ * @see SVGs
+ */
+public final class ImageLoader {
+ private ImageLoader() {
+
+ }
+
+ private final HashMap<String, Integer> imageHashMap = new HashMap<>();
+ private final HashMap<String, Integer> svgHashMap = new HashMap<>();
+ public static ImageLoader INSTANCE = new ImageLoader();
+
+ /**
+ * Loads an image from resources.
+ *
+ * @param vg The NanoVG context.
+ * @param fileName The name of the file to load.
+ * @return Whether the image was loaded successfully.
+ */
+ public boolean loadImage(long vg, String fileName) {
+ if (!imageHashMap.containsKey(fileName)) {
+ int[] width = {0};
+ int[] height = {0};
+ int[] channels = {0};
+
+ ByteBuffer image = IOUtils.resourceToByteBufferNullable(fileName);
+ if (image == null) {
+ return false;
+ }
+
+ ByteBuffer buffer = STBImage.stbi_load_from_memory(image, width, height, channels, 4);
+ if (buffer == null) {
+ return false;
+ }
+
+ imageHashMap.put(fileName, NanoVG.nvgCreateImageRGBA(vg, width[0], height[0], NanoVG.NVG_IMAGE_REPEATX | NanoVG.NVG_IMAGE_REPEATY | NanoVG.NVG_IMAGE_GENERATE_MIPMAPS, buffer));
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Loads an SVG from resources.
+ *
+ * @param vg The NanoVG context.
+ * @param fileName The name of the file to load.
+ * @param width The width of the SVG.
+ * @param height The height of the SVG.
+ * @return Whether the SVG was loaded successfully.
+ */
+ public boolean loadSVG(long vg, String fileName, float width, float height) {
+ String name = fileName + "-" + width + "-" + height;
+ if (!svgHashMap.containsKey(name)) {
+ try {
+ InputStream inputStream = this.getClass().getResourceAsStream(fileName);
+ if (inputStream == null) return false;
+ StringBuilder resultStringBuilder = new StringBuilder();
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ resultStringBuilder.append(line);
+ }
+ }
+ CharSequence s = resultStringBuilder.toString();
+ NSVGImage svg = NanoSVG.nsvgParse(s, "px", 96f);
+ if (svg == null) return false;
+ long rasterizer = NanoSVG.nsvgCreateRasterizer();
+
+ int w = (int) svg.width();
+ int h = (int) svg.height();
+ float scale = Math.max(width / w, height / h);
+ w = (int) (w * scale);
+ h = (int) (h * scale);
+
+ ByteBuffer image = MemoryUtil.memAlloc(w * h * 4);
+ NanoSVG.nsvgRasterize(rasterizer, svg, 0, 0, scale, image, w, h, w * 4);
+
+ NanoSVG.nsvgDeleteRasterizer(rasterizer);
+ NanoSVG.nsvgDelete(svg);
+
+ svgHashMap.put(name, NanoVG.nvgCreateImageRGBA(vg, w, h, NanoVG.NVG_IMAGE_REPEATX | NanoVG.NVG_IMAGE_REPEATY | NanoVG.NVG_IMAGE_GENERATE_MIPMAPS, image));
+ return true;
+ } catch (Exception e) {
+ System.err.println("Failed to parse SVG file");
+ e.printStackTrace();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get a loaded image from the cache.
+ * <p><b>Requires the image to have been loaded first.</b></p>
+ *
+ * @param fileName The name of the file to load.
+ * @return The image
+ * @see ImageLoader#loadImage(long, String)
+ */
+ public int getImage(String fileName) {
+ return imageHashMap.get(fileName);
+ }
+
+ /**
+ * Remove an image from the cache, allowing the image to be garbage collected.
+ * Should be used when the GUI rendering the image is closed.
+ *
+ * @param vg The NanoVG context.
+ * @param fileName The name of the file to remove.
+ * @see ImageLoader#loadImage(long, String)
+ */
+ public void removeImage(long vg, String fileName) {
+ NanoVG.nvgDeleteImage(vg, imageHashMap.get(fileName));
+ imageHashMap.remove(fileName);
+ }
+
+ /**
+ * Clears all images from the cache, allowing the images cleared to be garbage collected.
+ * Should be used when the GUI rendering loaded images are closed.
+ *
+ * @param vg The NanoVG context.
+ */
+ public void clearImages(long vg) {
+ HashMap<String, Integer> temp = new HashMap<>(imageHashMap);
+ for (String image : temp.keySet()) {
+ NanoVG.nvgDeleteImage(vg, imageHashMap.get(image));
+ imageHashMap.remove(image);
+ }
+ }
+
+ /**
+ * Get a loaded SVG from the cache.
+ * <p><b>Requires the SVG to have been loaded first.</b></p>
+ *
+ * @param fileName The name of the file to load.
+ * @return The SVG
+ * @see ImageLoader#loadSVG(long, String, float, float)
+ */
+ public int getSVG(String fileName, float width, float height) {
+ String name = fileName + "-" + width + "-" + height;
+ return svgHashMap.get(name);
+ }
+
+ /**
+ * Remove a SVG from the cache, allowing the SVG to be garbage collected.
+ * Should be used when the GUI rendering the SVG is closed.
+ *
+ * @param vg The NanoVG context.
+ * @param fileName The name of the file to remove.
+ * @see ImageLoader#loadSVG(long, String, float, float)
+ */
+ public void removeSVG(long vg, String fileName, float width, float height) {
+ String name = fileName + "-" + width + "-" + height;
+ NanoVG.nvgDeleteImage(vg, imageHashMap.get(name));
+ svgHashMap.remove(name);
+ }
+
+ /**
+ * Clears all SVGs from the cache, allowing the SVGs cleared to be garbage collected.
+ * Should be used when the GUI rendering loaded SVGs are closed.
+ *
+ * @param vg The NanoVG context.
+ */
+ public void clearSVGs(long vg) {
+ HashMap<String, Integer> temp = new HashMap<>(svgHashMap);
+ for (String image : temp.keySet()) {
+ NanoVG.nvgDeleteImage(vg, svgHashMap.get(image));
+ svgHashMap.remove(image);
+ }
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/image/Images.java b/src/main/java/cc/polyfrost/oneconfig/renderer/image/Images.java
new file mode 100644
index 0000000..ad1941e
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/renderer/image/Images.java
@@ -0,0 +1,19 @@
+package cc.polyfrost.oneconfig.renderer.image;
+
+/**
+ * An enum of images used in OneConfig.
+ *
+ * @see cc.polyfrost.oneconfig.renderer.RenderManager#drawImage(long, String, float, float, float, float, int)
+ * @see ImageLoader
+ */
+public enum Images {
+ HUE_GRADIENT("/assets/oneconfig/options/HueGradient.png"),
+ COLOR_WHEEL("/assets/oneconfig/options/ColorWheel.png"),
+ ALPHA_GRID("/assets/oneconfig/options/AlphaGrid.png");
+
+ public final String filePath;
+
+ Images(String filePath) {
+ this.filePath = filePath;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/image/SVGs.java b/src/main/java/cc/polyfrost/oneconfig/renderer/image/SVGs.java
new file mode 100644
index 0000000..5ba3fcd
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/renderer/image/SVGs.java
@@ -0,0 +1,52 @@
+package cc.polyfrost.oneconfig.renderer.image;
+
+/**
+ * An enum of SVGs used in OneConfig.
+ *
+ * @see cc.polyfrost.oneconfig.renderer.RenderManager#drawSvg(long, String, float, float, float, float, int)
+ * @see ImageLoader
+ */
+public enum SVGs {
+ ONECONFIG("/assets/oneconfig/icons/OneConfig.svg"),
+ ONECONFIG_OFF("/assets/oneconfig/icons/OneConfigOff.svg"),
+ COPYRIGHT_FILL("/assets/oneconfig/icons/CopyrightFill.svg"),
+ APERTURE_FILL("/assets/oneconfig/icons/ApertureFill.svg"),
+ ARROWS_CLOCKWISE_BOLD("/assets/oneconfig/icons/ArrowsClockwiseBold.svg"),
+ FADERS_HORIZONTAL_BOLD("/assets/oneconfig/icons/FadersHorizontalBold.svg"),
+ GAUGE_FILL("/assets/oneconfig/icons/GaugeFill.svg"),
+ GEAR_SIX_FILL("/assets/oneconfig/icons/GearSixFill.svg"),
+ MAGNIFYING_GLASS_BOLD("/assets/oneconfig/icons/MagnifyingGlassBold.svg"),
+ NOTE_PENCIL_BOLD("/assets/oneconfig/icons/NotePencilBold.svg"),
+ PAINT_BRUSH_BROAD_FILL("/assets/oneconfig/icons/PaintBrushBroadFill.svg"),
+ USER_SWITCH_FILL("/assets/oneconfig/icons/UserSwitchFill.svg"),
+ X_CIRCLE_BOLD("/assets/oneconfig/icons/XCircleBold.svg"),
+ CARET_LEFT("/assets/oneconfig/icons/CaretLeftBold.svg"),
+ CARET_RIGHT("/assets/oneconfig/icons/CaretRightBold.svg"),
+
+ // OLD ICONS
+ BOX("/assets/oneconfig/old-icons/Box.svg"),
+ CHECKBOX_TICK("/assets/oneconfig/old-icons/CheckboxTick.svg"),
+ CHECK_CIRCLE("/assets/oneconfig/old-icons/CheckCircle.svg"),
+ CHEVRON_DOWN("/assets/oneconfig/old-icons/ChevronDown.svg"),
+ CHEVRON_UP("/assets/oneconfig/old-icons/ChevronUp.svg"),
+ COPY("/assets/oneconfig/old-icons/Copy.svg"),
+ DROPDOWN_LIST("/assets/oneconfig/old-icons/DropdownList.svg"),
+ ERROR("/assets/oneconfig/old-icons/Error.svg"),
+ EYE("/assets/oneconfig/old-icons/Eye.svg"),
+ EYE_OFF("/assets/oneconfig/old-icons/EyeOff.svg"),
+ HEART_FILL("/assets/oneconfig/old-icons/HeartFill.svg"),
+ HEART_OUTLINE("/assets/oneconfig/old-icons/HeartOutline.svg"),
+ HELP_CIRCLE("/assets/oneconfig/old-icons/HelpCircle.svg"),
+ HISTORY("/assets/oneconfig/old-icons/History.svg"),
+ INFO_CIRCLE("/assets/oneconfig/old-icons/InfoCircle.svg"),
+ KEYSTROKE("/assets/oneconfig/old-icons/Keystroke.svg"),
+ PASTE("/assets/oneconfig/old-icons/Paste.svg"),
+ POP_OUT("/assets/oneconfig/old-icons/PopOut.svg"),
+ WARNING("/assets/oneconfig/old-icons/Warning.svg");
+
+ public final String filePath;
+
+ SVGs(String filePath) {
+ this.filePath = filePath;
+ }
+}