| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116 |
- /*!
- * @pixi/text - v6.5.10
- * Compiled Thu, 06 Jul 2023 15:25:11 UTC
- *
- * @pixi/text is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license
- */
- this.PIXI = this.PIXI || {};
- var _pixi_text = (function (exports, sprite, core, settings, math, utils) {
- 'use strict';
- /*! *****************************************************************************
- Copyright (c) Microsoft Corporation.
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
- ***************************************************************************** */
- /* global Reflect, Promise */
- var extendStatics = function(d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) { if (b.hasOwnProperty(p)) { d[p] = b[p]; } } };
- return extendStatics(d, b);
- };
- function __extends(d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- }
- var __assign = function() {
- __assign = Object.assign || function __assign(t) {
- var arguments$1 = arguments;
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments$1[i];
- for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) { t[p] = s[p]; } }
- }
- return t;
- };
- return __assign.apply(this, arguments);
- };
- function __rest(s, e) {
- var t = {};
- for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
- { t[p] = s[p]; } }
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
- { for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
- { t[p[i]] = s[p[i]]; }
- } }
- return t;
- }
- function __decorate(decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") { r = Reflect.decorate(decorators, target, key, desc); }
- else { for (var i = decorators.length - 1; i >= 0; i--) { if (d = decorators[i]) { r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; } } }
- return c > 3 && r && Object.defineProperty(target, key, r), r;
- }
- function __param(paramIndex, decorator) {
- return function (target, key) { decorator(target, key, paramIndex); }
- }
- function __metadata(metadataKey, metadataValue) {
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") { return Reflect.metadata(metadataKey, metadataValue); }
- }
- function __awaiter(thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- }
- function __generator(thisArg, body) {
- var _ = { label: 0, sent: function() { if (t[0] & 1) { throw t[1]; } return t[1]; }, trys: [], ops: [] }, f, y, t, g;
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
- function verb(n) { return function (v) { return step([n, v]); }; }
- function step(op) {
- if (f) { throw new TypeError("Generator is already executing."); }
- while (_) { try {
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) { return t; }
- if (y = 0, t) { op = [op[0] & 2, t.value]; }
- switch (op[0]) {
- case 0: case 1: t = op; break;
- case 4: _.label++; return { value: op[1], done: false };
- case 5: _.label++; y = op[1]; op = [0]; continue;
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
- default:
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
- if (t[2]) { _.ops.pop(); }
- _.trys.pop(); continue;
- }
- op = body.call(thisArg, _);
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } }
- if (op[0] & 5) { throw op[1]; } return { value: op[0] ? op[1] : void 0, done: true };
- }
- }
- function __createBinding(o, m, k, k2) {
- if (k2 === undefined) { k2 = k; }
- o[k2] = m[k];
- }
- function __exportStar(m, exports) {
- for (var p in m) { if (p !== "default" && !exports.hasOwnProperty(p)) { exports[p] = m[p]; } }
- }
- function __values(o) {
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
- if (m) { return m.call(o); }
- if (o && typeof o.length === "number") { return {
- next: function () {
- if (o && i >= o.length) { o = void 0; }
- return { value: o && o[i++], done: !o };
- }
- }; }
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
- }
- function __read(o, n) {
- var m = typeof Symbol === "function" && o[Symbol.iterator];
- if (!m) { return o; }
- var i = m.call(o), r, ar = [], e;
- try {
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) { ar.push(r.value); }
- }
- catch (error) { e = { error: error }; }
- finally {
- try {
- if (r && !r.done && (m = i["return"])) { m.call(i); }
- }
- finally { if (e) { throw e.error; } }
- }
- return ar;
- }
- function __spread() {
- var arguments$1 = arguments;
- for (var ar = [], i = 0; i < arguments.length; i++)
- { ar = ar.concat(__read(arguments$1[i])); }
- return ar;
- }
- function __spreadArrays() {
- var arguments$1 = arguments;
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) { s += arguments$1[i].length; }
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
- { for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
- { r[k] = a[j]; } }
- return r;
- };
- function __await(v) {
- return this instanceof __await ? (this.v = v, this) : new __await(v);
- }
- function __asyncGenerator(thisArg, _arguments, generator) {
- if (!Symbol.asyncIterator) { throw new TypeError("Symbol.asyncIterator is not defined."); }
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
- function verb(n) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } }
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
- function fulfill(value) { resume("next", value); }
- function reject(value) { resume("throw", value); }
- function settle(f, v) { if (f(v), q.shift(), q.length) { resume(q[0][0], q[0][1]); } }
- }
- function __asyncDelegator(o) {
- var i, p;
- return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
- }
- function __asyncValues(o) {
- if (!Symbol.asyncIterator) { throw new TypeError("Symbol.asyncIterator is not defined."); }
- var m = o[Symbol.asyncIterator], i;
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
- }
- function __makeTemplateObject(cooked, raw) {
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
- return cooked;
- };
- function __importStar(mod) {
- if (mod && mod.__esModule) { return mod; }
- var result = {};
- if (mod != null) { for (var k in mod) { if (Object.hasOwnProperty.call(mod, k)) { result[k] = mod[k]; } } }
- result.default = mod;
- return result;
- }
- function __importDefault(mod) {
- return (mod && mod.__esModule) ? mod : { default: mod };
- }
- function __classPrivateFieldGet(receiver, privateMap) {
- if (!privateMap.has(receiver)) {
- throw new TypeError("attempted to get private field on non-instance");
- }
- return privateMap.get(receiver);
- }
- function __classPrivateFieldSet(receiver, privateMap, value) {
- if (!privateMap.has(receiver)) {
- throw new TypeError("attempted to set private field on non-instance");
- }
- privateMap.set(receiver, value);
- return value;
- }
- /**
- * Constants that define the type of gradient on text.
- * @static
- * @constant
- * @name TEXT_GRADIENT
- * @memberof PIXI
- * @type {object}
- * @property {number} LINEAR_VERTICAL Vertical gradient
- * @property {number} LINEAR_HORIZONTAL Linear gradient
- */
- exports.TEXT_GRADIENT = void 0;
- (function (TEXT_GRADIENT) {
- TEXT_GRADIENT[TEXT_GRADIENT["LINEAR_VERTICAL"] = 0] = "LINEAR_VERTICAL";
- TEXT_GRADIENT[TEXT_GRADIENT["LINEAR_HORIZONTAL"] = 1] = "LINEAR_HORIZONTAL";
- })(exports.TEXT_GRADIENT || (exports.TEXT_GRADIENT = {}));
- // disabling eslint for now, going to rewrite this in v5
- var defaultStyle = {
- align: 'left',
- breakWords: false,
- dropShadow: false,
- dropShadowAlpha: 1,
- dropShadowAngle: Math.PI / 6,
- dropShadowBlur: 0,
- dropShadowColor: 'black',
- dropShadowDistance: 5,
- fill: 'black',
- fillGradientType: exports.TEXT_GRADIENT.LINEAR_VERTICAL,
- fillGradientStops: [],
- fontFamily: 'Arial',
- fontSize: 26,
- fontStyle: 'normal',
- fontVariant: 'normal',
- fontWeight: 'normal',
- letterSpacing: 0,
- lineHeight: 0,
- lineJoin: 'miter',
- miterLimit: 10,
- padding: 0,
- stroke: 'black',
- strokeThickness: 0,
- textBaseline: 'alphabetic',
- trim: false,
- whiteSpace: 'pre',
- wordWrap: false,
- wordWrapWidth: 100,
- leading: 0,
- };
- var genericFontFamilies = [
- 'serif',
- 'sans-serif',
- 'monospace',
- 'cursive',
- 'fantasy',
- 'system-ui' ];
- /**
- * A TextStyle Object contains information to decorate a Text objects.
- *
- * An instance can be shared between multiple Text objects; then changing the style will update all text objects using it.
- *
- * A tool can be used to generate a text style [here](https://pixijs.io/pixi-text-style).
- *
- * @memberof PIXI
- */
- var TextStyle = /** @class */ (function () {
- /**
- * @param {object} [style] - The style parameters
- * @param {string} [style.align='left'] - Alignment for multiline text ('left', 'center' or 'right'),
- * does not affect single line text
- * @param {boolean} [style.breakWords=false] - Indicates if lines can be wrapped within words, it
- * needs wordWrap to be set to true
- * @param {boolean} [style.dropShadow=false] - Set a drop shadow for the text
- * @param {number} [style.dropShadowAlpha=1] - Set alpha for the drop shadow
- * @param {number} [style.dropShadowAngle=Math.PI/6] - Set a angle of the drop shadow
- * @param {number} [style.dropShadowBlur=0] - Set a shadow blur radius
- * @param {string|number} [style.dropShadowColor='black'] - A fill style to be used on the dropshadow e.g 'red', '#00FF00'
- * @param {number} [style.dropShadowDistance=5] - Set a distance of the drop shadow
- * @param {string|string[]|number|number[]|CanvasGradient|CanvasPattern} [style.fill='black'] - A canvas
- * fillstyle that will be used on the text e.g 'red', '#00FF00'. Can be an array to create a gradient
- * eg ['#000000','#FFFFFF']
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle|MDN}
- * @param {number} [style.fillGradientType=PIXI.TEXT_GRADIENT.LINEAR_VERTICAL] - If fill is an array of colours
- * to create a gradient, this can change the type/direction of the gradient. See {@link PIXI.TEXT_GRADIENT}
- * @param {number[]} [style.fillGradientStops] - If fill is an array of colours to create a gradient, this array can set
- * the stop points (numbers between 0 and 1) for the color, overriding the default behaviour of evenly spacing them.
- * @param {string|string[]} [style.fontFamily='Arial'] - The font family
- * @param {number|string} [style.fontSize=26] - The font size (as a number it converts to px, but as a string,
- * equivalents are '26px','20pt','160%' or '1.6em')
- * @param {string} [style.fontStyle='normal'] - The font style ('normal', 'italic' or 'oblique')
- * @param {string} [style.fontVariant='normal'] - The font variant ('normal' or 'small-caps')
- * @param {string} [style.fontWeight='normal'] - The font weight ('normal', 'bold', 'bolder', 'lighter' and '100',
- * '200', '300', '400', '500', '600', '700', '800' or '900')
- * @param {number} [style.leading=0] - The space between lines
- * @param {number} [style.letterSpacing=0] - The amount of spacing between letters, default is 0
- * @param {number} [style.lineHeight] - The line height, a number that represents the vertical space that a letter uses
- * @param {string} [style.lineJoin='miter'] - The lineJoin property sets the type of corner created, it can resolve
- * spiked text issues. Possible values "miter" (creates a sharp corner), "round" (creates a round corner) or "bevel"
- * (creates a squared corner).
- * @param {number} [style.miterLimit=10] - The miter limit to use when using the 'miter' lineJoin mode. This can reduce
- * or increase the spikiness of rendered text.
- * @param {number} [style.padding=0] - Occasionally some fonts are cropped. Adding some padding will prevent this from
- * happening by adding padding to all sides of the text.
- * @param {string|number} [style.stroke='black'] - A canvas fillstyle that will be used on the text stroke
- * e.g 'blue', '#FCFF00'
- * @param {number} [style.strokeThickness=0] - A number that represents the thickness of the stroke.
- * Default is 0 (no stroke)
- * @param {boolean} [style.trim=false] - Trim transparent borders
- * @param {string} [style.textBaseline='alphabetic'] - The baseline of the text that is rendered.
- * @param {string} [style.whiteSpace='pre'] - Determines whether newlines & spaces are collapsed or preserved "normal"
- * (collapse, collapse), "pre" (preserve, preserve) | "pre-line" (preserve, collapse). It needs wordWrap to be set to true
- * @param {boolean} [style.wordWrap=false] - Indicates if word wrap should be used
- * @param {number} [style.wordWrapWidth=100] - The width at which text will wrap, it needs wordWrap to be set to true
- */
- function TextStyle(style) {
- this.styleID = 0;
- this.reset();
- deepCopyProperties(this, style, style);
- }
- /**
- * Creates a new TextStyle object with the same values as this one.
- * Note that the only the properties of the object are cloned.
- *
- * @return New cloned TextStyle object
- */
- TextStyle.prototype.clone = function () {
- var clonedProperties = {};
- deepCopyProperties(clonedProperties, this, defaultStyle);
- return new TextStyle(clonedProperties);
- };
- /** Resets all properties to the defaults specified in TextStyle.prototype._default */
- TextStyle.prototype.reset = function () {
- deepCopyProperties(this, defaultStyle, defaultStyle);
- };
- Object.defineProperty(TextStyle.prototype, "align", {
- /**
- * Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
- *
- * @member {string}
- */
- get: function () {
- return this._align;
- },
- set: function (align) {
- if (this._align !== align) {
- this._align = align;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "breakWords", {
- /** Indicates if lines can be wrapped within words, it needs wordWrap to be set to true. */
- get: function () {
- return this._breakWords;
- },
- set: function (breakWords) {
- if (this._breakWords !== breakWords) {
- this._breakWords = breakWords;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadow", {
- /** Set a drop shadow for the text. */
- get: function () {
- return this._dropShadow;
- },
- set: function (dropShadow) {
- if (this._dropShadow !== dropShadow) {
- this._dropShadow = dropShadow;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadowAlpha", {
- /** Set alpha for the drop shadow. */
- get: function () {
- return this._dropShadowAlpha;
- },
- set: function (dropShadowAlpha) {
- if (this._dropShadowAlpha !== dropShadowAlpha) {
- this._dropShadowAlpha = dropShadowAlpha;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadowAngle", {
- /** Set a angle of the drop shadow. */
- get: function () {
- return this._dropShadowAngle;
- },
- set: function (dropShadowAngle) {
- if (this._dropShadowAngle !== dropShadowAngle) {
- this._dropShadowAngle = dropShadowAngle;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadowBlur", {
- /** Set a shadow blur radius. */
- get: function () {
- return this._dropShadowBlur;
- },
- set: function (dropShadowBlur) {
- if (this._dropShadowBlur !== dropShadowBlur) {
- this._dropShadowBlur = dropShadowBlur;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadowColor", {
- /** A fill style to be used on the dropshadow e.g 'red', '#00FF00'. */
- get: function () {
- return this._dropShadowColor;
- },
- set: function (dropShadowColor) {
- var outputColor = getColor(dropShadowColor);
- if (this._dropShadowColor !== outputColor) {
- this._dropShadowColor = outputColor;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "dropShadowDistance", {
- /** Set a distance of the drop shadow. */
- get: function () {
- return this._dropShadowDistance;
- },
- set: function (dropShadowDistance) {
- if (this._dropShadowDistance !== dropShadowDistance) {
- this._dropShadowDistance = dropShadowDistance;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fill", {
- /**
- * A canvas fillstyle that will be used on the text e.g 'red', '#00FF00'.
- *
- * Can be an array to create a gradient eg ['#000000','#FFFFFF']
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle|MDN}
- *
- * @member {string|string[]|number|number[]|CanvasGradient|CanvasPattern}
- */
- get: function () {
- return this._fill;
- },
- set: function (fill) {
- // TODO: Can't have different types for getter and setter. The getter shouldn't have the number type as
- // the setter converts to string. See this thread for more details:
- // https://github.com/microsoft/TypeScript/issues/2521
- // TODO: Not sure if getColor works properly with CanvasGradient and/or CanvasPattern, can't pass in
- // without casting here.
- var outputColor = getColor(fill);
- if (this._fill !== outputColor) {
- this._fill = outputColor;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fillGradientType", {
- /**
- * If fill is an array of colours to create a gradient, this can change the type/direction of the gradient.
- *
- * @see PIXI.TEXT_GRADIENT
- */
- get: function () {
- return this._fillGradientType;
- },
- set: function (fillGradientType) {
- if (this._fillGradientType !== fillGradientType) {
- this._fillGradientType = fillGradientType;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fillGradientStops", {
- /**
- * If fill is an array of colours to create a gradient, this array can set the stop points
- * (numbers between 0 and 1) for the color, overriding the default behaviour of evenly spacing them.
- */
- get: function () {
- return this._fillGradientStops;
- },
- set: function (fillGradientStops) {
- if (!areArraysEqual(this._fillGradientStops, fillGradientStops)) {
- this._fillGradientStops = fillGradientStops;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fontFamily", {
- /** The font family. */
- get: function () {
- return this._fontFamily;
- },
- set: function (fontFamily) {
- if (this.fontFamily !== fontFamily) {
- this._fontFamily = fontFamily;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fontSize", {
- /**
- * The font size
- * (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em')
- */
- get: function () {
- return this._fontSize;
- },
- set: function (fontSize) {
- if (this._fontSize !== fontSize) {
- this._fontSize = fontSize;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fontStyle", {
- /**
- * The font style
- * ('normal', 'italic' or 'oblique')
- *
- * @member {string}
- */
- get: function () {
- return this._fontStyle;
- },
- set: function (fontStyle) {
- if (this._fontStyle !== fontStyle) {
- this._fontStyle = fontStyle;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fontVariant", {
- /**
- * The font variant
- * ('normal' or 'small-caps')
- *
- * @member {string}
- */
- get: function () {
- return this._fontVariant;
- },
- set: function (fontVariant) {
- if (this._fontVariant !== fontVariant) {
- this._fontVariant = fontVariant;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "fontWeight", {
- /**
- * The font weight
- * ('normal', 'bold', 'bolder', 'lighter' and '100', '200', '300', '400', '500', '600', '700', 800' or '900')
- *
- * @member {string}
- */
- get: function () {
- return this._fontWeight;
- },
- set: function (fontWeight) {
- if (this._fontWeight !== fontWeight) {
- this._fontWeight = fontWeight;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "letterSpacing", {
- /** The amount of spacing between letters, default is 0. */
- get: function () {
- return this._letterSpacing;
- },
- set: function (letterSpacing) {
- if (this._letterSpacing !== letterSpacing) {
- this._letterSpacing = letterSpacing;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "lineHeight", {
- /** The line height, a number that represents the vertical space that a letter uses. */
- get: function () {
- return this._lineHeight;
- },
- set: function (lineHeight) {
- if (this._lineHeight !== lineHeight) {
- this._lineHeight = lineHeight;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "leading", {
- /** The space between lines. */
- get: function () {
- return this._leading;
- },
- set: function (leading) {
- if (this._leading !== leading) {
- this._leading = leading;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "lineJoin", {
- /**
- * The lineJoin property sets the type of corner created, it can resolve spiked text issues.
- * Default is 'miter' (creates a sharp corner).
- *
- * @member {string}
- */
- get: function () {
- return this._lineJoin;
- },
- set: function (lineJoin) {
- if (this._lineJoin !== lineJoin) {
- this._lineJoin = lineJoin;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "miterLimit", {
- /**
- * The miter limit to use when using the 'miter' lineJoin mode.
- *
- * This can reduce or increase the spikiness of rendered text.
- */
- get: function () {
- return this._miterLimit;
- },
- set: function (miterLimit) {
- if (this._miterLimit !== miterLimit) {
- this._miterLimit = miterLimit;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "padding", {
- /**
- * Occasionally some fonts are cropped. Adding some padding will prevent this from happening
- * by adding padding to all sides of the text.
- */
- get: function () {
- return this._padding;
- },
- set: function (padding) {
- if (this._padding !== padding) {
- this._padding = padding;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "stroke", {
- /**
- * A canvas fillstyle that will be used on the text stroke
- * e.g 'blue', '#FCFF00'
- */
- get: function () {
- return this._stroke;
- },
- set: function (stroke) {
- // TODO: Can't have different types for getter and setter. The getter shouldn't have the number type as
- // the setter converts to string. See this thread for more details:
- // https://github.com/microsoft/TypeScript/issues/2521
- var outputColor = getColor(stroke);
- if (this._stroke !== outputColor) {
- this._stroke = outputColor;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "strokeThickness", {
- /**
- * A number that represents the thickness of the stroke.
- *
- * @default 0
- */
- get: function () {
- return this._strokeThickness;
- },
- set: function (strokeThickness) {
- if (this._strokeThickness !== strokeThickness) {
- this._strokeThickness = strokeThickness;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "textBaseline", {
- /**
- * The baseline of the text that is rendered.
- *
- * @member {string}
- */
- get: function () {
- return this._textBaseline;
- },
- set: function (textBaseline) {
- if (this._textBaseline !== textBaseline) {
- this._textBaseline = textBaseline;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "trim", {
- /** Trim transparent borders. */
- get: function () {
- return this._trim;
- },
- set: function (trim) {
- if (this._trim !== trim) {
- this._trim = trim;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "whiteSpace", {
- /**
- * How newlines and spaces should be handled.
- * Default is 'pre' (preserve, preserve).
- *
- * value | New lines | Spaces
- * --- | --- | ---
- * 'normal' | Collapse | Collapse
- * 'pre' | Preserve | Preserve
- * 'pre-line' | Preserve | Collapse
- *
- * @member {string}
- */
- get: function () {
- return this._whiteSpace;
- },
- set: function (whiteSpace) {
- if (this._whiteSpace !== whiteSpace) {
- this._whiteSpace = whiteSpace;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "wordWrap", {
- /** Indicates if word wrap should be used. */
- get: function () {
- return this._wordWrap;
- },
- set: function (wordWrap) {
- if (this._wordWrap !== wordWrap) {
- this._wordWrap = wordWrap;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextStyle.prototype, "wordWrapWidth", {
- /** The width at which text will wrap, it needs wordWrap to be set to true. */
- get: function () {
- return this._wordWrapWidth;
- },
- set: function (wordWrapWidth) {
- if (this._wordWrapWidth !== wordWrapWidth) {
- this._wordWrapWidth = wordWrapWidth;
- this.styleID++;
- }
- },
- enumerable: false,
- configurable: true
- });
- /**
- * Generates a font style string to use for `TextMetrics.measureFont()`.
- *
- * @return Font style string, for passing to `TextMetrics.measureFont()`
- */
- TextStyle.prototype.toFontString = function () {
- // build canvas api font setting from individual components. Convert a numeric this.fontSize to px
- var fontSizeString = (typeof this.fontSize === 'number') ? this.fontSize + "px" : this.fontSize;
- // Clean-up fontFamily property by quoting each font name
- // this will support font names with spaces
- var fontFamilies = this.fontFamily;
- if (!Array.isArray(this.fontFamily)) {
- fontFamilies = this.fontFamily.split(',');
- }
- for (var i = fontFamilies.length - 1; i >= 0; i--) {
- // Trim any extra white-space
- var fontFamily = fontFamilies[i].trim();
- // Check if font already contains strings
- if (!(/([\"\'])[^\'\"]+\1/).test(fontFamily) && genericFontFamilies.indexOf(fontFamily) < 0) {
- fontFamily = "\"" + fontFamily + "\"";
- }
- fontFamilies[i] = fontFamily;
- }
- return this.fontStyle + " " + this.fontVariant + " " + this.fontWeight + " " + fontSizeString + " " + fontFamilies.join(',');
- };
- return TextStyle;
- }());
- /**
- * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string.
- * @private
- * @param color
- * @return The color as a string.
- */
- function getSingleColor(color) {
- if (typeof color === 'number') {
- return utils.hex2string(color);
- }
- else if (typeof color === 'string') {
- if (color.indexOf('0x') === 0) {
- color = color.replace('0x', '#');
- }
- }
- return color;
- }
- function getColor(color) {
- if (!Array.isArray(color)) {
- return getSingleColor(color);
- }
- else {
- for (var i = 0; i < color.length; ++i) {
- color[i] = getSingleColor(color[i]);
- }
- return color;
- }
- }
- /**
- * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string.
- * This version can also convert array of colors
- * @private
- * @param array1 - First array to compare
- * @param array2 - Second array to compare
- * @return Do the arrays contain the same values in the same order
- */
- function areArraysEqual(array1, array2) {
- if (!Array.isArray(array1) || !Array.isArray(array2)) {
- return false;
- }
- if (array1.length !== array2.length) {
- return false;
- }
- for (var i = 0; i < array1.length; ++i) {
- if (array1[i] !== array2[i]) {
- return false;
- }
- }
- return true;
- }
- /**
- * Utility function to ensure that object properties are copied by value, and not by reference
- * @private
- * @param target - Target object to copy properties into
- * @param source - Source object for the properties to copy
- * @param propertyObj - Object containing properties names we want to loop over
- */
- function deepCopyProperties(target, source, propertyObj) {
- for (var prop in propertyObj) {
- if (Array.isArray(source[prop])) {
- target[prop] = source[prop].slice();
- }
- else {
- target[prop] = source[prop];
- }
- }
- }
- // Default settings used for all getContext calls
- var contextSettings = {
- // TextMetrics requires getImageData readback for measuring fonts.
- willReadFrequently: true,
- };
- /**
- * The TextMetrics object represents the measurement of a block of text with a specified style.
- *
- * ```js
- * let style = new PIXI.TextStyle({fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'})
- * let textMetrics = PIXI.TextMetrics.measureText('Your text', style)
- * ```
- * @memberof PIXI
- */
- var TextMetrics = /** @class */ (function () {
- /**
- * @param text - the text that was measured
- * @param style - the style that was measured
- * @param width - the measured width of the text
- * @param height - the measured height of the text
- * @param lines - an array of the lines of text broken by new lines and wrapping if specified in style
- * @param lineWidths - an array of the line widths for each line matched to `lines`
- * @param lineHeight - the measured line height for this style
- * @param maxLineWidth - the maximum line width for all measured lines
- * @param {PIXI.IFontMetrics} fontProperties - the font properties object from TextMetrics.measureFont
- */
- function TextMetrics(text, style, width, height, lines, lineWidths, lineHeight, maxLineWidth, fontProperties) {
- this.text = text;
- this.style = style;
- this.width = width;
- this.height = height;
- this.lines = lines;
- this.lineWidths = lineWidths;
- this.lineHeight = lineHeight;
- this.maxLineWidth = maxLineWidth;
- this.fontProperties = fontProperties;
- }
- /**
- * Measures the supplied string of text and returns a Rectangle.
- * @param text - The text to measure.
- * @param style - The text style to use for measuring
- * @param wordWrap - Override for if word-wrap should be applied to the text.
- * @param canvas - optional specification of the canvas to use for measuring.
- * @returns Measured width and height of the text.
- */
- TextMetrics.measureText = function (text, style, wordWrap, canvas) {
- if (canvas === void 0) { canvas = TextMetrics._canvas; }
- wordWrap = (wordWrap === undefined || wordWrap === null) ? style.wordWrap : wordWrap;
- var font = style.toFontString();
- var fontProperties = TextMetrics.measureFont(font);
- // fallback in case UA disallow canvas data extraction
- // (toDataURI, getImageData functions)
- if (fontProperties.fontSize === 0) {
- fontProperties.fontSize = style.fontSize;
- fontProperties.ascent = style.fontSize;
- }
- var context = canvas.getContext('2d', contextSettings);
- context.font = font;
- var outputText = wordWrap ? TextMetrics.wordWrap(text, style, canvas) : text;
- var lines = outputText.split(/(?:\r\n|\r|\n)/);
- var lineWidths = new Array(lines.length);
- var maxLineWidth = 0;
- for (var i = 0; i < lines.length; i++) {
- var lineWidth = context.measureText(lines[i]).width + ((lines[i].length - 1) * style.letterSpacing);
- lineWidths[i] = lineWidth;
- maxLineWidth = Math.max(maxLineWidth, lineWidth);
- }
- var width = maxLineWidth + style.strokeThickness;
- if (style.dropShadow) {
- width += style.dropShadowDistance;
- }
- var lineHeight = style.lineHeight || fontProperties.fontSize + style.strokeThickness;
- var height = Math.max(lineHeight, fontProperties.fontSize + style.strokeThickness)
- + ((lines.length - 1) * (lineHeight + style.leading));
- if (style.dropShadow) {
- height += style.dropShadowDistance;
- }
- return new TextMetrics(text, style, width, height, lines, lineWidths, lineHeight + style.leading, maxLineWidth, fontProperties);
- };
- /**
- * Applies newlines to a string to have it optimally fit into the horizontal
- * bounds set by the Text object's wordWrapWidth property.
- * @param text - String to apply word wrapping to
- * @param style - the style to use when wrapping
- * @param canvas - optional specification of the canvas to use for measuring.
- * @returns New string with new lines applied where required
- */
- TextMetrics.wordWrap = function (text, style, canvas) {
- if (canvas === void 0) { canvas = TextMetrics._canvas; }
- var context = canvas.getContext('2d', contextSettings);
- var width = 0;
- var line = '';
- var lines = '';
- var cache = Object.create(null);
- var letterSpacing = style.letterSpacing, whiteSpace = style.whiteSpace;
- // How to handle whitespaces
- var collapseSpaces = TextMetrics.collapseSpaces(whiteSpace);
- var collapseNewlines = TextMetrics.collapseNewlines(whiteSpace);
- // whether or not spaces may be added to the beginning of lines
- var canPrependSpaces = !collapseSpaces;
- // There is letterSpacing after every char except the last one
- // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!
- // so for convenience the above needs to be compared to width + 1 extra letterSpace
- // t_h_i_s_' '_i_s_' '_a_n_' '_e_x_a_m_p_l_e_' '_!_
- // ________________________________________________
- // And then the final space is simply no appended to each line
- var wordWrapWidth = style.wordWrapWidth + letterSpacing;
- // break text into words, spaces and newline chars
- var tokens = TextMetrics.tokenize(text);
- for (var i = 0; i < tokens.length; i++) {
- // get the word, space or newlineChar
- var token = tokens[i];
- // if word is a new line
- if (TextMetrics.isNewline(token)) {
- // keep the new line
- if (!collapseNewlines) {
- lines += TextMetrics.addLine(line);
- canPrependSpaces = !collapseSpaces;
- line = '';
- width = 0;
- continue;
- }
- // if we should collapse new lines
- // we simply convert it into a space
- token = ' ';
- }
- // if we should collapse repeated whitespaces
- if (collapseSpaces) {
- // check both this and the last tokens for spaces
- var currIsBreakingSpace = TextMetrics.isBreakingSpace(token);
- var lastIsBreakingSpace = TextMetrics.isBreakingSpace(line[line.length - 1]);
- if (currIsBreakingSpace && lastIsBreakingSpace) {
- continue;
- }
- }
- // get word width from cache if possible
- var tokenWidth = TextMetrics.getFromCache(token, letterSpacing, cache, context);
- // word is longer than desired bounds
- if (tokenWidth > wordWrapWidth) {
- // if we are not already at the beginning of a line
- if (line !== '') {
- // start newlines for overflow words
- lines += TextMetrics.addLine(line);
- line = '';
- width = 0;
- }
- // break large word over multiple lines
- if (TextMetrics.canBreakWords(token, style.breakWords)) {
- // break word into characters
- var characters = TextMetrics.wordWrapSplit(token);
- // loop the characters
- for (var j = 0; j < characters.length; j++) {
- var char = characters[j];
- var k = 1;
- // we are not at the end of the token
- while (characters[j + k]) {
- var nextChar = characters[j + k];
- var lastChar = char[char.length - 1];
- // should not split chars
- if (!TextMetrics.canBreakChars(lastChar, nextChar, token, j, style.breakWords)) {
- // combine chars & move forward one
- char += nextChar;
- }
- else {
- break;
- }
- k++;
- }
- j += char.length - 1;
- var characterWidth = TextMetrics.getFromCache(char, letterSpacing, cache, context);
- if (characterWidth + width > wordWrapWidth) {
- lines += TextMetrics.addLine(line);
- canPrependSpaces = false;
- line = '';
- width = 0;
- }
- line += char;
- width += characterWidth;
- }
- }
- // run word out of the bounds
- else {
- // if there are words in this line already
- // finish that line and start a new one
- if (line.length > 0) {
- lines += TextMetrics.addLine(line);
- line = '';
- width = 0;
- }
- var isLastToken = i === tokens.length - 1;
- // give it its own line if it's not the end
- lines += TextMetrics.addLine(token, !isLastToken);
- canPrependSpaces = false;
- line = '';
- width = 0;
- }
- }
- // word could fit
- else {
- // word won't fit because of existing words
- // start a new line
- if (tokenWidth + width > wordWrapWidth) {
- // if its a space we don't want it
- canPrependSpaces = false;
- // add a new line
- lines += TextMetrics.addLine(line);
- // start a new line
- line = '';
- width = 0;
- }
- // don't add spaces to the beginning of lines
- if (line.length > 0 || !TextMetrics.isBreakingSpace(token) || canPrependSpaces) {
- // add the word to the current line
- line += token;
- // update width counter
- width += tokenWidth;
- }
- }
- }
- lines += TextMetrics.addLine(line, false);
- return lines;
- };
- /**
- * Convienience function for logging each line added during the wordWrap method.
- * @param line - The line of text to add
- * @param newLine - Add new line character to end
- * @returns A formatted line
- */
- TextMetrics.addLine = function (line, newLine) {
- if (newLine === void 0) { newLine = true; }
- line = TextMetrics.trimRight(line);
- line = (newLine) ? line + "\n" : line;
- return line;
- };
- /**
- * Gets & sets the widths of calculated characters in a cache object
- * @param key - The key
- * @param letterSpacing - The letter spacing
- * @param cache - The cache
- * @param context - The canvas context
- * @returns The from cache.
- */
- TextMetrics.getFromCache = function (key, letterSpacing, cache, context) {
- var width = cache[key];
- if (typeof width !== 'number') {
- var spacing = ((key.length) * letterSpacing);
- width = context.measureText(key).width + spacing;
- cache[key] = width;
- }
- return width;
- };
- /**
- * Determines whether we should collapse breaking spaces.
- * @param whiteSpace - The TextStyle property whiteSpace
- * @returns Should collapse
- */
- TextMetrics.collapseSpaces = function (whiteSpace) {
- return (whiteSpace === 'normal' || whiteSpace === 'pre-line');
- };
- /**
- * Determines whether we should collapse newLine chars.
- * @param whiteSpace - The white space
- * @returns should collapse
- */
- TextMetrics.collapseNewlines = function (whiteSpace) {
- return (whiteSpace === 'normal');
- };
- /**
- * Trims breaking whitespaces from string.
- * @param text - The text
- * @returns Trimmed string
- */
- TextMetrics.trimRight = function (text) {
- if (typeof text !== 'string') {
- return '';
- }
- for (var i = text.length - 1; i >= 0; i--) {
- var char = text[i];
- if (!TextMetrics.isBreakingSpace(char)) {
- break;
- }
- text = text.slice(0, -1);
- }
- return text;
- };
- /**
- * Determines if char is a newline.
- * @param char - The character
- * @returns True if newline, False otherwise.
- */
- TextMetrics.isNewline = function (char) {
- if (typeof char !== 'string') {
- return false;
- }
- return (TextMetrics._newlines.indexOf(char.charCodeAt(0)) >= 0);
- };
- /**
- * Determines if char is a breaking whitespace.
- *
- * It allows one to determine whether char should be a breaking whitespace
- * For example certain characters in CJK langs or numbers.
- * It must return a boolean.
- * @param char - The character
- * @param [_nextChar] - The next character
- * @returns True if whitespace, False otherwise.
- */
- TextMetrics.isBreakingSpace = function (char, _nextChar) {
- if (typeof char !== 'string') {
- return false;
- }
- return (TextMetrics._breakingSpaces.indexOf(char.charCodeAt(0)) >= 0);
- };
- /**
- * Splits a string into words, breaking-spaces and newLine characters
- * @param text - The text
- * @returns A tokenized array
- */
- TextMetrics.tokenize = function (text) {
- var tokens = [];
- var token = '';
- if (typeof text !== 'string') {
- return tokens;
- }
- for (var i = 0; i < text.length; i++) {
- var char = text[i];
- var nextChar = text[i + 1];
- if (TextMetrics.isBreakingSpace(char, nextChar) || TextMetrics.isNewline(char)) {
- if (token !== '') {
- tokens.push(token);
- token = '';
- }
- tokens.push(char);
- continue;
- }
- token += char;
- }
- if (token !== '') {
- tokens.push(token);
- }
- return tokens;
- };
- /**
- * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.
- *
- * It allows one to customise which words should break
- * Examples are if the token is CJK or numbers.
- * It must return a boolean.
- * @param _token - The token
- * @param breakWords - The style attr break words
- * @returns Whether to break word or not
- */
- TextMetrics.canBreakWords = function (_token, breakWords) {
- return breakWords;
- };
- /**
- * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.
- *
- * It allows one to determine whether a pair of characters
- * should be broken by newlines
- * For example certain characters in CJK langs or numbers.
- * It must return a boolean.
- * @param _char - The character
- * @param _nextChar - The next character
- * @param _token - The token/word the characters are from
- * @param _index - The index in the token of the char
- * @param _breakWords - The style attr break words
- * @returns whether to break word or not
- */
- TextMetrics.canBreakChars = function (_char, _nextChar, _token, _index, _breakWords) {
- return true;
- };
- /**
- * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior.
- *
- * It is called when a token (usually a word) has to be split into separate pieces
- * in order to determine the point to break a word.
- * It must return an array of characters.
- * @example
- * // Correctly splits emojis, eg "🤪🤪" will result in two element array, each with one emoji.
- * TextMetrics.wordWrapSplit = (token) => [...token];
- * @param token - The token to split
- * @returns The characters of the token
- */
- TextMetrics.wordWrapSplit = function (token) {
- return token.split('');
- };
- /**
- * Calculates the ascent, descent and fontSize of a given font-style
- * @param font - String representing the style of the font
- * @returns Font properties object
- */
- TextMetrics.measureFont = function (font) {
- // as this method is used for preparing assets, don't recalculate things if we don't need to
- if (TextMetrics._fonts[font]) {
- return TextMetrics._fonts[font];
- }
- var properties = {
- ascent: 0,
- descent: 0,
- fontSize: 0,
- };
- var canvas = TextMetrics._canvas;
- var context = TextMetrics._context;
- context.font = font;
- var metricsString = TextMetrics.METRICS_STRING + TextMetrics.BASELINE_SYMBOL;
- var width = Math.ceil(context.measureText(metricsString).width);
- var baseline = Math.ceil(context.measureText(TextMetrics.BASELINE_SYMBOL).width);
- var height = Math.ceil(TextMetrics.HEIGHT_MULTIPLIER * baseline);
- baseline = baseline * TextMetrics.BASELINE_MULTIPLIER | 0;
- canvas.width = width;
- canvas.height = height;
- context.fillStyle = '#f00';
- context.fillRect(0, 0, width, height);
- context.font = font;
- context.textBaseline = 'alphabetic';
- context.fillStyle = '#000';
- context.fillText(metricsString, 0, baseline);
- var imagedata = context.getImageData(0, 0, width, height).data;
- var pixels = imagedata.length;
- var line = width * 4;
- var i = 0;
- var idx = 0;
- var stop = false;
- // ascent. scan from top to bottom until we find a non red pixel
- for (i = 0; i < baseline; ++i) {
- for (var j = 0; j < line; j += 4) {
- if (imagedata[idx + j] !== 255) {
- stop = true;
- break;
- }
- }
- if (!stop) {
- idx += line;
- }
- else {
- break;
- }
- }
- properties.ascent = baseline - i;
- idx = pixels - line;
- stop = false;
- // descent. scan from bottom to top until we find a non red pixel
- for (i = height; i > baseline; --i) {
- for (var j = 0; j < line; j += 4) {
- if (imagedata[idx + j] !== 255) {
- stop = true;
- break;
- }
- }
- if (!stop) {
- idx -= line;
- }
- else {
- break;
- }
- }
- properties.descent = i - baseline;
- properties.fontSize = properties.ascent + properties.descent;
- TextMetrics._fonts[font] = properties;
- return properties;
- };
- /**
- * Clear font metrics in metrics cache.
- * @param {string} [font] - font name. If font name not set then clear cache for all fonts.
- */
- TextMetrics.clearMetrics = function (font) {
- if (font === void 0) { font = ''; }
- if (font) {
- delete TextMetrics._fonts[font];
- }
- else {
- TextMetrics._fonts = {};
- }
- };
- Object.defineProperty(TextMetrics, "_canvas", {
- /**
- * Cached canvas element for measuring text
- * TODO: this should be private, but isn't because of backward compat, will fix later.
- * @ignore
- */
- get: function () {
- if (!TextMetrics.__canvas) {
- var canvas = void 0;
- try {
- // OffscreenCanvas2D measureText can be up to 40% faster.
- var c = new OffscreenCanvas(0, 0);
- var context = c.getContext('2d', contextSettings);
- if (context && context.measureText) {
- TextMetrics.__canvas = c;
- return c;
- }
- canvas = settings.settings.ADAPTER.createCanvas();
- }
- catch (ex) {
- canvas = settings.settings.ADAPTER.createCanvas();
- }
- canvas.width = canvas.height = 10;
- TextMetrics.__canvas = canvas;
- }
- return TextMetrics.__canvas;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(TextMetrics, "_context", {
- /**
- * TODO: this should be private, but isn't because of backward compat, will fix later.
- * @ignore
- */
- get: function () {
- if (!TextMetrics.__context) {
- TextMetrics.__context = TextMetrics._canvas.getContext('2d', contextSettings);
- }
- return TextMetrics.__context;
- },
- enumerable: false,
- configurable: true
- });
- return TextMetrics;
- }());
- /**
- * Internal return object for {@link PIXI.TextMetrics.measureFont `TextMetrics.measureFont`}.
- * @typedef {object} FontMetrics
- * @property {number} ascent - The ascent distance
- * @property {number} descent - The descent distance
- * @property {number} fontSize - Font size from ascent to descent
- * @memberof PIXI.TextMetrics
- * @private
- */
- /**
- * Cache of {@see PIXI.TextMetrics.FontMetrics} objects.
- * @memberof PIXI.TextMetrics
- * @type {object}
- * @private
- */
- TextMetrics._fonts = {};
- /**
- * String used for calculate font metrics.
- * These characters are all tall to help calculate the height required for text.
- * @static
- * @memberof PIXI.TextMetrics
- * @name METRICS_STRING
- * @type {string}
- * @default |ÉqÅ
- */
- TextMetrics.METRICS_STRING = '|ÉqÅ';
- /**
- * Baseline symbol for calculate font metrics.
- * @static
- * @memberof PIXI.TextMetrics
- * @name BASELINE_SYMBOL
- * @type {string}
- * @default M
- */
- TextMetrics.BASELINE_SYMBOL = 'M';
- /**
- * Baseline multiplier for calculate font metrics.
- * @static
- * @memberof PIXI.TextMetrics
- * @name BASELINE_MULTIPLIER
- * @type {number}
- * @default 1.4
- */
- TextMetrics.BASELINE_MULTIPLIER = 1.4;
- /**
- * Height multiplier for setting height of canvas to calculate font metrics.
- * @static
- * @memberof PIXI.TextMetrics
- * @name HEIGHT_MULTIPLIER
- * @type {number}
- * @default 2.00
- */
- TextMetrics.HEIGHT_MULTIPLIER = 2.0;
- /**
- * Cache of new line chars.
- * @memberof PIXI.TextMetrics
- * @type {number[]}
- * @private
- */
- TextMetrics._newlines = [
- 0x000A,
- 0x000D ];
- /**
- * Cache of breaking spaces.
- * @memberof PIXI.TextMetrics
- * @type {number[]}
- * @private
- */
- TextMetrics._breakingSpaces = [
- 0x0009,
- 0x0020,
- 0x2000,
- 0x2001,
- 0x2002,
- 0x2003,
- 0x2004,
- 0x2005,
- 0x2006,
- 0x2008,
- 0x2009,
- 0x200A,
- 0x205F,
- 0x3000 ];
- /**
- * A number, or a string containing a number.
- * @memberof PIXI
- * @typedef {object} IFontMetrics
- * @property {number} ascent - Font ascent
- * @property {number} descent - Font descent
- * @property {number} fontSize - Font size
- */
- var defaultDestroyOptions = {
- texture: true,
- children: false,
- baseTexture: true,
- };
- /**
- * A Text Object will create a line or multiple lines of text.
- *
- * The text is created using the [Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API).
- *
- * The primary advantage of this class over BitmapText is that you have great control over the style of the text,
- * which you can change at runtime.
- *
- * The primary disadvantages is that each piece of text has it's own texture, which can use more memory.
- * When text changes, this texture has to be re-generated and re-uploaded to the GPU, taking up time.
- *
- * To split a line you can use '\n' in your text string, or, on the `style` object,
- * change its `wordWrap` property to true and and give the `wordWrapWidth` property a value.
- *
- * A Text can be created directly from a string and a style object,
- * which can be generated [here](https://pixijs.io/pixi-text-style).
- *
- * ```js
- * let text = new PIXI.Text('This is a PixiJS text',{fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'});
- * ```
- * @memberof PIXI
- */
- var Text = /** @class */ (function (_super) {
- __extends(Text, _super);
- /**
- * @param text - The string that you would like the text to display
- * @param {object|PIXI.TextStyle} [style] - The style parameters
- * @param canvas - The canvas element for drawing text
- */
- function Text(text, style, canvas) {
- var _this = this;
- var ownCanvas = false;
- if (!canvas) {
- canvas = settings.settings.ADAPTER.createCanvas();
- ownCanvas = true;
- }
- canvas.width = 3;
- canvas.height = 3;
- var texture = core.Texture.from(canvas);
- texture.orig = new math.Rectangle();
- texture.trim = new math.Rectangle();
- _this = _super.call(this, texture) || this;
- _this._ownCanvas = ownCanvas;
- _this.canvas = canvas;
- _this.context = canvas.getContext('2d', {
- // required for trimming to work without warnings
- willReadFrequently: true,
- });
- _this._resolution = settings.settings.RESOLUTION;
- _this._autoResolution = true;
- _this._text = null;
- _this._style = null;
- _this._styleListener = null;
- _this._font = '';
- _this.text = text;
- _this.style = style;
- _this.localStyleID = -1;
- return _this;
- }
- /**
- * Renders text to its canvas, and updates its texture.
- *
- * By default this is used internally to ensure the texture is correct before rendering,
- * but it can be used called externally, for example from this class to 'pre-generate' the texture from a piece of text,
- * and then shared across multiple Sprites.
- * @param respectDirty - Whether to abort updating the text if the Text isn't dirty and the function is called.
- */
- Text.prototype.updateText = function (respectDirty) {
- var style = this._style;
- // check if style has changed..
- if (this.localStyleID !== style.styleID) {
- this.dirty = true;
- this.localStyleID = style.styleID;
- }
- if (!this.dirty && respectDirty) {
- return;
- }
- this._font = this._style.toFontString();
- var context = this.context;
- var measured = TextMetrics.measureText(this._text || ' ', this._style, this._style.wordWrap, this.canvas);
- var width = measured.width;
- var height = measured.height;
- var lines = measured.lines;
- var lineHeight = measured.lineHeight;
- var lineWidths = measured.lineWidths;
- var maxLineWidth = measured.maxLineWidth;
- var fontProperties = measured.fontProperties;
- this.canvas.width = Math.ceil(Math.ceil((Math.max(1, width) + (style.padding * 2))) * this._resolution);
- this.canvas.height = Math.ceil(Math.ceil((Math.max(1, height) + (style.padding * 2))) * this._resolution);
- context.scale(this._resolution, this._resolution);
- context.clearRect(0, 0, this.canvas.width, this.canvas.height);
- context.font = this._font;
- context.lineWidth = style.strokeThickness;
- context.textBaseline = style.textBaseline;
- context.lineJoin = style.lineJoin;
- context.miterLimit = style.miterLimit;
- var linePositionX;
- var linePositionY;
- // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text
- var passesCount = style.dropShadow ? 2 : 1;
- // For v4, we drew text at the colours of the drop shadow underneath the normal text. This gave the correct zIndex,
- // but features such as alpha and shadowblur did not look right at all, since we were using actual text as a shadow.
- //
- // For v5.0.0, we moved over to just use the canvas API for drop shadows, which made them look much nicer and more
- // visually please, but now because the stroke is drawn and then the fill, drop shadows would appear on both the fill
- // and the stroke; and fill drop shadows would appear over the top of the stroke.
- //
- // For v5.1.1, the new route is to revert to v4 style of drawing text first to get the drop shadows underneath normal
- // text, but instead drawing text in the correct location, we'll draw it off screen (-paddingY), and then adjust the
- // drop shadow so only that appears on screen (+paddingY). Now we'll have the correct draw order of the shadow
- // beneath the text, whilst also having the proper text shadow styling.
- for (var i = 0; i < passesCount; ++i) {
- var isShadowPass = style.dropShadow && i === 0;
- // we only want the drop shadow, so put text way off-screen
- var dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (style.padding * 2)) : 0;
- var dsOffsetShadow = dsOffsetText * this._resolution;
- if (isShadowPass) {
- // On Safari, text with gradient and drop shadows together do not position correctly
- // if the scale of the canvas is not 1: https://bugs.webkit.org/show_bug.cgi?id=197689
- // Therefore we'll set the styles to be a plain black whilst generating this drop shadow
- context.fillStyle = 'black';
- context.strokeStyle = 'black';
- var dropShadowColor = style.dropShadowColor;
- var rgb = utils.hex2rgb(typeof dropShadowColor === 'number' ? dropShadowColor : utils.string2hex(dropShadowColor));
- var dropShadowBlur = style.dropShadowBlur * this._resolution;
- var dropShadowDistance = style.dropShadowDistance * this._resolution;
- context.shadowColor = "rgba(" + rgb[0] * 255 + "," + rgb[1] * 255 + "," + rgb[2] * 255 + "," + style.dropShadowAlpha + ")";
- context.shadowBlur = dropShadowBlur;
- context.shadowOffsetX = Math.cos(style.dropShadowAngle) * dropShadowDistance;
- context.shadowOffsetY = (Math.sin(style.dropShadowAngle) * dropShadowDistance) + dsOffsetShadow;
- }
- else {
- // set canvas text styles
- context.fillStyle = this._generateFillStyle(style, lines, measured);
- // TODO: Can't have different types for getter and setter. The getter shouldn't have the number type as
- // the setter converts to string. See this thread for more details:
- // https://github.com/microsoft/TypeScript/issues/2521
- context.strokeStyle = style.stroke;
- context.shadowColor = 'black';
- context.shadowBlur = 0;
- context.shadowOffsetX = 0;
- context.shadowOffsetY = 0;
- }
- var linePositionYShift = (lineHeight - fontProperties.fontSize) / 2;
- if (!Text.nextLineHeightBehavior || lineHeight - fontProperties.fontSize < 0) {
- linePositionYShift = 0;
- }
- // draw lines line by line
- for (var i_1 = 0; i_1 < lines.length; i_1++) {
- linePositionX = style.strokeThickness / 2;
- linePositionY = ((style.strokeThickness / 2) + (i_1 * lineHeight)) + fontProperties.ascent
- + linePositionYShift;
- if (style.align === 'right') {
- linePositionX += maxLineWidth - lineWidths[i_1];
- }
- else if (style.align === 'center') {
- linePositionX += (maxLineWidth - lineWidths[i_1]) / 2;
- }
- if (style.stroke && style.strokeThickness) {
- this.drawLetterSpacing(lines[i_1], linePositionX + style.padding, linePositionY + style.padding - dsOffsetText, true);
- }
- if (style.fill) {
- this.drawLetterSpacing(lines[i_1], linePositionX + style.padding, linePositionY + style.padding - dsOffsetText);
- }
- }
- }
- this.updateTexture();
- };
- /**
- * Render the text with letter-spacing.
- * @param text - The text to draw
- * @param x - Horizontal position to draw the text
- * @param y - Vertical position to draw the text
- * @param isStroke - Is this drawing for the outside stroke of the
- * text? If not, it's for the inside fill
- */
- Text.prototype.drawLetterSpacing = function (text, x, y, isStroke) {
- if (isStroke === void 0) { isStroke = false; }
- var style = this._style;
- // letterSpacing of 0 means normal
- var letterSpacing = style.letterSpacing;
- // Checking that we can use moddern canvas2D api
- // https://developer.chrome.com/origintrials/#/view_trial/3585991203293757441
- // note: this is unstable API, Chrome less 94 use a `textLetterSpacing`, newest use a letterSpacing
- // eslint-disable-next-line max-len
- var supportLetterSpacing = Text.experimentalLetterSpacing
- && ('letterSpacing' in CanvasRenderingContext2D.prototype
- || 'textLetterSpacing' in CanvasRenderingContext2D.prototype);
- if (letterSpacing === 0 || supportLetterSpacing) {
- if (supportLetterSpacing) {
- this.context.letterSpacing = letterSpacing;
- this.context.textLetterSpacing = letterSpacing;
- }
- if (isStroke) {
- this.context.strokeText(text, x, y);
- }
- else {
- this.context.fillText(text, x, y);
- }
- return;
- }
- var currentPosition = x;
- // Using Array.from correctly splits characters whilst keeping emoji together.
- // This is not supported on IE as it requires ES6, so regular text splitting occurs.
- // This also doesn't account for emoji that are multiple emoji put together to make something else.
- // Handling all of this would require a big library itself.
- // https://medium.com/@giltayar/iterating-over-emoji-characters-the-es6-way-f06e4589516
- // https://github.com/orling/grapheme-splitter
- var stringArray = Array.from ? Array.from(text) : text.split('');
- var previousWidth = this.context.measureText(text).width;
- var currentWidth = 0;
- for (var i = 0; i < stringArray.length; ++i) {
- var currentChar = stringArray[i];
- if (isStroke) {
- this.context.strokeText(currentChar, currentPosition, y);
- }
- else {
- this.context.fillText(currentChar, currentPosition, y);
- }
- var textStr = '';
- for (var j = i + 1; j < stringArray.length; ++j) {
- textStr += stringArray[j];
- }
- currentWidth = this.context.measureText(textStr).width;
- currentPosition += previousWidth - currentWidth + letterSpacing;
- previousWidth = currentWidth;
- }
- };
- /** Updates texture size based on canvas size. */
- Text.prototype.updateTexture = function () {
- var canvas = this.canvas;
- if (this._style.trim) {
- var trimmed = utils.trimCanvas(canvas);
- if (trimmed.data) {
- canvas.width = trimmed.width;
- canvas.height = trimmed.height;
- this.context.putImageData(trimmed.data, 0, 0);
- }
- }
- var texture = this._texture;
- var style = this._style;
- var padding = style.trim ? 0 : style.padding;
- var baseTexture = texture.baseTexture;
- texture.trim.width = texture._frame.width = canvas.width / this._resolution;
- texture.trim.height = texture._frame.height = canvas.height / this._resolution;
- texture.trim.x = -padding;
- texture.trim.y = -padding;
- texture.orig.width = texture._frame.width - (padding * 2);
- texture.orig.height = texture._frame.height - (padding * 2);
- // call sprite onTextureUpdate to update scale if _width or _height were set
- this._onTextureUpdate();
- baseTexture.setRealSize(canvas.width, canvas.height, this._resolution);
- texture.updateUvs();
- this.dirty = false;
- };
- /**
- * Renders the object using the WebGL renderer
- * @param renderer - The renderer
- */
- Text.prototype._render = function (renderer) {
- if (this._autoResolution && this._resolution !== renderer.resolution) {
- this._resolution = renderer.resolution;
- this.dirty = true;
- }
- this.updateText(true);
- _super.prototype._render.call(this, renderer);
- };
- /** Updates the transform on all children of this container for rendering. */
- Text.prototype.updateTransform = function () {
- this.updateText(true);
- _super.prototype.updateTransform.call(this);
- };
- Text.prototype.getBounds = function (skipUpdate, rect) {
- this.updateText(true);
- if (this._textureID === -1) {
- // texture was updated: recalculate transforms
- skipUpdate = false;
- }
- return _super.prototype.getBounds.call(this, skipUpdate, rect);
- };
- /**
- * Gets the local bounds of the text object.
- * @param rect - The output rectangle.
- * @returns The bounds.
- */
- Text.prototype.getLocalBounds = function (rect) {
- this.updateText(true);
- return _super.prototype.getLocalBounds.call(this, rect);
- };
- /** Calculates the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account. */
- Text.prototype._calculateBounds = function () {
- this.calculateVertices();
- // if we have already done this on THIS frame.
- this._bounds.addQuad(this.vertexData);
- };
- /**
- * Generates the fill style. Can automatically generate a gradient based on the fill style being an array
- * @param style - The style.
- * @param lines - The lines of text.
- * @param metrics
- * @returns The fill style
- */
- Text.prototype._generateFillStyle = function (style, lines, metrics) {
- // TODO: Can't have different types for getter and setter. The getter shouldn't have the number type as
- // the setter converts to string. See this thread for more details:
- // https://github.com/microsoft/TypeScript/issues/2521
- var fillStyle = style.fill;
- if (!Array.isArray(fillStyle)) {
- return fillStyle;
- }
- else if (fillStyle.length === 1) {
- return fillStyle[0];
- }
- // the gradient will be evenly spaced out according to how large the array is.
- // ['#FF0000', '#00FF00', '#0000FF'] would created stops at 0.25, 0.5 and 0.75
- var gradient;
- // a dropshadow will enlarge the canvas and result in the gradient being
- // generated with the incorrect dimensions
- var dropShadowCorrection = (style.dropShadow) ? style.dropShadowDistance : 0;
- // should also take padding into account, padding can offset the gradient
- var padding = style.padding || 0;
- var width = (this.canvas.width / this._resolution) - dropShadowCorrection - (padding * 2);
- var height = (this.canvas.height / this._resolution) - dropShadowCorrection - (padding * 2);
- // make a copy of the style settings, so we can manipulate them later
- var fill = fillStyle.slice();
- var fillGradientStops = style.fillGradientStops.slice();
- // wanting to evenly distribute the fills. So an array of 4 colours should give fills of 0.25, 0.5 and 0.75
- if (!fillGradientStops.length) {
- var lengthPlus1 = fill.length + 1;
- for (var i = 1; i < lengthPlus1; ++i) {
- fillGradientStops.push(i / lengthPlus1);
- }
- }
- // stop the bleeding of the last gradient on the line above to the top gradient of the this line
- // by hard defining the first gradient colour at point 0, and last gradient colour at point 1
- fill.unshift(fillStyle[0]);
- fillGradientStops.unshift(0);
- fill.push(fillStyle[fillStyle.length - 1]);
- fillGradientStops.push(1);
- if (style.fillGradientType === exports.TEXT_GRADIENT.LINEAR_VERTICAL) {
- // start the gradient at the top center of the canvas, and end at the bottom middle of the canvas
- gradient = this.context.createLinearGradient(width / 2, padding, width / 2, height + padding);
- // we need to repeat the gradient so that each individual line of text has the same vertical gradient effect
- // ['#FF0000', '#00FF00', '#0000FF'] over 2 lines would create stops at 0.125, 0.25, 0.375, 0.625, 0.75, 0.875
- // Actual height of the text itself, not counting spacing for lineHeight/leading/dropShadow etc
- var textHeight = metrics.fontProperties.fontSize + style.strokeThickness;
- for (var i = 0; i < lines.length; i++) {
- var lastLineBottom = (metrics.lineHeight * (i - 1)) + textHeight;
- var thisLineTop = metrics.lineHeight * i;
- var thisLineGradientStart = thisLineTop;
- // Handle case where last & this line overlap
- if (i > 0 && lastLineBottom > thisLineTop) {
- thisLineGradientStart = (thisLineTop + lastLineBottom) / 2;
- }
- var thisLineBottom = thisLineTop + textHeight;
- var nextLineTop = metrics.lineHeight * (i + 1);
- var thisLineGradientEnd = thisLineBottom;
- // Handle case where this & next line overlap
- if (i + 1 < lines.length && nextLineTop < thisLineBottom) {
- thisLineGradientEnd = (thisLineBottom + nextLineTop) / 2;
- }
- // textHeight, but as a 0-1 size in global gradient stop space
- var gradStopLineHeight = (thisLineGradientEnd - thisLineGradientStart) / height;
- for (var j = 0; j < fill.length; j++) {
- // 0-1 stop point for the current line, multiplied to global space afterwards
- var lineStop = 0;
- if (typeof fillGradientStops[j] === 'number') {
- lineStop = fillGradientStops[j];
- }
- else {
- lineStop = j / fill.length;
- }
- var globalStop = Math.min(1, Math.max(0, (thisLineGradientStart / height) + (lineStop * gradStopLineHeight)));
- // There's potential for floating point precision issues at the seams between gradient repeats.
- globalStop = Number(globalStop.toFixed(5));
- gradient.addColorStop(globalStop, fill[j]);
- }
- }
- }
- else {
- // start the gradient at the center left of the canvas, and end at the center right of the canvas
- gradient = this.context.createLinearGradient(padding, height / 2, width + padding, height / 2);
- // can just evenly space out the gradients in this case, as multiple lines makes no difference
- // to an even left to right gradient
- var totalIterations = fill.length + 1;
- var currentIteration = 1;
- for (var i = 0; i < fill.length; i++) {
- var stop = void 0;
- if (typeof fillGradientStops[i] === 'number') {
- stop = fillGradientStops[i];
- }
- else {
- stop = currentIteration / totalIterations;
- }
- gradient.addColorStop(stop, fill[i]);
- currentIteration++;
- }
- }
- return gradient;
- };
- /**
- * Destroys this text object.
- *
- * Note* Unlike a Sprite, a Text object will automatically destroy its baseTexture and texture as
- * the majority of the time the texture will not be shared with any other Sprites.
- * @param options - Options parameter. A boolean will act as if all options
- * have been set to that value
- * @param {boolean} [options.children=false] - if set to true, all the children will have their
- * destroy method called as well. 'options' will be passed on to those calls.
- * @param {boolean} [options.texture=true] - Should it destroy the current texture of the sprite as well
- * @param {boolean} [options.baseTexture=true] - Should it destroy the base texture of the sprite as well
- */
- Text.prototype.destroy = function (options) {
- if (typeof options === 'boolean') {
- options = { children: options };
- }
- options = Object.assign({}, defaultDestroyOptions, options);
- _super.prototype.destroy.call(this, options);
- // set canvas width and height to 0 to workaround memory leak in Safari < 13
- // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
- if (this._ownCanvas) {
- this.canvas.height = this.canvas.width = 0;
- }
- // make sure to reset the context and canvas.. dont want this hanging around in memory!
- this.context = null;
- this.canvas = null;
- this._style = null;
- };
- Object.defineProperty(Text.prototype, "width", {
- /** The width of the Text, setting this will actually modify the scale to achieve the value set. */
- get: function () {
- this.updateText(true);
- return Math.abs(this.scale.x) * this._texture.orig.width;
- },
- set: function (value) {
- this.updateText(true);
- var s = utils.sign(this.scale.x) || 1;
- this.scale.x = s * value / this._texture.orig.width;
- this._width = value;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(Text.prototype, "height", {
- /** The height of the Text, setting this will actually modify the scale to achieve the value set. */
- get: function () {
- this.updateText(true);
- return Math.abs(this.scale.y) * this._texture.orig.height;
- },
- set: function (value) {
- this.updateText(true);
- var s = utils.sign(this.scale.y) || 1;
- this.scale.y = s * value / this._texture.orig.height;
- this._height = value;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(Text.prototype, "style", {
- /**
- * Set the style of the text.
- *
- * Set up an event listener to listen for changes on the style object and mark the text as dirty.
- */
- get: function () {
- // TODO: Can't have different types for getter and setter. The getter shouldn't have the ITextStyle
- // since the setter creates the TextStyle. See this thread for more details:
- // https://github.com/microsoft/TypeScript/issues/2521
- return this._style;
- },
- set: function (style) {
- style = style || {};
- if (style instanceof TextStyle) {
- this._style = style;
- }
- else {
- this._style = new TextStyle(style);
- }
- this.localStyleID = -1;
- this.dirty = true;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(Text.prototype, "text", {
- /** Set the copy for the text object. To split a line you can use '\n'. */
- get: function () {
- return this._text;
- },
- set: function (text) {
- text = String(text === null || text === undefined ? '' : text);
- if (this._text === text) {
- return;
- }
- this._text = text;
- this.dirty = true;
- },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(Text.prototype, "resolution", {
- /**
- * The resolution / device pixel ratio of the canvas.
- *
- * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually.
- * @default 1
- */
- get: function () {
- return this._resolution;
- },
- set: function (value) {
- this._autoResolution = false;
- if (this._resolution === value) {
- return;
- }
- this._resolution = value;
- this.dirty = true;
- },
- enumerable: false,
- configurable: true
- });
- /**
- * New behavior for `lineHeight` that's meant to mimic HTML text. A value of `true` will
- * make sure the first baseline is offset by the `lineHeight` value if it is greater than `fontSize`.
- * A value of `false` will use the legacy behavior and not change the baseline of the first line.
- * In the next major release, we'll enable this by default.
- */
- Text.nextLineHeightBehavior = false;
- /**
- * New rendering behavior for letter-spacing which uses Chrome's new native API. This will
- * lead to more accurate letter-spacing results because it does not try to manually draw
- * each character. However, this Chrome API is experimental and may not serve all cases yet.
- */
- Text.experimentalLetterSpacing = false;
- return Text;
- }(sprite.Sprite));
- exports.Text = Text;
- exports.TextMetrics = TextMetrics;
- exports.TextStyle = TextStyle;
- Object.defineProperty(exports, '__esModule', { value: true });
- return exports;
- })({}, PIXI, PIXI, PIXI, PIXI, PIXI.utils);
- Object.assign(this.PIXI, _pixi_text);
- //# sourceMappingURL=text.js.map
|