diff --git a/src/applyparseattributes.ts b/src/applyparseattributes.ts index 24cc7e26..e85a8a03 100644 --- a/src/applyparseattributes.ts +++ b/src/applyparseattributes.ts @@ -308,3 +308,117 @@ export function applyAttributes( ) } } + +export function applyContext(context: Context): void { + const { attributeState, pdf } = context + + let fillOpacity = 1.0, + strokeOpacity = 1.0 + + fillOpacity *= attributeState.fillOpacity + fillOpacity *= attributeState.opacity + if ( + attributeState.fill instanceof ColorFill && + typeof attributeState.fill.color.a !== 'undefined' + ) { + fillOpacity *= attributeState.fill.color.a + } + + strokeOpacity *= attributeState.strokeOpacity + strokeOpacity *= attributeState.opacity + if ( + attributeState.stroke instanceof ColorFill && + typeof attributeState.stroke.color.a !== 'undefined' + ) { + strokeOpacity *= attributeState.stroke.color.a + } + + const gState: GState = {} + gState['opacity'] = fillOpacity + gState['stroke-opacity'] = strokeOpacity + pdf.setGState(new GState(gState)) + + if ( + attributeState.fill && + attributeState.fill instanceof ColorFill && + attributeState.fill.color.ok + ) { + // text fill color will be applied through setTextColor() + pdf.setFillColor( + attributeState.fill.color.r, + attributeState.fill.color.g, + attributeState.fill.color.b + ) + } else { + pdf.setFillColor(0, 0, 0) + } + + pdf.setLineWidth(attributeState.strokeWidth) + + if (attributeState.stroke instanceof ColorFill) { + pdf.setDrawColor( + attributeState.stroke.color.r, + attributeState.stroke.color.g, + attributeState.stroke.color.b + ) + } else { + pdf.setDrawColor(0, 0, 0) + } + + pdf.setLineCap(attributeState.strokeLinecap) + pdf.setLineJoin(attributeState.strokeLinejoin) + + if (attributeState.strokeDasharray) { + pdf.setLineDashPattern(attributeState.strokeDasharray, attributeState.strokeDashoffset) + } else { + pdf.setLineDashPattern([], 0) + } + + pdf.setLineMiterLimit(attributeState.strokeMiterlimit) + + let font: string | undefined + if (fontAliases.hasOwnProperty(attributeState.fontFamily)) { + font = fontAliases[attributeState.fontFamily] + } else { + font = attributeState.fontFamily + } + + if ( + attributeState.fill && + attributeState.fill instanceof ColorFill && + attributeState.fill.color.ok + ) { + const fillColor = attributeState.fill.color + pdf.setTextColor(fillColor.r, fillColor.g, fillColor.b) + } else { + pdf.setTextColor(0, 0, 0) + } + + let fontStyle: string | undefined = '' + if (attributeState.fontWeight === 'bold') { + fontStyle = 'bold' + } + if (attributeState.fontStyle === 'italic') { + fontStyle += 'italic' + } + + if (fontStyle === '') { + fontStyle = 'normal' + } + + if (font !== undefined || fontStyle !== undefined) { + if (font === undefined) { + if (fontAliases.hasOwnProperty(attributeState.fontFamily)) { + font = fontAliases[attributeState.fontFamily] + } else { + font = attributeState.fontFamily + } + } + pdf.setFont(font, fontStyle) + } else { + pdf.setFont('helvetica', fontStyle) + } + + // correct for a jsPDF-instance measurement unit that differs from `pt` + pdf.setFontSize(attributeState.fontSize * pdf.internal.scaleFactor) +} diff --git a/src/markerlist.ts b/src/markerlist.ts index 9959241d..f1c79813 100644 --- a/src/markerlist.ts +++ b/src/markerlist.ts @@ -44,7 +44,6 @@ export class MarkerList { // as the marker is already scaled by the current line width we must not apply the line width twice! context.pdf.saveGraphicsState() - context.pdf.setLineWidth(1.0) await context.refsHandler.getRendered(marker.id, null, node => (node as MarkerNode).apply(context) ) diff --git a/src/nodes/marker.ts b/src/nodes/marker.ts index f2c55f7f..0c894847 100644 --- a/src/nodes/marker.ts +++ b/src/nodes/marker.ts @@ -5,6 +5,7 @@ import { NonRenderedNode } from './nonrenderednode' import { svgNodeAndChildrenVisible } from '../utils/node' import { Rect } from '../utils/geometry' import { Matrix } from 'jspdf' +import { applyContext } from '../applyparseattributes' export class MarkerNode extends NonRenderedNode { async apply(parentContext: Context): Promise { @@ -13,15 +14,23 @@ export class MarkerNode extends NonRenderedNode { const bBox = this.getBoundingBox(parentContext) parentContext.pdf.beginFormObject(bBox[0], bBox[1], bBox[2], bBox[3], tfMatrix) + + const childContext = new Context(parentContext.pdf, { + refsHandler: parentContext.refsHandler, + styleSheets: parentContext.styleSheets, + viewport: parentContext.viewport, + svg2pdfParameters: parentContext.svg2pdfParameters + }) + + // "Properties do not inherit from the element referencing the 'marker' into the contents of the + // marker. However, by using the context-stroke value for the fill or stroke on elements in its + // definition, a single marker can be designed to match the style of the element referencing the + // marker." + // -> we need to reset all attributes + applyContext(childContext) + for (const child of this.children) { - await child.render( - new Context(parentContext.pdf, { - refsHandler: parentContext.refsHandler, - styleSheets: parentContext.styleSheets, - viewport: parentContext.viewport, - svg2pdfParameters: parentContext.svg2pdfParameters - }) - ) + await child.render(childContext) } parentContext.pdf.endFormObject(this.element.getAttribute('id')) } @@ -36,8 +45,8 @@ export class MarkerNode extends NonRenderedNode { return [ (vb && vb[0]) || 0, (vb && vb[1]) || 0, - (vb && vb[2]) || parseFloat(this.element.getAttribute('marker-width') || '0'), - (vb && vb[3]) || parseFloat(this.element.getAttribute('marker-height') || '0') + (vb && vb[2]) || parseFloat(this.element.getAttribute('markerWidth') || '3'), + (vb && vb[3]) || parseFloat(this.element.getAttribute('markerHeight') || '3') ] } diff --git a/test/specs/complete-social-network/reference.pdf b/test/specs/complete-social-network/reference.pdf index e7222aaf..f27feadc 100644 Binary files a/test/specs/complete-social-network/reference.pdf and b/test/specs/complete-social-network/reference.pdf differ diff --git a/test/specs/markers/reference.pdf b/test/specs/markers/reference.pdf index 0e2aa0c0..770c790f 100644 Binary files a/test/specs/markers/reference.pdf and b/test/specs/markers/reference.pdf differ diff --git a/test/specs/markers/spec.svg b/test/specs/markers/spec.svg index c46fa377..139cc414 100644 --- a/test/specs/markers/spec.svg +++ b/test/specs/markers/spec.svg @@ -8,6 +8,9 @@ + + + @@ -31,5 +34,8 @@ - + + + +