Files
CGW-Printing/RUST_TRANSFORMATION_FLOWS.md
T

263 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.