This library is built with Clean Architecture principles, using SOLID design patterns and dependency injection for maintainability and testability.
- Interfaces: Defines contracts (
IPrinter,IPrinterManager) - Types: Enums and type definitions (PrintQuality, PaperSize, DuplexMode, etc.)
- Logger: Structured logging system with multiple levels and performance timers
- Log levels: DEBUG, INFO, WARN, ERROR, SILENT
- Context-based logging for better traceability
- Automatic environment detection (test/production)
- Performance measurement with
startTimer()/endTimer()
- Windows Adapter: Windows GDI implementation
- Services: Specialized services for different printing aspects
PdfRenderService- PDF rendering with PDFium + intelligent cachingDevModeConfigService- DEVMODE structure configuration and validationPrintDialogService- Native Windows print dialog integrationPrinterCapabilitiesService- Query printer features and capabilities
The Graphics Device Interface (GDI) is the core Windows API for rendering graphics and managing printing.
Key Functions:
CreateDCW- Create Device Context with printer settingsStartDocW- Initialize print jobStartPage- Begin new pageStretchDIBits- Transfer bitmap to printer with scalingEndPage- Complete pageEndDoc- Finalize print jobDeleteDC- Release Device Context
Windows Print Spooler manages print jobs and printer configuration.
Key Functions:
EnumPrintersW- List all system printersGetDefaultPrinterW- Get default printer nameOpenPrinterW- Open printer for configurationDocumentPropertiesW- Get/set DEVMODE settingsClosePrinter- Close printer handle
System-level error reporting and memory management.
Key Functions:
GetLastError- Retrieve last error codeFormatMessageW- Convert error codes to human-readable messagesGlobalLock/GlobalUnlock- Memory management for DEVMODE
Windows common dialogs library for native UI.
Key Functions:
PrintDlgW- Display native Windows print dialogPageSetupDlgW- Display page setup dialog (future feature)
Google's high-performance PDF rendering library.
Key Functions:
FPDF_InitLibrary- Initialize PDFium libraryFPDF_LoadMemDocument- Load PDF from memory bufferFPDF_GetPageCount- Get number of pagesFPDF_LoadPage- Load specific pageFPDF_RenderPageBitmap- Render page to bitmap at specified DPIFPDFBitmap_Create- Create bitmap bufferFPDFBitmap_Destroy- Free bitmap memoryFPDF_ClosePage- Close page handleFPDF_CloseDocument- Close PDF document
-
Initialization
PDFPrinter constructor ├─> Get/validate printer name └─> Initialize WindowsPrinterAdapter -
PDF Loading
print(pdfPath, options) ├─> Read PDF file to Buffer ├─> FPDF_LoadMemDocument └─> FPDF_GetPageCount -
Configuration
DevModeConfigService ├─> OpenPrinterW (open printer handle) ├─> DocumentPropertiesW (get default DEVMODE size) ├─> DocumentPropertiesW (get current DEVMODE) ├─> Apply print options: │ ├─> Quality (DPI) │ ├─> Duplex mode │ ├─> Paper size │ ├─> Orientation │ ├─> Paper tray │ └─> Copies/Collate ├─> DocumentPropertiesW (validate with driver) └─> CreateDCW with configured DEVMODE -
Rendering & Printing
Print Dialog (optional): └─> PrintDlgW (shows native dialog, returns DC if confirmed) Cache Strategy: ├─> If copies > 1 && !collate: disable cache (prevent GDI corruption) └─> Otherwise: use cache for performance For each copy (respecting collate setting): For each page: ├─> PdfRenderService.renderPage │ ├─> Check cache (if enabled) │ ├─> FPDF_LoadPage │ ├─> FPDFBitmap_Create (BGRA format) │ ├─> FPDFBitmap_FillRect (white background) │ ├─> FPDF_RenderPageBitmap (with FPDF_PRINTING flag) │ ├─> Cache bitmap (if enabled) │ └─> Return bitmap data + metadata ├─> StartPage ├─> StretchDIBits (scale & transfer bitmap) ├─> EndPage └─> Cleanup rendered page (destroy bitmap if not cached) Restore cache state -
Cleanup
├─> EndDoc ├─> DeleteDC ├─> ClosePrinter └─> FPDF_CloseDocument
The DEVMODE structure is the heart of Windows printer configuration. It's a complex binary structure that controls all printer settings.
Key Fields:
dmFields- Bitmask indicating which fields are validdmOrientation- DMORIENT_PORTRAIT (1) or DMORIENT_LANDSCAPE (2)dmPaperSize- Paper size constant (e.g., DMPAPER_A4 = 9)dmPrintQuality- DPI for X resolutiondmYResolution- DPI for Y resolutiondmColor- DMCOLOR_MONOCHROME (1) or DMCOLOR_COLOR (2)dmDuplex- DMDUP_SIMPLEX (1), DMDUP_HORIZONTAL (2), DMDUP_VERTICAL (3)dmCopies- Number of copies (1-9999)dmDefaultSource- Paper tray/sourcedmCollate- DMCOLLATE_FALSE (0) or DMCOLLATE_TRUE (1)
The library implements smart caching to optimize performance while avoiding GDI issues:
class PdfRenderService {
private pageCache = new Map<string, RenderedPage>();
private cacheEnabled = true;
renderPage(pageIndex: number, options: RenderOptions): RenderedPage {
const cacheKey = `${pageIndex}_${options.width}_${options.height}`;
// Check cache if enabled
if (this.cacheEnabled && this.pageCache.has(cacheKey)) {
return this.pageCache.get(cacheKey)!;
}
// Render page
const renderedPage = this.renderPageInternal(pageIndex, options);
// Cache if enabled
if (this.cacheEnabled) {
this.pageCache.set(cacheKey, renderedPage);
}
return renderedPage;
}
}Cache Strategy:
- Enabled by default for collated printing and single copies
- Automatically disabled for multiple copies without collate
- Prevents GDI buffer corruption when same bitmap is reused consecutively
- Each copy gets a fresh bitmap render
- Manual control via
printer.setCacheEnabled(false)for batch printing different PDFs - Automatic cleanup when PDF document is closed
Benefits:
- Up to 3x faster for multiple collated copies
- Prevents memory buildup in sequential printing
- Avoids GDI corruption with uncollated multi-copy jobs
- Consistent print quality
- Bitmap lifecycle: Created, used, destroyed immediately (or cached)
- PDFium singleton: Reference counting for shared library instance
- Resource cleanup: All resources freed in
finallyblocksFPDFBitmap_Destroy- Free bitmap memoryFPDF_ClosePage- Close page handleFPDF_CloseDocument- Close documentDeleteDC- Release Device ContextClosePrinter- Close printer handle
- Cache management: Cleared when document closes or manually disabled
- No memory leaks: Comprehensive cleanup even on errors
The library uses optimized DPI defaults based on use case:
- 150 DPI (LOW): Draft quality, ~2x faster than medium
- 300 DPI (MEDIUM): Optimal balance for documents (default)
- 600 DPI (HIGH): High quality for images, ~3.3x slower than medium
Performance Impact:
- Rendering time scales quadratically with DPI (4x pixels = 4x time)
- Memory usage scales quadratically with DPI
- Printer DPI is independent (handled by driver)
- Use aspect-ratio-aware scaling to avoid distortion
const logger = createLogger({ context: 'PdfRender' });
const timer = logger.startTimer('renderPage');
// ... operation ...
logger.endTimer(timer); // Automatically logs durationFeatures:
- Zero-cost when disabled (SILENT level in production)
- Automatic timing measurements
- Context-based filtering
- Color-coded console output with timestamps
Errors are captured at multiple levels:
-
Windows API Errors
const result = gdi32.StartDocW(hdc, docInfo); if (result <= 0) { const error = kernel32.GetLastError(); const message = formatWindowsError(error); throw new Error(`StartDocW failed: ${message}`); }
-
PDFium Errors
const doc = pdfium.FPDF_LoadMemDocument(buffer, buffer.length, null); if (doc === null) { throw new Error('Failed to load PDF document'); }
-
Service-Level Validation
if (!printerExists(printerName)) { throw new Error(`Printer "${printerName}" not found`); }
- Service classes with mocked dependencies
- Isolated testing of each service component
- Test coverage for error conditions
- Real printer interaction (requires configured printer)
- Full printing workflow validation
- Cross-service integration testing
- Benchmark different quality settings
- Memory leak detection
- Comparison with baseline results
Services receive dependencies through constructors:
class WindowsPrinterAdapter {
constructor(
private devModeService: DevModeConfigService,
private pdfRenderService: PdfRenderService,
private capabilitiesService: PrinterCapabilitiesService
) {}
}Specialized services handle specific concerns:
DevModeConfigService- ConfigurationPdfRenderService- RenderingPrintDialogService- User interactionPrinterCapabilitiesService- Feature detection
Clean interfaces define contracts:
IPrinter- Core printing operationsIPrinterManager- Printer discoveryPrintOptions- Configuration options
- Page range selection (programmatic)
- Print preview generation
- Printer status monitoring
- Job queue management
For more information, see the main README.