Read the pixel size of a texture in a graph (#262)

A graph had no way to know how big a picture is. An icon sprite with a
fixed size therefore stretched every icon of another size, an 8x8
pixel-art icon in a 16x16 slot was drawn twice as big.

- New data node Texture size. It takes a texture, a frame or a pixel
  art and hands out width and height in pixels, 0 x 0 for none.
  Wired into a sprite's width and height, the picture shows pixel for
  pixel.
- GraphLookup gets textureSize. The project answers it with the same
  pictureSize rule a sprite uses to size itself.

Tests:

- ./check.sh: 2749 tests, CHECK EXIT 0.
- 2 catalog cases (a picture, no picture) and one test against a real
  project: pixel-art sheet, single frame, missing texture.
- No e2e check and no counter-check for this node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-09-29 06:01:27 +02:00
1 parent d7d0a6e7d4
commit ef2600493f
6 files changed
+71

No files matched your search

+13
View File
@@ -265,6 +265,19 @@ const CASES: Record<string, Case[]> = {
after: (ctx) => expect(ctx.states).toEqual({}),
},
],
TextureSize: [
{
name: "hands out the picture's own pixel size",
inputs: { texture: 'coin' },
lookup: { ...NO_LOOKUP, textureSize: (id) => (id === 'coin' ? { w: 8, h: 6 } : null) },
outputs: { width: 8, height: 6 },
},
{
name: 'no picture is 0 × 0',
inputs: { texture: '' },
outputs: { width: 0, height: 0 },
},
],
CurrentState: [
{
name: 'names the state the machine is in, and hands out its id as well',
+18
View File
@@ -54,6 +54,7 @@ import {
withLayerMoved,
withLayerRemoved,
} from '../../src/core/model/pixelEdit';
import { graphLookup } from '../../src/core/model/graphLookup';
import { findAsset, type Project } from '../../src/core/model/Project';
import { resolvePicture } from '../../src/core/model/texture';
import { pictureChoices, textureRefLabel } from '../../src/core/properties/textureRef';
@@ -295,6 +296,23 @@ describe('the picture', () => {
}
});
it('tells a graph its own pixel size, the sheet for the asset and the cut for a frame', () => {
const remove = registerPictureSource('pixelart', pixelArtPicture);
try {
const { project } = makeProject();
const asset = art(project);
asset.width = 8;
asset.height = 6;
asset.frames.push({ id: 'second', cels: {} });
const lookup = graphLookup(project);
expect(lookup.textureSize(asset.id)).toEqual({ w: 16, h: 6 });
expect(lookup.textureSize('second')).toEqual({ w: 8, h: 6 });
expect(lookup.textureSize('gone')).toBeNull();
} finally {
remove();
}
});
it('with one frame is offered as the picture alone', () => {
const remove = registerPictureSource('pixelart', pixelArtPicture);
try {