Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support icon-text-fit with vertical text #8835

Merged
merged 7 commits into from
Oct 15, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 66 additions & 50 deletions src/data/array_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,14 @@ register('StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48', StructArrayLayout2i2ui3ul3u

/**
* Implementation of the StructArray layout:
* [0]: Int16[7]
* [14]: Uint16[11]
* [36]: Uint32[1]
* [40]: Float32[3]
* [0]: Int16[8]
* [16]: Uint16[14]
* [44]: Uint32[1]
* [48]: Float32[3]
*
* @private
*/
class StructArrayLayout7i11ui1ul3f52 extends StructArray {
class StructArrayLayout8i14ui1ul3f60 extends StructArray {
uint8: Uint8Array;
int16: Int16Array;
uint16: Uint16Array;
Expand All @@ -499,23 +499,23 @@ class StructArrayLayout7i11ui1ul3f52 extends StructArray {
this.float32 = new Float32Array(this.arrayBuffer);
}

emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number) {
emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number, v22: number, v23: number, v24: number, v25: number) {
const i = this.length;
this.resize(i + 1);
return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25);
}

emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number) {
const o2 = i * 26;
const o4 = i * 13;
emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number, v12: number, v13: number, v14: number, v15: number, v16: number, v17: number, v18: number, v19: number, v20: number, v21: number, v22: number, v23: number, v24: number, v25: number) {
const o2 = i * 30;
const o4 = i * 15;
this.int16[o2 + 0] = v0;
this.int16[o2 + 1] = v1;
this.int16[o2 + 2] = v2;
this.int16[o2 + 3] = v3;
this.int16[o2 + 4] = v4;
this.int16[o2 + 5] = v5;
this.int16[o2 + 6] = v6;
this.uint16[o2 + 7] = v7;
this.int16[o2 + 7] = v7;
this.uint16[o2 + 8] = v8;
this.uint16[o2 + 9] = v9;
this.uint16[o2 + 10] = v10;
Expand All @@ -526,16 +526,20 @@ class StructArrayLayout7i11ui1ul3f52 extends StructArray {
this.uint16[o2 + 15] = v15;
this.uint16[o2 + 16] = v16;
this.uint16[o2 + 17] = v17;
this.uint32[o4 + 9] = v18;
this.float32[o4 + 10] = v19;
this.float32[o4 + 11] = v20;
this.float32[o4 + 12] = v21;
this.uint16[o2 + 18] = v18;
this.uint16[o2 + 19] = v19;
this.uint16[o2 + 20] = v20;
this.uint16[o2 + 21] = v21;
this.uint32[o4 + 11] = v22;
this.float32[o4 + 12] = v23;
this.float32[o4 + 13] = v24;
this.float32[o4 + 14] = v25;
return i;
}
}

StructArrayLayout7i11ui1ul3f52.prototype.bytesPerElement = 52;
register('StructArrayLayout7i11ui1ul3f52', StructArrayLayout7i11ui1ul3f52);
StructArrayLayout8i14ui1ul3f60.prototype.bytesPerElement = 60;
register('StructArrayLayout8i14ui1ul3f60', StructArrayLayout8i14ui1ul3f60);

/**
* Implementation of the StructArray layout:
Expand Down Expand Up @@ -943,17 +947,21 @@ class SymbolInstanceStruct extends Struct {
leftJustifiedTextSymbolIndex: number;
verticalPlacedTextSymbolIndex: number;
placedIconSymbolIndex: number;
verticalPlacedIconSymbolIndex: number;
key: number;
textBoxStartIndex: number;
textBoxEndIndex: number;
verticalTextBoxStartIndex: number;
verticalTextBoxEndIndex: number;
iconBoxStartIndex: number;
iconBoxEndIndex: number;
verticalIconBoxStartIndex: number;
verticalIconBoxEndIndex: number;
featureIndex: number;
numHorizontalGlyphVertices: number;
numVerticalGlyphVertices: number;
numIconVertices: number;
numVerticalIconVertices: number;
crossTileID: number;
textBoxScale: number;
textOffset0: number;
Expand All @@ -972,46 +980,54 @@ class SymbolInstanceStruct extends Struct {
set verticalPlacedTextSymbolIndex(x: number) { this._structArray.int16[this._pos2 + 5] = x; }
get placedIconSymbolIndex() { return this._structArray.int16[this._pos2 + 6]; }
set placedIconSymbolIndex(x: number) { this._structArray.int16[this._pos2 + 6] = x; }
get key() { return this._structArray.uint16[this._pos2 + 7]; }
set key(x: number) { this._structArray.uint16[this._pos2 + 7] = x; }
get textBoxStartIndex() { return this._structArray.uint16[this._pos2 + 8]; }
set textBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 8] = x; }
get textBoxEndIndex() { return this._structArray.uint16[this._pos2 + 9]; }
set textBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 9] = x; }
get verticalTextBoxStartIndex() { return this._structArray.uint16[this._pos2 + 10]; }
set verticalTextBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 10] = x; }
get verticalTextBoxEndIndex() { return this._structArray.uint16[this._pos2 + 11]; }
set verticalTextBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 11] = x; }
get iconBoxStartIndex() { return this._structArray.uint16[this._pos2 + 12]; }
set iconBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 12] = x; }
get iconBoxEndIndex() { return this._structArray.uint16[this._pos2 + 13]; }
set iconBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 13] = x; }
get featureIndex() { return this._structArray.uint16[this._pos2 + 14]; }
set featureIndex(x: number) { this._structArray.uint16[this._pos2 + 14] = x; }
get numHorizontalGlyphVertices() { return this._structArray.uint16[this._pos2 + 15]; }
set numHorizontalGlyphVertices(x: number) { this._structArray.uint16[this._pos2 + 15] = x; }
get numVerticalGlyphVertices() { return this._structArray.uint16[this._pos2 + 16]; }
set numVerticalGlyphVertices(x: number) { this._structArray.uint16[this._pos2 + 16] = x; }
get numIconVertices() { return this._structArray.uint16[this._pos2 + 17]; }
set numIconVertices(x: number) { this._structArray.uint16[this._pos2 + 17] = x; }
get crossTileID() { return this._structArray.uint32[this._pos4 + 9]; }
set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 9] = x; }
get textBoxScale() { return this._structArray.float32[this._pos4 + 10]; }
set textBoxScale(x: number) { this._structArray.float32[this._pos4 + 10] = x; }
get textOffset0() { return this._structArray.float32[this._pos4 + 11]; }
set textOffset0(x: number) { this._structArray.float32[this._pos4 + 11] = x; }
get textOffset1() { return this._structArray.float32[this._pos4 + 12]; }
set textOffset1(x: number) { this._structArray.float32[this._pos4 + 12] = x; }
get verticalPlacedIconSymbolIndex() { return this._structArray.int16[this._pos2 + 7]; }
set verticalPlacedIconSymbolIndex(x: number) { this._structArray.int16[this._pos2 + 7] = x; }
get key() { return this._structArray.uint16[this._pos2 + 8]; }
set key(x: number) { this._structArray.uint16[this._pos2 + 8] = x; }
get textBoxStartIndex() { return this._structArray.uint16[this._pos2 + 9]; }
set textBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 9] = x; }
get textBoxEndIndex() { return this._structArray.uint16[this._pos2 + 10]; }
set textBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 10] = x; }
get verticalTextBoxStartIndex() { return this._structArray.uint16[this._pos2 + 11]; }
set verticalTextBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 11] = x; }
get verticalTextBoxEndIndex() { return this._structArray.uint16[this._pos2 + 12]; }
set verticalTextBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 12] = x; }
get iconBoxStartIndex() { return this._structArray.uint16[this._pos2 + 13]; }
set iconBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 13] = x; }
get iconBoxEndIndex() { return this._structArray.uint16[this._pos2 + 14]; }
set iconBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 14] = x; }
get verticalIconBoxStartIndex() { return this._structArray.uint16[this._pos2 + 15]; }
set verticalIconBoxStartIndex(x: number) { this._structArray.uint16[this._pos2 + 15] = x; }
get verticalIconBoxEndIndex() { return this._structArray.uint16[this._pos2 + 16]; }
set verticalIconBoxEndIndex(x: number) { this._structArray.uint16[this._pos2 + 16] = x; }
get featureIndex() { return this._structArray.uint16[this._pos2 + 17]; }
set featureIndex(x: number) { this._structArray.uint16[this._pos2 + 17] = x; }
get numHorizontalGlyphVertices() { return this._structArray.uint16[this._pos2 + 18]; }
set numHorizontalGlyphVertices(x: number) { this._structArray.uint16[this._pos2 + 18] = x; }
get numVerticalGlyphVertices() { return this._structArray.uint16[this._pos2 + 19]; }
set numVerticalGlyphVertices(x: number) { this._structArray.uint16[this._pos2 + 19] = x; }
get numIconVertices() { return this._structArray.uint16[this._pos2 + 20]; }
set numIconVertices(x: number) { this._structArray.uint16[this._pos2 + 20] = x; }
get numVerticalIconVertices() { return this._structArray.uint16[this._pos2 + 21]; }
set numVerticalIconVertices(x: number) { this._structArray.uint16[this._pos2 + 21] = x; }
get crossTileID() { return this._structArray.uint32[this._pos4 + 11]; }
set crossTileID(x: number) { this._structArray.uint32[this._pos4 + 11] = x; }
get textBoxScale() { return this._structArray.float32[this._pos4 + 12]; }
set textBoxScale(x: number) { this._structArray.float32[this._pos4 + 12] = x; }
get textOffset0() { return this._structArray.float32[this._pos4 + 13]; }
set textOffset0(x: number) { this._structArray.float32[this._pos4 + 13] = x; }
get textOffset1() { return this._structArray.float32[this._pos4 + 14]; }
set textOffset1(x: number) { this._structArray.float32[this._pos4 + 14] = x; }
}

SymbolInstanceStruct.prototype.size = 52;
SymbolInstanceStruct.prototype.size = 60;

export type SymbolInstance = SymbolInstanceStruct;

/**
* @private
*/
export class SymbolInstanceArray extends StructArrayLayout7i11ui1ul3f52 {
export class SymbolInstanceArray extends StructArrayLayout8i14ui1ul3f60 {
/**
* Return the SymbolInstanceStruct at the given location in the array.
* @param {number} index The index of the element.
Expand Down Expand Up @@ -1134,7 +1150,7 @@ export {
StructArrayLayout2i2i2i12,
StructArrayLayout2ub2f12,
StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48,
StructArrayLayout7i11ui1ul3f52,
StructArrayLayout8i14ui1ul3f60,
StructArrayLayout1f4,
StructArrayLayout3i6,
StructArrayLayout1ul2ui8,
Expand Down
4 changes: 4 additions & 0 deletions src/data/bucket/symbol_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,21 @@ export const symbolInstance = createLayout([
{type: 'Int16', name: 'leftJustifiedTextSymbolIndex'},
{type: 'Int16', name: 'verticalPlacedTextSymbolIndex'},
{type: 'Int16', name: 'placedIconSymbolIndex'},
{type: 'Int16', name: 'verticalPlacedIconSymbolIndex'},
{type: 'Uint16', name: 'key'},
{type: 'Uint16', name: 'textBoxStartIndex'},
{type: 'Uint16', name: 'textBoxEndIndex'},
{type: 'Uint16', name: 'verticalTextBoxStartIndex'},
{type: 'Uint16', name: 'verticalTextBoxEndIndex'},
{type: 'Uint16', name: 'iconBoxStartIndex'},
{type: 'Uint16', name: 'iconBoxEndIndex'},
{type: 'Uint16', name: 'verticalIconBoxStartIndex'},
{type: 'Uint16', name: 'verticalIconBoxEndIndex'},
{type: 'Uint16', name: 'featureIndex'},
{type: 'Uint16', name: 'numHorizontalGlyphVertices'},
{type: 'Uint16', name: 'numVerticalGlyphVertices'},
{type: 'Uint16', name: 'numIconVertices'},
{type: 'Uint16', name: 'numVerticalIconVertices'},
{type: 'Uint32', name: 'crossTileID'},
{type: 'Float32', name: 'textBoxScale'},
{type: 'Float32', components: 2, name: 'textOffset'}
Expand Down
43 changes: 36 additions & 7 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ export type CollisionArrays = {
textBox?: SingleCollisionBox;
verticalTextBox?: SingleCollisionBox;
iconBox?: SingleCollisionBox;
verticalIconBox?: SingleCollisionBox;
textCircles?: Array<number>;
textFeatureIndex?: number;
verticalTextFeatureIndex?: number;
iconFeatureIndex?: number;
verticalIconFeatureIndex?: number;
};

export type SymbolFeature = {|
Expand Down Expand Up @@ -711,12 +713,18 @@ class SymbolBucket implements Bucket {
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance, true);
this.addDebugCollisionBoxes(symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance, true);
this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance, false);
this.addDebugCollisionBoxes(symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex, symbolInstance, false);
}
}

// These flat arrays are meant to be quicker to iterate over than the source
// CollisionBoxArray
_deserializeCollisionBoxesForSymbol(collisionBoxArray: CollisionBoxArray, textStartIndex: number, textEndIndex: number, verticalTextStartIndex: number, verticalTextEndIndex: number, iconStartIndex: number, iconEndIndex: number): CollisionArrays {
_deserializeCollisionBoxesForSymbol(collisionBoxArray: CollisionBoxArray,
textStartIndex: number, textEndIndex: number,
verticalTextStartIndex: number, verticalTextEndIndex: number,
iconStartIndex: number, iconEndIndex: number,
verticalIconStartIndex: number, verticalIconEndIndex: number): CollisionArrays {

const collisionArrays = {};
for (let k = textStartIndex; k < textEndIndex; k++) {
const box: CollisionBox = (collisionBoxArray.get(k): any);
Expand Down Expand Up @@ -750,6 +758,15 @@ class SymbolBucket implements Bucket {
break; // Only one box allowed per instance
}
}
for (let k = verticalIconStartIndex; k < verticalIconEndIndex; k++) {
// An icon can only have one box now, so this indexing is a bit vestigial...
const box: CollisionBox = (collisionBoxArray.get(k): any);
if (box.radius === 0) {
collisionArrays.verticalIconBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY};
collisionArrays.verticalIconFeatureIndex = box.featureIndex;
break; // Only one box allowed per instance
}
}
return collisionArrays;
}

Expand All @@ -764,7 +781,9 @@ class SymbolBucket implements Bucket {
symbolInstance.verticalTextBoxStartIndex,
symbolInstance.verticalTextBoxEndIndex,
symbolInstance.iconBoxStartIndex,
symbolInstance.iconBoxEndIndex
symbolInstance.iconBoxEndIndex,
symbolInstance.verticalIconBoxStartIndex,
symbolInstance.verticalIconBoxEndIndex
));
}
}
Expand Down Expand Up @@ -803,6 +822,15 @@ class SymbolBucket implements Bucket {
}
}

addIndicesForPlacedIconSymbol(placedIconSymbolIndex: number) {
const placedIcon = this.icon.placedSymbolArray.get(placedIconSymbolIndex);
if (placedIcon.numGlyphs) {
const vertexIndex = placedIcon.vertexStartIndex;
this.icon.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
this.icon.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
}
}

getSortedSymbolIndexes(angle: number) {
if (this.sortedAngle === angle && this.symbolInstanceIndexes !== undefined) {
return this.symbolInstanceIndexes;
Expand Down Expand Up @@ -870,11 +898,12 @@ class SymbolBucket implements Bucket {
this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex);
}

const placedIcon = this.icon.placedSymbolArray.get(i);
if (placedIcon.numGlyphs) {
const vertexIndex = placedIcon.vertexStartIndex;
this.icon.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
this.icon.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
if (symbolInstance.placedIconSymbolIndex >= 0) {
this.addIndicesForPlacedIconSymbol(symbolInstance.placedIconSymbolIndex);
}

if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) {
this.addIndicesForPlacedIconSymbol(symbolInstance.verticalPlacedIconSymbolIndex);
}
}

Expand Down
25 changes: 0 additions & 25 deletions src/render/draw_symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,29 +208,6 @@ function updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, var
bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicTextLayoutVertexArray);
}

function updateVerticalLabels(bucket) {
const placedSymbols = bucket.text.placedSymbolArray;
const dynamicLayoutVertexArray = bucket.text.dynamicLayoutVertexArray;
dynamicLayoutVertexArray.clear();
for (let s = 0; s < placedSymbols.length; s++) {
const symbol: any = placedSymbols.get(s);
const shouldHide = symbol.hidden || !symbol.placedOrientation;
if (shouldHide) {
// These symbols are from an orientation that is not being used, or a label that wasn't placed
// so we don't need to do the extra math to figure out what incremental shift to apply.
symbolProjection.hideGlyphs(symbol.numGlyphs, dynamicLayoutVertexArray);
} else {
const tileAnchor = new Point(symbol.anchorX, symbol.anchorY);
const angle = (bucket.allowVerticalPlacement && symbol.placedOrientation === WritingMode.vertical) ? Math.PI / 2 : 0;

for (let g = 0; g < symbol.numGlyphs; g++) {
addDynamicAttributes(dynamicLayoutVertexArray, tileAnchor, angle);
}
}
}
bucket.text.dynamicLayoutVertexBuffer.updateData(dynamicLayoutVertexArray);
}

function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor,
rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode) {

Expand Down Expand Up @@ -305,8 +282,6 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate

if (alongLine) {
symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright);
} else if (isText && size && bucket.allowVerticalPlacement && !variablePlacement) {
updateVerticalLabels(bucket);
}

const matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor),
Expand Down
Loading