feat: add first-class text layers

This commit is contained in:
syntaxbullet
2026-07-11 12:38:34 +02:00
parent 606426c885
commit 37aa719047
33 changed files with 315 additions and 41 deletions

View File

@@ -10,6 +10,7 @@ import type { ImageTextureRenderer } from "./image-textures";
import { documentRectToScreenRect } from "./screen-rect";
import type { RgbaColor, ScreenRect, WebGlRendererContext } from "./types";
import type { AdjustmentPass } from "./adjustment-pass";
import { textLayerRenderAsset } from "./text-asset";
const imageLayerColor: RgbaColor = [0.38, 0.42, 0.5, 1];
const imageLayerInsetColor: RgbaColor = [0.48, 0.54, 0.64, 1];
@@ -63,10 +64,22 @@ function renderLayerTree(
adjustmentPass.apply(layer.adjustment, effectiveOpacity, effectiveClipRect);
continue;
}
renderLeafLayer(context, documentIndex, editor, layer, imageTextureRenderer, effectiveClipRect, effectiveOpacity);
if (layer.type === "text") {
renderTextLayer(context, documentIndex, editor, layer, imageTextureRenderer, effectiveClipRect, effectiveOpacity);
} else {
renderLeafLayer(context, documentIndex, editor, layer, imageTextureRenderer, effectiveClipRect, effectiveOpacity);
}
}
}
function renderTextLayer(context: WebGlRendererContext, documentIndex: DocumentReadIndex, editor: EditorState, layer: Extract<Layer, { type: "text" }>, imageTextureRenderer: ImageTextureRenderer, clipRect: ScreenRect, opacity: number) {
if (editor.maskEdit?.viewMode && isIsolatedMaskView(editor.maskEdit.viewMode)) return;
const bounds = resolveIndexedLayerBounds(documentIndex, layer);
if (!bounds) return;
const rect = documentRectToScreenRect(context.canvas, bounds, editor.viewport);
imageTextureRenderer.render(textLayerRenderAsset(layer), rect, clipRect, opacity, layer.transform.rotation);
}
function renderLeafLayer(
context: WebGlRendererContext,
documentIndex: DocumentReadIndex,
@@ -88,7 +101,7 @@ function renderLeafLayer(
const asset = assetWithBrushStrokePreview(documentIndex.assetById.get(layer.assetId), editor);
const layerMask = getLayerMask(layer);
const maskLayer = !editingMaskLayer && layerMask?.enabled ? documentIndex.layerById.get(layerMask.maskLayerId) : undefined;
const maskAsset = assetWithBrushStrokePreview(maskLayer && maskLayer.type !== "group" && maskLayer.type !== "adjustment" ? documentIndex.assetById.get(maskLayer.assetId) : undefined, editor);
const maskAsset = assetWithBrushStrokePreview(maskLayer && (maskLayer.type === "image" || maskLayer.type === "raster") ? documentIndex.assetById.get(maskLayer.assetId) : undefined, editor);
const maskBounds = maskLayer ? resolveIndexedLayerBounds(documentIndex, maskLayer) : undefined;
const maskRect = maskBounds ? documentRectToScreenRect(context.canvas, maskBounds, editor.viewport) : undefined;
const activeMaskTarget = Boolean(editor.maskEdit?.targetLayerId === layer.id && editor.maskEdit.maskLayerId === layerMask?.maskLayerId);