|
| 1 | +import type { ContentStream } from '@ralfstx/pdf-core'; |
| 2 | + |
| 3 | +export type ColorType = 'Grayscale' | 'RGB' | 'CMYK'; |
| 4 | + |
| 5 | +export type Grayscale = { |
| 6 | + type: 'Grayscale'; |
| 7 | + gray: number; |
| 8 | +}; |
| 9 | + |
| 10 | +export type RGB = { |
| 11 | + type: 'RGB'; |
| 12 | + red: number; |
| 13 | + green: number; |
| 14 | + blue: number; |
| 15 | +}; |
| 16 | + |
| 17 | +export type CMYK = { |
| 18 | + type: 'CMYK'; |
| 19 | + cyan: number; |
| 20 | + magenta: number; |
| 21 | + yellow: number; |
| 22 | + key: number; |
| 23 | +}; |
| 24 | + |
| 25 | +export type Color = Grayscale | RGB | CMYK; |
| 26 | + |
| 27 | +export const grayscale = (gray: number): Grayscale => { |
| 28 | + assertRange(gray, 'gray', 0.0, 1.0); |
| 29 | + return { type: 'Grayscale', gray }; |
| 30 | +}; |
| 31 | + |
| 32 | +export const rgb = (red: number, green: number, blue: number): RGB => { |
| 33 | + assertRange(red, 'red', 0, 1); |
| 34 | + assertRange(green, 'green', 0, 1); |
| 35 | + assertRange(blue, 'blue', 0, 1); |
| 36 | + return { type: 'RGB', red, green, blue }; |
| 37 | +}; |
| 38 | + |
| 39 | +export const cmyk = (cyan: number, magenta: number, yellow: number, key: number): CMYK => { |
| 40 | + assertRange(cyan, 'cyan', 0, 1); |
| 41 | + assertRange(magenta, 'magenta', 0, 1); |
| 42 | + assertRange(yellow, 'yellow', 0, 1); |
| 43 | + assertRange(key, 'key', 0, 1); |
| 44 | + return { type: 'CMYK', cyan, magenta, yellow, key }; |
| 45 | +}; |
| 46 | + |
| 47 | +export function setFillingColor(cs: ContentStream, color: Color): void { |
| 48 | + if (color.type === 'Grayscale') { |
| 49 | + cs.setFillGray(color.gray); |
| 50 | + } else if (color.type === 'RGB') { |
| 51 | + cs.setFillRGB(color.red, color.green, color.blue); |
| 52 | + } else if (color.type === 'CMYK') { |
| 53 | + cs.setFillCMYK(color.cyan, color.magenta, color.yellow, color.key); |
| 54 | + } else throw new Error(`Invalid color: ${JSON.stringify(color)}`); |
| 55 | +} |
| 56 | + |
| 57 | +export function setStrokingColor(cs: ContentStream, color: Color): void { |
| 58 | + if (color.type === 'Grayscale') { |
| 59 | + cs.setStrokeGray(color.gray); |
| 60 | + } else if (color.type === 'RGB') { |
| 61 | + cs.setStrokeRGB(color.red, color.green, color.blue); |
| 62 | + } else if (color.type === 'CMYK') { |
| 63 | + cs.setStrokeCMYK(color.cyan, color.magenta, color.yellow, color.key); |
| 64 | + } else throw new Error(`Invalid color: ${JSON.stringify(color)}`); |
| 65 | +} |
| 66 | + |
| 67 | +function assertRange(value: number, valueName: string, min: number, max: number) { |
| 68 | + if (typeof value !== 'number' || value < min || value > max) { |
| 69 | + throw new Error(`${valueName} must be a number between ${min} and ${max}, got: ${value}`); |
| 70 | + } |
| 71 | +} |
0 commit comments