@mapwhit/tilerenderer 0.47.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 (356) hide show
  1. package/LICENSE.txt +87 -0
  2. package/README.md +25 -0
  3. package/build/min/.dir +0 -0
  4. package/build/min/package.json +3 -0
  5. package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
  6. package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
  7. package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
  8. package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
  9. package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
  10. package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
  11. package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
  12. package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
  13. package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
  14. package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
  15. package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
  16. package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
  17. package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
  18. package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
  19. package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
  20. package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
  21. package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
  22. package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
  23. package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
  24. package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
  25. package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
  26. package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
  27. package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
  28. package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
  29. package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
  30. package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
  31. package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
  32. package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
  33. package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
  34. package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
  35. package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
  36. package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
  37. package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
  38. package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
  39. package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
  40. package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
  41. package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
  42. package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
  43. package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
  44. package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
  45. package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
  46. package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
  47. package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
  48. package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
  49. package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
  50. package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
  51. package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
  52. package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
  53. package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
  54. package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
  55. package/package.json +44 -0
  56. package/src/css/mapbox-gl.css +506 -0
  57. package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
  58. package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
  59. package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
  60. package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
  61. package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
  62. package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
  63. package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
  64. package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
  65. package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
  66. package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
  67. package/src/data/array_types.js +1138 -0
  68. package/src/data/bucket/circle_attributes.js +5 -0
  69. package/src/data/bucket/circle_bucket.js +118 -0
  70. package/src/data/bucket/fill_attributes.js +5 -0
  71. package/src/data/bucket/fill_bucket.js +166 -0
  72. package/src/data/bucket/fill_extrusion_attributes.js +11 -0
  73. package/src/data/bucket/fill_extrusion_bucket.js +247 -0
  74. package/src/data/bucket/heatmap_bucket.js +12 -0
  75. package/src/data/bucket/line_attributes.js +11 -0
  76. package/src/data/bucket/line_bucket.js +625 -0
  77. package/src/data/bucket/pattern_attributes.js +9 -0
  78. package/src/data/bucket/pattern_bucket_features.js +44 -0
  79. package/src/data/bucket/symbol_attributes.js +95 -0
  80. package/src/data/bucket/symbol_bucket.js +697 -0
  81. package/src/data/bucket.js +53 -0
  82. package/src/data/dem_data.js +126 -0
  83. package/src/data/extent.js +17 -0
  84. package/src/data/feature_index.js +254 -0
  85. package/src/data/index_array_type.js +14 -0
  86. package/src/data/load_geometry.js +42 -0
  87. package/src/data/pos_attributes.js +3 -0
  88. package/src/data/program_configuration.js +782 -0
  89. package/src/data/raster_bounds_attributes.js +6 -0
  90. package/src/data/segment.js +63 -0
  91. package/src/geo/coordinate.js +78 -0
  92. package/src/geo/lng_lat.js +129 -0
  93. package/src/geo/lng_lat_bounds.js +253 -0
  94. package/src/geo/transform.js +605 -0
  95. package/src/gl/color_mode.js +21 -0
  96. package/src/gl/context.js +193 -0
  97. package/src/gl/cull_face_mode.js +22 -0
  98. package/src/gl/depth_mode.js +18 -0
  99. package/src/gl/framebuffer.js +28 -0
  100. package/src/gl/index_buffer.js +52 -0
  101. package/src/gl/stencil_mode.js +17 -0
  102. package/src/gl/types.js +0 -0
  103. package/src/gl/value.js +676 -0
  104. package/src/gl/vertex_buffer.js +101 -0
  105. package/src/index.js +50 -0
  106. package/src/render/draw_background.js +60 -0
  107. package/src/render/draw_circle.js +55 -0
  108. package/src/render/draw_collision_debug.js +45 -0
  109. package/src/render/draw_debug.js +429 -0
  110. package/src/render/draw_fill.js +143 -0
  111. package/src/render/draw_fill_extrusion.js +101 -0
  112. package/src/render/draw_heatmap.js +159 -0
  113. package/src/render/draw_hillshade.js +144 -0
  114. package/src/render/draw_line.js +99 -0
  115. package/src/render/draw_raster.js +151 -0
  116. package/src/render/draw_symbol.js +231 -0
  117. package/src/render/glyph_atlas.js +55 -0
  118. package/src/render/glyph_manager.js +145 -0
  119. package/src/render/image_atlas.js +97 -0
  120. package/src/render/image_manager.js +183 -0
  121. package/src/render/line_atlas.js +139 -0
  122. package/src/render/painter.js +483 -0
  123. package/src/render/program/background_program.js +46 -0
  124. package/src/render/program/circle_program.js +40 -0
  125. package/src/render/program/clipping_mask_program.js +11 -0
  126. package/src/render/program/collision_program.js +28 -0
  127. package/src/render/program/debug_program.js +13 -0
  128. package/src/render/program/fill_extrusion_program.js +76 -0
  129. package/src/render/program/fill_program.js +60 -0
  130. package/src/render/program/heatmap_program.js +46 -0
  131. package/src/render/program/hillshade_program.js +77 -0
  132. package/src/render/program/line_program.js +119 -0
  133. package/src/render/program/pattern.js +57 -0
  134. package/src/render/program/program_uniforms.js +46 -0
  135. package/src/render/program/raster_program.js +50 -0
  136. package/src/render/program/symbol_program.js +112 -0
  137. package/src/render/program.js +133 -0
  138. package/src/render/texture.js +88 -0
  139. package/src/render/tile_mask.js +108 -0
  140. package/src/render/uniform_binding.js +129 -0
  141. package/src/render/vertex_array_object.js +155 -0
  142. package/src/shaders/README.md +42 -0
  143. package/src/shaders/_prelude.fragment.glsl +17 -0
  144. package/src/shaders/_prelude.vertex.glsl +73 -0
  145. package/src/shaders/background.fragment.glsl +10 -0
  146. package/src/shaders/background.vertex.glsl +7 -0
  147. package/src/shaders/background_pattern.fragment.glsl +28 -0
  148. package/src/shaders/background_pattern.vertex.glsl +20 -0
  149. package/src/shaders/circle.fragment.glsl +39 -0
  150. package/src/shaders/circle.vertex.glsl +63 -0
  151. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  152. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  153. package/src/shaders/collision_box.fragment.glsl +21 -0
  154. package/src/shaders/collision_box.vertex.glsl +26 -0
  155. package/src/shaders/collision_circle.fragment.glsl +34 -0
  156. package/src/shaders/collision_circle.vertex.glsl +36 -0
  157. package/src/shaders/debug.fragment.glsl +5 -0
  158. package/src/shaders/debug.vertex.glsl +7 -0
  159. package/src/shaders/encode_attribute.js +19 -0
  160. package/src/shaders/fill.fragment.glsl +13 -0
  161. package/src/shaders/fill.vertex.glsl +13 -0
  162. package/src/shaders/fill_extrusion.fragment.glsl +16 -0
  163. package/src/shaders/fill_extrusion.vertex.glsl +66 -0
  164. package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
  165. package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
  166. package/src/shaders/fill_outline.fragment.glsl +17 -0
  167. package/src/shaders/fill_outline.vertex.glsl +17 -0
  168. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  169. package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
  170. package/src/shaders/fill_pattern.fragment.glsl +36 -0
  171. package/src/shaders/fill_pattern.vertex.glsl +36 -0
  172. package/src/shaders/heatmap.fragment.glsl +21 -0
  173. package/src/shaders/heatmap.vertex.glsl +53 -0
  174. package/src/shaders/heatmap_texture.fragment.glsl +14 -0
  175. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  176. package/src/shaders/hillshade.fragment.glsl +52 -0
  177. package/src/shaders/hillshade.vertex.glsl +11 -0
  178. package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
  179. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  180. package/src/shaders/index.js +194 -0
  181. package/src/shaders/line.fragment.glsl +28 -0
  182. package/src/shaders/line.vertex.glsl +84 -0
  183. package/src/shaders/line_gradient.fragment.glsl +34 -0
  184. package/src/shaders/line_gradient.vertex.glsl +84 -0
  185. package/src/shaders/line_pattern.fragment.glsl +69 -0
  186. package/src/shaders/line_pattern.vertex.glsl +88 -0
  187. package/src/shaders/line_sdf.fragment.glsl +44 -0
  188. package/src/shaders/line_sdf.vertex.glsl +95 -0
  189. package/src/shaders/raster.fragment.glsl +52 -0
  190. package/src/shaders/raster.vertex.glsl +21 -0
  191. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  192. package/src/shaders/symbol_icon.vertex.glsl +91 -0
  193. package/src/shaders/symbol_sdf.fragment.glsl +50 -0
  194. package/src/shaders/symbol_sdf.vertex.glsl +117 -0
  195. package/src/source/geojson_source.js +267 -0
  196. package/src/source/geojson_worker_source.js +210 -0
  197. package/src/source/geojson_wrapper.js +67 -0
  198. package/src/source/image_source.js +213 -0
  199. package/src/source/load_tilejson.js +40 -0
  200. package/src/source/pixels_to_tile_units.js +17 -0
  201. package/src/source/query_features.js +198 -0
  202. package/src/source/raster_dem_tile_source.js +140 -0
  203. package/src/source/raster_dem_tile_worker_source.js +26 -0
  204. package/src/source/raster_tile_source.js +126 -0
  205. package/src/source/rtl_text_plugin.js +63 -0
  206. package/src/source/source.js +75 -0
  207. package/src/source/source_cache.js +794 -0
  208. package/src/source/source_state.js +55 -0
  209. package/src/source/tile.js +332 -0
  210. package/src/source/tile_bounds.js +40 -0
  211. package/src/source/tile_cache.js +122 -0
  212. package/src/source/tile_id.js +150 -0
  213. package/src/source/vector_tile_source.js +144 -0
  214. package/src/source/vector_tile_worker_source.js +126 -0
  215. package/src/source/worker.js +175 -0
  216. package/src/source/worker_source.js +14 -0
  217. package/src/source/worker_tile.js +199 -0
  218. package/src/style/create_style_layer.js +25 -0
  219. package/src/style/evaluation_parameters.js +45 -0
  220. package/src/style/light.js +112 -0
  221. package/src/style/load_glyph_range.js +17 -0
  222. package/src/style/load_sprite.js +26 -0
  223. package/src/style/parse_glyph_pbf.js +45 -0
  224. package/src/style/pauseable_placement.js +88 -0
  225. package/src/style/properties.js +691 -0
  226. package/src/style/query_utils.js +39 -0
  227. package/src/style/style.js +955 -0
  228. package/src/style/style_layer/background_style_layer.js +11 -0
  229. package/src/style/style_layer/background_style_layer_properties.js +25 -0
  230. package/src/style/style_layer/circle_style_layer.js +93 -0
  231. package/src/style/style_layer/circle_style_layer_properties.js +76 -0
  232. package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
  233. package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
  234. package/src/style/style_layer/fill_style_layer.js +46 -0
  235. package/src/style/style_layer/fill_style_layer_properties.js +45 -0
  236. package/src/style/style_layer/heatmap_style_layer.js +51 -0
  237. package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
  238. package/src/style/style_layer/hillshade_style_layer.js +15 -0
  239. package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
  240. package/src/style/style_layer/line_style_layer.js +129 -0
  241. package/src/style/style_layer/line_style_layer_properties.js +104 -0
  242. package/src/style/style_layer/raster_style_layer.js +11 -0
  243. package/src/style/style_layer/raster_style_layer_properties.js +55 -0
  244. package/src/style/style_layer/symbol_style_layer.js +66 -0
  245. package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
  246. package/src/style/style_layer.js +183 -0
  247. package/src/style/style_layer_index.js +61 -0
  248. package/src/style/zoom_history.js +36 -0
  249. package/src/style-spec/deref.js +51 -0
  250. package/src/style-spec/error/parsing_error.js +8 -0
  251. package/src/style-spec/error/validation_error.js +10 -0
  252. package/src/style-spec/expression/compound_expression.js +118 -0
  253. package/src/style-spec/expression/definitions/array.js +82 -0
  254. package/src/style-spec/expression/definitions/assertion.js +69 -0
  255. package/src/style-spec/expression/definitions/at.js +57 -0
  256. package/src/style-spec/expression/definitions/case.js +73 -0
  257. package/src/style-spec/expression/definitions/coalesce.js +68 -0
  258. package/src/style-spec/expression/definitions/coercion.js +96 -0
  259. package/src/style-spec/expression/definitions/collator.js +102 -0
  260. package/src/style-spec/expression/definitions/equals.js +93 -0
  261. package/src/style-spec/expression/definitions/index.js +407 -0
  262. package/src/style-spec/expression/definitions/interpolate.js +235 -0
  263. package/src/style-spec/expression/definitions/length.js +54 -0
  264. package/src/style-spec/expression/definitions/let.js +60 -0
  265. package/src/style-spec/expression/definitions/literal.js +64 -0
  266. package/src/style-spec/expression/definitions/match.js +142 -0
  267. package/src/style-spec/expression/definitions/step.js +116 -0
  268. package/src/style-spec/expression/definitions/var.js +38 -0
  269. package/src/style-spec/expression/evaluation_context.js +35 -0
  270. package/src/style-spec/expression/index.js +329 -0
  271. package/src/style-spec/expression/is_constant.js +63 -0
  272. package/src/style-spec/expression/parsing_context.js +213 -0
  273. package/src/style-spec/expression/parsing_error.js +9 -0
  274. package/src/style-spec/expression/runtime_error.js +12 -0
  275. package/src/style-spec/expression/scope.js +34 -0
  276. package/src/style-spec/expression/stops.js +37 -0
  277. package/src/style-spec/expression/types.js +77 -0
  278. package/src/style-spec/expression/values.js +126 -0
  279. package/src/style-spec/feature_filter/README.md +55 -0
  280. package/src/style-spec/feature_filter/index.js +158 -0
  281. package/src/style-spec/function/convert.js +256 -0
  282. package/src/style-spec/function/index.js +299 -0
  283. package/src/style-spec/group_by_layout.js +68 -0
  284. package/src/style-spec/reference/v8.json +5356 -0
  285. package/src/style-spec/util/color.js +73 -0
  286. package/src/style-spec/util/color_spaces.js +128 -0
  287. package/src/style-spec/util/eval_support.js +8 -0
  288. package/src/style-spec/util/get_type.js +18 -0
  289. package/src/style-spec/util/interpolate.js +21 -0
  290. package/src/style-spec/util/properties.js +17 -0
  291. package/src/style-spec/util/ref_properties.js +1 -0
  292. package/src/style-spec/util/result.js +19 -0
  293. package/src/symbol/anchor.js +21 -0
  294. package/src/symbol/check_max_angle.js +75 -0
  295. package/src/symbol/clip_line.js +73 -0
  296. package/src/symbol/collision_feature.js +230 -0
  297. package/src/symbol/collision_index.js +379 -0
  298. package/src/symbol/cross_tile_symbol_index.js +270 -0
  299. package/src/symbol/get_anchors.js +177 -0
  300. package/src/symbol/grid_index.js +318 -0
  301. package/src/symbol/mergelines.js +75 -0
  302. package/src/symbol/opacity_state.js +21 -0
  303. package/src/symbol/placement.js +563 -0
  304. package/src/symbol/projection.js +601 -0
  305. package/src/symbol/quads.js +173 -0
  306. package/src/symbol/shaping.js +347 -0
  307. package/src/symbol/symbol_layout.js +519 -0
  308. package/src/symbol/symbol_size.js +110 -0
  309. package/src/symbol/transform_text.js +16 -0
  310. package/src/ui/anchor.js +24 -0
  311. package/src/ui/bind_handlers.js +199 -0
  312. package/src/ui/camera.js +954 -0
  313. package/src/ui/events.js +210 -0
  314. package/src/ui/handler/box_zoom.js +151 -0
  315. package/src/ui/handler/dblclick_zoom.js +91 -0
  316. package/src/ui/handler/drag_pan.js +285 -0
  317. package/src/ui/handler/drag_rotate.js +290 -0
  318. package/src/ui/handler/frame.js +28 -0
  319. package/src/ui/handler/inertia.js +45 -0
  320. package/src/ui/handler/keyboard.js +148 -0
  321. package/src/ui/handler/scroll_zoom.js +284 -0
  322. package/src/ui/handler/touch_zoom_rotate.js +263 -0
  323. package/src/ui/map.js +1645 -0
  324. package/src/util/actor.js +104 -0
  325. package/src/util/async.js +23 -0
  326. package/src/util/browser.js +61 -0
  327. package/src/util/callback.js +26 -0
  328. package/src/util/classify_rings.js +43 -0
  329. package/src/util/color_ramp.js +24 -0
  330. package/src/util/config.js +24 -0
  331. package/src/util/dictionary_coder.js +25 -0
  332. package/src/util/dispatcher.js +68 -0
  333. package/src/util/dom.js +102 -0
  334. package/src/util/evented.js +182 -0
  335. package/src/util/find_pole_of_inaccessibility.js +129 -0
  336. package/src/util/global_worker_pool.js +15 -0
  337. package/src/util/image.js +124 -0
  338. package/src/util/interpolate.js +5 -0
  339. package/src/util/intersection_tests.js +207 -0
  340. package/src/util/is_char_in_unicode_block.js +287 -0
  341. package/src/util/loader/image.js +32 -0
  342. package/src/util/object.js +178 -0
  343. package/src/util/script_detection.js +337 -0
  344. package/src/util/struct_array.js +197 -0
  345. package/src/util/task_queue.js +57 -0
  346. package/src/util/throttle.js +26 -0
  347. package/src/util/tile_cover.js +114 -0
  348. package/src/util/token.js +13 -0
  349. package/src/util/unique_id.js +12 -0
  350. package/src/util/util.js +192 -0
  351. package/src/util/vectortile_to_geojson.js +44 -0
  352. package/src/util/verticalize_punctuation.js +112 -0
  353. package/src/util/warn.js +21 -0
  354. package/src/util/web_worker.js +5 -0
  355. package/src/util/web_worker_transfer.js +228 -0
  356. package/src/util/worker_pool.js +41 -0
@@ -0,0 +1,173 @@
1
+ const Point = require('@mapbox/point-geometry');
2
+
3
+ const { GLYPH_PBF_BORDER } = require('../style/parse_glyph_pbf');
4
+
5
+ /**
6
+ * A textured quad for rendering a single icon or glyph.
7
+ *
8
+ * The zoom range the glyph can be shown is defined by minScale and maxScale.
9
+ *
10
+ * @param tl The offset of the top left corner from the anchor.
11
+ * @param tr The offset of the top right corner from the anchor.
12
+ * @param bl The offset of the bottom left corner from the anchor.
13
+ * @param br The offset of the bottom right corner from the anchor.
14
+ * @param tex The texture coordinates.
15
+ *
16
+ * @private
17
+ */
18
+
19
+ /**
20
+ * Create the quads used for rendering an icon.
21
+ * @private
22
+ */
23
+ function getIconQuads(anchor, shapedIcon, layer, alongLine, shapedText, feature) {
24
+ const image = shapedIcon.image;
25
+ const layout = layer.layout;
26
+
27
+ // If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual
28
+ // pixels. The quad needs to be padded to account for this, otherwise they'll look slightly clipped
29
+ // on one edge in some cases.
30
+ const border = 1;
31
+
32
+ const top = shapedIcon.top - border / image.pixelRatio;
33
+ const left = shapedIcon.left - border / image.pixelRatio;
34
+ const bottom = shapedIcon.bottom + border / image.pixelRatio;
35
+ const right = shapedIcon.right + border / image.pixelRatio;
36
+ let tl;
37
+ let tr;
38
+ let br;
39
+ let bl;
40
+
41
+ // text-fit mode
42
+ if (layout.get('icon-text-fit') !== 'none' && shapedText) {
43
+ const iconWidth = right - left;
44
+ const iconHeight = bottom - top;
45
+ const size = layout.get('text-size').evaluate(feature, {}) / 24;
46
+ const textLeft = shapedText.left * size;
47
+ const textRight = shapedText.right * size;
48
+ const textTop = shapedText.top * size;
49
+ const textBottom = shapedText.bottom * size;
50
+ const textWidth = textRight - textLeft;
51
+ const textHeight = textBottom - textTop;
52
+ const padT = layout.get('icon-text-fit-padding')[0];
53
+ const padR = layout.get('icon-text-fit-padding')[1];
54
+ const padB = layout.get('icon-text-fit-padding')[2];
55
+ const padL = layout.get('icon-text-fit-padding')[3];
56
+ const offsetY = layout.get('icon-text-fit') === 'width' ? (textHeight - iconHeight) * 0.5 : 0;
57
+ const offsetX = layout.get('icon-text-fit') === 'height' ? (textWidth - iconWidth) * 0.5 : 0;
58
+ const width =
59
+ layout.get('icon-text-fit') === 'width' || layout.get('icon-text-fit') === 'both' ? textWidth : iconWidth;
60
+ const height =
61
+ layout.get('icon-text-fit') === 'height' || layout.get('icon-text-fit') === 'both' ? textHeight : iconHeight;
62
+ tl = new Point(textLeft + offsetX - padL, textTop + offsetY - padT);
63
+ tr = new Point(textLeft + offsetX + padR + width, textTop + offsetY - padT);
64
+ br = new Point(textLeft + offsetX + padR + width, textTop + offsetY + padB + height);
65
+ bl = new Point(textLeft + offsetX - padL, textTop + offsetY + padB + height);
66
+ // Normal icon size mode
67
+ } else {
68
+ tl = new Point(left, top);
69
+ tr = new Point(right, top);
70
+ br = new Point(right, bottom);
71
+ bl = new Point(left, bottom);
72
+ }
73
+
74
+ const angle = (layer.layout.get('icon-rotate').evaluate(feature, {}) * Math.PI) / 180;
75
+
76
+ if (angle) {
77
+ const sin = Math.sin(angle);
78
+ const cos = Math.cos(angle);
79
+ const matrix = [cos, -sin, sin, cos];
80
+
81
+ tl._matMult(matrix);
82
+ tr._matMult(matrix);
83
+ bl._matMult(matrix);
84
+ br._matMult(matrix);
85
+ }
86
+
87
+ // Icon quad is padded, so texture coordinates also need to be padded.
88
+ return [{ tl, tr, bl, br, tex: image.paddedRect, writingMode: undefined, glyphOffset: [0, 0] }];
89
+ }
90
+
91
+ /**
92
+ * Create the quads used for rendering a text label.
93
+ * @private
94
+ */
95
+ function getGlyphQuads(anchor, shaping, layer, alongLine, feature, positions) {
96
+ const oneEm = 24;
97
+ const textRotate = (layer.layout.get('text-rotate').evaluate(feature, {}) * Math.PI) / 180;
98
+ const textOffset = layer.layout
99
+ .get('text-offset')
100
+ .evaluate(feature, {})
101
+ .map(t => t * oneEm);
102
+
103
+ const positionedGlyphs = shaping.positionedGlyphs;
104
+ const quads = [];
105
+
106
+ for (let k = 0; k < positionedGlyphs.length; k++) {
107
+ const positionedGlyph = positionedGlyphs[k];
108
+ const glyph = positions[positionedGlyph.glyph];
109
+ if (!glyph) continue;
110
+
111
+ const rect = glyph.rect;
112
+ if (!rect) continue;
113
+
114
+ // The rects have an addditional buffer that is not included in their size.
115
+ const glyphPadding = 1.0;
116
+ const rectBuffer = GLYPH_PBF_BORDER + glyphPadding;
117
+
118
+ const halfAdvance = glyph.metrics.advance / 2;
119
+
120
+ const glyphOffset = alongLine ? [positionedGlyph.x + halfAdvance, positionedGlyph.y] : [0, 0];
121
+
122
+ const builtInOffset = alongLine
123
+ ? [0, 0]
124
+ : [positionedGlyph.x + halfAdvance + textOffset[0], positionedGlyph.y + textOffset[1]];
125
+
126
+ const x1 = glyph.metrics.left - rectBuffer - halfAdvance + builtInOffset[0];
127
+ const y1 = -glyph.metrics.top - rectBuffer + builtInOffset[1];
128
+ const x2 = x1 + rect.w;
129
+ const y2 = y1 + rect.h;
130
+
131
+ const tl = new Point(x1, y1);
132
+ const tr = new Point(x2, y1);
133
+ const bl = new Point(x1, y2);
134
+ const br = new Point(x2, y2);
135
+
136
+ if (alongLine && positionedGlyph.vertical) {
137
+ // Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em)
138
+ // In horizontal orientation, the y values for glyphs are below the midline
139
+ // and we use a "yOffset" of -17 to pull them up to the middle.
140
+ // By rotating counter-clockwise around the point at the center of the left
141
+ // edge of a 24x24 layout box centered below the midline, we align the center
142
+ // of the glyphs with the horizontal midline, so the yOffset is no longer
143
+ // necessary, but we also pull the glyph to the left along the x axis
144
+ const center = new Point(-halfAdvance, halfAdvance);
145
+ const verticalRotation = -Math.PI / 2;
146
+ const xOffsetCorrection = new Point(5, 0);
147
+ tl._rotateAround(verticalRotation, center)._add(xOffsetCorrection);
148
+ tr._rotateAround(verticalRotation, center)._add(xOffsetCorrection);
149
+ bl._rotateAround(verticalRotation, center)._add(xOffsetCorrection);
150
+ br._rotateAround(verticalRotation, center)._add(xOffsetCorrection);
151
+ }
152
+
153
+ if (textRotate) {
154
+ const sin = Math.sin(textRotate);
155
+ const cos = Math.cos(textRotate);
156
+ const matrix = [cos, -sin, sin, cos];
157
+
158
+ tl._matMult(matrix);
159
+ tr._matMult(matrix);
160
+ bl._matMult(matrix);
161
+ br._matMult(matrix);
162
+ }
163
+
164
+ quads.push({ tl, tr, bl, br, tex: rect, writingMode: shaping.writingMode, glyphOffset });
165
+ }
166
+
167
+ return quads;
168
+ }
169
+
170
+ module.exports = {
171
+ getIconQuads,
172
+ getGlyphQuads
173
+ };
@@ -0,0 +1,347 @@
1
+ const { charHasUprightVerticalOrientation, charAllowsIdeographicBreaking } = require('../util/script_detection');
2
+ const verticalizePunctuation = require('../util/verticalize_punctuation');
3
+ const { plugin: rtlTextPlugin } = require('../source/rtl_text_plugin');
4
+
5
+ const WritingMode = {
6
+ horizontal: 1,
7
+ vertical: 2,
8
+ horizontalOnly: 3
9
+ };
10
+
11
+ module.exports = {
12
+ shapeText,
13
+ shapeIcon,
14
+ WritingMode
15
+ };
16
+
17
+ // The position of a glyph relative to the text's anchor point.
18
+
19
+ // A collection of positioned glyphs and some metadata
20
+
21
+ function breakLines(text, lineBreakPoints) {
22
+ const lines = [];
23
+ let start = 0;
24
+ for (const lineBreak of lineBreakPoints) {
25
+ lines.push(text.substring(start, lineBreak));
26
+ start = lineBreak;
27
+ }
28
+
29
+ if (start < text.length) {
30
+ lines.push(text.substring(start, text.length));
31
+ }
32
+ return lines;
33
+ }
34
+
35
+ function shapeText(
36
+ text,
37
+ glyphs,
38
+ maxWidth,
39
+ lineHeight,
40
+ textAnchor,
41
+ textJustify,
42
+ spacing,
43
+ translate,
44
+ verticalHeight,
45
+ writingMode
46
+ ) {
47
+ let logicalInput = text.trim();
48
+ if (writingMode === WritingMode.vertical) {
49
+ logicalInput = verticalizePunctuation(logicalInput);
50
+ }
51
+
52
+ const positionedGlyphs = [];
53
+ const shaping = {
54
+ positionedGlyphs,
55
+ text: logicalInput,
56
+ top: translate[1],
57
+ bottom: translate[1],
58
+ left: translate[0],
59
+ right: translate[0],
60
+ writingMode
61
+ };
62
+
63
+ let lines;
64
+
65
+ const { processBidirectionalText } = rtlTextPlugin;
66
+ if (processBidirectionalText) {
67
+ lines = processBidirectionalText(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphs));
68
+ } else {
69
+ lines = breakLines(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphs));
70
+ }
71
+
72
+ shapeLines(shaping, glyphs, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, verticalHeight);
73
+
74
+ if (!positionedGlyphs.length) return false;
75
+
76
+ return shaping;
77
+ }
78
+
79
+ const whitespace = {
80
+ [0x09]: true, // tab
81
+ [0x0a]: true, // newline
82
+ [0x0b]: true, // vertical tab
83
+ [0x0c]: true, // form feed
84
+ [0x0d]: true, // carriage return
85
+ [0x20]: true // space
86
+ };
87
+
88
+ const breakable = {
89
+ [0x0a]: true, // newline
90
+ [0x20]: true, // space
91
+ [0x26]: true, // ampersand
92
+ [0x28]: true, // left parenthesis
93
+ [0x29]: true, // right parenthesis
94
+ [0x2b]: true, // plus sign
95
+ [0x2d]: true, // hyphen-minus
96
+ [0x2f]: true, // solidus
97
+ [0xad]: true, // soft hyphen
98
+ [0xb7]: true, // middle dot
99
+ [0x200b]: true, // zero-width space
100
+ [0x2010]: true, // hyphen
101
+ [0x2013]: true, // en dash
102
+ [0x2027]: true // interpunct
103
+ // Many other characters may be reasonable breakpoints
104
+ // Consider "neutral orientation" characters at scriptDetection.charHasNeutralVerticalOrientation
105
+ // See https://github.com/mapbox/mapbox-gl-js/issues/3658
106
+ };
107
+
108
+ function determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphs) {
109
+ let totalWidth = 0;
110
+
111
+ for (let index = 0; index < logicalInput.length; index++) {
112
+ const glyph = glyphs[logicalInput.charCodeAt(index)];
113
+ if (!glyph) continue;
114
+ totalWidth += glyph.metrics.advance + spacing;
115
+ }
116
+
117
+ const lineCount = Math.max(1, Math.ceil(totalWidth / maxWidth));
118
+ return totalWidth / lineCount;
119
+ }
120
+
121
+ function calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) {
122
+ const raggedness = (lineWidth - targetWidth) ** 2;
123
+ if (isLastBreak) {
124
+ // Favor finals lines shorter than average over longer than average
125
+ if (lineWidth < targetWidth) {
126
+ return raggedness / 2;
127
+ }
128
+ return raggedness * 2;
129
+ }
130
+
131
+ return raggedness + Math.abs(penalty) * penalty;
132
+ }
133
+
134
+ function calculatePenalty(codePoint, nextCodePoint) {
135
+ let penalty = 0;
136
+ // Force break on newline
137
+ if (codePoint === 0x0a) {
138
+ penalty -= 10000;
139
+ }
140
+ // Penalize open parenthesis at end of line
141
+ if (codePoint === 0x28 || codePoint === 0xff08) {
142
+ penalty += 50;
143
+ }
144
+
145
+ // Penalize close parenthesis at beginning of line
146
+ if (nextCodePoint === 0x29 || nextCodePoint === 0xff09) {
147
+ penalty += 50;
148
+ }
149
+ return penalty;
150
+ }
151
+
152
+ function evaluateBreak(breakIndex, breakX, targetWidth, potentialBreaks, penalty, isLastBreak) {
153
+ // We could skip evaluating breaks where the line length (breakX - priorBreak.x) > maxWidth
154
+ // ...but in fact we allow lines longer than maxWidth (if there's no break points)
155
+ // ...and when targetWidth and maxWidth are close, strictly enforcing maxWidth can give
156
+ // more lopsided results.
157
+
158
+ let bestPriorBreak = null;
159
+ let bestBreakBadness = calculateBadness(breakX, targetWidth, penalty, isLastBreak);
160
+
161
+ for (const potentialBreak of potentialBreaks) {
162
+ const lineWidth = breakX - potentialBreak.x;
163
+ const breakBadness = calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) + potentialBreak.badness;
164
+ if (breakBadness <= bestBreakBadness) {
165
+ bestPriorBreak = potentialBreak;
166
+ bestBreakBadness = breakBadness;
167
+ }
168
+ }
169
+
170
+ return {
171
+ index: breakIndex,
172
+ x: breakX,
173
+ priorBreak: bestPriorBreak,
174
+ badness: bestBreakBadness
175
+ };
176
+ }
177
+
178
+ function leastBadBreaks(lastLineBreak) {
179
+ if (!lastLineBreak) {
180
+ return [];
181
+ }
182
+ return leastBadBreaks(lastLineBreak.priorBreak).concat(lastLineBreak.index);
183
+ }
184
+
185
+ function determineLineBreaks(logicalInput, spacing, maxWidth, glyphs) {
186
+ if (!maxWidth) return [];
187
+
188
+ if (!logicalInput) return [];
189
+
190
+ const potentialLineBreaks = [];
191
+ const targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphs);
192
+
193
+ let currentX = 0;
194
+
195
+ for (let i = 0; i < logicalInput.length; i++) {
196
+ const codePoint = logicalInput.charCodeAt(i);
197
+ const glyph = glyphs[codePoint];
198
+
199
+ if (glyph && !whitespace[codePoint]) currentX += glyph.metrics.advance + spacing;
200
+
201
+ // Ideographic characters, spaces, and word-breaking punctuation that often appear without
202
+ // surrounding spaces.
203
+ if (i < logicalInput.length - 1 && (breakable[codePoint] || charAllowsIdeographicBreaking(codePoint))) {
204
+ potentialLineBreaks.push(
205
+ evaluateBreak(
206
+ i + 1,
207
+ currentX,
208
+ targetWidth,
209
+ potentialLineBreaks,
210
+ calculatePenalty(codePoint, logicalInput.charCodeAt(i + 1)),
211
+ false
212
+ )
213
+ );
214
+ }
215
+ }
216
+
217
+ return leastBadBreaks(evaluateBreak(logicalInput.length, currentX, targetWidth, potentialLineBreaks, 0, true));
218
+ }
219
+
220
+ function getAnchorAlignment(anchor) {
221
+ let horizontalAlign = 0.5;
222
+ let verticalAlign = 0.5;
223
+
224
+ switch (anchor) {
225
+ case 'right':
226
+ case 'top-right':
227
+ case 'bottom-right':
228
+ horizontalAlign = 1;
229
+ break;
230
+ case 'left':
231
+ case 'top-left':
232
+ case 'bottom-left':
233
+ horizontalAlign = 0;
234
+ break;
235
+ }
236
+
237
+ switch (anchor) {
238
+ case 'bottom':
239
+ case 'bottom-right':
240
+ case 'bottom-left':
241
+ verticalAlign = 1;
242
+ break;
243
+ case 'top':
244
+ case 'top-right':
245
+ case 'top-left':
246
+ verticalAlign = 0;
247
+ break;
248
+ }
249
+
250
+ return { horizontalAlign, verticalAlign };
251
+ }
252
+
253
+ function shapeLines(shaping, glyphs, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, verticalHeight) {
254
+ // the y offset *should* be part of the font metadata
255
+ const yOffset = -17;
256
+
257
+ let x = 0;
258
+ let y = yOffset;
259
+
260
+ let maxLineLength = 0;
261
+ const positionedGlyphs = shaping.positionedGlyphs;
262
+
263
+ const justify = textJustify === 'right' ? 1 : textJustify === 'left' ? 0 : 0.5;
264
+
265
+ for (let line of lines) {
266
+ line = line.trim();
267
+
268
+ if (!line.length) {
269
+ y += lineHeight; // Still need a line feed after empty line
270
+ continue;
271
+ }
272
+
273
+ const lineStartIndex = positionedGlyphs.length;
274
+ for (let i = 0; i < line.length; i++) {
275
+ const codePoint = line.charCodeAt(i);
276
+ const glyph = glyphs[codePoint];
277
+
278
+ if (!glyph) continue;
279
+
280
+ if (!charHasUprightVerticalOrientation(codePoint) || writingMode === WritingMode.horizontal) {
281
+ positionedGlyphs.push({ glyph: codePoint, x, y, vertical: false });
282
+ x += glyph.metrics.advance + spacing;
283
+ } else {
284
+ positionedGlyphs.push({ glyph: codePoint, x, y: 0, vertical: true });
285
+ x += verticalHeight + spacing;
286
+ }
287
+ }
288
+
289
+ // Only justify if we placed at least one glyph
290
+ if (positionedGlyphs.length !== lineStartIndex) {
291
+ const lineLength = x - spacing;
292
+ maxLineLength = Math.max(lineLength, maxLineLength);
293
+
294
+ justifyLine(positionedGlyphs, glyphs, lineStartIndex, positionedGlyphs.length - 1, justify);
295
+ }
296
+
297
+ x = 0;
298
+ y += lineHeight;
299
+ }
300
+
301
+ const { horizontalAlign, verticalAlign } = getAnchorAlignment(textAnchor);
302
+ align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, lines.length);
303
+
304
+ // Calculate the bounding box
305
+ const height = lines.length * lineHeight;
306
+
307
+ shaping.top += -verticalAlign * height;
308
+ shaping.bottom = shaping.top + height;
309
+ shaping.left += -horizontalAlign * maxLineLength;
310
+ shaping.right = shaping.left + maxLineLength;
311
+ }
312
+
313
+ // justify right = 1, left = 0, center = 0.5
314
+ function justifyLine(positionedGlyphs, glyphs, start, end, justify) {
315
+ if (!justify) return;
316
+
317
+ const glyph = glyphs[positionedGlyphs[end].glyph];
318
+ if (glyph) {
319
+ const lastAdvance = glyph.metrics.advance;
320
+ const lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify;
321
+
322
+ for (let j = start; j <= end; j++) {
323
+ positionedGlyphs[j].x -= lineIndent;
324
+ }
325
+ }
326
+ }
327
+
328
+ function align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, lineCount) {
329
+ const shiftX = (justify - horizontalAlign) * maxLineLength;
330
+ const shiftY = (-verticalAlign * lineCount + 0.5) * lineHeight;
331
+
332
+ for (let j = 0; j < positionedGlyphs.length; j++) {
333
+ positionedGlyphs[j].x += shiftX;
334
+ positionedGlyphs[j].y += shiftY;
335
+ }
336
+ }
337
+
338
+ function shapeIcon(image, iconOffset, iconAnchor) {
339
+ const { horizontalAlign, verticalAlign } = getAnchorAlignment(iconAnchor);
340
+ const dx = iconOffset[0];
341
+ const dy = iconOffset[1];
342
+ const x1 = dx - image.displaySize[0] * horizontalAlign;
343
+ const x2 = x1 + image.displaySize[0];
344
+ const y1 = dy - image.displaySize[1] * verticalAlign;
345
+ const y2 = y1 + image.displaySize[1];
346
+ return { image, top: y1, bottom: y2, left: x1, right: x2 };
347
+ }