@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.1

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 (321) hide show
  1. package/README.md +60 -2
  2. package/dist/core.js +36923 -0
  3. package/dist/core.js.map +6 -0
  4. package/dist/index.js +32 -0
  5. package/dist/loaders-gl-worker.js +82 -0
  6. package/dist/loaders-gl-worker.js.map +6 -0
  7. package/dist/map-logic.js +2 -0
  8. package/dist/map-logic.js.map +6 -0
  9. package/dist/projected-basemaps-worker.js +3 -0
  10. package/dist/projected-basemaps-worker.js.map +6 -0
  11. package/dist/shader-modules.js +141 -0
  12. package/dist/shader-modules.js.map +6 -0
  13. package/dist/style-schema.js +126 -0
  14. package/dist/style-schema.js.map +6 -0
  15. package/dist/tangram-style.schema.json +882 -0
  16. package/dist/tangram.debug.mjs +37139 -0
  17. package/dist/tangram.debug.mjs.map +6 -0
  18. package/dist/tangram.min.mjs +4950 -0
  19. package/dist/types/builders/earcut.d.ts +15 -0
  20. package/dist/types/core.d.ts +29 -0
  21. package/dist/types/gl/constants.d.ts +2 -0
  22. package/dist/types/gl/globe_mesh.d.ts +48 -0
  23. package/dist/types/gl/glsl.d.ts +17 -0
  24. package/dist/types/gl/vertex-constants.d.ts +4 -0
  25. package/dist/types/gl/vertex-types.d.ts +34 -0
  26. package/dist/types/gl/vertex_data.d.ts +32 -0
  27. package/dist/types/gl/vertex_elements.d.ts +8 -0
  28. package/dist/types/gl/vertex_layout.d.ts +32 -0
  29. package/dist/types/glsl.d.ts +14 -0
  30. package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
  31. package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
  32. package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
  33. package/dist/types/index.d.ts +155 -0
  34. package/dist/types/lights/light-definitions.d.ts +121 -0
  35. package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
  36. package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
  37. package/dist/types/map-logic/globe-terrain.d.ts +54 -0
  38. package/dist/types/map-logic/index.d.ts +33 -0
  39. package/dist/types/map-logic/label-identity.d.ts +22 -0
  40. package/dist/types/map-logic/label-placement.d.ts +32 -0
  41. package/dist/types/map-logic/screen-bounds.d.ts +15 -0
  42. package/dist/types/map-logic/terrain-data.d.ts +55 -0
  43. package/dist/types/map-logic/terrain-error.d.ts +51 -0
  44. package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
  45. package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
  46. package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
  47. package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
  48. package/dist/types/map-logic/terrain-query.d.ts +33 -0
  49. package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
  50. package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
  51. package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
  52. package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
  53. package/dist/types/map-logic/tile-residency.d.ts +17 -0
  54. package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
  55. package/dist/types/procedures/js-yaml.d.ts +15 -0
  56. package/dist/types/procedures/mesh-projector.d.ts +107 -0
  57. package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
  58. package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
  59. package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
  60. package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
  61. package/dist/types/procedures/terrain-draping.d.ts +165 -0
  62. package/dist/types/procedures/terrain-globe.d.ts +6 -0
  63. package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
  64. package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
  65. package/dist/types/procedures/web-mercator-math.d.ts +4 -0
  66. package/dist/types/scene/globals.d.ts +11 -0
  67. package/dist/types/scene/ground_footprint.d.ts +16 -0
  68. package/dist/types/scene/host_frame.d.ts +54 -0
  69. package/dist/types/scene/projection_math.d.ts +52 -0
  70. package/dist/types/scene/scene-resource-types.d.ts +177 -0
  71. package/dist/types/scene/scene_bundle.d.ts +69 -0
  72. package/dist/types/scene/visibility_adapter.d.ts +106 -0
  73. package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
  74. package/dist/types/selection/terrain_surface.d.ts +149 -0
  75. package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
  76. package/dist/types/shader-modules/height-decode.d.ts +13 -0
  77. package/dist/types/shader-modules/hillshade.d.ts +13 -0
  78. package/dist/types/shader-modules/index.d.ts +6 -0
  79. package/dist/types/shader-modules/planar.d.ts +12 -0
  80. package/dist/types/shader-modules/sphere-map.d.ts +13 -0
  81. package/dist/types/shader-modules/triplanar.d.ts +15 -0
  82. package/dist/types/sources/decoded_tile_store.d.ts +95 -0
  83. package/dist/types/sources/tile_source_metadata.d.ts +32 -0
  84. package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
  85. package/dist/types/tile/tile_id.d.ts +37 -0
  86. package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
  87. package/dist/types/types.d.ts +293 -0
  88. package/dist/types/utils/geo.d.ts +57 -0
  89. package/dist/types/utils/hash.d.ts +1 -0
  90. package/dist/types/utils/log.d.ts +27 -0
  91. package/dist/types/utils/props.d.ts +6 -0
  92. package/dist/types/utils/subscribe.d.ts +10 -0
  93. package/dist/types/utils/thread.d.ts +6 -0
  94. package/dist/types/utils/urls.d.ts +26 -0
  95. package/dist/types/utils/utils.d.ts +26 -0
  96. package/dist/types/utils/version.d.ts +2 -0
  97. package/dist/types/utils/worker-types.d.ts +68 -0
  98. package/dist/types/utils/worker_broker.d.ts +3 -0
  99. package/package.json +103 -3
  100. package/src/builders/common.ts +41 -0
  101. package/src/builders/earcut.d.ts +15 -0
  102. package/src/builders/geometry-types.ts +60 -0
  103. package/src/builders/points.ts +115 -0
  104. package/src/builders/polygons.ts +225 -0
  105. package/src/builders/polylines.ts +682 -0
  106. package/src/builders/wireframe.ts +31 -0
  107. package/src/core.d.ts +29 -0
  108. package/src/core.ts +33 -0
  109. package/src/experimental/loaders-gl-worker.ts +19 -0
  110. package/src/experimental/projected-basemaps-worker.ts +13 -0
  111. package/src/experimental/projected-mesh-cache.ts +137 -0
  112. package/src/experimental/projected-mesh-domain.ts +110 -0
  113. package/src/experimental/projected-mesh-refinement.ts +193 -0
  114. package/src/experimental/projected-mesh.ts +399 -0
  115. package/src/experimental/projected-normal.ts +26 -0
  116. package/src/experimental/projected-symbol-mesh.ts +74 -0
  117. package/src/gl/constants.ts +18 -0
  118. package/src/gl/context.ts +103 -0
  119. package/src/gl/extensions.ts +30 -0
  120. package/src/gl/globe_mesh.ts +285 -0
  121. package/src/gl/glsl.ts +257 -0
  122. package/src/gl/mesh-types.ts +56 -0
  123. package/src/gl/render_state.ts +111 -0
  124. package/src/gl/shader_program.ts +1310 -0
  125. package/src/gl/texture.ts +814 -0
  126. package/src/gl/uniform_buffer.ts +340 -0
  127. package/src/gl/vao.ts +154 -0
  128. package/src/gl/vbo_mesh.ts +349 -0
  129. package/src/gl/vertex-constants.ts +19 -0
  130. package/src/gl/vertex-types.ts +35 -0
  131. package/src/gl/vertex_data.ts +126 -0
  132. package/src/gl/vertex_elements.ts +54 -0
  133. package/src/gl/vertex_layout.ts +241 -0
  134. package/src/glsl.d.ts +14 -0
  135. package/src/gpu/luma_device_renderer.ts +579 -0
  136. package/src/gpu/pixel_readback.ts +51 -0
  137. package/src/gpu/resource_lifecycle.ts +32 -0
  138. package/src/gpu/tangram_gpu_backend.ts +195 -0
  139. package/src/index.d.ts +155 -0
  140. package/src/index.ts +105 -0
  141. package/src/labels/collision-types.ts +94 -0
  142. package/src/labels/collision.ts +273 -0
  143. package/src/labels/collision_grid.ts +61 -0
  144. package/src/labels/intersect.ts +30 -0
  145. package/src/labels/label-types.ts +91 -0
  146. package/src/labels/label.ts +207 -0
  147. package/src/labels/label_line.ts +801 -0
  148. package/src/labels/label_point.ts +131 -0
  149. package/src/labels/main-pass-types.ts +73 -0
  150. package/src/labels/main_pass.ts +221 -0
  151. package/src/labels/point_anchor.ts +100 -0
  152. package/src/labels/point_placement.ts +150 -0
  153. package/src/labels/projected-pass.ts +259 -0
  154. package/src/labels/repeat_group.ts +72 -0
  155. package/src/lights/ambient_light.glsl +18 -0
  156. package/src/lights/directional_light.glsl +39 -0
  157. package/src/lights/geographic-lights.ts +21 -0
  158. package/src/lights/light-definitions.ts +285 -0
  159. package/src/lights/light.ts +590 -0
  160. package/src/lights/lighting-uniforms.ts +80 -0
  161. package/src/lights/lighting-wgsl.ts +116 -0
  162. package/src/lights/material.glsl +237 -0
  163. package/src/lights/material.ts +145 -0
  164. package/src/lights/native-falloff.ts +37 -0
  165. package/src/lights/point_light.glsl +96 -0
  166. package/src/lights/spot_light.glsl +111 -0
  167. package/src/map-logic/draped-terrain-bounds.ts +71 -0
  168. package/src/map-logic/globe-terrain-preparation.ts +217 -0
  169. package/src/map-logic/globe-terrain.ts +296 -0
  170. package/src/map-logic/index.ts +37 -0
  171. package/src/map-logic/label-identity.ts +36 -0
  172. package/src/map-logic/label-placement.ts +117 -0
  173. package/src/map-logic/screen-bounds.ts +34 -0
  174. package/src/map-logic/terrain-data.ts +107 -0
  175. package/src/map-logic/terrain-error.ts +134 -0
  176. package/src/map-logic/terrain-ground-topology.ts +164 -0
  177. package/src/map-logic/terrain-height-field.ts +254 -0
  178. package/src/map-logic/terrain-navigation.ts +50 -0
  179. package/src/map-logic/terrain-neighborhood.ts +43 -0
  180. package/src/map-logic/terrain-query.ts +51 -0
  181. package/src/map-logic/terrain-resource-budget.ts +124 -0
  182. package/src/map-logic/terrain-transition-topology.ts +164 -0
  183. package/src/map-logic/tile-build-queue.ts +110 -0
  184. package/src/map-logic/tile-cache-policy.ts +89 -0
  185. package/src/map-logic/tile-residency.ts +50 -0
  186. package/src/map-logic/triangle-query-index.ts +265 -0
  187. package/src/procedures/js-yaml.d.ts +15 -0
  188. package/src/procedures/mesh-projector.ts +191 -0
  189. package/src/procedures/mlt-loaders.ts +55 -0
  190. package/src/procedures/mvt-dependencies.d.ts +20 -0
  191. package/src/procedures/mvt-legacy.ts +150 -0
  192. package/src/procedures/mvt-loaders.ts +53 -0
  193. package/src/procedures/mvt-parser.ts +48 -0
  194. package/src/procedures/mvt-properties.ts +36 -0
  195. package/src/procedures/mvt-tile-provider.ts +72 -0
  196. package/src/procedures/pmtiles-loader.ts +75 -0
  197. package/src/procedures/projected-coordinate-transform.ts +79 -0
  198. package/src/procedures/projection-batch-executor.ts +140 -0
  199. package/src/procedures/scene-yaml-legacy.ts +16 -0
  200. package/src/procedures/scene-yaml-loaders.ts +10 -0
  201. package/src/procedures/terrain-draping.ts +713 -0
  202. package/src/procedures/terrain-globe.ts +32 -0
  203. package/src/procedures/terrain-styled-topology.ts +184 -0
  204. package/src/procedures/web-mercator-legacy.ts +24 -0
  205. package/src/procedures/web-mercator-math.ts +50 -0
  206. package/src/scene/camera.ts +298 -0
  207. package/src/scene/camera_base.ts +116 -0
  208. package/src/scene/classic_scene.ts +20 -0
  209. package/src/scene/external_camera.ts +101 -0
  210. package/src/scene/globals.ts +120 -0
  211. package/src/scene/ground_footprint.ts +139 -0
  212. package/src/scene/host_frame.ts +326 -0
  213. package/src/scene/projected_tile_lod.ts +125 -0
  214. package/src/scene/projection_math.ts +142 -0
  215. package/src/scene/projection_shaders.ts +183 -0
  216. package/src/scene/renderer.ts +516 -0
  217. package/src/scene/scene-resource-types.ts +174 -0
  218. package/src/scene/scene.ts +2378 -0
  219. package/src/scene/scene_bundle.ts +304 -0
  220. package/src/scene/scene_debug.ts +129 -0
  221. package/src/scene/scene_loader.ts +402 -0
  222. package/src/scene/scene_worker.ts +528 -0
  223. package/src/scene/view.ts +683 -0
  224. package/src/scene/visibility_adapter.ts +319 -0
  225. package/src/scene/worker_url.ts +15 -0
  226. package/src/selection/draped-terrain-surface.ts +377 -0
  227. package/src/selection/selection-types.ts +79 -0
  228. package/src/selection/selection.ts +542 -0
  229. package/src/selection/selection_fragment.glsl +18 -0
  230. package/src/selection/selection_globals.glsl +9 -0
  231. package/src/selection/selection_pixels.ts +59 -0
  232. package/src/selection/selection_vertex.glsl +15 -0
  233. package/src/selection/terrain_surface.ts +298 -0
  234. package/src/shader-modules/globe-horizon.ts +52 -0
  235. package/src/shader-modules/height-decode.ts +41 -0
  236. package/src/shader-modules/hillshade.ts +70 -0
  237. package/src/shader-modules/index.ts +10 -0
  238. package/src/shader-modules/planar.ts +24 -0
  239. package/src/shader-modules/sphere-map.ts +38 -0
  240. package/src/shader-modules/triplanar.ts +45 -0
  241. package/src/sources/aligned_tile_source.ts +122 -0
  242. package/src/sources/data_source.ts +655 -0
  243. package/src/sources/decoded_tile_store.ts +245 -0
  244. package/src/sources/geojson.ts +300 -0
  245. package/src/sources/mvt.ts +247 -0
  246. package/src/sources/raster.ts +341 -0
  247. package/src/sources/shared_tile_source_adapter.ts +117 -0
  248. package/src/sources/sources.ts +10 -0
  249. package/src/sources/tile_source_adapter.ts +84 -0
  250. package/src/sources/tile_source_metadata.ts +65 -0
  251. package/src/sources/tile_source_state.ts +112 -0
  252. package/src/sources/topojson.ts +90 -0
  253. package/src/styles/feature_annotations.ts +16 -0
  254. package/src/styles/filter.ts +190 -0
  255. package/src/styles/geometry-style-types.ts +209 -0
  256. package/src/styles/globe_visibility_wgsl.ts +22 -0
  257. package/src/styles/layer-types.ts +45 -0
  258. package/src/styles/layer.ts +586 -0
  259. package/src/styles/lines/dasharray.ts +49 -0
  260. package/src/styles/lines/lines.ts +707 -0
  261. package/src/styles/lines/lines_wgsl.ts +224 -0
  262. package/src/styles/points/point-runtime-types.ts +125 -0
  263. package/src/styles/points/points.ts +1079 -0
  264. package/src/styles/points/points_fragment.glsl +126 -0
  265. package/src/styles/points/points_vertex.glsl +230 -0
  266. package/src/styles/points/points_wgsl.ts +189 -0
  267. package/src/styles/polygons/polygons.ts +268 -0
  268. package/src/styles/polygons/polygons_fragment.glsl +173 -0
  269. package/src/styles/polygons/polygons_vertex.glsl +213 -0
  270. package/src/styles/polygons/polygons_wgsl.ts +127 -0
  271. package/src/styles/property-types.ts +125 -0
  272. package/src/styles/raster/raster.ts +33 -0
  273. package/src/styles/raster/raster_globals.glsl +46 -0
  274. package/src/styles/style-mixing-types.ts +101 -0
  275. package/src/styles/style-runtime-types.ts +220 -0
  276. package/src/styles/style-schema.ts +133 -0
  277. package/src/styles/style.ts +1033 -0
  278. package/src/styles/style_globals.glsl +69 -0
  279. package/src/styles/style_manager.ts +464 -0
  280. package/src/styles/style_parser.ts +620 -0
  281. package/src/styles/text/font_manager.ts +180 -0
  282. package/src/styles/text/fontfaceobserver.d.ts +10 -0
  283. package/src/styles/text/text-types.ts +220 -0
  284. package/src/styles/text/text.ts +378 -0
  285. package/src/styles/text/text_canvas.ts +773 -0
  286. package/src/styles/text/text_labels.ts +436 -0
  287. package/src/styles/text/text_segments.ts +142 -0
  288. package/src/styles/text/text_settings.ts +228 -0
  289. package/src/styles/text/text_wgsl.ts +159 -0
  290. package/src/styles/text/text_wrap.ts +194 -0
  291. package/src/tile/globe_tile_preload.ts +40 -0
  292. package/src/tile/tangram_tileset_2d.ts +108 -0
  293. package/src/tile/tile-build-types.ts +155 -0
  294. package/src/tile/tile.ts +807 -0
  295. package/src/tile/tile_id.ts +172 -0
  296. package/src/tile/tile_manager.ts +889 -0
  297. package/src/tile/tile_pyramid.ts +119 -0
  298. package/src/tile/tile_resource_cache.ts +91 -0
  299. package/src/tile/tile_traversal_adapter.ts +132 -0
  300. package/src/types.ts +332 -0
  301. package/src/utils/debounce.ts +17 -0
  302. package/src/utils/debug_settings.ts +43 -0
  303. package/src/utils/errors.ts +12 -0
  304. package/src/utils/functions.ts +95 -0
  305. package/src/utils/geo.ts +364 -0
  306. package/src/utils/hash.ts +14 -0
  307. package/src/utils/log.ts +108 -0
  308. package/src/utils/media_capture.ts +193 -0
  309. package/src/utils/merge.ts +44 -0
  310. package/src/utils/obb.ts +134 -0
  311. package/src/utils/props.ts +43 -0
  312. package/src/utils/slice.ts +14 -0
  313. package/src/utils/subscribe.ts +58 -0
  314. package/src/utils/task.ts +154 -0
  315. package/src/utils/thread.ts +26 -0
  316. package/src/utils/urls.ts +223 -0
  317. package/src/utils/utils.ts +310 -0
  318. package/src/utils/vector.ts +197 -0
  319. package/src/utils/version.ts +8 -0
  320. package/src/utils/worker-types.ts +79 -0
  321. package/src/utils/worker_broker.ts +523 -0
@@ -0,0 +1,228 @@
1
+ // Tangram
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) 2013-2016 Brett Camper and Mapzen
4
+ // Copyright (c) 2026 vis.gl contributors
5
+
6
+ import Utils from '../../utils/utils';
7
+ import StyleParser from '../style_parser';
8
+
9
+ type TextColorValue = unknown;
10
+
11
+ interface TextFontStroke {
12
+ color?: TextColorValue;
13
+ alpha?: TextColorValue;
14
+ width?: TextColorValue;
15
+ }
16
+
17
+ interface TextFontBackground {
18
+ color?: TextColorValue;
19
+ alpha?: TextColorValue;
20
+ width?: TextColorValue;
21
+ stroke?: TextFontStroke;
22
+ }
23
+
24
+ interface TextFont {
25
+ fill?: TextColorValue;
26
+ alpha?: TextColorValue;
27
+ stroke?: TextFontStroke;
28
+ underline?: boolean;
29
+ background?: TextFontBackground;
30
+ weight?: TextColorValue;
31
+ family?: string;
32
+ style?: string;
33
+ transform?: string;
34
+ px_size?: TextColorValue;
35
+ size?: TextColorValue;
36
+ }
37
+
38
+ export interface TextDraw {
39
+ font?: TextFont;
40
+ supersample_text?: boolean;
41
+ can_articulate?: boolean;
42
+ text_wrap?: boolean | number;
43
+ max_lines?: number;
44
+ }
45
+
46
+ export interface TextSettingsResult {
47
+ style?: string;
48
+ weight?: string | number;
49
+ px_size?: number;
50
+ family?: string;
51
+ fill?: string;
52
+ stroke?: string;
53
+ stroke_width?: number;
54
+ underline_width?: number;
55
+ background_color?: string;
56
+ background_width?: number;
57
+ background_stroke_color?: string;
58
+ background_stroke_width?: number;
59
+ transform?: string;
60
+ text_wrap?: boolean | number;
61
+ max_lines?: number;
62
+ supersample: number;
63
+ can_articulate?: boolean;
64
+ font_css?: string;
65
+ }
66
+
67
+ interface TextSettingsContext {
68
+ [key: string]: unknown;
69
+ }
70
+
71
+ interface StyleParserApi {
72
+ zeroPair: readonly [number, number];
73
+ evalCachedProperty(value: unknown, context: unknown): unknown;
74
+ evalCachedColorPropertyWithAlpha(value: unknown, alpha: unknown, context: unknown): number[] | false | null | undefined;
75
+ }
76
+
77
+ const typedStyleParser = StyleParser as unknown as StyleParserApi;
78
+
79
+ function toCssColor(value: number[] | false | null | undefined): string | undefined {
80
+ return Array.isArray(value) ? Utils.toCSSColor(value) : undefined;
81
+ }
82
+
83
+ const TextSettings = {
84
+
85
+ // A key for grouping all labels of the same text style (e.g. same Canvas state, to minimize state changes)
86
+ key (settings: TextSettingsResult): string {
87
+ return [
88
+ settings.style,
89
+ settings.weight,
90
+ settings.family,
91
+ settings.px_size,
92
+ settings.fill,
93
+ settings.stroke,
94
+ settings.stroke_width,
95
+ settings.underline_width,
96
+ settings.background_color,
97
+ settings.background_width,
98
+ settings.background_stroke_color,
99
+ settings.background_stroke_width,
100
+ settings.transform,
101
+ settings.text_wrap,
102
+ settings.max_lines,
103
+ settings.supersample,
104
+ Utils.device_pixel_ratio
105
+ ].join('/');
106
+ },
107
+
108
+ defaults: {
109
+ style: 'normal',
110
+ weight: 'normal',
111
+ size: '12px',
112
+ px_size: 12,
113
+ family: 'Helvetica',
114
+ fill: [1, 1, 1, 1],
115
+ text_wrap: 15,
116
+ max_lines: 5,
117
+ align: 'center'
118
+ },
119
+
120
+ compute (draw: TextDraw, context: TextSettingsContext): TextSettingsResult {
121
+ const style: TextSettingsResult = {supersample: 1};
122
+
123
+ draw.font = draw.font || this.defaults;
124
+
125
+ style.supersample = draw.supersample_text ? 1.5 : 1; // optionally render text at 150% to improve clarity
126
+
127
+ // LineString labels can articulate while point labels cannot. Needed for future texture coordinate calculations.
128
+ style.can_articulate = draw.can_articulate;
129
+
130
+ // Text fill
131
+ const fillColor = typedStyleParser.evalCachedColorPropertyWithAlpha(draw.font.fill, draw.font.alpha, context);
132
+ style.fill = toCssColor(fillColor); // convert to CSS for Canvas
133
+
134
+ // Text stroke
135
+ if (draw.font.stroke && draw.font.stroke.color) {
136
+ style.stroke = toCssColor(typedStyleParser.evalCachedColorPropertyWithAlpha(draw.font.stroke.color, draw.font.stroke.alpha, context)); // convert to CSS for Canvas
137
+ style.stroke_width = typedStyleParser.evalCachedProperty(draw.font.stroke.width, context) as number;
138
+ }
139
+
140
+ // Text underline
141
+ if (draw.font.underline === true && !style.can_articulate) {
142
+ style.underline_width = 1.5 * style.supersample;
143
+ }
144
+
145
+ // Background box
146
+ if (draw.font.background && !style.can_articulate) { // supported for point labels only
147
+ // Background fill
148
+ style.background_color = toCssColor(typedStyleParser.evalCachedColorPropertyWithAlpha(draw.font.background.color, draw.font.background.alpha, context)); // convert to CSS for Canvas
149
+ if (style.background_color) {
150
+ style.background_width = typedStyleParser.evalCachedProperty(draw.font.background.width, context) as number;
151
+ }
152
+
153
+ // Background stroke
154
+ const backgroundStroke = draw.font.background.stroke;
155
+ const backgroundStrokeColor = backgroundStroke?.color != null ?
156
+ typedStyleParser.evalCachedColorPropertyWithAlpha(backgroundStroke.color, backgroundStroke.alpha, context) :
157
+ undefined;
158
+ style.background_stroke_color = toCssColor(backgroundStrokeColor);
159
+ if (style.background_stroke_color) {
160
+ // default background stroke to 1px when stroke color but no stroke width specified
161
+ style.background_stroke_width = backgroundStroke?.width != null ?
162
+ typedStyleParser.evalCachedProperty(backgroundStroke.width, context) as number : 1;
163
+ }
164
+ }
165
+
166
+ // Font properties are modeled after CSS names:
167
+ // - family: Helvetica, Futura, etc.
168
+ // - size: in pt, px, or em
169
+ // - style: normal, italic, oblique
170
+ // - weight: normal, bold, etc.
171
+ // - transform: capitalize, uppercase, lowercase
172
+
173
+ // clamp weight to 1-1000 (see https://drafts.csswg.org/css-fonts-4/#valdef-font-weight-number)
174
+ style.weight = typedStyleParser.evalCachedProperty(draw.font.weight, context) as string | number || this.defaults.weight;
175
+ if (typeof style.weight === 'number') {
176
+ style.weight = Math.min(Math.max(style.weight, 1), 1000);
177
+ }
178
+
179
+ if (draw.font.family) {
180
+ style.family = draw.font.family;
181
+ if (style.family !== this.defaults.family) {
182
+ style.family += ', ' + this.defaults.family;
183
+ }
184
+ }
185
+ else {
186
+ style.family = this.defaults.family;
187
+ }
188
+
189
+ style.style = draw.font.style || this.defaults.style;
190
+ style.transform = draw.font.transform;
191
+
192
+ // calculated pixel size
193
+ style.px_size = (typedStyleParser.evalCachedProperty(draw.font.px_size, context) as number) * style.supersample;
194
+
195
+ style.font_css = this.fontCSS(style);
196
+
197
+ // Word wrap and text alignment
198
+ // Not a font properties, but affect atlas of unique text textures
199
+ let text_wrap = draw.text_wrap; // use explicitly set value
200
+
201
+ if (text_wrap == null && !style.can_articulate) {
202
+ // point labels (for point and polygon features) have word wrap on w/default max length,
203
+ // line labels default off
204
+ text_wrap = true;
205
+ }
206
+
207
+ // setting to 'true' causes default wrap value to be used
208
+ if (text_wrap === true) {
209
+ text_wrap = this.defaults.text_wrap;
210
+ }
211
+ style.text_wrap = text_wrap;
212
+
213
+ // max_lines setting to truncate very long labels with an ellipsis
214
+ style.max_lines = draw.max_lines || this.defaults.max_lines;
215
+
216
+ return style;
217
+ },
218
+
219
+ // Build CSS-style font string (to set Canvas draw state)
220
+ fontCSS ({style, weight, px_size, family}: TextSettingsResult): string {
221
+ return [style, weight, px_size + 'px', family]
222
+ .filter(x => x) // remove null props
223
+ .join(' ');
224
+ }
225
+
226
+ };
227
+
228
+ export default TextSettings;
@@ -0,0 +1,159 @@
1
+ // tangram-layers
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {GLOBE_PROJECTION_WGSL, TERRAIN_DRAPING_WGSL} from '../../scene/projection_shaders';
6
+ import {GLOBE_VISIBILITY_WGSL} from '../globe_visibility_wgsl';
7
+
8
+ const PI = Math.PI;
9
+
10
+ /**
11
+ * Build the portable standalone-text shader used by the luma.gl WebGPU renderer.
12
+ *
13
+ * Text quads retain Tangram's CPU collision, atlas, and curved-label geometry.
14
+ * The shader applies the buffered screen-space shape and samples the luma-owned
15
+ * atlas texture without reading a backend texture handle.
16
+ *
17
+ * @param cpuProjection Use preprojected ground anchors for screen-laid-out annotations.
18
+ * @param selection Emit the worker selection key for visible atlas pixels.
19
+ * @param terrain Add physical terrain height/morph attributes to the anchor.
20
+ * @returns {string} Complete WGSL source for Tangram's text style.
21
+ */
22
+ export function buildTextWGSL(cpuProjection = false, selection = false, terrain = false) {
23
+ return `
24
+ @group(0) @binding(3) var u_texture: texture_2d<f32>;
25
+ @group(0) @binding(4) var u_textureSampler: sampler;
26
+ ${GLOBE_PROJECTION_WGSL}
27
+ ${terrain ? TERRAIN_DRAPING_WGSL : ''}
28
+ ${GLOBE_VISIBILITY_WGSL}
29
+
30
+ struct TextAttributes {
31
+ ${terrain ? '@location(14) a_terrain: vec4<f32>, @location(15) a_terrain_previous: vec4<f32>,' : ''}
32
+ @location(0) a_position: vec4<${terrain ? 'f32' : 'i32'}>,
33
+ @location(1) a_shape: vec4<i32>,
34
+ @location(2) a_texcoord: vec2<f32>,
35
+ @location(3) a_offset: vec2<i32>,
36
+ @location(4) a_color: vec4<f32>,
37
+ ${selection ? '@location(5) a_selection_color: vec4<f32>,' : ''}
38
+ @location(6) a_pre_angles: vec4<i32>,
39
+ @location(7) a_angles: vec4<i32>,
40
+ @location(8) a_offsets: vec4<u32>,
41
+ ${cpuProjection ? '@location(9) a_projected_position: vec3<f32>,' : ''}
42
+ };
43
+
44
+ struct TextVaryings {
45
+ @builtin(position) position: vec4<f32>,
46
+ @location(0) texcoord: vec2<f32>,
47
+ @location(1) color: vec4<f32>,
48
+ ${selection ? '@location(2) @interpolate(flat) selection_color: vec4<f32>,' : ''}
49
+ };
50
+
51
+ fn rotate2D(point: vec2<f32>, angle: f32) -> vec2<f32> {
52
+ let cosine = cos(angle);
53
+ let sine = sin(angle);
54
+ return vec2<f32>(
55
+ cosine * point.x - sine * point.y,
56
+ sine * point.x + cosine * point.y
57
+ );
58
+ }
59
+
60
+ fn mix4Linear(values: vec4<f32>, amount: f32) -> f32 {
61
+ let clamped_amount = clamp(amount, 0.0, 1.0);
62
+ let first_segment = mix(values.x, values.y, 3.0 * clamped_amount);
63
+ let last_segment = mix(
64
+ values.z,
65
+ values.w,
66
+ 3.0 * (max(clamped_amount, 0.66) - 0.66)
67
+ );
68
+ let remaining_segments = mix(
69
+ values.y,
70
+ last_segment,
71
+ 3.0 * (clamp(clamped_amount, 0.33, 0.66) - 0.33)
72
+ );
73
+ return select(first_segment, remaining_segments, clamped_amount >= 0.33);
74
+ }
75
+
76
+ @vertex
77
+ fn vertexMain(attributes: TextAttributes) -> TextVaryings {
78
+ var output: TextVaryings;
79
+ ${selection ? 'output.selection_color = attributes.a_selection_color;' : ''}
80
+ output.texcoord = vec2<f32>(
81
+ attributes.a_texcoord.x,
82
+ 1.0 - attributes.a_texcoord.y
83
+ );
84
+ output.color = attributes.a_color;
85
+
86
+ if (attributes.a_shape.w == 0) {
87
+ output.position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
88
+ return output;
89
+ }
90
+
91
+ var shape = vec2<f32>(attributes.a_shape.xy) / 256.0;
92
+ let offset = vec2<f32>(
93
+ f32(attributes.a_offset.x),
94
+ -f32(attributes.a_offset.y)
95
+ );
96
+ let theta = f32(attributes.a_shape.z) / 4096.0;
97
+
98
+ if (attributes.a_offsets.x != 0u) {
99
+ let zoom = clamp(
100
+ TangramView.u_map_position.z - TangramTile.u_tile_origin.z,
101
+ 0.0,
102
+ 1.0
103
+ );
104
+ let pre_angle = mix4Linear(
105
+ vec4<f32>(attributes.a_pre_angles) * (${PI} / 128.0),
106
+ zoom
107
+ );
108
+ let curve_angle = mix4Linear(
109
+ vec4<f32>(attributes.a_angles) * (${PI} / 16384.0),
110
+ zoom
111
+ );
112
+ let curve_offset = mix4Linear(
113
+ vec4<f32>(attributes.a_offsets) / 64.0,
114
+ zoom
115
+ );
116
+ shape = rotate2D(shape, pre_angle);
117
+ shape = vec2<f32>(shape.x + curve_offset, shape.y);
118
+ shape = rotate2D(shape, curve_angle);
119
+ shape += rotate2D(offset, theta);
120
+ }
121
+ else {
122
+ shape = rotate2D(shape + offset, theta);
123
+ }
124
+
125
+ let local_position = vec4<f32>(
126
+ f32(attributes.a_position.x),
127
+ f32(attributes.a_position.y),
128
+ f32(attributes.a_position.z) ${terrain ? '+ tangramTerrainHeight(attributes.a_terrain, attributes.a_terrain_previous)' : ''},
129
+ 1.0
130
+ );
131
+ let projected_position = ${cpuProjection ? 'vec4<f32>(attributes.a_projected_position, 1.0)' : 'tangramModelView(local_position)'};
132
+ if (TangramView.u_projection_mode == 1 && tangramGlobeOccluded(projected_position.xyz,
133
+ (TangramTile.u_model * local_position).z, TangramCamera.u_eye)) {
134
+ output.position = vec4<f32>(2.0, 2.0, 2.0, 1.0);
135
+ return output;
136
+ }
137
+ var clip_position = TangramCamera.u_projection * projected_position;
138
+ ${cpuProjection ? 'clip_position.z = (clip_position.z + clip_position.w) * 0.5;' : ''}
139
+ let screen_offset = shape * clip_position.w * 2.0 *
140
+ TangramView.u_device_pixel_ratio / TangramView.u_resolution;
141
+ clip_position = vec4<f32>(
142
+ clip_position.xy + screen_offset,
143
+ clip_position.zw
144
+ );
145
+
146
+ output.position = clip_position;
147
+ return output;
148
+ }
149
+
150
+ @fragment
151
+ fn fragmentMain(input: TextVaryings) -> @location(0) vec4<f32> {
152
+ var atlas_color = textureSample(u_texture, u_textureSampler, input.texcoord);
153
+ ${selection ? 'if (atlas_color.a < 0.001) { discard; }\n return input.selection_color;' : `return vec4<f32>(
154
+ atlas_color.rgb / max(atlas_color.a, 0.001),
155
+ atlas_color.a
156
+ );`}
157
+ }
158
+ `;
159
+ }
@@ -0,0 +1,194 @@
1
+ // Tangram
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) 2013-2016 Brett Camper and Mapzen
4
+
5
+ // Word wrapping
6
+
7
+ import { isTextRTL, isTextNeutral, RTL_MARKER } from './text_segments';
8
+
9
+ interface TextMeasurementContext {
10
+ measureText(text: string): {width: number};
11
+ }
12
+
13
+ // Private class to arrange text labels into multiple lines based on
14
+ // "text wrap" and "max line" values
15
+ export default class MultiLine {
16
+ static ellipsis: string;
17
+ width: number;
18
+ height: number;
19
+ lines: Line[];
20
+ max_lines: number;
21
+ text_wrap: number | boolean;
22
+ context: TextMeasurementContext;
23
+
24
+ constructor (context: TextMeasurementContext, max_lines = Infinity, text_wrap: number | boolean = Infinity) {
25
+ this.width = 0;
26
+ this.height = 0;
27
+ this.lines = [];
28
+
29
+ this.max_lines = max_lines;
30
+ this.text_wrap = text_wrap;
31
+ this.context = context;
32
+ }
33
+
34
+ createLine (line_height: number): Line | false {
35
+ if (this.lines.length < this.max_lines){
36
+ return new Line(line_height, this.text_wrap);
37
+ }
38
+ else {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ push (line: Line): boolean {
44
+ if (this.lines.length < this.max_lines){
45
+ // measure line width
46
+ let line_width = this.context.measureText(line.text).width;
47
+ line.width = line_width;
48
+
49
+ if (line_width > this.width){
50
+ this.width = Math.ceil(line_width);
51
+ }
52
+
53
+ // add to lines and increment height
54
+ this.lines.push(line);
55
+ this.height += line.height;
56
+ return true;
57
+ }
58
+ else {
59
+ this.addEllipsis();
60
+ return false;
61
+ }
62
+ }
63
+
64
+ // pushes to the lines array and returns a new line if possible (false otherwise)
65
+ advance (line: Line, line_height: number): Line | false {
66
+ let can_push = this.push(line);
67
+ if (can_push){
68
+ return this.createLine(line_height);
69
+ }
70
+ else {
71
+ return false;
72
+ }
73
+ }
74
+
75
+ addEllipsis (): void {
76
+ let last_line = this.lines[this.lines.length - 1];
77
+ let ellipsis_width = Math.ceil(this.context.measureText(MultiLine.ellipsis).width);
78
+
79
+ last_line.append(MultiLine.ellipsis);
80
+ last_line.width += ellipsis_width;
81
+
82
+ if (last_line.width > this.width) {
83
+ this.width = last_line.width;
84
+ }
85
+ }
86
+
87
+ finish (line: Line | false): void {
88
+ if (line){
89
+ this.push(line);
90
+ }
91
+ else {
92
+ this.addEllipsis();
93
+ }
94
+ }
95
+
96
+ static parse (
97
+ str: string,
98
+ text_wrap: boolean | number,
99
+ max_lines: number,
100
+ line_height: number,
101
+ ctx: TextMeasurementContext
102
+ ): MultiLine {
103
+ // Word wrapping
104
+ // Line breaks can be caused by:
105
+ // - implicit line break when a maximum character threshold is exceeded per line (text_wrap)
106
+ // - explicit line break in the label text (\n)
107
+ let words;
108
+ if (typeof text_wrap === 'number') {
109
+ words = str.split(' '); // split words on spaces
110
+ }
111
+ else {
112
+ words = [str]; // no max line word wrapping (but new lines will still be in effect)
113
+ }
114
+
115
+ let multiline = new MultiLine(ctx, max_lines, text_wrap);
116
+ let line = multiline.createLine(line_height);
117
+
118
+ // First iterate on space-break groups (will be one if max line length off), then iterate on line-break groups
119
+ for (let i = 0; i < words.length; i++) {
120
+ let breaks = words[i].split('\n'); // split on line breaks
121
+ let new_line = (i === 0) ? true : false;
122
+
123
+ for (let n=0; n < breaks.length; n++) {
124
+ if (!line){
125
+ break;
126
+ }
127
+
128
+ let word = breaks[n];
129
+
130
+ // force punctuation (neutral chars) at the end of a RTL line, so they stay attached to original word
131
+ if (isTextRTL(word) && isTextNeutral(word[word.length - 1])) {
132
+ word += RTL_MARKER;
133
+ }
134
+
135
+ let spaced_word = (new_line) ? word : ' ' + word;
136
+
137
+ // if adding current word would overflow, add a new line instead
138
+ // first word (i === 0) always appends
139
+ if (text_wrap && i > 0 && line.exceedsTextwrap(spaced_word)) {
140
+ line = multiline.advance(line, line_height);
141
+ if (!line){
142
+ break;
143
+ }
144
+ line.append(word);
145
+ new_line = true;
146
+ }
147
+ else {
148
+ line.append(spaced_word);
149
+ }
150
+
151
+ // if line breaks present, add new line (unless on last line)
152
+ if (n < breaks.length - 1) {
153
+ line = multiline.advance(line, line_height);
154
+ new_line = true;
155
+ }
156
+ }
157
+
158
+ if (i === words.length - 1){
159
+ multiline.finish(line);
160
+ }
161
+ }
162
+ return multiline;
163
+ }
164
+ }
165
+
166
+ MultiLine.ellipsis = '...';
167
+
168
+ // A Private class used by MultiLine to contain the logic for a single line
169
+ // including character count, width, height and text
170
+ class Line {
171
+ chars: number;
172
+ text: string;
173
+ width: number;
174
+ height: number;
175
+ text_wrap: number | boolean;
176
+
177
+ constructor (height = 0, text_wrap: number | boolean = 0){
178
+ this.chars = 0;
179
+ this.text = '';
180
+ this.width = 0;
181
+
182
+ this.height = Math.ceil(height);
183
+ this.text_wrap = text_wrap;
184
+ }
185
+
186
+ append (text: string): void {
187
+ this.chars += text.length;
188
+ this.text += text;
189
+ }
190
+
191
+ exceedsTextwrap (text: string): boolean {
192
+ return typeof this.text_wrap === 'number' && text.length + this.chars > this.text_wrap;
193
+ }
194
+ }
@@ -0,0 +1,40 @@
1
+ // tangram-layers
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {TileID, type TileCoordinate, type TileCoordinates, type TileSource} from './tile_id';
6
+ import Geo from '../utils/geo';
7
+
8
+ /** Enumerate one bounded global level, independent of camera or hemisphere. */
9
+ export function createGlobePreloadCoordinates(zoom: number): TileCoordinate[] {
10
+ if (!Number.isInteger(zoom) || zoom < 0 || zoom > 3) {
11
+ throw new Error('Globe preload zoom must be an integer from 0 to 3');
12
+ }
13
+ const coordinates: TileCoordinate[] = [];
14
+ for (let x = 0; x < 2 ** zoom; x++) {
15
+ for (let y = 0; y < 2 ** zoom; y++) coordinates.push(TileID.coord({x, y, z: zoom}));
16
+ }
17
+ return coordinates;
18
+ }
19
+
20
+ /** Resolve a coarse ancestor without expanding a source's minimum zoom into global high-detail requests. */
21
+ export function getGlobePreloadKey(coordinates: TileCoordinates, source: TileSource, styleZoom: number, zoom: number): string | undefined {
22
+ const normalized = TileID.normalizedCoord(TileID.coordAtZoom(coordinates, zoom), source);
23
+ if (normalized.z > zoom) return undefined;
24
+ return TileID.key(normalized, source, styleZoom);
25
+ }
26
+
27
+ /** Clip a fallback mesh in its local packed tile units to one missing detail tile. */
28
+ export function getGlobeFallbackClipBounds(parent: TileCoordinates, child: TileCoordinates): [number, number, number, number] {
29
+ const scale = 2 ** (child.z - parent.z);
30
+ const width = Geo.tile_scale / scale;
31
+ const horizontal = child.x - parent.x * scale;
32
+ const vertical = child.y - parent.y * scale;
33
+ return [horizontal * width, -(vertical + 1) * width, (horizontal + 1) * width, vertical === 0 ? 0 : -vertical * width];
34
+ }
35
+
36
+ /** Only surface geometry can be drawn as a clipped loading placeholder. */
37
+ export function isGlobeFallbackStyle(name: string, base?: string | null): boolean {
38
+ const style = base || name;
39
+ return style === 'polygons' || style === 'lines' || style === 'raster';
40
+ }