From 3b748ab73c784948d4f97fbe086a1a8be621e9ba Mon Sep 17 00:00:00 2001
From: Asourla <3754198@gmain.com>
Date: Wed, 15 Jul 2026 16:15:41 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=B0=B4=E5=B9=B3?=
=?UTF-8?q?=E4=B8=8E=E9=95=9C=E5=83=8F=E7=BF=BB=E8=BD=AC=E7=9A=84=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=96=B9=E6=B3=95=E5=9C=A8?=
=?UTF-8?q?flip=E4=B8=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/FontCreator/useFontCreator.js | 22 ++-
src/components/ImageCreator/ImageCreator.vue | 24 ++-
.../SettingPanel/panels/FontSettingPanel.vue | 15 +-
.../SettingPanel/panels/ImageSettingPanel.vue | 15 +-
src/stores/useSettingStore.js | 6 +
src/utils/flip.js | 141 ++++++++++++++++++
6 files changed, 217 insertions(+), 6 deletions(-)
create mode 100644 src/utils/flip.js
diff --git a/src/components/FontCreator/useFontCreator.js b/src/components/FontCreator/useFontCreator.js
index 98a712f..588d565 100644
--- a/src/components/FontCreator/useFontCreator.js
+++ b/src/components/FontCreator/useFontCreator.js
@@ -1,11 +1,12 @@
import { ref } from "vue";
import { createGlobalState } from "@vueuse/core";
import useSettingStore from "@/stores/useSettingStore";
+import { flipGlyphData } from "../../utils/flip";
import { getFontGlyph } from "../../apis/font";
import { watchDebounced } from "@vueuse/core";
export default createGlobalState(() => {
const needText = ref("波特律动");
- const { mode, color, fontSize } = useSettingStore();
+ const { mode, hFlip, vFlip, color, fontSize } = useSettingStore();
const fontTemplates = ref([
{
name: "波特律动OLED驱动",
@@ -33,7 +34,7 @@ export default createGlobalState(() => {
const fontFace = ref(fontFaces.value[0]);
watchDebounced(
- [needText, fontSize, mode, color, fontFace],
+ [needText, fontSize, mode, hFlip, vFlip, color, fontFace],
async () => {
const needList = [...new Set(needText.value.split(""))];
const res = await getFontGlyph(
@@ -45,6 +46,10 @@ export default createGlobalState(() => {
color.value
);
console.log(res.data);
+ if (!res.data || !res.data.data) {
+ console.error('API返回数据异常', res)
+ return
+ }
const a = {};
needList.forEach((item) => {
a[item] = {
@@ -53,6 +58,19 @@ export default createGlobalState(() => {
data: res.data.data[item],
};
});
+ // 应用水平/垂直翻转
+ if (hFlip.value || vFlip.value) {
+ Object.keys(a).forEach((key) => {
+ a[key].data = flipGlyphData(
+ a[key].data,
+ a[key].width,
+ a[key].height,
+ mode.value,
+ hFlip.value,
+ vFlip.value
+ )
+ })
+ }
fonts.value = a;
},
{ immediate: true, deep: true, debounce: 100, maxWait: 300 }
diff --git a/src/components/ImageCreator/ImageCreator.vue b/src/components/ImageCreator/ImageCreator.vue
index c9d0a21..730eea7 100644
--- a/src/components/ImageCreator/ImageCreator.vue
+++ b/src/components/ImageCreator/ImageCreator.vue
@@ -5,7 +5,7 @@ import useImageCreator from "./useImageCreator";
import { watchDebounced } from "@vueuse/core";
const canvasRef = ref(null);
const imgRef = ref(null);
-const { mode, color, imageSize } = useSettingStore();
+const { mode, hFlip, vFlip, color, imageSize } = useSettingStore();
const { sourceImg, imgGlyph, imgThreshold, mask } = useImageCreator();
@@ -50,6 +50,26 @@ async function getGlyph() {
const res = [];
+ // 像素级翻转(在取模转换之前)
+ if (hFlip.value) {
+ for (let y = 0; y < height; y++) {
+ for (let x = 0; x < width / 2; x++) {
+ const a = (y * width + x) * 4
+ const b = (y * width + (width - 1 - x)) * 4
+ ;[canvasImg.data[a], canvasImg.data[b]] = [canvasImg.data[b], canvasImg.data[a]]
+ }
+ }
+ }
+ if (vFlip.value) {
+ for (let y = 0; y < height / 2; y++) {
+ for (let x = 0; x < width; x++) {
+ const a = (y * width + x) * 4
+ const b = ((height - 1 - y) * width + x) * 4
+ ;[canvasImg.data[a], canvasImg.data[b]] = [canvasImg.data[b], canvasImg.data[a]]
+ }
+ }
+ }
+
if (mode.value == '列行式') {
const page = ~~((imageSize.value.height + 7) / 8);
for (let i = 0; i < page; i++) {
@@ -134,7 +154,7 @@ onMounted(async () => {
getGlyph()
mask.value = {}
}, { immediate: true, deep: true, debounce: 100, maxWait: 300 });
- watchDebounced([mode, color, mask], async () => {
+ watchDebounced([mode, hFlip, vFlip, color, mask], async () => {
getGlyph()
}, { immediate: true, deep: true, debounce: 100, maxWait: 300 });
});
diff --git a/src/components/SettingPanel/panels/FontSettingPanel.vue b/src/components/SettingPanel/panels/FontSettingPanel.vue
index 7b38a33..d8953c1 100644
--- a/src/components/SettingPanel/panels/FontSettingPanel.vue
+++ b/src/components/SettingPanel/panels/FontSettingPanel.vue
@@ -6,7 +6,7 @@ import { Codemirror } from 'vue-codemirror'
import { oneDark } from '@codemirror/theme-one-dark'
import { cpp } from '@codemirror/lang-cpp'
import { computed } from 'vue';
-const { fontSize, modeList, mode, color, } = useSettingStore();
+const { fontSize, modeList, mode, hFlip, vFlip, color } = useSettingStore();
const { needText, fontTemplates, fontTemplate, fontFaces, fontFace } = useFontCreator();
const currentFontface = computed({
@@ -61,6 +61,19 @@ const currentFontface = computed({