UNPKG

svg-paper

Version:

The world's most maintainable way to create paper-printable documents 🖨💘

57 lines (45 loc) • 2.06 kB
'use strict' import splitStringByWidth from './utility/split-string-by-width' import fixTextTransform from './utility/fix-text-transform' export default (textSvg, textContent, width, height, lineHeight = 1.2, paddingX = 0.5, paddingY = 0.5, nowrap = false) => { if (!textSvg.match(new RegExp('<text [^>]*font-size="\\d+"[^>]*><tspan( [^>]*>|>)[^<>]*</tspan></text>'))) { console.error('Invalid svg string of text element', textSvg) return textSvg } const originalFontSize = parseInt(textSvg.match(/.+font-size="(\d+)".+/)[1]) let fontSize = originalFontSize // find the right-size font-size const physicalLines = textContent.split("\n") let logicalLines = [] while (true) { let maxRows = Math.floor((height - (2 * fontSize * paddingY)) / (fontSize * lineHeight)) let maxColumns = Math.floor((width - (2 * fontSize * paddingX)) / fontSize) // doesn't care about proportional font if (nowrap) { logicalLines = physicalLines } else { logicalLines = [] physicalLines.forEach(line => { logicalLines = logicalLines.concat(splitStringByWidth(line, maxColumns * 2)) // 2 single-byte characters can be placed in 1 column }) } if (logicalLines.length > maxRows) { fontSize *= 0.95 } else { break } } // raise y-coordinate up because y-coordinate of <text transform="translate(x y)"> or <tspan y=""> is on lower base of text object const adjustY = fontSize - originalFontSize let adjustedTextSvg = fixTextTransform(textSvg) adjustedTextSvg = adjustedTextSvg.replace(new RegExp('<tspan(.|\\s)+</text>'), '') adjustedTextSvg = adjustedTextSvg.replace(new RegExp('font-size="\\d+"'), `font-size="${fontSize}"`) adjustedTextSvg += '{tspan}</text>' let tspan = '' const x = fontSize * paddingX logicalLines.forEach((line, i) => { const y = adjustY + fontSize * (paddingY + (i * lineHeight)) tspan += `<tspan x="${x}" y="${y}">${line}</tspan>` }) adjustedTextSvg = adjustedTextSvg.replace('{tspan}', tspan) return adjustedTextSvg }