mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
support kerning and hyphens
This commit is contained in:
parent
95ca5a627a
commit
962d0a68d9
@ -3,11 +3,14 @@ html2canvas
|
||||
|
||||
[Homepage](https://html2canvas.hertzen.com) | [Downloads](https://github.com/niklasvh/html2canvas/releases) | [Questions](http://stackoverflow.com/questions/tagged/html2canvas?sort=newest)
|
||||
|
||||
[](https://gitter.im/niklasvh/html2canvas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://gitter.im/niklasvh/html2canvas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://dev.azure.com/niklasvh/html2canvas/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://www.npmjs.org/package/html2canvas)
|
||||
[](https://www.npmjs.org/package/html2canvas)
|
||||
|
||||
This is a branch of the original and fixes:
|
||||
- Rendering of textarea (see [#2008](https://github.com/niklasvh/html2canvas/issues/2008))
|
||||
|
||||
#### JavaScript HTML renderer ####
|
||||
|
||||
The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
|
||||
|
@ -35,10 +35,22 @@ describe('textarea-layout', () => {
|
||||
layoutEqual('Donaudampfsc x2',
|
||||
['Donaudampfsc', 'x2']);
|
||||
});
|
||||
it('should wrap lines at -', () => {
|
||||
layoutEqual(' Long text- message with sev lines.',
|
||||
[' Long text-', 'message with','sev lines.']);
|
||||
});
|
||||
it('should wrap lines at - 2', () => {
|
||||
layoutEqual('Long text- message with sev lines.',
|
||||
['Long text- ', 'message with','sev lines.']);
|
||||
});
|
||||
it('should wrap lines at - 3', () => {
|
||||
layoutEqual('Long text-message with sev lines.',
|
||||
['Long text-', 'message with','sev lines.']);
|
||||
});
|
||||
});
|
||||
|
||||
function layoutEqual(s: string, lines: string[]) {
|
||||
const pos = layout(toCodePoints(s).map(i => fromCodePoint(i)), 120, _ => 10);
|
||||
const pos = layout(toCodePoints(s).map(i => fromCodePoint(i)), 120, (_, len) => 10 * len);
|
||||
let line = '';
|
||||
let y = 0;
|
||||
let j = 0;
|
||||
|
@ -146,7 +146,8 @@ export class CanvasRenderer {
|
||||
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
|
||||
} else {
|
||||
const chars = toCodePoints(text.text).map(i => fromCodePoint(i));
|
||||
const pos = layout(chars, text.bounds.width, s => this.ctx.measureText(s).width + letterSpacing);
|
||||
const pos = layout(chars, text.bounds.width, (s, len) =>
|
||||
this.ctx.measureText(s).width + letterSpacing * (len - 1));
|
||||
const dx = text.bounds.left;
|
||||
const dy = text.bounds.top + lineHeight / 2;
|
||||
for (let i = 0; i < pos.length; i++) {
|
||||
|
@ -1,40 +1,44 @@
|
||||
export function layout(chars: string[], width: number, measure: (s: string) => number): number[][] {
|
||||
export function layout(chars: string[], width: number, measure: (s: string, len: number) => number): number[][] {
|
||||
const pos: number[][] = [];
|
||||
let line = 0;
|
||||
let lineWidth = 0;
|
||||
let lineString = '';
|
||||
let lineLen = 0;
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
if (chars[i] === '\n') {
|
||||
pos.push([-1, line]);
|
||||
line++;
|
||||
lineWidth = 0;
|
||||
setLine(0, 0);
|
||||
} else {
|
||||
pos.push([lineWidth, line]);
|
||||
lineWidth += measure(chars[i]);
|
||||
addChar(i);
|
||||
const lineWidth = measure(lineString, lineLen);
|
||||
pos.push([lineWidth - measure(chars[i], 1), line]);
|
||||
if (lineWidth > width) {
|
||||
if (chars[i] === ' ') {
|
||||
if (chars[i] === ' ' || chars[i] === '-') {
|
||||
let p = i;
|
||||
while (p > 0 && pos[p][1] === line && chars[p] === ' ') p--;
|
||||
for (let j = i; j > p; j--) {
|
||||
pos[j][0] = -1;
|
||||
}
|
||||
line++;
|
||||
lineWidth = 0;
|
||||
setLine(0, 0);
|
||||
while (i < chars.length + 1 && chars[i + 1] === ' ') {
|
||||
pos.push([-1, line]);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
let p = i;
|
||||
while (p > 0 && pos[p][1] === line && chars[p] !== ' ') p--;
|
||||
while (p > 0 && pos[p][1] === line && chars[p] !== ' ' && chars[p] !== '-') p--;
|
||||
line++;
|
||||
if (chars[p] === ' ') {
|
||||
lineWidth -= pos[p + 1][0];
|
||||
if (chars[p] === ' ' || chars[p] === '-') {
|
||||
setLine(p + 1, i + 1);
|
||||
for (let j = i; j > p; j--) {
|
||||
pos[j] = [pos[j][0] - pos[p + 1][0], line];
|
||||
}
|
||||
pos[p][0] = -1;
|
||||
if (chars[p] === ' ') {
|
||||
pos[p][0] = -1;
|
||||
}
|
||||
} else {
|
||||
lineWidth -= pos[i][0];
|
||||
setLine(i, i + 1);
|
||||
pos[i] = [0, line];
|
||||
}
|
||||
}
|
||||
@ -42,4 +46,17 @@ export function layout(chars: string[], width: number, measure: (s: string) => n
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
|
||||
function addChar(pos: number) {
|
||||
lineString += chars[pos];
|
||||
lineLen++;
|
||||
}
|
||||
|
||||
function setLine(from: number, to: number) {
|
||||
lineString = '';
|
||||
for (let i = from; i < to; i++) {
|
||||
lineString += chars[i];
|
||||
}
|
||||
lineLen = to - from;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,19 @@
|
||||
|
||||
<p>7. long word</p>
|
||||
<textarea>Donaudampfschifffahrtsgesellschaftskapitänskochmütze</textarea>
|
||||
|
||||
<p>8. hyphen</p>
|
||||
<textarea>A text with many-manymany manys.</textarea>
|
||||
|
||||
<p>9. kerning</p>
|
||||
<textarea>AVAVAVAVAVAVAVAV TeTeTeTeTeTeTeTeTe YaYaYaYaYaYaYaYaY</textarea>
|
||||
|
||||
<p>10. kerning with letter spacing</p>
|
||||
<textarea style="letter-spacing: 1px">AVAVAVAVAVAVAV TeTeTeTeTeTeTeTe YaYaYaYaYaYaYaY</textarea>
|
||||
|
||||
<p>11. kerning with letter spacing</p>
|
||||
<textarea style="letter-spacing: 5px">AVAVAVAVAV TeTeTeTeTeT YaYaYaYaYa</textarea>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user