完成 netlist 保存
This commit is contained in:
parent
5d579ba82a
commit
b21502526e
6
package-lock.json
generated
6
package-lock.json
generated
@ -16,6 +16,7 @@
|
|||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-i18n": "10.0.5",
|
"vue-i18n": "10.0.5",
|
||||||
"web-worker": "^1.3.0"
|
"web-worker": "^1.3.0"
|
||||||
@ -8768,6 +8769,11 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
||||||
|
},
|
||||||
"node_modules/param-case": {
|
"node_modules/param-case": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
|
"pako": "^2.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-i18n": "10.0.5",
|
"vue-i18n": "10.0.5",
|
||||||
"web-worker": "^1.3.0"
|
"web-worker": "^1.3.0"
|
||||||
|
129
src/api/index.js
129
src/api/index.js
@ -1,16 +1,141 @@
|
|||||||
|
import { colorManager } from "@/components/setting/color";
|
||||||
|
import { increaseBrightness, lowerBrightness, parseColor } from "@/hook/color";
|
||||||
import { globalLookup } from "@/hook/global";
|
import { globalLookup } from "@/hook/global";
|
||||||
import { pinkLog } from "@/hook/utils";
|
import { pinkLog } from "@/hook/utils";
|
||||||
|
import axios from 'axios';
|
||||||
|
import pako from 'pako';
|
||||||
|
|
||||||
const mode = window.acquireVsCodeApi === undefined ? 'debug' : 'release';
|
const mode = window.acquireVsCodeApi === undefined ? 'debug' : 'release';
|
||||||
pinkLog('digital-netlist-render mode: ' + mode);
|
pinkLog('digital-netlist-render mode: ' + mode);
|
||||||
|
|
||||||
let vscode = window.acquireVsCodeApi === undefined ? undefined : acquireVsCodeApi();
|
let vscode = window.acquireVsCodeApi === undefined ? undefined : acquireVsCodeApi();
|
||||||
|
|
||||||
export async function saveAsSvg() {
|
function getColorFromMacro(rootStyles, optionName, theme) {
|
||||||
const selection = globalLookup.netlistRender.selection;
|
if (theme === 'dark') {
|
||||||
|
return rootStyles.getPropertyValue(optionName);
|
||||||
|
} else {
|
||||||
|
switch (optionName) {
|
||||||
|
case '--foreground':
|
||||||
|
case '--wire-color':
|
||||||
|
case '--cross-dot-color':
|
||||||
|
return '#2D323B';
|
||||||
|
}
|
||||||
|
const color = rootStyles.getPropertyValue(optionName);
|
||||||
|
if (!color) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
const rgb = parseColor(color);
|
||||||
|
const { r, g, b } = increaseBrightness(rgb, 10);
|
||||||
|
return `rgb(${r}, ${g}, ${b})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeStyleString(config = {}) {
|
||||||
|
const theme = config.theme || 'dark';
|
||||||
|
// 加入全局颜色宏
|
||||||
|
const colorMacros = [];
|
||||||
|
const rootStyles = getComputedStyle(document.documentElement);
|
||||||
|
|
||||||
|
for (const item of colorManager.generals) {
|
||||||
|
const colorOption = `--${item.type}-color`;
|
||||||
|
const colorFillOption = `--${item.type}-fill-color`;
|
||||||
|
|
||||||
|
const color = getColorFromMacro(rootStyles, colorOption, theme);
|
||||||
|
const colorFill = getColorFromMacro(rootStyles, colorFillOption, theme);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${colorOption}: ${color};`);
|
||||||
|
}
|
||||||
|
if (colorFill) {
|
||||||
|
colorMacros.push(`${colorFillOption}: ${colorFill};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of colorManager.cells) {
|
||||||
|
const colorOption = `--${item.type}-color`;
|
||||||
|
const colorFillOption = `--${item.type}-fill-color`;
|
||||||
|
|
||||||
|
const color = getColorFromMacro(rootStyles, colorOption, theme);
|
||||||
|
const colorFill = getColorFromMacro(rootStyles, colorFillOption, theme);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${colorOption}: ${color};`);
|
||||||
|
}
|
||||||
|
if (colorFill) {
|
||||||
|
colorMacros.push(`${colorFillOption}: ${colorFill};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalSetting = [
|
||||||
|
'--foreground',
|
||||||
|
'--background',
|
||||||
|
'--main-color'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const setting of globalSetting) {
|
||||||
|
const color = getColorFromMacro(rootStyles, setting, theme);
|
||||||
|
if (color) {
|
||||||
|
colorMacros.push(`${setting}: ${color};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const styleString = `:root {\n${colorMacros.join('\n')}\n}`;
|
||||||
|
return styleString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompressedSvgBuffer(config = {}) {
|
||||||
|
const selection = globalLookup.netlistRender.selection;
|
||||||
|
const node = selection.node();
|
||||||
|
|
||||||
|
const styleString = makeStyleString(config);
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = styleString;
|
||||||
|
node.insertBefore(style, node.firstChild);
|
||||||
|
|
||||||
|
const serializer = new XMLSerializer();
|
||||||
|
const svgString = serializer.serializeToString(node);
|
||||||
|
const array = pako.gzip(svgString);
|
||||||
|
|
||||||
|
// 还原
|
||||||
|
const styleElement = node.querySelector('style');
|
||||||
|
if (styleElement) {
|
||||||
|
styleElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveAsSvg() {
|
||||||
|
const svgBuffer = getCompressedSvgBuffer();
|
||||||
|
const moduleName = globalLookup.topModuleName;
|
||||||
|
if (mode === 'debug') {
|
||||||
|
const res = await axios.post('http://localhost:3000/netlist/save-as-svg', { svgBuffer, moduleName });
|
||||||
|
if (res.success) {
|
||||||
|
pinkLog('成功保存到”' + res.savePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vscode.postMessage({
|
||||||
|
command: 'save-as-svg',
|
||||||
|
data: { svgBuffer, moduleName }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveAsPdf() {
|
export async function saveAsPdf() {
|
||||||
|
const svgBuffer = getCompressedSvgBuffer({ theme: 'light' });
|
||||||
|
const moduleName = globalLookup.topModuleName;
|
||||||
|
|
||||||
|
const node = globalLookup.netlistRender.selection.node();
|
||||||
|
const width = node.getAttribute('width');
|
||||||
|
const height = node.getAttribute('height');
|
||||||
|
|
||||||
|
if (mode === 'debug') {
|
||||||
|
const res = await axios.post('http://localhost:3000/netlist/save-as-pdf', { svgBuffer, moduleName, width, height });
|
||||||
|
if (res.success) {
|
||||||
|
pinkLog('成功保存到”' + res.savePath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vscode.postMessage({
|
||||||
|
command: 'save-as-pdf',
|
||||||
|
data: { svgBuffer, moduleName, width, height }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,7 +3,7 @@
|
|||||||
<div class="status"></div>
|
<div class="status"></div>
|
||||||
<div class="item" @click="manualLoadView()">
|
<div class="item" @click="manualLoadView()">
|
||||||
<span>{{ t('toolbar.save-as-svg') }}</span>
|
<span>{{ t('toolbar.save-as-svg') }}</span>
|
||||||
<span></span>
|
<span><code>Shift S</code></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -29,11 +29,11 @@ async function manualLoadView() {
|
|||||||
loading.close();
|
loading.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// document.addEventListener('keydown', async event => {
|
document.addEventListener('keydown', async event => {
|
||||||
// if (event.ctrlKey && event.key === 'k') {
|
if (event.ctrlKey && event.key === 's') {
|
||||||
// event.preventDefault();
|
event.preventDefault();
|
||||||
// manualLoadView();
|
manualLoadView();
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
@ -68,6 +68,28 @@ export function increaseBrightness(rgb, percent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 降低颜色的亮度
|
||||||
|
* @param {RgbColor} rgb
|
||||||
|
* @param {number} percent 0 - 100 的数字,代表增强的亮度比例
|
||||||
|
* @returns {RgbColor}
|
||||||
|
*/
|
||||||
|
export function lowerBrightness(rgb, percent) {
|
||||||
|
// 确保 percent 在 0 到 100 之间
|
||||||
|
percent = Math.max(0, Math.min(100, percent));
|
||||||
|
|
||||||
|
// 计算每个颜色分量的增量
|
||||||
|
const increment = (percent / 100) * 255;
|
||||||
|
|
||||||
|
// 提升每个颜色分量的亮度
|
||||||
|
const r = Math.min(255, Math.round(rgb.r - increment));
|
||||||
|
const g = Math.min(255, Math.round(rgb.g - increment));
|
||||||
|
const b = Math.min(255, Math.round(rgb.b - increment));
|
||||||
|
|
||||||
|
return { r, g, b };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description gamma 修正
|
* @description gamma 修正
|
||||||
* @param {number} c 颜色通道值,取值范围为 0 - 255
|
* @param {number} c 颜色通道值,取值范围为 0 - 255
|
||||||
|
Loading…
x
Reference in New Issue
Block a user