Skip to content

Commit

Permalink
Merge pull request #360 from galacean/dev
Browse files Browse the repository at this point in the history
Merge origin/dev into origin/main
  • Loading branch information
yiiqii authored May 17, 2024
2 parents 81811af + c9f7633 commit f366766
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 23 deletions.
15 changes: 10 additions & 5 deletions packages/effects-core/src/asset-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Downloader, loadWebPOptional, loadImage, loadVideo } from './downloader
import { passRenderLevel } from './pass-render-level';
import { isScene } from './scene';
import type { Disposable } from './utils';
import { isObject, isString, logger } from './utils';
import { isObject, isString, logger, isValidFontFamily } from './utils';
import type { ImageSource, Scene } from './scene';
import type { TextureSourceOptions } from './texture';
import { deserializeMipmapTexture, TextureSourceType, getKTXTextureOptions, Texture } from './texture';
Expand Down Expand Up @@ -383,19 +383,24 @@ export class AssetManager implements Disposable {
if (!fonts) {
return;
}

const jobs = fonts.map(async font => {
// 数据模版兼容判断
if (font.fontURL && !AssetManager.fonts.has(font.fontFamily)) {
const url = new URL(font.fontURL, this.baseUrl).href;
const fontFace = new FontFace(font.fontFamily ?? '', 'url(' + url + ')');

if (!isValidFontFamily(font.fontFamily)) {
// 在所有设备上提醒开发者
console.warn(`Risky font family: ${font.fontFamily}`);
}
try {
const url = new URL(font.fontURL, this.baseUrl).href;
const fontFace = new FontFace(font.fontFamily ?? '', 'url(' + url + ')');

await fontFace.load();
//@ts-expect-error
document.fonts.add(fontFace);
AssetManager.fonts.add(font.fontFamily);
} catch (e) {
logger.warn(`Invalid fonts source: ${JSON.stringify(url)}`);
logger.warn(`Invalid font family or font source: ${JSON.stringify(font.fontURL)}`);
}
}
});
Expand Down
20 changes: 11 additions & 9 deletions packages/effects-core/src/plugins/text/text-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { TextLayout } from './text-layout';
import type { Engine } from '../../engine';
import { glContext } from '../../gl';
import type { SpriteVFXItem } from '../sprite/sprite-vfx-item';
import { isValidFontFamily } from '../../utils';

interface CharInfo {
/**
Expand Down Expand Up @@ -166,7 +167,9 @@ export class TextItem extends SpriteItem {
* @returns
*/
setFontFamily (value: string): void {
if (this.textStyle.fontFamily === value) {
if (this.textStyle.fontFamily === value && !isValidFontFamily(value)) {
console.warn('The font is either the current font or an risky font family.');

return;
}
this.textStyle.fontFamily = value;
Expand Down Expand Up @@ -286,7 +289,7 @@ export class TextItem extends SpriteItem {

this.char = (this.text || '').split('');

this.canvas.width = width ;
this.canvas.width = width;
this.canvas.height = height;

context.clearRect(0, 0, width, this.canvas.height);
Expand Down Expand Up @@ -354,10 +357,10 @@ export class TextItem extends SpriteItem {
charOffsetX,
});

charsInfo.forEach(charInfo=>{
charsInfo.forEach(charInfo => {
const x = layout.getOffsetX(style, charInfo.width);

charInfo.chars.forEach((str, i)=>{
charInfo.chars.forEach((str, i) => {
if (style.isOutlined) {

context.strokeText(str, x + charInfo.charOffsetX[i], charInfo.y);
Expand All @@ -384,7 +387,7 @@ export class TextItem extends SpriteItem {
height: imageData.height,
},
{
flipY:true,
flipY: true,
magFilter: glContext.LINEAR,
minFilter: glContext.LINEAR,
wrapS: glContext.CLAMP_TO_EDGE,
Expand All @@ -404,7 +407,6 @@ export class TextItem extends SpriteItem {
} else {
fontDesc += textStyle.fontFamily;
}

if (textStyle.textWeight !== spec.TextWeight.normal) {
fontDesc = `${textStyle.textWeight} ${fontDesc}`;
}
Expand All @@ -430,8 +432,8 @@ export class TextItem extends SpriteItem {
const style = this.textStyle;

context!.shadowColor = `rgba(${style.shadowColor[0] * 255}, ${style.shadowColor[1] * 255}, ${style.shadowColor[2] * 255}, ${style.shadowColor[3]})`;
context!.shadowBlur = style.shadowBlur ;
context!.shadowOffsetX = style.shadowOffsetX ;
context!.shadowOffsetY = -style.shadowOffsetY ;
context!.shadowBlur = style.shadowBlur;
context!.shadowOffsetX = style.shadowOffsetX;
context!.shadowOffsetY = -style.shadowOffsetY;
}
}
1 change: 1 addition & 0 deletions packages/effects-core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './device';
export * from './image-data';
export * from './sortable';
export * from './asserts';
export * from './text';
export * from './timeline-component';
export * from './logger';

Expand Down
11 changes: 11 additions & 0 deletions packages/effects-core/src/utils/text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* 判断是否为可解析的字体
* - 首字母不能为数字或 `.`
* - 不能包含特殊字符,`_-` 是被允许的
* @param fontFamily - 字体名称
* @returns
*/
export function isValidFontFamily (fontFamily: string): boolean {
// iOS 11/12 不支持自定义字体开头为数字的名称,特殊字符也有风险
return /^[^\d.][\w-]*$/.test(fontFamily);
}
8 changes: 4 additions & 4 deletions plugin-packages/spine/demo/src/api-test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// @ts-nocheck
import type { Camera, JSONValue } from '@galacean/effects';
import { Player, loadBinary } from '@galacean/effects';
import type { FileFormat } from './files';
import { direct, premultiply } from './files';
import { loadBinary, Player } from '@galacean/effects';
import type { SkeletonData } from '@galacean/effects-plugin-spine';
import {
createSkeletonData,
Expand All @@ -11,6 +9,8 @@ import {
getSkinList,
TextureAtlas,
} from '@galacean/effects-plugin-spine';
import type { FileFormat } from './files';
import { direct, premultiply } from './files';
import 'fpsmeter';

const playerOptions = {
Expand Down Expand Up @@ -44,7 +44,7 @@ const format = document.getElementById('J-formatList') as HTMLSelectElement;
format.onchange = handleChange;
delay.onchange = handleChange;

const files: Record<string, FileFormat> = premultiply;
const files: Record<string, FileFormat> = direct;

if (files === premultiply) {
filetype.innerText = '纹理打包选择预乘alpha: true';
Expand Down
5 changes: 5 additions & 0 deletions plugin-packages/spine/demo/src/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ export const direct: Record<string, FileFormat> = {
json: 'https://gw.alipayobjects.com/os/gltf-asset/95023136604660/skeleton.json',
png: ['https://gw.alipayobjects.com/zos/gltf-asset/95023136604660/skeleton.png'],
},
noDefault: {
json: 'https://gw.alipayobjects.com/os/gltf-asset/15687627881185/zJ.json',
atlas: 'https://gw.alipayobjects.com/os/gltf-asset/15687627881185/zJ.atlas',
png: ['https://gw.alipayobjects.com/zos/gltf-asset/15687627881185/zJ.png'],
},
};

export interface FileFormat {
Expand Down
10 changes: 5 additions & 5 deletions plugin-packages/spine/src/spine-vfx-item.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { HitTestType, VFXItem, spec, PLAYER_OPTIONS_ENV_EDITOR, assertExist, math } from '@galacean/effects';
import type { HitTestTriangleParams, Engine, Composition, VFXItemProps, BoundingBoxTriangle } from '@galacean/effects';
import type { AnimationStateListener, SkeletonData } from '@esotericsoftware/spine-core';
import { AnimationState, AnimationStateData, Physics, Skeleton } from '@esotericsoftware/spine-core';
import type { BoundingBoxTriangle, Composition, Engine, HitTestTriangleParams, VFXItemProps } from '@galacean/effects';
import { assertExist, HitTestType, math, PLAYER_OPTIONS_ENV_EDITOR, spec, VFXItem } from '@galacean/effects';
import { SlotGroup } from './slot-group';
import type { SpineResource } from './spine-loader';
import { createSkeletonData, getAnimationDuration } from './utils';
import type { SpineMesh } from './spine-mesh';
import { createSkeletonData, getAnimationDuration } from './utils';

const { Vector2, Vector3 } = math;

Expand Down Expand Up @@ -86,7 +86,7 @@ export class SpineVFXItem extends VFXItem<SpineContent> {
if (isNaN(index)) {
return;
}
const skin = spineOptions.activeSkin || 'default';

const { atlas, skeletonFile, skeletonType, skinList, animationList } = spineDatas[index];
const activeAnimation = typeof spineOptions.activeAnimation === 'string' ? [spineOptions.activeAnimation] : spineOptions.activeAnimation;

Expand All @@ -97,7 +97,7 @@ export class SpineVFXItem extends VFXItem<SpineContent> {
this.skinList = skinList.slice();
this.animationList = animationList.slice();
this.skeleton = new Skeleton(this.skeletonData);
this.setSkin(skin);
this.setSkin(spineOptions.activeSkin || (skinList.length ? skinList[0] : 'default'));
this.state = new AnimationState(this.animationStateData);
if (activeAnimation.length === 1) {
// 兼容旧JSON,根据时长计算速度
Expand Down
1 change: 1 addition & 0 deletions web-packages/test/unit/src/effects-core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './image-template/image-template-v2.spec';
import './interact/interact.spec';
import './math/value-getter.spec';
import './transform.spec';
import './utils.spec';
//
import './plugins/common/end-behevior.spec';
import './plugins/cal/transform.spec';
Expand Down
35 changes: 35 additions & 0 deletions web-packages/test/unit/src/effects-core/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { isValidFontFamily } from '@galacean/effects';

const { expect } = chai;

describe('isValidFontFamily 判断是否合法字体名称', () => {
it('合法的字体名称', () => {
expect(isValidFontFamily('_BDFZ_FZZeBrach-Regular')).eq(true);
expect(isValidFontFamily('_BDFZ_FZZeBrach88-Regular')).eq(true);
expect(isValidFontFamily('FZZeBrach')).eq(true);
});
it('首字母不能为数字或.', () => {
expect(isValidFontFamily('200_BDFZ_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('._BDFZ_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('.01_BDFZ_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('.')).eq(false);
expect(isValidFontFamily('01')).eq(false);
});
it('不能包含特殊字符', () => {
expect(isValidFontFamily('BDFZ_FZZeB@rach-Regular')).eq(false);
expect(isValidFontFamily('BDFZ_FZZeB??rach-Regular')).eq(false);
expect(isValidFontFamily('BDFZ_FZZeB.rach-Regular')).eq(false);
expect(isValidFontFamily('_BD!FZ_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('_BD::FZ_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('_BD<01>_FZZeBrach-Regular')).eq(false);
expect(isValidFontFamily('1 ?2@3')).eq(false);
expect(isValidFontFamily('1?2@3')).eq(false);
expect(isValidFontFamily('r1<23')).eq(false);
expect(isValidFontFamily('x1|2|3')).eq(false);
expect(isValidFontFamily('??qg?e_ewe')).eq(false);
expect(isValidFontFamily('qge_ew\'e')).eq(false);
expect(isValidFontFamily('qge_e$we')).eq(false);
expect(isValidFontFamily('2.00;BDFZ;FZZeBrach-Regular;2000; FLVI-612')).eq(false);
expect(isValidFontFamily('2.00;BDFZ;FZZeBrach-Regular;2000;FL720')).eq(false);
});
});

0 comments on commit f366766

Please sign in to comment.