Integrate flyfish CAD viewer

This commit is contained in:
2026-10-26 18:07:00 +08:00
parent e4eee1b3b7
commit e01c7eaecb
28 changed files with 560 additions and 5376 deletions
+3 -3
View File
@@ -47,7 +47,7 @@ const sourceDir = path.join(appDir, 'java')
const outDir = path.join(root, 'android', 'build')
const classesDir = path.join(outDir, 'classes')
const dexDir = path.join(outDir, 'dex')
const apkName = 'PhoneViewer-0.4.1.apk'
const apkName = 'PhoneViewer-0.5.0.apk'
function run(command, args, options = {}) {
console.log('>', path.basename(command), args.join(' '))
@@ -139,9 +139,9 @@ run(path.join(buildTools, 'aapt2.exe'), [
'--target-sdk-version',
'34',
'--version-code',
'5',
'6',
'--version-name',
'0.4.1',
'0.5.0',
'--auto-add-overlay'
])
+27
View File
@@ -0,0 +1,27 @@
import fs from 'node:fs'
import path from 'node:path'
const source = path.join('node_modules', '@flyfish-dev', 'cad-viewer', 'dist', 'wasm')
const target = path.join('public', 'wasm')
const files = [
'dwg-worker.js',
'dwfv-render.wasm',
'libredwg-web.js',
'libredwg-web.wasm'
]
if (!fs.existsSync(source)) {
console.warn(`[cad-wasm] source not found: ${source}`)
process.exit(0)
}
fs.mkdirSync(target, { recursive: true })
for (const file of files) {
const from = path.join(source, file)
if (!fs.existsSync(from)) {
console.warn(`[cad-wasm] missing: ${from}`)
continue
}
fs.copyFileSync(from, path.join(target, file))
}
console.log(`[cad-wasm] copied ${files.length} runtime files to ${target}`)
-86
View File
@@ -1,86 +0,0 @@
import fs from 'node:fs'
import path from 'node:path'
const source = process.argv[2] ?? 'node_modules/@mlightcad/libredwg-web/wasm/libredwg-web.wasm'
const target = process.argv[3] ?? 'public/vendor/libredwg/wasm/libredwg-web.wasm'
const INITIAL_PAGES = 4096 // 256 MiB; the module can still grow up to its 4 GiB maximum.
const MAX_PAGES = 65536
const buf = fs.readFileSync(source)
if (buf.readUInt32LE(0) !== 0x6d736100 || buf.readUInt32LE(4) !== 1) {
throw new Error('Not a WebAssembly module')
}
function readU32(data, offset) {
let value = 0
let shift = 0
let pos = offset
while (true) {
const byte = data[pos++]
value += (byte & 0x7f) * 2 ** shift
if (!(byte & 0x80)) break
shift += 7
if (shift > 35) throw new Error('Invalid LEB128 value')
}
return [value >>> 0, pos]
}
function encodeU32(value) {
const bytes = []
let v = value >>> 0
do {
let byte = v & 0x7f
v >>>= 7
if (v) byte |= 0x80
bytes.push(byte)
} while (v)
return Buffer.from(bytes)
}
function encodeSection(id, payload) {
return Buffer.concat([Buffer.from([id]), encodeU32(payload.length), payload])
}
const sections = []
let pos = 8
while (pos < buf.length) {
const id = buf[pos++]
const [size, afterSize] = readU32(buf, pos)
const payload = buf.subarray(afterSize, afterSize + size)
sections.push({ id, payload })
pos = afterSize + size
}
let patched = false
const output = []
output.push(buf.subarray(0, 8))
for (const section of sections) {
if (section.id === 5 && !patched) {
const [count, afterCount] = readU32(section.payload, 0)
if (count < 1) throw new Error('Memory section has no memory')
const flags = section.payload[afterCount]
if ((flags & 0x01) === 0) throw new Error('Memory has no maximum; refusing to patch')
const [oldMin, afterMin] = readU32(section.payload, afterCount + 1)
const [oldMax] = readU32(section.payload, afterMin)
if (oldMin !== 16384) throw new Error(`Unexpected initial memory: ${oldMin}`)
const payload = Buffer.concat([
encodeU32(count),
Buffer.from([flags]),
encodeU32(INITIAL_PAGES),
encodeU32(MAX_PAGES),
section.payload.subarray(afterMin + encodeU32(oldMax).length)
])
output.push(encodeSection(5, payload))
patched = true
console.log(
`patched memory: ${oldMin} -> ${INITIAL_PAGES} pages (${Math.round((INITIAL_PAGES * 64) / 1024)} MiB)`
)
} else {
output.push(encodeSection(section.id, section.payload))
}
}
if (!patched) throw new Error('Memory section not found')
fs.mkdirSync(path.dirname(target), { recursive: true })
fs.writeFileSync(target, Buffer.concat(output))
console.log('wrote', target, fs.statSync(target).size, 'bytes')