@visactor/vrender-core
Version:
## Description
132 lines (124 loc) • 9.52 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.seperateParagraph = void 0;
const utils_1 = require("../../common/utils"), utils_2 = require("./utils");
function getFixedLRTB(left, right, top, bottom) {
const leftInt = Math.round(left), topInt = Math.round(top), rightInt = Math.round(right), bottomInt = Math.round(bottom);
return {
left: left > leftInt ? leftInt : leftInt - .5,
top: top > topInt ? topInt : topInt - .5,
right: rightInt > right ? rightInt : rightInt + .5,
bottom: bottomInt > bottom ? bottomInt : bottomInt + .5
};
}
class Paragraph {
constructor(text, newLine, character, ascentDescentMode) {
this.fontSize = character.fontSize || 16, this.textBaseline = character.textBaseline || "alphabetic",
this.ascentDescentMode = ascentDescentMode;
const lineHeight = (0, utils_1.calculateLineHeight)(character.lineHeight, this.fontSize);
this.lineHeight = "number" == typeof lineHeight ? lineHeight > this.fontSize ? lineHeight : this.fontSize : Math.floor(1.2 * this.fontSize),
this.height = this.lineHeight;
const {ascent: ascent, height: height, descent: descent, width: width} = (0, utils_2.measureTextCanvas)(text, character, this.ascentDescentMode);
let halfDetaHeight = 0, deltaAscent = 0, deltaDescent = 0;
this.height > height && (halfDetaHeight = (this.height - height) / 2, deltaAscent = Math.ceil(halfDetaHeight),
deltaDescent = Math.floor(halfDetaHeight)), "top" === this.textBaseline ? (this.ascent = halfDetaHeight,
this.descent = height - halfDetaHeight) : "bottom" === this.textBaseline ? (this.ascent = height - halfDetaHeight,
this.descent = halfDetaHeight) : "middle" === this.textBaseline ? (this.ascent = this.height / 2,
this.descent = this.height / 2) : (this.ascent = ascent + deltaAscent, this.descent = descent + deltaDescent),
this.length = text.length, this.width = width || 0, this.text = text || "", this.newLine = newLine || !1,
this.character = character, this.left = 0, this.top = 0, this.ellipsis = "normal",
this.ellipsisWidth = 0, this.ellipsisOtherParagraphWidth = 0, "vertical" === character.direction && (this.direction = character.direction,
this.widthOrigin = this.width, this.heightOrigin = this.height, this.width = this.heightOrigin,
this.height = this.widthOrigin, this.lineHeight = this.height), this.ellipsisStr = "...";
}
updateWidth() {
const {width: width} = (0, utils_2.measureTextCanvas)(this.text, this.character, this.ascentDescentMode);
this.width = width, "vertical" === this.direction && (this.widthOrigin = this.width,
this.width = this.heightOrigin, this.height = this.widthOrigin);
}
drawBackground(ctx, top, ascent, deltaLeft, isLineFirst, textAlign, lineHeight) {
if ("" === this.text || "\n" === this.text || !this.character.background || this.character.backgroundOpacity && !(this.character.backgroundOpacity > 0)) return;
let baseline = top + ascent, text = this.text, left = this.left + deltaLeft;
baseline += this.top;
let direction = this.direction;
if (this.verticalEllipsis) text = this.ellipsisStr, direction = "vertical", baseline -= this.ellipsisWidth / 2; else {
if ("hide" === this.ellipsis) return;
if ("add" === this.ellipsis) text += this.ellipsisStr, "right" !== textAlign && "end" !== textAlign || (left -= this.ellipsisWidth); else if ("replace" === this.ellipsis) {
const index = (0, utils_2.getStrByWithCanvas)(text, ("vertical" === direction ? this.height : this.width) - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.character, text.length - 1);
if (text = text.slice(0, index), text += this.ellipsisStr, "right" === textAlign || "end" === textAlign) {
const {width: width} = (0, utils_2.measureTextCanvas)(this.text.slice(index), this.character, this.ascentDescentMode);
"vertical" === direction || (left -= this.ellipsisWidth - width);
}
}
}
const lrtb = getFixedLRTB(left, left + (this.widthOrigin || this.width), top, top + lineHeight);
return Object.assign(Object.assign({}, lrtb), {
fillStyle: this.character.background,
globalAlpha: this.character.backgroundOpacity
});
}
draw(ctx, top, ascent, deltaLeft, isLineFirst, textAlign, lineHeight) {
let baseline = top + ascent, text = this.text, left = this.left + deltaLeft;
baseline += this.top;
let direction = this.direction;
if (this.verticalEllipsis) text = this.ellipsisStr, direction = "vertical", baseline -= this.ellipsisWidth / 2; else {
if ("hide" === this.ellipsis) return;
if ("add" === this.ellipsis) text += this.ellipsisStr, "right" !== textAlign && "end" !== textAlign || (left -= this.ellipsisWidth); else if ("replace" === this.ellipsis) {
const index = (0, utils_2.getStrByWithCanvas)(text, ("vertical" === direction ? this.height : this.width) - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.character, text.length - 1);
if (text = text.slice(0, index), text += this.ellipsisStr, "right" === textAlign || "end" === textAlign) {
const {width: width} = (0, utils_2.measureTextCanvas)(this.text.slice(index), this.character, this.ascentDescentMode);
"vertical" === direction || (left -= this.ellipsisWidth - width);
}
}
}
switch (this.character.script) {
case "super":
baseline -= this.ascent * (1 / 3);
break;
case "sub":
baseline += this.descent / 2;
}
"vertical" === direction && (ctx.save(), ctx.rotateAbout(Math.PI / 2, left, baseline),
ctx.translate(-this.heightOrigin || -this.lineHeight / 2, -this.descent / 2), ctx.translate(left, baseline),
left = 0, baseline = 0);
const {lineWidth: lineWidth = 1} = this.character;
if (this.character.stroke && lineWidth && ctx.strokeText(text, left, baseline),
this.character.fill && ctx.fillText(text, left, baseline), this.character.fill) if (this.character.lineThrough || this.character.underline) {
if (this.character.underline) {
const top = 1 + baseline, lrtb = getFixedLRTB(left, left + (this.widthOrigin || this.width), top, top + (this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1));
ctx.fillRect(lrtb.left, 1 + baseline, lrtb.right - lrtb.left, this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1);
}
if (this.character.lineThrough) {
const top = 1 + baseline - this.ascent / 2, lrtb = getFixedLRTB(left, left + (this.widthOrigin || this.width), top, top + (this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1));
ctx.fillRect(lrtb.left, 1 + baseline - this.ascent / 2, lrtb.right - lrtb.left, this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1);
}
} else if ("underline" === this.character.textDecoration) {
const top = 1 + baseline, lrtb = getFixedLRTB(left, left + (this.widthOrigin || this.width), top, top + (this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1));
ctx.fillRect(lrtb.left, 1 + baseline, lrtb.right - lrtb.left, this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1);
} else if ("line-through" === this.character.textDecoration) {
const top = 1 + baseline - this.ascent / 2, lrtb = getFixedLRTB(left, left + (this.widthOrigin || this.width), top, top + (this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1));
ctx.fillRect(lrtb.left, 1 + baseline - this.ascent / 2, lrtb.right - lrtb.left, this.character.fontSize ? Math.max(1, Math.floor(this.character.fontSize / 10)) : 1);
}
"vertical" === direction && ctx.restore();
}
getWidthWithEllips(direction) {
let text = this.text;
const width = "vertical" === direction ? this.height : this.width;
if ("hide" === this.ellipsis) return width;
if ("add" === this.ellipsis) return width + this.ellipsisWidth;
if ("replace" === this.ellipsis) {
const index = (0, utils_2.getStrByWithCanvas)(text, width - this.ellipsisWidth + this.ellipsisOtherParagraphWidth, this.character, text.length - 1);
text = text.slice(0, index), text += this.ellipsisStr;
const {width: measureWidth} = (0, utils_2.measureTextCanvas)(this.text.slice(index), this.character, this.ascentDescentMode);
return width + this.ellipsisWidth - measureWidth;
}
return width;
}
}
function seperateParagraph(paragraph, index) {
const text1 = paragraph.text.slice(0, index), text2 = paragraph.text.slice(index);
return [ new Paragraph(text1, paragraph.newLine, paragraph.character, paragraph.ascentDescentMode), new Paragraph(text2, !0, paragraph.character, paragraph.ascentDescentMode) ];
}
exports.default = Paragraph, exports.seperateParagraph = seperateParagraph;
//# sourceMappingURL=paragraph.js.map