Add printer-config integration and Rust transformation flow docs
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
# Rust Content Transformation Flows
|
||||
|
||||
This document describes the content transformation steps performed by the Rust CLI (`cgwprint`) that need to be ported to the C# PrintService.
|
||||
|
||||
## Configuration Overview
|
||||
|
||||
Each job type is defined in `printers.json` under the `process` section with the following possible properties:
|
||||
|
||||
- **label**: Display name for the job type
|
||||
- **line_padding**: Left margin/indent for all lines (in units)
|
||||
- **remove_ord_num**: Remove both "Order #: " label and the order number entirely
|
||||
- **remove_ord_num_label**: Remove "Order #: " label but keep the order number (and make it bold)
|
||||
- **indent_ord_num**: Add spacing before the order number (shifts it right)
|
||||
- **row_shift**: Dictionary of line numbers → vertical adjustment (in 1/100 inch units)
|
||||
- **row_trim**: Dictionary of line numbers → {start, end} (removes characters from start to end)
|
||||
- **printer**: Array of printer/tray assignments
|
||||
|
||||
## Universal Transformation Flow (All Job Types)
|
||||
|
||||
Every document goes through this sequence:
|
||||
|
||||
### Step 1: File Reading & Page Splitting
|
||||
- Read entire file content as string
|
||||
- Split content by **form-feed character** (`\x0C` / ASCII 12)
|
||||
- Filter out empty pages
|
||||
- Each page becomes an array of lines
|
||||
|
||||
### Step 2: Font Code Normalization (Pre-processing)
|
||||
- Prefix entire content with `\x1Bw0` (ensure normal font at start)
|
||||
- Replace `\x1BW1` → `\x1Bw1` (normalize uppercase W to lowercase)
|
||||
- Replace `\x1BW0` → `\x1Bw0` (normalize uppercase W to lowercase)
|
||||
- Deduplicate consecutive `\x1Bw1` sequences → single `\x1Bw1`
|
||||
- Deduplicate consecutive `\x1Bw0` sequences → single `\x1Bw0`
|
||||
|
||||
### Step 3: Order Number Manipulation (If order number provided)
|
||||
**Note:** Only ONE of these operations executes per job based on configuration flags.
|
||||
|
||||
**3a. Remove Order Number Label** (if `remove_ord_num_label: true`)
|
||||
- Find: `"Order #: {ordnum}"`
|
||||
- Replace with: `" \x1Bw1{ordnum}\x1Bw0"` (spaces equal to "Order #: " length + bold order number)
|
||||
|
||||
**3b. Remove Order Number Completely** (if `remove_ord_num: true`)
|
||||
- Find: `"Order #: {ordnum}"`
|
||||
- Replace with: spaces equal to the entire string length
|
||||
|
||||
**3c. Indent Order Number** (if `indent_ord_num` is not empty)
|
||||
- Find: `\x1Bw1{ordnum}\x1Bw0` (regex search)
|
||||
- Replace with: `{indent_ord_num}\x1Bw1{ordnum}\x1Bw0`
|
||||
|
||||
### Step 4: Font Code Replacement
|
||||
Replace ESC sequences with actual PCL font commands from printer configuration:
|
||||
|
||||
- `\x1Bw1` → Bold font PCL code (e.g., `\x1B(0N\x1B(s0p5h0s3b4099T`)
|
||||
- `\x1Bw0` → Normal font PCL code (e.g., `\x1B(0N\x1B(s0p10h0s0b4099T`)
|
||||
|
||||
### Step 5: Process All Hex Escapes
|
||||
Convert remaining `\xHH` escape sequences to actual bytes throughout content.
|
||||
|
||||
### Step 6: Page Layout Construction
|
||||
For each original page, for each assigned tray:
|
||||
|
||||
**6a. Tray Selection**
|
||||
- Insert PCL tray selection code (e.g., `\x1B&l4H` for tray 1)
|
||||
|
||||
**6b. Line-by-Line Rendering**
|
||||
For each line (index = `pos_v`) in the page:
|
||||
|
||||
1. **Check for Row Shift** (Vertical positioning adjustment)
|
||||
- If `row_shift["{pos_v}"]` exists, add adjustment to cumulative `line_spacing`
|
||||
- Example: `row_shift["7"]: -200` means line 7 moves UP 200 units (negative = up, positive = down)
|
||||
- This allows overlaying text or changing vertical line order
|
||||
|
||||
2. **Check for Row Trim** (Horizontal character manipulation)
|
||||
- If `row_trim["{pos_v}"]` exists:
|
||||
- Extract substring: `line[0..start] + line[end..]` (removes characters from start to end)
|
||||
- Use trimmed line for rendering
|
||||
- Example: `row_trim["8"]: {start: 0, end: 65}` removes first 65 characters
|
||||
- This is used to add/remove horizontal spacing or adjust text positions on a line
|
||||
|
||||
3. **Position Cursor & Write Line**
|
||||
- Insert PCL positioning: `\x1B&a{line_padding}h{vertical_position}V`
|
||||
- `vertical_position = (pos_v × spacing) + line_spacing`
|
||||
- `spacing` = printer's spacing value (100 or 150 = 1/100 inch per line)
|
||||
- Append the line content
|
||||
**Note:** The Rust implementation wraps content with PCL/PJL commands because it sends raw data via TCP socket. The C# implementation uses Windows printer drivers, so **most of these commands may not be needed**. We'll need to test what's actually required.
|
||||
|
||||
**7a. Header (based on PCL version from printer config) - MAY NOT BE NEEDED IN C#**
|
||||
```
|
||||
\x1B%-12345X // PCL mode enter
|
||||
@PJL ENTER LANGUAGE=PCL6 // PJL language (if PCL 6)
|
||||
@PJL SET RENDERMODE=GRAYSCALE // PJL grayscale (if PCL 6)
|
||||
@PJL SET RESOLUTION=600 // PJL resolution (if PCL 6)
|
||||
\x1B&l0O // Portrait orientation (if PCL 6)
|
||||
{content here}
|
||||
```
|
||||
|
||||
**7b. Footer - MAY NOT BE NEEDED IN C#**
|
||||
```
|
||||
\x1B%-12345X // PCL mode exit
|
||||
```
|
||||
|
||||
### Step 8: Send to Printer
|
||||
**Rust approach:** Raw TCP socket to printer IP:port 9100
|
||||
**C# approach:** Windows PrintDocument API with Graphics renderingket to printer IP:port (typically 9100)
|
||||
- Send raw bytes
|
||||
- Close socket
|
||||
|
||||
---
|
||||
|
||||
## Job Type Specific Examples
|
||||
|
||||
### **DELIVERY**
|
||||
```json
|
||||
{
|
||||
"label": "Delivery",
|
||||
"indent_ord_num": " ", // Shift order number right 4 spaces
|
||||
"line_padding": 10, // 10 units left margin
|
||||
"printer": [{
|
||||
"name": "HL-L6415DW",
|
||||
"tray": [3, 2] // Print to tray 3, then tray 2
|
||||
}],
|
||||
"row_shift": {
|
||||
"0": 625, // Move line 0 down 625 units
|
||||
"7": -200, // Move line 7 up 200 units
|
||||
"8": -100, // Move line 8 up 100 units
|
||||
"14": 100, // Move line 14 down 100 units
|
||||
"19": 172 // Move line 19 down 172 units
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Transformations Applied:**
|
||||
- Order number gets 4 spaces prepended
|
||||
- Specific lines get vertical position adjustments
|
||||
- Each page prints twice (tray 3, then tray 2)
|
||||
|
||||
---
|
||||
|
||||
### **INVOICE**
|
||||
```json
|
||||
{
|
||||
"label": "Invoice",
|
||||
"remove_ord_num": true, // Remove "Order #: 12345" entirely
|
||||
"line_padding": 10,
|
||||
"printer": [
|
||||
{
|
||||
"name": "HL-L6415DW",
|
||||
"tray": [2, 4, 5] // 3 copies on different trays
|
||||
},
|
||||
{
|
||||
"name": "SAVIN-100",
|
||||
"tray": [1] // Additional copy on different printer
|
||||
}
|
||||
],
|
||||
"row_shift": {
|
||||
"0": 625,
|
||||
"7": -200,
|
||||
"8": -100,
|
||||
"14": 100,
|
||||
"19": 172
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Transformations Applied:**
|
||||
- "Order #: 12345" → " " (spaces)
|
||||
- Same row shifts as delivery
|
||||
- Prints 4 times total: HL-L6415DW tray 2, 4, 5, then SAVIN tray 1
|
||||
|
||||
---
|
||||
|
||||
### **PRE-BILL**
|
||||
```json
|
||||
{
|
||||
"label": "Pre-bill",
|
||||
"remove_ord_num": false,
|
||||
"remove_ord_num_label": true, // Keep number but remove label
|
||||
"indent_ord_num": "",
|
||||
"line_padding": 4,
|
||||
"printer": [{
|
||||
"name": "HP-LJP4001",
|
||||
"tray": [1]
|
||||
}],
|
||||
"row_shift": {
|
||||
"8": -2000, // Major upward shift for line 8
|
||||
"12": 1550 // Major downward shift for line 12
|
||||
},
|
||||
"row_trim": {
|
||||
"8": {
|
||||
"start": 0,
|
||||
"end": 65 // Remove chars 0-65 from line 8
|
||||
},
|
||||
"12": {
|
||||
"start": 0,
|
||||
"end": 6 // Remove chars 0-6 from line 12
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Transformations Applied:**
|
||||
- "Order #: 12345" → " **12345**" (bold number, no label)
|
||||
- Line 8: Characters 0-65 removed, positioned -2000 units (major upward shift)
|
||||
- Line 12: Characters 0-6 removed, positioned +1550 units (major downward shift)
|
||||
|
||||
---
|
||||
|
||||
### **PRODUCTION** / **ORDERDESK** / **BACKORDER** / **GOLDEN** / etc.
|
||||
Similar patterns with variations in:
|
||||
- Order number handling
|
||||
- Line padding amounts
|
||||
- Tray assignments
|
||||
- Row shift values (some have none)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Coordinate System
|
||||
- Horizontal: `\x1B&a{H}h{V}V` where H = horizontal position (1/300 inch), V = vertical (1/300 inch)
|
||||
- `line_padding` = left margin in 1/300 inch units
|
||||
- `spacing` = line height in 1/100 inch units (100 or 150)
|
||||
- `row_shift` = vertical adjustment in 1/100 inch units
|
||||
|
||||
### Font Codes
|
||||
Fonts are printer-specific PCL sequences. Example for HL-L6415DW:
|
||||
- **Normal**: `\x1B(0N\x1B(s0p10h0s0b4099T`
|
||||
- **Bold**: `\x1B(0N\x1B(s0p5h0s3b4099T`
|
||||
|
||||
### Tray Codes
|
||||
Tray selection uses PCL commands. Example for HL-L6415DW:
|
||||
- Tray 1: `\x1B&l4H`
|
||||
- Tray 2: `\x1B&l5H`
|
||||
- Tray 3: `\x1B&l8H`
|
||||
- Tray 4: `\x1B&l9H`
|
||||
- Tray 5: `\x1B&l10H`
|
||||
|
||||
### Multi-Printer Jobs
|
||||
When multiple printers are specified (like Invoice), the entire transformation process runs separately for each printer with its own font codes, tray codes, and PCL version.
|
||||
|
||||
---
|
||||
|
||||
## Questions for Review
|
||||
|
||||
1. Answers to Review Questions
|
||||
|
||||
1. **Order of Operations**: ✅ Only ONE order number manipulation happens per job based on flags, so order doesn't matter.
|
||||
|
||||
2. **Row Shift vs Row Trim**: ✅ Independent operations:
|
||||
- **Row Shift**: Vertical movement (up/down on page) - changes line order or overlays
|
||||
- **Row Trim**: Horizontal character manipulation (add/remove spacing or characters)
|
||||
|
||||
3. **Tray Duplication Pattern**: ✅ Current C# approach is CORRECT:
|
||||
- Page 1 → Tray 1, Tray 4, Tray 5, Tray 2
|
||||
- Page 2 → Tray 1, Tray 4, Tray 5, Tray 2
|
||||
- This maintains carbon copy layer order
|
||||
- **Future consideration**: Add optional flag to change tray ordering per job type
|
||||
|
||||
4. **Empty Row Shift/Trim**: ✅ Skip if not present in configuration.
|
||||
|
||||
5. **Hex Escape Timing**: ⚠️ May not be needed in C# since we use Windows drivers instead of raw PCL. Test to determine what's actually required.
|
||||
|
||||
6. **Multiple Printers**: ✅ Either sequential or parallel is fine, just maintain page order within each printer.
|
||||
Reference in New Issue
Block a user