@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.
- package/LICENSE.txt +87 -0
- package/README.md +25 -0
- package/build/min/.dir +0 -0
- package/build/min/package.json +3 -0
- package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
- package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
- package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
- package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
- package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
- package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
- package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
- package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
- package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
- package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
- package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
- package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
- package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
- package/package.json +44 -0
- package/src/css/mapbox-gl.css +506 -0
- package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
- package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
- package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
- package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
- package/src/data/array_types.js +1138 -0
- package/src/data/bucket/circle_attributes.js +5 -0
- package/src/data/bucket/circle_bucket.js +118 -0
- package/src/data/bucket/fill_attributes.js +5 -0
- package/src/data/bucket/fill_bucket.js +166 -0
- package/src/data/bucket/fill_extrusion_attributes.js +11 -0
- package/src/data/bucket/fill_extrusion_bucket.js +247 -0
- package/src/data/bucket/heatmap_bucket.js +12 -0
- package/src/data/bucket/line_attributes.js +11 -0
- package/src/data/bucket/line_bucket.js +625 -0
- package/src/data/bucket/pattern_attributes.js +9 -0
- package/src/data/bucket/pattern_bucket_features.js +44 -0
- package/src/data/bucket/symbol_attributes.js +95 -0
- package/src/data/bucket/symbol_bucket.js +697 -0
- package/src/data/bucket.js +53 -0
- package/src/data/dem_data.js +126 -0
- package/src/data/extent.js +17 -0
- package/src/data/feature_index.js +254 -0
- package/src/data/index_array_type.js +14 -0
- package/src/data/load_geometry.js +42 -0
- package/src/data/pos_attributes.js +3 -0
- package/src/data/program_configuration.js +782 -0
- package/src/data/raster_bounds_attributes.js +6 -0
- package/src/data/segment.js +63 -0
- package/src/geo/coordinate.js +78 -0
- package/src/geo/lng_lat.js +129 -0
- package/src/geo/lng_lat_bounds.js +253 -0
- package/src/geo/transform.js +605 -0
- package/src/gl/color_mode.js +21 -0
- package/src/gl/context.js +193 -0
- package/src/gl/cull_face_mode.js +22 -0
- package/src/gl/depth_mode.js +18 -0
- package/src/gl/framebuffer.js +28 -0
- package/src/gl/index_buffer.js +52 -0
- package/src/gl/stencil_mode.js +17 -0
- package/src/gl/types.js +0 -0
- package/src/gl/value.js +676 -0
- package/src/gl/vertex_buffer.js +101 -0
- package/src/index.js +50 -0
- package/src/render/draw_background.js +60 -0
- package/src/render/draw_circle.js +55 -0
- package/src/render/draw_collision_debug.js +45 -0
- package/src/render/draw_debug.js +429 -0
- package/src/render/draw_fill.js +143 -0
- package/src/render/draw_fill_extrusion.js +101 -0
- package/src/render/draw_heatmap.js +159 -0
- package/src/render/draw_hillshade.js +144 -0
- package/src/render/draw_line.js +99 -0
- package/src/render/draw_raster.js +151 -0
- package/src/render/draw_symbol.js +231 -0
- package/src/render/glyph_atlas.js +55 -0
- package/src/render/glyph_manager.js +145 -0
- package/src/render/image_atlas.js +97 -0
- package/src/render/image_manager.js +183 -0
- package/src/render/line_atlas.js +139 -0
- package/src/render/painter.js +483 -0
- package/src/render/program/background_program.js +46 -0
- package/src/render/program/circle_program.js +40 -0
- package/src/render/program/clipping_mask_program.js +11 -0
- package/src/render/program/collision_program.js +28 -0
- package/src/render/program/debug_program.js +13 -0
- package/src/render/program/fill_extrusion_program.js +76 -0
- package/src/render/program/fill_program.js +60 -0
- package/src/render/program/heatmap_program.js +46 -0
- package/src/render/program/hillshade_program.js +77 -0
- package/src/render/program/line_program.js +119 -0
- package/src/render/program/pattern.js +57 -0
- package/src/render/program/program_uniforms.js +46 -0
- package/src/render/program/raster_program.js +50 -0
- package/src/render/program/symbol_program.js +112 -0
- package/src/render/program.js +133 -0
- package/src/render/texture.js +88 -0
- package/src/render/tile_mask.js +108 -0
- package/src/render/uniform_binding.js +129 -0
- package/src/render/vertex_array_object.js +155 -0
- package/src/shaders/README.md +42 -0
- package/src/shaders/_prelude.fragment.glsl +17 -0
- package/src/shaders/_prelude.vertex.glsl +73 -0
- package/src/shaders/background.fragment.glsl +10 -0
- package/src/shaders/background.vertex.glsl +7 -0
- package/src/shaders/background_pattern.fragment.glsl +28 -0
- package/src/shaders/background_pattern.vertex.glsl +20 -0
- package/src/shaders/circle.fragment.glsl +39 -0
- package/src/shaders/circle.vertex.glsl +63 -0
- package/src/shaders/clipping_mask.fragment.glsl +3 -0
- package/src/shaders/clipping_mask.vertex.glsl +7 -0
- package/src/shaders/collision_box.fragment.glsl +21 -0
- package/src/shaders/collision_box.vertex.glsl +26 -0
- package/src/shaders/collision_circle.fragment.glsl +34 -0
- package/src/shaders/collision_circle.vertex.glsl +36 -0
- package/src/shaders/debug.fragment.glsl +5 -0
- package/src/shaders/debug.vertex.glsl +7 -0
- package/src/shaders/encode_attribute.js +19 -0
- package/src/shaders/fill.fragment.glsl +13 -0
- package/src/shaders/fill.vertex.glsl +13 -0
- package/src/shaders/fill_extrusion.fragment.glsl +16 -0
- package/src/shaders/fill_extrusion.vertex.glsl +66 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
- package/src/shaders/fill_outline.fragment.glsl +17 -0
- package/src/shaders/fill_outline.vertex.glsl +17 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
- package/src/shaders/fill_pattern.fragment.glsl +36 -0
- package/src/shaders/fill_pattern.vertex.glsl +36 -0
- package/src/shaders/heatmap.fragment.glsl +21 -0
- package/src/shaders/heatmap.vertex.glsl +53 -0
- package/src/shaders/heatmap_texture.fragment.glsl +14 -0
- package/src/shaders/heatmap_texture.vertex.glsl +11 -0
- package/src/shaders/hillshade.fragment.glsl +52 -0
- package/src/shaders/hillshade.vertex.glsl +11 -0
- package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
- package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
- package/src/shaders/index.js +194 -0
- package/src/shaders/line.fragment.glsl +28 -0
- package/src/shaders/line.vertex.glsl +84 -0
- package/src/shaders/line_gradient.fragment.glsl +34 -0
- package/src/shaders/line_gradient.vertex.glsl +84 -0
- package/src/shaders/line_pattern.fragment.glsl +69 -0
- package/src/shaders/line_pattern.vertex.glsl +88 -0
- package/src/shaders/line_sdf.fragment.glsl +44 -0
- package/src/shaders/line_sdf.vertex.glsl +95 -0
- package/src/shaders/raster.fragment.glsl +52 -0
- package/src/shaders/raster.vertex.glsl +21 -0
- package/src/shaders/symbol_icon.fragment.glsl +17 -0
- package/src/shaders/symbol_icon.vertex.glsl +91 -0
- package/src/shaders/symbol_sdf.fragment.glsl +50 -0
- package/src/shaders/symbol_sdf.vertex.glsl +117 -0
- package/src/source/geojson_source.js +267 -0
- package/src/source/geojson_worker_source.js +210 -0
- package/src/source/geojson_wrapper.js +67 -0
- package/src/source/image_source.js +213 -0
- package/src/source/load_tilejson.js +40 -0
- package/src/source/pixels_to_tile_units.js +17 -0
- package/src/source/query_features.js +198 -0
- package/src/source/raster_dem_tile_source.js +140 -0
- package/src/source/raster_dem_tile_worker_source.js +26 -0
- package/src/source/raster_tile_source.js +126 -0
- package/src/source/rtl_text_plugin.js +63 -0
- package/src/source/source.js +75 -0
- package/src/source/source_cache.js +794 -0
- package/src/source/source_state.js +55 -0
- package/src/source/tile.js +332 -0
- package/src/source/tile_bounds.js +40 -0
- package/src/source/tile_cache.js +122 -0
- package/src/source/tile_id.js +150 -0
- package/src/source/vector_tile_source.js +144 -0
- package/src/source/vector_tile_worker_source.js +126 -0
- package/src/source/worker.js +175 -0
- package/src/source/worker_source.js +14 -0
- package/src/source/worker_tile.js +199 -0
- package/src/style/create_style_layer.js +25 -0
- package/src/style/evaluation_parameters.js +45 -0
- package/src/style/light.js +112 -0
- package/src/style/load_glyph_range.js +17 -0
- package/src/style/load_sprite.js +26 -0
- package/src/style/parse_glyph_pbf.js +45 -0
- package/src/style/pauseable_placement.js +88 -0
- package/src/style/properties.js +691 -0
- package/src/style/query_utils.js +39 -0
- package/src/style/style.js +955 -0
- package/src/style/style_layer/background_style_layer.js +11 -0
- package/src/style/style_layer/background_style_layer_properties.js +25 -0
- package/src/style/style_layer/circle_style_layer.js +93 -0
- package/src/style/style_layer/circle_style_layer_properties.js +76 -0
- package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
- package/src/style/style_layer/fill_style_layer.js +46 -0
- package/src/style/style_layer/fill_style_layer_properties.js +45 -0
- package/src/style/style_layer/heatmap_style_layer.js +51 -0
- package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
- package/src/style/style_layer/hillshade_style_layer.js +15 -0
- package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
- package/src/style/style_layer/line_style_layer.js +129 -0
- package/src/style/style_layer/line_style_layer_properties.js +104 -0
- package/src/style/style_layer/raster_style_layer.js +11 -0
- package/src/style/style_layer/raster_style_layer_properties.js +55 -0
- package/src/style/style_layer/symbol_style_layer.js +66 -0
- package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
- package/src/style/style_layer.js +183 -0
- package/src/style/style_layer_index.js +61 -0
- package/src/style/zoom_history.js +36 -0
- package/src/style-spec/deref.js +51 -0
- package/src/style-spec/error/parsing_error.js +8 -0
- package/src/style-spec/error/validation_error.js +10 -0
- package/src/style-spec/expression/compound_expression.js +118 -0
- package/src/style-spec/expression/definitions/array.js +82 -0
- package/src/style-spec/expression/definitions/assertion.js +69 -0
- package/src/style-spec/expression/definitions/at.js +57 -0
- package/src/style-spec/expression/definitions/case.js +73 -0
- package/src/style-spec/expression/definitions/coalesce.js +68 -0
- package/src/style-spec/expression/definitions/coercion.js +96 -0
- package/src/style-spec/expression/definitions/collator.js +102 -0
- package/src/style-spec/expression/definitions/equals.js +93 -0
- package/src/style-spec/expression/definitions/index.js +407 -0
- package/src/style-spec/expression/definitions/interpolate.js +235 -0
- package/src/style-spec/expression/definitions/length.js +54 -0
- package/src/style-spec/expression/definitions/let.js +60 -0
- package/src/style-spec/expression/definitions/literal.js +64 -0
- package/src/style-spec/expression/definitions/match.js +142 -0
- package/src/style-spec/expression/definitions/step.js +116 -0
- package/src/style-spec/expression/definitions/var.js +38 -0
- package/src/style-spec/expression/evaluation_context.js +35 -0
- package/src/style-spec/expression/index.js +329 -0
- package/src/style-spec/expression/is_constant.js +63 -0
- package/src/style-spec/expression/parsing_context.js +213 -0
- package/src/style-spec/expression/parsing_error.js +9 -0
- package/src/style-spec/expression/runtime_error.js +12 -0
- package/src/style-spec/expression/scope.js +34 -0
- package/src/style-spec/expression/stops.js +37 -0
- package/src/style-spec/expression/types.js +77 -0
- package/src/style-spec/expression/values.js +126 -0
- package/src/style-spec/feature_filter/README.md +55 -0
- package/src/style-spec/feature_filter/index.js +158 -0
- package/src/style-spec/function/convert.js +256 -0
- package/src/style-spec/function/index.js +299 -0
- package/src/style-spec/group_by_layout.js +68 -0
- package/src/style-spec/reference/v8.json +5356 -0
- package/src/style-spec/util/color.js +73 -0
- package/src/style-spec/util/color_spaces.js +128 -0
- package/src/style-spec/util/eval_support.js +8 -0
- package/src/style-spec/util/get_type.js +18 -0
- package/src/style-spec/util/interpolate.js +21 -0
- package/src/style-spec/util/properties.js +17 -0
- package/src/style-spec/util/ref_properties.js +1 -0
- package/src/style-spec/util/result.js +19 -0
- package/src/symbol/anchor.js +21 -0
- package/src/symbol/check_max_angle.js +75 -0
- package/src/symbol/clip_line.js +73 -0
- package/src/symbol/collision_feature.js +230 -0
- package/src/symbol/collision_index.js +379 -0
- package/src/symbol/cross_tile_symbol_index.js +270 -0
- package/src/symbol/get_anchors.js +177 -0
- package/src/symbol/grid_index.js +318 -0
- package/src/symbol/mergelines.js +75 -0
- package/src/symbol/opacity_state.js +21 -0
- package/src/symbol/placement.js +563 -0
- package/src/symbol/projection.js +601 -0
- package/src/symbol/quads.js +173 -0
- package/src/symbol/shaping.js +347 -0
- package/src/symbol/symbol_layout.js +519 -0
- package/src/symbol/symbol_size.js +110 -0
- package/src/symbol/transform_text.js +16 -0
- package/src/ui/anchor.js +24 -0
- package/src/ui/bind_handlers.js +199 -0
- package/src/ui/camera.js +954 -0
- package/src/ui/events.js +210 -0
- package/src/ui/handler/box_zoom.js +151 -0
- package/src/ui/handler/dblclick_zoom.js +91 -0
- package/src/ui/handler/drag_pan.js +285 -0
- package/src/ui/handler/drag_rotate.js +290 -0
- package/src/ui/handler/frame.js +28 -0
- package/src/ui/handler/inertia.js +45 -0
- package/src/ui/handler/keyboard.js +148 -0
- package/src/ui/handler/scroll_zoom.js +284 -0
- package/src/ui/handler/touch_zoom_rotate.js +263 -0
- package/src/ui/map.js +1645 -0
- package/src/util/actor.js +104 -0
- package/src/util/async.js +23 -0
- package/src/util/browser.js +61 -0
- package/src/util/callback.js +26 -0
- package/src/util/classify_rings.js +43 -0
- package/src/util/color_ramp.js +24 -0
- package/src/util/config.js +24 -0
- package/src/util/dictionary_coder.js +25 -0
- package/src/util/dispatcher.js +68 -0
- package/src/util/dom.js +102 -0
- package/src/util/evented.js +182 -0
- package/src/util/find_pole_of_inaccessibility.js +129 -0
- package/src/util/global_worker_pool.js +15 -0
- package/src/util/image.js +124 -0
- package/src/util/interpolate.js +5 -0
- package/src/util/intersection_tests.js +207 -0
- package/src/util/is_char_in_unicode_block.js +287 -0
- package/src/util/loader/image.js +32 -0
- package/src/util/object.js +178 -0
- package/src/util/script_detection.js +337 -0
- package/src/util/struct_array.js +197 -0
- package/src/util/task_queue.js +57 -0
- package/src/util/throttle.js +26 -0
- package/src/util/tile_cover.js +114 -0
- package/src/util/token.js +13 -0
- package/src/util/unique_id.js +12 -0
- package/src/util/util.js +192 -0
- package/src/util/vectortile_to_geojson.js +44 -0
- package/src/util/verticalize_punctuation.js +112 -0
- package/src/util/warn.js +21 -0
- package/src/util/web_worker.js +5 -0
- package/src/util/web_worker_transfer.js +228 -0
- 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
|
+
}
|