Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
text-pitch-alignment (#5288)
Browse files Browse the repository at this point in the history
* First pass at port of mapbox/mapbox-gl-js#2668

* RotationAlignmentType => AlignmentType

* Handle undefined default value for text-pitch-alignment and implement inheritance for this value from text-rotation-alignment

* Update dependencies

* Move handling fo undefined default value out of camelize functions
  • Loading branch information
yhahn authored Jun 11, 2016
1 parent a8df0fe commit ecd4aa1
Show file tree
Hide file tree
Showing 22 changed files with 107 additions and 65 deletions.
11 changes: 7 additions & 4 deletions include/mbgl/style/layers/symbol_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class SymbolLayer : public Layer {
PropertyValue<bool> getIconOptional() const;
void setIconOptional(PropertyValue<bool>);

PropertyValue<RotationAlignmentType> getIconRotationAlignment() const;
void setIconRotationAlignment(PropertyValue<RotationAlignmentType>);
PropertyValue<AlignmentType> getIconRotationAlignment() const;
void setIconRotationAlignment(PropertyValue<AlignmentType>);

PropertyValue<float> getIconSize() const;
void setIconSize(PropertyValue<float>);
Expand All @@ -68,8 +68,11 @@ class SymbolLayer : public Layer {
PropertyValue<std::array<float, 2>> getIconOffset() const;
void setIconOffset(PropertyValue<std::array<float, 2>>);

PropertyValue<RotationAlignmentType> getTextRotationAlignment() const;
void setTextRotationAlignment(PropertyValue<RotationAlignmentType>);
PropertyValue<AlignmentType> getTextPitchAlignment() const;
void setTextPitchAlignment(PropertyValue<AlignmentType>);

PropertyValue<AlignmentType> getTextRotationAlignment() const;
void setTextRotationAlignment(PropertyValue<AlignmentType>);

PropertyValue<std::string> getTextField() const;
void setTextField(PropertyValue<std::string>);
Expand Down
3 changes: 2 additions & 1 deletion include/mbgl/style/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ enum class SymbolPlacementType : bool {
Line,
};

enum class RotationAlignmentType : bool {
enum class AlignmentType : uint8_t {
Map,
Viewport,
Undefined,
};

enum class TextJustifyType : uint8_t {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"csscolorparser": "^1.0.2",
"ejs": "^2.4.1",
"express": "^4.11.1",
"mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#f0b94dcc5f782958e9aade61d592a207d8a46e0f",
"mapbox-gl-style-spec": "^8.5.1",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#3e27bc27ea050952481ef1f9a655538590eccb26",
"mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#30caf388dbddd02cfc4f967ffc94c1338c30fbf8",
"mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#2461efc3d883f2f2e56a6c6b2bfd7d54bbfe9f86",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#5587d796c99145991ea2a7b749a8782b7a0cb483",
"node-gyp": "^3.3.1",
"request": "^2.72.0",
"tape": "^4.5.1"
Expand Down
10 changes: 7 additions & 3 deletions scripts/generate-style-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ global.propertyType = function (property) {
if (/-translate-anchor$/.test(property.name)) {
return 'TranslateAnchorType';
}
if (/-rotation-alignment$/.test(property.name)) {
return 'RotationAlignmentType';
if (/-(rotation|pitch)-alignment$/.test(property.name)) {
return 'AlignmentType';
}
switch (property.type) {
case 'boolean':
Expand Down Expand Up @@ -57,7 +57,11 @@ global.defaultValue = function (property) {
case 'string':
return JSON.stringify(property.default || "");
case 'enum':
return `${propertyType(property)}::${camelize(property.default)}`;
if (property.default === undefined) {
return `${propertyType(property)}::Undefined`;
} else {
return `${propertyType(property)}::${camelize(property.default)}`;
}
case 'color':
return `{{ ${parseCSSColor(property.default).join(', ')} }}`
case 'array':
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/geometry/icon_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace mbgl {

size_t IconVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom) {
size_t IconVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
const size_t idx = index();
void *data = addElement();

Expand All @@ -21,6 +21,7 @@ size_t IconVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, int16_t t
ubytes[8] /* tex */ = tx / 4;
ubytes[9] /* tex */ = ty / 4;
ubytes[10] /* labelminzoom */ = labelminzoom * 10;
ubytes[11] /* labelangle */ = labelangle;

// a_data2
ubytes[12] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/geometry/icon_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace mbgl {
16
> {
public:
size_t add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom);
size_t add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);

};

Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/geometry/text_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace mbgl {

size_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom) {
size_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
const size_t idx = index();
void *data = addElement();

Expand All @@ -21,6 +21,7 @@ size_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t
ubytes[8] /* tex */ = tx / 4;
ubytes[9] /* tex */ = ty / 4;
ubytes[10] /* labelminzoom */ = labelminzoom * 10;
ubytes[11] /* labelangle */ = labelangle;

// a_data2
ubytes[12] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/geometry/text_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TextVertexBuffer : public Buffer <
public:
typedef int16_t vertex_type;

size_t add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom);
size_t add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);
};


Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/painter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ class Painter : private util::noncopyable {
void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&),

// Layout
style::RotationAlignmentType rotationAlignment,
style::AlignmentType rotationAlignment,
style::AlignmentType pitchAlignment,
float layoutSize,

// Paint
Expand Down
30 changes: 20 additions & 10 deletions src/mbgl/renderer/painter_symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ void Painter::renderSDF(SymbolBucket &bucket,
void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&),

// Layout
RotationAlignmentType rotationAlignment,
AlignmentType rotationAlignment,
AlignmentType pitchAlignment,
float layoutSize,

// Paint
Expand All @@ -45,10 +46,11 @@ void Painter::renderSDF(SymbolBucket &bucket,

float scale = fontScale;
std::array<float, 2> exScale = extrudeScale;
bool alignedWithMap = rotationAlignment == RotationAlignmentType::Map;
bool rotateWithMap = rotationAlignment == AlignmentType::Map;
bool pitchWithMap = pitchAlignment == AlignmentType::Map;
float gammaScale = 1.0f;

if (alignedWithMap) {
if (pitchWithMap) {
scale *= tileID.pixelsToTileUnits(1, state.getZoom());
exScale.fill(scale);
gammaScale /= std::cos(state.getPitch());
Expand All @@ -60,8 +62,12 @@ void Painter::renderSDF(SymbolBucket &bucket,
sdfShader.u_matrix = vtxMatrix;
sdfShader.u_extrude_scale = exScale;
sdfShader.u_texsize = texsize;
sdfShader.u_skewed = alignedWithMap;
sdfShader.u_rotate_with_map = rotateWithMap;
sdfShader.u_pitch_with_map = pitchWithMap;
sdfShader.u_texture = 0;
sdfShader.u_pitch = state.getPitch() * util::DEG2RAD;
sdfShader.u_bearing = -1.0f * state.getAngle();
sdfShader.u_aspect_ratio = (state.getWidth() * 1.0f) / (state.getHeight() * 1.0f);

// adjust min/max zooms for variable font sies
float zoomAdjust = std::log(fontSize / layoutSize) / std::log(2);
Expand Down Expand Up @@ -135,7 +141,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
}

if (bucket.hasIconData()) {
if (layout.iconRotationAlignment == RotationAlignmentType::Map) {
if (layout.iconRotationAlignment == AlignmentType::Map) {
config.depthFunc.reset();
config.depthTest = GL_TRUE;
} else {
Expand All @@ -145,7 +151,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
bool sdf = bucket.sdfIcons;

const float angleOffset =
layout.iconRotationAlignment == RotationAlignmentType::Map
layout.iconRotationAlignment == AlignmentType::Map
? state.getAngle()
: 0;

Expand All @@ -154,7 +160,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,

SpriteAtlas* activeSpriteAtlas = layer.impl->spriteAtlas;
const bool iconScaled = fontScale != 1 || frame.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear;
const bool iconTransformed = layout.iconRotationAlignment == RotationAlignmentType::Map || angleOffset != 0 || state.getPitch() != 0;
const bool iconTransformed = layout.iconRotationAlignment == AlignmentType::Map || angleOffset != 0 || state.getPitch() != 0;
config.activeTexture = GL_TEXTURE0;
activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed, store);

Expand All @@ -167,6 +173,9 @@ void Painter::renderSymbol(SymbolBucket& bucket,
*sdfIconShader,
&SymbolBucket::drawIcons,
layout.iconRotationAlignment,
// icon-pitch-alignment is not yet implemented
// and we simply inherit the rotation alignment
layout.iconRotationAlignment,
layout.iconSize,
paint.iconOpacity,
paint.iconColor,
Expand All @@ -182,7 +191,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,

float scale = fontScale;
std::array<float, 2> exScale = extrudeScale;
const bool alignedWithMap = layout.iconRotationAlignment == RotationAlignmentType::Map;
const bool alignedWithMap = layout.iconRotationAlignment == AlignmentType::Map;
if (alignedWithMap) {
scale *= tileID.pixelsToTileUnits(1, state.getZoom());
exScale.fill(scale);
Expand All @@ -194,7 +203,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
iconShader->u_matrix = vtxMatrix;
iconShader->u_extrude_scale = exScale;
iconShader->u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
iconShader->u_skewed = alignedWithMap;
iconShader->u_rotate_with_map = alignedWithMap;
iconShader->u_texture = 0;

// adjust min/max zooms for variable font sies
Expand All @@ -212,7 +221,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
}

if (bucket.hasTextData()) {
if (layout.textRotationAlignment == RotationAlignmentType::Map) {
if (layout.textRotationAlignment == AlignmentType::Map) {
config.depthFunc.reset();
config.depthTest = GL_TRUE;
} else {
Expand All @@ -230,6 +239,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
*sdfGlyphShader,
&SymbolBucket::drawGlyphs,
layout.textRotationAlignment,
layout.textPitchAlignment,
layout.textSize,
paint.textOpacity,
paint.textColor,
Expand Down
21 changes: 12 additions & 9 deletions src/mbgl/renderer/symbol_bucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ void SymbolBucket::addFeature(const GeometryCollection &lines,
const float iconPadding = layout.iconPadding * tilePixelRatio;
const float textMaxAngle = layout.textMaxAngle * util::DEG2RAD;
const bool textAlongLine =
layout.textRotationAlignment == RotationAlignmentType::Map &&
layout.textRotationAlignment == AlignmentType::Map &&
layout.symbolPlacement == SymbolPlacementType::Line;
const bool iconAlongLine =
layout.iconRotationAlignment == RotationAlignmentType::Map &&
layout.iconRotationAlignment == AlignmentType::Map &&
layout.symbolPlacement == SymbolPlacementType::Line;
const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap ||
layout.textIgnorePlacement || layout.iconIgnorePlacement;
Expand Down Expand Up @@ -394,10 +394,10 @@ void SymbolBucket::placeFeatures(CollisionTile& collisionTile) {
// create the bufers used for rendering.

const bool textAlongLine =
layout.textRotationAlignment == RotationAlignmentType::Map &&
layout.textRotationAlignment == AlignmentType::Map &&
layout.symbolPlacement == SymbolPlacementType::Line;
const bool iconAlongLine =
layout.iconRotationAlignment == RotationAlignmentType::Map &&
layout.iconRotationAlignment == AlignmentType::Map &&
layout.symbolPlacement == SymbolPlacementType::Line;

const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap ||
Expand Down Expand Up @@ -495,7 +495,7 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
const auto &anchorPoint = symbol.anchorPoint;

// drop upside down versions of glyphs
const float a = std::fmod(symbol.angle + placementAngle + M_PI, M_PI * 2);
const float a = std::fmod(symbol.anchorAngle + placementAngle + M_PI, M_PI * 2);
if (keepUpright && alongLine && (a <= M_PI / 2 || a > M_PI * 3 / 2)) continue;


Expand All @@ -521,15 +521,18 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
auto &triangleGroup = *buffer.groups.back();
GLsizei triangleIndex = triangleGroup.vertex_length;

// Encode angle of glyph
uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256);

// coordinates (2 triangles)
buffer.vertices.add(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
maxZoom, placementZoom);
maxZoom, placementZoom, glyphAngle);
buffer.vertices.add(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
minZoom, maxZoom, placementZoom);
minZoom, maxZoom, placementZoom, glyphAngle);
buffer.vertices.add(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
minZoom, maxZoom, placementZoom);
minZoom, maxZoom, placementZoom, glyphAngle);
buffer.vertices.add(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
minZoom, maxZoom, placementZoom);
minZoom, maxZoom, placementZoom, glyphAngle);

// add the two triangles, referencing the four coordinates we just inserted.
buffer.triangles.add(triangleIndex + 0, triangleIndex + 1, triangleIndex + 2);
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/shader/icon_shader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class IconShader : public Shader {
Uniform<GLfloat> u_zoom = {"u_zoom", *this};
Uniform<GLfloat> u_opacity = {"u_opacity", *this};
Uniform<std::array<GLfloat, 2>> u_texsize = {"u_texsize", *this};
Uniform<GLint> u_skewed = {"u_skewed", *this};
Uniform<GLint> u_rotate_with_map = {"u_rotate_with_map", *this};
Uniform<GLint> u_texture = {"u_texture", *this};
Uniform<GLint> u_fadetexture = {"u_fadetexture", *this};

Expand Down
6 changes: 5 additions & 1 deletion src/mbgl/shader/sdf_shader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ class SDFShader : public Shader {
Uniform<GLfloat> u_buffer = {"u_buffer", *this};
Uniform<GLfloat> u_gamma = {"u_gamma", *this};
Uniform<GLfloat> u_zoom = {"u_zoom", *this};
Uniform<GLint> u_skewed = {"u_skewed", *this};
Uniform<GLfloat> u_pitch = {"u_pitch", *this};
Uniform<GLfloat> u_bearing = {"u_bearing", *this};
Uniform<GLfloat> u_aspect_ratio = {"u_aspect_ratio", *this};
Uniform<GLint> u_rotate_with_map = {"u_rotate_with_map",*this};
Uniform<GLint> u_pitch_with_map = {"u_pitch_with_map",*this};
Uniform<GLint> u_texture = {"u_texture", *this};
Uniform<GLint> u_fadetexture = {"u_fadetexture", *this};

Expand Down
15 changes: 11 additions & 4 deletions src/mbgl/style/layers/symbol_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ PropertyValue<bool> SymbolLayer::getIconOptional() const {
void SymbolLayer::setIconOptional(PropertyValue<bool> value) {
impl->layout.iconOptional.set(value);
}
PropertyValue<RotationAlignmentType> SymbolLayer::getIconRotationAlignment() const {
PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const {
return impl->layout.iconRotationAlignment.get();
}

void SymbolLayer::setIconRotationAlignment(PropertyValue<RotationAlignmentType> value) {
void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) {
impl->layout.iconRotationAlignment.set(value);
}
PropertyValue<float> SymbolLayer::getIconSize() const {
Expand Down Expand Up @@ -141,11 +141,18 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) {
impl->layout.iconOffset.set(value);
}
PropertyValue<RotationAlignmentType> SymbolLayer::getTextRotationAlignment() const {
PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const {
return impl->layout.textPitchAlignment.get();
}

void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) {
impl->layout.textPitchAlignment.set(value);
}
PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const {
return impl->layout.textRotationAlignment.get();
}

void SymbolLayer::setTextRotationAlignment(PropertyValue<RotationAlignmentType> value) {
void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) {
impl->layout.textRotationAlignment.set(value);
}
PropertyValue<std::string> SymbolLayer::getTextField() const {
Expand Down
9 changes: 7 additions & 2 deletions src/mbgl/style/layers/symbol_layer_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters& parame
CalculationParameters p(parameters.tileID.overscaledZ);
bucket->layout.symbolPlacement.calculate(p);
if (bucket->layout.symbolPlacement.value == SymbolPlacementType::Line) {
bucket->layout.iconRotationAlignment.value = RotationAlignmentType::Map;
bucket->layout.textRotationAlignment.value = RotationAlignmentType::Map;
bucket->layout.iconRotationAlignment.value = AlignmentType::Map;
bucket->layout.textRotationAlignment.value = AlignmentType::Map;
};

// If unspecified `text-pitch-alignment` inherits `text-rotation-alignment`
if (bucket->layout.textPitchAlignment.value == AlignmentType::Undefined) {
bucket->layout.textPitchAlignment.value = bucket->layout.textRotationAlignment.value;
};

bucket->layout.recalculate(p);
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/style/layers/symbol_layer_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void SymbolLayoutProperties::parse(const JSValue& value) {
iconPadding.parse("icon-padding", value);
iconKeepUpright.parse("icon-keep-upright", value);
iconOffset.parse("icon-offset", value);
textPitchAlignment.parse("text-pitch-alignment", value);
textRotationAlignment.parse("text-rotation-alignment", value);
textField.parse("text-field", value);
textFont.parse("text-font", value);
Expand Down Expand Up @@ -53,6 +54,7 @@ void SymbolLayoutProperties::recalculate(const CalculationParameters& parameters
iconPadding.calculate(parameters);
iconKeepUpright.calculate(parameters);
iconOffset.calculate(parameters);
textPitchAlignment.calculate(parameters);
textRotationAlignment.calculate(parameters);
textField.calculate(parameters);
textFont.calculate(parameters);
Expand Down
Loading

0 comments on commit ecd4aa1

Please sign in to comment.