@tangram.gl/basemap-layers 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -2
- package/THIRD-PARTY-NOTICES.md +205 -0
- package/dist/geojson-worker.js +2160 -0
- package/dist/geojson-worker.js.map +6 -0
- package/dist/index.cjs +11388 -0
- package/dist/index.cjs.map +6 -0
- package/dist/index.js +11369 -0
- package/dist/index.js.map +6 -0
- package/dist/map-style.cjs +445 -0
- package/dist/map-style.cjs.map +6 -0
- package/dist/map-style.js +431 -0
- package/dist/map-style.js.map +6 -0
- package/dist/types/arabic-shaping.d.ts +7 -0
- package/dist/types/atmosphere-layer.d.ts +10 -0
- package/dist/types/basemap-layer.d.ts +150 -0
- package/dist/types/bidi.d.ts +8 -0
- package/dist/types/circle-layer.d.ts +49 -0
- package/dist/types/fill-extrusion-lighting-extension.d.ts +49 -0
- package/dist/types/fill-outline-extension.d.ts +22 -0
- package/dist/types/fill-pattern.d.ts +99 -0
- package/dist/types/fill-style-extensions.d.ts +100 -0
- package/dist/types/geojson-source.d.ts +29 -0
- package/dist/types/geojson-tiler.d.ts +48 -0
- package/dist/types/geojson-worker.d.ts +40 -0
- package/dist/types/globe-horizon-extension.d.ts +61 -0
- package/dist/types/globe-layers.d.ts +239 -0
- package/dist/types/globe-line-angle-extension.d.ts +37 -0
- package/dist/types/glyph-font-renderer.d.ts +37 -0
- package/dist/types/glyph-pbf.d.ts +37 -0
- package/dist/types/glyph-store.d.ts +103 -0
- package/dist/types/grid-index.d.ts +47 -0
- package/dist/types/hillshade-layer.d.ts +154 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/is-globe-viewport.d.ts +2 -0
- package/dist/types/label-font-renderer.d.ts +18 -0
- package/dist/types/label-placement.d.ts +247 -0
- package/dist/types/label-text-layer.d.ts +231 -0
- package/dist/types/line-blur-extension.d.ts +73 -0
- package/dist/types/line-glyphs.d.ts +60 -0
- package/dist/types/line-placement.d.ts +93 -0
- package/dist/types/map-style-loader.d.ts +48 -0
- package/dist/types/map-style-schema.d.ts +72 -0
- package/dist/types/map-style.d.ts +6 -0
- package/dist/types/mapbox-style.d.ts +40 -0
- package/dist/types/mvt-label-layer.d.ts +923 -0
- package/dist/types/polylabel.d.ts +17 -0
- package/dist/types/raster-color-extension.d.ts +146 -0
- package/dist/types/shared-texture.d.ts +34 -0
- package/dist/types/sort-key.d.ts +10 -0
- package/dist/types/sprite.d.ts +82 -0
- package/dist/types/style-accessor.d.ts +45 -0
- package/dist/types/style-expression.d.ts +83 -0
- package/dist/types/style-resolver.d.ts +94 -0
- package/dist/types/text-font.d.ts +36 -0
- package/dist/types/text-halo-blur-extension.d.ts +55 -0
- package/dist/types/text-layout.d.ts +71 -0
- package/dist/types/util.d.ts +22 -0
- package/dist/types/zoom-paint-extension.d.ts +72 -0
- package/package.json +80 -3
- package/src/arabic-shaping.ts +366 -0
- package/src/atmosphere-layer.ts +19 -0
- package/src/basemap-layer.ts +533 -0
- package/src/bidi.ts +199 -0
- package/src/circle-layer.ts +191 -0
- package/src/fill-extrusion-lighting-extension.ts +206 -0
- package/src/fill-outline-extension.ts +70 -0
- package/src/fill-pattern.ts +400 -0
- package/src/fill-style-extensions.ts +177 -0
- package/src/geojson-source.ts +318 -0
- package/src/geojson-tiler.ts +185 -0
- package/src/geojson-worker.ts +98 -0
- package/src/globe-horizon-extension.ts +64 -0
- package/src/globe-layers.ts +3487 -0
- package/src/globe-line-angle-extension.ts +131 -0
- package/src/glyph-font-renderer.ts +173 -0
- package/src/glyph-pbf.ts +164 -0
- package/src/glyph-store.ts +326 -0
- package/src/grid-index.ts +177 -0
- package/src/hillshade-layer.ts +775 -0
- package/src/index.ts +18 -0
- package/src/is-globe-viewport.ts +24 -0
- package/src/label-font-renderer.ts +159 -0
- package/src/label-placement.ts +727 -0
- package/src/label-text-layer.ts +913 -0
- package/src/line-blur-extension.ts +237 -0
- package/src/line-glyphs.ts +364 -0
- package/src/line-placement.ts +446 -0
- package/src/map-style-loader.ts +56 -0
- package/src/map-style-schema.ts +83 -0
- package/src/map-style.ts +23 -0
- package/src/mapbox-style.ts +168 -0
- package/src/mvt-label-layer.ts +3744 -0
- package/src/polylabel.ts +312 -0
- package/src/raster-color-extension.ts +245 -0
- package/src/shared-texture.ts +153 -0
- package/src/sort-key.ts +63 -0
- package/src/sprite.ts +244 -0
- package/src/style-accessor.ts +95 -0
- package/src/style-expression.ts +327 -0
- package/src/style-resolver.ts +301 -0
- package/src/text-font.ts +150 -0
- package/src/text-halo-blur-extension.ts +115 -0
- package/src/text-layout.ts +441 -0
- package/src/util.ts +47 -0
- package/src/zoom-paint-extension.ts +207 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether `text-letter-spacing` applies to `text`: as in MapLibre, text with any character of a
|
|
3
|
+
* cursive script (Arabic, Duployan, Mongolian, Old Uyghur, Syriac) is not letter-spaced.
|
|
4
|
+
*/
|
|
5
|
+
export declare function allowsLetterSpacing(text: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* `text-transform`, as MapLibre applies it: locale-aware upper or lower case, then Arabic shaping
|
|
8
|
+
* (see {@link applyArabicShaping}), so that the glyphs looked up, measured and drawn are those of
|
|
9
|
+
* the shapes the letters take.
|
|
10
|
+
*/
|
|
11
|
+
export declare function transformText(text: string, transform: unknown): string;
|
|
12
|
+
/**
|
|
13
|
+
* Longest label, in UTF-16 code units, that {@link wrapText} wraps. Line breaking is quadratic in
|
|
14
|
+
* the number of break opportunities, and tile data is untrusted, so longer text is returned
|
|
15
|
+
* unwrapped. Real labels are far shorter; at this length even ideographic text, where every
|
|
16
|
+
* character is a break opportunity, costs tens of thousands of steps.
|
|
17
|
+
*/
|
|
18
|
+
export declare const MAX_WRAPPED_TEXT_LENGTH = 256;
|
|
19
|
+
/**
|
|
20
|
+
* Line-breaking work that {@link wrapText} may still spend, shared by the labels of one tile and
|
|
21
|
+
* style layer. Each wrap costs an upper bound of its steps: one per character plus one per pair of
|
|
22
|
+
* break opportunities. A label whose cost exceeds what is left is returned unwrapped.
|
|
23
|
+
*/
|
|
24
|
+
export type WrapBudget = {
|
|
25
|
+
steps: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Breaks `text` into lines no wider than `maxWidth` ems where it can, with MapLibre's balanced
|
|
29
|
+
* line breaking, and returns the lines joined by '\n', each in the order it is drawn (see
|
|
30
|
+
* {@link orderBidirectionalText}). Advances from `measure` are in ems; words without break
|
|
31
|
+
* opportunities stay intact, even when they exceed the requested width. Text longer than
|
|
32
|
+
* {@link MAX_WRAPPED_TEXT_LENGTH}, or whose cost exceeds `budget`, is not broken.
|
|
33
|
+
*/
|
|
34
|
+
export declare function wrapText(text: string, maxWidth: number, measure: (character: string) => number, budget?: WrapBudget): string;
|
|
35
|
+
/**
|
|
36
|
+
* Puts text that is not wrapped, such as a label along a line, into the order it is drawn: right-
|
|
37
|
+
* to-left runs reversed, as MapLibre does. Text without right-to-left characters is unchanged.
|
|
38
|
+
*/
|
|
39
|
+
export declare function orderBidirectionalText(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether text can be measured with a canvas here; otherwise {@link getCharacterWidthMeasurer}
|
|
42
|
+
* returns {@link FALLBACK_CHARACTER_WIDTH} for every character.
|
|
43
|
+
*/
|
|
44
|
+
export declare function canMeasureText(): boolean;
|
|
45
|
+
/** Advance in ems used when canvas measurement is unavailable, as for missing atlas glyphs. */
|
|
46
|
+
export declare const FALLBACK_CHARACTER_WIDTH = 0.5;
|
|
47
|
+
/**
|
|
48
|
+
* Bounds on the measurement caches: fonts and characters both come from untrusted style and tile
|
|
49
|
+
* data. A full cache is cleared rather than grown.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MAX_CACHED_FONTS = 32;
|
|
52
|
+
export declare const MAX_CACHED_CHARACTERS = 4096;
|
|
53
|
+
/**
|
|
54
|
+
* Forgets the character advances measured for a CSS font, so they are measured again: a font that
|
|
55
|
+
* was still loading was measured with a fallback font. When the advances measured before differ
|
|
56
|
+
* from those measured now, or were not all kept, the font's revision changes.
|
|
57
|
+
*/
|
|
58
|
+
export declare function forgetCharacterWidths(fontWeight: number | string, fontFamily: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* A number that changes whenever {@link forgetCharacterWidths} finds a font's advances changed, so
|
|
61
|
+
* that what was measured in it before can be measured again. Loading another font, or a measurer
|
|
62
|
+
* evicted from a full cache, measuring the same advances again, does not change it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getCharacterWidthsRevision(fontWeight: number | string, fontFamily: string): number;
|
|
65
|
+
/**
|
|
66
|
+
* Returns a function giving a character's advance width in ems for a CSS font, measured the way
|
|
67
|
+
* deck.gl's TextLayer builds its font atlas: at 64px, then divided by 64. Measurers and character
|
|
68
|
+
* advances are cached, up to {@link MAX_CACHED_FONTS} and {@link MAX_CACHED_CHARACTERS}.
|
|
69
|
+
* Environments without a canvas 2D context use a half-em advance.
|
|
70
|
+
*/
|
|
71
|
+
export declare function getCharacterWidthMeasurer(fontWeight: number | string, fontFamily: string): (character: string) => number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type FeatureLike = {
|
|
2
|
+
properties?: Record<string, unknown>;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link featuresArrayToObject}.
|
|
6
|
+
*/
|
|
7
|
+
export type FeaturesArrayToObjectOptions = {
|
|
8
|
+
/** Features to group by the requested layer-name property. */
|
|
9
|
+
features?: FeatureLike[];
|
|
10
|
+
/** Feature property name that contains the source-layer identifier. */
|
|
11
|
+
layerName?: string;
|
|
12
|
+
/** Optional source name wrapper for the returned object. */
|
|
13
|
+
sourceName?: string | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Converts an array of GeoJSON-like features into an object keyed by layer
|
|
17
|
+
* name, optionally wrapped by a source identifier.
|
|
18
|
+
*/
|
|
19
|
+
export declare function featuresArrayToObject(options?: FeaturesArrayToObjectOptions): Record<string, FeatureLike[] | Record<string, FeatureLike[]>>;
|
|
20
|
+
/** Whether two lists hold the same items, by identity. */
|
|
21
|
+
export declare function isSameList(a: readonly unknown[] | undefined, b: readonly unknown[]): boolean;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { LayerExtension } from '@deck.gl/core';
|
|
2
|
+
import type { Accessor, Layer, LayerContext } from '@deck.gl/core';
|
|
3
|
+
import type { Device, Texture } from '@luma.gl/core';
|
|
4
|
+
/** The most style layers whose paint one layer can take from `ZoomPaintExtension`. */
|
|
5
|
+
export declare const MAX_ZOOM_PAINT_PARTS = 64;
|
|
6
|
+
/** The rows of `ZoomPaintValues`. */
|
|
7
|
+
export declare const ZOOM_PAINT_WIDTH_ROW = 0;
|
|
8
|
+
export declare const ZOOM_PAINT_LINE_COLOR_ROW = 1;
|
|
9
|
+
export declare const ZOOM_PAINT_FILL_COLOR_ROW = 2;
|
|
10
|
+
/**
|
|
11
|
+
* The paint of each style layer drawn by a layer, at one zoom: an RGBA texel per style layer
|
|
12
|
+
* (column) and value (row), `MAX_ZOOM_PAINT_PARTS` by 3. Column `i` is the style layer that
|
|
13
|
+
* `getStylePart` returns `i` for.
|
|
14
|
+
*
|
|
15
|
+
* - `ZOOM_PAINT_WIDTH_ROW`: in red, a factor of the layer's width attribute.
|
|
16
|
+
* - `ZOOM_PAINT_LINE_COLOR_ROW`, `ZOOM_PAINT_FILL_COLOR_ROW`: a color in 0-1, which replaces the
|
|
17
|
+
* layer's color attribute unless its alpha is negative: the attribute then holds the style
|
|
18
|
+
* layer's per-feature colors.
|
|
19
|
+
*/
|
|
20
|
+
export type ZoomPaintValues = Float32Array;
|
|
21
|
+
/** Creates values with every width factor 1 and every color taken from the attributes. */
|
|
22
|
+
export declare function createZoomPaintValues(): ZoomPaintValues;
|
|
23
|
+
/** The index of a style layer's texel in a row of `ZoomPaintValues`. */
|
|
24
|
+
export declare function getZoomPaintOffset(row: number, part: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* The paint of the style layers drawn by a layer, and the texture that hands it to the shaders,
|
|
27
|
+
* which `destroy` releases.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ZoomPaint {
|
|
30
|
+
readonly getValues: () => ZoomPaintValues;
|
|
31
|
+
private texture;
|
|
32
|
+
private written;
|
|
33
|
+
/** `getValues` returns the values at the current zoom, the same array while they are unchanged. */
|
|
34
|
+
constructor(getValues: () => ZoomPaintValues);
|
|
35
|
+
/** The texture of the current values, created on first use. */
|
|
36
|
+
getTexture(device: Device): Texture;
|
|
37
|
+
destroy(): void;
|
|
38
|
+
}
|
|
39
|
+
export type ZoomPaintExtensionProps = {
|
|
40
|
+
/** The paint to apply; the layer draws its attributes as they are without it. */
|
|
41
|
+
zoomPaint?: ZoomPaint | null;
|
|
42
|
+
/** Which of `zoomPaint`'s style layers each object belongs to. */
|
|
43
|
+
getStylePart?: Accessor<any, number>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Takes the zoom-dependent paint of the style layers a `PathLayer` or flat `SolidPolygonLayer`
|
|
47
|
+
* draws from a texture instead of attributes: per style layer, its line width and, when they are
|
|
48
|
+
* the same for all of its features, its colors. The values are read when the layer draws, so a
|
|
49
|
+
* zoom step changes a small texture, shared by every layer with the same `zoomPaint`: the layers'
|
|
50
|
+
* props, and so their attributes, stay the same. Each object's style layer is an attribute, which
|
|
51
|
+
* changes only with the data.
|
|
52
|
+
*
|
|
53
|
+
* The width factor applies after `widthMinPixels` and `widthMaxPixels`, which must not clamp.
|
|
54
|
+
* The owner of a `ZoomPaint` destroys its texture. WebGL only.
|
|
55
|
+
*/
|
|
56
|
+
export declare class ZoomPaintExtension extends LayerExtension {
|
|
57
|
+
static extensionName: string;
|
|
58
|
+
static defaultProps: {
|
|
59
|
+
zoomPaint: {
|
|
60
|
+
type: string;
|
|
61
|
+
value: null;
|
|
62
|
+
};
|
|
63
|
+
getStylePart: {
|
|
64
|
+
type: string;
|
|
65
|
+
value: number;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
isEnabled(layer: Layer): boolean;
|
|
69
|
+
getShaders(this: Layer<ZoomPaintExtensionProps>, extension: this): any;
|
|
70
|
+
initializeState(this: Layer<ZoomPaintExtensionProps>, context: LayerContext, extension: this): void;
|
|
71
|
+
draw(this: Layer<ZoomPaintExtensionProps>, params: any, extension: this): void;
|
|
72
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,83 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangram.gl/basemap-layers",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Basemap layer and map-style helpers for deck.gl.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"deck.gl",
|
|
8
|
+
"mapbox",
|
|
9
|
+
"basemap"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/visgl/tangram.gl.git",
|
|
14
|
+
"directory": "modules/basemap-layers"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"types": "./dist/types/index.d.ts",
|
|
22
|
+
"main": "./dist/index.cjs",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/types/index.d.ts",
|
|
27
|
+
"require": "./dist/index.cjs",
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./map-style": {
|
|
32
|
+
"types": "./dist/types/map-style.d.ts",
|
|
33
|
+
"require": "./dist/map-style.cjs",
|
|
34
|
+
"import": "./dist/map-style.js",
|
|
35
|
+
"default": "./dist/map-style.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"src",
|
|
41
|
+
"THIRD-PARTY-NOTICES.md"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "yarn build:types && yarn build:bundle && yarn build:worker",
|
|
45
|
+
"build:types": "node ../../scripts/build-package-types.mjs modules/basemap-layers index.ts map-style.ts",
|
|
46
|
+
"build:bundle": "ocular-bundle src/index.ts --env=dev --format=esm --output=dist/index.js --externals=@loaders.gl/loader-utils,@loaders.gl/mvt,@mapbox/tiny-sdf,@maplibre/geojson-vt,@maplibre/maplibre-gl-style-spec,@turf/polygon-to-line,bidi-js,zod --sourcemap=true --sourcesContent=false && ocular-bundle src/map-style.ts --env=dev --format=esm --output=dist/map-style.js --externals=@loaders.gl/loader-utils,@loaders.gl/mvt,@mapbox/tiny-sdf,@maplibre/geojson-vt,@maplibre/maplibre-gl-style-spec,@turf/polygon-to-line,bidi-js,zod --sourcemap=true --sourcesContent=false && ocular-bundle src/index.ts --env=dev --format=cjs --output=dist/index.cjs --externals=@loaders.gl/loader-utils,@loaders.gl/mvt,@mapbox/tiny-sdf,@maplibre/geojson-vt,@maplibre/maplibre-gl-style-spec,@turf/polygon-to-line,bidi-js,zod --sourcemap=true --sourcesContent=false && ocular-bundle src/map-style.ts --env=dev --format=cjs --output=dist/map-style.cjs --externals=@loaders.gl/loader-utils,@loaders.gl/mvt,@mapbox/tiny-sdf,@maplibre/geojson-vt,@maplibre/maplibre-gl-style-spec,@turf/polygon-to-line,bidi-js,zod --sourcemap=true --sourcesContent=false",
|
|
47
|
+
"build:worker": "ocular-bundle src/geojson-worker.ts --env=dev --format=iife --output=dist/geojson-worker.js --sourcemap=true --sourcesContent=false",
|
|
48
|
+
"prepack": "yarn build",
|
|
49
|
+
"test": "yarn --cwd ../.. vitest run --config modules/basemap-layers/vitest.config.ts",
|
|
50
|
+
"test-watch": "yarn --cwd ../.. vitest --config modules/basemap-layers/vitest.config.ts"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@deck.gl-community/geo-layers": "~9.4.2",
|
|
54
|
+
"@deck.gl/test-utils": "~9.4.0",
|
|
55
|
+
"@fontsource/montserrat": "5.3.0",
|
|
56
|
+
"@fontsource/noto-sans": "5.3.0",
|
|
57
|
+
"@fontsource/open-sans": "5.3.0",
|
|
58
|
+
"@loaders.gl/core": "^4.5.1",
|
|
59
|
+
"@vis.gl/dev-tools": "2.0.0-alpha.8",
|
|
60
|
+
"maplibre-gl": "6.13.0",
|
|
61
|
+
"vitest": "^4.0.18"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@loaders.gl/loader-utils": "^4.5.1",
|
|
65
|
+
"@loaders.gl/mvt": "^4.5.1",
|
|
66
|
+
"@mapbox/tiny-sdf": "^2.0.5",
|
|
67
|
+
"@maplibre/geojson-vt": "^6.1.2",
|
|
68
|
+
"@maplibre/maplibre-gl-style-spec": "^24.8.1",
|
|
69
|
+
"@turf/polygon-to-line": "^6.0.3",
|
|
70
|
+
"bidi-js": "^1.1.0",
|
|
71
|
+
"zod": "^4.0.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"@deck.gl-community/geo-layers": "~9.4.2",
|
|
75
|
+
"@deck.gl/core": "~9.4.0",
|
|
76
|
+
"@deck.gl/extensions": "~9.4.0",
|
|
77
|
+
"@deck.gl/geo-layers": "~9.4.0",
|
|
78
|
+
"@deck.gl/layers": "~9.4.0",
|
|
79
|
+
"@loaders.gl/core": "^4.5.1",
|
|
80
|
+
"@luma.gl/core": "~9.4.0",
|
|
81
|
+
"@luma.gl/engine": "~9.4.0"
|
|
82
|
+
}
|
|
6
83
|
}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
// tangram-layers
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// deck.gl-community
|
|
6
|
+
// SPDX-License-Identifier: MIT AND BSD-3-Clause AND Unicode-3.0
|
|
7
|
+
// Copyright (c) vis.gl contributors
|
|
8
|
+
// Copyright (c) 2023, MapLibre contributors
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @license
|
|
12
|
+
* Portions of this file are adapted from MapLibre GL JS v6.13.0, src/symbol/arabic_shaping.ts and the
|
|
13
|
+
* tables its build/generate-unicode-data.ts writes to src/util/unicode_properties.g.ts,
|
|
14
|
+
* under this license:
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2023, MapLibre contributors
|
|
17
|
+
*
|
|
18
|
+
* All rights reserved.
|
|
19
|
+
*
|
|
20
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
21
|
+
* are permitted provided that the following conditions are met:
|
|
22
|
+
*
|
|
23
|
+
* * Redistributions of source code must retain the above copyright notice,
|
|
24
|
+
* this list of conditions and the following disclaimer.
|
|
25
|
+
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
26
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
27
|
+
* and/or other materials provided with the distribution.
|
|
28
|
+
* * Neither the name of MapLibre GL JS nor the names of its contributors
|
|
29
|
+
* may be used to endorse or promote products derived from this software
|
|
30
|
+
* without specific prior written permission.
|
|
31
|
+
*
|
|
32
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
33
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
34
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
35
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
36
|
+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
37
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
38
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
39
|
+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
40
|
+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
41
|
+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
42
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @license
|
|
47
|
+
* The joining types, presentation forms and ligatures below are derived from the Unicode
|
|
48
|
+
* Character Database 17.0.0 (extracted/DerivedJoiningType.txt and UnicodeData.txt), under
|
|
49
|
+
* this license:
|
|
50
|
+
*
|
|
51
|
+
* UNICODE LICENSE V3
|
|
52
|
+
*
|
|
53
|
+
* COPYRIGHT AND PERMISSION NOTICE
|
|
54
|
+
*
|
|
55
|
+
* Copyright © 1991-2026 Unicode, Inc.
|
|
56
|
+
*
|
|
57
|
+
* NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
58
|
+
* DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
59
|
+
* SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
60
|
+
* TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
61
|
+
* DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
62
|
+
*
|
|
63
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
64
|
+
* copy of data files and any associated documentation (the "Data Files") or
|
|
65
|
+
* software and any associated documentation (the "Software") to deal in the
|
|
66
|
+
* Data Files or Software without restriction, including without limitation
|
|
67
|
+
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
68
|
+
* copies of the Data Files or Software, and to permit persons to whom the
|
|
69
|
+
* Data Files or Software are furnished to do so, provided that either (a)
|
|
70
|
+
* this copyright and permission notice appear with all copies of the Data
|
|
71
|
+
* Files or Software, or (b) this copyright and permission notice appear in
|
|
72
|
+
* associated Documentation.
|
|
73
|
+
*
|
|
74
|
+
* THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
75
|
+
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
76
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
77
|
+
* THIRD PARTY RIGHTS.
|
|
78
|
+
*
|
|
79
|
+
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
80
|
+
* BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
|
|
81
|
+
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
82
|
+
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
83
|
+
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
|
|
84
|
+
* FILES OR SOFTWARE.
|
|
85
|
+
*
|
|
86
|
+
* Except as contained in this notice, the name of a copyright holder shall
|
|
87
|
+
* not be used in advertising or otherwise to promote the sale, use or other
|
|
88
|
+
* dealings in these Data Files or Software without prior written
|
|
89
|
+
* authorization of the copyright holder.
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
// Arabic shaping as MapLibre GL JS 6.13 does it, without a right-to-left text plugin.
|
|
93
|
+
|
|
94
|
+
// The joining type of each code point, as delta-encoded base-36 `start,length` ranges per type.
|
|
95
|
+
const ENCODED_JOINING_TYPES: Record<string, string> = {
|
|
96
|
+
C: '18g,1;g2,3;4nb,1',
|
|
97
|
+
D: '17k,1;5,1;1,1;1,5;4,d;1,7;1,2;z,2;8,g;i,12;1,2;9,1;1,1;1,2;14,3;2,1;28,9;3,f;2,4;1,1;2,3;2,6;7a,1;2,5;1,1;g,a;5,2;2,6;1,f',
|
|
98
|
+
R: '17m,4;1,1;1,1;5,4;l,1;14,3;1,3;g,i;12,1;2,9;1,1;1,1;2,2;1,1;o,2;2x,3;f,2;4,1;1,2;3,2;6u,j;b,1;r,3;1,1;2,2;6,1',
|
|
99
|
+
T: '174,b;1,1;1a,l;g,1;2t,7;2,6;2,2;1,4;bt,9;16,o;1,t;1clb,1'
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Each Arabic letter's Presentation Forms code points, as `[isolated, final, initial, medial]`.
|
|
104
|
+
* A shape the letter is not written in is 0.
|
|
105
|
+
*/
|
|
106
|
+
const PRESENTATION_FORMS: Record<number, [number, number, number, number]> = {
|
|
107
|
+
1569: [65152, 0, 0, 0],
|
|
108
|
+
1570: [65153, 65154, 0, 0],
|
|
109
|
+
1571: [65155, 65156, 0, 0],
|
|
110
|
+
1572: [65157, 65158, 0, 0],
|
|
111
|
+
1573: [65159, 65160, 0, 0],
|
|
112
|
+
1574: [65161, 65162, 65163, 65164],
|
|
113
|
+
1575: [65165, 65166, 0, 0],
|
|
114
|
+
1576: [65167, 65168, 65169, 65170],
|
|
115
|
+
1577: [65171, 65172, 0, 0],
|
|
116
|
+
1578: [65173, 65174, 65175, 65176],
|
|
117
|
+
1579: [65177, 65178, 65179, 65180],
|
|
118
|
+
1580: [65181, 65182, 65183, 65184],
|
|
119
|
+
1581: [65185, 65186, 65187, 65188],
|
|
120
|
+
1582: [65189, 65190, 65191, 65192],
|
|
121
|
+
1583: [65193, 65194, 0, 0],
|
|
122
|
+
1584: [65195, 65196, 0, 0],
|
|
123
|
+
1585: [65197, 65198, 0, 0],
|
|
124
|
+
1586: [65199, 65200, 0, 0],
|
|
125
|
+
1587: [65201, 65202, 65203, 65204],
|
|
126
|
+
1588: [65205, 65206, 65207, 65208],
|
|
127
|
+
1589: [65209, 65210, 65211, 65212],
|
|
128
|
+
1590: [65213, 65214, 65215, 65216],
|
|
129
|
+
1591: [65217, 65218, 65219, 65220],
|
|
130
|
+
1592: [65221, 65222, 65223, 65224],
|
|
131
|
+
1593: [65225, 65226, 65227, 65228],
|
|
132
|
+
1594: [65229, 65230, 65231, 65232],
|
|
133
|
+
1601: [65233, 65234, 65235, 65236],
|
|
134
|
+
1602: [65237, 65238, 65239, 65240],
|
|
135
|
+
1603: [65241, 65242, 65243, 65244],
|
|
136
|
+
1604: [65245, 65246, 65247, 65248],
|
|
137
|
+
1605: [65249, 65250, 65251, 65252],
|
|
138
|
+
1606: [65253, 65254, 65255, 65256],
|
|
139
|
+
1607: [65257, 65258, 65259, 65260],
|
|
140
|
+
1608: [65261, 65262, 0, 0],
|
|
141
|
+
1609: [65263, 65264, 64488, 64489],
|
|
142
|
+
1610: [65265, 65266, 65267, 65268],
|
|
143
|
+
1611: [65136, 0, 0, 65137],
|
|
144
|
+
1612: [65138, 0, 0, 0],
|
|
145
|
+
1613: [65140, 0, 0, 0],
|
|
146
|
+
1614: [65142, 0, 0, 65143],
|
|
147
|
+
1615: [65144, 0, 0, 65145],
|
|
148
|
+
1616: [65146, 0, 0, 65147],
|
|
149
|
+
1617: [65148, 0, 0, 65149],
|
|
150
|
+
1618: [65150, 0, 0, 65151],
|
|
151
|
+
1649: [64336, 64337, 0, 0],
|
|
152
|
+
1655: [64477, 0, 0, 0],
|
|
153
|
+
1657: [64358, 64359, 64360, 64361],
|
|
154
|
+
1658: [64350, 64351, 64352, 64353],
|
|
155
|
+
1659: [64338, 64339, 64340, 64341],
|
|
156
|
+
1662: [64342, 64343, 64344, 64345],
|
|
157
|
+
1663: [64354, 64355, 64356, 64357],
|
|
158
|
+
1664: [64346, 64347, 64348, 64349],
|
|
159
|
+
1667: [64374, 64375, 64376, 64377],
|
|
160
|
+
1668: [64370, 64371, 64372, 64373],
|
|
161
|
+
1670: [64378, 64379, 64380, 64381],
|
|
162
|
+
1671: [64382, 64383, 64384, 64385],
|
|
163
|
+
1672: [64392, 64393, 0, 0],
|
|
164
|
+
1676: [64388, 64389, 0, 0],
|
|
165
|
+
1677: [64386, 64387, 0, 0],
|
|
166
|
+
1678: [64390, 64391, 0, 0],
|
|
167
|
+
1681: [64396, 64397, 0, 0],
|
|
168
|
+
1688: [64394, 64395, 0, 0],
|
|
169
|
+
1700: [64362, 64363, 64364, 64365],
|
|
170
|
+
1702: [64366, 64367, 64368, 64369],
|
|
171
|
+
1705: [64398, 64399, 64400, 64401],
|
|
172
|
+
1709: [64467, 64468, 64469, 64470],
|
|
173
|
+
1711: [64402, 64403, 64404, 64405],
|
|
174
|
+
1713: [64410, 64411, 64412, 64413],
|
|
175
|
+
1715: [64406, 64407, 64408, 64409],
|
|
176
|
+
1722: [64414, 64415, 0, 0],
|
|
177
|
+
1723: [64416, 64417, 64418, 64419],
|
|
178
|
+
1726: [64426, 64427, 64428, 64429],
|
|
179
|
+
1728: [64420, 64421, 0, 0],
|
|
180
|
+
1729: [64422, 64423, 64424, 64425],
|
|
181
|
+
1733: [64480, 64481, 0, 0],
|
|
182
|
+
1734: [64473, 64474, 0, 0],
|
|
183
|
+
1735: [64471, 64472, 0, 0],
|
|
184
|
+
1736: [64475, 64476, 0, 0],
|
|
185
|
+
1737: [64482, 64483, 0, 0],
|
|
186
|
+
1739: [64478, 64479, 0, 0],
|
|
187
|
+
1740: [64508, 64509, 64510, 64511],
|
|
188
|
+
1744: [64484, 64485, 64486, 64487],
|
|
189
|
+
1746: [64430, 64431, 0, 0],
|
|
190
|
+
1747: [64432, 64433, 0, 0]
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/** The lam-alef ligatures, keyed by the pair of letters they replace, as `[isolated, final]`. */
|
|
194
|
+
const LIGATURES: Record<string, [number, number]> = {
|
|
195
|
+
'\u0644\u0622': [65269, 65270],
|
|
196
|
+
'\u0644\u0623': [65271, 65272],
|
|
197
|
+
'\u0644\u0625': [65273, 65274],
|
|
198
|
+
'\u0644\u0627': [65275, 65276]
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* How a character joins to the ones beside it. `D` joins on both sides, `R` only to the character
|
|
203
|
+
* before it, `L` only to the one after it, `C` joins without being written itself, `T` is skipped
|
|
204
|
+
* over entirely, and `U` does not join at all.
|
|
205
|
+
*/
|
|
206
|
+
type JoiningType = 'R' | 'L' | 'D' | 'C' | 'U' | 'T';
|
|
207
|
+
|
|
208
|
+
/** Lam, the only letter written as a ligature with the letter after it. */
|
|
209
|
+
const LAM = 0x0644;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The blocks Arabic is written from, and the two blocks of shapes this rewrites letters into, so
|
|
213
|
+
* that text already shaped is looked at again.
|
|
214
|
+
*/
|
|
215
|
+
const ARABIC = /[-ۿݐ-ݿࡰ-࢟ࢠ-ࣿﭐ-﷿ﹰ-]/;
|
|
216
|
+
|
|
217
|
+
/** The shape a letter takes, as an index into its entry in `PRESENTATION_FORMS`. */
|
|
218
|
+
const ISOLATED = 0;
|
|
219
|
+
const FINAL = 1;
|
|
220
|
+
const INITIAL = 2;
|
|
221
|
+
const MEDIAL = 3;
|
|
222
|
+
type Form = typeof ISOLATED | typeof FINAL | typeof INITIAL | typeof MEDIAL;
|
|
223
|
+
|
|
224
|
+
/** One character of the text, with the shape the joining rules gave it. */
|
|
225
|
+
type ShapedCharacter = {
|
|
226
|
+
codePoint: number;
|
|
227
|
+
type: JoiningType;
|
|
228
|
+
form: Form | null;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/** Unpacks the delta-encoded ranges of one joining type into the code points they stand for. */
|
|
232
|
+
function decodeRanges(encoded: string, type: JoiningType, into: Map<number, JoiningType>): void {
|
|
233
|
+
let previousEnd = 0;
|
|
234
|
+
for (const range of encoded.split(';')) {
|
|
235
|
+
const [delta, length] = range.split(',').map(value => parseInt(value, 36));
|
|
236
|
+
const start = previousEnd + delta;
|
|
237
|
+
for (let codePoint = start; codePoint < start + length; codePoint++) {
|
|
238
|
+
into.set(codePoint, type);
|
|
239
|
+
}
|
|
240
|
+
previousEnd = start + length;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
let joiningTypes: Map<number, JoiningType> | null = null;
|
|
245
|
+
|
|
246
|
+
/** The joining type of a code point; anything the Unicode database gives none stands alone. */
|
|
247
|
+
function joiningType(codePoint: number): JoiningType {
|
|
248
|
+
if (!joiningTypes) {
|
|
249
|
+
joiningTypes = new Map();
|
|
250
|
+
for (const [type, encoded] of Object.entries(ENCODED_JOINING_TYPES)) {
|
|
251
|
+
decodeRanges(encoded, type as JoiningType, joiningTypes);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return joiningTypes.get(codePoint) ?? 'U';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Whether the character before this one reaches forward to touch it. */
|
|
258
|
+
function joinsForward(type: JoiningType): boolean {
|
|
259
|
+
return type === 'D' || type === 'L' || type === 'C';
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** Whether the character after this one reaches back to touch it. */
|
|
263
|
+
function joinsBackward(type: JoiningType): boolean {
|
|
264
|
+
return type === 'D' || type === 'R' || type === 'C';
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* The shape a letter takes given what it can reach on either side. A letter that never joins is
|
|
269
|
+
* left as it was written.
|
|
270
|
+
*/
|
|
271
|
+
function formFor(type: JoiningType, joinedBefore: boolean, joinedAfter: boolean): Form | null {
|
|
272
|
+
if (type === 'D') {
|
|
273
|
+
if (joinedBefore && joinedAfter) return MEDIAL;
|
|
274
|
+
if (joinedBefore) return FINAL;
|
|
275
|
+
if (joinedAfter) return INITIAL;
|
|
276
|
+
return ISOLATED;
|
|
277
|
+
}
|
|
278
|
+
if (type === 'R') return joinedBefore ? FINAL : ISOLATED;
|
|
279
|
+
if (type === 'L') return joinedAfter ? INITIAL : ISOLATED;
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Works out the shape of every letter. Transparent characters (vowel points) are looked straight
|
|
285
|
+
* through, so a letter joins to its neighbour across them.
|
|
286
|
+
*/
|
|
287
|
+
function assignLetterForms(characters: ShapedCharacter[]): void {
|
|
288
|
+
const visible = characters.filter(character => character.type !== 'T');
|
|
289
|
+
for (let i = 0; i < visible.length; i++) {
|
|
290
|
+
const joinedBefore = i > 0 && joinsForward(visible[i - 1].type);
|
|
291
|
+
const joinedAfter = i + 1 < visible.length && joinsBackward(visible[i + 1].type);
|
|
292
|
+
visible[i].form = formFor(visible[i].type, joinedBefore, joinedAfter);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** Gives each vowel point the shape it takes over its letter: medial where the letter joins on. */
|
|
297
|
+
function assignMarkForms(characters: ShapedCharacter[]): void {
|
|
298
|
+
let letterJoinsForward = false;
|
|
299
|
+
for (const character of characters) {
|
|
300
|
+
if (character.type === 'T') {
|
|
301
|
+
character.form = letterJoinsForward ? MEDIAL : ISOLATED;
|
|
302
|
+
} else {
|
|
303
|
+
letterJoinsForward = character.form === INITIAL || character.form === MEDIAL;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Replaces each lam followed by an alef with their ligature: final when the lam joined the letter
|
|
310
|
+
* before it, isolated otherwise. Vowel points between the two follow the ligature.
|
|
311
|
+
*/
|
|
312
|
+
function applyLigatures(characters: ShapedCharacter[]): ShapedCharacter[] {
|
|
313
|
+
const result: ShapedCharacter[] = [];
|
|
314
|
+
for (let i = 0; i < characters.length; i++) {
|
|
315
|
+
const lam = characters[i];
|
|
316
|
+
if (lam.codePoint !== LAM) {
|
|
317
|
+
result.push(lam);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
let next = i + 1;
|
|
321
|
+
while (next < characters.length && characters[next].type === 'T') next++;
|
|
322
|
+
const alef = characters[next];
|
|
323
|
+
const ligature = alef && LIGATURES[String.fromCodePoint(LAM, alef.codePoint)];
|
|
324
|
+
if (!ligature) {
|
|
325
|
+
result.push(lam);
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
const joinedBefore = lam.form === MEDIAL || lam.form === FINAL;
|
|
329
|
+
result.push({codePoint: ligature[joinedBefore ? 1 : 0], type: 'R', form: ISOLATED});
|
|
330
|
+
// One at a time: spreading a long run of marks from tile text would overflow the call stack.
|
|
331
|
+
for (let k = i + 1; k < next; k++) {
|
|
332
|
+
result.push(characters[k]);
|
|
333
|
+
}
|
|
334
|
+
i = next;
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** The presentation form of a character, or the character itself where there is none. */
|
|
340
|
+
function toPresentationForm(character: ShapedCharacter): number {
|
|
341
|
+
if (character.form === null) return character.codePoint;
|
|
342
|
+
const forms = PRESENTATION_FORMS[character.codePoint];
|
|
343
|
+
if (!forms) return character.codePoint;
|
|
344
|
+
return forms[character.form] || forms[ISOLATED] || character.codePoint;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Rewrites Arabic letters as the shape they take in their word, named by their Arabic
|
|
349
|
+
* Presentation Forms code points (U+FB50–FDFF, U+FE70–FEFF), with lam-alef ligatures, as MapLibre
|
|
350
|
+
* GL JS does: glyphs are drawn one code point at a time, so the contextual shape has to be chosen
|
|
351
|
+
* before glyphs are looked up. Text with no Arabic in it is returned unchanged.
|
|
352
|
+
*/
|
|
353
|
+
export function applyArabicShaping(text: string): string {
|
|
354
|
+
if (!ARABIC.test(text)) {
|
|
355
|
+
return text;
|
|
356
|
+
}
|
|
357
|
+
const characters = Array.from(text, character => {
|
|
358
|
+
const codePoint = character.codePointAt(0)!;
|
|
359
|
+
return {codePoint, type: joiningType(codePoint), form: null} as ShapedCharacter;
|
|
360
|
+
});
|
|
361
|
+
assignLetterForms(characters);
|
|
362
|
+
assignMarkForms(characters);
|
|
363
|
+
return applyLigatures(characters)
|
|
364
|
+
.map(character => String.fromCodePoint(toPresentationForm(character)))
|
|
365
|
+
.join('');
|
|
366
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// tangram-layers
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the top-of-globe atmosphere overlay layer when atmosphere rendering
|
|
7
|
+
* is enabled.
|
|
8
|
+
*/
|
|
9
|
+
export function getGlobeAtmosphereLayer() {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns the background sky layer rendered behind the globe when atmosphere
|
|
15
|
+
* rendering is enabled.
|
|
16
|
+
*/
|
|
17
|
+
export function getGlobeAtmosphereSkyLayer() {
|
|
18
|
+
return null;
|
|
19
|
+
}
|