text-pitch-alignment (#5288)
* First pass at port of https://github.com/mapbox/mapbox-gl-js/pull/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
This commit is contained in:
@@ -47,8 +47,8 @@ public:
|
||||
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>);
|
||||
@@ -68,8 +68,11 @@ public:
|
||||
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>);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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':
|
||||
@@ -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':
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -140,7 +140,8 @@ private:
|
||||
void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&),
|
||||
|
||||
// Layout
|
||||
style::RotationAlignmentType rotationAlignment,
|
||||
style::AlignmentType rotationAlignment,
|
||||
style::AlignmentType pitchAlignment,
|
||||
float layoutSize,
|
||||
|
||||
// Paint
|
||||
|
||||
@@ -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
|
||||
@@ -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());
|
||||
@@ -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);
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
@@ -230,6 +239,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
|
||||
*sdfGlyphShader,
|
||||
&SymbolBucket::drawGlyphs,
|
||||
layout.textRotationAlignment,
|
||||
layout.textPitchAlignment,
|
||||
layout.textSize,
|
||||
paint.textOpacity,
|
||||
paint.textColor,
|
||||
|
||||
@@ -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;
|
||||
@@ -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 ||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
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};
|
||||
|
||||
|
||||
@@ -17,7 +17,11 @@ public:
|
||||
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};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -23,14 +23,15 @@ public:
|
||||
LayoutProperty<bool> iconAllowOverlap { false };
|
||||
LayoutProperty<bool> iconIgnorePlacement { false };
|
||||
LayoutProperty<bool> iconOptional { false };
|
||||
LayoutProperty<RotationAlignmentType> iconRotationAlignment { RotationAlignmentType::Viewport };
|
||||
LayoutProperty<AlignmentType> iconRotationAlignment { AlignmentType::Viewport };
|
||||
LayoutProperty<float> iconSize { 1 };
|
||||
LayoutProperty<std::string> iconImage { "" };
|
||||
LayoutProperty<float> iconRotate { 0 };
|
||||
LayoutProperty<float> iconPadding { 2 };
|
||||
LayoutProperty<bool> iconKeepUpright { false };
|
||||
LayoutProperty<std::array<float, 2>> iconOffset { {{ 0, 0 }} };
|
||||
LayoutProperty<RotationAlignmentType> textRotationAlignment { RotationAlignmentType::Viewport };
|
||||
LayoutProperty<AlignmentType> textPitchAlignment { AlignmentType::Undefined };
|
||||
LayoutProperty<AlignmentType> textRotationAlignment { AlignmentType::Viewport };
|
||||
LayoutProperty<std::string> textField { "" };
|
||||
LayoutProperty<std::vector<std::string>> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } };
|
||||
LayoutProperty<float> textSize { 16 };
|
||||
|
||||
@@ -29,7 +29,7 @@ template <> inline SymbolPlacementType defaultStopsValue() { return {}; };
|
||||
template <> inline TextAnchorType defaultStopsValue() { return {}; };
|
||||
template <> inline TextJustifyType defaultStopsValue() { return {}; };
|
||||
template <> inline TextTransformType defaultStopsValue() { return {}; };
|
||||
template <> inline RotationAlignmentType defaultStopsValue() { return {}; };
|
||||
template <> inline AlignmentType defaultStopsValue() { return {}; };
|
||||
|
||||
template <typename T>
|
||||
T PropertyEvaluator<T>::operator()(const Function<T>& fn) const {
|
||||
@@ -97,7 +97,7 @@ template class PropertyEvaluator<SymbolPlacementType>;
|
||||
template class PropertyEvaluator<TextAnchorType>;
|
||||
template class PropertyEvaluator<TextJustifyType>;
|
||||
template class PropertyEvaluator<TextTransformType>;
|
||||
template class PropertyEvaluator<RotationAlignmentType>;
|
||||
template class PropertyEvaluator<AlignmentType>;
|
||||
|
||||
template <typename T>
|
||||
Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Undefined&) const {
|
||||
|
||||
@@ -188,19 +188,19 @@ optional<TextTransformType> parseConstant<TextTransformType>(const char* name, c
|
||||
return { TextTransformTypeClass({ value.GetString(), value.GetStringLength() }) };
|
||||
}
|
||||
|
||||
MBGL_DEFINE_ENUM_CLASS(RotationAlignmentTypeClass, RotationAlignmentType, {
|
||||
{ RotationAlignmentType::Map, "map" },
|
||||
{ RotationAlignmentType::Viewport, "viewport" },
|
||||
MBGL_DEFINE_ENUM_CLASS(AlignmentTypeClass, AlignmentType, {
|
||||
{ AlignmentType::Map, "map" },
|
||||
{ AlignmentType::Viewport, "viewport" },
|
||||
});
|
||||
|
||||
template <>
|
||||
optional<RotationAlignmentType> parseConstant<RotationAlignmentType>(const char* name, const JSValue& value) {
|
||||
optional<AlignmentType> parseConstant<AlignmentType>(const char* name, const JSValue& value) {
|
||||
if (!value.IsString()) {
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
|
||||
return {};
|
||||
}
|
||||
|
||||
return { RotationAlignmentTypeClass({ value.GetString(), value.GetStringLength() }) };
|
||||
return { AlignmentTypeClass({ value.GetString(), value.GetStringLength() }) };
|
||||
}
|
||||
|
||||
template <>
|
||||
|
||||
@@ -32,7 +32,7 @@ template <> optional<SymbolPlacementType> parseConstant(const char*, const JSVal
|
||||
template <> optional<TextAnchorType> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<TextJustifyType> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<TextTransformType> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<RotationAlignmentType> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<AlignmentType> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<std::array<float, 2>> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<std::vector<float>> parseConstant(const char*, const JSValue&);
|
||||
template <> optional<std::vector<std::string>> parseConstant(const char*, const JSValue&);
|
||||
|
||||
@@ -57,7 +57,7 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
|
||||
}
|
||||
|
||||
SymbolQuads quads;
|
||||
quads.emplace_back(tl, tr, bl, br, image.pos, 0, anchor.point, globalMinScale, std::numeric_limits<float>::infinity());
|
||||
quads.emplace_back(tl, tr, bl, br, image.pos, 0, 0, anchor.point, globalMinScale, std::numeric_limits<float>::infinity());
|
||||
return quads;
|
||||
}
|
||||
|
||||
@@ -102,8 +102,6 @@ void getSegmentGlyphs(std::back_insert_iterator<GlyphInstances> glyphs, Anchor &
|
||||
float angle = std::atan2(end.y - newAnchorPoint.y, end.x - newAnchorPoint.x);
|
||||
if (!forward)
|
||||
angle += M_PI;
|
||||
if (upsideDown)
|
||||
angle += M_PI;
|
||||
|
||||
glyphs = GlyphInstance{
|
||||
/* anchor */ newAnchorPoint,
|
||||
@@ -188,12 +186,11 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText,
|
||||
Point<float> tr = otr;
|
||||
Point<float> bl = obl;
|
||||
Point<float> br = obr;
|
||||
const float angle = instance.angle + textRotate;
|
||||
|
||||
if (angle) {
|
||||
if (textRotate) {
|
||||
// Compute the transformation matrix.
|
||||
float angle_sin = std::sin(angle);
|
||||
float angle_cos = std::cos(angle);
|
||||
float angle_sin = std::sin(textRotate);
|
||||
float angle_cos = std::cos(textRotate);
|
||||
std::array<float, 4> matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
|
||||
|
||||
tl = util::matrixMultiply(matrix, tl);
|
||||
@@ -205,8 +202,9 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText,
|
||||
// Prevent label from extending past the end of the line
|
||||
const float glyphMinScale = std::max(instance.minScale, anchor.scale);
|
||||
|
||||
const float glyphAngle = std::fmod((anchor.angle + textRotate + instance.offset + 2 * M_PI), (2 * M_PI));
|
||||
quads.emplace_back(tl, tr, bl, br, rect, glyphAngle, instance.anchorPoint, glyphMinScale, instance.maxScale);
|
||||
const float anchorAngle = std::fmod((anchor.angle + textRotate + instance.offset + 2 * M_PI), (2 * M_PI));
|
||||
const float glyphAngle = std::fmod((instance.angle + textRotate + instance.offset + 2 * M_PI), (2 * M_PI));
|
||||
quads.emplace_back(tl, tr, bl, br, rect, anchorAngle, glyphAngle, instance.anchorPoint, glyphMinScale, instance.maxScale);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -17,21 +17,22 @@ class SymbolLayoutProperties;
|
||||
struct SymbolQuad {
|
||||
explicit SymbolQuad(const Point<float> &tl_, const Point<float> &tr_,
|
||||
const Point<float> &bl_, const Point<float> &br_,
|
||||
const Rect<uint16_t> &tex_, float angle_, const Point<float> &anchorPoint_,
|
||||
const Rect<uint16_t> &tex_, float anchorAngle_, float glyphAngle_, const Point<float> &anchorPoint_,
|
||||
float minScale_, float maxScale_)
|
||||
: tl(tl_),
|
||||
tr(tr_),
|
||||
bl(bl_),
|
||||
br(br_),
|
||||
tex(tex_),
|
||||
angle(angle_),
|
||||
anchorAngle(anchorAngle_),
|
||||
glyphAngle(glyphAngle_),
|
||||
anchorPoint(anchorPoint_),
|
||||
minScale(minScale_),
|
||||
maxScale(maxScale_) {}
|
||||
|
||||
Point<float> tl, tr, bl, br;
|
||||
Rect<uint16_t> tex;
|
||||
float angle;
|
||||
float anchorAngle, glyphAngle;
|
||||
Point<float> anchorPoint;
|
||||
float minScale, maxScale;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user