@typecad/ui 1.0.0-alpha.11 → 1.0.0-alpha.13
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/README.md +21 -1
- package/assets/fonts/dejavu/DejaVuSans-Bold.ttf +0 -0
- package/assets/fonts/dejavu/DejaVuSans-ExtraLight.ttf +0 -0
- package/assets/fonts/dejavu/DejaVuSans-Oblique.ttf +0 -0
- package/assets/fonts/dejavu/DejaVuSans.ttf +0 -0
- package/assets/fonts/dejavu/DejaVuSansMono-Bold.ttf +0 -0
- package/assets/fonts/dejavu/DejaVuSansMono.ttf +0 -0
- package/assets/fonts/dejavu/LICENSE +187 -0
- package/assets/fonts/dejavu/README.md +49 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +74 -0
- package/dist/engine-index.js +2 -0
- package/dist/preview/build-program.d.ts +7 -1
- package/dist/preview/build-program.js +94 -15
- package/dist/preview/host-gfx.d.ts +3 -0
- package/dist/preview/host-gfx.js +30 -3
- package/dist/preview/host-ui-runtime.d.ts +115 -0
- package/dist/preview/host-ui-runtime.js +928 -46
- package/dist/ui-engine/block-layout.js +25 -11
- package/dist/ui-engine/color.d.ts +6 -0
- package/dist/ui-engine/color.js +80 -2
- package/dist/ui-engine/compat-report.d.ts +8 -0
- package/dist/ui-engine/compat-report.js +124 -0
- package/dist/ui-engine/css-imports.d.ts +4 -0
- package/dist/ui-engine/css-imports.js +70 -0
- package/dist/ui-engine/css-parser.js +58 -14
- package/dist/ui-engine/default-font.d.ts +25 -0
- package/dist/ui-engine/default-font.js +80 -0
- package/dist/ui-engine/font-assets.d.ts +2 -2
- package/dist/ui-engine/font-assets.js +22 -5
- package/dist/ui-engine/html-parser.d.ts +4 -0
- package/dist/ui-engine/html-parser.js +241 -26
- package/dist/ui-engine/image-assets.d.ts +8 -1
- package/dist/ui-engine/image-assets.js +35 -2
- package/dist/ui-engine/image-decode.d.ts +22 -0
- package/dist/ui-engine/image-decode.js +194 -0
- package/dist/ui-engine/inline-parser.js +1 -1
- package/dist/ui-engine/layout-engine.d.ts +19 -0
- package/dist/ui-engine/layout-engine.js +59 -3
- package/dist/ui-engine/model.d.ts +18 -0
- package/dist/ui-engine/model.js +76 -8
- package/dist/ui-engine/runtime-header/blend-bodies.js +29 -9
- package/dist/ui-engine/runtime-header/canvas-helpers.js +5 -2
- package/dist/ui-engine/runtime-header/canvas-scrollbar.js +115 -111
- package/dist/ui-engine/runtime-header/cuttlefish-gfx.js +21 -0
- package/dist/ui-engine/runtime-header/dirty-scroll-mutators.js +182 -179
- package/dist/ui-engine/runtime-header/forward-decls.js +215 -167
- package/dist/ui-engine/runtime-header/init-press-input.js +138 -135
- package/dist/ui-engine/runtime-header/keyboard.js +682 -380
- package/dist/ui-engine/runtime-header/node-draw-body.js +1656 -1377
- package/dist/ui-engine/runtime-header/paint-order-coords.js +259 -214
- package/dist/ui-engine/runtime-header/paint-rects-repair.js +736 -568
- package/dist/ui-engine/runtime-header/scroll-physics.js +25 -1
- package/dist/ui-engine/runtime-header/state-bindings-nav.js +9 -0
- package/dist/ui-engine/runtime-header/structs.js +228 -216
- package/dist/ui-engine/runtime-header/text-rendering.js +888 -770
- package/dist/ui-engine/runtime-header/tick/bindings-phase.js +118 -116
- package/dist/ui-engine/runtime-header/tick/dirty-draw-phase.js +897 -633
- package/dist/ui-engine/runtime-header/tick/scroll-canvas-phase.js +24 -25
- package/dist/ui-engine/runtime-header/touch-keyboard-fwd.js +79 -23
- package/dist/ui-engine/runtime-header/types-defines.js +110 -93
- package/dist/ui-engine/shadcn-kit.d.ts +1 -0
- package/dist/ui-engine/shadcn-kit.js +502 -0
- package/dist/ui-engine/style-resolver.d.ts +4 -0
- package/dist/ui-engine/style-resolver.js +58 -6
- package/dist/ui-engine/transpile-ui.js +12 -5
- package/dist/ui-engine/ua-stylesheet.d.ts +22 -1
- package/dist/ui-engine/ua-stylesheet.js +119 -32
- package/dist/ui-engine/ui-lowering.js +37 -3
- package/dist/ui-engine/ui-registry.js +32 -4
- package/dist/ui-engine/yoga-layout.js +57 -52
- package/dist/wizard/config-writer.d.ts +49 -0
- package/dist/wizard/config-writer.js +366 -0
- package/dist/wizard/display-catalog.d.ts +75 -0
- package/dist/wizard/display-catalog.js +207 -0
- package/dist/wizard/index.d.ts +7 -0
- package/dist/wizard/index.js +10 -0
- package/dist/wizard/integration-wizard.d.ts +15 -0
- package/dist/wizard/integration-wizard.js +486 -0
- package/dist/wizard/prompts.d.ts +32 -0
- package/dist/wizard/prompts.js +95 -0
- package/dist/wizard/starter-ui.d.ts +1 -0
- package/dist/wizard/starter-ui.js +56 -0
- package/package.json +18 -5
- package/src/cli.ts +87 -0
- package/src/engine-index.ts +53 -51
- package/src/preview/build-program.ts +810 -734
- package/src/preview/host-gfx.ts +30 -3
- package/src/preview/host-ui-runtime.ts +4133 -3289
- package/src/ui-engine/block-layout.ts +24 -11
- package/src/ui-engine/color.ts +77 -2
- package/src/ui-engine/compat-report.ts +139 -0
- package/src/ui-engine/css-imports.ts +69 -0
- package/src/ui-engine/css-parser.ts +64 -15
- package/src/ui-engine/default-font.ts +95 -0
- package/src/ui-engine/font-assets.ts +545 -525
- package/src/ui-engine/html-parser.ts +615 -397
- package/src/ui-engine/image-assets.ts +37 -2
- package/src/ui-engine/image-decode.ts +244 -0
- package/src/ui-engine/inline-parser.ts +1 -1
- package/src/ui-engine/layout-engine.ts +61 -3
- package/src/ui-engine/model.ts +1317 -1230
- package/src/ui-engine/runtime-header/blend-bodies.ts +29 -9
- package/src/ui-engine/runtime-header/canvas-helpers.ts +5 -2
- package/src/ui-engine/runtime-header/canvas-scrollbar.ts +121 -117
- package/src/ui-engine/runtime-header/cuttlefish-gfx.ts +21 -0
- package/src/ui-engine/runtime-header/dirty-scroll-mutators.ts +188 -185
- package/src/ui-engine/runtime-header/forward-decls.ts +227 -179
- package/src/ui-engine/runtime-header/init-press-input.ts +144 -141
- package/src/ui-engine/runtime-header/keyboard.ts +689 -386
- package/src/ui-engine/runtime-header/node-draw-body.ts +1681 -1402
- package/src/ui-engine/runtime-header/paint-order-coords.ts +265 -220
- package/src/ui-engine/runtime-header/paint-rects-repair.ts +742 -574
- package/src/ui-engine/runtime-header/scroll-physics.ts +25 -1
- package/src/ui-engine/runtime-header/state-bindings-nav.ts +9 -0
- package/src/ui-engine/runtime-header/structs.ts +234 -222
- package/src/ui-engine/runtime-header/text-rendering.ts +894 -776
- package/src/ui-engine/runtime-header/tick/bindings-phase.ts +124 -122
- package/src/ui-engine/runtime-header/tick/dirty-draw-phase.ts +902 -638
- package/src/ui-engine/runtime-header/tick/scroll-canvas-phase.ts +30 -31
- package/src/ui-engine/runtime-header/touch-keyboard-fwd.ts +79 -23
- package/src/ui-engine/runtime-header/types-defines.ts +116 -99
- package/src/ui-engine/shadcn-kit.ts +503 -0
- package/src/ui-engine/style-resolver.ts +471 -416
- package/src/ui-engine/transpile-ui.ts +12 -5
- package/src/ui-engine/ua-stylesheet.ts +137 -31
- package/src/ui-engine/ui-lowering.ts +486 -452
- package/src/ui-engine/ui-registry.ts +556 -524
- package/src/ui-engine/yoga-layout.ts +307 -309
- package/src/wizard/config-writer.ts +404 -0
- package/src/wizard/display-catalog.ts +273 -0
- package/src/wizard/index.ts +38 -0
- package/src/wizard/integration-wizard.ts +619 -0
- package/src/wizard/prompts.ts +145 -0
- package/src/wizard/starter-ui.ts +58 -0
package/README.md
CHANGED
|
@@ -13,6 +13,26 @@ npm install --save-dev @typecad/cuttlefish
|
|
|
13
13
|
|
|
14
14
|
`@typecad/ui` is compile-time only — none of its code is shipped to the device. The transpiler intercepts `ui.mount` / `ui.signal` / `ui.bind` / ... calls and lowers them to device variables and binding-table entries, so the package can be safely kept in `dependencies`.
|
|
15
15
|
|
|
16
|
+
### Integration wizard
|
|
17
|
+
|
|
18
|
+
Integrating a display is the one step with real hardware decisions — which panel, which bus, which pins, whether there's touch and how it connects. Run the wizard from your project directory:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx @typecad/ui --config
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
It asks:
|
|
25
|
+
|
|
26
|
+
1. **Display** — a built-in profile (ILI9341 320×240 SPI TFT, ST7796S 320×480 SPI TFT, SSD1309 128×64 I2C OLED), the desktop SDL simulator, or a fully custom driver.
|
|
27
|
+
2. **Bus wiring** — SPI pins (CS/DC/RST/backlight, frequency in MHz, optional SCK/MOSI/MISO override) or the I2C address. Defaults match the framework profiles and the repo's demo wiring (ESP32 VSPI), and any existing `display` section in your config pre-fills the answers.
|
|
28
|
+
3. **Orientation & rendering** — rotation and antialiasing, with advanced color-order/inversion options behind a confirm.
|
|
29
|
+
4. **Touch** — none, resistive (XPT2046, STMPE610, 4-wire analog), capacitive (FT6336U, GT911, CST816S), or a custom adapter file — each with its pins, address, and a sensible default calibration.
|
|
30
|
+
5. **Theme** — optional `themeCss` / `themeClass`.
|
|
31
|
+
|
|
32
|
+
After a summary preview and confirmation, the wizard splices only the `display` section into `cuttlefish.config.ts` — every other section (and its comments) is preserved byte-for-byte, unmanaged display keys like `scroll` are carried over, and the result is syntax-checked before anything is written. If your config's `entry` points at a `.ui` file that doesn't exist yet, it offers to generate a starter screen, and it prints the exact `arduino-cli lib install ...`, preview, compile, and flash commands as next steps.
|
|
33
|
+
|
|
34
|
+
If there is no `cuttlefish.config.ts` yet, create the project first with `npx @typecad/cuttlefish init`, then re-run the wizard.
|
|
35
|
+
|
|
16
36
|
## Project layout
|
|
17
37
|
|
|
18
38
|
A TypeCAD UI project has one **entry** — the file you point `cuttlefish.config.ts` at. The entry can be either a `.ui` single-file component or a plain `.ts` module. Both intermix freely with regular cuttlefish TypeScript (HAL pin reads, `setInterval`, `console.log`, your own `.ts` modules) — the `<script>` block of a `.ui` file and a standalone `.ts` file are lowered by the same pipeline.
|
|
@@ -217,7 +237,7 @@ The fastest path is a single `.ui` file with markup, styling, and behavior toget
|
|
|
217
237
|
</screen>
|
|
218
238
|
```
|
|
219
239
|
|
|
220
|
-
Display hardware and wiring live in `cuttlefish.config.ts` under `display`, so the UI source stays focused on UI behavior.
|
|
240
|
+
Display hardware and wiring live in `cuttlefish.config.ts` under `display`, so the UI source stays focused on UI behavior. Run `npx @typecad/ui --config` to generate that section interactively (see [Integration wizard](#integration-wizard)) — the result looks like the `display` line below.
|
|
221
241
|
|
|
222
242
|
### 2. Point the entry at the `.ui` file
|
|
223
243
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
|
2
|
+
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Bitstream Vera Fonts Copyright
|
|
6
|
+
------------------------------
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
|
9
|
+
a trademark of Bitstream, Inc.
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of the fonts accompanying this license ("Fonts") and associated
|
|
13
|
+
documentation files (the "Font Software"), to reproduce and distribute the
|
|
14
|
+
Font Software, including without limitation the rights to use, copy, merge,
|
|
15
|
+
publish, distribute, and/or sell copies of the Font Software, and to permit
|
|
16
|
+
persons to whom the Font Software is furnished to do so, subject to the
|
|
17
|
+
following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright and trademark notices and this permission notice shall
|
|
20
|
+
be included in all copies of one or more of the Font Software typefaces.
|
|
21
|
+
|
|
22
|
+
The Font Software may be modified, altered, or added to, and in particular
|
|
23
|
+
the designs of glyphs or characters in the Fonts may be modified and
|
|
24
|
+
additional glyphs or characters may be added to the Fonts, only if the fonts
|
|
25
|
+
are renamed to names not containing either the words "Bitstream" or the word
|
|
26
|
+
"Vera".
|
|
27
|
+
|
|
28
|
+
This License becomes null and void to the extent applicable to Fonts or Font
|
|
29
|
+
Software that has been modified and is distributed under the "Bitstream
|
|
30
|
+
Vera" names.
|
|
31
|
+
|
|
32
|
+
The Font Software may be sold as part of a larger software package but no
|
|
33
|
+
copy of one or more of the Font Software typefaces may be sold by itself.
|
|
34
|
+
|
|
35
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
36
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
|
37
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
|
38
|
+
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
|
39
|
+
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
|
40
|
+
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
|
41
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
42
|
+
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
|
43
|
+
FONT SOFTWARE.
|
|
44
|
+
|
|
45
|
+
Except as contained in this notice, the names of Gnome, the Gnome
|
|
46
|
+
Foundation, and Bitstream Inc., shall not be used in advertising or
|
|
47
|
+
otherwise to promote the sale, use or other dealings in this Font Software
|
|
48
|
+
without prior written authorization from the Gnome Foundation or Bitstream
|
|
49
|
+
Inc., respectively. For further information, contact: fonts at gnome dot
|
|
50
|
+
org.
|
|
51
|
+
|
|
52
|
+
Arev Fonts Copyright
|
|
53
|
+
------------------------------
|
|
54
|
+
|
|
55
|
+
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
|
56
|
+
|
|
57
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
58
|
+
a copy of the fonts accompanying this license ("Fonts") and
|
|
59
|
+
associated documentation files (the "Font Software"), to reproduce
|
|
60
|
+
and distribute the modifications to the Bitstream Vera Font Software,
|
|
61
|
+
including without limitation the rights to use, copy, merge, publish,
|
|
62
|
+
distribute, and/or sell copies of the Font Software, and to permit
|
|
63
|
+
persons to whom the Font Software is furnished to do so, subject to
|
|
64
|
+
the following conditions:
|
|
65
|
+
|
|
66
|
+
The above copyright and trademark notices and this permission notice
|
|
67
|
+
shall be included in all copies of one or more of the Font Software
|
|
68
|
+
typefaces.
|
|
69
|
+
|
|
70
|
+
The Font Software may be modified, altered, or added to, and in
|
|
71
|
+
particular the designs of glyphs or characters in the Fonts may be
|
|
72
|
+
modified and additional glyphs or characters may be added to the
|
|
73
|
+
Fonts, only if the fonts are renamed to names not containing either
|
|
74
|
+
the words "Tavmjong Bah" or the word "Arev".
|
|
75
|
+
|
|
76
|
+
This License becomes null and void to the extent applicable to Fonts
|
|
77
|
+
or Font Software that has been modified and is distributed under the
|
|
78
|
+
"Tavmjong Bah Arev" names.
|
|
79
|
+
|
|
80
|
+
The Font Software may be sold as part of a larger software package but
|
|
81
|
+
no copy of one or more of the Font Software typefaces may be sold by
|
|
82
|
+
itself.
|
|
83
|
+
|
|
84
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
85
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
86
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
87
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
|
88
|
+
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
89
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
90
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
91
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
92
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
93
|
+
|
|
94
|
+
Except as contained in this notice, the name of Tavmjong Bah shall not
|
|
95
|
+
be used in advertising or otherwise to promote the sale, use or other
|
|
96
|
+
dealings in this Font Software without prior written authorization
|
|
97
|
+
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
|
98
|
+
. fr.
|
|
99
|
+
|
|
100
|
+
TeX Gyre DJV Math
|
|
101
|
+
-----------------
|
|
102
|
+
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
|
103
|
+
|
|
104
|
+
Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski
|
|
105
|
+
(on behalf of TeX users groups) are in public domain.
|
|
106
|
+
|
|
107
|
+
Letters imported from Euler Fraktur from AMSfonts are (c) American
|
|
108
|
+
Mathematical Society (see below).
|
|
109
|
+
Bitstream Vera Fonts Copyright
|
|
110
|
+
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera
|
|
111
|
+
is a trademark of Bitstream, Inc.
|
|
112
|
+
|
|
113
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
114
|
+
of the fonts accompanying this license (“Fonts”) and associated
|
|
115
|
+
documentation
|
|
116
|
+
files (the “Font Software”), to reproduce and distribute the Font Software,
|
|
117
|
+
including without limitation the rights to use, copy, merge, publish,
|
|
118
|
+
distribute,
|
|
119
|
+
and/or sell copies of the Font Software, and to permit persons to whom
|
|
120
|
+
the Font Software is furnished to do so, subject to the following
|
|
121
|
+
conditions:
|
|
122
|
+
|
|
123
|
+
The above copyright and trademark notices and this permission notice
|
|
124
|
+
shall be
|
|
125
|
+
included in all copies of one or more of the Font Software typefaces.
|
|
126
|
+
|
|
127
|
+
The Font Software may be modified, altered, or added to, and in particular
|
|
128
|
+
the designs of glyphs or characters in the Fonts may be modified and
|
|
129
|
+
additional
|
|
130
|
+
glyphs or characters may be added to the Fonts, only if the fonts are
|
|
131
|
+
renamed
|
|
132
|
+
to names not containing either the words “Bitstream” or the word “Vera”.
|
|
133
|
+
|
|
134
|
+
This License becomes null and void to the extent applicable to Fonts or
|
|
135
|
+
Font Software
|
|
136
|
+
that has been modified and is distributed under the “Bitstream Vera”
|
|
137
|
+
names.
|
|
138
|
+
|
|
139
|
+
The Font Software may be sold as part of a larger software package but
|
|
140
|
+
no copy
|
|
141
|
+
of one or more of the Font Software typefaces may be sold by itself.
|
|
142
|
+
|
|
143
|
+
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
144
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
|
145
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
|
146
|
+
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
|
147
|
+
FOUNDATION
|
|
148
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL,
|
|
149
|
+
SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
|
|
150
|
+
ACTION
|
|
151
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
|
|
152
|
+
INABILITY TO USE
|
|
153
|
+
THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
154
|
+
Except as contained in this notice, the names of GNOME, the GNOME
|
|
155
|
+
Foundation,
|
|
156
|
+
and Bitstream Inc., shall not be used in advertising or otherwise to promote
|
|
157
|
+
the sale, use or other dealings in this Font Software without prior written
|
|
158
|
+
authorization from the GNOME Foundation or Bitstream Inc., respectively.
|
|
159
|
+
For further information, contact: fonts at gnome dot org.
|
|
160
|
+
|
|
161
|
+
AMSFonts (v. 2.2) copyright
|
|
162
|
+
|
|
163
|
+
The PostScript Type 1 implementation of the AMSFonts produced by and
|
|
164
|
+
previously distributed by Blue Sky Research and Y&Y, Inc. are now freely
|
|
165
|
+
available for general use. This has been accomplished through the
|
|
166
|
+
cooperation
|
|
167
|
+
of a consortium of scientific publishers with Blue Sky Research and Y&Y.
|
|
168
|
+
Members of this consortium include:
|
|
169
|
+
|
|
170
|
+
Elsevier Science IBM Corporation Society for Industrial and Applied
|
|
171
|
+
Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS)
|
|
172
|
+
|
|
173
|
+
In order to assure the authenticity of these fonts, copyright will be
|
|
174
|
+
held by
|
|
175
|
+
the American Mathematical Society. This is not meant to restrict in any way
|
|
176
|
+
the legitimate use of the fonts, such as (but not limited to) electronic
|
|
177
|
+
distribution of documents containing these fonts, inclusion of these fonts
|
|
178
|
+
into other public domain or commercial font collections or computer
|
|
179
|
+
applications, use of the outline data to create derivative fonts and/or
|
|
180
|
+
faces, etc. However, the AMS does require that the AMS copyright notice be
|
|
181
|
+
removed from any derivative versions of the fonts which have been altered in
|
|
182
|
+
any way. In addition, to ensure the fidelity of TeX documents using Computer
|
|
183
|
+
Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces,
|
|
184
|
+
has requested that any alterations which yield different font metrics be
|
|
185
|
+
given a different name.
|
|
186
|
+
|
|
187
|
+
$Id$
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Bundled DejaVu fonts
|
|
2
|
+
|
|
3
|
+
These are the unmodified TrueType files from the [DejaVu fonts] project,
|
|
4
|
+
release **2.37** (the final upstream release). They are bundled here so every
|
|
5
|
+
cuttlefish UI project gets an antialiased, continuously-sized font out of the
|
|
6
|
+
box (see `@font-face` injection in `packages/ui/src/ui-engine/default-font.ts`).
|
|
7
|
+
|
|
8
|
+
Do **not** rename or modify these files: the license terms (Bitstream Vera
|
|
9
|
+
License, see [LICENSE](./LICENSE)) permit free redistribution of unmodified
|
|
10
|
+
copies under the original name, but modified variants must be renamed to
|
|
11
|
+
something without the word "DejaVu". Build-time subsetting/rasterization into
|
|
12
|
+
glyph bitmaps is fine — only the installable font files must stay pristine.
|
|
13
|
+
|
|
14
|
+
## Files
|
|
15
|
+
|
|
16
|
+
| File | Face | Used for |
|
|
17
|
+
| ----------------------- | ----------- | ----------------------------------------- |
|
|
18
|
+
| `DejaVuSans.ttf` | Regular | Default injected face (weight 400) |
|
|
19
|
+
| `DejaVuSans-Bold.ttf` | Bold | Default injected face (weight 700) |
|
|
20
|
+
| `DejaVuSansMono.ttf` | Mono Regular | Default injected mono face (`pre`/`code`/`kbd`) |
|
|
21
|
+
| `DejaVuSansMono-Bold.ttf` | Mono Bold | Default injected mono face (weight 700) |
|
|
22
|
+
| `DejaVuSans-Oblique.ttf`| Oblique | Opt-in via `@font-face` (italic) |
|
|
23
|
+
| `DejaVuSans-ExtraLight.ttf` | ExtraLight | Opt-in via `@font-face` (weight 300) |
|
|
24
|
+
|
|
25
|
+
Only `DejaVuSans(.ttf/-Bold.ttf)` and `DejaVuSansMono(.ttf/-Bold.ttf)` are
|
|
26
|
+
injected by default (the "DejaVu Sans" and "DejaVu Sans Mono" families); the
|
|
27
|
+
oblique and extra-light faces ship for projects that declare them explicitly.
|
|
28
|
+
Devices never receive these files — the build rasterizes the exact (family,
|
|
29
|
+
px, weight, style, characters) subsets a UI uses into glyph tables.
|
|
30
|
+
|
|
31
|
+
## Checksums (SHA-256, release 2.37)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
e6476c1b80502924294eed40894c5b18e06c181444ca953e5334262df9c27724 DejaVuSans-Bold.ttf
|
|
35
|
+
6cb0746a1f68d176bebe83752cee35ebdf726cb1a1e88a01fc038ddf76de9ea8 DejaVuSans-ExtraLight.ttf
|
|
36
|
+
4af75fa16ee6d3ad43e1ecec41862c24954af26a55c6bb1ebb27bd486a50f5f4 DejaVuSans-Oblique.ttf
|
|
37
|
+
7da195a74c55bef988d0d48f9508bd5d849425c1770dba5d7bfc6ce9ed848954 DejaVuSans.ttf
|
|
38
|
+
b4a6c3e4faab8773f4ff761d56451646409f29abedd68f05d38c2df667d3c582 DejaVuSansMono.ttf
|
|
39
|
+
bce60f1b4421acd9ea51ba6623d7024ecbe6817a953e3654df62a5e6bdf8f769 DejaVuSansMono-Bold.ttf
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Bitstream Vera License (DejaVu variant) — permissive, GPL-compatible, free to
|
|
45
|
+
redistribute and embed in commercial firmware. The full text is in
|
|
46
|
+
[LICENSE](./LICENSE) and must accompany any redistribution of these files.
|
|
47
|
+
Generated font tables carry an attribution comment pointing back here.
|
|
48
|
+
|
|
49
|
+
[DejaVu fonts]: https://dejavu-fonts.github.io/
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// @typecad/ui CLI — display integration wizard.
|
|
4
|
+
//
|
|
5
|
+
// npx @typecad/ui --config Run the interactive integration wizard
|
|
6
|
+
// npx @typecad/ui --help Show usage
|
|
7
|
+
// npx @typecad/ui --version Show the installed version
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
import { runIntegrationWizard } from "./wizard/integration-wizard.js";
|
|
10
|
+
const USAGE = `
|
|
11
|
+
@typecad/ui — HTML/CSS-driven graphics for microcontrollers
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
npx @typecad/ui --config Configure a display (+ touch) for your
|
|
15
|
+
cuttlefish project interactively. Writes the
|
|
16
|
+
\`display\` section of cuttlefish.config.ts.
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--config Run the integration wizard
|
|
20
|
+
--help, -h Show this help
|
|
21
|
+
--version, -v Print the installed @typecad/ui version
|
|
22
|
+
|
|
23
|
+
The wizard asks which display module you are using (ILI9341 / ST7796S SPI TFT,
|
|
24
|
+
SSD1309 I2C OLED, desktop simulator, or custom), then walks through bus pins,
|
|
25
|
+
SPI/I2C speed, rotation, and touch controller wiring with hardware-aware
|
|
26
|
+
defaults. It never touches the rest of your cuttlefish.config.ts.
|
|
27
|
+
|
|
28
|
+
Docs: https://github.com/justind000/typecode/tree/main/packages/ui
|
|
29
|
+
`.trim();
|
|
30
|
+
function printUsage() {
|
|
31
|
+
console.log(USAGE);
|
|
32
|
+
}
|
|
33
|
+
async function main(argv) {
|
|
34
|
+
const args = argv.slice(2);
|
|
35
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
36
|
+
printUsage();
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
40
|
+
// Lazily read the version so importing this module stays side-effect free.
|
|
41
|
+
const { readFile } = await import("node:fs/promises");
|
|
42
|
+
const { fileURLToPath } = await import("node:url");
|
|
43
|
+
const { dirname, join } = await import("node:path");
|
|
44
|
+
try {
|
|
45
|
+
const packageJson = JSON.parse(await readFile(join(dirname(dirname(fileURLToPath(import.meta.url))), "package.json"), "utf-8"));
|
|
46
|
+
console.log(packageJson.version ?? "unknown");
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
console.log("unknown");
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (args.length === 0 || (args.length === 1 && (args[0] === "--config" || args[0] === "config"))) {
|
|
55
|
+
if (!process.stdin.isTTY) {
|
|
56
|
+
console.error("The integration wizard is interactive and needs a terminal.");
|
|
57
|
+
console.error("Run `npx @typecad/ui --config` from your project directory, or configure");
|
|
58
|
+
console.error("the `display` section of cuttlefish.config.ts manually:");
|
|
59
|
+
console.error("https://github.com/justind000/typecode/tree/main/packages/ui#display-configuration");
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
const result = await runIntegrationWizard(process.cwd());
|
|
63
|
+
return result.exitCode;
|
|
64
|
+
}
|
|
65
|
+
console.error(`Unknown option${args.length > 1 ? "s" : ""}: ${args.join(" ")}\n`);
|
|
66
|
+
printUsage();
|
|
67
|
+
return 2;
|
|
68
|
+
}
|
|
69
|
+
main(process.argv).then((code) => {
|
|
70
|
+
process.exitCode = code;
|
|
71
|
+
}, (error) => {
|
|
72
|
+
console.error(error instanceof Error ? error.message : error);
|
|
73
|
+
process.exitCode = 1;
|
|
74
|
+
});
|
package/dist/engine-index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { resolveColor, resolveColorInternal } from "./ui-engine/color.js";
|
|
|
14
14
|
import { emitRuntimeHeader } from "./ui-engine/runtime-header.js";
|
|
15
15
|
import { emitCuttlefishGfx } from "./ui-engine/runtime-header/cuttlefish-gfx.js";
|
|
16
16
|
import { splitUiFile } from "./ui-engine/ui-file-splitter.js";
|
|
17
|
+
import { warmUpImageDecoding } from "./ui-engine/image-decode.js";
|
|
17
18
|
/**
|
|
18
19
|
* Build and return the TranspilerUIHook — the object cuttlefish core uses
|
|
19
20
|
* to access all UI capabilities (parsing, layout, lowering, emission).
|
|
@@ -36,6 +37,7 @@ export function registerTranspilerUI() {
|
|
|
36
37
|
emitRuntimeHeader,
|
|
37
38
|
emitCuttlefishGfx,
|
|
38
39
|
splitUiFile,
|
|
40
|
+
warmUpImageDecoding,
|
|
39
41
|
generateProjectUITypeDeclarations,
|
|
40
42
|
};
|
|
41
43
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { ResolvedCuttlefishConfig } from "@typecad/cuttlefish/config-loader";
|
|
2
|
-
import type { PreviewSnapshot } from "./types.js";
|
|
2
|
+
import type { PreviewDiagnostic, PreviewSnapshot } from "./types.js";
|
|
3
3
|
export interface BuildPreviewSnapshotOptions {
|
|
4
4
|
config: ResolvedCuttlefishConfig;
|
|
5
5
|
projectRoot: string;
|
|
6
6
|
}
|
|
7
|
+
/** Load the stock 5x7 GFX font for the preview runtime. A project-local
|
|
8
|
+
* Adafruit_GFX copy wins (byte-identical to what the firmware compiles
|
|
9
|
+
* against); otherwise fall back to the table bundled in
|
|
10
|
+
* @typecad/cuttlefish (api/shared glcdfont.ts) so stock-font text renders
|
|
11
|
+
* without a vendored library. */
|
|
12
|
+
export declare function loadFont(projectRoot: string, diagnostics: PreviewDiagnostic[]): number[];
|
|
7
13
|
export declare function buildPreviewSnapshot(options: BuildPreviewSnapshotOptions): Promise<PreviewSnapshot>;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import ts from "typescript";
|
|
4
|
-
import { effectiveDisplaySize, resolveDisplayProfile } from "@typecad/cuttlefish/api/shared";
|
|
4
|
+
import { effectiveDisplaySize, resolveDisplayProfile, GLCDFONT_BYTES } from "@typecad/cuttlefish/api/shared";
|
|
5
5
|
import { parseCss, parseFontFaces, parseKeyframes } from "../ui-engine/css-parser.js";
|
|
6
|
+
import { expandCssImports } from "../ui-engine/css-imports.js";
|
|
7
|
+
import { injectDefaultFontFaces } from "../ui-engine/default-font.js";
|
|
6
8
|
import { extractStyleBlocks, parseHtmlWithKeyboards } from "../ui-engine/html-parser.js";
|
|
7
9
|
import { splitUiFile } from "../ui-engine/ui-file-splitter.js";
|
|
8
10
|
import { buildUIFontAssets } from "../ui-engine/font-assets.js";
|
|
9
|
-
import { loadImageAssets } from "../ui-engine/image-assets.js";
|
|
11
|
+
import { loadImageAssets, applyDecodedImageSizes } from "../ui-engine/image-assets.js";
|
|
12
|
+
import { warmUpImageDecoding } from "../ui-engine/image-decode.js";
|
|
13
|
+
import { SHADCN_KIT_CSS } from "../ui-engine/shadcn-kit.js";
|
|
10
14
|
import { buildKeyframeSets } from "../ui-engine/keyframes.js";
|
|
11
15
|
import { measureWithFonts } from "../ui-engine/layout-engine.js";
|
|
12
16
|
import { lowerUIToModel } from "../ui-engine/model.js";
|
|
@@ -66,6 +70,35 @@ function interpolationToExpression(raw) {
|
|
|
66
70
|
return undefined;
|
|
67
71
|
return "`" + parts.join("") + "`";
|
|
68
72
|
}
|
|
73
|
+
/** Warn about interactive nodes the preview cannot wire because they lack an
|
|
74
|
+
* id: on:* handlers, bind:* bindings, and {expr} interpolations all resolve
|
|
75
|
+
* their node by id in the preview (the device build auto-wires them without
|
|
76
|
+
* one). Without this the element renders but never reacts. */
|
|
77
|
+
function warnUnnamedInteractiveNodes(trees, diagnostics) {
|
|
78
|
+
const walk = (node) => {
|
|
79
|
+
if (!node.id) {
|
|
80
|
+
const features = [];
|
|
81
|
+
if (node.events && Object.keys(node.events).length > 0)
|
|
82
|
+
features.push(`on:${Object.keys(node.events).join("/on:")}`);
|
|
83
|
+
if (node.bind && Object.keys(node.bind).length > 0)
|
|
84
|
+
features.push(`bind:${Object.keys(node.bind).join("/bind:")}`);
|
|
85
|
+
if (node.hasInterpolation)
|
|
86
|
+
features.push("{expr} interpolation");
|
|
87
|
+
// Images key their loaded asset by node id too (image-assets.ts skips
|
|
88
|
+
// id-less <img src> silently) — warn so empty frames are explainable.
|
|
89
|
+
if (node.tag === "img" && node.src)
|
|
90
|
+
features.push("img src");
|
|
91
|
+
if (features.length > 0) {
|
|
92
|
+
diagnostics.push({
|
|
93
|
+
severity: "warning",
|
|
94
|
+
message: `<${node.tag}> uses ${features.join(", ")} but has no id — the preview loads/wires these by id, so the element renders empty or inert. Add an id, e.g. <${node.tag} id="${node.tag}1"> (the device build behaves the same).`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
node.children?.forEach(walk);
|
|
99
|
+
};
|
|
100
|
+
trees.forEach(walk);
|
|
101
|
+
}
|
|
69
102
|
/** Walk styled trees for {expr} interpolation nodes and synthesize preview text
|
|
70
103
|
* bindings (mirroring the runtime's auto-wire synthesis). Each produces a
|
|
71
104
|
* PreviewBindingSpec whose expression is a template-literal the preview evals. */
|
|
@@ -151,22 +184,33 @@ async function loadProfileRegistry(frameworkPackage) {
|
|
|
151
184
|
const registry = new Map();
|
|
152
185
|
if (!frameworkPackage)
|
|
153
186
|
return registry;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
187
|
+
// Every framework package exports its named profiles as BUILT_IN_PROFILES
|
|
188
|
+
// in the shared DisplayProfile shape (Arduino: the displays modules; Zephyr:
|
|
189
|
+
// the display barrel, mapped from its DT-binding descriptors). Try each
|
|
190
|
+
// known entry point — the miss is expected per framework — so this loader
|
|
191
|
+
// stays layout-agnostic and profile names resolve identically here and via
|
|
192
|
+
// the strategy's getProfileRegistry() (which transpile.ts uses).
|
|
193
|
+
for (const modPath of [frameworkPackage + "/displays/ili9341-spi", frameworkPackage + "/display"]) {
|
|
194
|
+
const mod = await import(modPath).catch(() => null);
|
|
195
|
+
const profiles = mod?.BUILT_IN_PROFILES;
|
|
196
|
+
if (profiles) {
|
|
197
|
+
for (const [key, value] of Object.entries(profiles)) {
|
|
198
|
+
registry.set(key, value);
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
158
201
|
}
|
|
159
202
|
}
|
|
160
203
|
return registry;
|
|
161
204
|
}
|
|
162
|
-
|
|
205
|
+
/** Load the stock 5x7 GFX font for the preview runtime. A project-local
|
|
206
|
+
* Adafruit_GFX copy wins (byte-identical to what the firmware compiles
|
|
207
|
+
* against); otherwise fall back to the table bundled in
|
|
208
|
+
* @typecad/cuttlefish (api/shared glcdfont.ts) so stock-font text renders
|
|
209
|
+
* without a vendored library. */
|
|
210
|
+
export function loadFont(projectRoot, diagnostics) {
|
|
163
211
|
const fontPath = path.join(projectRoot, "lib", "Adafruit_GFX_Library", "glcdfont.c");
|
|
164
212
|
if (!fs.existsSync(fontPath)) {
|
|
165
|
-
|
|
166
|
-
severity: "warning",
|
|
167
|
-
message: `Default GFX font not found at ${fontPath}; text pixels will be blank.`,
|
|
168
|
-
});
|
|
169
|
-
return Array.from(new Uint8Array(1280));
|
|
213
|
+
return GLCDFONT_BYTES.slice(0, 1280);
|
|
170
214
|
}
|
|
171
215
|
const source = fs.readFileSync(fontPath, "utf-8");
|
|
172
216
|
const match = /font\[\]\s+PROGMEM\s*=\s*\{([\s\S]*?)\};/.exec(source);
|
|
@@ -568,6 +612,7 @@ export async function buildPreviewSnapshot(options) {
|
|
|
568
612
|
let sourceFile;
|
|
569
613
|
let htmlText;
|
|
570
614
|
let cssText;
|
|
615
|
+
let cssFileDir; // directory @imports inside cssText resolve from
|
|
571
616
|
let htmlFilePath; // the effective .ui.html path (real or synthetic)
|
|
572
617
|
let uiImports;
|
|
573
618
|
if (entryExt === ".ui") {
|
|
@@ -581,6 +626,7 @@ export async function buildPreviewSnapshot(options) {
|
|
|
581
626
|
sourceFile = ts.createSourceFile(entryFile, scriptWithImport, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
582
627
|
htmlText = parts.html;
|
|
583
628
|
cssText = parts.style;
|
|
629
|
+
cssFileDir = entryDir;
|
|
584
630
|
uiImports = [{ treeName: "screen", htmlPath: htmlFilePath }];
|
|
585
631
|
}
|
|
586
632
|
else {
|
|
@@ -600,13 +646,24 @@ export async function buildPreviewSnapshot(options) {
|
|
|
600
646
|
htmlText = fs.readFileSync(firstImport.htmlPath, "utf-8");
|
|
601
647
|
const cssPath = themeCssPath(config.display?.themeCss, firstImport.htmlPath, configDir);
|
|
602
648
|
cssText = fs.existsSync(cssPath) ? fs.readFileSync(cssPath, "utf-8") : "";
|
|
649
|
+
cssFileDir = path.dirname(cssPath);
|
|
603
650
|
}
|
|
604
651
|
const registry = await loadProfileRegistry(config.framework);
|
|
605
652
|
const resolved = resolveDisplayProfile(config.display ?? { profile: "ili9341-spi" }, registry);
|
|
606
653
|
const profile = resolved.profile;
|
|
607
654
|
const displaySize = effectiveDisplaySize(profile);
|
|
608
655
|
const parsedHtml = parseHtmlWithKeyboards(htmlText);
|
|
609
|
-
|
|
656
|
+
// @import parity with the CLI build (loadUIModuleFromText in ui-registry.ts
|
|
657
|
+
// expands imports before parsing). Without this, `@import "./styles/shadcn.css"`
|
|
658
|
+
// in a .ui <style> stays literal in the preview, the kit's tokens never load,
|
|
659
|
+
// and model lowering rejects the raw var() color strings. The sidecar css and
|
|
660
|
+
// the html style blocks can live in different directories, so each part
|
|
661
|
+
// expands against its own base.
|
|
662
|
+
// Built-in shadcn kit first (device parity with ui-registry): user token
|
|
663
|
+
// blocks and recipe overrides win by cascade order.
|
|
664
|
+
const fullCss = SHADCN_KIT_CSS + "\n" +
|
|
665
|
+
expandCssImports(cssText, cssFileDir) + "\n" +
|
|
666
|
+
expandCssImports(extractStyleBlocks(htmlText), path.dirname(htmlFilePath));
|
|
610
667
|
const cssRules = (() => {
|
|
611
668
|
const previousThemeClass = getThemeClass();
|
|
612
669
|
setThemeClass(config.display?.themeClass ?? null);
|
|
@@ -617,12 +674,29 @@ export async function buildPreviewSnapshot(options) {
|
|
|
617
674
|
setThemeClass(previousThemeClass);
|
|
618
675
|
}
|
|
619
676
|
})();
|
|
620
|
-
|
|
677
|
+
// Default-font parity with the CLI build (ui-registry.ts / transpile-ui.ts
|
|
678
|
+
// both inject the bundled DejaVu faces before planning font assets). Without
|
|
679
|
+
// this the UA root's font-family: "DejaVu Sans" resolves to no face and the
|
|
680
|
+
// preview falls back to the smoothed 5x7 — the device renders real AA glyphs.
|
|
681
|
+
const fontFaces = injectDefaultFontFaces(parseFontFaces(fullCss), profile.colorFormat);
|
|
621
682
|
const rawKeyframes = parseKeyframes(fullCss);
|
|
622
683
|
const styled = resolveStyles(parsedHtml.tree, cssRules);
|
|
623
684
|
const allStyledScreens = parsedHtml.screens.map((screen) => resolveStyles(screen, cssRules));
|
|
624
685
|
const fontRoot = { tag: "screen", classes: [], style: {}, children: allStyledScreens };
|
|
625
|
-
|
|
686
|
+
// Script-side ui.bind(..., 'text', ...) targets render runtime strings the
|
|
687
|
+
// static template can't predict — collect their ids so font planning widens
|
|
688
|
+
// those faces to the fallback charset (markup {expr} and bind:text are
|
|
689
|
+
// detected from the tree inside the planner).
|
|
690
|
+
const dynamicTextIds = new Set();
|
|
691
|
+
const bindTextRe = /ui\.bind\(\s*screen\.([A-Za-z_$][\w$]*)\s*,\s*["']text["']/g;
|
|
692
|
+
for (const m of sourceFile.text.matchAll(bindTextRe))
|
|
693
|
+
dynamicTextIds.add(m[1]);
|
|
694
|
+
const fontAssets = buildUIFontAssets(fontRoot, fontFaces, path.dirname(htmlFilePath), dynamicTextIds);
|
|
695
|
+
// Prime the image-conversion cache (<img src="*.png|jpg|ico|…"> decodes
|
|
696
|
+
// here) and give id-less-size img nodes their natural geometry before the
|
|
697
|
+
// synchronous layout + asset pass below.
|
|
698
|
+
await warmUpImageDecoding(htmlText, path.dirname(htmlFilePath), { maxW: displaySize.width, maxH: displaySize.height });
|
|
699
|
+
applyDecodedImageSizes(allStyledScreens.length > 0 ? allStyledScreens : [styled], path.dirname(htmlFilePath));
|
|
626
700
|
const viewport = { x: 0, y: 0, w: displaySize.width, h: displaySize.height };
|
|
627
701
|
const boxes = allStyledScreens.flatMap((screen) => {
|
|
628
702
|
const engine = selectEngine(screen);
|
|
@@ -633,6 +707,11 @@ export async function buildPreviewSnapshot(options) {
|
|
|
633
707
|
const program = lowerUIToModel(styled, boxes, profile.colorFormat, profile, fontAssets, allStyledScreens, imageAssets.nodeIdToAssetIndex, keyframeSets, imageAssets.assets);
|
|
634
708
|
const specs = extractAuthorSpecs(sourceFile, uiImports, program.nodes);
|
|
635
709
|
const hrefCallbacks = collectHrefCallbacks(allStyledScreens, program.nodes);
|
|
710
|
+
// on:*/bind:*/{expr} features resolve their node by id — the device build
|
|
711
|
+
// auto-wires id-less nodes, but the preview's binding/callback tables key on
|
|
712
|
+
// id, so an unnamed interactive node is silently inert here. Make that
|
|
713
|
+
// visible instead of a dead button.
|
|
714
|
+
warnUnnamedInteractiveNodes(allStyledScreens, diagnostics);
|
|
636
715
|
// {expr} interpolation bindings synthesized from the HTML (mirrors the runtime's
|
|
637
716
|
// auto-wire synthesis). Authors write `taps: {count}` in markup; this collects
|
|
638
717
|
// them so the preview evaluates the template-literal expression each frame.
|
|
@@ -28,6 +28,7 @@ export declare class HostAdafruitGFX {
|
|
|
28
28
|
private textColor;
|
|
29
29
|
private textBgColor;
|
|
30
30
|
private monoSnap;
|
|
31
|
+
private storage;
|
|
31
32
|
private textSizeX;
|
|
32
33
|
private textSizeY;
|
|
33
34
|
private wrap;
|
|
@@ -38,6 +39,8 @@ export declare class HostAdafruitGFX {
|
|
|
38
39
|
* every color to black/white by luminance, matching the device's
|
|
39
40
|
* UI_MAYBE_SNAP_MONO565. Uses the same threshold as toMono (0.27). */
|
|
40
41
|
setMonoSnap(on: boolean): void;
|
|
42
|
+
/** Set the buffer's storage depth (see the `storage` field). */
|
|
43
|
+
setStorageMode(mode: "rgb565" | "rgb666" | "rgb888"): void;
|
|
41
44
|
private snap;
|
|
42
45
|
setRotation(_rotation: number): void;
|
|
43
46
|
setClipRect(rect: {
|