Built test page for testing tray output for debugging in main app.
This commit is contained in:
@@ -12,11 +12,16 @@ public class PrinterService
|
||||
{
|
||||
private readonly AppSettings _settings;
|
||||
private readonly ILogger<PrinterService> _logger;
|
||||
private readonly ContentTransformer _transformer;
|
||||
|
||||
public PrinterService(IOptions<AppSettings> settings, ILogger<PrinterService> logger)
|
||||
public PrinterService(
|
||||
IOptions<AppSettings> settings,
|
||||
ILogger<PrinterService> logger,
|
||||
ContentTransformer transformer)
|
||||
{
|
||||
_settings = settings.Value;
|
||||
_logger = logger;
|
||||
_transformer = transformer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -24,16 +29,18 @@ public class PrinterService
|
||||
/// 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, DocumentTypeConfig config, string originalFileName)
|
||||
public void Print(string content, DocumentTypeConfig config, string originalFileName, string? orderNumber = null)
|
||||
{
|
||||
if (config.Pages.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No pages/trays defined for document type");
|
||||
}
|
||||
|
||||
var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
|
||||
// Transform content according to Rust CLI logic
|
||||
var transformed = _transformer.TransformContent(content, config, orderNumber);
|
||||
|
||||
var linesPerPage = CalculateLinesPerPage(config.FontSize);
|
||||
var totalOriginalPages = Math.Max(1, (int)Math.Ceiling(lines.Length / (double)linesPerPage));
|
||||
var totalOriginalPages = Math.Max(1, (int)Math.Ceiling(transformed.Lines.Count / (double)linesPerPage));
|
||||
var originalPageIndex = 0;
|
||||
var copyIndex = 0; // index into config.Pages (one entry per tray copy)
|
||||
|
||||
@@ -44,7 +51,10 @@ public class PrinterService
|
||||
|
||||
var printDoc = new PrintDocument
|
||||
{
|
||||
PrinterSettings = { PrinterName = primaryPrinterName }
|
||||
PrinterSettings = {
|
||||
PrinterName = primaryPrinterName,
|
||||
Duplex = Duplex.Simplex // Force single-sided printing (no duplexing)
|
||||
}
|
||||
};
|
||||
|
||||
// Handle PDF output if using Microsoft Print to PDF
|
||||
@@ -67,9 +77,10 @@ public class PrinterService
|
||||
throw new InvalidOperationException($"Printer '{primaryPrinterName}' not found");
|
||||
}
|
||||
|
||||
printDoc.PrintPage += (sender, e) =>
|
||||
// QueryPageSettings fires BEFORE PrintPage - set tray here
|
||||
printDoc.QueryPageSettings += (sender, e) =>
|
||||
{
|
||||
if (e.Graphics == null || e.PageSettings == null)
|
||||
if (e.PageSettings == null)
|
||||
return;
|
||||
|
||||
var pageConfig = config.Pages[copyIndex];
|
||||
@@ -96,9 +107,15 @@ public class PrinterService
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to set tray {Tray}, using default", pageConfig.TrayNumber);
|
||||
}
|
||||
};
|
||||
|
||||
printDoc.PrintPage += (sender, e) =>
|
||||
{
|
||||
if (e.Graphics == null)
|
||||
return;
|
||||
|
||||
// Render the same original page for every copy before moving to next original page.
|
||||
RenderPage(e.Graphics, lines, originalPageIndex * linesPerPage, linesPerPage,
|
||||
RenderPage(e.Graphics, transformed, originalPageIndex * linesPerPage, linesPerPage,
|
||||
config.FontName, config.FontSize, config.HorizontalOffset, config.VerticalOffset);
|
||||
|
||||
copyIndex++;
|
||||
@@ -122,28 +139,70 @@ public class PrinterService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Render page content using Graphics API
|
||||
/// Render page content using Graphics API with styled text and transformations
|
||||
/// </summary>
|
||||
private void RenderPage(Graphics graphics, string[] lines, int startLine, int linesPerPage,
|
||||
private void RenderPage(Graphics graphics, TransformedDocument transformed, int startLine, int linesPerPage,
|
||||
string fontName, float fontSize, int horizontalOffset, int verticalOffset)
|
||||
{
|
||||
var font = new Font(fontName, fontSize);
|
||||
var normalFont = new Font(fontName, fontSize, System.Drawing.FontStyle.Regular);
|
||||
var boldFont = new Font(fontName, fontSize, System.Drawing.FontStyle.Bold);
|
||||
var brush = Brushes.Black;
|
||||
var lineHeight = font.GetHeight(graphics);
|
||||
var lineHeight = normalFont.GetHeight(graphics);
|
||||
|
||||
var x = (float)horizontalOffset;
|
||||
var y = (float)verticalOffset;
|
||||
// Convert line padding from 1/100 inch to pixels (assuming 96 DPI for screen, but printers use their own DPI)
|
||||
// For printers, Graphics.DpiX will give the actual printer DPI
|
||||
var linePaddingPixels = (transformed.LinePadding / 100f) * graphics.DpiX;
|
||||
|
||||
var endLine = Math.Min(startLine + linesPerPage, lines.Length);
|
||||
var endLine = Math.Min(startLine + linesPerPage, transformed.Lines.Count);
|
||||
|
||||
for (int i = startLine; i < endLine; i++)
|
||||
// Track cumulative vertical shift
|
||||
float cumulativeShift = 0;
|
||||
|
||||
for (int lineIndex = startLine; lineIndex < endLine; lineIndex++)
|
||||
{
|
||||
if (i < lines.Length)
|
||||
if (lineIndex >= transformed.Lines.Count)
|
||||
break;
|
||||
|
||||
var styledLine = transformed.Lines[lineIndex];
|
||||
|
||||
// Apply row shift if defined for this line
|
||||
if (transformed.RowShifts.TryGetValue(lineIndex, out var shift))
|
||||
{
|
||||
graphics.DrawString(lines[i], font, brush, x, y);
|
||||
y += lineHeight;
|
||||
// Convert shift from 1/100 inch to pixels
|
||||
var shiftPixels = (shift / 100f) * graphics.DpiY;
|
||||
cumulativeShift += shiftPixels;
|
||||
|
||||
if (_settings.VerboseLogging)
|
||||
{
|
||||
_logger.LogDebug("Line {LineNum}: applying row shift {Shift} units ({Pixels} px)",
|
||||
lineIndex, shift, shiftPixels);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate Y position with offsets and shifts
|
||||
var y = verticalOffset + ((lineIndex - startLine) * lineHeight) + cumulativeShift;
|
||||
|
||||
// Start X position with horizontal offset and line padding
|
||||
var x = (float)horizontalOffset + linePaddingPixels;
|
||||
|
||||
// Render each text segment with appropriate font style
|
||||
foreach (var segment in styledLine.Segments)
|
||||
{
|
||||
var font = segment.Style == Services.FontStyle.Bold ? boldFont : normalFont;
|
||||
|
||||
if (!string.IsNullOrEmpty(segment.Text))
|
||||
{
|
||||
graphics.DrawString(segment.Text, font, brush, x, y);
|
||||
|
||||
// Measure text width to advance X position for next segment
|
||||
var textSize = graphics.MeasureString(segment.Text, font);
|
||||
x += textSize.Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
normalFont.Dispose();
|
||||
boldFont.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user