@combos-fun/plugin-renderer-text 0.0.38 → 0.0.39

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/agent-skill.md CHANGED
@@ -12,22 +12,20 @@ Read for any 2D text label, score display, dialog text, or HUD title.
12
12
  import { Text, TextSystem, type TextParams } from '@combos-fun/plugin-renderer-text';
13
13
  ```
14
14
 
15
- `componentName = 'Text'`, `systemName = 'TextSystem'`.
15
+ `componentName = 'Text'`, `systemName = 'Text'` (class is `TextSystem` — use `game.getSystem(TextSystem)`, not the string).
16
16
 
17
17
  ### `TextParams`
18
18
 
19
19
  | Field | Type | Default |
20
20
  |-------|------|---------|
21
21
  | `text` | `string` | — (required) |
22
- | `style` | `Partial<TextStyle>` | `{ fontSize: 20 }` |
22
+ | `style` | `TextStyleInput` | `{ fontSize: 20 }` |
23
23
 
24
24
  `style` is Pixi **v8** `TextStyle` / `TextStyleOptions`. Common safe fields:
25
25
 
26
26
  - `fill`, `fontFamily`, `fontSize`, `fontWeight`, `fontStyle`
27
27
  - `align`, `wordWrap`, `wordWrapWidth`, `breakWords`, `lineHeight`, `letterSpacing`, `leading`, `padding`
28
- - `stroke`, `dropShadow`
29
-
30
- **Not supported:** `backgroundColor` (and other CSS/DOM or Pixi v7-only shortcuts). For a text plate/bubble background, put `Graphics` or `Img` on a **separate** GameObject behind the text (one visible render Component per GameObject).
28
+ - `stroke`, `dropShadow`, `backgroundColor`
31
29
 
32
30
  Do not treat “full Pixi TextStyle” as “any CSS text property”.
33
31
 
@@ -41,7 +39,6 @@ Do not treat “full Pixi TextStyle” as “any CSS text property”.
41
39
 
42
40
  | Symptom | Fix |
43
41
  |---------|-----|
44
- | `tsc`: `backgroundColor` does not exist on `Partial<TextStyle>` | Remove it; use a sibling/child `Graphics`/`Img` plate |
45
42
  | Text invisible on dark background | Set `style.fill: 0xffffff` (default fill is dark) |
46
43
  | Wrap not working | Set `style.wordWrap: true` AND `style.wordWrapWidth: <px>` |
47
44
  | Custom font not loading | Load the webfont before adding the component (e.g. `document.fonts.load(...)`) |
@@ -50,8 +47,7 @@ Do not treat “full Pixi TextStyle” as “any CSS text property”.
50
47
  ## Minimal example
51
48
 
52
49
  ```ts
53
- const score = new GameObject('score');
54
- score.addComponent(new Transform({ position: { x: 20, y: 20 } }));
50
+ const score = new GameObject('score', { position: { x: 20, y: 20 } });
55
51
  score.addComponent(new Text({ text: 'Score: 0', style: { fontSize: 32, fill: 0xffffff } }));
56
52
  ```
57
53
 
@@ -32,6 +32,41 @@ tslib.__decorate([
32
32
  })
33
33
  ], Text$1.prototype, "text", void 0);
34
34
 
35
+ function splitTextStyle(style = {}) {
36
+ const { backgroundColor, ...pixiStyle } = style;
37
+ return { backgroundColor, pixiStyle };
38
+ }
39
+ /**
40
+ * Accept the common agent guesses: `0xffffff`, `"#fff"`, `"#ffffff"`, `"0xff0000"`.
41
+ * Returns `null` when the value cannot be used as a Pixi fill color.
42
+ */
43
+ function parseTextColor(color) {
44
+ if (color == null)
45
+ return null;
46
+ if (typeof color === 'number') {
47
+ if (!Number.isFinite(color))
48
+ return null;
49
+ return color >>> 0;
50
+ }
51
+ const raw = color.trim();
52
+ if (!raw)
53
+ return null;
54
+ if (raw[0] === '#') {
55
+ const hex = raw.slice(1);
56
+ if (hex.length === 3 && /^[0-9a-fA-F]{3}$/.test(hex)) {
57
+ return parseInt(hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2], 16);
58
+ }
59
+ if ((hex.length === 6 || hex.length === 8) && /^[0-9a-fA-F]+$/.test(hex)) {
60
+ return parseInt(hex.slice(0, 6), 16);
61
+ }
62
+ return null;
63
+ }
64
+ if (/^0x[0-9a-fA-F]+$/.test(raw)) {
65
+ return parseInt(raw, 16) >>> 0;
66
+ }
67
+ return null;
68
+ }
69
+
35
70
  let Text = class Text extends pluginRenderer.Renderer {
36
71
  constructor() {
37
72
  super(...arguments);
@@ -48,22 +83,32 @@ let Text = class Text extends pluginRenderer.Renderer {
48
83
  return;
49
84
  if (changed.type === engine.OBSERVER_TYPE.ADD) {
50
85
  const component = changed.component;
51
- const text = new rendererAdapter.Text(component.text, component.style);
52
- this.containerManager.getContainer(changed.gameObject.id).addChildAt(text, 0);
86
+ const { pixiStyle } = splitTextStyle(component.style);
87
+ const text = new rendererAdapter.Text(component.text, pixiStyle);
88
+ const container = this.containerManager.getContainer(changed.gameObject.id);
89
+ container.addChildAt(text, 0);
53
90
  this.texts[changed.gameObject.id] = {
54
91
  text,
55
- component: changed.component,
92
+ component,
56
93
  };
57
94
  this.setSize(changed);
95
+ this.syncBackground(changed.gameObject.id);
58
96
  }
59
97
  else if (changed.type === engine.OBSERVER_TYPE.REMOVE) {
60
- this.containerManager.getContainer(changed.gameObject.id).removeChild(this.texts[changed.gameObject.id].text);
61
- this.texts[changed.gameObject.id].text.destroy({ children: true });
98
+ const entry = this.texts[changed.gameObject.id];
99
+ const container = this.containerManager.getContainer(changed.gameObject.id);
100
+ if (entry.background) {
101
+ container.removeChild(entry.background);
102
+ entry.background.destroy({ children: true });
103
+ }
104
+ container.removeChild(entry.text);
105
+ entry.text.destroy({ children: true });
62
106
  delete this.texts[changed.gameObject.id];
63
107
  }
64
108
  else {
65
109
  this.change(changed);
66
110
  this.setSize(changed);
111
+ this.syncBackground(changed.gameObject.id);
67
112
  }
68
113
  }
69
114
  change(changed) {
@@ -72,7 +117,8 @@ let Text = class Text extends pluginRenderer.Renderer {
72
117
  text.text = component.text;
73
118
  }
74
119
  else if (changed.prop.prop[0] === 'style') {
75
- Object.assign(text.style, changed.component.style);
120
+ const { pixiStyle } = splitTextStyle(changed.component.style);
121
+ Object.assign(text.style, pixiStyle);
76
122
  }
77
123
  }
78
124
  setSize(changed) {
@@ -82,6 +128,31 @@ let Text = class Text extends pluginRenderer.Renderer {
82
128
  transform.size.width = this.texts[changed.gameObject.id].text.width;
83
129
  transform.size.height = this.texts[changed.gameObject.id].text.height;
84
130
  }
131
+ syncBackground(id) {
132
+ const entry = this.texts[id];
133
+ if (!entry)
134
+ return;
135
+ const color = parseTextColor(splitTextStyle(entry.component.style).backgroundColor);
136
+ const container = this.containerManager.getContainer(id);
137
+ if (color == null) {
138
+ if (entry.background) {
139
+ container.removeChild(entry.background);
140
+ entry.background.destroy({ children: true });
141
+ entry.background = undefined;
142
+ }
143
+ return;
144
+ }
145
+ if (!entry.background) {
146
+ entry.background = new rendererAdapter.Graphics();
147
+ container.addChildAt(entry.background, 0);
148
+ }
149
+ const width = entry.text.width;
150
+ const height = entry.text.height;
151
+ entry.background.clear();
152
+ if (width > 0 && height > 0) {
153
+ entry.background.rect(0, 0, width, height).fill({ color });
154
+ }
155
+ }
85
156
  };
86
157
  Text = tslib.__decorate([
87
158
  engine.decorators.componentObserver({
@@ -92,4 +163,6 @@ var Text_default = Text;
92
163
 
93
164
  exports.Text = Text$1;
94
165
  exports.TextSystem = Text_default;
166
+ exports.parseTextColor = parseTextColor;
167
+ exports.splitTextStyle = splitTextStyle;
95
168
  //# sourceMappingURL=plugin-renderer-text.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-renderer-text.cjs.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import type { TextStyle } from 'pixi.js';\nimport { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface TextParams {\n text: string;\n style?: Partial<TextStyle>;\n}\n\nexport default class Text extends Component<TextParams> {\n static componentName: string = 'Text';\n\n @Field({\n type: 'string',\n group: 'Text',\n label: 'text',\n description: 'Visible text content.',\n editor: 'text',\n })\n text: string = '';\n\n // Complex style object — Scene Edit exposes leaf fields later if needed.\n style: TextParams['style'] = {};\n\n init(obj?: TextParams) {\n this.style = { fontSize: 20 };\n if (obj) {\n this.text = obj.text;\n Object.assign(this.style, obj.style);\n }\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\n\nimport { RendererManager, ContainerManager, RendererSystem, Renderer } from '@combos-fun/plugin-renderer';\nimport { Text as TextEngine } from '@combos-fun/renderer-adapter';\n\nimport TextComponent from './component';\n@decorators.componentObserver({\n Text: ['text', { prop: ['style'], deep: true }],\n})\nexport default class Text extends Renderer {\n static systemName = 'Text';\n name: string = 'Text';\n texts: {\n [propName: number]: { text: TextEngine; component: TextComponent };\n } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text') return;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const component = changed.component as TextComponent;\n const text = new TextEngine(component.text, component.style);\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(text, 0);\n this.texts[changed.gameObject.id] = {\n text,\n component: changed.component as TextComponent,\n };\n this.setSize(changed);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.containerManager.getContainer(changed.gameObject.id).removeChild(this.texts[changed.gameObject.id].text);\n this.texts[changed.gameObject.id].text.destroy({ children: true });\n delete this.texts[changed.gameObject.id];\n } else {\n this.change(changed);\n this.setSize(changed);\n }\n }\n change(changed: ComponentChanged) {\n const { text, component } = this.texts[changed.gameObject.id];\n if (changed.prop.prop[0] === 'text') {\n text.text = component.text;\n } else if (changed.prop.prop[0] === 'style') {\n Object.assign(text.style, (changed.component as TextComponent).style);\n }\n }\n setSize(changed: ComponentChanged) {\n const { transform } = changed.gameObject;\n if (!transform) return;\n transform.size.width = this.texts[changed.gameObject.id].text.width;\n transform.size.height = this.texts[changed.gameObject.id].text.height;\n }\n}\n"],"names":["Component","__decorate","Field","Text","Renderer","RendererSystem","OBSERVER_TYPE","TextEngine","decorators"],"mappings":"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"}
1
+ {"version":3,"file":"plugin-renderer-text.cjs.js","sources":["../lib/component.ts","../lib/textStyle.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextStyleInput } from './textStyle';\n\nexport type { TextStyleInput } from './textStyle';\n\nexport interface TextParams {\n text: string;\n style?: TextStyleInput;\n}\n\nexport default class Text extends Component<TextParams> {\n static componentName: string = 'Text';\n\n @Field({\n type: 'string',\n group: 'Text',\n label: 'text',\n description: 'Visible text content.',\n editor: 'text',\n })\n text: string = '';\n\n // Complex style object — Scene Edit exposes leaf fields later if needed.\n style: TextParams['style'] = {};\n\n init(obj?: TextParams) {\n this.style = { fontSize: 20 };\n if (obj) {\n this.text = obj.text;\n Object.assign(this.style, obj.style);\n }\n }\n}\n","import type { TextStyle } from 'pixi.js';\n\n/** Combos extra on Pixi v8 `TextStyle` — stripped before constructing Pixi Text. */\nexport type TextColor = number | string;\n\nexport type TextStyleInput = Partial<TextStyle> & {\n backgroundColor?: TextColor;\n};\n\nexport function splitTextStyle(style: TextStyleInput = {}): {\n backgroundColor: TextColor | undefined;\n pixiStyle: Partial<TextStyle>;\n} {\n const { backgroundColor, ...pixiStyle } = style;\n return { backgroundColor, pixiStyle };\n}\n\n/**\n * Accept the common agent guesses: `0xffffff`, `\"#fff\"`, `\"#ffffff\"`, `\"0xff0000\"`.\n * Returns `null` when the value cannot be used as a Pixi fill color.\n */\nexport function parseTextColor(color: TextColor | undefined | null): number | null {\n if (color == null) return null;\n if (typeof color === 'number') {\n if (!Number.isFinite(color)) return null;\n return color >>> 0;\n }\n const raw = color.trim();\n if (!raw) return null;\n\n if (raw[0] === '#') {\n const hex = raw.slice(1);\n if (hex.length === 3 && /^[0-9a-fA-F]{3}$/.test(hex)) {\n return parseInt(hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2], 16);\n }\n if ((hex.length === 6 || hex.length === 8) && /^[0-9a-fA-F]+$/.test(hex)) {\n return parseInt(hex.slice(0, 6), 16);\n }\n return null;\n }\n\n if (/^0x[0-9a-fA-F]+$/.test(raw)) {\n return parseInt(raw, 16) >>> 0;\n }\n\n return null;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\n\nimport { RendererManager, ContainerManager, RendererSystem, Renderer } from '@combos-fun/plugin-renderer';\nimport { Graphics, Text as TextEngine } from '@combos-fun/renderer-adapter';\n\nimport TextComponent from './component';\nimport { parseTextColor, splitTextStyle } from './textStyle';\n\n@decorators.componentObserver({\n Text: ['text', { prop: ['style'], deep: true }],\n})\nexport default class Text extends Renderer {\n static systemName = 'Text';\n name: string = 'Text';\n texts: {\n [propName: number]: {\n text: TextEngine;\n background?: Graphics;\n component: TextComponent;\n };\n } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text') return;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const component = changed.component as TextComponent;\n const { pixiStyle } = splitTextStyle(component.style);\n const text = new TextEngine(component.text, pixiStyle);\n const container = this.containerManager.getContainer(changed.gameObject.id);\n container.addChildAt(text, 0);\n this.texts[changed.gameObject.id] = {\n text,\n component,\n };\n this.setSize(changed);\n this.syncBackground(changed.gameObject.id);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n const entry = this.texts[changed.gameObject.id];\n const container = this.containerManager.getContainer(changed.gameObject.id);\n if (entry.background) {\n container.removeChild(entry.background);\n entry.background.destroy({ children: true });\n }\n container.removeChild(entry.text);\n entry.text.destroy({ children: true });\n delete this.texts[changed.gameObject.id];\n } else {\n this.change(changed);\n this.setSize(changed);\n this.syncBackground(changed.gameObject.id);\n }\n }\n change(changed: ComponentChanged) {\n const { text, component } = this.texts[changed.gameObject.id];\n if (changed.prop.prop[0] === 'text') {\n text.text = component.text;\n } else if (changed.prop.prop[0] === 'style') {\n const { pixiStyle } = splitTextStyle((changed.component as TextComponent).style);\n Object.assign(text.style, pixiStyle);\n }\n }\n setSize(changed: ComponentChanged) {\n const { transform } = changed.gameObject;\n if (!transform) return;\n transform.size.width = this.texts[changed.gameObject.id].text.width;\n transform.size.height = this.texts[changed.gameObject.id].text.height;\n }\n private syncBackground(id: number) {\n const entry = this.texts[id];\n if (!entry) return;\n const color = parseTextColor(splitTextStyle(entry.component.style).backgroundColor);\n const container = this.containerManager.getContainer(id);\n if (color == null) {\n if (entry.background) {\n container.removeChild(entry.background);\n entry.background.destroy({ children: true });\n entry.background = undefined;\n }\n return;\n }\n if (!entry.background) {\n entry.background = new Graphics();\n container.addChildAt(entry.background, 0);\n }\n const width = entry.text.width;\n const height = entry.text.height;\n entry.background.clear();\n if (width > 0 && height > 0) {\n entry.background.rect(0, 0, width, height).fill({ color });\n }\n }\n}\n"],"names":["Component","__decorate","Field","Text","Renderer","RendererSystem","OBSERVER_TYPE","TextEngine","Graphics","decorators"],"mappings":"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"}
@@ -1 +1 @@
1
- "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),s=require("@combos-fun/inspector-decorator"),i=require("@combos-fun/plugin-renderer"),r=require("@combos-fun/renderer-adapter");let n=class extends t.Component{constructor(){super(...arguments),this.text="",this.style={}}static{this.componentName="Text"}init(e){this.style={fontSize:20},e&&(this.text=e.text,Object.assign(this.style,e.style))}};e.__decorate([s.Field({type:"string",group:"Text",label:"text",description:"Visible text content.",editor:"text"})],n.prototype,"text",void 0);let o=class extends i.Renderer{constructor(){super(...arguments),this.name="Text",this.texts={}}static{this.systemName="Text"}init(){this.renderSystem=this.game.getSystem(i.RendererSystem),this.renderSystem.rendererManager.register(this)}async componentChanged(e){if("Text"===e.componentName)if(e.type===t.OBSERVER_TYPE.ADD){const t=e.component,s=new r.Text(t.text,t.style);this.containerManager.getContainer(e.gameObject.id).addChildAt(s,0),this.texts[e.gameObject.id]={text:s,component:e.component},this.setSize(e)}else e.type===t.OBSERVER_TYPE.REMOVE?(this.containerManager.getContainer(e.gameObject.id).removeChild(this.texts[e.gameObject.id].text),this.texts[e.gameObject.id].text.destroy({children:!0}),delete this.texts[e.gameObject.id]):(this.change(e),this.setSize(e))}change(e){const{text:t,component:s}=this.texts[e.gameObject.id];"text"===e.prop.prop[0]?t.text=s.text:"style"===e.prop.prop[0]&&Object.assign(t.style,e.component.style)}setSize(e){const{transform:t}=e.gameObject;t&&(t.size.width=this.texts[e.gameObject.id].text.width,t.size.height=this.texts[e.gameObject.id].text.height)}};o=e.__decorate([t.decorators.componentObserver({Text:["text",{prop:["style"],deep:!0}]})],o);var c=o;exports.Text=n,exports.TextSystem=c;
1
+ "use strict";var e=require("tslib"),t=require("@combos-fun/engine"),n=require("@combos-fun/inspector-decorator"),r=require("@combos-fun/plugin-renderer"),s=require("@combos-fun/renderer-adapter");let i=class extends t.Component{constructor(){super(...arguments),this.text="",this.style={}}static{this.componentName="Text"}init(e){this.style={fontSize:20},e&&(this.text=e.text,Object.assign(this.style,e.style))}};function o(e={}){const{backgroundColor:t,...n}=e;return{backgroundColor:t,pixiStyle:n}}function c(e){if(null==e)return null;if("number"==typeof e)return Number.isFinite(e)?e>>>0:null;const t=e.trim();if(!t)return null;if("#"===t[0]){const e=t.slice(1);return 3===e.length&&/^[0-9a-fA-F]{3}$/.test(e)?parseInt(e[0]+e[0]+e[1]+e[1]+e[2]+e[2],16):6!==e.length&&8!==e.length||!/^[0-9a-fA-F]+$/.test(e)?null:parseInt(e.slice(0,6),16)}return/^0x[0-9a-fA-F]+$/.test(t)?parseInt(t,16)>>>0:null}e.__decorate([n.Field({type:"string",group:"Text",label:"text",description:"Visible text content.",editor:"text"})],i.prototype,"text",void 0);let a=class extends r.Renderer{constructor(){super(...arguments),this.name="Text",this.texts={}}static{this.systemName="Text"}init(){this.renderSystem=this.game.getSystem(r.RendererSystem),this.renderSystem.rendererManager.register(this)}async componentChanged(e){if("Text"===e.componentName)if(e.type===t.OBSERVER_TYPE.ADD){const t=e.component,{pixiStyle:n}=o(t.style),r=new s.Text(t.text,n);this.containerManager.getContainer(e.gameObject.id).addChildAt(r,0),this.texts[e.gameObject.id]={text:r,component:t},this.setSize(e),this.syncBackground(e.gameObject.id)}else if(e.type===t.OBSERVER_TYPE.REMOVE){const t=this.texts[e.gameObject.id],n=this.containerManager.getContainer(e.gameObject.id);t.background&&(n.removeChild(t.background),t.background.destroy({children:!0})),n.removeChild(t.text),t.text.destroy({children:!0}),delete this.texts[e.gameObject.id]}else this.change(e),this.setSize(e),this.syncBackground(e.gameObject.id)}change(e){const{text:t,component:n}=this.texts[e.gameObject.id];if("text"===e.prop.prop[0])t.text=n.text;else if("style"===e.prop.prop[0]){const{pixiStyle:n}=o(e.component.style);Object.assign(t.style,n)}}setSize(e){const{transform:t}=e.gameObject;t&&(t.size.width=this.texts[e.gameObject.id].text.width,t.size.height=this.texts[e.gameObject.id].text.height)}syncBackground(e){const t=this.texts[e];if(!t)return;const n=c(o(t.component.style).backgroundColor),r=this.containerManager.getContainer(e);if(null==n)return void(t.background&&(r.removeChild(t.background),t.background.destroy({children:!0}),t.background=void 0));t.background||(t.background=new s.Graphics,r.addChildAt(t.background,0));const i=t.text.width,a=t.text.height;t.background.clear(),i>0&&a>0&&t.background.rect(0,0,i,a).fill({color:n})}};a=e.__decorate([t.decorators.componentObserver({Text:["text",{prop:["style"],deep:!0}]})],a);var d=a;exports.Text=i,exports.TextSystem=d,exports.parseTextColor=c,exports.splitTextStyle=o;
@@ -1,11 +1,26 @@
1
- import { TextStyle } from 'pixi.js';
2
1
  import { Component, ComponentChanged } from '@combos-fun/engine';
2
+ import { TextStyle } from 'pixi.js';
3
3
  import { Renderer, RendererSystem, RendererManager, ContainerManager } from '@combos-fun/plugin-renderer';
4
- import { Text as Text$2 } from '@combos-fun/renderer-adapter';
4
+ import { Text as Text$2, Graphics } from '@combos-fun/renderer-adapter';
5
+
6
+ /** Combos extra on Pixi v8 `TextStyle` — stripped before constructing Pixi Text. */
7
+ type TextColor = number | string;
8
+ type TextStyleInput = Partial<TextStyle> & {
9
+ backgroundColor?: TextColor;
10
+ };
11
+ declare function splitTextStyle(style?: TextStyleInput): {
12
+ backgroundColor: TextColor | undefined;
13
+ pixiStyle: Partial<TextStyle>;
14
+ };
15
+ /**
16
+ * Accept the common agent guesses: `0xffffff`, `"#fff"`, `"#ffffff"`, `"0xff0000"`.
17
+ * Returns `null` when the value cannot be used as a Pixi fill color.
18
+ */
19
+ declare function parseTextColor(color: TextColor | undefined | null): number | null;
5
20
 
6
21
  interface TextParams {
7
22
  text: string;
8
- style?: Partial<TextStyle>;
23
+ style?: TextStyleInput;
9
24
  }
10
25
  declare class Text$1 extends Component<TextParams> {
11
26
  static componentName: string;
@@ -20,6 +35,7 @@ declare class Text extends Renderer {
20
35
  texts: {
21
36
  [propName: number]: {
22
37
  text: Text$2;
38
+ background?: Graphics;
23
39
  component: Text$1;
24
40
  };
25
41
  };
@@ -30,7 +46,8 @@ declare class Text extends Renderer {
30
46
  componentChanged(changed: ComponentChanged): Promise<void>;
31
47
  change(changed: ComponentChanged): void;
32
48
  setSize(changed: ComponentChanged): void;
49
+ private syncBackground;
33
50
  }
34
51
 
35
- export { Text$1 as Text, Text as TextSystem };
36
- export type { TextParams };
52
+ export { Text$1 as Text, Text as TextSystem, parseTextColor, splitTextStyle };
53
+ export type { TextParams, TextStyleInput };
@@ -2,7 +2,7 @@ import { __decorate } from 'tslib';
2
2
  import { Component, OBSERVER_TYPE, decorators } from '@combos-fun/engine';
3
3
  import { Field } from '@combos-fun/inspector-decorator';
4
4
  import { Renderer, RendererSystem } from '@combos-fun/plugin-renderer';
5
- import { Text as Text$2 } from '@combos-fun/renderer-adapter';
5
+ import { Text as Text$2, Graphics } from '@combos-fun/renderer-adapter';
6
6
 
7
7
  let Text$1 = class Text extends Component {
8
8
  constructor() {
@@ -30,6 +30,41 @@ __decorate([
30
30
  })
31
31
  ], Text$1.prototype, "text", void 0);
32
32
 
33
+ function splitTextStyle(style = {}) {
34
+ const { backgroundColor, ...pixiStyle } = style;
35
+ return { backgroundColor, pixiStyle };
36
+ }
37
+ /**
38
+ * Accept the common agent guesses: `0xffffff`, `"#fff"`, `"#ffffff"`, `"0xff0000"`.
39
+ * Returns `null` when the value cannot be used as a Pixi fill color.
40
+ */
41
+ function parseTextColor(color) {
42
+ if (color == null)
43
+ return null;
44
+ if (typeof color === 'number') {
45
+ if (!Number.isFinite(color))
46
+ return null;
47
+ return color >>> 0;
48
+ }
49
+ const raw = color.trim();
50
+ if (!raw)
51
+ return null;
52
+ if (raw[0] === '#') {
53
+ const hex = raw.slice(1);
54
+ if (hex.length === 3 && /^[0-9a-fA-F]{3}$/.test(hex)) {
55
+ return parseInt(hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2], 16);
56
+ }
57
+ if ((hex.length === 6 || hex.length === 8) && /^[0-9a-fA-F]+$/.test(hex)) {
58
+ return parseInt(hex.slice(0, 6), 16);
59
+ }
60
+ return null;
61
+ }
62
+ if (/^0x[0-9a-fA-F]+$/.test(raw)) {
63
+ return parseInt(raw, 16) >>> 0;
64
+ }
65
+ return null;
66
+ }
67
+
33
68
  let Text = class Text extends Renderer {
34
69
  constructor() {
35
70
  super(...arguments);
@@ -46,22 +81,32 @@ let Text = class Text extends Renderer {
46
81
  return;
47
82
  if (changed.type === OBSERVER_TYPE.ADD) {
48
83
  const component = changed.component;
49
- const text = new Text$2(component.text, component.style);
50
- this.containerManager.getContainer(changed.gameObject.id).addChildAt(text, 0);
84
+ const { pixiStyle } = splitTextStyle(component.style);
85
+ const text = new Text$2(component.text, pixiStyle);
86
+ const container = this.containerManager.getContainer(changed.gameObject.id);
87
+ container.addChildAt(text, 0);
51
88
  this.texts[changed.gameObject.id] = {
52
89
  text,
53
- component: changed.component,
90
+ component,
54
91
  };
55
92
  this.setSize(changed);
93
+ this.syncBackground(changed.gameObject.id);
56
94
  }
57
95
  else if (changed.type === OBSERVER_TYPE.REMOVE) {
58
- this.containerManager.getContainer(changed.gameObject.id).removeChild(this.texts[changed.gameObject.id].text);
59
- this.texts[changed.gameObject.id].text.destroy({ children: true });
96
+ const entry = this.texts[changed.gameObject.id];
97
+ const container = this.containerManager.getContainer(changed.gameObject.id);
98
+ if (entry.background) {
99
+ container.removeChild(entry.background);
100
+ entry.background.destroy({ children: true });
101
+ }
102
+ container.removeChild(entry.text);
103
+ entry.text.destroy({ children: true });
60
104
  delete this.texts[changed.gameObject.id];
61
105
  }
62
106
  else {
63
107
  this.change(changed);
64
108
  this.setSize(changed);
109
+ this.syncBackground(changed.gameObject.id);
65
110
  }
66
111
  }
67
112
  change(changed) {
@@ -70,7 +115,8 @@ let Text = class Text extends Renderer {
70
115
  text.text = component.text;
71
116
  }
72
117
  else if (changed.prop.prop[0] === 'style') {
73
- Object.assign(text.style, changed.component.style);
118
+ const { pixiStyle } = splitTextStyle(changed.component.style);
119
+ Object.assign(text.style, pixiStyle);
74
120
  }
75
121
  }
76
122
  setSize(changed) {
@@ -80,6 +126,31 @@ let Text = class Text extends Renderer {
80
126
  transform.size.width = this.texts[changed.gameObject.id].text.width;
81
127
  transform.size.height = this.texts[changed.gameObject.id].text.height;
82
128
  }
129
+ syncBackground(id) {
130
+ const entry = this.texts[id];
131
+ if (!entry)
132
+ return;
133
+ const color = parseTextColor(splitTextStyle(entry.component.style).backgroundColor);
134
+ const container = this.containerManager.getContainer(id);
135
+ if (color == null) {
136
+ if (entry.background) {
137
+ container.removeChild(entry.background);
138
+ entry.background.destroy({ children: true });
139
+ entry.background = undefined;
140
+ }
141
+ return;
142
+ }
143
+ if (!entry.background) {
144
+ entry.background = new Graphics();
145
+ container.addChildAt(entry.background, 0);
146
+ }
147
+ const width = entry.text.width;
148
+ const height = entry.text.height;
149
+ entry.background.clear();
150
+ if (width > 0 && height > 0) {
151
+ entry.background.rect(0, 0, width, height).fill({ color });
152
+ }
153
+ }
83
154
  };
84
155
  Text = __decorate([
85
156
  decorators.componentObserver({
@@ -88,5 +159,5 @@ Text = __decorate([
88
159
  ], Text);
89
160
  var Text_default = Text;
90
161
 
91
- export { Text$1 as Text, Text_default as TextSystem };
162
+ export { Text$1 as Text, Text_default as TextSystem, parseTextColor, splitTextStyle };
92
163
  //# sourceMappingURL=plugin-renderer-text.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-renderer-text.esm.js","sources":["../lib/component.ts","../lib/system.ts"],"sourcesContent":["import type { TextStyle } from 'pixi.js';\nimport { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\n\nexport interface TextParams {\n text: string;\n style?: Partial<TextStyle>;\n}\n\nexport default class Text extends Component<TextParams> {\n static componentName: string = 'Text';\n\n @Field({\n type: 'string',\n group: 'Text',\n label: 'text',\n description: 'Visible text content.',\n editor: 'text',\n })\n text: string = '';\n\n // Complex style object — Scene Edit exposes leaf fields later if needed.\n style: TextParams['style'] = {};\n\n init(obj?: TextParams) {\n this.style = { fontSize: 20 };\n if (obj) {\n this.text = obj.text;\n Object.assign(this.style, obj.style);\n }\n }\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\n\nimport { RendererManager, ContainerManager, RendererSystem, Renderer } from '@combos-fun/plugin-renderer';\nimport { Text as TextEngine } from '@combos-fun/renderer-adapter';\n\nimport TextComponent from './component';\n@decorators.componentObserver({\n Text: ['text', { prop: ['style'], deep: true }],\n})\nexport default class Text extends Renderer {\n static systemName = 'Text';\n name: string = 'Text';\n texts: {\n [propName: number]: { text: TextEngine; component: TextComponent };\n } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text') return;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const component = changed.component as TextComponent;\n const text = new TextEngine(component.text, component.style);\n this.containerManager.getContainer(changed.gameObject.id).addChildAt(text, 0);\n this.texts[changed.gameObject.id] = {\n text,\n component: changed.component as TextComponent,\n };\n this.setSize(changed);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n this.containerManager.getContainer(changed.gameObject.id).removeChild(this.texts[changed.gameObject.id].text);\n this.texts[changed.gameObject.id].text.destroy({ children: true });\n delete this.texts[changed.gameObject.id];\n } else {\n this.change(changed);\n this.setSize(changed);\n }\n }\n change(changed: ComponentChanged) {\n const { text, component } = this.texts[changed.gameObject.id];\n if (changed.prop.prop[0] === 'text') {\n text.text = component.text;\n } else if (changed.prop.prop[0] === 'style') {\n Object.assign(text.style, (changed.component as TextComponent).style);\n }\n }\n setSize(changed: ComponentChanged) {\n const { transform } = changed.gameObject;\n if (!transform) return;\n transform.size.width = this.texts[changed.gameObject.id].text.width;\n transform.size.height = this.texts[changed.gameObject.id].text.height;\n }\n}\n"],"names":["Text","TextEngine"],"mappings":"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"}
1
+ {"version":3,"file":"plugin-renderer-text.esm.js","sources":["../lib/component.ts","../lib/textStyle.ts","../lib/system.ts"],"sourcesContent":["import { Component } from '@combos-fun/engine';\nimport { Field } from '@combos-fun/inspector-decorator';\nimport type { TextStyleInput } from './textStyle';\n\nexport type { TextStyleInput } from './textStyle';\n\nexport interface TextParams {\n text: string;\n style?: TextStyleInput;\n}\n\nexport default class Text extends Component<TextParams> {\n static componentName: string = 'Text';\n\n @Field({\n type: 'string',\n group: 'Text',\n label: 'text',\n description: 'Visible text content.',\n editor: 'text',\n })\n text: string = '';\n\n // Complex style object — Scene Edit exposes leaf fields later if needed.\n style: TextParams['style'] = {};\n\n init(obj?: TextParams) {\n this.style = { fontSize: 20 };\n if (obj) {\n this.text = obj.text;\n Object.assign(this.style, obj.style);\n }\n }\n}\n","import type { TextStyle } from 'pixi.js';\n\n/** Combos extra on Pixi v8 `TextStyle` — stripped before constructing Pixi Text. */\nexport type TextColor = number | string;\n\nexport type TextStyleInput = Partial<TextStyle> & {\n backgroundColor?: TextColor;\n};\n\nexport function splitTextStyle(style: TextStyleInput = {}): {\n backgroundColor: TextColor | undefined;\n pixiStyle: Partial<TextStyle>;\n} {\n const { backgroundColor, ...pixiStyle } = style;\n return { backgroundColor, pixiStyle };\n}\n\n/**\n * Accept the common agent guesses: `0xffffff`, `\"#fff\"`, `\"#ffffff\"`, `\"0xff0000\"`.\n * Returns `null` when the value cannot be used as a Pixi fill color.\n */\nexport function parseTextColor(color: TextColor | undefined | null): number | null {\n if (color == null) return null;\n if (typeof color === 'number') {\n if (!Number.isFinite(color)) return null;\n return color >>> 0;\n }\n const raw = color.trim();\n if (!raw) return null;\n\n if (raw[0] === '#') {\n const hex = raw.slice(1);\n if (hex.length === 3 && /^[0-9a-fA-F]{3}$/.test(hex)) {\n return parseInt(hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2], 16);\n }\n if ((hex.length === 6 || hex.length === 8) && /^[0-9a-fA-F]+$/.test(hex)) {\n return parseInt(hex.slice(0, 6), 16);\n }\n return null;\n }\n\n if (/^0x[0-9a-fA-F]+$/.test(raw)) {\n return parseInt(raw, 16) >>> 0;\n }\n\n return null;\n}\n","import { decorators, ComponentChanged, OBSERVER_TYPE } from '@combos-fun/engine';\n\nimport { RendererManager, ContainerManager, RendererSystem, Renderer } from '@combos-fun/plugin-renderer';\nimport { Graphics, Text as TextEngine } from '@combos-fun/renderer-adapter';\n\nimport TextComponent from './component';\nimport { parseTextColor, splitTextStyle } from './textStyle';\n\n@decorators.componentObserver({\n Text: ['text', { prop: ['style'], deep: true }],\n})\nexport default class Text extends Renderer {\n static systemName = 'Text';\n name: string = 'Text';\n texts: {\n [propName: number]: {\n text: TextEngine;\n background?: Graphics;\n component: TextComponent;\n };\n } = {};\n renderSystem: RendererSystem;\n rendererManager: RendererManager;\n containerManager: ContainerManager;\n init() {\n this.renderSystem = this.game.getSystem(RendererSystem) as RendererSystem;\n this.renderSystem.rendererManager.register(this);\n }\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Text') return;\n if (changed.type === OBSERVER_TYPE.ADD) {\n const component = changed.component as TextComponent;\n const { pixiStyle } = splitTextStyle(component.style);\n const text = new TextEngine(component.text, pixiStyle);\n const container = this.containerManager.getContainer(changed.gameObject.id);\n container.addChildAt(text, 0);\n this.texts[changed.gameObject.id] = {\n text,\n component,\n };\n this.setSize(changed);\n this.syncBackground(changed.gameObject.id);\n } else if (changed.type === OBSERVER_TYPE.REMOVE) {\n const entry = this.texts[changed.gameObject.id];\n const container = this.containerManager.getContainer(changed.gameObject.id);\n if (entry.background) {\n container.removeChild(entry.background);\n entry.background.destroy({ children: true });\n }\n container.removeChild(entry.text);\n entry.text.destroy({ children: true });\n delete this.texts[changed.gameObject.id];\n } else {\n this.change(changed);\n this.setSize(changed);\n this.syncBackground(changed.gameObject.id);\n }\n }\n change(changed: ComponentChanged) {\n const { text, component } = this.texts[changed.gameObject.id];\n if (changed.prop.prop[0] === 'text') {\n text.text = component.text;\n } else if (changed.prop.prop[0] === 'style') {\n const { pixiStyle } = splitTextStyle((changed.component as TextComponent).style);\n Object.assign(text.style, pixiStyle);\n }\n }\n setSize(changed: ComponentChanged) {\n const { transform } = changed.gameObject;\n if (!transform) return;\n transform.size.width = this.texts[changed.gameObject.id].text.width;\n transform.size.height = this.texts[changed.gameObject.id].text.height;\n }\n private syncBackground(id: number) {\n const entry = this.texts[id];\n if (!entry) return;\n const color = parseTextColor(splitTextStyle(entry.component.style).backgroundColor);\n const container = this.containerManager.getContainer(id);\n if (color == null) {\n if (entry.background) {\n container.removeChild(entry.background);\n entry.background.destroy({ children: true });\n entry.background = undefined;\n }\n return;\n }\n if (!entry.background) {\n entry.background = new Graphics();\n container.addChildAt(entry.background, 0);\n }\n const width = entry.text.width;\n const height = entry.text.height;\n entry.background.clear();\n if (width > 0 && height > 0) {\n entry.background.rect(0, 0, width, height).fill({ color });\n }\n }\n}\n"],"names":["Text","TextEngine"],"mappings":";;;;;;aAWc,MAAO,IAAK,SAAQ,SAAqB,CAAA;AAAvD,IAAA,WAAA,GAAA;;QAUE,IAAA,CAAA,IAAI,GAAW,EAAE;;QAGjB,IAAA,CAAA,KAAK,GAAwB,EAAE;IASjC;aArBS,IAAA,CAAA,aAAa,GAAW,MAAX,CAAkB;AActC,IAAA,IAAI,CAAC,GAAgB,EAAA;QACnB,IAAI,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC7B,IAAI,GAAG,EAAE;AACP,YAAA,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC;QACtC;IACF;;AAXA,UAAA,CAAA;AAPC,IAAA,KAAK,CAAC;AACL,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,KAAK,EAAE,MAAM;AACb,QAAA,KAAK,EAAE,MAAM;AACb,QAAA,WAAW,EAAE,uBAAuB;AACpC,QAAA,MAAM,EAAE,MAAM;KACf;AACiB,CAAA,EAAAA,MAAA,CAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA;;ACZd,SAAU,cAAc,CAAC,KAAA,GAAwB,EAAE,EAAA;IAIvD,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK;AAC/C,IAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE;AACvC;AAEA;;;AAGG;AACG,SAAU,cAAc,CAAC,KAAmC,EAAA;IAChE,IAAI,KAAK,IAAI,IAAI;AAAE,QAAA,OAAO,IAAI;AAC9B,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,YAAA,OAAO,IAAI;QACxC,OAAO,KAAK,KAAK,CAAC;IACpB;AACA,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE;AACxB,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,IAAI;AAErB,IAAA,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;QAClB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACxB,QAAA,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACpD,YAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC1E;QACA,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACxE,YAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QACtC;AACA,QAAA,OAAO,IAAI;IACb;AAEA,IAAA,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAChC,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC;IAChC;AAEA,IAAA,OAAO,IAAI;AACb;;ACnCe,IAAM,IAAI,GAAV,MAAM,IAAK,SAAQ,QAAQ,CAAA;AAA3B,IAAA,WAAA,GAAA;;QAEb,IAAA,CAAA,IAAI,GAAW,MAAM;QACrB,IAAA,CAAA,KAAK,GAMD,EAAE;IA6ER;aArFS,IAAA,CAAA,UAAU,GAAG,MAAH,CAAU;IAY3B,IAAI,GAAA;QACF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAmB;QACzE,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClD;IACA,MAAM,gBAAgB,CAAC,OAAyB,EAAA;AAC9C,QAAA,IAAI,OAAO,CAAC,aAAa,KAAK,MAAM;YAAE;QACtC,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,GAAG,EAAE;AACtC,YAAA,MAAM,SAAS,GAAG,OAAO,CAAC,SAA0B;YACpD,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC;YACrD,MAAM,IAAI,GAAG,IAAIC,MAAU,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC;AACtD,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3E,YAAA,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG;gBAClC,IAAI;gBACJ,SAAS;aACV;AACD,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C;aAAO,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE;AAChD,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC/C,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAC3E,YAAA,IAAI,KAAK,CAAC,UAAU,EAAE;AACpB,gBAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC9C;AACA,YAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C;aAAO;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACpB,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C;IACF;AACA,IAAA,MAAM,CAAC,OAAyB,EAAA;AAC9B,QAAA,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;AACnC,YAAA,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI;QAC5B;aAAO,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE;AAC3C,YAAA,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAE,OAAO,CAAC,SAA2B,CAAC,KAAK,CAAC;YAChF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;QACtC;IACF;AACA,IAAA,OAAO,CAAC,OAAyB,EAAA;AAC/B,QAAA,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU;AACxC,QAAA,IAAI,CAAC,SAAS;YAAE;AAChB,QAAA,SAAS,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK;AACnE,QAAA,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;IACvE;AACQ,IAAA,cAAc,CAAC,EAAU,EAAA;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5B,QAAA,IAAI,CAAC,KAAK;YAAE;AACZ,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC;QACnF,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,CAAC;AACxD,QAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACjB,YAAA,IAAI,KAAK,CAAC,UAAU,EAAE;AACpB,gBAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5C,gBAAA,KAAK,CAAC,UAAU,GAAG,SAAS;YAC9B;YACA;QACF;AACA,QAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;AACrB,YAAA,KAAK,CAAC,UAAU,GAAG,IAAI,QAAQ,EAAE;YACjC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3C;AACA,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK;AAC9B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM;AAChC,QAAA,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE;QACxB,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE;YAC3B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;QAC5D;IACF;;AArFmB,IAAI,GAAA,UAAA,CAAA;IAHxB,UAAU,CAAC,iBAAiB,CAAC;AAC5B,QAAA,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KAChD;AACoB,CAAA,EAAA,IAAI,CAsFxB;mBAtFoB,IAAI;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@combos-fun/plugin-renderer-text",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
4
4
  "description": "Text rendering",
5
5
  "main": "index.js",
6
6
  "module": "dist/plugin-renderer-text.esm.js",
@@ -35,13 +35,17 @@
35
35
  ],
36
36
  "author": "sun668 <q947692259@gmail.com>",
37
37
  "dependencies": {
38
- "@combos-fun/plugin-renderer": "0.0.38",
39
- "@combos-fun/renderer-adapter": "0.0.38",
40
- "@combos-fun/engine": "0.0.38",
38
+ "@combos-fun/plugin-renderer": "0.0.39",
39
+ "@combos-fun/renderer-adapter": "0.0.39",
40
+ "@combos-fun/engine": "0.0.39",
41
41
  "pixi.js": "^8.18.1",
42
- "@combos-fun/inspector-decorator": "0.0.38"
42
+ "@combos-fun/inspector-decorator": "0.0.39"
43
+ },
44
+ "devDependencies": {
45
+ "tsx": "^4.20.3"
43
46
  },
44
47
  "scripts": {
45
- "build": "node ../../scripts/build-package.mjs"
48
+ "build": "node ../../scripts/build-package.mjs",
49
+ "test": "node --import tsx --test test/textStyle.test.ts"
46
50
  }
47
51
  }