mapbox-gl 1.13.2

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 (460) hide show
  1. package/.flowconfig +61 -0
  2. package/CHANGELOG.md +2485 -0
  3. package/LICENSE.txt +84 -0
  4. package/README.md +34 -0
  5. package/build/banner.js +4 -0
  6. package/build/check-bundle-size.js +140 -0
  7. package/build/diff-tarball.js +18 -0
  8. package/build/generate-access-token-script.js +11 -0
  9. package/build/generate-flow-typed-style-spec.js +188 -0
  10. package/build/generate-release-list.js +21 -0
  11. package/build/generate-struct-arrays.js +243 -0
  12. package/build/generate-style-code.js +159 -0
  13. package/build/mapbox-gl.js.flow +3 -0
  14. package/build/print-release-url.js +6 -0
  15. package/build/rollup_plugin_minify_style_spec.js +24 -0
  16. package/build/rollup_plugins.js +80 -0
  17. package/build/run-node +3 -0
  18. package/build/run-tap +8 -0
  19. package/build/test/build-tape.js +19 -0
  20. package/dist/mapbox-gl-csp-worker.js +2 -0
  21. package/dist/mapbox-gl-csp-worker.js.map +1 -0
  22. package/dist/mapbox-gl-csp.js +2 -0
  23. package/dist/mapbox-gl-csp.js.map +1 -0
  24. package/dist/mapbox-gl-dev.js +65889 -0
  25. package/dist/mapbox-gl-dev.js.flow +3 -0
  26. package/dist/mapbox-gl-unminified.js +42889 -0
  27. package/dist/mapbox-gl-unminified.js.map +1 -0
  28. package/dist/mapbox-gl.css +1 -0
  29. package/dist/mapbox-gl.js +42 -0
  30. package/dist/mapbox-gl.js.flow +3 -0
  31. package/dist/mapbox-gl.js.map +1 -0
  32. package/dist/style-spec/index.es.js +15032 -0
  33. package/dist/style-spec/index.es.js.map +1 -0
  34. package/dist/style-spec/index.js +15058 -0
  35. package/dist/style-spec/index.js.map +1 -0
  36. package/flow-typed/gl.js +5 -0
  37. package/flow-typed/jsdom.js +18 -0
  38. package/flow-typed/mapbox-gl-supported.js +9 -0
  39. package/flow-typed/mapbox-unitbezier.js +14 -0
  40. package/flow-typed/offscreen-canvas.js +9 -0
  41. package/flow-typed/pbf.js +25 -0
  42. package/flow-typed/point-geometry.js +44 -0
  43. package/flow-typed/potpack.js +12 -0
  44. package/flow-typed/sinon.js +28 -0
  45. package/flow-typed/vector-tile.js +41 -0
  46. package/package.json +173 -0
  47. package/src/css/mapbox-gl.css +812 -0
  48. package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
  49. package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
  50. package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
  51. package/src/css/svg/mapboxgl-ctrl-geolocate.svg +5 -0
  52. package/src/css/svg/mapboxgl-ctrl-logo.svg +20 -0
  53. package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
  54. package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
  55. package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
  56. package/src/data/array_types.js +1135 -0
  57. package/src/data/bucket/circle_attributes.js +9 -0
  58. package/src/data/bucket/circle_bucket.js +201 -0
  59. package/src/data/bucket/fill_attributes.js +9 -0
  60. package/src/data/bucket/fill_bucket.js +229 -0
  61. package/src/data/bucket/fill_extrusion_attributes.js +10 -0
  62. package/src/data/bucket/fill_extrusion_bucket.js +283 -0
  63. package/src/data/bucket/heatmap_bucket.js +17 -0
  64. package/src/data/bucket/line_attributes.js +10 -0
  65. package/src/data/bucket/line_attributes_ext.js +10 -0
  66. package/src/data/bucket/line_bucket.js +594 -0
  67. package/src/data/bucket/pattern_attributes.js +12 -0
  68. package/src/data/bucket/pattern_bucket_features.js +60 -0
  69. package/src/data/bucket/symbol_attributes.js +117 -0
  70. package/src/data/bucket/symbol_bucket.js +937 -0
  71. package/src/data/bucket.js +123 -0
  72. package/src/data/dem_data.js +125 -0
  73. package/src/data/evaluation_feature.js +25 -0
  74. package/src/data/extent.js +18 -0
  75. package/src/data/feature_index.js +322 -0
  76. package/src/data/feature_position_map.js +131 -0
  77. package/src/data/index_array_type.js +16 -0
  78. package/src/data/load_geometry.js +46 -0
  79. package/src/data/pos_attributes.js +6 -0
  80. package/src/data/program_configuration.js +708 -0
  81. package/src/data/raster_bounds_attributes.js +7 -0
  82. package/src/data/segment.js +76 -0
  83. package/src/geo/edge_insets.js +102 -0
  84. package/src/geo/lng_lat.js +168 -0
  85. package/src/geo/lng_lat_bounds.js +276 -0
  86. package/src/geo/mercator_coordinate.js +150 -0
  87. package/src/geo/transform.js +834 -0
  88. package/src/gl/color_mode.js +34 -0
  89. package/src/gl/context.js +302 -0
  90. package/src/gl/cull_face_mode.js +26 -0
  91. package/src/gl/depth_mode.js +29 -0
  92. package/src/gl/framebuffer.js +44 -0
  93. package/src/gl/index_buffer.js +55 -0
  94. package/src/gl/stencil_mode.js +30 -0
  95. package/src/gl/types.js +84 -0
  96. package/src/gl/value.js +520 -0
  97. package/src/gl/vertex_buffer.js +119 -0
  98. package/src/index.js +230 -0
  99. package/src/render/draw_background.js +57 -0
  100. package/src/render/draw_circle.js +113 -0
  101. package/src/render/draw_collision_debug.js +172 -0
  102. package/src/render/draw_custom.js +49 -0
  103. package/src/render/draw_debug.js +127 -0
  104. package/src/render/draw_fill.js +124 -0
  105. package/src/render/draw_fill_extrusion.js +95 -0
  106. package/src/render/draw_heatmap.js +133 -0
  107. package/src/render/draw_hillshade.js +107 -0
  108. package/src/render/draw_line.js +125 -0
  109. package/src/render/draw_raster.js +125 -0
  110. package/src/render/draw_symbol.js +392 -0
  111. package/src/render/glyph_atlas.js +71 -0
  112. package/src/render/glyph_manager.js +182 -0
  113. package/src/render/image_atlas.js +149 -0
  114. package/src/render/image_manager.js +306 -0
  115. package/src/render/line_atlas.js +210 -0
  116. package/src/render/painter.js +654 -0
  117. package/src/render/program/background_program.js +103 -0
  118. package/src/render/program/circle_program.js +69 -0
  119. package/src/render/program/clipping_mask_program.js +20 -0
  120. package/src/render/program/collision_program.js +76 -0
  121. package/src/render/program/debug_program.js +35 -0
  122. package/src/render/program/fill_extrusion_program.js +122 -0
  123. package/src/render/program/fill_program.js +126 -0
  124. package/src/render/program/heatmap_program.js +83 -0
  125. package/src/render/program/hillshade_program.js +119 -0
  126. package/src/render/program/line_program.js +211 -0
  127. package/src/render/program/pattern.js +102 -0
  128. package/src/render/program/program_uniforms.js +42 -0
  129. package/src/render/program/raster_program.js +92 -0
  130. package/src/render/program/symbol_program.js +224 -0
  131. package/src/render/program.js +188 -0
  132. package/src/render/texture.js +122 -0
  133. package/src/render/uniform_binding.js +147 -0
  134. package/src/render/vertex_array_object.js +163 -0
  135. package/src/shaders/README.md +42 -0
  136. package/src/shaders/_prelude.fragment.glsl +17 -0
  137. package/src/shaders/_prelude.vertex.glsl +73 -0
  138. package/src/shaders/background.fragment.glsl +10 -0
  139. package/src/shaders/background.vertex.glsl +7 -0
  140. package/src/shaders/background_pattern.fragment.glsl +28 -0
  141. package/src/shaders/background_pattern.vertex.glsl +20 -0
  142. package/src/shaders/circle.fragment.glsl +39 -0
  143. package/src/shaders/circle.vertex.glsl +64 -0
  144. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  145. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  146. package/src/shaders/collision_box.fragment.glsl +21 -0
  147. package/src/shaders/collision_box.vertex.glsl +27 -0
  148. package/src/shaders/collision_circle.fragment.glsl +17 -0
  149. package/src/shaders/collision_circle.vertex.glsl +59 -0
  150. package/src/shaders/debug.fragment.glsl +9 -0
  151. package/src/shaders/debug.vertex.glsl +12 -0
  152. package/src/shaders/encode_attribute.js +17 -0
  153. package/src/shaders/fill.fragment.glsl +13 -0
  154. package/src/shaders/fill.vertex.glsl +13 -0
  155. package/src/shaders/fill_extrusion.fragment.glsl +9 -0
  156. package/src/shaders/fill_extrusion.vertex.glsl +66 -0
  157. package/src/shaders/fill_extrusion_pattern.fragment.glsl +45 -0
  158. package/src/shaders/fill_extrusion_pattern.vertex.glsl +79 -0
  159. package/src/shaders/fill_outline.fragment.glsl +17 -0
  160. package/src/shaders/fill_outline.vertex.glsl +17 -0
  161. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  162. package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
  163. package/src/shaders/fill_pattern.fragment.glsl +36 -0
  164. package/src/shaders/fill_pattern.vertex.glsl +39 -0
  165. package/src/shaders/heatmap.fragment.glsl +22 -0
  166. package/src/shaders/heatmap.vertex.glsl +54 -0
  167. package/src/shaders/heatmap_texture.fragment.glsl +14 -0
  168. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  169. package/src/shaders/hillshade.fragment.glsl +52 -0
  170. package/src/shaders/hillshade.vertex.glsl +11 -0
  171. package/src/shaders/hillshade_prepare.fragment.glsl +75 -0
  172. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  173. package/src/shaders/index.js +20 -0
  174. package/src/shaders/line.fragment.glsl +30 -0
  175. package/src/shaders/line.vertex.glsl +85 -0
  176. package/src/shaders/line_gradient.fragment.glsl +34 -0
  177. package/src/shaders/line_gradient.vertex.glsl +88 -0
  178. package/src/shaders/line_pattern.fragment.glsl +74 -0
  179. package/src/shaders/line_pattern.vertex.glsl +99 -0
  180. package/src/shaders/line_sdf.fragment.glsl +45 -0
  181. package/src/shaders/line_sdf.vertex.glsl +98 -0
  182. package/src/shaders/raster.fragment.glsl +52 -0
  183. package/src/shaders/raster.vertex.glsl +21 -0
  184. package/src/shaders/shaders.js +185 -0
  185. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  186. package/src/shaders/symbol_icon.vertex.glsl +94 -0
  187. package/src/shaders/symbol_sdf.fragment.glsl +52 -0
  188. package/src/shaders/symbol_sdf.vertex.glsl +115 -0
  189. package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
  190. package/src/shaders/symbol_text_and_icon.vertex.glsl +116 -0
  191. package/src/source/canvas_source.js +238 -0
  192. package/src/source/geojson_source.js +370 -0
  193. package/src/source/geojson_worker_source.js +366 -0
  194. package/src/source/geojson_wrapper.js +94 -0
  195. package/src/source/image_source.js +307 -0
  196. package/src/source/load_tilejson.js +39 -0
  197. package/src/source/pixels_to_tile_units.js +21 -0
  198. package/src/source/query_features.js +208 -0
  199. package/src/source/raster_dem_tile_source.js +138 -0
  200. package/src/source/raster_dem_tile_worker_source.js +62 -0
  201. package/src/source/raster_tile_source.js +169 -0
  202. package/src/source/rtl_text_plugin.js +143 -0
  203. package/src/source/source.js +137 -0
  204. package/src/source/source_cache.js +953 -0
  205. package/src/source/source_state.js +159 -0
  206. package/src/source/tile.js +458 -0
  207. package/src/source/tile_bounds.js +38 -0
  208. package/src/source/tile_cache.js +212 -0
  209. package/src/source/tile_id.js +199 -0
  210. package/src/source/vector_tile_source.js +259 -0
  211. package/src/source/vector_tile_worker_source.js +216 -0
  212. package/src/source/video_source.js +203 -0
  213. package/src/source/worker.js +240 -0
  214. package/src/source/worker_source.js +107 -0
  215. package/src/source/worker_tile.js +224 -0
  216. package/src/style/create_style_layer.js +36 -0
  217. package/src/style/evaluation_parameters.js +62 -0
  218. package/src/style/format_section_override.js +56 -0
  219. package/src/style/light.js +130 -0
  220. package/src/style/load_glyph_range.js +38 -0
  221. package/src/style/load_sprite.js +67 -0
  222. package/src/style/parse_glyph_pbf.js +44 -0
  223. package/src/style/pauseable_placement.js +132 -0
  224. package/src/style/properties.js +753 -0
  225. package/src/style/query_utils.js +43 -0
  226. package/src/style/style.js +1374 -0
  227. package/src/style/style_glyph.js +17 -0
  228. package/src/style/style_image.js +137 -0
  229. package/src/style/style_layer/background_style_layer.js +21 -0
  230. package/src/style/style_layer/background_style_layer_properties.js +40 -0
  231. package/src/style/style_layer/circle_style_layer.js +98 -0
  232. package/src/style/style_layer/circle_style_layer_properties.js +63 -0
  233. package/src/style/style_layer/custom_style_layer.js +223 -0
  234. package/src/style/style_layer/fill_extrusion_style_layer.js +224 -0
  235. package/src/style/style_layer/fill_extrusion_style_layer_properties.js +50 -0
  236. package/src/style/style_layer/fill_style_layer.js +67 -0
  237. package/src/style/style_layer/fill_style_layer_properties.js +55 -0
  238. package/src/style/style_layer/heatmap_style_layer.js +73 -0
  239. package/src/style/style_layer/heatmap_style_layer_properties.js +44 -0
  240. package/src/style/style_layer/hillshade_style_layer.js +25 -0
  241. package/src/style/style_layer/hillshade_style_layer_properties.js +46 -0
  242. package/src/style/style_layer/layer_properties.js.ejs +69 -0
  243. package/src/style/style_layer/line_style_layer.js +150 -0
  244. package/src/style/style_layer/line_style_layer_properties.js +71 -0
  245. package/src/style/style_layer/raster_style_layer.js +21 -0
  246. package/src/style/style_layer/raster_style_layer_properties.js +50 -0
  247. package/src/style/style_layer/symbol_style_layer.js +190 -0
  248. package/src/style/style_layer/symbol_style_layer_properties.js +153 -0
  249. package/src/style/style_layer/typed_style_layer.js +17 -0
  250. package/src/style/style_layer.js +283 -0
  251. package/src/style/style_layer_index.js +80 -0
  252. package/src/style/validate_style.js +42 -0
  253. package/src/style/zoom_history.js +44 -0
  254. package/src/style-spec/.eslintrc +5 -0
  255. package/src/style-spec/CHANGELOG.md +468 -0
  256. package/src/style-spec/README.md +59 -0
  257. package/src/style-spec/bin/gl-style-composite +9 -0
  258. package/src/style-spec/bin/gl-style-format +22 -0
  259. package/src/style-spec/bin/gl-style-migrate +9 -0
  260. package/src/style-spec/bin/gl-style-validate +50 -0
  261. package/src/style-spec/composite.js +50 -0
  262. package/src/style-spec/declass.js +42 -0
  263. package/src/style-spec/deref.js +52 -0
  264. package/src/style-spec/diff.js +393 -0
  265. package/src/style-spec/dist/.gitkeep +0 -0
  266. package/src/style-spec/dist/index.es.js +15032 -0
  267. package/src/style-spec/dist/index.es.js.map +1 -0
  268. package/src/style-spec/dist/index.js +15058 -0
  269. package/src/style-spec/dist/index.js.map +1 -0
  270. package/src/style-spec/empty.js +29 -0
  271. package/src/style-spec/error/parsing_error.js +16 -0
  272. package/src/style-spec/error/validation_error.js +18 -0
  273. package/src/style-spec/expression/compound_expression.js +162 -0
  274. package/src/style-spec/expression/definitions/assertion.js +130 -0
  275. package/src/style-spec/expression/definitions/at.js +70 -0
  276. package/src/style-spec/expression/definitions/case.js +85 -0
  277. package/src/style-spec/expression/definitions/coalesce.js +93 -0
  278. package/src/style-spec/expression/definitions/coercion.js +133 -0
  279. package/src/style-spec/expression/definitions/collator.js +78 -0
  280. package/src/style-spec/expression/definitions/comparison.js +184 -0
  281. package/src/style-spec/expression/definitions/format.js +144 -0
  282. package/src/style-spec/expression/definitions/image.js +52 -0
  283. package/src/style-spec/expression/definitions/in.js +72 -0
  284. package/src/style-spec/expression/definitions/index.js +565 -0
  285. package/src/style-spec/expression/definitions/index_of.js +89 -0
  286. package/src/style-spec/expression/definitions/interpolate.js +267 -0
  287. package/src/style-spec/expression/definitions/length.js +61 -0
  288. package/src/style-spec/expression/definitions/let.js +72 -0
  289. package/src/style-spec/expression/definitions/literal.js +77 -0
  290. package/src/style-spec/expression/definitions/match.js +158 -0
  291. package/src/style-spec/expression/definitions/number_format.js +142 -0
  292. package/src/style-spec/expression/definitions/slice.js +86 -0
  293. package/src/style-spec/expression/definitions/step.js +120 -0
  294. package/src/style-spec/expression/definitions/var.js +46 -0
  295. package/src/style-spec/expression/definitions/within.js +342 -0
  296. package/src/style-spec/expression/evaluation_context.js +59 -0
  297. package/src/style-spec/expression/expression.js +27 -0
  298. package/src/style-spec/expression/index.js +392 -0
  299. package/src/style-spec/expression/is_constant.js +59 -0
  300. package/src/style-spec/expression/parsing_context.js +233 -0
  301. package/src/style-spec/expression/parsing_error.js +13 -0
  302. package/src/style-spec/expression/runtime_error.js +17 -0
  303. package/src/style-spec/expression/scope.js +36 -0
  304. package/src/style-spec/expression/stops.js +39 -0
  305. package/src/style-spec/expression/types/collator.js +61 -0
  306. package/src/style-spec/expression/types/formatted.js +73 -0
  307. package/src/style-spec/expression/types/resolved_image.js +29 -0
  308. package/src/style-spec/expression/types.js +126 -0
  309. package/src/style-spec/expression/values.js +123 -0
  310. package/src/style-spec/feature_filter/README.md +55 -0
  311. package/src/style-spec/feature_filter/convert.js +208 -0
  312. package/src/style-spec/feature_filter/index.js +175 -0
  313. package/src/style-spec/format.js +51 -0
  314. package/src/style-spec/function/convert.js +270 -0
  315. package/src/style-spec/function/index.js +262 -0
  316. package/src/style-spec/group_by_layout.js +75 -0
  317. package/src/style-spec/migrate/expressions.js +39 -0
  318. package/src/style-spec/migrate/v8.js +203 -0
  319. package/src/style-spec/migrate/v9.js +26 -0
  320. package/src/style-spec/migrate.js +36 -0
  321. package/src/style-spec/package.json +41 -0
  322. package/src/style-spec/read_style.js +14 -0
  323. package/src/style-spec/reference/latest.js +3 -0
  324. package/src/style-spec/reference/v8.json +5914 -0
  325. package/src/style-spec/rollup.config.js +65 -0
  326. package/src/style-spec/style-spec.js +124 -0
  327. package/src/style-spec/types.js +432 -0
  328. package/src/style-spec/util/color.js +95 -0
  329. package/src/style-spec/util/color_spaces.js +139 -0
  330. package/src/style-spec/util/deep_equal.js +28 -0
  331. package/src/style-spec/util/extend.js +10 -0
  332. package/src/style-spec/util/get_type.js +17 -0
  333. package/src/style-spec/util/interpolate.js +22 -0
  334. package/src/style-spec/util/properties.js +15 -0
  335. package/src/style-spec/util/ref_properties.js +2 -0
  336. package/src/style-spec/util/result.js +19 -0
  337. package/src/style-spec/util/unbundle_jsonlint.js +24 -0
  338. package/src/style-spec/validate/latest.js +11 -0
  339. package/src/style-spec/validate/validate.js +75 -0
  340. package/src/style-spec/validate/validate_array.js +52 -0
  341. package/src/style-spec/validate/validate_boolean.js +15 -0
  342. package/src/style-spec/validate/validate_color.js +20 -0
  343. package/src/style-spec/validate/validate_constants.js +13 -0
  344. package/src/style-spec/validate/validate_enum.js +21 -0
  345. package/src/style-spec/validate/validate_expression.js +43 -0
  346. package/src/style-spec/validate/validate_filter.js +117 -0
  347. package/src/style-spec/validate/validate_formatted.js +11 -0
  348. package/src/style-spec/validate/validate_function.js +207 -0
  349. package/src/style-spec/validate/validate_glyphs_url.js +21 -0
  350. package/src/style-spec/validate/validate_image.js +11 -0
  351. package/src/style-spec/validate/validate_layer.js +134 -0
  352. package/src/style-spec/validate/validate_layout_property.js +6 -0
  353. package/src/style-spec/validate/validate_light.js +47 -0
  354. package/src/style-spec/validate/validate_number.js +29 -0
  355. package/src/style-spec/validate/validate_object.js +61 -0
  356. package/src/style-spec/validate/validate_paint_property.js +6 -0
  357. package/src/style-spec/validate/validate_property.js +64 -0
  358. package/src/style-spec/validate/validate_source.js +111 -0
  359. package/src/style-spec/validate/validate_string.js +15 -0
  360. package/src/style-spec/validate_mapbox_api_supported.js +171 -0
  361. package/src/style-spec/validate_style.js +39 -0
  362. package/src/style-spec/validate_style.min.js +78 -0
  363. package/src/style-spec/visit.js +77 -0
  364. package/src/symbol/anchor.js +26 -0
  365. package/src/symbol/check_max_angle.js +81 -0
  366. package/src/symbol/clip_line.js +71 -0
  367. package/src/symbol/collision_feature.js +109 -0
  368. package/src/symbol/collision_index.js +373 -0
  369. package/src/symbol/cross_tile_symbol_index.js +301 -0
  370. package/src/symbol/get_anchors.js +167 -0
  371. package/src/symbol/grid_index.js +335 -0
  372. package/src/symbol/mergelines.js +82 -0
  373. package/src/symbol/one_em.js +4 -0
  374. package/src/symbol/opacity_state.js +27 -0
  375. package/src/symbol/path_interpolator.js +61 -0
  376. package/src/symbol/placement.js +1124 -0
  377. package/src/symbol/projection.js +451 -0
  378. package/src/symbol/quads.js +334 -0
  379. package/src/symbol/shaping.js +816 -0
  380. package/src/symbol/symbol_layout.js +796 -0
  381. package/src/symbol/symbol_size.js +113 -0
  382. package/src/symbol/transform_text.js +29 -0
  383. package/src/types/callback.js +17 -0
  384. package/src/types/cancelable.js +3 -0
  385. package/src/types/tilejson.js +17 -0
  386. package/src/types/transferable.js +3 -0
  387. package/src/types/window.js +172 -0
  388. package/src/ui/anchor.js +32 -0
  389. package/src/ui/camera.js +1277 -0
  390. package/src/ui/control/attribution_control.js +212 -0
  391. package/src/ui/control/fullscreen_control.js +147 -0
  392. package/src/ui/control/geolocate_control.js +707 -0
  393. package/src/ui/control/logo_control.js +92 -0
  394. package/src/ui/control/navigation_control.js +257 -0
  395. package/src/ui/control/scale_control.js +142 -0
  396. package/src/ui/default_locale.js +22 -0
  397. package/src/ui/events.js +1301 -0
  398. package/src/ui/handler/box_zoom.js +170 -0
  399. package/src/ui/handler/click_zoom.js +52 -0
  400. package/src/ui/handler/handler_util.js +12 -0
  401. package/src/ui/handler/keyboard.js +208 -0
  402. package/src/ui/handler/map_event.js +156 -0
  403. package/src/ui/handler/mouse.js +171 -0
  404. package/src/ui/handler/scroll_zoom.js +350 -0
  405. package/src/ui/handler/shim/dblclick_zoom.js +62 -0
  406. package/src/ui/handler/shim/drag_pan.js +88 -0
  407. package/src/ui/handler/shim/drag_rotate.js +67 -0
  408. package/src/ui/handler/shim/touch_zoom_rotate.js +108 -0
  409. package/src/ui/handler/tap_drag_zoom.js +103 -0
  410. package/src/ui/handler/tap_recognizer.js +133 -0
  411. package/src/ui/handler/tap_zoom.js +93 -0
  412. package/src/ui/handler/touch_pan.js +101 -0
  413. package/src/ui/handler/touch_zoom_rotate.js +305 -0
  414. package/src/ui/handler_inertia.js +158 -0
  415. package/src/ui/handler_manager.js +531 -0
  416. package/src/ui/hash.js +148 -0
  417. package/src/ui/map.js +2874 -0
  418. package/src/ui/marker.js +672 -0
  419. package/src/ui/popup.js +640 -0
  420. package/src/util/actor.js +212 -0
  421. package/src/util/ajax.js +388 -0
  422. package/src/util/browser/web_worker.js +10 -0
  423. package/src/util/browser/window.js +6 -0
  424. package/src/util/browser.js +70 -0
  425. package/src/util/classify_rings.js +52 -0
  426. package/src/util/color_ramp.js +61 -0
  427. package/src/util/config.js +30 -0
  428. package/src/util/debug.js +28 -0
  429. package/src/util/dictionary_coder.js +30 -0
  430. package/src/util/dispatcher.js +70 -0
  431. package/src/util/dom.js +142 -0
  432. package/src/util/evented.js +174 -0
  433. package/src/util/find_pole_of_inaccessibility.js +129 -0
  434. package/src/util/global_worker_pool.js +35 -0
  435. package/src/util/image.js +142 -0
  436. package/src/util/intersection_tests.js +208 -0
  437. package/src/util/is_char_in_unicode_block.js +311 -0
  438. package/src/util/mapbox.js +491 -0
  439. package/src/util/offscreen_canvas_supported.js +14 -0
  440. package/src/util/performance.js +112 -0
  441. package/src/util/primitives.js +145 -0
  442. package/src/util/resolve_tokens.js +16 -0
  443. package/src/util/script_detection.js +328 -0
  444. package/src/util/sku_token.js +42 -0
  445. package/src/util/smart_wrap.js +55 -0
  446. package/src/util/struct_array.js +243 -0
  447. package/src/util/struct_array.js.ejs +112 -0
  448. package/src/util/struct_array_layout.js.ejs +98 -0
  449. package/src/util/task_queue.js +68 -0
  450. package/src/util/throttle.js +27 -0
  451. package/src/util/throttled_invoker.js +46 -0
  452. package/src/util/tile_request_cache.js +172 -0
  453. package/src/util/util.js +524 -0
  454. package/src/util/vectortile_to_geojson.js +50 -0
  455. package/src/util/verticalize_punctuation.js +114 -0
  456. package/src/util/web_worker.js +91 -0
  457. package/src/util/web_worker_transfer.js +266 -0
  458. package/src/util/webp_supported.js +69 -0
  459. package/src/util/window.js +102 -0
  460. package/src/util/worker_pool.js +57 -0
@@ -0,0 +1,816 @@
1
+ // @flow
2
+
3
+ import assert from 'assert';
4
+ import {
5
+ charHasUprightVerticalOrientation,
6
+ charAllowsIdeographicBreaking,
7
+ charInComplexShapingScript
8
+ } from '../util/script_detection';
9
+ import verticalizePunctuation from '../util/verticalize_punctuation';
10
+ import {plugin as rtlTextPlugin} from '../source/rtl_text_plugin';
11
+ import ONE_EM from './one_em';
12
+ import {warnOnce} from '../util/util';
13
+
14
+ import type {StyleGlyph, GlyphMetrics} from '../style/style_glyph';
15
+ import {GLYPH_PBF_BORDER} from '../style/parse_glyph_pbf';
16
+ import type {ImagePosition} from '../render/image_atlas';
17
+ import {IMAGE_PADDING} from '../render/image_atlas';
18
+ import type {Rect, GlyphPosition} from '../render/glyph_atlas';
19
+ import Formatted, {FormattedSection} from '../style-spec/expression/types/formatted';
20
+
21
+ const WritingMode = {
22
+ horizontal: 1,
23
+ vertical: 2,
24
+ horizontalOnly: 3
25
+ };
26
+
27
+ const SHAPING_DEFAULT_OFFSET = -17;
28
+ export {shapeText, shapeIcon, fitIconToText, getAnchorAlignment, WritingMode, SHAPING_DEFAULT_OFFSET};
29
+
30
+ // The position of a glyph relative to the text's anchor point.
31
+ export type PositionedGlyph = {
32
+ glyph: number,
33
+ imageName: string | null,
34
+ x: number,
35
+ y: number,
36
+ vertical: boolean,
37
+ scale: number,
38
+ fontStack: string,
39
+ sectionIndex: number,
40
+ metrics: GlyphMetrics,
41
+ rect: Rect | null
42
+ };
43
+
44
+ export type PositionedLine = {
45
+ positionedGlyphs: Array<PositionedGlyph>,
46
+ lineOffset: number
47
+ };
48
+
49
+ // A collection of positioned glyphs and some metadata
50
+ export type Shaping = {
51
+ positionedLines: Array<PositionedLine>,
52
+ top: number,
53
+ bottom: number,
54
+ left: number,
55
+ right: number,
56
+ writingMode: 1 | 2,
57
+ text: string,
58
+ iconsInText: boolean,
59
+ verticalizable: boolean
60
+ };
61
+
62
+ function isEmpty(positionedLines: Array<PositionedLine>) {
63
+ for (const line of positionedLines) {
64
+ if (line.positionedGlyphs.length !== 0) {
65
+ return false;
66
+ }
67
+ }
68
+ return true;
69
+ }
70
+
71
+ export type SymbolAnchor = 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
72
+ export type TextJustify = 'left' | 'center' | 'right';
73
+
74
+ // Max number of images in label is 6401 U+E000–U+F8FF that covers
75
+ // Basic Multilingual Plane Unicode Private Use Area (PUA).
76
+ const PUAbegin = 0xE000;
77
+ const PUAend = 0xF8FF;
78
+
79
+ class SectionOptions {
80
+ // Text options
81
+ scale: number;
82
+ fontStack: string;
83
+ // Image options
84
+ imageName: string | null;
85
+
86
+ constructor() {
87
+ this.scale = 1.0;
88
+ this.fontStack = "";
89
+ this.imageName = null;
90
+ }
91
+
92
+ static forText(scale: number | null, fontStack: string) {
93
+ const textOptions = new SectionOptions();
94
+ textOptions.scale = scale || 1;
95
+ textOptions.fontStack = fontStack;
96
+ return textOptions;
97
+ }
98
+
99
+ static forImage(imageName: string) {
100
+ const imageOptions = new SectionOptions();
101
+ imageOptions.imageName = imageName;
102
+ return imageOptions;
103
+ }
104
+
105
+ }
106
+
107
+ class TaggedString {
108
+ text: string;
109
+ sectionIndex: Array<number> // maps each character in 'text' to its corresponding entry in 'sections'
110
+ sections: Array<SectionOptions>
111
+ imageSectionID: number | null;
112
+
113
+ constructor() {
114
+ this.text = "";
115
+ this.sectionIndex = [];
116
+ this.sections = [];
117
+ this.imageSectionID = null;
118
+ }
119
+
120
+ static fromFeature(text: Formatted, defaultFontStack: string) {
121
+ const result = new TaggedString();
122
+ for (let i = 0; i < text.sections.length; i++) {
123
+ const section = text.sections[i];
124
+ if (!section.image) {
125
+ result.addTextSection(section, defaultFontStack);
126
+ } else {
127
+ result.addImageSection(section);
128
+ }
129
+ }
130
+ return result;
131
+ }
132
+
133
+ length(): number {
134
+ return this.text.length;
135
+ }
136
+
137
+ getSection(index: number): SectionOptions {
138
+ return this.sections[this.sectionIndex[index]];
139
+ }
140
+
141
+ getSectionIndex(index: number): number {
142
+ return this.sectionIndex[index];
143
+ }
144
+
145
+ getCharCode(index: number): number {
146
+ return this.text.charCodeAt(index);
147
+ }
148
+
149
+ verticalizePunctuation() {
150
+ this.text = verticalizePunctuation(this.text);
151
+ }
152
+
153
+ trim() {
154
+ let beginningWhitespace = 0;
155
+ for (let i = 0;
156
+ i < this.text.length && whitespace[this.text.charCodeAt(i)];
157
+ i++) {
158
+ beginningWhitespace++;
159
+ }
160
+ let trailingWhitespace = this.text.length;
161
+ for (let i = this.text.length - 1;
162
+ i >= 0 && i >= beginningWhitespace && whitespace[this.text.charCodeAt(i)];
163
+ i--) {
164
+ trailingWhitespace--;
165
+ }
166
+ this.text = this.text.substring(beginningWhitespace, trailingWhitespace);
167
+ this.sectionIndex = this.sectionIndex.slice(beginningWhitespace, trailingWhitespace);
168
+ }
169
+
170
+ substring(start: number, end: number): TaggedString {
171
+ const substring = new TaggedString();
172
+ substring.text = this.text.substring(start, end);
173
+ substring.sectionIndex = this.sectionIndex.slice(start, end);
174
+ substring.sections = this.sections;
175
+ return substring;
176
+ }
177
+
178
+ toString(): string {
179
+ return this.text;
180
+ }
181
+
182
+ getMaxScale() {
183
+ return this.sectionIndex.reduce((max, index) => Math.max(max, this.sections[index].scale), 0);
184
+ }
185
+
186
+ addTextSection(section: FormattedSection, defaultFontStack: string) {
187
+ this.text += section.text;
188
+ this.sections.push(SectionOptions.forText(section.scale, section.fontStack || defaultFontStack));
189
+ const index = this.sections.length - 1;
190
+ for (let i = 0; i < section.text.length; ++i) {
191
+ this.sectionIndex.push(index);
192
+ }
193
+ }
194
+
195
+ addImageSection(section: FormattedSection) {
196
+ const imageName = section.image ? section.image.name : '';
197
+ if (imageName.length === 0) {
198
+ warnOnce(`Can't add FormattedSection with an empty image.`);
199
+ return;
200
+ }
201
+
202
+ const nextImageSectionCharCode = this.getNextImageSectionCharCode();
203
+ if (!nextImageSectionCharCode) {
204
+ warnOnce(`Reached maximum number of images ${PUAend - PUAbegin + 2}`);
205
+ return;
206
+ }
207
+
208
+ this.text += String.fromCharCode(nextImageSectionCharCode);
209
+ this.sections.push(SectionOptions.forImage(imageName));
210
+ this.sectionIndex.push(this.sections.length - 1);
211
+ }
212
+
213
+ getNextImageSectionCharCode(): number | null {
214
+ if (!this.imageSectionID) {
215
+ this.imageSectionID = PUAbegin;
216
+ return this.imageSectionID;
217
+ }
218
+
219
+ if (this.imageSectionID >= PUAend) return null;
220
+ return ++this.imageSectionID;
221
+ }
222
+ }
223
+
224
+ function breakLines(input: TaggedString, lineBreakPoints: Array<number>): Array<TaggedString> {
225
+ const lines = [];
226
+ const text = input.text;
227
+ let start = 0;
228
+ for (const lineBreak of lineBreakPoints) {
229
+ lines.push(input.substring(start, lineBreak));
230
+ start = lineBreak;
231
+ }
232
+
233
+ if (start < text.length) {
234
+ lines.push(input.substring(start, text.length));
235
+ }
236
+ return lines;
237
+ }
238
+
239
+ function shapeText(text: Formatted,
240
+ glyphMap: {[_: string]: {[_: number]: ?StyleGlyph}},
241
+ glyphPositions: {[_: string]: {[_: number]: GlyphPosition}},
242
+ imagePositions: {[_: string]: ImagePosition},
243
+ defaultFontStack: string,
244
+ maxWidth: number,
245
+ lineHeight: number,
246
+ textAnchor: SymbolAnchor,
247
+ textJustify: TextJustify,
248
+ spacing: number,
249
+ translate: [number, number],
250
+ writingMode: 1 | 2,
251
+ allowVerticalPlacement: boolean,
252
+ symbolPlacement: string,
253
+ layoutTextSize: number,
254
+ layoutTextSizeThisZoom: number): Shaping | false {
255
+ const logicalInput = TaggedString.fromFeature(text, defaultFontStack);
256
+
257
+ if (writingMode === WritingMode.vertical) {
258
+ logicalInput.verticalizePunctuation();
259
+ }
260
+
261
+ let lines: Array<TaggedString>;
262
+
263
+ const {processBidirectionalText, processStyledBidirectionalText} = rtlTextPlugin;
264
+ if (processBidirectionalText && logicalInput.sections.length === 1) {
265
+ // Bidi doesn't have to be style-aware
266
+ lines = [];
267
+ const untaggedLines =
268
+ processBidirectionalText(logicalInput.toString(),
269
+ determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize));
270
+ for (const line of untaggedLines) {
271
+ const taggedLine = new TaggedString();
272
+ taggedLine.text = line;
273
+ taggedLine.sections = logicalInput.sections;
274
+ for (let i = 0; i < line.length; i++) {
275
+ taggedLine.sectionIndex.push(0);
276
+ }
277
+ lines.push(taggedLine);
278
+ }
279
+ } else if (processStyledBidirectionalText) {
280
+ // Need version of mapbox-gl-rtl-text with style support for combining RTL text
281
+ // with formatting
282
+ lines = [];
283
+ const processedLines =
284
+ processStyledBidirectionalText(logicalInput.text,
285
+ logicalInput.sectionIndex,
286
+ determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize));
287
+ for (const line of processedLines) {
288
+ const taggedLine = new TaggedString();
289
+ taggedLine.text = line[0];
290
+ taggedLine.sectionIndex = line[1];
291
+ taggedLine.sections = logicalInput.sections;
292
+ lines.push(taggedLine);
293
+ }
294
+ } else {
295
+ lines = breakLines(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphMap, imagePositions, symbolPlacement, layoutTextSize));
296
+ }
297
+
298
+ const positionedLines = [];
299
+ const shaping = {
300
+ positionedLines,
301
+ text: logicalInput.toString(),
302
+ top: translate[1],
303
+ bottom: translate[1],
304
+ left: translate[0],
305
+ right: translate[0],
306
+ writingMode,
307
+ iconsInText: false,
308
+ verticalizable: false
309
+ };
310
+
311
+ shapeLines(shaping, glyphMap, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement, layoutTextSizeThisZoom);
312
+ if (isEmpty(positionedLines)) return false;
313
+
314
+ return shaping;
315
+ }
316
+
317
+ // using computed properties due to https://github.com/facebook/flow/issues/380
318
+ /* eslint no-useless-computed-key: 0 */
319
+
320
+ const whitespace: {[_: number]: boolean} = {
321
+ [0x09]: true, // tab
322
+ [0x0a]: true, // newline
323
+ [0x0b]: true, // vertical tab
324
+ [0x0c]: true, // form feed
325
+ [0x0d]: true, // carriage return
326
+ [0x20]: true, // space
327
+ };
328
+
329
+ const breakable: {[_: number]: boolean} = {
330
+ [0x0a]: true, // newline
331
+ [0x20]: true, // space
332
+ [0x26]: true, // ampersand
333
+ [0x28]: true, // left parenthesis
334
+ [0x29]: true, // right parenthesis
335
+ [0x2b]: true, // plus sign
336
+ [0x2d]: true, // hyphen-minus
337
+ [0x2f]: true, // solidus
338
+ [0xad]: true, // soft hyphen
339
+ [0xb7]: true, // middle dot
340
+ [0x200b]: true, // zero-width space
341
+ [0x2010]: true, // hyphen
342
+ [0x2013]: true, // en dash
343
+ [0x2027]: true // interpunct
344
+ // Many other characters may be reasonable breakpoints
345
+ // Consider "neutral orientation" characters at scriptDetection.charHasNeutralVerticalOrientation
346
+ // See https://github.com/mapbox/mapbox-gl-js/issues/3658
347
+ };
348
+
349
+ function getGlyphAdvance(codePoint: number,
350
+ section: SectionOptions,
351
+ glyphMap: {[_: string]: {[_: number]: ?StyleGlyph}},
352
+ imagePositions: {[_: string]: ImagePosition},
353
+ spacing: number,
354
+ layoutTextSize: number): number {
355
+ if (!section.imageName) {
356
+ const positions = glyphMap[section.fontStack];
357
+ const glyph = positions && positions[codePoint];
358
+ if (!glyph) return 0;
359
+ return glyph.metrics.advance * section.scale + spacing;
360
+ } else {
361
+ const imagePosition = imagePositions[section.imageName];
362
+ if (!imagePosition) return 0;
363
+ return imagePosition.displaySize[0] * section.scale * ONE_EM / layoutTextSize + spacing;
364
+ }
365
+ }
366
+
367
+ function determineAverageLineWidth(logicalInput: TaggedString,
368
+ spacing: number,
369
+ maxWidth: number,
370
+ glyphMap: {[_: string]: {[_: number]: ?StyleGlyph}},
371
+ imagePositions: {[_: string]: ImagePosition},
372
+ layoutTextSize: number) {
373
+ let totalWidth = 0;
374
+
375
+ for (let index = 0; index < logicalInput.length(); index++) {
376
+ const section = logicalInput.getSection(index);
377
+ totalWidth += getGlyphAdvance(logicalInput.getCharCode(index), section, glyphMap, imagePositions, spacing, layoutTextSize);
378
+ }
379
+
380
+ const lineCount = Math.max(1, Math.ceil(totalWidth / maxWidth));
381
+ return totalWidth / lineCount;
382
+ }
383
+
384
+ function calculateBadness(lineWidth: number,
385
+ targetWidth: number,
386
+ penalty: number,
387
+ isLastBreak: boolean) {
388
+ const raggedness = Math.pow(lineWidth - targetWidth, 2);
389
+ if (isLastBreak) {
390
+ // Favor finals lines shorter than average over longer than average
391
+ if (lineWidth < targetWidth) {
392
+ return raggedness / 2;
393
+ } else {
394
+ return raggedness * 2;
395
+ }
396
+ }
397
+
398
+ return raggedness + Math.abs(penalty) * penalty;
399
+ }
400
+
401
+ function calculatePenalty(codePoint: number, nextCodePoint: number, penalizableIdeographicBreak: boolean) {
402
+ let penalty = 0;
403
+ // Force break on newline
404
+ if (codePoint === 0x0a) {
405
+ penalty -= 10000;
406
+ }
407
+ // Penalize breaks between characters that allow ideographic breaking because
408
+ // they are less preferable than breaks at spaces (or zero width spaces).
409
+ if (penalizableIdeographicBreak) {
410
+ penalty += 150;
411
+ }
412
+
413
+ // Penalize open parenthesis at end of line
414
+ if (codePoint === 0x28 || codePoint === 0xff08) {
415
+ penalty += 50;
416
+ }
417
+
418
+ // Penalize close parenthesis at beginning of line
419
+ if (nextCodePoint === 0x29 || nextCodePoint === 0xff09) {
420
+ penalty += 50;
421
+ }
422
+ return penalty;
423
+ }
424
+
425
+ type Break = {
426
+ index: number,
427
+ x: number,
428
+ priorBreak: ?Break,
429
+ badness: number
430
+ };
431
+
432
+ function evaluateBreak(breakIndex: number,
433
+ breakX: number,
434
+ targetWidth: number,
435
+ potentialBreaks: Array<Break>,
436
+ penalty: number,
437
+ isLastBreak: boolean): Break {
438
+ // We could skip evaluating breaks where the line length (breakX - priorBreak.x) > maxWidth
439
+ // ...but in fact we allow lines longer than maxWidth (if there's no break points)
440
+ // ...and when targetWidth and maxWidth are close, strictly enforcing maxWidth can give
441
+ // more lopsided results.
442
+
443
+ let bestPriorBreak: ?Break = null;
444
+ let bestBreakBadness = calculateBadness(breakX, targetWidth, penalty, isLastBreak);
445
+
446
+ for (const potentialBreak of potentialBreaks) {
447
+ const lineWidth = breakX - potentialBreak.x;
448
+ const breakBadness =
449
+ calculateBadness(lineWidth, targetWidth, penalty, isLastBreak) + potentialBreak.badness;
450
+ if (breakBadness <= bestBreakBadness) {
451
+ bestPriorBreak = potentialBreak;
452
+ bestBreakBadness = breakBadness;
453
+ }
454
+ }
455
+
456
+ return {
457
+ index: breakIndex,
458
+ x: breakX,
459
+ priorBreak: bestPriorBreak,
460
+ badness: bestBreakBadness
461
+ };
462
+ }
463
+
464
+ function leastBadBreaks(lastLineBreak: ?Break): Array<number> {
465
+ if (!lastLineBreak) {
466
+ return [];
467
+ }
468
+ return leastBadBreaks(lastLineBreak.priorBreak).concat(lastLineBreak.index);
469
+ }
470
+
471
+ function determineLineBreaks(logicalInput: TaggedString,
472
+ spacing: number,
473
+ maxWidth: number,
474
+ glyphMap: {[_: string]: {[_: number]: ?StyleGlyph}},
475
+ imagePositions: {[_: string]: ImagePosition},
476
+ symbolPlacement: string,
477
+ layoutTextSize: number): Array<number> {
478
+ if (symbolPlacement !== 'point')
479
+ return [];
480
+
481
+ if (!logicalInput)
482
+ return [];
483
+
484
+ const potentialLineBreaks = [];
485
+ const targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize);
486
+
487
+ const hasServerSuggestedBreakpoints = logicalInput.text.indexOf("\u200b") >= 0;
488
+
489
+ let currentX = 0;
490
+
491
+ for (let i = 0; i < logicalInput.length(); i++) {
492
+ const section = logicalInput.getSection(i);
493
+ const codePoint = logicalInput.getCharCode(i);
494
+ if (!whitespace[codePoint]) currentX += getGlyphAdvance(codePoint, section, glyphMap, imagePositions, spacing, layoutTextSize);
495
+
496
+ // Ideographic characters, spaces, and word-breaking punctuation that often appear without
497
+ // surrounding spaces.
498
+ if ((i < logicalInput.length() - 1)) {
499
+ const ideographicBreak = charAllowsIdeographicBreaking(codePoint);
500
+ if (breakable[codePoint] || ideographicBreak || section.imageName) {
501
+
502
+ potentialLineBreaks.push(
503
+ evaluateBreak(
504
+ i + 1,
505
+ currentX,
506
+ targetWidth,
507
+ potentialLineBreaks,
508
+ calculatePenalty(codePoint, logicalInput.getCharCode(i + 1), ideographicBreak && hasServerSuggestedBreakpoints),
509
+ false));
510
+ }
511
+ }
512
+ }
513
+
514
+ return leastBadBreaks(
515
+ evaluateBreak(
516
+ logicalInput.length(),
517
+ currentX,
518
+ targetWidth,
519
+ potentialLineBreaks,
520
+ 0,
521
+ true));
522
+ }
523
+
524
+ function getAnchorAlignment(anchor: SymbolAnchor) {
525
+ let horizontalAlign = 0.5, verticalAlign = 0.5;
526
+
527
+ switch (anchor) {
528
+ case 'right':
529
+ case 'top-right':
530
+ case 'bottom-right':
531
+ horizontalAlign = 1;
532
+ break;
533
+ case 'left':
534
+ case 'top-left':
535
+ case 'bottom-left':
536
+ horizontalAlign = 0;
537
+ break;
538
+ }
539
+
540
+ switch (anchor) {
541
+ case 'bottom':
542
+ case 'bottom-right':
543
+ case 'bottom-left':
544
+ verticalAlign = 1;
545
+ break;
546
+ case 'top':
547
+ case 'top-right':
548
+ case 'top-left':
549
+ verticalAlign = 0;
550
+ break;
551
+ }
552
+
553
+ return {horizontalAlign, verticalAlign};
554
+ }
555
+
556
+ function shapeLines(shaping: Shaping,
557
+ glyphMap: {[_: string]: {[_: number]: ?StyleGlyph}},
558
+ glyphPositions: {[_: string]: {[_: number]: GlyphPosition}},
559
+ imagePositions: {[_: string]: ImagePosition},
560
+ lines: Array<TaggedString>,
561
+ lineHeight: number,
562
+ textAnchor: SymbolAnchor,
563
+ textJustify: TextJustify,
564
+ writingMode: 1 | 2,
565
+ spacing: number,
566
+ allowVerticalPlacement: boolean,
567
+ layoutTextSizeThisZoom: number) {
568
+
569
+ let x = 0;
570
+ let y = SHAPING_DEFAULT_OFFSET;
571
+
572
+ let maxLineLength = 0;
573
+ let maxLineHeight = 0;
574
+
575
+ const justify =
576
+ textJustify === 'right' ? 1 :
577
+ textJustify === 'left' ? 0 : 0.5;
578
+
579
+ let lineIndex = 0;
580
+ for (const line of lines) {
581
+ line.trim();
582
+
583
+ const lineMaxScale = line.getMaxScale();
584
+ const maxLineOffset = (lineMaxScale - 1) * ONE_EM;
585
+ const positionedLine = {positionedGlyphs: [], lineOffset: 0};
586
+ shaping.positionedLines[lineIndex] = positionedLine;
587
+ const positionedGlyphs = positionedLine.positionedGlyphs;
588
+ let lineOffset = 0.0;
589
+
590
+ if (!line.length()) {
591
+ y += lineHeight; // Still need a line feed after empty line
592
+ ++lineIndex;
593
+ continue;
594
+ }
595
+
596
+ for (let i = 0; i < line.length(); i++) {
597
+ const section = line.getSection(i);
598
+ const sectionIndex = line.getSectionIndex(i);
599
+ const codePoint = line.getCharCode(i);
600
+ let baselineOffset = 0.0;
601
+ let metrics = null;
602
+ let rect = null;
603
+ let imageName = null;
604
+ let verticalAdvance = ONE_EM;
605
+ const vertical = !(writingMode === WritingMode.horizontal ||
606
+ // Don't verticalize glyphs that have no upright orientation if vertical placement is disabled.
607
+ (!allowVerticalPlacement && !charHasUprightVerticalOrientation(codePoint)) ||
608
+ // If vertical placement is enabled, don't verticalize glyphs that
609
+ // are from complex text layout script, or whitespaces.
610
+ (allowVerticalPlacement && (whitespace[codePoint] || charInComplexShapingScript(codePoint))));
611
+
612
+ if (!section.imageName) {
613
+ const positions = glyphPositions[section.fontStack];
614
+ const glyphPosition = positions && positions[codePoint];
615
+ if (glyphPosition && glyphPosition.rect) {
616
+ rect = glyphPosition.rect;
617
+ metrics = glyphPosition.metrics;
618
+ } else {
619
+ const glyphs = glyphMap[section.fontStack];
620
+ const glyph = glyphs && glyphs[codePoint];
621
+ if (!glyph) continue;
622
+ metrics = glyph.metrics;
623
+ }
624
+
625
+ // We don't know the baseline, but since we're laying out
626
+ // at 24 points, we can calculate how much it will move when
627
+ // we scale up or down.
628
+ baselineOffset = (lineMaxScale - section.scale) * ONE_EM;
629
+ } else {
630
+ const imagePosition = imagePositions[section.imageName];
631
+ if (!imagePosition) continue;
632
+ imageName = section.imageName;
633
+ shaping.iconsInText = shaping.iconsInText || true;
634
+ rect = imagePosition.paddedRect;
635
+ const size = imagePosition.displaySize;
636
+ // If needed, allow to set scale factor for an image using
637
+ // alias "image-scale" that could be alias for "font-scale"
638
+ // when FormattedSection is an image section.
639
+ section.scale = section.scale * ONE_EM / layoutTextSizeThisZoom;
640
+
641
+ metrics = {width: size[0],
642
+ height: size[1],
643
+ left: IMAGE_PADDING,
644
+ top: -GLYPH_PBF_BORDER,
645
+ advance: vertical ? size[1] : size[0]};
646
+
647
+ // Difference between one EM and an image size.
648
+ // Aligns bottom of an image to a baseline level.
649
+ const imageOffset = ONE_EM - size[1] * section.scale;
650
+ baselineOffset = maxLineOffset + imageOffset;
651
+ verticalAdvance = metrics.advance;
652
+
653
+ // Difference between height of an image and one EM at max line scale.
654
+ // Pushes current line down if an image size is over 1 EM at max line scale.
655
+ const offset = vertical ? size[0] * section.scale - ONE_EM * lineMaxScale :
656
+ size[1] * section.scale - ONE_EM * lineMaxScale;
657
+ if (offset > 0 && offset > lineOffset) {
658
+ lineOffset = offset;
659
+ }
660
+ }
661
+
662
+ if (!vertical) {
663
+ positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + baselineOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
664
+ x += metrics.advance * section.scale + spacing;
665
+ } else {
666
+ shaping.verticalizable = true;
667
+ positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + baselineOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
668
+ x += verticalAdvance * section.scale + spacing;
669
+ }
670
+ }
671
+
672
+ // Only justify if we placed at least one glyph
673
+ if (positionedGlyphs.length !== 0) {
674
+ const lineLength = x - spacing;
675
+ maxLineLength = Math.max(lineLength, maxLineLength);
676
+ justifyLine(positionedGlyphs, 0, positionedGlyphs.length - 1, justify, lineOffset);
677
+ }
678
+
679
+ x = 0;
680
+ const currentLineHeight = lineHeight * lineMaxScale + lineOffset;
681
+ positionedLine.lineOffset = Math.max(lineOffset, maxLineOffset);
682
+ y += currentLineHeight;
683
+ maxLineHeight = Math.max(currentLineHeight, maxLineHeight);
684
+ ++lineIndex;
685
+ }
686
+
687
+ // Calculate the bounding box and justify / align text block.
688
+ const height = y - SHAPING_DEFAULT_OFFSET;
689
+ const {horizontalAlign, verticalAlign} = getAnchorAlignment(textAnchor);
690
+ align(shaping.positionedLines, justify, horizontalAlign, verticalAlign, maxLineLength, maxLineHeight, lineHeight, height, lines.length);
691
+
692
+ shaping.top += -verticalAlign * height;
693
+ shaping.bottom = shaping.top + height;
694
+ shaping.left += -horizontalAlign * maxLineLength;
695
+ shaping.right = shaping.left + maxLineLength;
696
+ }
697
+
698
+ // justify right = 1, left = 0, center = 0.5
699
+ function justifyLine(positionedGlyphs: Array<PositionedGlyph>,
700
+ start: number,
701
+ end: number,
702
+ justify: 1 | 0 | 0.5,
703
+ lineOffset: number) {
704
+ if (!justify && !lineOffset)
705
+ return;
706
+
707
+ const lastPositionedGlyph = positionedGlyphs[end];
708
+ const lastAdvance = lastPositionedGlyph.metrics.advance * lastPositionedGlyph.scale;
709
+ const lineIndent = (positionedGlyphs[end].x + lastAdvance) * justify;
710
+
711
+ for (let j = start; j <= end; j++) {
712
+ positionedGlyphs[j].x -= lineIndent;
713
+ positionedGlyphs[j].y += lineOffset;
714
+ }
715
+ }
716
+
717
+ function align(positionedLines: Array<PositionedLine>,
718
+ justify: number,
719
+ horizontalAlign: number,
720
+ verticalAlign: number,
721
+ maxLineLength: number,
722
+ maxLineHeight: number,
723
+ lineHeight: number,
724
+ blockHeight: number,
725
+ lineCount: number) {
726
+ const shiftX = (justify - horizontalAlign) * maxLineLength;
727
+ let shiftY = 0;
728
+
729
+ if (maxLineHeight !== lineHeight) {
730
+ shiftY = -blockHeight * verticalAlign - SHAPING_DEFAULT_OFFSET;
731
+ } else {
732
+ shiftY = (-verticalAlign * lineCount + 0.5) * lineHeight;
733
+ }
734
+
735
+ for (const line of positionedLines) {
736
+ for (const positionedGlyph of line.positionedGlyphs) {
737
+ positionedGlyph.x += shiftX;
738
+ positionedGlyph.y += shiftY;
739
+ }
740
+ }
741
+ }
742
+
743
+ export type PositionedIcon = {
744
+ image: ImagePosition,
745
+ top: number,
746
+ bottom: number,
747
+ left: number,
748
+ right: number,
749
+ collisionPadding?: [number, number, number, number]
750
+ };
751
+
752
+ function shapeIcon(image: ImagePosition, iconOffset: [number, number], iconAnchor: SymbolAnchor): PositionedIcon {
753
+ const {horizontalAlign, verticalAlign} = getAnchorAlignment(iconAnchor);
754
+ const dx = iconOffset[0];
755
+ const dy = iconOffset[1];
756
+ const x1 = dx - image.displaySize[0] * horizontalAlign;
757
+ const x2 = x1 + image.displaySize[0];
758
+ const y1 = dy - image.displaySize[1] * verticalAlign;
759
+ const y2 = y1 + image.displaySize[1];
760
+ return {image, top: y1, bottom: y2, left: x1, right: x2};
761
+ }
762
+
763
+ function fitIconToText(shapedIcon: PositionedIcon, shapedText: Shaping,
764
+ textFit: string,
765
+ padding: [ number, number, number, number ],
766
+ iconOffset: [ number, number ], fontScale: number): PositionedIcon {
767
+ assert(textFit !== 'none');
768
+ assert(Array.isArray(padding) && padding.length === 4);
769
+ assert(Array.isArray(iconOffset) && iconOffset.length === 2);
770
+
771
+ const image = shapedIcon.image;
772
+
773
+ let collisionPadding;
774
+ if (image.content) {
775
+ const content = image.content;
776
+ const pixelRatio = image.pixelRatio || 1;
777
+ collisionPadding = [
778
+ content[0] / pixelRatio,
779
+ content[1] / pixelRatio,
780
+ image.displaySize[0] - content[2] / pixelRatio,
781
+ image.displaySize[1] - content[3] / pixelRatio
782
+ ];
783
+ }
784
+
785
+ // We don't respect the icon-anchor, because icon-text-fit is set. Instead,
786
+ // the icon will be centered on the text, then stretched in the given
787
+ // dimensions.
788
+
789
+ const textLeft = shapedText.left * fontScale;
790
+ const textRight = shapedText.right * fontScale;
791
+
792
+ let top, right, bottom, left;
793
+ if (textFit === 'width' || textFit === 'both') {
794
+ // Stretched horizontally to the text width
795
+ left = iconOffset[0] + textLeft - padding[3];
796
+ right = iconOffset[0] + textRight + padding[1];
797
+ } else {
798
+ // Centered on the text
799
+ left = iconOffset[0] + (textLeft + textRight - image.displaySize[0]) / 2;
800
+ right = left + image.displaySize[0];
801
+ }
802
+
803
+ const textTop = shapedText.top * fontScale;
804
+ const textBottom = shapedText.bottom * fontScale;
805
+ if (textFit === 'height' || textFit === 'both') {
806
+ // Stretched vertically to the text height
807
+ top = iconOffset[1] + textTop - padding[0];
808
+ bottom = iconOffset[1] + textBottom + padding[2];
809
+ } else {
810
+ // Centered on the text
811
+ top = iconOffset[1] + (textTop + textBottom - image.displaySize[1]) / 2;
812
+ bottom = top + image.displaySize[1];
813
+ }
814
+
815
+ return {image, top, right, bottom, left, collisionPadding};
816
+ }