@m2c2kit/core 0.3.28 → 0.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +10 -18
- package/README.md +1 -1
- package/dist/index.d.ts +30 -3
- package/dist/index.js +281 -34
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +4 -3
- package/package.json +10 -10
package/LICENSE
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
Copyright 2023 Scott T. Yabiku
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @m2c2kit/core
|
|
2
2
|
|
|
3
|
-
[](https://opensource.org/license/apache-2-0)
|
|
4
4
|
[](https://github.com/m2c2-project/m2c2kit/actions/workflows/ci.yml)
|
|
5
5
|
[](https://www.npmjs.com/package/@m2c2kit/core)
|
|
6
6
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1846,7 +1846,9 @@ declare class Game implements Activity {
|
|
|
1846
1846
|
/**
|
|
1847
1847
|
* Adds a scene to the game.
|
|
1848
1848
|
*
|
|
1849
|
-
* @remarks A scene, and its children nodes, cannot be presented unless it
|
|
1849
|
+
* @remarks A scene, and its children nodes, cannot be presented unless it
|
|
1850
|
+
* has been added to the game object. A scene can be added to the game
|
|
1851
|
+
* only once.
|
|
1850
1852
|
*
|
|
1851
1853
|
* @param scene
|
|
1852
1854
|
*/
|
|
@@ -4195,6 +4197,8 @@ declare enum LabelHorizontalAlignmentMode {
|
|
|
4195
4197
|
}
|
|
4196
4198
|
|
|
4197
4199
|
interface LabelOptions extends M2NodeOptions, DrawableOptions, TextOptions {
|
|
4200
|
+
/** Text to be displayed. Tags for bold, italic, and underline are supported, e.g., `<b><u>Bold and underline</u></b>`. */
|
|
4201
|
+
text?: string;
|
|
4198
4202
|
/** Horizontal alignment of label text. see {@link LabelHorizontalAlignmentMode}. Default is LabelHorizontalAlignmentMode.center */
|
|
4199
4203
|
horizontalAlignmentMode?: LabelHorizontalAlignmentMode;
|
|
4200
4204
|
/** Maximum width of label text before wrapping occurs. Default is the canvas width */
|
|
@@ -4226,13 +4230,19 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
|
|
|
4226
4230
|
private builder?;
|
|
4227
4231
|
private _fontPaint?;
|
|
4228
4232
|
private _backgroundPaint?;
|
|
4233
|
+
private _underlinePaint?;
|
|
4229
4234
|
private localizedFontSize;
|
|
4230
4235
|
private localizedFontName;
|
|
4231
4236
|
private localizedFontNames;
|
|
4237
|
+
private plainText;
|
|
4238
|
+
private styleSegments;
|
|
4239
|
+
private underlinedRanges;
|
|
4240
|
+
private currentBuilderPosition;
|
|
4232
4241
|
/**
|
|
4233
4242
|
* Single or multi-line text formatted and rendered on the screen.
|
|
4234
4243
|
*
|
|
4235
|
-
* @remarks Label (in contrast to TextLine) has enhanced text support for
|
|
4244
|
+
* @remarks Label (in contrast to TextLine) has enhanced text support for
|
|
4245
|
+
* line wrapping, centering/alignment, and background colors.
|
|
4236
4246
|
*
|
|
4237
4247
|
* @param options - {@link LabelOptions}
|
|
4238
4248
|
*/
|
|
@@ -4263,6 +4273,19 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
|
|
|
4263
4273
|
suppressEvents?: boolean;
|
|
4264
4274
|
};
|
|
4265
4275
|
initialize(): void;
|
|
4276
|
+
/**
|
|
4277
|
+
* Parses text with formatting tags and returns plain text and style segments.
|
|
4278
|
+
* Supports <b> for bold, <i> for italics, and <u> for underline.
|
|
4279
|
+
* Properly handles nested tags like <b><u>bold and underlined</u></b>.
|
|
4280
|
+
* Throws errors for malformed tags, but treats unknown tags as plain text.
|
|
4281
|
+
*
|
|
4282
|
+
* @param text - The text with formatting tags
|
|
4283
|
+
* @returns The parsed text result
|
|
4284
|
+
* @throws Error if tags are improperly nested or unclosed
|
|
4285
|
+
*/
|
|
4286
|
+
private parseFormattedText;
|
|
4287
|
+
private addTextWithStylesToParagraphBuilder;
|
|
4288
|
+
private addTextWithStyle;
|
|
4266
4289
|
/**
|
|
4267
4290
|
* Determines the M2Font objects that need to be ready in order to draw
|
|
4268
4291
|
* the Label.
|
|
@@ -4303,6 +4326,8 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
|
|
|
4303
4326
|
private set backgroundPaint(value);
|
|
4304
4327
|
private get fontPaint();
|
|
4305
4328
|
private set fontPaint(value);
|
|
4329
|
+
private get underlinePaint();
|
|
4330
|
+
private set underlinePaint(value);
|
|
4306
4331
|
/**
|
|
4307
4332
|
* Duplicates a node using deep copy.
|
|
4308
4333
|
*
|
|
@@ -4316,6 +4341,7 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
|
|
|
4316
4341
|
duplicate(newName?: string): Label;
|
|
4317
4342
|
update(): void;
|
|
4318
4343
|
draw(canvas: Canvas): void;
|
|
4344
|
+
private drawUnderlines;
|
|
4319
4345
|
warmup(canvas: Canvas): void;
|
|
4320
4346
|
}
|
|
4321
4347
|
|
|
@@ -5341,4 +5367,5 @@ declare class WebGlInfo {
|
|
|
5341
5367
|
static dispose(): void;
|
|
5342
5368
|
}
|
|
5343
5369
|
|
|
5344
|
-
export { Action,
|
|
5370
|
+
export { Action, ActivityType, CanvasKitHelpers, ColorfulMutablePath, Composite, Constants, ConstraintType, CustomAction, Dimensions, Easings, Equal, Equals, EventStore, EventStoreMode, FadeAlphaAction, FontManager, Game, GroupAction, I18n, ImageManager, Label, LabelHorizontalAlignmentMode, LayoutConstraint, LegacyTimer, M2EventType, M2ImageStatus, M2Node, M2NodeFactory, M2NodeType, M2SoundStatus, M2c2KitHelpers, MoveAction, MutablePath, NoneTransition, PlayAction, RandomDraws, RepeatAction, RepeatForeverAction, RotateAction, ScaleAction, Scene, SceneTransition, SequenceAction, Shape, ShapeType, SlideTransition, SoundManager, SoundPlayer, SoundRecorder, Sprite, Story, TextLine, Timer, Transition, TransitionDirection, TransitionType, Uuid, WaitAction, WebColors, WebGlInfo, handleInterfaceOptions };
|
|
5371
|
+
export type { Activity, ActivityCallbacks, ActivityEvent, ActivityEventListener, ActivityKeyValueData, ActivityLifecycleEvent, ActivityResultsEvent, BrowserImage, BrowserImageDataReadyEvent, CallbackOptions, CompositeEvent, CompositeOptions, Constraints, CustomActionOptions, DefaultParameter, DomPointerDownEvent, DrawableOptions, EasingFunction, FadeAlphaActionOptions, FontAsset, FontData, GameData, GameEvent, GameOptions, GameParameters, GlobalVariables, I18nDataReadyEvent, IDataStore, IDrawable, IText, LabelOptions, Layout, LocaleSvg, M2ColorfulPath, M2DragEvent, M2Event, M2EventListener, M2Image, M2KeyboardEvent, M2NodeAddChildEvent, M2NodeConstructor, M2NodeEvent, M2NodeEventListener, M2NodeNewEvent, M2NodeOptions, M2NodePropertyChangeEvent, M2NodeRemoveChildEvent, M2Path, M2PointerEvent, M2Sound, MoveActionOptions, PlayActionOptions, Plugin, PluginEvent, Point, RectOptions, RgbaColor, ScaleActionOptions, SceneOptions, ScenePresentEvent, ScoringSchema, ShapeOptions, Size, SlideTransitionOptions, SoundAsset, SoundPlayerOptions, SoundRecorderOptions, SoundRecorderResults, SpriteOptions, StoryOptions, StringInterpolationMap, TapEvent, TextAndFont, TextLineOptions, TextLocalizationResult, TextOptions, TextWithFontCustomization, Translation, TranslationConfiguration, TranslationOptions, TrialData, TrialSchema, WaitActionOptions };
|
package/dist/index.js
CHANGED
|
@@ -4976,11 +4976,17 @@ const M2FontStatus = {
|
|
|
4976
4976
|
/** Font has fully finished loading and is ready to use. */
|
|
4977
4977
|
Ready: "Ready"};
|
|
4978
4978
|
|
|
4979
|
+
const TAG_NAME = {
|
|
4980
|
+
UNDERLINE: "u",
|
|
4981
|
+
ITALIC: "i",
|
|
4982
|
+
BOLD: "b"
|
|
4983
|
+
};
|
|
4979
4984
|
class Label extends M2Node {
|
|
4980
4985
|
/**
|
|
4981
4986
|
* Single or multi-line text formatted and rendered on the screen.
|
|
4982
4987
|
*
|
|
4983
|
-
* @remarks Label (in contrast to TextLine) has enhanced text support for
|
|
4988
|
+
* @remarks Label (in contrast to TextLine) has enhanced text support for
|
|
4989
|
+
* line wrapping, centering/alignment, and background colors.
|
|
4984
4990
|
*
|
|
4985
4991
|
* @param options - {@link LabelOptions}
|
|
4986
4992
|
*/
|
|
@@ -5005,6 +5011,10 @@ class Label extends M2Node {
|
|
|
5005
5011
|
// public getter/setter is below
|
|
5006
5012
|
this._localize = true;
|
|
5007
5013
|
this.localizedFontNames = [];
|
|
5014
|
+
this.plainText = "";
|
|
5015
|
+
this.styleSegments = [];
|
|
5016
|
+
this.underlinedRanges = [];
|
|
5017
|
+
this.currentBuilderPosition = 0;
|
|
5008
5018
|
handleInterfaceOptions(this, options);
|
|
5009
5019
|
if (options.horizontalAlignmentMode) {
|
|
5010
5020
|
this.horizontalAlignmentMode = options.horizontalAlignmentMode;
|
|
@@ -5056,14 +5066,14 @@ class Label extends M2Node {
|
|
|
5056
5066
|
this.fontColor[2],
|
|
5057
5067
|
this.fontColor[3]
|
|
5058
5068
|
);
|
|
5059
|
-
let
|
|
5069
|
+
let textAfterLocalization;
|
|
5060
5070
|
const i18n = this.game.i18n;
|
|
5061
5071
|
if (i18n && this.localize !== false) {
|
|
5062
5072
|
const textLocalization = i18n.getTextLocalization(
|
|
5063
5073
|
this.text,
|
|
5064
5074
|
this.interpolation
|
|
5065
5075
|
);
|
|
5066
|
-
|
|
5076
|
+
textAfterLocalization = textLocalization.text;
|
|
5067
5077
|
this.localizedFontSize = textLocalization.fontSize;
|
|
5068
5078
|
this.localizedFontName = textLocalization.fontName;
|
|
5069
5079
|
this.localizedFontNames = textLocalization.fontNames ?? [];
|
|
@@ -5076,8 +5086,13 @@ class Label extends M2Node {
|
|
|
5076
5086
|
);
|
|
5077
5087
|
}
|
|
5078
5088
|
} else {
|
|
5079
|
-
|
|
5089
|
+
textAfterLocalization = this.text;
|
|
5080
5090
|
}
|
|
5091
|
+
this.currentBuilderPosition = 0;
|
|
5092
|
+
this.underlinedRanges = [];
|
|
5093
|
+
const parsedText = this.parseFormattedText(textAfterLocalization);
|
|
5094
|
+
this.plainText = parsedText.plainText;
|
|
5095
|
+
this.styleSegments = parsedText.styleSegments;
|
|
5081
5096
|
if (this.fontName && this.fontNames) {
|
|
5082
5097
|
throw new Error("cannot specify both fontName and fontNames");
|
|
5083
5098
|
}
|
|
@@ -5117,36 +5132,39 @@ class Label extends M2Node {
|
|
|
5117
5132
|
} else {
|
|
5118
5133
|
this.backgroundPaint.setColor(this.canvasKit.Color(0, 0, 0, 0));
|
|
5119
5134
|
}
|
|
5120
|
-
this.
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
// Default decoration thickness
|
|
5135
|
-
decorationStyle: this.canvasKit.DecorationStyle.Solid,
|
|
5136
|
-
// Solid decoration style
|
|
5137
|
-
heightMultiplier: -1,
|
|
5138
|
-
// Providing -1, rather than 1.0, gives default height multiplier
|
|
5139
|
-
halfLeading: false,
|
|
5140
|
-
// Default half leading
|
|
5141
|
-
letterSpacing: 0,
|
|
5142
|
-
// Default letter spacing
|
|
5143
|
-
wordSpacing: 0
|
|
5144
|
-
// Default word spacing
|
|
5135
|
+
if (!this._underlinePaint) {
|
|
5136
|
+
this._underlinePaint = new this.canvasKit.Paint();
|
|
5137
|
+
}
|
|
5138
|
+
this.underlinePaint.setColor(this.fontPaint.getColor());
|
|
5139
|
+
this.underlinePaint.setAlphaf(this.absoluteAlpha);
|
|
5140
|
+
this.underlinePaint.setStyle(this.canvasKit.PaintStyle.Fill);
|
|
5141
|
+
this.underlinePaint.setAntiAlias(true);
|
|
5142
|
+
const defaultStyle = {
|
|
5143
|
+
fontFamilies: requiredFonts.map((font) => font.fontName),
|
|
5144
|
+
fontSize: (this.localizedFontSize ?? this.fontSize) * m2c2Globals.canvasScale,
|
|
5145
|
+
fontStyle: {
|
|
5146
|
+
weight: this.canvasKit.FontWeight.Normal,
|
|
5147
|
+
width: this.canvasKit.FontWidth.Normal,
|
|
5148
|
+
slant: this.canvasKit.FontSlant.Upright
|
|
5145
5149
|
},
|
|
5150
|
+
// Normal font style
|
|
5151
|
+
decoration: 0,
|
|
5152
|
+
// No decoration
|
|
5153
|
+
decorationThickness: 1,
|
|
5154
|
+
// Default decoration thickness
|
|
5155
|
+
decorationStyle: this.canvasKit.DecorationStyle.Solid,
|
|
5156
|
+
heightMultiplier: -1,
|
|
5157
|
+
// Providing -1, rather than 1.0, gives default height multiplier
|
|
5158
|
+
halfLeading: false,
|
|
5159
|
+
letterSpacing: 0,
|
|
5160
|
+
wordSpacing: 0
|
|
5161
|
+
};
|
|
5162
|
+
this.builder.pushPaintStyle(
|
|
5163
|
+
defaultStyle,
|
|
5146
5164
|
this.fontPaint,
|
|
5147
5165
|
this.backgroundPaint
|
|
5148
5166
|
);
|
|
5149
|
-
this.
|
|
5167
|
+
this.addTextWithStylesToParagraphBuilder(defaultStyle);
|
|
5150
5168
|
if (this.paragraph) {
|
|
5151
5169
|
this.paragraph.delete();
|
|
5152
5170
|
}
|
|
@@ -5174,6 +5192,185 @@ class Label extends M2Node {
|
|
|
5174
5192
|
this.size.height = this.paragraph.getHeight() / m2c2Globals.canvasScale;
|
|
5175
5193
|
this.needsInitialization = false;
|
|
5176
5194
|
}
|
|
5195
|
+
/**
|
|
5196
|
+
* Parses text with formatting tags and returns plain text and style segments.
|
|
5197
|
+
* Supports <b> for bold, <i> for italics, and <u> for underline.
|
|
5198
|
+
* Properly handles nested tags like <b><u>bold and underlined</u></b>.
|
|
5199
|
+
* Throws errors for malformed tags, but treats unknown tags as plain text.
|
|
5200
|
+
*
|
|
5201
|
+
* @param text - The text with formatting tags
|
|
5202
|
+
* @returns The parsed text result
|
|
5203
|
+
* @throws Error if tags are improperly nested or unclosed
|
|
5204
|
+
*/
|
|
5205
|
+
parseFormattedText(text) {
|
|
5206
|
+
let plainText = "";
|
|
5207
|
+
const styleChanges = [];
|
|
5208
|
+
const tagStack = [];
|
|
5209
|
+
const validTags = /* @__PURE__ */ new Set([
|
|
5210
|
+
TAG_NAME.UNDERLINE,
|
|
5211
|
+
TAG_NAME.BOLD,
|
|
5212
|
+
TAG_NAME.ITALIC
|
|
5213
|
+
]);
|
|
5214
|
+
const tagPattern = /<\/?([^>]+)>/g;
|
|
5215
|
+
let lastIndex = 0;
|
|
5216
|
+
let plainIndex = 0;
|
|
5217
|
+
let match = null;
|
|
5218
|
+
const getPosition = (index) => {
|
|
5219
|
+
let line = 1;
|
|
5220
|
+
let column = 1;
|
|
5221
|
+
for (let i = 0; i < index; i++) {
|
|
5222
|
+
if (text[i] === "\n") {
|
|
5223
|
+
line++;
|
|
5224
|
+
column = 1;
|
|
5225
|
+
} else {
|
|
5226
|
+
column++;
|
|
5227
|
+
}
|
|
5228
|
+
}
|
|
5229
|
+
return `line ${line}, column ${column}`;
|
|
5230
|
+
};
|
|
5231
|
+
while ((match = tagPattern.exec(text)) !== null) {
|
|
5232
|
+
const fullTag = match[0];
|
|
5233
|
+
const tagName = match[1];
|
|
5234
|
+
const isClosing = fullTag.charAt(1) === "/";
|
|
5235
|
+
const position = getPosition(match.index);
|
|
5236
|
+
if (!validTags.has(tagName)) {
|
|
5237
|
+
const beforeTag2 = text.substring(lastIndex, match.index);
|
|
5238
|
+
plainText += beforeTag2;
|
|
5239
|
+
plainIndex += beforeTag2.length;
|
|
5240
|
+
plainText += fullTag;
|
|
5241
|
+
plainIndex += fullTag.length;
|
|
5242
|
+
lastIndex = match.index + fullTag.length;
|
|
5243
|
+
continue;
|
|
5244
|
+
}
|
|
5245
|
+
const beforeTag = text.substring(lastIndex, match.index);
|
|
5246
|
+
plainText += beforeTag;
|
|
5247
|
+
plainIndex += beforeTag.length;
|
|
5248
|
+
if (isClosing) {
|
|
5249
|
+
if (tagStack.length === 0) {
|
|
5250
|
+
throw new Error(
|
|
5251
|
+
`Label has closing tag </${tagName}> at ${position} without matching opening tag. Text is: ${text}`
|
|
5252
|
+
);
|
|
5253
|
+
}
|
|
5254
|
+
const lastOpenTag = tagStack.pop();
|
|
5255
|
+
if (lastOpenTag !== tagName) {
|
|
5256
|
+
throw new Error(
|
|
5257
|
+
`Label has improperly nested tags at ${position}. Expected </${lastOpenTag}> but found </${tagName}>. Tags must be properly nested. Text is: ${text}`
|
|
5258
|
+
);
|
|
5259
|
+
}
|
|
5260
|
+
styleChanges.push({
|
|
5261
|
+
position: plainIndex,
|
|
5262
|
+
style: tagName,
|
|
5263
|
+
isStart: false
|
|
5264
|
+
});
|
|
5265
|
+
} else {
|
|
5266
|
+
tagStack.push(tagName);
|
|
5267
|
+
styleChanges.push({
|
|
5268
|
+
position: plainIndex,
|
|
5269
|
+
style: tagName,
|
|
5270
|
+
isStart: true
|
|
5271
|
+
});
|
|
5272
|
+
}
|
|
5273
|
+
lastIndex = match.index + fullTag.length;
|
|
5274
|
+
}
|
|
5275
|
+
plainText += text.substring(lastIndex);
|
|
5276
|
+
if (tagStack.length > 0) {
|
|
5277
|
+
throw new Error(
|
|
5278
|
+
`Label has unclosed format tags: <${tagStack.join(">, <")}>. All tags must be closed. Text is: ${text}`
|
|
5279
|
+
);
|
|
5280
|
+
}
|
|
5281
|
+
const activeStyles = /* @__PURE__ */ new Set();
|
|
5282
|
+
const segments = [];
|
|
5283
|
+
let lastPosition = 0;
|
|
5284
|
+
styleChanges.sort((a, b) => a.position - b.position);
|
|
5285
|
+
for (const change of styleChanges) {
|
|
5286
|
+
if (change.position > lastPosition && activeStyles.size > 0) {
|
|
5287
|
+
segments.push({
|
|
5288
|
+
start: lastPosition,
|
|
5289
|
+
end: change.position,
|
|
5290
|
+
styles: new Set(activeStyles)
|
|
5291
|
+
// Create a copy of the current styles
|
|
5292
|
+
});
|
|
5293
|
+
}
|
|
5294
|
+
if (change.isStart) {
|
|
5295
|
+
activeStyles.add(change.style);
|
|
5296
|
+
} else {
|
|
5297
|
+
activeStyles.delete(change.style);
|
|
5298
|
+
}
|
|
5299
|
+
lastPosition = change.position;
|
|
5300
|
+
}
|
|
5301
|
+
return {
|
|
5302
|
+
plainText,
|
|
5303
|
+
styleSegments: segments
|
|
5304
|
+
};
|
|
5305
|
+
}
|
|
5306
|
+
addTextWithStylesToParagraphBuilder(defaultStyle) {
|
|
5307
|
+
if (this.styleSegments.length === 0) {
|
|
5308
|
+
if (!this.builder) {
|
|
5309
|
+
throw new Error("ParagraphBuilder is undefined");
|
|
5310
|
+
}
|
|
5311
|
+
this.builder.addText(this.plainText);
|
|
5312
|
+
} else {
|
|
5313
|
+
let lastIndex = 0;
|
|
5314
|
+
for (const segment of this.styleSegments) {
|
|
5315
|
+
if (segment.start > lastIndex) {
|
|
5316
|
+
this.addTextWithStyle(
|
|
5317
|
+
this.plainText.substring(lastIndex, segment.start),
|
|
5318
|
+
defaultStyle
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
const styleModifiers = {};
|
|
5322
|
+
if (segment.styles.has(TAG_NAME.BOLD)) {
|
|
5323
|
+
styleModifiers.fontStyle = {
|
|
5324
|
+
...defaultStyle.fontStyle,
|
|
5325
|
+
weight: this.canvasKit.FontWeight.Bold
|
|
5326
|
+
};
|
|
5327
|
+
}
|
|
5328
|
+
if (segment.styles.has(TAG_NAME.ITALIC)) {
|
|
5329
|
+
styleModifiers.fontStyle = {
|
|
5330
|
+
...styleModifiers.fontStyle || defaultStyle.fontStyle,
|
|
5331
|
+
slant: this.canvasKit.FontSlant.Italic
|
|
5332
|
+
};
|
|
5333
|
+
}
|
|
5334
|
+
if (segment.styles.has(TAG_NAME.UNDERLINE)) {
|
|
5335
|
+
styleModifiers.underline = true;
|
|
5336
|
+
}
|
|
5337
|
+
this.addTextWithStyle(
|
|
5338
|
+
this.plainText.substring(segment.start, segment.end),
|
|
5339
|
+
defaultStyle,
|
|
5340
|
+
styleModifiers
|
|
5341
|
+
);
|
|
5342
|
+
lastIndex = segment.end;
|
|
5343
|
+
}
|
|
5344
|
+
if (lastIndex < this.plainText.length) {
|
|
5345
|
+
this.addTextWithStyle(
|
|
5346
|
+
this.plainText.substring(lastIndex),
|
|
5347
|
+
defaultStyle
|
|
5348
|
+
);
|
|
5349
|
+
}
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
// Helper to apply style and add text
|
|
5353
|
+
addTextWithStyle(text, defaultStyle, styleModifiers = {}) {
|
|
5354
|
+
if (!text) return;
|
|
5355
|
+
const style = {
|
|
5356
|
+
...defaultStyle,
|
|
5357
|
+
...styleModifiers
|
|
5358
|
+
};
|
|
5359
|
+
if (styleModifiers.underline) {
|
|
5360
|
+
const currentPosition = this.currentBuilderPosition;
|
|
5361
|
+
this.underlinedRanges.push({
|
|
5362
|
+
start: currentPosition,
|
|
5363
|
+
end: currentPosition + text.length
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5366
|
+
if (!this.builder) {
|
|
5367
|
+
throw new Error("ParagraphBuilder is undefined");
|
|
5368
|
+
}
|
|
5369
|
+
this.builder.pushPaintStyle(style, this.fontPaint, this.backgroundPaint);
|
|
5370
|
+
this.builder.addText(text);
|
|
5371
|
+
this.currentBuilderPosition += text.length;
|
|
5372
|
+
this.builder.pop();
|
|
5373
|
+
}
|
|
5177
5374
|
/**
|
|
5178
5375
|
* Determines the M2Font objects that need to be ready in order to draw
|
|
5179
5376
|
* the Label.
|
|
@@ -5214,7 +5411,9 @@ class Label extends M2Node {
|
|
|
5214
5411
|
this.builder,
|
|
5215
5412
|
this._fontPaint,
|
|
5216
5413
|
// use backing field since it may be undefined
|
|
5217
|
-
this._backgroundPaint
|
|
5414
|
+
this._backgroundPaint,
|
|
5415
|
+
// use backing field since it may be undefined
|
|
5416
|
+
this._underlinePaint
|
|
5218
5417
|
// use backing field since it may be undefined
|
|
5219
5418
|
]);
|
|
5220
5419
|
}
|
|
@@ -5395,6 +5594,15 @@ class Label extends M2Node {
|
|
|
5395
5594
|
set fontPaint(fontPaint) {
|
|
5396
5595
|
this._fontPaint = fontPaint;
|
|
5397
5596
|
}
|
|
5597
|
+
get underlinePaint() {
|
|
5598
|
+
if (!this._underlinePaint) {
|
|
5599
|
+
throw new Error("underlinePaint cannot be undefined");
|
|
5600
|
+
}
|
|
5601
|
+
return this._underlinePaint;
|
|
5602
|
+
}
|
|
5603
|
+
set underlinePaint(underlinePaint) {
|
|
5604
|
+
this._underlinePaint = underlinePaint;
|
|
5605
|
+
}
|
|
5398
5606
|
/**
|
|
5399
5607
|
* Duplicates a node using deep copy.
|
|
5400
5608
|
*
|
|
@@ -5442,10 +5650,42 @@ class Label extends M2Node {
|
|
|
5442
5650
|
throw new Error("no paragraph");
|
|
5443
5651
|
}
|
|
5444
5652
|
canvas.drawParagraph(this.paragraph, x, y);
|
|
5653
|
+
if (this.underlinedRanges.length > 0) {
|
|
5654
|
+
this.drawUnderlines(canvas, this.paragraph, x, y);
|
|
5655
|
+
}
|
|
5445
5656
|
canvas.restore();
|
|
5446
5657
|
}
|
|
5447
5658
|
super.drawChildren(canvas);
|
|
5448
5659
|
}
|
|
5660
|
+
drawUnderlines(canvas, paragraph, x, y) {
|
|
5661
|
+
const drawScale = m2c2Globals.canvasScale / this.absoluteScale;
|
|
5662
|
+
for (const range of this.underlinedRanges) {
|
|
5663
|
+
const positions = paragraph.getRectsForRange(
|
|
5664
|
+
range.start,
|
|
5665
|
+
range.end,
|
|
5666
|
+
this.canvasKit.RectHeightStyle.Max,
|
|
5667
|
+
this.canvasKit.RectWidthStyle.Tight
|
|
5668
|
+
);
|
|
5669
|
+
for (const rect of positions) {
|
|
5670
|
+
const rectHeight = rect.rect[3] - rect.rect[1];
|
|
5671
|
+
const underlineVerticalOffset = -rectHeight * 0.08 * drawScale * this.absoluteScale;
|
|
5672
|
+
const lineThickness = rectHeight * 0.04 * drawScale * this.absoluteScale;
|
|
5673
|
+
canvas.drawRect(
|
|
5674
|
+
[
|
|
5675
|
+
x + rect.rect[0],
|
|
5676
|
+
// left
|
|
5677
|
+
y + rect.rect[3] + underlineVerticalOffset,
|
|
5678
|
+
// bottom of text + offset
|
|
5679
|
+
x + rect.rect[2],
|
|
5680
|
+
// right
|
|
5681
|
+
y + rect.rect[3] + underlineVerticalOffset + lineThickness
|
|
5682
|
+
// bottom of text + offset + thickness
|
|
5683
|
+
],
|
|
5684
|
+
this.underlinePaint
|
|
5685
|
+
);
|
|
5686
|
+
}
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5449
5689
|
warmup(canvas) {
|
|
5450
5690
|
const i18n = this.game.i18n;
|
|
5451
5691
|
if (i18n && this.localize !== false) {
|
|
@@ -7253,7 +7493,7 @@ function getDefaultExportFromCjs (x) {
|
|
|
7253
7493
|
}
|
|
7254
7494
|
|
|
7255
7495
|
function getAugmentedNamespace(n) {
|
|
7256
|
-
if (n
|
|
7496
|
+
if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n;
|
|
7257
7497
|
var f = n.default;
|
|
7258
7498
|
if (typeof f == "function") {
|
|
7259
7499
|
var a = function a () {
|
|
@@ -9220,11 +9460,18 @@ class Game {
|
|
|
9220
9460
|
/**
|
|
9221
9461
|
* Adds a scene to the game.
|
|
9222
9462
|
*
|
|
9223
|
-
* @remarks A scene, and its children nodes, cannot be presented unless it
|
|
9463
|
+
* @remarks A scene, and its children nodes, cannot be presented unless it
|
|
9464
|
+
* has been added to the game object. A scene can be added to the game
|
|
9465
|
+
* only once.
|
|
9224
9466
|
*
|
|
9225
9467
|
* @param scene
|
|
9226
9468
|
*/
|
|
9227
9469
|
addScene(scene) {
|
|
9470
|
+
if (this.scenes.includes(scene)) {
|
|
9471
|
+
console.warn(
|
|
9472
|
+
`Game.addScene(): scene ${scene.toString()} has already been added to the game. This will cause unpredictable behavior. This warning will become an error in a future release.`
|
|
9473
|
+
);
|
|
9474
|
+
}
|
|
9228
9475
|
scene.game = this;
|
|
9229
9476
|
scene.needsInitialization = true;
|
|
9230
9477
|
this.scenes.push(scene);
|
|
@@ -12271,7 +12518,7 @@ class Story {
|
|
|
12271
12518
|
}
|
|
12272
12519
|
}
|
|
12273
12520
|
|
|
12274
|
-
console.log("\u26AA @m2c2kit/core version 0.3.
|
|
12521
|
+
console.log("\u26AA @m2c2kit/core version 0.3.29 (d1ad307f)");
|
|
12275
12522
|
|
|
12276
12523
|
export { Action, ActivityType, CanvasKitHelpers, ColorfulMutablePath, Composite, Constants, ConstraintType, CustomAction, Dimensions, Easings, Equal, Equals, EventStore, EventStoreMode, FadeAlphaAction, FontManager, Game, GroupAction, I18n, ImageManager, Label, LabelHorizontalAlignmentMode, LayoutConstraint, LegacyTimer, M2EventType, M2ImageStatus, M2Node, M2NodeFactory, M2NodeType, M2SoundStatus, M2c2KitHelpers, MoveAction, MutablePath, NoneTransition, PlayAction, RandomDraws, RepeatAction, RepeatForeverAction, RotateAction, ScaleAction, Scene, SceneTransition, SequenceAction, Shape, ShapeType, SlideTransition, SoundManager, SoundPlayer, SoundRecorder, Sprite, Story, TextLine, Timer, Transition, TransitionDirection, TransitionType, Uuid, WaitAction, WebColors, WebGlInfo, handleInterfaceOptions };
|
|
12277
12524
|
//# sourceMappingURL=index.js.map
|