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 } }); } }