UNPKG

phaser4-rex-plugins

Version:
364 lines (305 loc) 11.5 kB
import DrawMethods from './DrawMethods.js'; import PenManager from '../penmanger/PenManager.js'; import HitAreaManager from '../hitareamanager/HitAreaManager.js'; import SetInteractive from './SetInteractive.js'; import GetHitArea from './GetHitArea.js'; import CONST from '../../../textbase/const.js'; import WrapText from '../wraptext/WrapText.js'; import Clone from '../../../../utils/object/Clone.js'; const GetValue = Phaser.Utils.Objects.GetValue; const NO_WRAP = CONST.NO_WRAP; const NO_NEWLINE = CONST.NO_NEWLINE; const RAW_NEWLINE = CONST.RAW_NEWLINE; const WRAPPED_NEWLINE = CONST.WRAPPED_NEWLINE; class CanvasText { constructor(config) { this.parent = config.parent; this.scene = this.parent.scene; this.context = GetValue(config, 'context', null); this.canvas = this.context.canvas; this.parser = GetValue(config, 'parser', null); this.defaultStyle = GetValue(config, 'style', null); this.autoRound = true; this.pensPool = config.pensPool; // Required this.linesPool = config.linesPool; // Required this.wrapTextLinesPool = config.wrapTextLinesPool; // Required this.penManager = this.newPenManager(); this._tmpPenManager = null; this.hitAreaManager = new HitAreaManager(); this.lastHitAreaKey = null; this.urlTagCursorStyle = null; } destroy() { this.parent = undefined; this.scene = undefined; this.context = undefined; this.canvas = undefined; this.parser = undefined; this.defaultStyle = undefined; if (this.penManager) { this.penManager.destroy(); this.penManager = undefined; } if (this._tmpPenManager) { this._tmpPenManager.destroy(); this._tmpPenManager = undefined; } if (this.hitAreaManager) { this.hitAreaManager.destroy(); this.hitAreaManager = undefined; } this.pensPool = undefined; this.linesPool = undefined; this.wrapTextLinesPool = undefined; } updatePenManager(text, wrapMode, wrapWidth, lineHeight, penManager) { if (penManager === undefined) { penManager = this.penManager; } penManager.clear(); if (text === "") { return penManager; } var textStyle = this.parent.style; if (textStyle.isWrapFitMode) { var padding = this.parent.padding; wrapWidth = textStyle.fixedWidth - padding.left - padding.right; } var canvas = this.canvas; var context = this.context; var cursorX = 0, cursorY = 0; var customTextWrapCallback = textStyle.wrapCallback, customTextWrapCallbackScope = textStyle.wrapCallbackScope; var isBuiltInWrappingMode = (!customTextWrapCallback); var reuseLines = true; var plainText, curProp, curStyle; var match = this.parser.splitText(text), result, wrapLines, wrapTextLinesPool = this.wrapTextLinesPool; for (var i = 0, len = match.length; i < len; i++) { result = this.parser.tagTextToProp(match[i], curProp); plainText = result.plainText; curProp = result.prop; if (curProp.img) { // Image tag var imgWidth = this.imageManager.getOuterWidth(curProp.img); if ((wrapWidth > 0) && (wrapMode !== NO_WRAP)) { // Wrap mode if (wrapWidth < (cursorX + imgWidth)) { penManager.addNewLinePen(); cursorY += lineHeight; cursorX = 0; } } penManager.addImagePen(cursorX, cursorY, imgWidth, Clone(curProp)); cursorX += imgWidth; } else if (plainText !== '') { // wrap text to lines // Save the current context. context.save(); curStyle = this.parser.propToContextStyle(this.defaultStyle, curProp); curStyle.buildFont(); curStyle.syncFont(canvas, context); curStyle.syncStyle(canvas, context); if (isBuiltInWrappingMode) { wrapLines = WrapText( plainText, context, wrapMode, wrapWidth, curStyle.letterSpacing, cursorX, wrapTextLinesPool ); } else { // customTextWrapCallback wrapLines = customTextWrapCallback.call(customTextWrapCallbackScope, plainText, context, wrapWidth, curStyle.letterSpacing, cursorX ); if (typeof (wrapLines) === 'string') { wrapLines = wrapLines.split('\n'); } var segment; for (var j = 0, jLen = wrapLines.length; j < jLen; j++) { segment = wrapLines[j]; if (typeof (segment) === 'string') { wrapLines[j] = wrapTextLinesPool.getLine( segment, context.measureText(segment).width, (j < (jLen - 1)) ? WRAPPED_NEWLINE : NO_NEWLINE ); } else { reuseLines = false; } } } // customTextWrapCallback // add pens var segment; for (var j = 0, jLen = wrapLines.length; j < jLen; j++) { segment = wrapLines[j]; penManager.addTextPen( segment.text, cursorX, cursorY, segment.width, Clone(curProp), segment.newLineMode ); if (segment.newLineMode !== NO_NEWLINE) { cursorX = 0; cursorY += lineHeight; } else { cursorX += segment.width; } } if (reuseLines) { wrapTextLinesPool.freeLines(wrapLines); } wrapLines = null; context.restore(); } } // Process last pen of each line for (var i = 0, len = this.lines.length; i < len; i++) { // Last pen of a line var line = this.lines[i]; var lastPen = line[line.length - 1]; if (lastPen) { // Add strokeThinkness lastPen.width += this.parser.getStrokeThinkness(this.defaultStyle, lastPen.prop); // Remove letterSpacing lastPen.width -= this.parser.getLetterSpacing(this.defaultStyle, lastPen.prop); } } return penManager; } get startXOffset() { return this.defaultStyle.xOffset; } get startYOffset() { return this.defaultStyle.metrics.ascent; } get lines() { return this.penManager.lines; } get displayLinesCount() { var linesCount = this.penManager.linesCount, maxLines = this.defaultStyle.maxLines; if ((maxLines > 0) && (linesCount > maxLines)) { linesCount = maxLines; } return linesCount; } get linesWidth() { return Math.ceil(this.penManager.getMaxLineWidth()); } get linesHeight() { var linesCount = this.displayLinesCount; var linesHeight = (this.defaultStyle.lineHeight * linesCount); if (linesCount > 0) { linesHeight -= this.defaultStyle.lineSpacing; } return linesHeight; } get imageManager() { return this.parent.imageManager; } get rtl() { return this.parent.style.rtl; } newPenManager() { return new PenManager({ pensPool: this.pensPool, linesPool: this.linesPool, tagToText: this.parser.propToTagText, tagToTextScope: this.parser }); } get tmpPenManager() { if (this._tmpPenManager === null) { this._tmpPenManager = this.newPenManager(); } return this._tmpPenManager; } getPlainText(text, start, end) { var plainText; if (text == null) { plainText = this.penManager.plainText; } else { var m, match = this.parser.splitText(text, 1); // PLAINTEXTONLY_MODE plainText = ""; for (var i = 0, len = match.length; i < len; i++) { plainText += match[i]; } } if ((start != null) || (end != null)) { if (start == null) { start = 0; } if (end == null) { end = plainText.length; } plainText = plainText.substring(start, end); } return plainText; } getPenManager(text, retPenManager) { if (text === undefined) { return this.copyPenManager(retPenManager, this.penManager); } if (retPenManager === undefined) { retPenManager = this.newPenManager(); } var defaultStyle = this.defaultStyle; this.updatePenManager( text, defaultStyle.wrapMode, defaultStyle.wrapWidth, defaultStyle.lineHeight, retPenManager ); return retPenManager; } getText(text, start, end, wrap) { if (text == null) { return this.penManager.getSliceTagText(start, end, wrap); } var penManager = this.tmpPenManager; var defaultStyle = this.defaultStyle; this.updatePenManager( text, defaultStyle.wrapMode, defaultStyle.wrapWidth, defaultStyle.lineHeight, penManager ); return penManager.getSliceTagText(start, end, wrap); } copyPenManager(ret, src) { if (src === undefined) { src = this.penManager; } return src.copy(ret); } getTextWidth(penManager) { if (penManager === undefined) { penManager = this.penManager; } return penManager.getMaxLineWidth(); } getLastPen(penManager) { if (penManager === undefined) { penManager = this.penManager; } return penManager.lastPen; } }; var methods = { setInteractive: SetInteractive, getHitArea: GetHitArea, } Object.assign( CanvasText.prototype, DrawMethods, methods ); export default CanvasText;