From bd9fd9867b504dbcd6b475052cde5aadddd6e3ab Mon Sep 17 00:00:00 2001 From: Wolfgang Gassler Date: Tue, 29 Apr 2014 20:55:15 +0200 Subject: [PATCH 1/2] processing of css style text-align center and right added --- jspdf.plugin.from_html.js | 53 +++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/jspdf.plugin.from_html.js b/jspdf.plugin.from_html.js index f7dc9d921..3e7392f58 100644 --- a/jspdf.plugin.from_html.js +++ b/jspdf.plugin.from_html.js @@ -26,7 +26,11 @@ */ (function(jsPDFAPI) { - var DrillForContent, FontNameDB, FontStyleMap, FontWeightMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, process, tableToJson; + var clone,DrillForContent, FontNameDB, FontStyleMap, FontWeightMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, process, tableToJson; + clone = (function(){ + return function (obj) { Clone.prototype=obj; return new Clone() }; + function Clone(){} + }()); PurgeWhiteSpace = function(array) { var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace; i = 0; @@ -140,6 +144,7 @@ tmp = void 0; css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times"; css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal"; + css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left"; tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal"; if (tmp === "bold") { if (css["font-style"] === "normal") { @@ -399,8 +404,28 @@ } } } + + //if text alignment was set, set margin/indent of each line + if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right')) { + for(var i = 0; i < lines.length; ++i) { + var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k; + //if there is more than on line we have to clone the style object as all lines hold a reference on this object + if (i > 0) { + lines[i][0][1] = clone(lines[i][0][1]); + } + var space = (maxLineLength-length); + console.log(lines[i][0][0]+" with space: "+space) + if (style['text-align'] === 'right') { + lines[i][0][1]['margin-left'] = space; + //if alignment is not right, it has to be center so split the space to the left and the right + } else { + lines[i][0][1]['margin-left'] = space/2; + } + }; + } + return lines; - }; + }; Renderer.prototype.RenderTextFragment = function(text, style) { var defaultFontSize, font; if (this.pdf.internal.pageSize.height - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) { @@ -411,7 +436,7 @@ } defaultFontSize = 12; font = this.pdf.internal.getFont(style["font-family"], style["font-style"]); - return this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj"); + return this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");; }; Renderer.prototype.renderParagraph = function() { var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstype, styles; @@ -440,7 +465,11 @@ l = void 0; this.y += paragraphspacing_before; out("q", "BT", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td"); - while (lines.length) { + + //stores the current indent of cursor position + var currentIndent = 0; + + while (lines.length) { line = lines.shift(); maxLineHeight = 0; i = 0; @@ -451,7 +480,16 @@ } i++; } - out(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td"); + //if we have to move the cursor to adapt the indent + var indentMove = 0; + //if a margin was added (by e.g. a text-alignment), move the cursor + if (line[0][1]["margin-left"] !== undefined && line[0][1]["margin-left"] > 0) { + wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]); + indentMove = wantedIndent-currentIndent; + currentIndent = wantedIndent; + } + //move the cursor + out(indentMove, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td"); i = 0; l = line.length; while (i !== l) { @@ -504,6 +542,11 @@ italic: "italic", oblique: "italic" }; + TextAlignMap = { + left: "left", + right: "right", + center: "center" + }; UnitedNumberMap = { normal: 1 /* From 88130350d23d382f92fad3358395a4ac05d6d79a Mon Sep 17 00:00:00 2001 From: Wolfgang Gassler Date: Tue, 29 Apr 2014 22:12:22 +0200 Subject: [PATCH 2/2] prcoessing css style justify added --- jspdf.plugin.from_html.js | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/jspdf.plugin.from_html.js b/jspdf.plugin.from_html.js index 3e7392f58..1b8ebb8cf 100644 --- a/jspdf.plugin.from_html.js +++ b/jspdf.plugin.from_html.js @@ -406,7 +406,7 @@ } //if text alignment was set, set margin/indent of each line - if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right')) { + if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) { for(var i = 0; i < lines.length; ++i) { var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k; //if there is more than on line we have to clone the style object as all lines hold a reference on this object @@ -414,14 +414,22 @@ lines[i][0][1] = clone(lines[i][0][1]); } var space = (maxLineLength-length); - console.log(lines[i][0][0]+" with space: "+space) + if (style['text-align'] === 'right') { lines[i][0][1]['margin-left'] = space; //if alignment is not right, it has to be center so split the space to the left and the right - } else { + } else if (style['text-align'] === 'center') { lines[i][0][1]['margin-left'] = space/2; + //if justify was set, calculate the word spacing and define in by using the css property + } else if (style['text-align'] === 'justify') { + var countSpaces = lines[i][0][0].split(' ').length-1; + lines[i][0][1]['word-spacing'] = space/countSpaces; + //ignore the last line in justify mode + if (i === (lines.length-1)) { + lines[i][0][1]['word-spacing'] = 0; + } } - }; + } } return lines; @@ -436,7 +444,19 @@ } defaultFontSize = 12; font = this.pdf.internal.getFont(style["font-family"], style["font-style"]); - return this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");; + + //set the word spacing for e.g. justify style + if (style['word-spacing'] !== undefined && style['word-spacing'] > 0) { + this.pdf.internal.write(style['word-spacing'].toFixed(2), "Tw"); + } + + this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj"); + + //set the word spacing back to neutral => 0 + if (style['word-spacing'] !== undefined) { + this.pdf.internal.write(0, "Tw"); + } + }; Renderer.prototype.renderParagraph = function() { var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstype, styles; @@ -487,7 +507,7 @@ wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]); indentMove = wantedIndent-currentIndent; currentIndent = wantedIndent; - } + } //move the cursor out(indentMove, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td"); i = 0; @@ -545,7 +565,8 @@ TextAlignMap = { left: "left", right: "right", - center: "center" + center: "center", + justify: "justify" }; UnitedNumberMap = { normal: 1