- 在 .gitignore 中添加 node_modules 目录 - 在 Msvc.php 中添加 compileResourceFile 方法用于编译 .rc 资源文件 - 新增 package.json 配置文件及 svg-to-ico.js 转换脚本 - 在 project.yml 中添加 Windows 资源文件配置示例 - 添加 swoole-logo.svg 图标文件 - 在 Translator.php 中集成资源文件生成功能 - 实现资源文件编译和链接到最终可执行文件的流程 - 更新版本号从 1049 到 1051pull/1/head
parent
c79573a9fe
commit
b17b4acbac
10 changed files with 381 additions and 7 deletions
@ -1,6 +1,19 @@ |
||||
name: win32-hello |
||||
version: 0.0.1 |
||||
mode: bin |
||||
|
||||
# Windows 资源文件配置示例 |
||||
# resource: |
||||
# icon: icon.ico |
||||
# version-info: |
||||
# file-version: 0.0.1.0 |
||||
# product-version: 0.0.1.0 |
||||
# company-name: "My Company" |
||||
# file-description: "Win32 Hello World Application" |
||||
# legal-copyright: "Copyright (C) 2026 My Company" |
||||
# product-name: "Win32 Hello" |
||||
# original-filename: "win32-hello.exe" |
||||
|
||||
sources: |
||||
- hello-win.php |
||||
- ./cpp-src |
||||
|
||||
@ -0,0 +1,25 @@ |
||||
{ |
||||
"name": "compiler", |
||||
"version": "1.0.0", |
||||
"description": "- 需要 PHP-8.2 以上版本 - 需要 GCC-9 以上版本,支持 C++17 标准 - 需要 CMake-3.24 以上版本", |
||||
"main": "index.js", |
||||
"directories": { |
||||
"doc": "docs", |
||||
"example": "examples", |
||||
"test": "tests" |
||||
}, |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "git@git.code-galaxy.net:aot/compiler.git" |
||||
}, |
||||
"keywords": [], |
||||
"author": "", |
||||
"license": "ISC", |
||||
"type": "commonjs", |
||||
"dependencies": { |
||||
"sharp": "^0.34.5" |
||||
} |
||||
} |
||||
@ -0,0 +1,147 @@ |
||||
/** |
||||
* SVG → ICO 转换脚本 (Node.js) |
||||
*
|
||||
* 使用 sharp 库将 SVG 渲染为多尺寸 PNG,再合并为 ICO |
||||
*
|
||||
* 用法: node svg-to-ico.js <input.svg> [output.ico] |
||||
*/ |
||||
|
||||
const sharp = require('sharp'); |
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
|
||||
const sizes = [16, 32, 48, 64, 128, 256]; |
||||
|
||||
async function main() { |
||||
const args = process.argv.slice(2); |
||||
if (args.length < 1) { |
||||
console.log('用法: node svg-to-ico.js <input.svg> [output.ico]'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const inputSvg = path.resolve(args[0]); |
||||
const outputIco = args.length >= 2
|
||||
? path.resolve(args[1])
|
||||
: path.join(path.dirname(inputSvg), path.basename(inputSvg, '.svg') + '.ico'); |
||||
|
||||
if (!fs.existsSync(inputSvg)) { |
||||
console.log(`错误: SVG 文件不存在: ${inputSvg}`); |
||||
process.exit(1); |
||||
} |
||||
|
||||
console.log('=== SVG → ICO 转换工具 ===\n'); |
||||
console.log(`输入: ${inputSvg}`); |
||||
console.log(`输出: ${outputIco}\n`); |
||||
|
||||
const svgBuffer = fs.readFileSync(inputSvg); |
||||
|
||||
// 步骤1: 渲染 SVG 为多个尺寸的 PNG
|
||||
const pngBuffers = {}; |
||||
for (const size of sizes) { |
||||
console.log(`[1/2] 渲染 SVG → PNG (${size}x${size})...`); |
||||
try { |
||||
const pngBuffer = await sharp(svgBuffer, { density: 300 }) |
||||
.resize(size, size, { fit: 'contain', background: { r: 255, g: 255, b: 255, alpha: 1 } }) |
||||
.png() |
||||
.toBuffer(); |
||||
pngBuffers[size] = pngBuffer; |
||||
console.log(` 完成: ${size}x${size} (${pngBuffer.length} bytes)`); |
||||
} catch (err) { |
||||
console.log(` 警告: ${size}x${size} PNG 生成失败: ${err.message},跳过`); |
||||
} |
||||
} |
||||
|
||||
const validSizes = Object.keys(pngBuffers).map(Number).sort((a, b) => a - b); |
||||
if (validSizes.length === 0) { |
||||
console.log('\n错误: 所有尺寸的 PNG 都生成失败'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
// 步骤2: 合并为 ICO
|
||||
console.log('\n[2/2] 合并 PNG → ICO...'); |
||||
const icoBuffer = createIcoFromPngs(pngBuffers, validSizes); |
||||
fs.writeFileSync(outputIco, icoBuffer); |
||||
|
||||
console.log(`\n成功! ICO 文件已生成: ${outputIco}`); |
||||
console.log(`包含尺寸: ${validSizes.join(', ')}`); |
||||
console.log(`文件大小: ${icoBuffer.length} bytes`); |
||||
} |
||||
|
||||
/** |
||||
* 将多个 PNG buffer 合并为 ICO 格式的 Buffer |
||||
*/ |
||||
function createIcoFromPngs(pngBuffers, sizes) { |
||||
const imageCount = sizes.length; |
||||
|
||||
// 计算各部分大小
|
||||
const headerSize = 6; // ICO 头部
|
||||
const dirEntrySize = 16; // 每个目录条目
|
||||
const dirSize = dirEntrySize * imageCount; |
||||
|
||||
let dataOffset = headerSize + dirSize; |
||||
|
||||
// 构建目录条目
|
||||
const dirEntries = []; |
||||
for (const size of sizes) { |
||||
const pngData = pngBuffers[size]; |
||||
const dataSize = pngData.length; |
||||
|
||||
// Width/Height: 0 表示 256
|
||||
const w = size >= 256 ? 0 : size; |
||||
const h = size >= 256 ? 0 : size; |
||||
|
||||
dirEntries.push({ |
||||
width: w, |
||||
height: h, |
||||
colorCount: 0, |
||||
reserved: 0, |
||||
planes: 1, |
||||
bitCount: 32, |
||||
dataSize: dataSize, |
||||
offset: dataOffset |
||||
}); |
||||
|
||||
dataOffset += dataSize; |
||||
} |
||||
|
||||
// 计算总大小
|
||||
let totalSize = headerSize + dirSize; |
||||
for (const size of sizes) { |
||||
totalSize += pngBuffers[size].length; |
||||
} |
||||
|
||||
// 构建 ICO 二进制数据
|
||||
const buffer = Buffer.alloc(totalSize); |
||||
let pos = 0; |
||||
|
||||
// ICO 头部 (6 bytes)
|
||||
buffer.writeUInt16LE(0, pos); pos += 2; // Reserved
|
||||
buffer.writeUInt16LE(1, pos); pos += 2; // Type: 1 = ICO
|
||||
buffer.writeUInt16LE(imageCount, pos); pos += 2; // Image count
|
||||
|
||||
// 目录条目
|
||||
for (const entry of dirEntries) { |
||||
buffer.writeUInt8(entry.width, pos); pos += 1; |
||||
buffer.writeUInt8(entry.height, pos); pos += 1; |
||||
buffer.writeUInt8(entry.colorCount, pos); pos += 1; |
||||
buffer.writeUInt8(entry.reserved, pos); pos += 1; |
||||
buffer.writeUInt16LE(entry.planes, pos); pos += 2; |
||||
buffer.writeUInt16LE(entry.bitCount, pos); pos += 2; |
||||
buffer.writeUInt32LE(entry.dataSize, pos); pos += 4; |
||||
buffer.writeUInt32LE(entry.offset, pos); pos += 4; |
||||
} |
||||
|
||||
// 图像数据
|
||||
for (const size of sizes) { |
||||
const pngData = pngBuffers[size]; |
||||
pngData.copy(buffer, pos); |
||||
pos += pngData.length; |
||||
} |
||||
|
||||
return buffer; |
||||
} |
||||
|
||||
main().catch(err => { |
||||
console.error('错误:', err); |
||||
process.exit(1); |
||||
}); |
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
@ -1 +1 @@ |
||||
1049 |
||||
1051 |
||||
Loading…
Reference in new issue