From dcea23e22e047ad8423e46031f8ea6e54cdd7fdc Mon Sep 17 00:00:00 2001 From: Geequlim Date: Tue, 25 Feb 2025 11:07:07 +0800 Subject: [PATCH] refactor: dynamic font created in downloader to allow override the implementation --- src/layaAir/laya/loaders/TTFFontLoader.ts | 53 ++--------------------- src/layaAir/laya/net/Downloader.ts | 45 +++++++++++++++++++ src/layaAir/laya/net/Loader.ts | 9 +++- 3 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/layaAir/laya/loaders/TTFFontLoader.ts b/src/layaAir/laya/loaders/TTFFontLoader.ts index 6890a8a3b6..018209b8bf 100644 --- a/src/layaAir/laya/loaders/TTFFontLoader.ts +++ b/src/layaAir/laya/loaders/TTFFontLoader.ts @@ -1,56 +1,9 @@ -import { ILaya } from "../../ILaya"; -import { LayaEnv } from "../../LayaEnv"; -import { IResourceLoader, ILoadTask, Loader } from "../net/Loader"; -import { URL } from "../net/URL"; -import { Browser } from "../utils/Browser"; -import { Utils } from "../utils/Utils"; - -const testString = "LayaTTFFont"; - +import { ILoadTask, IResourceLoader, Loader } from "../net/Loader"; class TTFFontLoader implements IResourceLoader { load(task: ILoadTask) { - let fontName = Utils.replaceFileExtension(Utils.getBaseName(task.url), ""); - if (LayaEnv.isConch) { - return task.loader.fetch(task.url, "arraybuffer").then(data => { - if (data) - (window as any)["conch"].registerFont(fontName, data); - return { family: fontName }; - }); - } - else if ((window as any).FontFace) { - let fontFace: any = new (window as any).FontFace(fontName, "url('" + URL.postFormatURL(URL.formatURL(task.url)) + "')"); - (document as any).fonts.add(fontFace); - return fontFace.load().then(() => { - return fontFace; - }); - } - else { - let fontTxt = "40px " + fontName; - let txtWidth = Browser.measureText(testString, fontTxt).width; - - let fontStyle: any = Browser.createElement("style"); - fontStyle.type = "text/css"; - document.body.appendChild(fontStyle); - fontStyle.textContent = "@font-face { font-family:'" + fontName + "'; src:url('" + URL.postFormatURL(URL.formatURL(task.url)) + "');}"; - - return new Promise((resolve) => { - let checkComplete = () => { - if (Browser.measureText(testString, fontTxt).width != txtWidth) - complete(); - }; - let complete = () => { - ILaya.systemTimer.clear(this, checkComplete); - ILaya.systemTimer.clear(this, complete); - - resolve({ family: fontName }); - }; - - ILaya.systemTimer.once(10000, this, complete); - ILaya.systemTimer.loop(20, this, checkComplete); - }); - } + return task.loader.fetch(task.url, "font", task.progress.createCallback(), task.options); } } -Loader.registerLoader(["ttf", "woff", "woff2", "otf"], TTFFontLoader, Loader.TTF); \ No newline at end of file +Loader.registerLoader(["ttf", "woff", "woff2", "otf"], TTFFontLoader, Loader.TTF); diff --git a/src/layaAir/laya/net/Downloader.ts b/src/layaAir/laya/net/Downloader.ts index 35a33d6fe5..401488d613 100644 --- a/src/layaAir/laya/net/Downloader.ts +++ b/src/layaAir/laya/net/Downloader.ts @@ -1,6 +1,8 @@ +import { ILaya } from '../../ILaya'; import { Event } from "../events/Event"; import { Browser } from "../utils/Browser"; import { ImgUtils } from "../utils/ImgUtils"; +import { Utils } from '../utils/Utils'; import { HttpRequest } from "./HttpRequest"; import { WorkerLoader } from "./WorkerLoader"; @@ -150,6 +152,49 @@ export class Downloader { owner.$ref = audio; //保持引用避免gc掉 } + font(owner: any, url: string, originalUrl: string, onProgress: (progress: number) => void, onComplete: (data: any, error?: string) => void): void { + let fontName = Utils.replaceFileExtension(Utils.getBaseName(url), ""); + if ((window as any).conch) { + this.common(owner, url, originalUrl, "arraybuffer", onProgress, (data, error) => { + if (error || !data) { + onComplete(null, error); + return; + } + (window as any).conch.registerFont(fontName, data); + onComplete({ family: fontName }); + }); + } else if ((window as any).FontFace) { + let fontFace: any = new (window as any).FontFace(fontName, "url('" + url + "')"); + fontFace.load() + .catch((err: Error) => onComplete(null, err.message)) + .then(() => { + (document as any).fonts.add(fontFace); + onComplete(fontFace); + }); + } else { + const testString = "LayaTTFFont"; + let fontTxt = "40px " + fontName; + let txtWidth = Browser.measureText(testString, fontTxt).width; + + let fontStyle: any = Browser.createElement("style"); + fontStyle.type = "text/css"; + document.body.appendChild(fontStyle); + fontStyle.textContent = "@font-face { font-family:'" + fontName + "'; src:url('" + url + "');}"; + + let checkComplete = () => { + if (Browser.measureText(testString, fontTxt).width != txtWidth) + complete(); + }; + let complete = () => { + ILaya.systemTimer.clear(this, checkComplete); + ILaya.systemTimer.clear(this, complete); + onComplete({ family: fontName }); + }; + ILaya.systemTimer.once(10000, this, complete); + ILaya.systemTimer.loop(20, this, checkComplete); + } + } + /** * @en Pool of HttpRequest instances. * @zh HttpRequest实例池。 diff --git a/src/layaAir/laya/net/Loader.ts b/src/layaAir/laya/net/Loader.ts index f4f039d886..476a51d65d 100644 --- a/src/layaAir/laya/net/Loader.ts +++ b/src/layaAir/laya/net/Loader.ts @@ -62,7 +62,8 @@ interface ContentTypeMap { "xml": XML, "arraybuffer": ArrayBuffer, "image": HTMLImageElement | ImageBitmap, - "sound": HTMLAudioElement + "sound": HTMLAudioElement, + "font": FontFace, } var typeIdCounter = 0; @@ -751,6 +752,10 @@ export class Loader extends EventDispatcher { Loader.downloader.audio(item, url, item.originalUrl, item.onProgress, (data: any, error: string) => this.completeItem(item, data, error)); } + else if (item.contentType == "font") { + Loader.downloader.font(item, url, item.originalUrl, item.onProgress, (data: any, error: string) => + this.completeItem(item, data, error)); + } else { let preloadedContent = Loader.preLoadedMap[item.url]; if (preloadedContent) { @@ -1487,4 +1492,4 @@ interface DownloadItem { startTime?: number; onComplete: (content: any) => void; onProgress: ProgressCallback; -} \ No newline at end of file +}