ol 10.4.1-dev.1740542736318 → 10.4.1-dev.1740574913397
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/dist/ol.d.ts +47 -33
- package/dist/ol.d.ts.map +1 -1
- package/dist/ol.js +1 -1
- package/dist/ol.js.map +1 -1
- package/expr/gpu.d.ts +0 -5
- package/expr/gpu.d.ts.map +1 -1
- package/expr/gpu.js +3 -8
- package/layer/BaseVector.d.ts +2 -2
- package/layer/BaseVector.d.ts.map +1 -1
- package/layer/BaseVector.js +1 -1
- package/layer/Flow.d.ts.map +1 -1
- package/layer/Flow.js +1 -2
- package/layer/Heatmap.d.ts +54 -18
- package/layer/Heatmap.d.ts.map +1 -1
- package/layer/Heatmap.js +169 -50
- package/layer/WebGLPoints.d.ts +1 -1
- package/layer/WebGLPoints.d.ts.map +1 -1
- package/layer/WebGLPoints.js +2 -2
- package/layer/WebGLTile.d.ts.map +1 -1
- package/layer/WebGLTile.js +1 -2
- package/package.json +1 -1
- package/render/webgl/MixedGeometryBatch.d.ts.map +1 -1
- package/render/webgl/MixedGeometryBatch.js +4 -0
- package/{webgl → render/webgl}/ShaderBuilder.d.ts +28 -29
- package/render/webgl/ShaderBuilder.d.ts.map +1 -0
- package/{webgl → render/webgl}/ShaderBuilder.js +115 -123
- package/render/webgl/VectorStyleRenderer.d.ts +2 -2
- package/render/webgl/VectorStyleRenderer.d.ts.map +1 -1
- package/render/webgl/VectorStyleRenderer.js +3 -3
- package/render/webgl/{utils.d.ts → bufferUtil.d.ts} +1 -37
- package/render/webgl/bufferUtil.d.ts.map +1 -0
- package/render/webgl/{utils.js → bufferUtil.js} +2 -123
- package/render/webgl/compileUtil.d.ts +51 -0
- package/render/webgl/compileUtil.d.ts.map +1 -0
- package/render/webgl/compileUtil.js +203 -0
- package/render/webgl/encodeUtil.d.ts +20 -0
- package/render/webgl/encodeUtil.d.ts.map +1 -0
- package/render/webgl/encodeUtil.js +39 -0
- package/render/webgl/style.d.ts +57 -0
- package/render/webgl/style.d.ts.map +1 -0
- package/{webgl/styleparser.js → render/webgl/style.js} +187 -322
- package/renderer/webgl/PointsLayer.js +1 -1
- package/renderer/webgl/VectorLayer.d.ts +1 -0
- package/renderer/webgl/VectorLayer.d.ts.map +1 -1
- package/renderer/webgl/VectorLayer.js +4 -1
- package/renderer/webgl/VectorTileLayer.d.ts.map +1 -1
- package/renderer/webgl/VectorTileLayer.js +5 -3
- package/util.js +1 -1
- package/worker/webgl.js +1 -1
- package/render/webgl/utils.d.ts.map +0 -1
- package/webgl/ShaderBuilder.d.ts.map +0 -1
- package/webgl/styleparser.d.ts +0 -57
- package/webgl/styleparser.d.ts.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Utilities for parsing
|
|
3
|
-
* @module ol/webgl/
|
|
2
|
+
* Utilities for parsing flat styles for WebGL renderers
|
|
3
|
+
* @module ol/render/webgl/style
|
|
4
4
|
*/
|
|
5
|
-
import {assert} from '
|
|
6
|
-
import {asArray} from '../color.js';
|
|
5
|
+
import {assert} from '../../asserts.js';
|
|
7
6
|
import {
|
|
8
7
|
BooleanType,
|
|
9
8
|
ColorType,
|
|
@@ -12,85 +11,23 @@ import {
|
|
|
12
11
|
SizeType,
|
|
13
12
|
StringType,
|
|
14
13
|
computeGeometryType,
|
|
15
|
-
|
|
16
|
-
} from '../expr/expression.js';
|
|
14
|
+
} from '../../expr/expression.js';
|
|
17
15
|
import {
|
|
18
16
|
FEATURE_ID_PROPERTY_NAME,
|
|
19
17
|
GEOMETRY_TYPE_PROPERTY_NAME,
|
|
20
|
-
buildExpression,
|
|
21
18
|
getStringNumberEquivalent,
|
|
22
19
|
newCompilationContext,
|
|
23
20
|
stringToGlsl,
|
|
24
|
-
|
|
25
|
-
} from '../expr/gpu.js';
|
|
21
|
+
} from '../../expr/gpu.js';
|
|
26
22
|
import {ShaderBuilder} from './ShaderBuilder.js';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
export function expressionToGlsl(compilationContext, value, expectedType) {
|
|
37
|
-
const parsingContext = newParsingContext();
|
|
38
|
-
return buildExpression(
|
|
39
|
-
value,
|
|
40
|
-
expectedType,
|
|
41
|
-
parsingContext,
|
|
42
|
-
compilationContext,
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Packs all components of a color into a two-floats array
|
|
48
|
-
* @param {import("../color.js").Color|string} color Color as array of numbers or string
|
|
49
|
-
* @return {Array<number>} Vec2 array containing the color in compressed form
|
|
50
|
-
*/
|
|
51
|
-
export function packColor(color) {
|
|
52
|
-
const array = asArray(color);
|
|
53
|
-
const r = array[0] * 256;
|
|
54
|
-
const g = array[1];
|
|
55
|
-
const b = array[2] * 256;
|
|
56
|
-
const a = Math.round(array[3] * 255);
|
|
57
|
-
return [r + g, b + a];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const UNPACK_COLOR_FN = `vec4 unpackColor(vec2 packedColor) {
|
|
61
|
-
return vec4(
|
|
62
|
-
fract(floor(packedColor[0] / 256.0) / 256.0),
|
|
63
|
-
fract(packedColor[0] / 256.0),
|
|
64
|
-
fract(floor(packedColor[1] / 256.0) / 256.0),
|
|
65
|
-
fract(packedColor[1] / 256.0)
|
|
66
|
-
);
|
|
67
|
-
}`;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param {number} type Value type
|
|
71
|
-
* @return {1|2|3|4} The amount of components for this value
|
|
72
|
-
*/
|
|
73
|
-
function getGlslSizeFromType(type) {
|
|
74
|
-
if (type === ColorType || type === SizeType) {
|
|
75
|
-
return 2;
|
|
76
|
-
}
|
|
77
|
-
if (type === NumberArrayType) {
|
|
78
|
-
return 4;
|
|
79
|
-
}
|
|
80
|
-
return 1;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @param {number} type Value type
|
|
85
|
-
* @return {'float'|'vec2'|'vec3'|'vec4'} The corresponding GLSL type for this value
|
|
86
|
-
*/
|
|
87
|
-
function getGlslTypeFromType(type) {
|
|
88
|
-
const size = getGlslSizeFromType(type);
|
|
89
|
-
if (size > 1) {
|
|
90
|
-
return /** @type {'vec2'|'vec3'|'vec4'} */ (`vec${size}`);
|
|
91
|
-
}
|
|
92
|
-
return 'float';
|
|
93
|
-
}
|
|
23
|
+
import {
|
|
24
|
+
applyContextToBuilder,
|
|
25
|
+
expressionToGlsl,
|
|
26
|
+
generateAttributesFromContext,
|
|
27
|
+
generateUniformsFromContext,
|
|
28
|
+
getGlslSizeFromType,
|
|
29
|
+
getGlslTypeFromType,
|
|
30
|
+
} from './compileUtil.js';
|
|
94
31
|
|
|
95
32
|
/**
|
|
96
33
|
* see https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
|
|
@@ -105,9 +42,9 @@ export function computeHash(input) {
|
|
|
105
42
|
}
|
|
106
43
|
|
|
107
44
|
/**
|
|
108
|
-
* @param {import("
|
|
45
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
109
46
|
* @param {ShaderBuilder} builder Shader builder
|
|
110
|
-
* @param {import("
|
|
47
|
+
* @param {import("../../expr/gpu.js").CompilationContext} vertContext Vertex shader compilation context
|
|
111
48
|
* @param {'shape-'|'circle-'|'icon-'} prefix Properties prefix
|
|
112
49
|
*/
|
|
113
50
|
function parseCommonSymbolProperties(style, builder, vertContext, prefix) {
|
|
@@ -197,9 +134,9 @@ function getColorFromDistanceField(
|
|
|
197
134
|
/**
|
|
198
135
|
* This will parse an image property provided by `<prefix>-src`
|
|
199
136
|
* The image size expression in GLSL will be returned
|
|
200
|
-
* @param {import("
|
|
137
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
201
138
|
* @param {ShaderBuilder} builder Shader builder
|
|
202
|
-
* @param {Object<string,import("
|
|
139
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
203
140
|
* @param {'icon-'|'fill-pattern-'|'stroke-pattern-'} prefix Property prefix
|
|
204
141
|
* @param {string} textureId A identifier that will be used in the generated uniforms: `sample2d u_texture<id>` and `vec2 u_texture<id>_size`
|
|
205
142
|
* @return {string} The image size expression
|
|
@@ -230,9 +167,9 @@ function parseImageProperties(style, builder, uniforms, prefix, textureId) {
|
|
|
230
167
|
|
|
231
168
|
/**
|
|
232
169
|
* This will parse an image's offset properties provided by `<prefix>-offset`, `<prefix>-offset-origin` and `<prefix>-size`
|
|
233
|
-
* @param {import("
|
|
170
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
234
171
|
* @param {'icon-'|'fill-pattern-'|'stroke-pattern-'} prefix Property prefix
|
|
235
|
-
* @param {import("
|
|
172
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context (vertex or fragment)
|
|
236
173
|
* @param {string} imageSize Pixel size of the full image as a GLSL expression
|
|
237
174
|
* @param {string} sampleSize Pixel size of the sample in the image as a GLSL expression
|
|
238
175
|
* @return {string} The offset expression
|
|
@@ -267,46 +204,31 @@ function parseImageOffsetProperties(
|
|
|
267
204
|
}
|
|
268
205
|
|
|
269
206
|
/**
|
|
270
|
-
* @param {import("
|
|
207
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
271
208
|
* @param {ShaderBuilder} builder Shader builder
|
|
272
|
-
* @param {Object<string,import("
|
|
273
|
-
* @param {import("
|
|
274
|
-
* @param {import("../expr/gpu.js").CompilationContext} fragContext Fragment shader compilation context
|
|
209
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
210
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context
|
|
275
211
|
*/
|
|
276
|
-
function parseCircleProperties(
|
|
277
|
-
style,
|
|
278
|
-
builder,
|
|
279
|
-
uniforms,
|
|
280
|
-
vertContext,
|
|
281
|
-
fragContext,
|
|
282
|
-
) {
|
|
212
|
+
function parseCircleProperties(style, builder, uniforms, context) {
|
|
283
213
|
// this function takes in screen coordinates in pixels and returns the signed distance field
|
|
284
214
|
// (0 on the boundary, negative inside the circle, positive outside, values in pixels)
|
|
285
|
-
|
|
215
|
+
context.functions['circleDistanceField'] =
|
|
286
216
|
`float circleDistanceField(vec2 point, float radius) {
|
|
287
217
|
return length(point) - radius;
|
|
288
218
|
}`;
|
|
289
219
|
|
|
290
|
-
parseCommonSymbolProperties(style, builder,
|
|
220
|
+
parseCommonSymbolProperties(style, builder, context, 'circle-');
|
|
291
221
|
|
|
292
222
|
// OPACITY
|
|
293
223
|
let opacity = null;
|
|
294
224
|
if ('circle-opacity' in style) {
|
|
295
|
-
opacity = expressionToGlsl(
|
|
296
|
-
fragContext,
|
|
297
|
-
style['circle-opacity'],
|
|
298
|
-
NumberType,
|
|
299
|
-
);
|
|
225
|
+
opacity = expressionToGlsl(context, style['circle-opacity'], NumberType);
|
|
300
226
|
}
|
|
301
227
|
|
|
302
228
|
// SCALE
|
|
303
229
|
let currentPoint = 'coordsPx';
|
|
304
230
|
if ('circle-scale' in style) {
|
|
305
|
-
const scale = expressionToGlsl(
|
|
306
|
-
fragContext,
|
|
307
|
-
style['circle-scale'],
|
|
308
|
-
SizeType,
|
|
309
|
-
);
|
|
231
|
+
const scale = expressionToGlsl(context, style['circle-scale'], SizeType);
|
|
310
232
|
currentPoint = `coordsPx / ${scale}`;
|
|
311
233
|
}
|
|
312
234
|
|
|
@@ -314,7 +236,7 @@ function parseCircleProperties(
|
|
|
314
236
|
let fillColor = null;
|
|
315
237
|
if ('circle-fill-color' in style) {
|
|
316
238
|
fillColor = expressionToGlsl(
|
|
317
|
-
|
|
239
|
+
context,
|
|
318
240
|
style['circle-fill-color'],
|
|
319
241
|
ColorType,
|
|
320
242
|
);
|
|
@@ -324,24 +246,20 @@ function parseCircleProperties(
|
|
|
324
246
|
let strokeColor = null;
|
|
325
247
|
if ('circle-stroke-color' in style) {
|
|
326
248
|
strokeColor = expressionToGlsl(
|
|
327
|
-
|
|
249
|
+
context,
|
|
328
250
|
style['circle-stroke-color'],
|
|
329
251
|
ColorType,
|
|
330
252
|
);
|
|
331
253
|
}
|
|
332
254
|
|
|
333
255
|
// RADIUS
|
|
334
|
-
let radius = expressionToGlsl(
|
|
335
|
-
fragContext,
|
|
336
|
-
style['circle-radius'],
|
|
337
|
-
NumberType,
|
|
338
|
-
);
|
|
256
|
+
let radius = expressionToGlsl(context, style['circle-radius'], NumberType);
|
|
339
257
|
|
|
340
258
|
// STROKE WIDTH
|
|
341
259
|
let strokeWidth = null;
|
|
342
260
|
if ('circle-stroke-width' in style) {
|
|
343
261
|
strokeWidth = expressionToGlsl(
|
|
344
|
-
|
|
262
|
+
context,
|
|
345
263
|
style['circle-stroke-width'],
|
|
346
264
|
NumberType,
|
|
347
265
|
);
|
|
@@ -361,27 +279,20 @@ function parseCircleProperties(
|
|
|
361
279
|
}
|
|
362
280
|
|
|
363
281
|
/**
|
|
364
|
-
* @param {import("
|
|
282
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
365
283
|
* @param {ShaderBuilder} builder Shader builder
|
|
366
|
-
* @param {Object<string,import("
|
|
367
|
-
* @param {import("
|
|
368
|
-
* @param {import("../expr/gpu.js").CompilationContext} fragContext Fragment shader compilation context
|
|
284
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
285
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context
|
|
369
286
|
*/
|
|
370
|
-
function parseShapeProperties(
|
|
371
|
-
|
|
372
|
-
builder,
|
|
373
|
-
uniforms,
|
|
374
|
-
vertContext,
|
|
375
|
-
fragContext,
|
|
376
|
-
) {
|
|
377
|
-
fragContext.functions['round'] = `float round(float v) {
|
|
287
|
+
function parseShapeProperties(style, builder, uniforms, context) {
|
|
288
|
+
context.functions['round'] = `float round(float v) {
|
|
378
289
|
return sign(v) * floor(abs(v) + 0.5);
|
|
379
290
|
}`;
|
|
380
291
|
|
|
381
292
|
// these functions take in screen coordinates in pixels and returns the signed distance field
|
|
382
293
|
// (0 on the boundary, negative inside the polygon, positive outside, values in pixels)
|
|
383
294
|
// inspired by https://github.com/zranger1/PixelblazePatterns/blob/master/Toolkit/sdf2d.md#n-sided-regular-polygon
|
|
384
|
-
|
|
295
|
+
context.functions['starDistanceField'] =
|
|
385
296
|
`float starDistanceField(vec2 point, float numPoints, float radius, float radius2, float angle) {
|
|
386
297
|
float startAngle = -PI * 0.5 + angle; // tip starts upwards and rotates clockwise with angle
|
|
387
298
|
float c = cos(startAngle);
|
|
@@ -397,7 +308,7 @@ function parseShapeProperties(
|
|
|
397
308
|
vec2 edgeNormal = vec2(radius2 * sin(alpha * 0.5), -radius2 * cos(alpha * 0.5) + radius);
|
|
398
309
|
return dot(normalize(edgeNormal), tipToPoint);
|
|
399
310
|
}`;
|
|
400
|
-
|
|
311
|
+
context.functions['regularDistanceField'] =
|
|
401
312
|
`float regularDistanceField(vec2 point, float numPoints, float radius, float angle) {
|
|
402
313
|
float startAngle = -PI * 0.5 + angle; // tip starts upwards and rotates clockwise with angle
|
|
403
314
|
float c = cos(startAngle);
|
|
@@ -413,36 +324,32 @@ function parseShapeProperties(
|
|
|
413
324
|
return inSector.x - radiusIn;
|
|
414
325
|
}`;
|
|
415
326
|
|
|
416
|
-
parseCommonSymbolProperties(style, builder,
|
|
327
|
+
parseCommonSymbolProperties(style, builder, context, 'shape-');
|
|
417
328
|
|
|
418
329
|
// OPACITY
|
|
419
330
|
let opacity = null;
|
|
420
331
|
if ('shape-opacity' in style) {
|
|
421
|
-
opacity = expressionToGlsl(
|
|
332
|
+
opacity = expressionToGlsl(context, style['shape-opacity'], NumberType);
|
|
422
333
|
}
|
|
423
334
|
|
|
424
335
|
// SCALE
|
|
425
336
|
let currentPoint = 'coordsPx';
|
|
426
337
|
if ('shape-scale' in style) {
|
|
427
|
-
const scale = expressionToGlsl(
|
|
338
|
+
const scale = expressionToGlsl(context, style['shape-scale'], SizeType);
|
|
428
339
|
currentPoint = `coordsPx / ${scale}`;
|
|
429
340
|
}
|
|
430
341
|
|
|
431
342
|
// FILL COLOR
|
|
432
343
|
let fillColor = null;
|
|
433
344
|
if ('shape-fill-color' in style) {
|
|
434
|
-
fillColor = expressionToGlsl(
|
|
435
|
-
fragContext,
|
|
436
|
-
style['shape-fill-color'],
|
|
437
|
-
ColorType,
|
|
438
|
-
);
|
|
345
|
+
fillColor = expressionToGlsl(context, style['shape-fill-color'], ColorType);
|
|
439
346
|
}
|
|
440
347
|
|
|
441
348
|
// STROKE COLOR
|
|
442
349
|
let strokeColor = null;
|
|
443
350
|
if ('shape-stroke-color' in style) {
|
|
444
351
|
strokeColor = expressionToGlsl(
|
|
445
|
-
|
|
352
|
+
context,
|
|
446
353
|
style['shape-stroke-color'],
|
|
447
354
|
ColorType,
|
|
448
355
|
);
|
|
@@ -452,7 +359,7 @@ function parseShapeProperties(
|
|
|
452
359
|
let strokeWidth = null;
|
|
453
360
|
if ('shape-stroke-width' in style) {
|
|
454
361
|
strokeWidth = expressionToGlsl(
|
|
455
|
-
|
|
362
|
+
context,
|
|
456
363
|
style['shape-stroke-width'],
|
|
457
364
|
NumberType,
|
|
458
365
|
);
|
|
@@ -460,25 +367,21 @@ function parseShapeProperties(
|
|
|
460
367
|
|
|
461
368
|
// SHAPE TYPE
|
|
462
369
|
const numPoints = expressionToGlsl(
|
|
463
|
-
|
|
370
|
+
context,
|
|
464
371
|
style['shape-points'],
|
|
465
372
|
NumberType,
|
|
466
373
|
);
|
|
467
374
|
let angle = '0.';
|
|
468
375
|
if ('shape-angle' in style) {
|
|
469
|
-
angle = expressionToGlsl(
|
|
376
|
+
angle = expressionToGlsl(context, style['shape-angle'], NumberType);
|
|
470
377
|
}
|
|
471
378
|
let shapeField;
|
|
472
|
-
let radius = expressionToGlsl(
|
|
379
|
+
let radius = expressionToGlsl(context, style['shape-radius'], NumberType);
|
|
473
380
|
if (strokeWidth !== null) {
|
|
474
381
|
radius = `${radius} + ${strokeWidth} * 0.5`;
|
|
475
382
|
}
|
|
476
383
|
if ('shape-radius2' in style) {
|
|
477
|
-
let radius2 = expressionToGlsl(
|
|
478
|
-
fragContext,
|
|
479
|
-
style['shape-radius2'],
|
|
480
|
-
NumberType,
|
|
481
|
-
);
|
|
384
|
+
let radius2 = expressionToGlsl(context, style['shape-radius2'], NumberType);
|
|
482
385
|
if (strokeWidth !== null) {
|
|
483
386
|
radius2 = `${radius2} + ${strokeWidth} * 0.5`;
|
|
484
387
|
}
|
|
@@ -499,29 +402,22 @@ function parseShapeProperties(
|
|
|
499
402
|
}
|
|
500
403
|
|
|
501
404
|
/**
|
|
502
|
-
* @param {import("
|
|
405
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
503
406
|
* @param {ShaderBuilder} builder Shader builder
|
|
504
|
-
* @param {Object<string,import("
|
|
505
|
-
* @param {import("
|
|
506
|
-
* @param {import("../expr/gpu.js").CompilationContext} fragContext Fragment shader compilation context
|
|
407
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
408
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context
|
|
507
409
|
*/
|
|
508
|
-
function parseIconProperties(
|
|
509
|
-
style,
|
|
510
|
-
builder,
|
|
511
|
-
uniforms,
|
|
512
|
-
vertContext,
|
|
513
|
-
fragContext,
|
|
514
|
-
) {
|
|
410
|
+
function parseIconProperties(style, builder, uniforms, context) {
|
|
515
411
|
// COLOR
|
|
516
412
|
let color = 'vec4(1.0)';
|
|
517
413
|
if ('icon-color' in style) {
|
|
518
|
-
color = expressionToGlsl(
|
|
414
|
+
color = expressionToGlsl(context, style['icon-color'], ColorType);
|
|
519
415
|
}
|
|
520
416
|
|
|
521
417
|
// OPACITY
|
|
522
418
|
if ('icon-opacity' in style) {
|
|
523
419
|
color = `${color} * vec4(1.0, 1.0, 1.0, ${expressionToGlsl(
|
|
524
|
-
|
|
420
|
+
context,
|
|
525
421
|
style['icon-opacity'],
|
|
526
422
|
NumberType,
|
|
527
423
|
)})`;
|
|
@@ -546,17 +442,17 @@ function parseIconProperties(
|
|
|
546
442
|
if ('icon-width' in style && 'icon-height' in style) {
|
|
547
443
|
builder.setSymbolSizeExpression(
|
|
548
444
|
`vec2(${expressionToGlsl(
|
|
549
|
-
|
|
445
|
+
context,
|
|
550
446
|
style['icon-width'],
|
|
551
447
|
NumberType,
|
|
552
|
-
)}, ${expressionToGlsl(
|
|
448
|
+
)}, ${expressionToGlsl(context, style['icon-height'], NumberType)})`,
|
|
553
449
|
);
|
|
554
450
|
}
|
|
555
451
|
|
|
556
452
|
// tex coord
|
|
557
453
|
if ('icon-offset' in style && 'icon-size' in style) {
|
|
558
454
|
const sampleSize = expressionToGlsl(
|
|
559
|
-
|
|
455
|
+
context,
|
|
560
456
|
style['icon-size'],
|
|
561
457
|
NumberArrayType,
|
|
562
458
|
);
|
|
@@ -565,7 +461,7 @@ function parseIconProperties(
|
|
|
565
461
|
const offset = parseImageOffsetProperties(
|
|
566
462
|
style,
|
|
567
463
|
'icon-',
|
|
568
|
-
|
|
464
|
+
context,
|
|
569
465
|
'v_quadSizePx',
|
|
570
466
|
sampleSize,
|
|
571
467
|
);
|
|
@@ -574,17 +470,17 @@ function parseIconProperties(
|
|
|
574
470
|
);
|
|
575
471
|
}
|
|
576
472
|
|
|
577
|
-
parseCommonSymbolProperties(style, builder,
|
|
473
|
+
parseCommonSymbolProperties(style, builder, context, 'icon-');
|
|
578
474
|
|
|
579
475
|
if ('icon-anchor' in style) {
|
|
580
476
|
const anchor = expressionToGlsl(
|
|
581
|
-
|
|
477
|
+
context,
|
|
582
478
|
style['icon-anchor'],
|
|
583
479
|
NumberArrayType,
|
|
584
480
|
);
|
|
585
481
|
let scale = `1.0`;
|
|
586
482
|
if (`icon-scale` in style) {
|
|
587
|
-
scale = expressionToGlsl(
|
|
483
|
+
scale = expressionToGlsl(context, style[`icon-scale`], SizeType);
|
|
588
484
|
}
|
|
589
485
|
let shiftPx;
|
|
590
486
|
if (
|
|
@@ -622,22 +518,15 @@ function parseIconProperties(
|
|
|
622
518
|
}
|
|
623
519
|
|
|
624
520
|
/**
|
|
625
|
-
* @param {import("
|
|
521
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
626
522
|
* @param {ShaderBuilder} builder Shader Builder
|
|
627
|
-
* @param {Object<string,import("
|
|
628
|
-
* @param {import("
|
|
629
|
-
* @param {import("../expr/gpu.js").CompilationContext} fragContext Fragment shader compilation context
|
|
523
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
524
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context
|
|
630
525
|
*/
|
|
631
|
-
function parseStrokeProperties(
|
|
632
|
-
style,
|
|
633
|
-
builder,
|
|
634
|
-
uniforms,
|
|
635
|
-
vertContext,
|
|
636
|
-
fragContext,
|
|
637
|
-
) {
|
|
526
|
+
function parseStrokeProperties(style, builder, uniforms, context) {
|
|
638
527
|
if ('stroke-color' in style) {
|
|
639
528
|
builder.setStrokeColorExpression(
|
|
640
|
-
expressionToGlsl(
|
|
529
|
+
expressionToGlsl(context, style['stroke-color'], ColorType),
|
|
641
530
|
);
|
|
642
531
|
}
|
|
643
532
|
if ('stroke-pattern-src' in style) {
|
|
@@ -653,14 +542,14 @@ function parseStrokeProperties(
|
|
|
653
542
|
let offsetExpression = 'vec2(0.)';
|
|
654
543
|
if ('stroke-pattern-offset' in style && 'stroke-pattern-size' in style) {
|
|
655
544
|
sampleSizeExpression = expressionToGlsl(
|
|
656
|
-
|
|
545
|
+
context,
|
|
657
546
|
style[`stroke-pattern-size`],
|
|
658
547
|
NumberArrayType,
|
|
659
548
|
);
|
|
660
549
|
offsetExpression = parseImageOffsetProperties(
|
|
661
550
|
style,
|
|
662
551
|
'stroke-pattern-',
|
|
663
|
-
|
|
552
|
+
context,
|
|
664
553
|
sizeExpression,
|
|
665
554
|
sampleSizeExpression,
|
|
666
555
|
);
|
|
@@ -668,12 +557,12 @@ function parseStrokeProperties(
|
|
|
668
557
|
let spacingExpression = '0.';
|
|
669
558
|
if ('stroke-pattern-spacing' in style) {
|
|
670
559
|
spacingExpression = expressionToGlsl(
|
|
671
|
-
|
|
560
|
+
context,
|
|
672
561
|
style['stroke-pattern-spacing'],
|
|
673
562
|
NumberType,
|
|
674
563
|
);
|
|
675
564
|
}
|
|
676
|
-
|
|
565
|
+
context.functions['sampleStrokePattern'] =
|
|
677
566
|
`vec4 sampleStrokePattern(sampler2D texture, vec2 textureSize, vec2 textureOffset, vec2 sampleSize, float spacingPx, float currentLengthPx, float currentRadiusRatio, float lineWidth) {
|
|
678
567
|
float currentLengthScaled = currentLengthPx * sampleSize.y / lineWidth;
|
|
679
568
|
float spacingScaled = spacingPx * sampleSize.y / lineWidth;
|
|
@@ -696,36 +585,36 @@ function parseStrokeProperties(
|
|
|
696
585
|
|
|
697
586
|
if ('stroke-width' in style) {
|
|
698
587
|
builder.setStrokeWidthExpression(
|
|
699
|
-
expressionToGlsl(
|
|
588
|
+
expressionToGlsl(context, style['stroke-width'], NumberType),
|
|
700
589
|
);
|
|
701
590
|
}
|
|
702
591
|
|
|
703
592
|
if ('stroke-offset' in style) {
|
|
704
593
|
builder.setStrokeOffsetExpression(
|
|
705
|
-
expressionToGlsl(
|
|
594
|
+
expressionToGlsl(context, style['stroke-offset'], NumberType),
|
|
706
595
|
);
|
|
707
596
|
}
|
|
708
597
|
|
|
709
598
|
if ('stroke-line-cap' in style) {
|
|
710
599
|
builder.setStrokeCapExpression(
|
|
711
|
-
expressionToGlsl(
|
|
600
|
+
expressionToGlsl(context, style['stroke-line-cap'], StringType),
|
|
712
601
|
);
|
|
713
602
|
}
|
|
714
603
|
|
|
715
604
|
if ('stroke-line-join' in style) {
|
|
716
605
|
builder.setStrokeJoinExpression(
|
|
717
|
-
expressionToGlsl(
|
|
606
|
+
expressionToGlsl(context, style['stroke-line-join'], StringType),
|
|
718
607
|
);
|
|
719
608
|
}
|
|
720
609
|
|
|
721
610
|
if ('stroke-miter-limit' in style) {
|
|
722
611
|
builder.setStrokeMiterLimitExpression(
|
|
723
|
-
expressionToGlsl(
|
|
612
|
+
expressionToGlsl(context, style['stroke-miter-limit'], NumberType),
|
|
724
613
|
);
|
|
725
614
|
}
|
|
726
615
|
|
|
727
616
|
if ('stroke-line-dash' in style) {
|
|
728
|
-
|
|
617
|
+
context.functions['getSingleDashDistance'] =
|
|
729
618
|
`float getSingleDashDistance(float distance, float radius, float dashOffset, float dashLength, float dashLengthTotal, float capType) {
|
|
730
619
|
float localDistance = mod(distance, dashLengthTotal);
|
|
731
620
|
float distanceSegment = abs(localDistance - dashOffset - dashLength * 0.5) - dashLength * 0.5;
|
|
@@ -739,7 +628,7 @@ function parseStrokeProperties(
|
|
|
739
628
|
}`;
|
|
740
629
|
|
|
741
630
|
let dashPattern = style['stroke-line-dash'].map((v) =>
|
|
742
|
-
expressionToGlsl(
|
|
631
|
+
expressionToGlsl(context, v, NumberType),
|
|
743
632
|
);
|
|
744
633
|
// if pattern has odd length, concatenate it with itself to be even
|
|
745
634
|
if (dashPattern.length % 2 === 1) {
|
|
@@ -749,7 +638,7 @@ function parseStrokeProperties(
|
|
|
749
638
|
let offsetExpression = '0.';
|
|
750
639
|
if ('stroke-line-dash-offset' in style) {
|
|
751
640
|
offsetExpression = expressionToGlsl(
|
|
752
|
-
|
|
641
|
+
context,
|
|
753
642
|
style['stroke-line-dash-offset'],
|
|
754
643
|
NumberType,
|
|
755
644
|
);
|
|
@@ -774,7 +663,7 @@ function parseStrokeProperties(
|
|
|
774
663
|
distanceExpression = `min(${distanceExpression}, getSingleDashDistance(distance, radius, ${currentDashOffset}, dashLength${i}, totalDashLength, capType))`;
|
|
775
664
|
}
|
|
776
665
|
|
|
777
|
-
|
|
666
|
+
context.functions[dashFunctionName] =
|
|
778
667
|
`float ${dashFunctionName}(float distance, float radius, float capType) {
|
|
779
668
|
${dashLengthsDef.join('\n ')}
|
|
780
669
|
float totalDashLength = ${totalLengthDef};
|
|
@@ -787,22 +676,15 @@ function parseStrokeProperties(
|
|
|
787
676
|
}
|
|
788
677
|
|
|
789
678
|
/**
|
|
790
|
-
* @param {import("
|
|
679
|
+
* @param {import("../../style/flat.js").FlatStyle} style Style
|
|
791
680
|
* @param {ShaderBuilder} builder Shader Builder
|
|
792
|
-
* @param {Object<string,import("
|
|
793
|
-
* @param {import("
|
|
794
|
-
* @param {import("../expr/gpu.js").CompilationContext} fragContext Fragment shader compilation context
|
|
681
|
+
* @param {Object<string,import("../../webgl/Helper").UniformValue>} uniforms Uniforms
|
|
682
|
+
* @param {import("../../expr/gpu.js").CompilationContext} context Shader compilation context
|
|
795
683
|
*/
|
|
796
|
-
function parseFillProperties(
|
|
797
|
-
style,
|
|
798
|
-
builder,
|
|
799
|
-
uniforms,
|
|
800
|
-
vertContext,
|
|
801
|
-
fragContext,
|
|
802
|
-
) {
|
|
684
|
+
function parseFillProperties(style, builder, uniforms, context) {
|
|
803
685
|
if ('fill-color' in style) {
|
|
804
686
|
builder.setFillColorExpression(
|
|
805
|
-
expressionToGlsl(
|
|
687
|
+
expressionToGlsl(context, style['fill-color'], ColorType),
|
|
806
688
|
);
|
|
807
689
|
}
|
|
808
690
|
if ('fill-pattern-src' in style) {
|
|
@@ -818,19 +700,19 @@ function parseFillProperties(
|
|
|
818
700
|
let offsetExpression = 'vec2(0.)';
|
|
819
701
|
if ('fill-pattern-offset' in style && 'fill-pattern-size' in style) {
|
|
820
702
|
sampleSizeExpression = expressionToGlsl(
|
|
821
|
-
|
|
703
|
+
context,
|
|
822
704
|
style[`fill-pattern-size`],
|
|
823
705
|
NumberArrayType,
|
|
824
706
|
);
|
|
825
707
|
offsetExpression = parseImageOffsetProperties(
|
|
826
708
|
style,
|
|
827
709
|
'fill-pattern-',
|
|
828
|
-
|
|
710
|
+
context,
|
|
829
711
|
sizeExpression,
|
|
830
712
|
sampleSizeExpression,
|
|
831
713
|
);
|
|
832
714
|
}
|
|
833
|
-
|
|
715
|
+
context.functions['sampleFillPattern'] =
|
|
834
716
|
`vec4 sampleFillPattern(sampler2D texture, vec2 textureSize, vec2 textureOffset, vec2 sampleSize, vec2 pxOrigin, vec2 pxPosition) {
|
|
835
717
|
float scaleRatio = pow(2., mod(u_zoom + 0.5, 1.) - 0.5);
|
|
836
718
|
vec2 pxRelativePos = pxPosition - pxOrigin;
|
|
@@ -857,160 +739,62 @@ function parseFillProperties(
|
|
|
857
739
|
/**
|
|
858
740
|
* @typedef {Object} StyleParseResult
|
|
859
741
|
* @property {ShaderBuilder} builder Shader builder pre-configured according to a given style
|
|
860
|
-
* @property {import("
|
|
861
|
-
* @property {import("
|
|
742
|
+
* @property {import("./VectorStyleRenderer.js").UniformDefinitions} uniforms Uniform definitions
|
|
743
|
+
* @property {import("./VectorStyleRenderer.js").AttributeDefinitions} attributes Attribute definitions
|
|
862
744
|
*/
|
|
863
745
|
|
|
864
746
|
/**
|
|
865
|
-
* Parses a {@link import("
|
|
747
|
+
* Parses a {@link import("../../style/flat.js").FlatStyle} object and returns a {@link ShaderBuilder}
|
|
866
748
|
* object that has been configured according to the given style, as well as `attributes` and `uniforms`
|
|
867
749
|
* arrays to be fed to the `WebGLPointsRenderer` class.
|
|
868
750
|
*
|
|
869
751
|
* Also returns `uniforms` and `attributes` properties as expected by the
|
|
870
752
|
* {@link module:ol/renderer/webgl/PointsLayer~WebGLPointsLayerRenderer}.
|
|
871
753
|
*
|
|
872
|
-
* @param {import("
|
|
873
|
-
* @param {import('
|
|
874
|
-
* @param {import("
|
|
754
|
+
* @param {import("../../style/flat.js").FlatStyle} style Flat style.
|
|
755
|
+
* @param {import('../../style/flat.js').StyleVariables} [variables] Style variables.
|
|
756
|
+
* @param {import("../../expr/expression.js").EncodedExpression} [filter] Filter (if any)
|
|
875
757
|
* @return {StyleParseResult} Result containing shader params, attributes and uniforms.
|
|
876
758
|
*/
|
|
877
759
|
export function parseLiteralStyle(style, variables, filter) {
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
/**
|
|
881
|
-
* @type {import("../expr/gpu.js").CompilationContext}
|
|
882
|
-
*/
|
|
883
|
-
const fragContext = {
|
|
884
|
-
...newCompilationContext(),
|
|
885
|
-
inFragmentShader: true,
|
|
886
|
-
variables: vertContext.variables,
|
|
887
|
-
};
|
|
760
|
+
const context = newCompilationContext();
|
|
888
761
|
|
|
889
762
|
const builder = new ShaderBuilder();
|
|
890
763
|
|
|
891
|
-
/** @type {Object<string,import("
|
|
764
|
+
/** @type {Object<string,import("../../webgl/Helper").UniformValue>} */
|
|
892
765
|
const uniforms = {};
|
|
893
766
|
|
|
894
767
|
if ('icon-src' in style) {
|
|
895
|
-
parseIconProperties(style, builder, uniforms,
|
|
768
|
+
parseIconProperties(style, builder, uniforms, context);
|
|
896
769
|
} else if ('shape-points' in style) {
|
|
897
|
-
parseShapeProperties(style, builder, uniforms,
|
|
770
|
+
parseShapeProperties(style, builder, uniforms, context);
|
|
898
771
|
} else if ('circle-radius' in style) {
|
|
899
|
-
parseCircleProperties(style, builder, uniforms,
|
|
772
|
+
parseCircleProperties(style, builder, uniforms, context);
|
|
900
773
|
}
|
|
901
|
-
parseStrokeProperties(style, builder, uniforms,
|
|
902
|
-
parseFillProperties(style, builder, uniforms,
|
|
774
|
+
parseStrokeProperties(style, builder, uniforms, context);
|
|
775
|
+
parseFillProperties(style, builder, uniforms, context);
|
|
903
776
|
|
|
904
777
|
// note that the style filter may have already been applied earlier when building the rendering instructions
|
|
905
778
|
// this is still needed in case a filter cannot be evaluated statically beforehand (e.g. depending on time)
|
|
906
779
|
if (filter) {
|
|
907
|
-
const parsedFilter = expressionToGlsl(
|
|
780
|
+
const parsedFilter = expressionToGlsl(context, filter, BooleanType);
|
|
908
781
|
builder.setFragmentDiscardExpression(`!${parsedFilter}`);
|
|
909
782
|
}
|
|
910
783
|
|
|
911
|
-
// define one uniform per variable
|
|
912
|
-
for (const varName in fragContext.variables) {
|
|
913
|
-
const variable = fragContext.variables[varName];
|
|
914
|
-
const uniformName = uniformNameForVariable(variable.name);
|
|
915
|
-
let glslType = getGlslTypeFromType(variable.type);
|
|
916
|
-
if (variable.type === ColorType) {
|
|
917
|
-
// we're not packing colors when they're passed as uniforms
|
|
918
|
-
glslType = 'vec4';
|
|
919
|
-
}
|
|
920
|
-
builder.addUniform(`${glslType} ${uniformName}`);
|
|
921
|
-
|
|
922
|
-
uniforms[uniformName] = () => {
|
|
923
|
-
const value = variables[variable.name];
|
|
924
|
-
if (typeof value === 'number') {
|
|
925
|
-
return value;
|
|
926
|
-
}
|
|
927
|
-
if (typeof value === 'boolean') {
|
|
928
|
-
return value ? 1 : 0;
|
|
929
|
-
}
|
|
930
|
-
if (variable.type === ColorType) {
|
|
931
|
-
return asArray(value || '#eee');
|
|
932
|
-
}
|
|
933
|
-
if (typeof value === 'string') {
|
|
934
|
-
return getStringNumberEquivalent(value);
|
|
935
|
-
}
|
|
936
|
-
return value;
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
// for each feature attribute used in the fragment shader, define a varying that will be used to pass data
|
|
941
|
-
// from the vertex to the fragment shader, as well as an attribute in the vertex shader (if not already present)
|
|
942
|
-
for (const propName in fragContext.properties) {
|
|
943
|
-
const property = fragContext.properties[propName];
|
|
944
|
-
if (!vertContext.properties[propName]) {
|
|
945
|
-
vertContext.properties[propName] = property;
|
|
946
|
-
}
|
|
947
|
-
let type = getGlslTypeFromType(property.type);
|
|
948
|
-
let expression = `a_prop_${property.name}`;
|
|
949
|
-
if (property.type === ColorType) {
|
|
950
|
-
type = 'vec4';
|
|
951
|
-
expression = `unpackColor(${expression})`;
|
|
952
|
-
builder.addVertexShaderFunction(UNPACK_COLOR_FN);
|
|
953
|
-
}
|
|
954
|
-
builder.addVarying(`v_prop_${property.name}`, type, expression);
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
// for each feature attribute used in the vertex shader, define an attribute in the vertex shader.
|
|
958
|
-
for (const propName in vertContext.properties) {
|
|
959
|
-
const property = vertContext.properties[propName];
|
|
960
|
-
builder.addAttribute(
|
|
961
|
-
`${getGlslTypeFromType(property.type)} a_prop_${property.name}`,
|
|
962
|
-
);
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
// add functions that were collected in the compilation contexts
|
|
966
|
-
for (const functionName in vertContext.functions) {
|
|
967
|
-
builder.addVertexShaderFunction(vertContext.functions[functionName]);
|
|
968
|
-
}
|
|
969
|
-
for (const functionName in fragContext.functions) {
|
|
970
|
-
builder.addFragmentShaderFunction(fragContext.functions[functionName]);
|
|
971
|
-
}
|
|
972
|
-
|
|
973
784
|
/**
|
|
974
|
-
* @type {import('
|
|
785
|
+
* @type {import('./VectorStyleRenderer.js').AttributeDefinitions}
|
|
975
786
|
*/
|
|
976
787
|
const attributes = {};
|
|
977
788
|
|
|
978
|
-
// Define attributes with their callback for each property used in the vertex shader
|
|
979
|
-
for (const propName in vertContext.properties) {
|
|
980
|
-
const property = vertContext.properties[propName];
|
|
981
|
-
const callback = (feature) => {
|
|
982
|
-
const value = feature.get(property.name);
|
|
983
|
-
if (property.type === ColorType) {
|
|
984
|
-
return packColor([...asArray(value || '#eee')]);
|
|
985
|
-
}
|
|
986
|
-
if (typeof value === 'string') {
|
|
987
|
-
return getStringNumberEquivalent(value);
|
|
988
|
-
}
|
|
989
|
-
if (typeof value === 'boolean') {
|
|
990
|
-
return value ? 1 : 0;
|
|
991
|
-
}
|
|
992
|
-
return value;
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
attributes[`prop_${property.name}`] = {
|
|
996
|
-
size: getGlslSizeFromType(property.type),
|
|
997
|
-
callback,
|
|
998
|
-
};
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
789
|
// Define attributes for special inputs
|
|
1002
790
|
function defineSpecialInput(contextPropName, glslPropName, type, callback) {
|
|
1003
|
-
|
|
1004
|
-
const inFragContext = fragContext[contextPropName];
|
|
1005
|
-
if (!inVertContext && !inFragContext) {
|
|
791
|
+
if (!context[contextPropName]) {
|
|
1006
792
|
return;
|
|
1007
793
|
}
|
|
1008
794
|
const glslType = getGlslTypeFromType(type);
|
|
1009
795
|
const attrSize = getGlslSizeFromType(type);
|
|
1010
|
-
builder.addAttribute(
|
|
1011
|
-
|
|
1012
|
-
builder.addVarying(`v_${glslPropName}`, glslType, `a_${glslPropName}`);
|
|
1013
|
-
}
|
|
796
|
+
builder.addAttribute(`a_${glslPropName}`, glslType);
|
|
797
|
+
|
|
1014
798
|
attributes[glslPropName] = {
|
|
1015
799
|
size: attrSize,
|
|
1016
800
|
callback,
|
|
@@ -1033,5 +817,86 @@ export function parseLiteralStyle(style, variables, filter) {
|
|
|
1033
817
|
},
|
|
1034
818
|
);
|
|
1035
819
|
|
|
1036
|
-
|
|
820
|
+
applyContextToBuilder(builder, context);
|
|
821
|
+
|
|
822
|
+
return {
|
|
823
|
+
builder,
|
|
824
|
+
attributes: {...attributes, ...generateAttributesFromContext(context)},
|
|
825
|
+
uniforms: {
|
|
826
|
+
...uniforms,
|
|
827
|
+
...generateUniformsFromContext(context, variables),
|
|
828
|
+
},
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* @typedef {import('./VectorStyleRenderer.js').AsShaders} StyleAsShaders
|
|
834
|
+
*/
|
|
835
|
+
/**
|
|
836
|
+
* @typedef {import('./VectorStyleRenderer.js').AsRule} StyleAsRule
|
|
837
|
+
*/
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Takes in either a Flat Style or an array of shaders (used as input for the webgl vector layer classes)
|
|
841
|
+
* and breaks it down into separate styles to be used by the VectorStyleRenderer class.
|
|
842
|
+
* @param {import('../../style/flat.js').FlatStyleLike | Array<StyleAsShaders> | StyleAsShaders} style Flat style or shaders
|
|
843
|
+
* @return {Array<StyleAsShaders | StyleAsRule>} Separate styles as shaders or rules with a single flat style and a filter
|
|
844
|
+
*/
|
|
845
|
+
export function breakDownFlatStyle(style) {
|
|
846
|
+
// possible cases:
|
|
847
|
+
// - single shader
|
|
848
|
+
// - multiple shaders
|
|
849
|
+
// - single style
|
|
850
|
+
// - multiple styles
|
|
851
|
+
// - multiple rules
|
|
852
|
+
const asArray = Array.isArray(style) ? style : [style];
|
|
853
|
+
|
|
854
|
+
// if array of rules: break rules into separate styles, compute "else" filters
|
|
855
|
+
if ('style' in asArray[0]) {
|
|
856
|
+
/** @type {Array<StyleAsRule>} */
|
|
857
|
+
const styles = [];
|
|
858
|
+
const rules = /** @type {Array<import('../../style/flat.js').Rule>} */ (
|
|
859
|
+
asArray
|
|
860
|
+
);
|
|
861
|
+
const previousFilters = [];
|
|
862
|
+
for (const rule of rules) {
|
|
863
|
+
const ruleStyles = Array.isArray(rule.style) ? rule.style : [rule.style];
|
|
864
|
+
/** @type {import("../../expr/expression.js").EncodedExpression} */
|
|
865
|
+
let currentFilter = rule.filter;
|
|
866
|
+
if (rule.else && previousFilters.length) {
|
|
867
|
+
currentFilter = [
|
|
868
|
+
'all',
|
|
869
|
+
...previousFilters.map((filter) => ['!', filter]),
|
|
870
|
+
];
|
|
871
|
+
if (rule.filter) {
|
|
872
|
+
currentFilter.push(rule.filter);
|
|
873
|
+
}
|
|
874
|
+
if (currentFilter.length < 3) {
|
|
875
|
+
currentFilter = currentFilter[1];
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (rule.filter) {
|
|
879
|
+
previousFilters.push(rule.filter);
|
|
880
|
+
}
|
|
881
|
+
/** @type {Array<StyleAsRule>} */
|
|
882
|
+
const stylesWithFilters = ruleStyles.map((style) => ({
|
|
883
|
+
style,
|
|
884
|
+
...(currentFilter && {filter: currentFilter}),
|
|
885
|
+
}));
|
|
886
|
+
styles.push(...stylesWithFilters);
|
|
887
|
+
}
|
|
888
|
+
return styles;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// if array of shaders: return as is
|
|
892
|
+
if ('builder' in asArray[0]) {
|
|
893
|
+
return /** @type {Array<StyleAsShaders>} */ (asArray);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
return asArray.map(
|
|
897
|
+
(style) =>
|
|
898
|
+
/** @type {StyleAsRule} */ ({
|
|
899
|
+
style,
|
|
900
|
+
}),
|
|
901
|
+
);
|
|
1037
902
|
}
|