Inmersión en la arquitectura
TCPDF-Next está organizado en 26 módulos a través de 4 paquetes, con 213 archivos fuente PHP en total.
Resumen de la arquitectura
graph TB
subgraph Core["Core (yeeefang/tcpdf-next)"]
Doc[Document] --> Font[FontRegistry]
Doc --> Img[ImageRegistry]
Doc --> Sec[SecurityEngine]
Doc --> Bar[BarcodeEngine]
end
subgraph Extensions["Extensions"]
Art["Artisan<br/>Chrome CDP"] -->|HTML→PDF| Doc
Pro["Pro<br/>PAdES B-LTA"] -->|Signing| Sec
end
subgraph Frameworks["Frameworks"]
Lara["Laravel 12"] -->|Facade| Doc
Sym["Symfony 7"] -->|Bundle| Doc
CI["CodeIgniter 4"] -->|Service| Doc
end
Adapt["Adaptation<br/>Legacy API"] -.->|Compat Layer| DocEstadísticas del proyecto
| Métrica | Core | Laravel | Artisan | Pro | Total |
|---|---|---|---|---|---|
| Archivos fuente PHP | 148 | 4 | 17 | 47 | 213 |
| Módulos | 16 | 1 | 2 | 7 | 26 |
| Tests | 908 | — | 7 clases | — | 908+ |
| Aserciones | 28,881 | — | — | — | 28,881+ |
| Nivel PHPStan | 10 | 10 | 10 | 10 | 10 |
Mapa de namespaces
Core (yeeefang/tcpdf-next)
Yeeefang\TcpdfNext\
├── Core\ # Document, ObjectRegistry, TransactionManager, CrossReferenceStream
│ └── Concerns\ # 12 traits componibles (HasMetadata, HasPages, ...)
├── Contracts\ # PdfDocumentInterface, SignerInterface, HsmSignerInterface, enums
├── ValueObjects\ # PageSize, Dimension, Margin, Position, Unit
├── Support\ # BinaryBuffer
├── Content\ # TextRenderer, JavaScriptManager, Hyphenator
│ └── Hyphenation\ # HyphenationPatterns
├── Typography\ # FontManager, TrueTypeParser, Type1Parser, FontSubsetter, BiDiResolver
├── Graphics\ # DrawingEngine, TransformEngine, Color, ImageLoader, SvgParser
├── Layout\ # HeaderFooter, ColumnLayout, BookletLayout, PageManager
├── Html\ # HtmlParser, TableParser, CssRule
├── Form\ # FormFieldManager, FormFlattener
├── Barcode\ # Barcode1D, Barcode2D, BarcodeRenderer
│ ├── QrCode\ # QrEncoder
│ ├── DataMatrix\ # DataMatrixEncoder
│ └── Pdf417\ # Pdf417Encoder
├── Navigation\ # BookmarkManager, LinkManager, TocBuilder, AnnotationManager
├── Accessibility\ # StructureTree, RoleMap, StructureElement
├── Security\ # Encryption + Signatures
│ ├── Encryption\ # Aes256Encryptor, SaslPrep
│ ├── Signature\ # DigitalSigner, PadesOrchestrator, CertificateInfo, SignatureAppearance
│ └── Timestamp\ # TsaClient
└── Writer\ # PdfWriter, Linearizer, ViewerPreferences, data classesArtisan (yeeefang/tcpdf-next-artisan)
Yeeefang\TcpdfNext\
├── Artisan\ # ChromeHtmlRenderer, BrowserPool, ChromeRendererConfig
│ └── Exception\ # ChromeNotAvailableException, ChromeRenderException, PdfParseException
└── Parser\ # PdfTokenizer, CrossRefParser, PdfReader, StreamDecoder, ResourceCollectorLaravel (yeeefang/tcpdf-next-laravel)
Yeeefang\TcpdfNext\Laravel\
├── TcpdfServiceProvider
├── Facades\Pdf
├── Http\PdfResponse
└── Jobs\GeneratePdfJobPro (yeeefang/tcpdf-next-pro)
Yeeefang\TcpdfNext\
├── Archive\ # PdfAManager, PdfAVersion, XmpMetadata, OutputIntent
├── Barcode\ # Códigos de barras especializados
│ ├── MicroQr\ # MicroQrEncoder
│ ├── DotCode\ # DotCodeEncoder
│ ├── HanXin\ # HanXinEncoder
│ ├── JabCode\ # JabCodeEncoder (LDPC, interleaver, matrix)
│ ├── Gs1\ # Gs1DataParser
│ └── Imb\ # ImbEncoder
├── Security\
│ ├── Ltv\ # LtvManager, DssBuilder, OcspClient, CrlFetcher, CertificateChainValidator
│ ├── Signature\Hsm\ # Pkcs11Signer, OpenSslEngineSigner
│ ├── Timestamp\ # DocumentTimestamp
│ ├── Asn1\ # CertificateParser, AlgorithmIdentifier
│ └── CertificateTransparency\ # CtValidationResult
└── Writer\ # IncrementalUpdateWriterInicialización lazy
La clase Document instancia solo los sub-motores esenciales en el constructor:
Siempre inicializados: DocumentData, PdfWriter, FontManager, DrawingEngine, TransformEngine, TextRenderer, HeaderFooter, ColumnLayout, BookmarkManager, LinkManager, TocBuilder, AnnotationManager, PageManager, FontMetrics
Lazy (null hasta primer uso): FormFieldManager, LayerManager, TemplateManager, TransactionManager, BookletLayout, FileAttachment, JavaScriptManager, SvgParser, EpsParser, StructureTree, SpotColorManager, ImageLoader, BiDiResolver
Esto mantiene la huella de memoria base pequeña para documentos simples mientras proporciona funcionalidad completa cuando se necesita.
Integración de extensiones
El paquete Core detecta extensiones en tiempo de ejecución via class_exists():
// Detección de Artisan
$rendererClass = 'Yeeefang\\TcpdfNext\\Artisan\\ChromeHtmlRenderer';
if (!class_exists($rendererClass)) {
throw new \RuntimeException(
'Chrome renderer requires yeeefang/tcpdf-next-artisan.'
);
}Esto significa:
- Core tiene cero dependencias duras en Artisan, Laravel o Pro
- Las extensiones se autocargan por Composer — solo
composer requirey funcionan - El ServiceProvider de Laravel auto-detecta Artisan y Pro, configurando los bindings correspondientes