'use strict'; var isArray = require('./helpers').isArray; var isPattern = require('./helpers').isPattern; var getPattern = require('./helpers').getPattern; function groupDecorations(line) { var groups = [], currentGroup = null; for (var i = 0, l = line.inlines.length; i < l; i++) { var inline = line.inlines[i]; var decoration = inline.decoration; if (!decoration) { currentGroup = null; continue; } if (!isArray(decoration)) { decoration = [decoration]; } var color = inline.decorationColor || inline.color || 'black'; var style = inline.decorationStyle || 'solid'; for (var ii = 0, ll = decoration.length; ii < ll; ii++) { var decorationItem = decoration[ii]; if (!currentGroup || decorationItem !== currentGroup.decoration || style !== currentGroup.decorationStyle || color !== currentGroup.decorationColor) { currentGroup = { line: line, decoration: decorationItem, decorationColor: color, decorationStyle: style, inlines: [inline] }; groups.push(currentGroup); } else { currentGroup.inlines.push(inline); } } } return groups; } function drawDecoration(group, x, y, pdfKitDoc) { function maxInline() { var max = 0; for (var i = 0, l = group.inlines.length; i < l; i++) { var inline = group.inlines[i]; max = inline.fontSize > max ? i : max; } return group.inlines[max]; } function width() { var sum = 0; for (var i = 0, l = group.inlines.length; i < l; i++) { var justifyShift = (group.inlines[i].justifyShift || 0); sum += group.inlines[i].width + justifyShift; } return sum; } var firstInline = group.inlines[0], biggerInline = maxInline(), totalWidth = width(), lineAscent = group.line.getAscenderHeight(), ascent = biggerInline.font.ascender / 1000 * biggerInline.fontSize, height = biggerInline.height, descent = height - ascent; var lw = 0.5 + Math.floor(Math.max(biggerInline.fontSize - 8, 0) / 2) * 0.12; switch (group.decoration) { case 'underline': y += lineAscent + descent * 0.45; break; case 'overline': y += lineAscent - (ascent * 0.85); break; case 'lineThrough': y += lineAscent - (ascent * 0.25); break; default: throw 'Unknown decoration : ' + group.decoration; } pdfKitDoc.save(); if (group.decorationStyle === 'double') { var gap = Math.max(0.5, lw * 2); pdfKitDoc.fillColor(group.decorationColor) .rect(x + firstInline.x, y - lw / 2, totalWidth, lw / 2).fill() .rect(x + firstInline.x, y + gap - lw / 2, totalWidth, lw / 2).fill(); } else if (group.decorationStyle === 'dashed') { var nbDashes = Math.ceil(totalWidth / (3.96 + 2.84)); var rdx = x + firstInline.x; pdfKitDoc.rect(rdx, y, totalWidth, lw).clip(); pdfKitDoc.fillColor(group.decorationColor); for (var i = 0; i < nbDashes; i++) { pdfKitDoc.rect(rdx, y - lw / 2, 3.96, lw).fill(); rdx += 3.96 + 2.84; } } else if (group.decorationStyle === 'dotted') { var nbDots = Math.ceil(totalWidth / (lw * 3)); var rx = x + firstInline.x; pdfKitDoc.rect(rx, y, totalWidth, lw).clip(); pdfKitDoc.fillColor(group.decorationColor); for (var ii = 0; ii < nbDots; ii++) { pdfKitDoc.rect(rx, y - lw / 2, lw, lw).fill(); rx += (lw * 3); } } else if (group.decorationStyle === 'wavy') { var sh = 0.7, sv = 1; var nbWaves = Math.ceil(totalWidth / (sh * 2)) + 1; var rwx = x + firstInline.x - 1; pdfKitDoc.rect(x + firstInline.x, y - sv, totalWidth, y + sv).clip(); pdfKitDoc.lineWidth(0.24); pdfKitDoc.moveTo(rwx, y); for (var iii = 0; iii < nbWaves; iii++) { pdfKitDoc.bezierCurveTo(rwx + sh, y - sv, rwx + sh * 2, y - sv, rwx + sh * 3, y) .bezierCurveTo(rwx + sh * 4, y + sv, rwx + sh * 5, y + sv, rwx + sh * 6, y); rwx += sh * 6; } pdfKitDoc.stroke(group.decorationColor); } else { pdfKitDoc.fillColor(group.decorationColor) .rect(x + firstInline.x, y - lw / 2, totalWidth, lw) .fill(); } pdfKitDoc.restore(); } function drawDecorations(line, x, y, pdfKitDoc) { var groups = groupDecorations(line); for (var i = 0, l = groups.length; i < l; i++) { drawDecoration(groups[i], x, y, pdfKitDoc); } } function drawBackground(line, x, y, patterns, pdfKitDoc) { var height = line.getHeight(); for (var i = 0, l = line.inlines.length; i < l; i++) { var inline = line.inlines[i]; if (!inline.background) { continue; } var color = inline.background; if (isPattern(inline.background)) { color = getPattern(inline.background, patterns); } var justifyShift = (inline.justifyShift || 0); pdfKitDoc.fillColor(color) .rect(x + inline.x - justifyShift, y, inline.width + justifyShift, height) .fill(); } } module.exports = { drawBackground: drawBackground, drawDecorations: drawDecorations };