Skip to content

Commit 61eb7cc

Browse files
committed
add context2d setLineDash() and lineDashOffset.
1 parent 99d4b95 commit 61eb7cc

File tree

7 files changed

+155
-5
lines changed

7 files changed

+155
-5
lines changed

src/jspdf.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,7 @@ function jsPDF(options) {
20012001
font: font,
20022002
out: out,
20032003
newObject: newObject,
2004-
putStream: putStream,
2004+
putStream: putStream
20052005
});
20062006

20072007
if (font.isAlreadyPutted !== true) {

src/libs/FileSaver.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ var saveAs =
9090
/* noop */
9191
}
9292
: // Use download attribute first if possible (#193 Lumia mobile) unless this is a native app
93-
(typeof HTMLAnchorElement !== "undefined" && "download" in HTMLAnchorElement.prototype)
93+
typeof HTMLAnchorElement !== "undefined" &&
94+
"download" in HTMLAnchorElement.prototype
9495
? function saveAs(blob, name, opts) {
9596
var URL = _global.URL || _global.webkitURL;
9697
var a = document.createElement("a");

src/libs/pdfname.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
*/
66
function toPDFName(str) {
77
// eslint-disable-next-line no-control-regex
8-
if(/[^\u0000-\u00ff]/.test(str)){ // non ascii string
9-
throw new Error('Invalid PDF Name Object: ' + str + ', Only accept ASCII characters.');
8+
if (/[^\u0000-\u00ff]/.test(str)) {
9+
// non ascii string
10+
throw new Error(
11+
"Invalid PDF Name Object: " + str + ", Only accept ASCII characters."
12+
);
1013
}
1114
var result = "",
1215
strLength = str.length;

src/modules/cell.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,10 @@ import { jsPDF } from "../jspdf.js";
442442
});
443443
}
444444

445-
if (autoSize || (Array.isArray(headers) && typeof headers[0] === "string")) {
445+
if (
446+
autoSize ||
447+
(Array.isArray(headers) && typeof headers[0] === "string")
448+
) {
446449
var headerName;
447450
for (i = 0; i < headerNames.length; i += 1) {
448451
headerName = headerNames[i];

src/modules/context2d.js

+68
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import {
5151
this.currentPoint = ctx.currentPoint || new Point();
5252
this.miterLimit = ctx.miterLimit || 10.0;
5353
this.lastPoint = ctx.lastPoint || new Point();
54+
this.lineDashOffset = ctx.lineDashOffset || 0.0;
55+
this.lineDash = ctx.lineDash || [];
5456

5557
this.ignoreClearRect =
5658
typeof ctx.ignoreClearRect === "boolean" ? ctx.ignoreClearRect : true;
@@ -641,6 +643,32 @@ import {
641643
}
642644
});
643645

646+
/**
647+
* A float specifying the amount of the line dash offset. The default value is 0.0.
648+
*
649+
* @name lineDashOffset
650+
* @default 0.0
651+
*/
652+
Object.defineProperty(this, "lineDashOffset", {
653+
get: function() {
654+
return this.ctx.lineDashOffset;
655+
},
656+
set: function(value) {
657+
this.ctx.lineDashOffset = value;
658+
setLineDash.call(this);
659+
}
660+
});
661+
662+
Object.defineProperty(this, "lineDash", {
663+
get: function() {
664+
return this.ctx.lineDash;
665+
},
666+
set: function(value) {
667+
this.ctx.lineDash = value;
668+
setLineDash.call(this);
669+
}
670+
});
671+
644672
// Not HTML API
645673
Object.defineProperty(this, "ignoreClearRect", {
646674
get: function() {
@@ -652,6 +680,16 @@ import {
652680
});
653681
};
654682

683+
/**
684+
* Sets the line dash pattern used when stroking lines.
685+
* @name setLineDash
686+
* @function
687+
* @description It uses an array of values that specify alternating lengths of lines and gaps which describe the pattern.
688+
*/
689+
Context2D.prototype.setLineDash = function(dashArray) {
690+
this.lineDash = dashArray;
691+
};
692+
655693
Context2D.prototype.fill = function() {
656694
pathPreProcess.call(this, "fill", false);
657695
};
@@ -1105,6 +1143,8 @@ import {
11051143
this.lineCap = this.ctx.lineCap;
11061144
this.lineWidth = this.ctx.lineWidth;
11071145
this.lineJoin = this.ctx.lineJoin;
1146+
this.lineDash = this.ctx.lineDash;
1147+
this.lineDashOffset = this.ctx.lineDashOffset;
11081148
}
11091149
};
11101150

@@ -2383,4 +2423,32 @@ import {
23832423
Math.round(maxy - miny)
23842424
);
23852425
};
2426+
2427+
var getPrevLineDashValue = function(lineDash, lineDashOffset) {
2428+
return JSON.stringify({
2429+
lineDash: lineDash,
2430+
lineDashOffset: lineDashOffset
2431+
});
2432+
};
2433+
2434+
var setLineDash = function() {
2435+
// Avoid unnecessary line dash declarations.
2436+
if (
2437+
!this.prevLineDash &&
2438+
!this.ctx.lineDash.length &&
2439+
!this.ctx.lineDashOffset
2440+
) {
2441+
return;
2442+
}
2443+
2444+
// Avoid unnecessary line dash declarations.
2445+
const nextLineDash = getPrevLineDashValue(
2446+
this.ctx.lineDash,
2447+
this.ctx.lineDashOffset
2448+
);
2449+
if (this.prevLineDash !== nextLineDash) {
2450+
this.pdf.setLineDash(this.ctx.lineDash, this.ctx.lineDashOffset);
2451+
this.prevLineDash = nextLineDash;
2452+
}
2453+
};
23862454
})(jsPDF.API);

test/reference/lineDash.pdf

3.51 KB
Binary file not shown.

test/specs/context2d.spec.js

+75
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,81 @@ describe("Context2D: standard tests", () => {
485485
comparePdf(doc.output(), "moveTo_lineTo_stroke_fill.pdf", "context2d");
486486
});
487487

488+
fit("context2d: setLineDash(), lineDashOffset", () => {
489+
var doc = new jsPDF({
490+
orientation: "p",
491+
unit: "pt",
492+
format: "a4",
493+
floatPrecision: 2
494+
});
495+
var ctx = doc.context2d;
496+
497+
var y = 20;
498+
var pad = 20;
499+
500+
ctx.lineWidth = 5;
501+
ctx.beginPath();
502+
ctx.moveTo(20, y);
503+
ctx.lineTo(200, y);
504+
ctx.stroke();
505+
y += pad;
506+
ctx.save();
507+
ctx.beginPath();
508+
ctx.setLineDash([10, 20]);
509+
ctx.lineDashOffset = 10;
510+
ctx.moveTo(20, y);
511+
ctx.lineTo(200, y);
512+
ctx.stroke();
513+
y += pad;
514+
ctx.beginPath();
515+
ctx.setLineDash([]);
516+
ctx.lineDashOffset = 0;
517+
ctx.moveTo(20, y);
518+
ctx.lineTo(200, y);
519+
ctx.stroke();
520+
y += pad;
521+
ctx.beginPath();
522+
ctx.setLineDash([10, 20]);
523+
ctx.lineDashOffset = 10;
524+
ctx.moveTo(20, y);
525+
ctx.lineTo(200, y);
526+
ctx.stroke();
527+
y += pad;
528+
ctx.save();
529+
ctx.beginPath();
530+
ctx.setLineDash([]);
531+
ctx.lineDashOffset = 0;
532+
ctx.moveTo(20, y);
533+
ctx.lineTo(200, y);
534+
ctx.stroke();
535+
y += pad;
536+
ctx.restore();
537+
ctx.beginPath();
538+
ctx.moveTo(20, y);
539+
ctx.lineTo(200, y);
540+
ctx.stroke();
541+
y += pad;
542+
ctx.save();
543+
ctx.beginPath();
544+
ctx.moveTo(20, y);
545+
ctx.lineTo(200, y);
546+
ctx.stroke();
547+
y += pad;
548+
ctx.restore();
549+
ctx.beginPath();
550+
ctx.moveTo(20, y);
551+
ctx.lineTo(200, y);
552+
ctx.stroke();
553+
y += pad;
554+
ctx.restore();
555+
ctx.beginPath();
556+
ctx.moveTo(20, y);
557+
ctx.lineTo(200, y);
558+
ctx.stroke();
559+
560+
comparePdf(doc.output(), "lineDash.pdf", "context2d");
561+
});
562+
488563
it("context2d: textBaseline", () => {
489564
var doc = new jsPDF({
490565
orientation: "p",

0 commit comments

Comments
 (0)