Add printer-config integration and Rust transformation flow docs
This commit is contained in:
@@ -20,42 +20,51 @@ public class PrinterService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print document to specified printer with tray sequence
|
||||
/// Print document using the new DocumentTypeConfig (printer-config.json).
|
||||
/// Each PageConfig entry defines one output copy per original content page,
|
||||
/// so a 4-page document with 4 PageConfig entries produces 16 output pages.
|
||||
/// </summary>
|
||||
public void Print(string content, DocumentConfig config, string originalFileName)
|
||||
public void Print(string content, DocumentTypeConfig config, string originalFileName)
|
||||
{
|
||||
if (config.TraySequence.Length == 0)
|
||||
if (config.Pages.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No tray sequence defined for document type");
|
||||
throw new InvalidOperationException("No pages/trays defined for document type");
|
||||
}
|
||||
|
||||
var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
|
||||
var linesPerPage = CalculateLinesPerPage(config);
|
||||
var currentPageIndex = 0;
|
||||
var linesPerPage = CalculateLinesPerPage(config.FontSize);
|
||||
var totalOriginalPages = Math.Max(1, (int)Math.Ceiling(lines.Length / (double)linesPerPage));
|
||||
var originalPageIndex = 0;
|
||||
var copyIndex = 0; // index into config.Pages (one entry per tray copy)
|
||||
|
||||
// All pages within one document type share the same printer in typical use,
|
||||
// but PageConfig supports per-page overrides — use the first page's printer for
|
||||
// the PrintDocument; tray (PaperSource) is set per page in the event handler.
|
||||
var primaryPrinterName = config.Pages[0].PrinterName;
|
||||
|
||||
var printDoc = new PrintDocument
|
||||
{
|
||||
PrinterSettings = { PrinterName = config.PrinterName }
|
||||
PrinterSettings = { PrinterName = primaryPrinterName }
|
||||
};
|
||||
|
||||
// Handle PDF output if using Microsoft Print to PDF
|
||||
if (config.PrinterName.Equals("Microsoft Print to PDF", StringComparison.OrdinalIgnoreCase) &&
|
||||
if (primaryPrinterName.Equals("Microsoft Print to PDF", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.IsNullOrEmpty(config.OutputPath))
|
||||
{
|
||||
Directory.CreateDirectory(config.OutputPath);
|
||||
var pdfFileName = Path.GetFileNameWithoutExtension(originalFileName) + ".pdf";
|
||||
var pdfPath = Path.Combine(config.OutputPath, pdfFileName);
|
||||
|
||||
|
||||
printDoc.PrinterSettings.PrintToFile = true;
|
||||
printDoc.PrinterSettings.PrintFileName = pdfPath;
|
||||
|
||||
|
||||
_logger.LogInformation("PDF will be saved to: {Path}", pdfPath);
|
||||
}
|
||||
|
||||
// Verify printer exists
|
||||
if (!PrinterSettings.InstalledPrinters.Cast<string>().Contains(config.PrinterName))
|
||||
// Verify primary printer exists
|
||||
if (!PrinterSettings.InstalledPrinters.Cast<string>().Contains(primaryPrinterName))
|
||||
{
|
||||
throw new InvalidOperationException($"Printer '{config.PrinterName}' not found");
|
||||
throw new InvalidOperationException($"Printer '{primaryPrinterName}' not found");
|
||||
}
|
||||
|
||||
printDoc.PrintPage += (sender, e) =>
|
||||
@@ -63,52 +72,67 @@ public class PrinterService
|
||||
if (e.Graphics == null || e.PageSettings == null)
|
||||
return;
|
||||
|
||||
// Select tray for current page
|
||||
var trayIndex = config.TraySequence[currentPageIndex % config.TraySequence.Length];
|
||||
|
||||
var pageConfig = config.Pages[copyIndex];
|
||||
|
||||
try
|
||||
{
|
||||
// Map logical tray number to PaperSource
|
||||
var paperSource = GetPaperSource(printDoc.PrinterSettings, trayIndex);
|
||||
var paperSource = GetPaperSource(printDoc.PrinterSettings, pageConfig.TrayNumber);
|
||||
if (paperSource != null)
|
||||
{
|
||||
e.PageSettings.PaperSource = paperSource;
|
||||
if (_settings.VerboseLogging)
|
||||
{
|
||||
_logger.LogDebug("Page {Page}: Using tray {Tray} ({Source})",
|
||||
currentPageIndex + 1, trayIndex, paperSource.SourceName);
|
||||
_logger.LogDebug(
|
||||
"Output page {OutputPage}: original page {OriginalPage}, tray {Tray} ({Label}) ({Source})",
|
||||
(originalPageIndex * config.Pages.Count) + copyIndex + 1,
|
||||
originalPageIndex + 1,
|
||||
pageConfig.TrayNumber,
|
||||
pageConfig.TrayLabel ?? "?",
|
||||
paperSource.SourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to set tray {Tray}, using default", trayIndex);
|
||||
_logger.LogWarning(ex, "Failed to set tray {Tray}, using default", pageConfig.TrayNumber);
|
||||
}
|
||||
|
||||
// Render page content
|
||||
RenderPage(e.Graphics, lines, currentPageIndex * linesPerPage, linesPerPage, config);
|
||||
// Render the same original page for every copy before moving to next original page.
|
||||
RenderPage(e.Graphics, lines, originalPageIndex * linesPerPage, linesPerPage,
|
||||
config.FontName, config.FontSize, config.HorizontalOffset, config.VerticalOffset);
|
||||
|
||||
currentPageIndex++;
|
||||
e.HasMorePages = (currentPageIndex < config.TraySequence.Length);
|
||||
copyIndex++;
|
||||
if (copyIndex >= config.Pages.Count)
|
||||
{
|
||||
copyIndex = 0;
|
||||
originalPageIndex++;
|
||||
}
|
||||
|
||||
e.HasMorePages = originalPageIndex < totalOriginalPages;
|
||||
};
|
||||
|
||||
_logger.LogInformation("Printing to {Printer} with {Pages} pages",
|
||||
config.PrinterName, config.TraySequence.Length);
|
||||
|
||||
_logger.LogInformation(
|
||||
"Printing to {Printer}: {OriginalPages} original page(s) × {Copies} copies = {Total} output pages",
|
||||
primaryPrinterName,
|
||||
totalOriginalPages,
|
||||
config.Pages.Count,
|
||||
totalOriginalPages * config.Pages.Count);
|
||||
|
||||
printDoc.Print();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render page content using Graphics API
|
||||
/// </summary>
|
||||
private void RenderPage(Graphics graphics, string[] lines, int startLine, int linesPerPage, DocumentConfig config)
|
||||
private void RenderPage(Graphics graphics, string[] lines, int startLine, int linesPerPage,
|
||||
string fontName, float fontSize, int horizontalOffset, int verticalOffset)
|
||||
{
|
||||
var font = new Font(config.FontName, config.FontSize);
|
||||
var font = new Font(fontName, fontSize);
|
||||
var brush = Brushes.Black;
|
||||
var lineHeight = font.GetHeight(graphics);
|
||||
|
||||
var x = (float)config.HorizontalOffset;
|
||||
var y = (float)config.VerticalOffset;
|
||||
var x = (float)horizontalOffset;
|
||||
var y = (float)verticalOffset;
|
||||
|
||||
var endLine = Math.Min(startLine + linesPerPage, lines.Length);
|
||||
|
||||
@@ -123,13 +147,12 @@ public class PrinterService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate lines per page based on font and page size
|
||||
/// Calculate lines per page based on font size
|
||||
/// </summary>
|
||||
private int CalculateLinesPerPage(DocumentConfig config)
|
||||
private int CalculateLinesPerPage(float fontSize)
|
||||
{
|
||||
// Estimate: standard letter size is 11 inches, at 10pt font ~66 lines
|
||||
// This is simplified; in production you'd calculate based on actual page dimensions
|
||||
var estimatedLineHeight = config.FontSize * 1.2f; // points
|
||||
var estimatedLineHeight = fontSize * 1.2f; // points
|
||||
var pageHeightInPoints = 11 * 72; // 11 inches * 72 points per inch
|
||||
return (int)Math.Floor(pageHeightInPoints / estimatedLineHeight);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user