文件
mynode/packages/lib/services/interop/xpsToPngPowerShellScript.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

124 行
3.9 KiB
TypeScript

// cspell:ignore isnot Pbgra
const xpsToPngPowerShellScript = String.raw`
$ErrorActionPreference = 'Stop'
# Load the WPF assemblies that expose XpsDocument and bitmap rendering APIs.
$assemblies = @(
'PresentationCore',
'PresentationFramework',
'ReachFramework',
'System.Xaml',
'WindowsBase'
)
foreach ($assembly in $assemblies) {
Add-Type -AssemblyName $assembly
}
# Compile the C# renderer once for this PowerShell process.
Add-Type -ReferencedAssemblies $assemblies -TypeDefinition @"
using System;
using System.IO;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Xps.Packaging;
namespace Joplin {
public static class XpsConverter {
private const double MaxRenderedPixels = 16000000;
public static void RenderPages(string inputPath, int[] pageNumbers, string[] outputPaths, double scale) {
if (String.IsNullOrEmpty(inputPath)) {
throw new ArgumentException("Missing input path.", "inputPath");
}
if (pageNumbers == null) {
throw new ArgumentNullException("pageNumbers");
}
if (outputPaths == null) {
throw new ArgumentNullException("outputPaths");
}
if (pageNumbers.Length != outputPaths.Length) {
throw new ArgumentException("Page numbers and output paths must have the same length.");
}
using (XpsDocument document = new XpsDocument(inputPath, FileAccess.Read)) {
FixedDocumentSequence sequence = document.GetFixedDocumentSequence();
DocumentPaginator paginator = sequence.DocumentPaginator;
for (int i = 0; i < pageNumbers.Length; i++) {
RenderPage(paginator, pageNumbers[i], outputPaths[i], scale);
}
}
}
private static void RenderPage(DocumentPaginator paginator, int pageNumber, string outputPath, double scale) {
if (String.IsNullOrEmpty(outputPath)) {
throw new ArgumentException("Missing output path.", "outputPath");
}
if (pageNumber < 1) {
throw new ArgumentOutOfRangeException("pageNumber");
}
int pageIndex = pageNumber - 1;
DocumentPage page = paginator.GetPage(pageIndex);
try {
Size pageSize = page.Size;
double renderScale = scale;
double unscaledPixels = pageSize.Width * pageSize.Height;
if (unscaledPixels * renderScale * renderScale > MaxRenderedPixels) {
renderScale = Math.Sqrt(MaxRenderedPixels / unscaledPixels);
}
int pixelWidth = Math.Max(1, (int)Math.Ceiling(pageSize.Width * renderScale));
int pixelHeight = Math.Max(1, (int)Math.Ceiling(pageSize.Height * renderScale));
DrawingVisual visual = new DrawingVisual();
using (DrawingContext context = visual.RenderOpen()) {
context.DrawRectangle(Brushes.White, null, new Rect(new Point(0, 0), pageSize));
context.PushTransform(new ScaleTransform(renderScale, renderScale));
context.DrawRectangle(new VisualBrush(page.Visual), null, new Rect(new Point(0, 0), pageSize));
context.Pop();
}
RenderTargetBitmap bitmap = new RenderTargetBitmap(pixelWidth, pixelHeight, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(visual);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (FileStream stream = new FileStream(outputPath, FileMode.Create, FileAccess.Write)) {
encoder.Save(stream);
}
} finally {
page.Dispose();
}
}
}
}
"@
# The TypeScript side passes page/output pairs as JSON in a file. This avoids
# environment variable size limits for large printouts with many pages.
$pages = Get-Content -LiteralPath $env:JOPLIN_XPS_PAGES_FILE -Raw | ConvertFrom-Json
if ($pages -isnot [array]) {
$pages = @($pages)
}
$pageNumbers = New-Object 'int[]' $pages.Count
$outputPaths = New-Object 'string[]' $pages.Count
for ($i = 0; $i -lt $pages.Count; $i++) {
$pageNumbers[$i] = [int]$pages[$i].PageNumber
$outputPaths[$i] = [string]$pages[$i].OutputPath
}
[Joplin.XpsConverter]::RenderPages($env:JOPLIN_XPS_INPUT, $pageNumbers, $outputPaths, 2.0)
`;
export default xpsToPngPowerShellScript;