Skip to content

Commit

Permalink
Add support for 'evenodd' fill rule
Browse files Browse the repository at this point in the history
  • Loading branch information
MatheusrdSantos authored and Sharcoux committed Nov 9, 2023
1 parent 0698125 commit cf1d601
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/api/PDFPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
translate,
LineCapStyle,
scale,
FillRule,
} from './operators';
import PDFDocument from './PDFDocument';
import PDFEmbeddedPage from './PDFEmbeddedPage';
Expand Down Expand Up @@ -1240,6 +1241,7 @@ export default class PDFPage {
1,
);
assertIsOneOfOrUndefined(options.blendMode, 'options.blendMode', BlendMode);
assertIsOneOfOrUndefined(options.fillRule, 'options.fillRule', FillRule);

const graphicsStateKey = this.maybeEmbedGraphicsState({
opacity: options.opacity,
Expand All @@ -1265,6 +1267,7 @@ export default class PDFPage {
borderDashPhase: options.borderDashPhase ?? undefined,
borderLineCap: options.borderLineCap ?? undefined,
graphicsState: graphicsStateKey,
fillRule: options.fillRule,
}),
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/api/PDFPageOptions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Color } from './colors';
import PDFFont from './PDFFont';
import { Rotation } from './rotations';
import { LineCapStyle } from './operators';
import { FillRule, LineCapStyle } from './operators';

export enum BlendMode {
Normal = 'Normal',
Expand Down Expand Up @@ -74,6 +74,7 @@ export interface PDFPageDrawSVGOptions {
borderDashPhase?: number;
borderLineCap?: LineCapStyle;
blendMode?: BlendMode;
fillRule?: FillRule
}

export interface PDFPageDrawLineOptions {
Expand Down
5 changes: 4 additions & 1 deletion src/api/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import {
clip,
endPath,
appendBezierCurve,
FillRule,
fillEvenOdd,
} from './operators';
import { Rotation, degrees, toRadians } from './rotations';
import { svgPathToOperators } from './svgPath';
Expand Down Expand Up @@ -348,6 +350,7 @@ export const drawSvgPath = (
borderDashPhase?: number | PDFNumber;
borderLineCap?: LineCapStyle;
graphicsState?: string | PDFName;
fillRule?: FillRule
},
) =>
[
Expand All @@ -369,7 +372,7 @@ export const drawSvgPath = (

// prettier-ignore
options.color && options.borderWidth ? fillAndStroke()
: options.color ? fill()
: options.color ? options.fillRule === FillRule.EvenOdd ? fillEvenOdd() : fill()
: options.borderColor ? stroke()
: closePath(),

Expand Down
7 changes: 7 additions & 0 deletions src/api/operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,15 @@ export const square = (xPos: number, yPos: number, size: number) =>

export const stroke = () => PDFOperator.of(Ops.StrokePath);

export enum FillRule {
NonZero = 'f',
EvenOdd = 'f*'
}

export const fill = () => PDFOperator.of(Ops.FillNonZero);

export const fillEvenOdd = () => PDFOperator.of(Ops.FillEvenOdd);

export const fillAndStroke = () => PDFOperator.of(Ops.FillNonZeroAndStroke);

export const endPath = () => PDFOperator.of(Ops.EndPath);
Expand Down
15 changes: 14 additions & 1 deletion src/api/svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import PDFFont from './PDFFont';
import PDFPage from './PDFPage';
import { PDFPageDrawSVGElementOptions } from './PDFPageOptions';
import { LineCapStyle, LineJoinStyle } from './operators';
import { LineCapStyle, LineJoinStyle, FillRule } from './operators';
import { Rectangle, Point, Segment, Ellipse } from '../utils/elements';
import { getIntersections } from '../utils/intersections';
import { distanceCoords, isEqual, distance, rotate } from '../utils/maths';
Expand Down Expand Up @@ -49,6 +49,7 @@ type InheritedAttributes = {
strokeWidth?: number;
strokeOpacity?: number;
strokeLineCap?: LineCapStyle;
fillRule?: FillRule;
strokeLineJoin?: LineJoinStyle;
fontFamily?: string;
fontStyle?: string;
Expand Down Expand Up @@ -119,6 +120,11 @@ const StrokeLineCapMap: Record<string, LineCapStyle> = {
square: LineCapStyle.Projecting,
};

const FillRuleMap: Record<string, FillRule> = {
evenodd: FillRule.EvenOdd,
nonzero: FillRule.NonZero
};

const StrokeLineJoinMap: Record<string, LineJoinStyle> = {
bevel: LineJoinStyle.Bevel,
miter: LineJoinStyle.Miter,
Expand Down Expand Up @@ -754,6 +760,7 @@ const runnersToPage = (
opacity: element.svgAttributes.fillOpacity,
scale: element.svgAttributes.scale,
rotate: element.svgAttributes.rotate,
fillRule: element.svgAttributes.fillRule,
});
},
async image(element) {
Expand Down Expand Up @@ -977,6 +984,11 @@ const parseAttributes = (
style,
'stroke-linejoin',
);
const fillRuleRaw = styleOrAttribute(
attributes,
style,
'fill-rule',
);
const strokeWidthRaw = styleOrAttribute(attributes, style, 'stroke-width');
const fontFamilyRaw = styleOrAttribute(attributes, style, 'font-family');
const fontStyleRaw = styleOrAttribute(attributes, style, 'font-style');
Expand Down Expand Up @@ -1005,6 +1017,7 @@ const parseAttributes = (
fillOpacity:
parseFloatValue(fillOpacityRaw || opacityRaw || fillRaw?.alpha) ??
inherited.fillOpacity,
fillRule: FillRuleMap[fillRuleRaw] || inherited.fillRule,
stroke: strokeRaw?.rgb || inherited.stroke,
strokeWidth: parseFloatValue(strokeWidthRaw) ?? inherited.strokeWidth,
strokeOpacity:
Expand Down

0 comments on commit cf1d601

Please sign in to comment.