Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat:The first version of text system #686

Merged
merged 106 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
2b94bb7
feat(text): init TextRenderer
singlecoder Oct 11, 2021
279bc2b
Merge branch 'dev/0.6' of https://github.com/oasis-engine/engine into…
singlecoder Oct 11, 2021
a707c94
feat(text): add bounds
singlecoder Oct 12, 2021
0108031
Merge branch 'dev/0.6' of https://github.com/oasis-engine/engine into…
singlecoder Oct 12, 2021
35355e2
Merge branch 'dev/0.6' of https://github.com/oasis-engine/engine into…
singlecoder Nov 1, 2021
81f8fe5
feat(text): first basic version
singlecoder Nov 2, 2021
1a0105a
feat(text): fix black border
singlecoder Nov 2, 2021
e57fdf9
feat(text): opt canvas for 2d
singlecoder Nov 4, 2021
1a0862d
feat(text): opt text color
singlecoder Nov 5, 2021
359ba5f
merge main (#576)
GuoLei1990 Nov 11, 2021
c1a7473
feat(text): fix conflicts
singlecoder Nov 15, 2021
28455a8
feat(text): opt code
singlecoder Nov 15, 2021
99dde83
feat(text): modify version
singlecoder Nov 15, 2021
7df7a01
feat(text): fix conflicts
singlecoder Nov 16, 2021
80d3fa8
feat(text): fix conflicts
singlecoder Nov 16, 2021
9a30dbe
feat: text (#586)
singlecoder Nov 16, 2021
dbd84ad
Dev/0.6 plus (#590)
GuoLei1990 Nov 16, 2021
1f1b45c
Merge latest main (#596)
GuoLei1990 Nov 19, 2021
1337de8
feat(text): text renderer handle text is empty (#597)
singlecoder Nov 22, 2021
df6ef22
Plus/ibl rotation (#599)
zhuxudong Nov 24, 2021
d56ed3d
fix: stop use collison detection i n lite package (#606)
yangfengzzz Dec 1, 2021
565c59d
Merge latest `main` to `dev/0.6-plus` (#612)
GuoLei1990 Dec 7, 2021
338512b
fix: front face bug (#613)
GuoLei1990 Dec 7, 2021
b3f5503
Fix Reject Error (#624)
gz65555 Dec 31, 2021
9a24887
Fix iOS not support promise.finally (#626)
gz65555 Dec 31, 2021
422fa16
feat: adapt text for paladin (#625)
singlecoder Dec 31, 2021
041f94b
fix `entity` and `glTF` destroy bug (#629)
GuoLei1990 Jan 5, 2022
d37b4c7
fixBug:No exception is thrown after the atlas fails to load (#631)
cptbtptpbcptdtptp Jan 7, 2022
e65cc89
fix(text): conflicts
Jan 10, 2022
7a6885b
feat(text): chagne TextRenderer base class change to Renderer
Jan 10, 2022
9d27c44
feat(text): text first version
Jan 12, 2022
1fcf71d
feat(text): text first version
singlecoder Jan 12, 2022
598dcac
Merge branch 'feat/text' of https://github.com/singlecoder/engine int…
singlecoder Jan 12, 2022
eb8a2e6
fix(text): wrap width not avalid
singlecoder Jan 13, 2022
2ad5d8a
feat(text): opt code
singlecoder Jan 13, 2022
7053a4d
feat(text): opt code
singlecoder Jan 17, 2022
7128985
feat(text): add dynamic atlas
singlecoder Jan 18, 2022
a6caa94
feat(text): temp code
singlecoder Jan 18, 2022
a91c1d4
feat(text): dynamic atlas first version
singlecoder Jan 18, 2022
d3e4ed9
feat(text): opt code for addSprite
singlecoder Jan 19, 2022
916abb0
feat(text): opt memory for text renderer
singlecoder Jan 19, 2022
c88417f
feat(text): opt code
singlecoder Jan 21, 2022
840c998
feat(text): opt code
singlecoder Jan 25, 2022
09fe2fe
feat(text): opt code
singlecoder Jan 25, 2022
7969a6b
feat(text): opt code
singlecoder Jan 25, 2022
a90938a
feat(text): opt code
singlecoder Feb 11, 2022
6ef0499
feat(text): fix texture mipmap error
singlecoder Feb 11, 2022
efd617d
feat(text): fix conflicts
singlecoder Feb 15, 2022
2eccca9
fix: normal attributer is need in unlit (#637)
zhuxudong Feb 17, 2022
b28c936
fix: physx bug (#651)
yangfengzzz Feb 17, 2022
55ce80f
v0.6.7
GuoLei1990 Feb 17, 2022
a704854
fix: get pixel buffer use mip level should right shift (#656)
gz65555 Mar 2, 2022
070e621
Update AnimatorState.ts (#657)
luzhuang Mar 2, 2022
ffe530c
Rename `ability` to `component`. (#608)
eyworldwide Mar 2, 2022
bec99aa
fix: resize max uniform vector count (#660)
zhuxudong Mar 2, 2022
1bb360f
fix: fix conflicts
singlecoder Mar 3, 2022
c31a820
Merge branch 'dev/0.7' of https://github.com/oasis-engine/engine into…
singlecoder Mar 8, 2022
42ab0bb
feat(text): fix when text change but position not update
singlecoder Mar 8, 2022
2db0f20
Merge branch 'dev/0.7' of https://github.com/oasis-engine/engine into…
singlecoder Mar 10, 2022
ce9575b
feat(text): fix conflicts
singlecoder Mar 10, 2022
9942fd5
Merge remote-tracking branch 'origin' into feat/text
singlecoder Mar 10, 2022
85d9871
feat(text): fix conflicts
singlecoder Mar 10, 2022
709e3e9
feat(text): fix conflicts
singlecoder Mar 10, 2022
120a86f
feat(text): fix conflicts
singlecoder Mar 10, 2022
793dc2b
feat(text): fix conflicts
singlecoder Mar 10, 2022
ff379b2
Merge branch 'dev/0.7' of https://github.com/oasis-engine/engine into…
singlecoder Mar 16, 2022
7ddd1ec
feat(text): opt code
singlecoder Mar 16, 2022
7797e47
feat(text): move dynamic atlas manager to internal
singlecoder Mar 18, 2022
a117250
feat(text): opt code
singlecoder Mar 18, 2022
a5eca02
feat(text): delete pre multiple
singlecoder Mar 18, 2022
6ef9176
feat(text): delete line
singlecoder Mar 18, 2022
bbb5c9e
feat(text): opt code, opt property name from lineSpace to lineSpacing
singlecoder Mar 18, 2022
0383302
feat(text): add text style
singlecoder Mar 18, 2022
0a68e20
Merge branch 'dev/0.7' of https://github.com/oasis-engine/engine into…
singlecoder Mar 21, 2022
01585ca
feat(text): add Font asset, and change fontName to font
singlecoder Mar 21, 2022
5c5e6eb
feat(text): opt api change _horizontalOverflow to _enableWarpping
singlecoder Mar 21, 2022
697be15
feat(text): rename overflow and wrap
singlecoder Mar 21, 2022
6ee9989
feat(text): opt recomment
singlecoder Mar 23, 2022
12dc4df
feat(text): spelling error correction
singlecoder Mar 23, 2022
03e3d10
feat(text): opt font style
singlecoder Mar 23, 2022
52c6552
feat(text): opt code
singlecoder Mar 23, 2022
a06182f
feat(text): close export dynamic text atlas manager
singlecoder Mar 24, 2022
c2945fb
feat(text): opt property name for Font
singlecoder Mar 24, 2022
33fc8eb
feat(text): opt recommend
singlecoder Mar 24, 2022
423a22b
feat(text): opt comment
singlecoder Mar 24, 2022
5b871c2
feat(text): opt dynamic atlas for text
singlecoder Mar 24, 2022
64f9b39
Merge branch 'dev/0.7' of https://github.com/oasis-engine/engine into…
singlecoder Mar 24, 2022
f4c66c7
feat(text): delete invalid import
singlecoder Mar 24, 2022
0483562
feat(text): opt code
singlecoder Mar 24, 2022
9fc8888
feat(text): opt code
singlecoder Mar 24, 2022
3669896
feat(text): add generic font families
singlecoder Mar 24, 2022
f2f839f
feat(text): remove TextRenderer from TextUtils
singlecoder Mar 24, 2022
177db10
feat(text): opt code
singlecoder Mar 25, 2022
ee84f20
feat(text): opt code
singlecoder Mar 25, 2022
d284767
feat(text): opt code
singlecoder Mar 25, 2022
8a1baf7
feat(text): opt code
singlecoder Mar 25, 2022
33f89ab
feat(text): fix type error
singlecoder Mar 25, 2022
b3cbdd4
feat(text): opt code for Font
singlecoder Mar 28, 2022
10f548d
feat(text): opt code for create font
singlecoder Mar 28, 2022
4f5bd7d
feat(text): opt code
singlecoder Mar 28, 2022
197f3f2
feat(text): opt code
singlecoder Mar 28, 2022
67a127d
feat(text): opt code
singlecoder Mar 28, 2022
cc7edb2
feat(text): opt code
singlecoder Mar 28, 2022
f8c22d4
feat(text): opt code
singlecoder Mar 28, 2022
0aea6d0
feat(text): opt code
singlecoder Mar 28, 2022
fc4434c
feat(text): opt code for trimCanvas
singlecoder Mar 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@rollup/plugin-node-resolve": "^11.0.1",
"@rollup/plugin-replace": "^2.3.4",
"@types/jest": "^26.0.20",
"@types/offscreencanvas": "^2019.6.4",
"@typescript-eslint/eslint-plugin": "^4.12.0",
"@typescript-eslint/parser": "^4.12.0",
"babel-jest": "^26.6.3",
Expand Down
95 changes: 95 additions & 0 deletions packages/core/src/2d/dynamic-atlas/DynamicTextAtlas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Rect } from "@oasis-engine/math";
import { Engine } from "../../Engine";
import { Texture2D } from "../../texture/Texture2D";
import { Sprite } from "../sprite/Sprite";

/**
* Dynamic atlas for text.
*/
export class DynamicTextAtlas {
private static _region: Rect = new Rect();

private _texture: Texture2D;
private _width: number;
private _height: number;

private _space: number = 1;
private _curX: number = 1;
private _curY: number = 1;
private _nextY: number = 1;

private _sprites: Record<number, Sprite> = {};

constructor(engine: Engine, width: number, height: number) {
this._width = width;
this._height = height;
this._texture = new Texture2D(engine, width, height);
this._texture._addRefCount(1);
}

/**
* Destroy atlas, it will release the texture.
*/
public destroy() {
this._sprites = {};
this._texture.destroy(true);
}

/**
* Add a sprite.
* @param sprite - the sprite to add
* @param imageSource - The source of texture
* @returns true if add sprite success, otherwise false
*/
public addSprite(sprite: Sprite, imageSource: TexImageSource | OffscreenCanvas): boolean {
const { _space: space, _texture: texture } = this;
const { width, height } = imageSource;

const endX = this._curX + width + space;
if (endX >= this._width) {
this._curX = space;
this._curY = this._nextY + space;
}

const endY = this._curY + height + space;
if (endY > this._nextY) {
this._nextY = endY;
}

if (this._nextY >= this._height) {
return false;
}

texture.setImageSource(imageSource, 0, false, false, this._curX, this._curY);
texture.generateMipmaps();

const { _width, _height } = this;
const region = DynamicTextAtlas._region;
region.setValue(this._curX / _width, this._curY / _height, width / _width, height / _height);

// destroy origin texture.
sprite.texture && sprite.texture.destroy();
// Update atlas texture.
sprite.atlasRegion = region;
sprite.texture = texture;
this._curX = endX + space;

return true;
}

/**
* Remove a sprite.
* @param sprite - the sprite to remove
* @returns true if remove sprite success, otherwise false
*/
public removeSprite(sprite: Sprite): boolean {
const id = sprite.instanceId;
const { _sprites } = this;
if (_sprites[id]) {
delete _sprites[id];
return true;
}
return false;
}
}

126 changes: 126 additions & 0 deletions packages/core/src/2d/dynamic-atlas/DynamicTextAtlasManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Sprite } from "../sprite/Sprite";
import { Engine } from "../../Engine";
import { DynamicTextAtlas } from "./DynamicTextAtlas";

/**
* Dynamic atlas manager for text.
*/
export class DynamicTextAtlasManager {
private _maxAtlasCount: number = 2;
private _textureSize: number = 1024;
private _atlases: Array<DynamicTextAtlas> = [];
private _atlasIndex: number = -1;
private _spritesInAtlasIndex: Record<number, number> = {};

/**
* Indicates how many atlases should be created.
*/
get maxAtlasCount(): number {
return this._maxAtlasCount;
}

set maxAtlasCount(val: number) {
this._maxAtlasCount = val;
}

/**
* Indicates the size of the texture.
*/
get textureSize(): number {
return this._textureSize;
}

set textureSize(val: number) {
this._textureSize = Math.min(val, 2048);
}

/**
* @internal
*/
constructor(public readonly engine: Engine) {}

/**
* Add a sprite to atlas.
* @param sprite - the sprite to add
* @param imageSource - The source of texture
* @returns true if add sprite success, otherwise false
*/
public addSprite(sprite: Sprite, imageSource: TexImageSource | OffscreenCanvas): boolean {
// Remove sprite if the sprite has been add.
const { _spritesInAtlasIndex, _atlases } = this;
const id = sprite.instanceId;
const atlasIndex = _spritesInAtlasIndex[id];
if (atlasIndex) {
_atlases[atlasIndex].removeSprite(sprite);
delete _spritesInAtlasIndex[id];
}

if (this._atlasIndex >= this._maxAtlasCount) {
return false;
}

let atlas = _atlases[this._atlasIndex];
if (!atlas) {
atlas = this._createAtlas();
}

if (atlas.addSprite(sprite, imageSource)) {
_spritesInAtlasIndex[id] = this._atlasIndex;
return true;
}

if (this._atlasIndex + 1 >= this._maxAtlasCount) {
this._atlasIndex = this._maxAtlasCount;
return false;
}

atlas = this._createAtlas();
if (atlas.addSprite(sprite, imageSource)) {
_spritesInAtlasIndex[id] = this._atlasIndex;
return true;
}
return false;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I pass in a larger word first and cause an atlas to be filtered, there will be a lot of wasted space in the filtered atlas?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never going back to use old atlas?


/**
* Remove a sprite from atlas.
* @param sprite - the sprite to remove
* @returns true if remove sprite success, otherwise false
*/
public removeSprite(sprite: Sprite): boolean {
if (!sprite) return false;

const { _atlases } = this;
for (let i = _atlases.length - 1; i >= 0; --i) {
const atlas = _atlases[i];
if(atlas.removeSprite(sprite)) {
delete this._spritesInAtlasIndex[i];
return true;
}
}

return false;
}

/**
* Reset all atlases.
*/
public reset() {
const { _atlases } = this;
for (let i = 0, l = _atlases.length; i < l; ++i) {
_atlases[i].destroy();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 for (let i = _atlases.length - 1; i >= 0; i--) {
      _atlases[i].destroy();
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


_atlases.length = 0;
this._atlasIndex = -1;
this._spritesInAtlasIndex = {};
}

private _createAtlas(): DynamicTextAtlas {
this._atlasIndex++;
const { _textureSize } = this;
const atlas = new DynamicTextAtlas(this.engine, _textureSize, _textureSize);
this._atlases.push(atlas);
return atlas;
}
}
11 changes: 11 additions & 0 deletions packages/core/src/2d/enums/FontStyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* The style of the font.
*/
export enum FontStyle {
/** Set font without style */
None = 0x0,
/** Set font bold */
Bold = 0x1,
/** Set font italic */
Italic = 0x2
}
23 changes: 23 additions & 0 deletions packages/core/src/2d/enums/TextAlignment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* The horizontal alignment of the text.
*/
export enum TextHorizontalAlignment {
/** Align left horizontally */
Left = 0,
/** Align center horizontally */
Center = 1,
/** Align right horizontally */
Right = 2
}

/**
* The vertical alignment of the text.
*/
export enum TextVerticalAlignment {
/** Align top vertically */
Top = 0,
/** Align center vertically */
Center = 1,
/** Align bottom vertically */
Bottom = 2
}
9 changes: 9 additions & 0 deletions packages/core/src/2d/enums/TextOverflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* The way to handle the situation where wrapped text is too tall to fit in the height.
*/
export enum OverflowMode {
/** Overflow when the text is too tall */
Overflow = 0,
/** Truncate with height when the text is too tall */
Truncate = 1
}
4 changes: 4 additions & 0 deletions packages/core/src/2d/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export { SpriteMaskInteraction } from "./enums/SpriteMaskInteraction";
export { SpriteMaskLayer } from "./enums/SpriteMaskLayer";
export { TextHorizontalAlignment, TextVerticalAlignment } from "./enums/TextAlignment";
export { OverflowMode } from "./enums/TextOverflow";
export { FontStyle } from "./enums/FontStyle";
export { SpriteAtlas } from "./atlas/SpriteAtlas";
export * from "./sprite/index";
export * from "./text/index";
50 changes: 50 additions & 0 deletions packages/core/src/2d/text/Font.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { RefObject } from "../../asset/RefObject"
import { Engine } from "../../Engine";
import { UpdateFlag } from "../../UpdateFlag";
import { UpdateFlagManager } from "../../UpdateFlagManager";

/**
* Font.
*/
export class Font extends RefObject {
private _name: string = "Arial";
private _updateFlagManager: UpdateFlagManager = new UpdateFlagManager();

/**
* The name of the font.
*/
get name(): string {
return this._name;
}

set name(value: string) {
value = value || "Arial";
if (this._name !== value) {
this._name = value;
this._updateFlagManager.distribute();
}
}

/**
* Create a font instance.
* @param engine - Engine to which the font belongs
* @param name - The name of font
*/
constructor(engine: Engine, name: string = "") {
super(engine);
this._name = name || "Arial";
}

/**
* @internal
*/
_registerUpdateFlag(): UpdateFlag {
return this._updateFlagManager.register();
}

/**
* @override
*/
protected _onDestroy(): void {}
}

Loading