refactor(Font): use pretext layout() directly in row size resolver
createFontRowSizeResolver was reaching into TextLayoutEngine, which internally called pretext's heavy layoutWithLines and then walked per-grapheme cursors to build chars arrays. The resolver discarded all that work and used only totalHeight. Replace with direct prepare + layout from @chenglou/pretext — pretext docs explicitly recommend layout() (not layoutWithLines) for the resize hot path: pure arithmetic on cached segment widths, no canvas calls, no string allocations. Test spies on TextLayoutEngine.prototype.layout migrated to vi.mock-ed pretext layout (pretext's ESM exports are frozen — vi.spyOn fails with "Cannot redefine property"). TextLayoutEngine marked @deprecated since it has no remaining consumers; slated for removal after a release cycle.
This commit is contained in:
@@ -1,7 +1,19 @@
|
||||
// @vitest-environment jsdom
|
||||
import { TextLayoutEngine } from '$shared/lib';
|
||||
import { installCanvasMock } from '$shared/lib/helpers/__mocks__/canvas';
|
||||
import { clearCache } from '@chenglou/pretext';
|
||||
import {
|
||||
clearCache,
|
||||
layout,
|
||||
} from '@chenglou/pretext';
|
||||
|
||||
// Wrap pretext's `layout` in a spy-able mock so tests can assert call counts.
|
||||
// `vi.mock` is hoisted, so the import above receives the mocked module.
|
||||
vi.mock('@chenglou/pretext', async () => {
|
||||
const actual = await vi.importActual<typeof import('@chenglou/pretext')>('@chenglou/pretext');
|
||||
return {
|
||||
...actual,
|
||||
layout: vi.fn(actual.layout),
|
||||
};
|
||||
});
|
||||
import {
|
||||
beforeEach,
|
||||
describe,
|
||||
@@ -112,13 +124,13 @@ describe('createFontRowSizeResolver', () => {
|
||||
const { resolver } = makeResolver();
|
||||
statusMap.set('inter@400', 'loaded');
|
||||
|
||||
const layoutSpy = vi.spyOn(TextLayoutEngine.prototype, 'layout');
|
||||
const layoutSpy = vi.mocked(layout);
|
||||
layoutSpy.mockClear();
|
||||
|
||||
resolver(0);
|
||||
resolver(0);
|
||||
|
||||
expect(layoutSpy).toHaveBeenCalledTimes(1);
|
||||
layoutSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('calls layout() again when containerWidth changes (cache miss)', () => {
|
||||
@@ -126,14 +138,14 @@ describe('createFontRowSizeResolver', () => {
|
||||
const { resolver } = makeResolver({ getContainerWidth: () => width });
|
||||
statusMap.set('inter@400', 'loaded');
|
||||
|
||||
const layoutSpy = vi.spyOn(TextLayoutEngine.prototype, 'layout');
|
||||
const layoutSpy = vi.mocked(layout);
|
||||
layoutSpy.mockClear();
|
||||
|
||||
resolver(0);
|
||||
width = 100;
|
||||
resolver(0);
|
||||
|
||||
expect(layoutSpy).toHaveBeenCalledTimes(2);
|
||||
layoutSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('returns greater height when container narrows (more wrapping)', () => {
|
||||
|
||||
Reference in New Issue
Block a user