@openpresentation/opf-render 0.23.0 → 0.24.3

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/svg.js +12 -2
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -216,7 +216,7 @@ Layout templates (OPF 0.19, core `opf-layout/v2`: `areas`, `rows`, `columns` and
216
216
 
217
217
  The installed open font pack works offline. The Aptos family previews with the metric-compatible Intos even under the default metric policy; this example additionally permits visual-only look-alikes for families with no metric replacement yet (a documented fallback), and the substitution report identifies requested and resolved faces. A visual substitute is not a claim of metric or pixel equivalence, and it is a known layout-fidelity gap rather than the end state. Replacements apply to rendering only; the document keeps the selected font name. Omit `substitutionPolicy` to restrict the Office pack to its metric mappings, or supply your own licensed faces (`faces`). Missing fonts/glyphs fail explicitly. Without `fonts`, synchronous SVG APIs use estimated widths; named fonts alone do not make rich-run spacing reliable. Browser hosts should load the same bytes using the loader below.
218
218
 
219
- Unresolved images produce an `unresolved-asset` diagnostic through `onDiagnostic`, including the OPF path, reason and complete description. The fallback shows a bounded status label when it fits above the selected readability floor, otherwise an icon with the full accessible description. The label is `Image unavailable` over the description (alt, else title, else `Image`) in semibold at 20 px on a 1280 x 720 canvas, and opf-pptx exports the same placeholder as native shapes. It preserves authored opacity, including faint decorative watermarks; a missing image is still missing even when its fallback fits. Use `strictAssets: true` to reject unresolved images. Supply embedded raster data URIs or a synchronous host `imageResolver` to resolve them; the renderer does not fetch URLs or read local paths. Caller descriptions and other metadata override referenced asset metadata through alias chains. These diagnostics identify unresolved sources, not malformed image bytes or native PowerPoint compatibility.
219
+ Unresolved images produce an `unresolved-asset` diagnostic through `onDiagnostic` (a warning in the CLI report, `render/unresolved-asset`, which `--fail-on warning` turns into a failure), including the OPF path, the `source` the author wrote, the reason and the complete description; the `message` names that source, and the image is skipped, not the render. It covers every place a deck spells an image: slide backgrounds (also tiled), image blocks, header/footer and organization logos, picture watermarks, picture bullets, and `asset:` references. The fallback shows a bounded status label when it fits above the selected readability floor, otherwise an icon with the full accessible description. The label is `Image unavailable` over the description (alt, else title, else `Image`) in semibold at 20 px on a 1280 x 720 canvas, and opf-pptx exports the same placeholder as native shapes. It preserves authored opacity, including faint decorative watermarks; a missing image is still missing even when its fallback fits. Use `strictAssets: true` to reject unresolved images. Supply embedded raster data URIs or a synchronous host `imageResolver` to resolve them; the renderer does not fetch URLs or read local paths. Caller descriptions and other metadata override referenced asset metadata through alias chains. These diagnostics identify unresolved sources, not malformed image bytes or native PowerPoint compatibility.
220
220
 
221
221
  Header/footer images and watermarks fit their complete artwork within their allocated regions. Image blocks use their own `fit`, else `design.imageFit` (default `cover`), as core resolves it into `item.image.fit`.
222
222
 
package/dist/svg.js CHANGED
@@ -1186,12 +1186,22 @@ function svgHasIntrinsicSize(attributes) {
1186
1186
  return Boolean((length(attributes.width) && length(attributes.height)) || view);
1187
1187
  }
1188
1188
 
1189
+ // RR-97: the message of an `unresolved-asset` diagnostic names the source the author wrote, so a report says which image to fix
1190
+ // (the diagnostic's `path` says where). The renderer fetches no URL and reads no path: a host resolves a local file to a data URI
1191
+ // (`imageResolver`, or the CLI's `--asset-dir`), and one that cannot says why in its own finding.
1192
+ function unresolvedImageMessage(kind, src, missingReference, outcome) {
1193
+ if (missingReference) return `${kind} asset "${missingReference}" is not declared in the deck's assets, so ${outcome}. Declare the asset or resolve it in the host.`;
1194
+ if (typeof src !== "string" || src === "") return `${kind} has no src, so ${outcome}.`;
1195
+ const shown = src.startsWith("data:") ? `${src.slice(0, Math.min(src.indexOf(",") + 1 || 40, 60))}...` : src.length > 120 ? `${src.slice(0, 117)}...` : src;
1196
+ return `${kind} "${shown}" was not resolved to an embedded PNG, JPEG, GIF, WebP or SVG data URI, so ${outcome}. Fix the path, embed the image as a data URI, or resolve it in the host (imageResolver, or --asset-dir in the CLI).`;
1197
+ }
1198
+
1189
1199
  // The drawable data URI of a picture bullet, or undefined (after reporting unresolved-asset once) so the glyph marker stays.
1190
1200
  function resolveBulletImage(bulletImage, bound, options) {
1191
1201
  const { drawable, source, asset, missingReference } = resolveImageSource({ value: bulletImage.source, path: bulletImage.path }, bound, options);
1192
1202
  if (drawable) return source;
1193
1203
  const reason=missingReference?'missing-reference':!asset.src?'missing-source':'unsupported-source';
1194
- const message=missingReference?`Bullet image asset ${missingReference} is missing; the preview draws the character bullet.`:'A picture bullet requires an embedded raster data URI or a host imageResolver; the preview draws the character bullet.';
1204
+ const message=unresolvedImageMessage('Bullet image',asset.src,missingReference,'the preview draws the character bullet');
1195
1205
  if (options.strictAssets) throw new OPFRenderError("unresolved-asset", message, { path: bulletImage.path,reason });
1196
1206
  reportDiagnostic({code:'unresolved-asset',path:bulletImage.path,message,reason,source:asset.src,assetId:missingReference,description:asset.alt??asset.title??'Bullet image',placeholder:'glyph'},options);
1197
1207
  return undefined;
@@ -1222,7 +1232,7 @@ function renderImage(item, box, bound, options) {
1222
1232
  ...attrs });
1223
1233
  }
1224
1234
  const reason=missingReference?'missing-reference':!asset.src?'missing-source':'unsupported-source';
1225
- const message=missingReference?`Image asset ${missingReference} is missing; supply the referenced asset or resolve it in the host.`:'Image requires an embedded raster or SVG data URI, or a host imageResolver.';
1235
+ const message=unresolvedImageMessage('Image',asset.src,missingReference,'the preview draws the unavailable-image placeholder');
1226
1236
  if (options.strictAssets) throw new OPFRenderError("unresolved-asset", message, { path: item.path,reason });
1227
1237
  const fill = bound.design.colors.surface;
1228
1238
  const scale=Math.min(bound.design.dimensions.width,bound.design.dimensions.height)/720;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpresentation/opf-render",
3
- "version": "0.23.0",
3
+ "version": "0.24.3",
4
4
  "description": "Deterministic local OPF renderer for SVG, PNG, and PDF output.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -142,7 +142,7 @@
142
142
  "test:forced-colors-browser": "node test/forced-colors-browser.mjs artifacts/forced-colors"
143
143
  },
144
144
  "dependencies": {
145
- "@openpresentation/opf": "^0.23.0",
145
+ "@openpresentation/opf": "^0.24.2",
146
146
  "bidi-js": "1.1.0",
147
147
  "fontkit": "^2.0.4",
148
148
  "harfbuzzjs": "1.6.3",
@@ -341,7 +341,7 @@
341
341
  }
342
342
  },
343
343
  "devDependencies": {
344
- "@openpresentation/gallery": "^3.0.0",
344
+ "@openpresentation/gallery": "^4.0.0",
345
345
  "@expo-google-fonts/arimo": "0.4.3",
346
346
  "@expo-google-fonts/caladea": "0.4.2",
347
347
  "@expo-google-fonts/cousine": "0.4.3",