@@ -10,6 +10,7 @@ import PDFFont from 'src/api/PDFFont';
1010import PDFImage from 'src/api/PDFImage' ;
1111import PDFPage from 'src/api/PDFPage' ;
1212import PDFForm from 'src/api/form/PDFForm' ;
13+ import PDFSeparation from 'src/api/PDFSeparation' ;
1314import { PageSizes } from 'src/api/sizes' ;
1415import { StandardFonts } from 'src/api/StandardFonts' ;
1516import {
@@ -33,6 +34,7 @@ import {
3334 PDFWriter ,
3435 PngEmbedder ,
3536 StandardFontEmbedder ,
37+ SeparationEmbedder ,
3638 UnexpectedObjectTypeError ,
3739} from 'src/core' ;
3840import {
@@ -61,11 +63,13 @@ import {
6163 pluckIndices ,
6264 range ,
6365 toUint8Array ,
66+ error ,
6467} from 'src/utils' ;
6568import FileEmbedder , { AFRelationship } from 'src/core/embedders/FileEmbedder' ;
6669import PDFEmbeddedFile from 'src/api/PDFEmbeddedFile' ;
6770import PDFJavaScript from 'src/api/PDFJavaScript' ;
6871import JavaScriptEmbedder from 'src/core/embedders/JavaScriptEmbedder' ;
72+ import { Color , ColorTypes , colorToComponents } from './colors' ;
6973
7074/**
7175 * Represents a PDF document.
@@ -185,6 +189,7 @@ export default class PDFDocument {
185189 private readonly formCache : Cache < PDFForm > ;
186190 private readonly fonts : PDFFont [ ] ;
187191 private readonly images : PDFImage [ ] ;
192+ private readonly separationColorSpaces : PDFSeparation [ ] ;
188193 private readonly embeddedPages : PDFEmbeddedPage [ ] ;
189194 private readonly embeddedFiles : PDFEmbeddedFile [ ] ;
190195 private readonly javaScripts : PDFJavaScript [ ] ;
@@ -206,6 +211,7 @@ export default class PDFDocument {
206211 this . formCache = Cache . populatedBy ( this . getOrCreateForm ) ;
207212 this . fonts = [ ] ;
208213 this . images = [ ] ;
214+ this . separationColorSpaces = [ ] ;
209215 this . embeddedPages = [ ] ;
210216 this . embeddedFiles = [ ] ;
211217 this . javaScripts = [ ] ;
@@ -997,6 +1003,32 @@ export default class PDFDocument {
9971003 return pdfFont ;
9981004 }
9991005
1006+ /**
1007+ * Embed a separation color space into this document.
1008+ * For example:
1009+ * ```js
1010+ * import { rgb } from 'pdf-lib'
1011+ * const separation = pdfDoc.embedSeparation('PANTONE 123 C', rgb(1, 0, 0))
1012+ * ```
1013+ *
1014+ * @param name The name of the separation color space.
1015+ * @param alternate An alternate color to be used to approximate the intended
1016+ * color.
1017+ */
1018+ embedSeparation ( name : string , alternate : Color ) : PDFSeparation {
1019+ const ref = this . context . nextRef ( ) ;
1020+ const alternateColorSpace = getColorSpace ( alternate ) ;
1021+ const alternateColorComponents = colorToComponents ( alternate ) ;
1022+ const embedder = SeparationEmbedder . for (
1023+ name ,
1024+ alternateColorSpace ,
1025+ alternateColorComponents ,
1026+ ) ;
1027+ const separation = PDFSeparation . of ( ref , this , embedder ) ;
1028+ this . separationColorSpaces . push ( separation ) ;
1029+ return separation ;
1030+ }
1031+
10001032 /**
10011033 * Embed a JPEG image into this document. The input data can be provided in
10021034 * multiple formats:
@@ -1243,6 +1275,7 @@ export default class PDFDocument {
12431275 async flush ( ) : Promise < void > {
12441276 await this . embedAll ( this . fonts ) ;
12451277 await this . embedAll ( this . images ) ;
1278+ await this . embedAll ( this . separationColorSpaces ) ;
12461279 await this . embedAll ( this . embeddedPages ) ;
12471280 await this . embedAll ( this . embeddedFiles ) ;
12481281 await this . embedAll ( this . javaScripts ) ;
@@ -1393,3 +1426,10 @@ function assertIsLiteralOrHexString(
13931426 throw new UnexpectedObjectTypeError ( [ PDFHexString , PDFString ] , pdfObject ) ;
13941427 }
13951428}
1429+
1430+ // prettier-ignore
1431+ const getColorSpace = ( color : Color ) =>
1432+ color . type === ColorTypes . Grayscale ? 'DeviceGray'
1433+ : color . type === ColorTypes . RGB ? 'DeviceRGB'
1434+ : color . type === ColorTypes . CMYK ? 'DeviceCMYK'
1435+ : error ( `Invalid alternate color: ${ JSON . stringify ( color ) } ` ) ;
0 commit comments