161 lines
5.0 KiB
JavaScript
161 lines
5.0 KiB
JavaScript
import { colorManager } from "@/components/setting/color";
|
||
import { increaseBrightness, isLightColorTheme, lowerBrightness, MacroColor, parseColor } from "@/hook/color";
|
||
import { globalLookup } from "@/hook/global";
|
||
import { pinkLog } from "@/hook/utils";
|
||
import axios from 'axios';
|
||
import pako from 'pako';
|
||
|
||
export const mode = window.acquireVsCodeApi === undefined ? 'debug' : 'release';
|
||
pinkLog('digital-netlist-render mode: ' + mode);
|
||
|
||
export let vscode = window.acquireVsCodeApi === undefined ? undefined : acquireVsCodeApi();
|
||
|
||
function getColorFromMacro(rootStyles, optionName, theme, isLight) {
|
||
if (theme === 'dark') {
|
||
return rootStyles.getPropertyValue(optionName);
|
||
} else {
|
||
// 亮色模式,pdf 类型的导出一定是这个颜色,
|
||
// 此时需要对特殊的几类颜色进行处理
|
||
// 如果此时的颜色主题本来就是偏亮色的,直接返回如下几个的颜色
|
||
|
||
switch (optionName) {
|
||
case '--foreground':
|
||
case '--wire-color':
|
||
case '--cross-dot-color':
|
||
if (!isLight) {
|
||
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})`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param {import("@/hook/color").GetColorOption} option
|
||
* @returns
|
||
*/
|
||
function makeStyleString(option = {}) {
|
||
// 加入全局颜色宏
|
||
const colorMacros = [];
|
||
const macroColor = new MacroColor({
|
||
BaseForegroundColorMacroName: '--foreground',
|
||
BaseBackgroundColorMacroName: '--background'
|
||
});
|
||
|
||
for (const item of colorManager.generals) {
|
||
const colorOption = `--${item.type}-color`;
|
||
const colorFillOption = `--${item.type}-fill-color`;
|
||
|
||
const color = macroColor.getColor(colorOption, option);
|
||
const colorFill = macroColor.getColor(colorFillOption, option);
|
||
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 = macroColor.getColor(colorOption, option);
|
||
const colorFill = macroColor.getColor(colorFillOption, option);
|
||
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 = macroColor.getColor(setting, option);
|
||
if (color) {
|
||
colorMacros.push(`${setting}: ${color};`);
|
||
}
|
||
}
|
||
|
||
const styleString = `:root {\n${colorMacros.join('\n')}\n}`;
|
||
return styleString;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param {import("@/hook/color").GetColorOption} option
|
||
* @returns
|
||
*/
|
||
function getCompressedSvgBuffer(option = {}) {
|
||
const selection = globalLookup.netlistRender.selection;
|
||
const node = selection.node();
|
||
|
||
const styleString = makeStyleString(option);
|
||
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() {
|
||
const svgBuffer = getCompressedSvgBuffer({ mode: 'pdf' });
|
||
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 }
|
||
});
|
||
}
|
||
} |