mirror of
https://github.com/pdfme/pdfme.git
synced 2026-04-19 21:49:03 -04:00
Added support for color type option in generator (#436)
* added support for color type option in generator * remove color type option from playground * use let or const instead of var
This commit is contained in:
committed by
GitHub
parent
2a7ad8b3af
commit
18cf33d037
@@ -21,6 +21,7 @@ import type {
|
||||
Schema,
|
||||
SchemaForUI,
|
||||
Font,
|
||||
ColorType,
|
||||
BasePdf,
|
||||
Template,
|
||||
GeneratorOptions,
|
||||
@@ -82,6 +83,7 @@ export type {
|
||||
Schema,
|
||||
SchemaForUI,
|
||||
Font,
|
||||
ColorType,
|
||||
BasePdf,
|
||||
Template,
|
||||
GeneratorOptions,
|
||||
|
||||
@@ -58,6 +58,8 @@ export const Dict = z.object({
|
||||
});
|
||||
export const Mode = z.enum(['viewer', 'form', 'designer']);
|
||||
|
||||
export const ColorType = z.enum(['rgb', 'cmyk']).optional();
|
||||
|
||||
export const Size = z.object({ height: z.number(), width: z.number() });
|
||||
|
||||
export const Schema = z
|
||||
@@ -113,6 +115,7 @@ const CommonProps = z.object({
|
||||
// -------------------generate-------------------
|
||||
|
||||
export const GeneratorOptions = CommonOptions.extend({
|
||||
colorType: ColorType,
|
||||
author: z.string().optional(),
|
||||
creationDate: z.date().optional(),
|
||||
creator: z.string().optional(),
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
UIProps,
|
||||
PreviewProps,
|
||||
DesignerProps,
|
||||
ColorType,
|
||||
} from './schema.js';
|
||||
|
||||
export type PropPanelSchema = _PropPanelSchema;
|
||||
@@ -158,6 +159,7 @@ export type SchemaForUI = z.infer<typeof SchemaForUI>;
|
||||
* @property {boolean} [subset] - The default is true (use subset font). So if you don't want to use a subset font, please set it to false.
|
||||
*/
|
||||
export type Font = z.infer<typeof Font>;
|
||||
export type ColorType = z.infer<typeof ColorType>;
|
||||
export type BasePdf = z.infer<typeof BasePdf>;
|
||||
export type Template = z.infer<typeof Template>;
|
||||
export type GeneratorOptions = z.infer<typeof GeneratorOptions>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Schema, Plugin, PDFRenderProps, UIRenderProps } from '@pdfme/common';
|
||||
import { rotatePoint, convertForPdfLayoutProps, hex2RgbColor } from '../utils.js';
|
||||
import { rotatePoint, convertForPdfLayoutProps, hex2PrintingColor } from '../utils.js';
|
||||
import { HEX_COLOR_PATTERN } from '../constants.js';
|
||||
|
||||
const DEFAULT_LINE_COLOR = '#000000';
|
||||
@@ -10,7 +10,8 @@ interface LineSchema extends Schema {
|
||||
|
||||
const lineSchema: Plugin<LineSchema> = {
|
||||
pdf: (arg: PDFRenderProps<LineSchema>) => {
|
||||
const { page, schema } = arg;
|
||||
const { page, schema, options } = arg;
|
||||
const { colorType } = options;
|
||||
const pageHeight = page.getHeight();
|
||||
const {
|
||||
width,
|
||||
@@ -24,7 +25,7 @@ const lineSchema: Plugin<LineSchema> = {
|
||||
start: rotatePoint({ x, y: y + height / 2 }, pivot, rotate.angle),
|
||||
end: rotatePoint({ x: x + width, y: y + height / 2 }, pivot, rotate.angle),
|
||||
thickness: height,
|
||||
color: hex2RgbColor(schema.color ?? DEFAULT_LINE_COLOR),
|
||||
color: hex2PrintingColor(schema.color ?? DEFAULT_LINE_COLOR, colorType),
|
||||
opacity: opacity,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Plugin, Schema, mm2pt } from '@pdfme/common';
|
||||
import { HEX_COLOR_PATTERN } from '../constants.js';
|
||||
import { hex2RgbColor, convertForPdfLayoutProps } from '../utils.js';
|
||||
import { hex2PrintingColor, convertForPdfLayoutProps } from '../utils.js';
|
||||
|
||||
interface Shape extends Schema {
|
||||
type: 'ellipse' | 'rectangle';
|
||||
@@ -27,7 +27,8 @@ const shape: Plugin<Shape> = {
|
||||
rootElement.appendChild(div);
|
||||
},
|
||||
pdf: (arg) => {
|
||||
const { schema, page } = arg;
|
||||
const { schema, page, options } = arg;
|
||||
const { colorType } = options;
|
||||
const pageHeight = page.getHeight();
|
||||
const cArg = { schema, pageHeight };
|
||||
const { position, width, height, rotate, opacity } = convertForPdfLayoutProps(cArg);
|
||||
@@ -39,8 +40,8 @@ const shape: Plugin<Shape> = {
|
||||
const drawOptions = {
|
||||
rotate,
|
||||
borderWidth,
|
||||
borderColor: hex2RgbColor(schema.borderColor),
|
||||
color: hex2RgbColor(schema.color),
|
||||
borderColor: hex2PrintingColor(schema.borderColor, colorType),
|
||||
color: hex2PrintingColor(schema.color, colorType),
|
||||
opacity,
|
||||
borderOpacity: opacity,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { PDFFont, PDFDocument } from '@pdfme/pdf-lib';
|
||||
import type { TextSchema, FontWidthCalcValues } from './types';
|
||||
import { PDFRenderProps, Font, getDefaultFont, getFallbackFontName, mm2pt } from '@pdfme/common';
|
||||
import {
|
||||
PDFRenderProps,
|
||||
Font,
|
||||
getDefaultFont,
|
||||
getFallbackFontName,
|
||||
mm2pt,
|
||||
ColorType,
|
||||
} from '@pdfme/common';
|
||||
import {
|
||||
VERTICAL_ALIGN_TOP,
|
||||
VERTICAL_ALIGN_MIDDLE,
|
||||
@@ -20,7 +27,7 @@ import {
|
||||
getSplittedLines,
|
||||
widthOfTextAtSize,
|
||||
} from './helper.js';
|
||||
import { convertForPdfLayoutProps, rotatePoint, hex2RgbColor } from '../utils.js';
|
||||
import { convertForPdfLayoutProps, rotatePoint, hex2PrintingColor } from '../utils.js';
|
||||
|
||||
const embedAndGetFontObj = async (arg: {
|
||||
pdfDoc: PDFDocument;
|
||||
@@ -57,17 +64,19 @@ const getFontProp = async ({
|
||||
value,
|
||||
font,
|
||||
schema,
|
||||
colorType,
|
||||
_cache,
|
||||
}: {
|
||||
value: string;
|
||||
font: Font;
|
||||
colorType?: ColorType;
|
||||
schema: TextSchema;
|
||||
_cache: Map<any, any>;
|
||||
}) => {
|
||||
const fontSize = schema.dynamicFontSize
|
||||
? await calculateDynamicFontSize({ textSchema: schema, font, value, _cache })
|
||||
: schema.fontSize ?? DEFAULT_FONT_SIZE;
|
||||
const color = hex2RgbColor(schema.fontColor || DEFAULT_FONT_COLOR);
|
||||
const color = hex2PrintingColor(schema.fontColor || DEFAULT_FONT_COLOR, colorType);
|
||||
|
||||
return {
|
||||
alignment: schema.alignment ?? DEFAULT_ALIGNMENT,
|
||||
@@ -83,12 +92,12 @@ export const pdfRender = async (arg: PDFRenderProps<TextSchema>) => {
|
||||
const { value, pdfDoc, pdfLib, page, options, schema, _cache } = arg;
|
||||
if (!value) return;
|
||||
|
||||
const { font = getDefaultFont() } = options;
|
||||
const { font = getDefaultFont(), colorType } = options;
|
||||
|
||||
const [pdfFontObj, fontKitFont, fontProp] = await Promise.all([
|
||||
embedAndGetFontObj({ pdfDoc, font, _cache }),
|
||||
getFontKitFont(schema, font, _cache),
|
||||
getFontProp({ value, font, schema, _cache }),
|
||||
getFontProp({ value, font, schema, _cache, colorType }),
|
||||
]);
|
||||
|
||||
const { fontSize, color, alignment, verticalAlignment, lineHeight, characterSpacing } = fontProp;
|
||||
@@ -108,7 +117,7 @@ export const pdfRender = async (arg: PDFRenderProps<TextSchema>) => {
|
||||
} = convertForPdfLayoutProps({ schema, pageHeight, applyRotateTranslate: false });
|
||||
|
||||
if (schema.backgroundColor) {
|
||||
const color = hex2RgbColor(schema.backgroundColor);
|
||||
const color = hex2PrintingColor(schema.backgroundColor, colorType);
|
||||
page.drawRectangle({ x, y, width, height, rotate, color });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as CSS from 'csstype';
|
||||
import { degrees, degreesToRadians, rgb } from '@pdfme/pdf-lib';
|
||||
import { Schema, mm2pt, Mode, isHexValid } from '@pdfme/common';
|
||||
import { cmyk, degrees, degreesToRadians, rgb } from '@pdfme/pdf-lib';
|
||||
import { Schema, mm2pt, Mode, isHexValid, ColorType } from '@pdfme/common';
|
||||
|
||||
export const convertForPdfLayoutProps = ({
|
||||
schema,
|
||||
@@ -103,6 +103,50 @@ export const hex2RgbColor = (hexString: string | undefined) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const hex2CmykColor = (hexString: string | undefined) => {
|
||||
if (hexString) {
|
||||
const isValid = isHexValid(hexString);
|
||||
|
||||
if (!isValid) {
|
||||
throw new Error(`Invalid hex color value ${hexString}`);
|
||||
}
|
||||
|
||||
// Remove the # if it's present
|
||||
hexString = hexString.replace('#', '');
|
||||
|
||||
// Extract the hexadecimal color code and the opacity
|
||||
const hexColor = hexString.substring(0, 6);
|
||||
const opacityColor = hexString.substring(6, 8);
|
||||
const opacity = opacityColor ? parseInt(opacityColor, 16) / 255 : 1;
|
||||
|
||||
// Convert the hex values to decimal
|
||||
let r = parseInt(hexColor.substring(0, 2), 16) / 255;
|
||||
let g = parseInt(hexColor.substring(2, 4), 16) / 255;
|
||||
let b = parseInt(hexColor.substring(4, 6), 16) / 255;
|
||||
|
||||
// Apply the opacity
|
||||
r = r * opacity + (1 - opacity);
|
||||
g = g * opacity + (1 - opacity);
|
||||
b = b * opacity + (1 - opacity);
|
||||
|
||||
// Calculate the CMYK values
|
||||
const k = 1 - Math.max(r, g, b);
|
||||
const c = r === 0 ? 0 : (1 - r - k) / (1 - k);
|
||||
const m = g === 0 ? 0 : (1 - g - k) / (1 - k);
|
||||
const y = b === 0 ? 0 : (1 - b - k) / (1 - k);
|
||||
|
||||
return cmyk(c, m, y, k);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const hex2PrintingColor = (hexString: string | undefined, colorType?: ColorType) => {
|
||||
return colorType?.toLocaleLowerCase() == 'cmyk'
|
||||
? hex2CmykColor(hexString)
|
||||
: hex2RgbColor(hexString);
|
||||
};
|
||||
|
||||
export const readFile = (input: File | FileList | null): Promise<string | ArrayBuffer> =>
|
||||
new Promise((resolve, reject) => {
|
||||
const fileReader = new FileReader();
|
||||
|
||||
Reference in New Issue
Block a user