@arraypress/covers 1.3.1 → 1.4.0

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.
@@ -1,7 +1,7 @@
1
1
  // Built-in symbols, drawn as shapes (the last glyph fallback).
2
2
  import type { LoadedFont } from '../fonts.js';
3
3
 
4
- /** The symbol face: ✺ ✦ ✶ ★ ☆ ♥ ♡ ▶ ◀ ● ◆ ■ ♪. */
4
+ /** The symbol face: ✺ ✦ ✶ ★ ☆ ♥ ♡ ▶ ◀ ● ◆ ■ ♪ ≠. */
5
5
  export function symbolFace(): LoadedFont;
6
6
  /** The characters it draws. */
7
7
  export const SYMBOLS: string;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A built-in face of a few symbols type often wants and fonts often lack
3
- * (✺ ✦ ✶ ★ ☆ ♥ ♡ ▶ ◀ ● ◆ ■ ♪), drawn as shapes. The last fallback when a
3
+ * (✺ ✦ ✶ ★ ☆ ♥ ♡ ▶ ◀ ● ◆ ■ ♪ ≠), drawn as shapes. The last fallback when a
4
4
  * text layer's font has no glyph for a character.
5
5
  *
6
6
  * @module type/symbols
@@ -38,6 +38,23 @@ function heart(k) {
38
38
  /** @param {number} r @param {number} [n=48] @returns {[number, number][]} */
39
39
  const circle = (r, n = 48) => Array.from({ length: n }, (_, i) => /** @type {[number, number]} */ ([CX + r * Math.sin((i / n) * Math.PI * 2), CY + r * Math.cos((i / n) * Math.PI * 2)]));
40
40
 
41
+ /**
42
+ * Not-equal, on a narrower advance (`NARROW`): two bars and a slash, one
43
+ * contour each, all wound alike so they fill as one.
44
+ *
45
+ * @returns {string}
46
+ */
47
+ function notEqual() {
48
+ const cx = NARROW / 2;
49
+ const [half, bar, gap, lean, stem] = [230, 62, 112, 150, 31];
50
+ const rect = (/** @type {number} */ y) => poly([[cx - half, y + bar / 2], [cx + half, y + bar / 2], [cx + half, y - bar / 2], [cx - half, y - bar / 2]]);
51
+ const slash = poly([[cx + lean - stem, CY + 300], [cx + lean + stem, CY + 300], [cx - lean + stem, CY - 300], [cx - lean - stem, CY - 300]]);
52
+ return rect(CY + gap) + rect(CY - gap) + slash;
53
+ }
54
+
55
+ /** Advance of the narrow symbols (≠), font units. */
56
+ const NARROW = 600;
57
+
41
58
  /** Outlines by character. An inner contour runs the other way (a hole). */
42
59
  const SHAPES = /** @type {Record<string, string>} */ ({
43
60
  '✺': poly(star(16, 0.5)),
@@ -53,6 +70,7 @@ const SHAPES = /** @type {Record<string, string>} */ ({
53
70
  '◆': poly([[CX, CY + R], [CX + R * 0.8, CY], [CX, CY - R], [CX - R * 0.8, CY]]),
54
71
  '■': poly([[CX - R * 0.75, CY + R * 0.75], [CX + R * 0.75, CY + R * 0.75], [CX + R * 0.75, CY - R * 0.75], [CX - R * 0.75, CY - R * 0.75]]),
55
72
  '♪': poly([[CX - 40, CY + R], [CX + 220, CY + R * 0.7], [CX + 220, CY + R * 0.45], [CX + 20, CY + R * 0.72], [CX + 20, CY - R * 0.55], [CX - 40, CY - R * 0.55]]) + poly(circle(110).map(([x, y]) => /** @type {[number, number]} */ ([x - 120, y - R * 0.6]))),
73
+ '≠': notEqual(),
56
74
  });
57
75
 
58
76
  const CHARS = Object.keys(SHAPES);
@@ -80,7 +98,7 @@ export function symbolFace() {
80
98
  variations: {},
81
99
  source: { name: 'symbols', src: 'covers:symbols', weight: 400 },
82
100
  glyphToPath: (/** @type {number} */ gid) => SHAPES[CHARS[gid - 1]] ?? '',
83
- shapeRun: (/** @type {string} */ text) => Array.from(text).map((ch, i) => ({ gid: CHARS.indexOf(ch) + 1, cluster: i, xAdvance: ADV, xOffset: 0, yOffset: 0 })),
101
+ shapeRun: (/** @type {string} */ text) => Array.from(text).map((ch, i) => ({ gid: CHARS.indexOf(ch) + 1, cluster: i, xAdvance: ch === '≠' ? NARROW : ADV, xOffset: 0, yOffset: 0 })),
84
102
  };
85
103
  return face;
86
104
  }
@@ -24,7 +24,8 @@
24
24
  * - **Live text**: `render: 'live'` writes `<text>` with the font embedded
25
25
  * by `@font-face` (or linked by URL), laid out the same way, for in-browser
26
26
  * speed and selectable text.
27
- * - **Mixed runs**: `spans`, each with its own font, weight, size, colour.
27
+ * - **Mixed runs**: `spans`, each with its own font, weight, size, colour;
28
+ * or `content` lines as span objects (`{ content, bold }`), one a line.
28
29
  * - **Per-glyph control**: `glyphs: { scale, dx, dy, rotate, color }` arrays.
29
30
  * - **Fallback**: characters the font lacks come from `fallback`, fonts
30
31
  * registered with `fallback: true`, or the built-in symbols.
@@ -52,7 +53,7 @@ import { fontFace } from './live.js';
52
53
  import { autoColor } from './auto-color.js';
53
54
  import { fallbackFaces, shapeText } from './fallback.js';
54
55
  import { controlGlyphs, glyphCount } from './glyphs.js';
55
- import { loadSpans, spanLines, shapeSpans, spanText } from './spans.js';
56
+ import { loadSpans, spanLines, shapeSpans, spanText, lineSpans } from './spans.js';
56
57
  import { recordLayout } from './layout-ref.js';
57
58
  import { marquee } from '../animate/marquee.js';
58
59
 
@@ -83,6 +84,9 @@ export function wantsType(layer) {
83
84
  * @returns {Promise<import('../layers.js').Markup>}
84
85
  */
85
86
  export async function typeset(layer, ctx) {
87
+ // Lines given as span objects (a headline whose lines change weight) are spans.
88
+ const perLine = lineSpans(layer.content);
89
+ if (perLine) layer = { ...layer, content: undefined, spans: perLine };
86
90
  const rawContent = Array.isArray(layer.content) ? layer.content.join('\n') : layer.content && typeof layer.content === 'object' ? layer.content.content : layer.content;
87
91
  const kase = layer.transform === 'uppercase' || layer.transform === 'lowercase' ? layer.transform : undefined;
88
92
  let content = layer.spans ? '' : caseText(String(rawContent ?? ''), kase);
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // Generated by scripts/generate.mjs from package.json. Do not edit.
2
2
 
3
3
  /** The package version, part of every cache key. */
4
- export const VERSION = '1.3.1';
4
+ export const VERSION = '1.4.0';