Skip to content

Commit 9ca4a6d

Browse files
committed
Merge pull request #252 from woolfg/alignment
from_html: Support of left, right, center, justify css text-align property
2 parents 7c555c7 + 8813035 commit 9ca4a6d

File tree

1 file changed

+69
-5
lines changed

1 file changed

+69
-5
lines changed

jspdf.plugin.from_html.js

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
*/
2828

2929
(function(jsPDFAPI) {
30-
var DrillForContent, FontNameDB, FontStyleMap, FontWeightMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, process, tableToJson;
30+
var clone,DrillForContent, FontNameDB, FontStyleMap, FontWeightMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, process, tableToJson;
31+
clone = (function(){
32+
return function (obj) { Clone.prototype=obj; return new Clone() };
33+
function Clone(){}
34+
}());
3135
PurgeWhiteSpace = function(array) {
3236
var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace;
3337
i = 0;
@@ -151,6 +155,7 @@
151155
tmp = void 0;
152156
css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times";
153157
css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal";
158+
css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left";
154159
tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal";
155160
if (tmp === "bold") {
156161
if (css["font-style"] === "normal") {
@@ -441,8 +446,36 @@
441446
}
442447
}
443448
}
449+
450+
//if text alignment was set, set margin/indent of each line
451+
if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) {
452+
for(var i = 0; i < lines.length; ++i) {
453+
var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
454+
//if there is more than on line we have to clone the style object as all lines hold a reference on this object
455+
if (i > 0) {
456+
lines[i][0][1] = clone(lines[i][0][1]);
457+
}
458+
var space = (maxLineLength-length);
459+
460+
if (style['text-align'] === 'right') {
461+
lines[i][0][1]['margin-left'] = space;
462+
//if alignment is not right, it has to be center so split the space to the left and the right
463+
} else if (style['text-align'] === 'center') {
464+
lines[i][0][1]['margin-left'] = space/2;
465+
//if justify was set, calculate the word spacing and define in by using the css property
466+
} else if (style['text-align'] === 'justify') {
467+
var countSpaces = lines[i][0][0].split(' ').length-1;
468+
lines[i][0][1]['word-spacing'] = space/countSpaces;
469+
//ignore the last line in justify mode
470+
if (i === (lines.length-1)) {
471+
lines[i][0][1]['word-spacing'] = 0;
472+
}
473+
}
474+
}
475+
}
476+
444477
return lines;
445-
};
478+
};
446479
Renderer.prototype.RenderTextFragment = function(text, style) {
447480
var defaultFontSize, font;
448481
if (this.pdf.internal.pageSize.height - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) {
@@ -453,7 +486,19 @@
453486
}
454487
defaultFontSize = 12;
455488
font = this.pdf.internal.getFont(style["font-family"], style["font-style"]);
456-
return this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");
489+
490+
//set the word spacing for e.g. justify style
491+
if (style['word-spacing'] !== undefined && style['word-spacing'] > 0) {
492+
this.pdf.internal.write(style['word-spacing'].toFixed(2), "Tw");
493+
}
494+
495+
this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");
496+
497+
//set the word spacing back to neutral => 0
498+
if (style['word-spacing'] !== undefined) {
499+
this.pdf.internal.write(0, "Tw");
500+
}
501+
457502
};
458503
Renderer.prototype.renderParagraph = function(cb) {
459504
var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstype, styles, fontSize;
@@ -482,7 +527,11 @@
482527
l = void 0;
483528
this.y += paragraphspacing_before;
484529
out("q", "BT", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
485-
while (lines.length) {
530+
531+
//stores the current indent of cursor position
532+
var currentIndent = 0;
533+
534+
while (lines.length) {
486535
line = lines.shift();
487536
maxLineHeight = 0;
488537
i = 0;
@@ -494,7 +543,16 @@
494543
}
495544
i++;
496545
}
497-
out(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
546+
//if we have to move the cursor to adapt the indent
547+
var indentMove = 0;
548+
//if a margin was added (by e.g. a text-alignment), move the cursor
549+
if (line[0][1]["margin-left"] !== undefined && line[0][1]["margin-left"] > 0) {
550+
wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]);
551+
indentMove = wantedIndent-currentIndent;
552+
currentIndent = wantedIndent;
553+
}
554+
//move the cursor
555+
out(indentMove, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
498556
i = 0;
499557
l = line.length;
500558
while (i !== l) {
@@ -550,6 +608,12 @@
550608
italic: "italic",
551609
oblique: "italic"
552610
};
611+
TextAlignMap = {
612+
left: "left",
613+
right: "right",
614+
center: "center",
615+
justify: "justify"
616+
};
553617
UnitedNumberMap = {
554618
normal: 1
555619
/*

0 commit comments

Comments
 (0)