@zseven-w/pen-renderer 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zseven-w/pen-renderer",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Standalone CanvasKit/Skia renderer for OpenPencil (.op) design files",
5
5
  "homepage": "https://github.com/ZSeven-W/openpencil/tree/main/packages/pen-renderer",
6
6
  "bugs": {
@@ -30,8 +30,8 @@
30
30
  "typecheck": "tsc --noEmit"
31
31
  },
32
32
  "dependencies": {
33
- "@zseven-w/pen-core": "0.7.1",
34
- "@zseven-w/pen-types": "0.7.1",
33
+ "@zseven-w/pen-core": "0.7.2",
34
+ "@zseven-w/pen-types": "0.7.2",
35
35
  "rbush": "^4.0.1"
36
36
  },
37
37
  "devDependencies": {
@@ -274,4 +274,35 @@ describe('flattenToRenderNodes — dimension consistency', () => {
274
274
  expect(t1.clipRect!.h).toBe(rootRN.absH);
275
275
  expect(t1.clipRect!.w).toBe(rootRN.absW);
276
276
  });
277
+
278
+ it('nested frame with clipContent clips its descendants using its own bounds/radius', () => {
279
+ const root = frame({
280
+ id: 'root',
281
+ width: 400,
282
+ height: 400,
283
+ children: [
284
+ frame({
285
+ id: 'card',
286
+ x: 40,
287
+ y: 50,
288
+ width: 200,
289
+ height: 120,
290
+ cornerRadius: 16,
291
+ clipContent: true,
292
+ children: [text('inner', 'Nested content', { width: 'fill_container' as any })],
293
+ }),
294
+ ],
295
+ });
296
+
297
+ const nodes = flattenToRenderNodes([root]);
298
+ const card = nodes.find((rn) => rn.node.id === 'card')!;
299
+ const inner = nodes.find((rn) => rn.node.id === 'inner')!;
300
+
301
+ expect(inner.clipRect).toBeDefined();
302
+ expect(inner.clipRect!.x).toBe(card.absX);
303
+ expect(inner.clipRect!.y).toBe(card.absY);
304
+ expect(inner.clipRect!.w).toBe(card.absW);
305
+ expect(inner.clipRect!.h).toBe(card.absH);
306
+ expect(inner.clipRect!.rx).toBe(16);
307
+ });
277
308
  });
@@ -241,10 +241,12 @@ export function flattenToRenderNodes(
241
241
  const positioned =
242
242
  layout && layout !== 'none' ? computeLayoutPositions(resolved, children) : children;
243
243
 
244
- // Clipping — only clip for root frames (artboard behavior).
244
+ // Clipping — root frames always clip like artboards. Nested containers
245
+ // clip only when clipContent is enabled.
245
246
  let childClip = clipCtx;
246
247
  const isRootFrame = node.type === 'frame' && depth === 0;
247
- if (isRootFrame) {
248
+ const explicitClip = 'clipContent' in resolved && resolved.clipContent === true;
249
+ if (isRootFrame || explicitClip) {
248
250
  const crRaw = 'cornerRadius' in node ? cornerRadiusVal(node.cornerRadius) : 0;
249
251
  const cr = Math.min(crRaw, nodeH / 2);
250
252
  childClip = { x: absX, y: absY, w: nodeW, h: nodeH, rx: cr };