Skip to content

Commit 628fa79

Browse files
committed
make stretchable images work with icon-text-fit: none (#9045)
1 parent c66228e commit 628fa79

File tree

11 files changed

+481
-22
lines changed

11 files changed

+481
-22
lines changed

src/data/bucket/symbol_bucket.js

+8-17
Original file line numberDiff line numberDiff line change
@@ -839,22 +839,13 @@ class SymbolBucket implements Bucket {
839839
return this.iconCollisionCircle.segments.get().length > 0;
840840
}
841841

842-
addIndicesForPlacedTextSymbol(placedTextSymbolIndex: number) {
843-
const placedSymbol = this.text.placedSymbolArray.get(placedTextSymbolIndex);
842+
addIndicesForPlacedSymbol(iconOrText: SymbolBuffers, placedSymbolIndex: number) {
843+
const placedSymbol = iconOrText.placedSymbolArray.get(placedSymbolIndex);
844844

845845
const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4;
846846
for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
847-
this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
848-
this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
849-
}
850-
}
851-
852-
addIndicesForPlacedIconSymbol(placedIconSymbolIndex: number) {
853-
const placedIcon = this.icon.placedSymbolArray.get(placedIconSymbolIndex);
854-
if (placedIcon.numGlyphs) {
855-
const vertexIndex = placedIcon.vertexStartIndex;
856-
this.icon.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
857-
this.icon.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
847+
iconOrText.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
848+
iconOrText.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
858849
}
859850
}
860851

@@ -917,20 +908,20 @@ class SymbolBucket implements Bucket {
917908
// to avoid duplicate opacity entries when multiple justifications
918909
// share the same glyphs.
919910
if (index >= 0 && array.indexOf(index) === i) {
920-
this.addIndicesForPlacedTextSymbol(index);
911+
this.addIndicesForPlacedSymbol(this.text, index);
921912
}
922913
});
923914

924915
if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) {
925-
this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex);
916+
this.addIndicesForPlacedSymbol(this.text, symbolInstance.verticalPlacedTextSymbolIndex);
926917
}
927918

928919
if (symbolInstance.placedIconSymbolIndex >= 0) {
929-
this.addIndicesForPlacedIconSymbol(symbolInstance.placedIconSymbolIndex);
920+
this.addIndicesForPlacedSymbol(this.icon, symbolInstance.placedIconSymbolIndex);
930921
}
931922

932923
if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) {
933-
this.addIndicesForPlacedIconSymbol(symbolInstance.verticalPlacedIconSymbolIndex);
924+
this.addIndicesForPlacedSymbol(this.icon, symbolInstance.verticalPlacedIconSymbolIndex);
934925
}
935926
}
936927

src/symbol/quads.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ const border = IMAGE_PADDING;
5959
export function getIconQuads(
6060
shapedIcon: PositionedIcon,
6161
iconRotate: number,
62-
isSDFIcon: boolean): Array<SymbolQuad> {
62+
isSDFIcon: boolean,
63+
hasIconTextFit: boolean): Array<SymbolQuad> {
6364
const quads = [];
6465

6566
const image = shapedIcon.image;
@@ -88,7 +89,7 @@ export function getIconQuads(
8889
let fixedOffsetY = 0;
8990
let fixedContentHeight = fixedHeight;
9091

91-
if (image.content) {
92+
if (image.content && hasIconTextFit) {
9293
const content = image.content;
9394
stretchOffsetX = sumWithinRange(stretchX, 0, content[0]);
9495
stretchOffsetY = sumWithinRange(stretchY, 0, content[1]);
@@ -153,7 +154,7 @@ export function getIconQuads(
153154
return {tl, tr, bl, br, tex: subRect, writingMode: undefined, glyphOffset: [0, 0], sectionIndex: 0, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY, isSDF: isSDFIcon};
154155
};
155156

156-
if (!image.stretchX && !image.stretchY) {
157+
if (!hasIconTextFit || (!image.stretchX && !image.stretchY)) {
157158
quads.push(makeBox(
158159
{fixed: 0, stretch: -1},
159160
{fixed: 0, stretch: -1},

src/symbol/symbol_layout.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,9 @@ function addSymbol(bucket: SymbolBucket,
608608
// For more info check `updateVariableAnchors` in `draw_symbol.js` .
609609
if (shapedIcon) {
610610
const iconRotate = layer.layout.get('icon-rotate').evaluate(feature, {});
611-
const iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon);
612-
const verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon) : undefined;
611+
const hasIconTextFit = layer.layout.get('icon-text-fit') !== 'none';
612+
const iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon, hasIconTextFit);
613+
const verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon, hasIconTextFit) : undefined;
613614
iconCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, /*align boxes to line*/false, bucket.overscaling, iconRotate);
614615

615616
numIconVertices = iconQuads.length * 4;
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": 8,
3+
"metadata": {
4+
"test": {
5+
"width": 200,
6+
"height": 150
7+
}
8+
},
9+
"zoom": 0.5,
10+
"sources": {
11+
"geojson": {
12+
"type": "geojson",
13+
"data": "local://geojson/anchors.json"
14+
}
15+
},
16+
"sprite": "local://sprites/stretch",
17+
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
18+
"layers": [
19+
{
20+
"id": "anchor-left",
21+
"type": "symbol",
22+
"source": "geojson",
23+
"layout": {
24+
"icon-image": "nine-part",
25+
"icon-allow-overlap": true,
26+
"icon-ignore-placement": true
27+
}
28+
},
29+
{
30+
"id": "anchors",
31+
"type": "circle",
32+
"source": "geojson",
33+
"paint": {
34+
"circle-radius": 2,
35+
"circle-color": "green",
36+
"circle-stroke-color": "white",
37+
"circle-stroke-width": 1
38+
}
39+
}
40+
]
41+
}
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": 8,
3+
"metadata": {
4+
"test": {
5+
"width": 200,
6+
"height": 150
7+
}
8+
},
9+
"zoom": 0.5,
10+
"sources": {
11+
"geojson": {
12+
"type": "geojson",
13+
"data": "local://geojson/anchors.json"
14+
}
15+
},
16+
"sprite": "local://sprites/stretch",
17+
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
18+
"layers": [
19+
{
20+
"id": "anchor-left",
21+
"type": "symbol",
22+
"source": "geojson",
23+
"layout": {
24+
"icon-image": "nine-part-content",
25+
"icon-allow-overlap": true,
26+
"icon-ignore-placement": true
27+
}
28+
},
29+
{
30+
"id": "anchors",
31+
"type": "circle",
32+
"source": "geojson",
33+
"paint": {
34+
"circle-radius": 2,
35+
"circle-color": "green",
36+
"circle-stroke-color": "white",
37+
"circle-stroke-width": 1
38+
}
39+
}
40+
]
41+
}
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
{
2+
"version": 8,
3+
"metadata": {
4+
"test": {
5+
"width": 200,
6+
"height": 150
7+
}
8+
},
9+
"sources": {
10+
"geojson": {
11+
"type": "geojson",
12+
"data": "local://geojson/anchors.json"
13+
}
14+
},
15+
"sprite": "local://sprites/stretch",
16+
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
17+
"layers": [
18+
{
19+
"id": "anchor-center",
20+
"type": "symbol",
21+
"source": "geojson",
22+
"filter": ["==", "anchor", "center"],
23+
"layout": {
24+
"text-field": "ASDFASDF",
25+
"text-size": 10,
26+
"text-anchor": "center",
27+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
28+
"text-allow-overlap": true,
29+
"text-ignore-placement": true,
30+
"icon-image": "nine-part",
31+
"icon-text-fit": "height",
32+
"icon-allow-overlap": true,
33+
"icon-ignore-placement": true
34+
}
35+
},
36+
{
37+
"id": "anchor-left",
38+
"type": "symbol",
39+
"source": "geojson",
40+
"filter": ["==", "anchor", "left"],
41+
"layout": {
42+
"text-field": "ASDFASDF",
43+
"text-size": 10,
44+
"text-anchor": "left",
45+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
46+
"text-allow-overlap": true,
47+
"text-ignore-placement": true,
48+
"icon-image": "nine-part",
49+
"icon-text-fit": "height",
50+
"icon-allow-overlap": true,
51+
"icon-ignore-placement": true
52+
}
53+
},
54+
{
55+
"id": "anchor-top-left",
56+
"type": "symbol",
57+
"source": "geojson",
58+
"filter": ["==", "anchor", "top-left"],
59+
"layout": {
60+
"text-field": "ASDFASDF",
61+
"text-size": 10,
62+
"text-anchor": "top-left",
63+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
64+
"text-allow-overlap": true,
65+
"text-ignore-placement": true,
66+
"icon-image": "nine-part",
67+
"icon-text-fit": "height",
68+
"icon-allow-overlap": true,
69+
"icon-ignore-placement": true
70+
}
71+
},
72+
{
73+
"id": "anchor-top",
74+
"type": "symbol",
75+
"source": "geojson",
76+
"filter": ["==", "anchor", "top"],
77+
"layout": {
78+
"text-field": "ASDFASDF",
79+
"text-size": 10,
80+
"text-anchor": "top",
81+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
82+
"text-allow-overlap": true,
83+
"text-ignore-placement": true,
84+
"icon-image": "nine-part",
85+
"icon-text-fit": "height",
86+
"icon-allow-overlap": true,
87+
"icon-ignore-placement": true
88+
}
89+
},
90+
{
91+
"id": "anchor-top-right",
92+
"type": "symbol",
93+
"source": "geojson",
94+
"filter": ["==", "anchor", "top-right"],
95+
"layout": {
96+
"text-field": "ASDFASDF",
97+
"text-size": 10,
98+
"text-anchor": "top-right",
99+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
100+
"text-allow-overlap": true,
101+
"text-ignore-placement": true,
102+
"icon-image": "nine-part",
103+
"icon-text-fit": "height",
104+
"icon-allow-overlap": true,
105+
"icon-ignore-placement": true
106+
}
107+
},
108+
{
109+
"id": "anchor-right",
110+
"type": "symbol",
111+
"source": "geojson",
112+
"filter": ["==", "anchor", "right"],
113+
"layout": {
114+
"text-field": "ASDFASDF",
115+
"text-size": 10,
116+
"text-anchor": "right",
117+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
118+
"text-allow-overlap": true,
119+
"text-ignore-placement": true,
120+
"icon-image": "nine-part",
121+
"icon-text-fit": "height",
122+
"icon-allow-overlap": true,
123+
"icon-ignore-placement": true
124+
}
125+
},
126+
{
127+
"id": "anchor-bottom-left",
128+
"type": "symbol",
129+
"source": "geojson",
130+
"filter": ["==", "anchor", "bottom-left"],
131+
"layout": {
132+
"text-field": "ASDFASDF",
133+
"text-size": 10,
134+
"text-anchor": "bottom-left",
135+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
136+
"text-allow-overlap": true,
137+
"text-ignore-placement": true,
138+
"icon-image": "nine-part",
139+
"icon-text-fit": "height",
140+
"icon-allow-overlap": true,
141+
"icon-ignore-placement": true
142+
}
143+
},
144+
{
145+
"id": "anchor-bottom",
146+
"type": "symbol",
147+
"source": "geojson",
148+
"filter": ["==", "anchor", "bottom"],
149+
"layout": {
150+
"text-field": "ASDFASDF",
151+
"text-size": 10,
152+
"text-anchor": "bottom",
153+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
154+
"text-allow-overlap": true,
155+
"text-ignore-placement": true,
156+
"icon-image": "nine-part",
157+
"icon-text-fit": "height",
158+
"icon-allow-overlap": true,
159+
"icon-ignore-placement": true
160+
}
161+
},
162+
{
163+
"id": "anchor-bottom-right",
164+
"type": "symbol",
165+
"source": "geojson",
166+
"filter": ["==", "anchor", "bottom-right"],
167+
"layout": {
168+
"text-field": "ASDFASDF",
169+
"text-size": 10,
170+
"text-anchor": "bottom-right",
171+
"text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ],
172+
"text-allow-overlap": true,
173+
"text-ignore-placement": true,
174+
"icon-image": "nine-part",
175+
"icon-text-fit": "height",
176+
"icon-allow-overlap": true,
177+
"icon-ignore-placement": true
178+
}
179+
},
180+
{
181+
"id": "anchors",
182+
"type": "circle",
183+
"source": "geojson",
184+
"paint": {
185+
"circle-radius": 2,
186+
"circle-color": "green",
187+
"circle-stroke-color": "white",
188+
"circle-stroke-width": 1
189+
}
190+
}
191+
]
192+
}
Loading

0 commit comments

Comments
 (0)