[core] Pass images and evaluated layout text size to shaping
This commit is contained in:
@@ -352,16 +352,22 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
|
||||
ShapedTextOrientations shapedTextOrientations;
|
||||
optional<PositionedIcon> shapedIcon;
|
||||
std::array<float, 2> textOffset{{0.0f, 0.0f}};
|
||||
const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature);
|
||||
const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature);
|
||||
|
||||
// if feature has text, shape the text
|
||||
if (feature.formattedText) {
|
||||
const float lineHeight = layout->get<TextLineHeight>() * util::ONE_EM;
|
||||
const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout->evaluate<TextLetterSpacing>(zoom, feature) * util::ONE_EM : 0.0f;
|
||||
|
||||
auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode, SymbolAnchorType textAnchor, TextJustifyType textJustify) {
|
||||
auto applyShaping = [&](const TaggedString& formattedText,
|
||||
WritingModeType writingMode,
|
||||
SymbolAnchorType textAnchor,
|
||||
TextJustifyType textJustify) {
|
||||
const Shaping result = getShaping(
|
||||
/* string */ formattedText,
|
||||
/* maxWidth: ems */ isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f,
|
||||
/* maxWidth: ems */
|
||||
isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f,
|
||||
/* ems */ lineHeight,
|
||||
textAnchor,
|
||||
textJustify,
|
||||
@@ -370,10 +376,13 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
|
||||
/* writingMode */ writingMode,
|
||||
/* bidirectional algorithm object */ bidi,
|
||||
/* glyphs */ glyphMap,
|
||||
/* images */ imagePositions,
|
||||
layoutTextSize,
|
||||
allowVerticalPlacement);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout->evaluate<TextVariableAnchor>(zoom, feature);
|
||||
const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature);
|
||||
if (variableTextAnchor.empty()) {
|
||||
@@ -475,7 +484,15 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
|
||||
|
||||
// if either shapedText or icon position is present, add the feature
|
||||
if (getDefaultHorizontalShaping(shapedTextOrientations) || shapedIcon) {
|
||||
addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, std::move(shapedIcon), glyphPositions, textOffset, iconType);
|
||||
addFeature(std::distance(features.begin(), it),
|
||||
feature,
|
||||
shapedTextOrientations,
|
||||
std::move(shapedIcon),
|
||||
glyphPositions,
|
||||
textOffset,
|
||||
layoutTextSize,
|
||||
layoutIconSize,
|
||||
iconType);
|
||||
}
|
||||
|
||||
feature.geometry.clear();
|
||||
@@ -490,13 +507,12 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
|
||||
optional<PositionedIcon> shapedIcon,
|
||||
const GlyphPositions& glyphPositions,
|
||||
std::array<float, 2> textOffset,
|
||||
float layoutTextSize,
|
||||
float layoutIconSize,
|
||||
const SymbolContent iconType) {
|
||||
const float minScale = 0.5f;
|
||||
const float glyphSize = 24.0f;
|
||||
|
||||
const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature);
|
||||
const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature);
|
||||
|
||||
const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature);
|
||||
|
||||
// To reduce the number of labels that jump around when zooming we need
|
||||
|
||||
@@ -62,6 +62,8 @@ private:
|
||||
optional<PositionedIcon> shapedIcon,
|
||||
const GlyphPositions&,
|
||||
std::array<float, 2> textOffset,
|
||||
float layoutTextSize,
|
||||
float layoutIconSize,
|
||||
const SymbolContent iconType);
|
||||
|
||||
bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&);
|
||||
|
||||
@@ -166,7 +166,9 @@ void justifyLine(std::vector<PositionedGlyph>& positionedGlyphs,
|
||||
float determineAverageLineWidth(const TaggedString& logicalInput,
|
||||
const float spacing,
|
||||
float maxWidth,
|
||||
const GlyphMap& glyphMap) {
|
||||
const GlyphMap& glyphMap,
|
||||
const ImagePositions& /*imagePositions*/,
|
||||
float /*layoutTextSize*/) {
|
||||
float totalWidth = 0;
|
||||
|
||||
for (std::size_t i = 0; i < logicalInput.length(); i++) {
|
||||
@@ -279,7 +281,9 @@ std::set<std::size_t> leastBadBreaks(const PotentialBreak& lastLineBreak) {
|
||||
std::set<std::size_t> determineLineBreaks(const TaggedString& logicalInput,
|
||||
const float spacing,
|
||||
float maxWidth,
|
||||
const GlyphMap& glyphMap) {
|
||||
const GlyphMap& glyphMap,
|
||||
const ImagePositions& imagePositions,
|
||||
float layoutTextSize) {
|
||||
if (!maxWidth) {
|
||||
return {};
|
||||
}
|
||||
@@ -287,9 +291,10 @@ std::set<std::size_t> determineLineBreaks(const TaggedString& logicalInput,
|
||||
if (logicalInput.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const float targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap);
|
||||
|
||||
|
||||
const float targetWidth =
|
||||
determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize);
|
||||
|
||||
std::list<PotentialBreak> potentialBreaks;
|
||||
float currentX = 0;
|
||||
// Find first occurance of zero width space (ZWSP) character.
|
||||
@@ -332,6 +337,8 @@ void shapeLines(Shaping& shaping,
|
||||
const style::TextJustifyType textJustify,
|
||||
const WritingModeType writingMode,
|
||||
const GlyphMap& glyphMap,
|
||||
const ImagePositions& /*imagePositions*/,
|
||||
float /*layoutTextSize*/,
|
||||
bool allowVerticalPlacement) {
|
||||
float x = 0;
|
||||
float y = Shaping::yOffset;
|
||||
@@ -425,27 +432,39 @@ const Shaping getShaping(const TaggedString& formattedString,
|
||||
const WritingModeType writingMode,
|
||||
BiDi& bidi,
|
||||
const GlyphMap& glyphs,
|
||||
const ImagePositions& imagePositions,
|
||||
float layoutTextSize,
|
||||
bool allowVerticalPlacement) {
|
||||
std::vector<TaggedString> reorderedLines;
|
||||
if (formattedString.sectionCount() == 1) {
|
||||
auto untaggedLines = bidi.processText(formattedString.rawText(),
|
||||
determineLineBreaks(formattedString, spacing, maxWidth, glyphs));
|
||||
auto untaggedLines = bidi.processText(
|
||||
formattedString.rawText(),
|
||||
determineLineBreaks(formattedString, spacing, maxWidth, glyphs, imagePositions, layoutTextSize));
|
||||
for (const auto& line : untaggedLines) {
|
||||
reorderedLines.emplace_back(line, formattedString.sectionAt(0));
|
||||
}
|
||||
} else {
|
||||
auto processedLines = bidi.processStyledText(formattedString.getStyledText(),
|
||||
determineLineBreaks(formattedString, spacing, maxWidth, glyphs));
|
||||
auto processedLines = bidi.processStyledText(
|
||||
formattedString.getStyledText(),
|
||||
determineLineBreaks(formattedString, spacing, maxWidth, glyphs, imagePositions, layoutTextSize));
|
||||
for (const auto& line : processedLines) {
|
||||
reorderedLines.emplace_back(line, formattedString.getSections());
|
||||
}
|
||||
}
|
||||
Shaping shaping(translate[0], translate[1], writingMode, reorderedLines.size());
|
||||
shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor,
|
||||
textJustify, writingMode, glyphs, allowVerticalPlacement);
|
||||
|
||||
shapeLines(shaping,
|
||||
reorderedLines,
|
||||
spacing,
|
||||
lineHeight,
|
||||
textAnchor,
|
||||
textJustify,
|
||||
writingMode,
|
||||
glyphs,
|
||||
imagePositions,
|
||||
layoutTextSize,
|
||||
allowVerticalPlacement);
|
||||
|
||||
return shaping;
|
||||
}
|
||||
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -69,6 +69,8 @@ const Shaping getShaping(const TaggedString& string,
|
||||
const WritingModeType,
|
||||
BiDi& bidi,
|
||||
const GlyphMap& glyphs,
|
||||
const ImagePositions& imagePositions,
|
||||
float layoutTextSize,
|
||||
bool allowVerticalPlacement);
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -26,17 +26,21 @@ TEST(Shaping, ZWSP) {
|
||||
{ FontStackHasher()(fontStack), {{u'中', std::move(immutableGlyph)}} }
|
||||
};
|
||||
|
||||
const auto testGetShaping = [&] (const TaggedString& string, unsigned maxWidthInChars) {
|
||||
ImagePositions imagePositions;
|
||||
|
||||
const auto testGetShaping = [&](const TaggedString& string, unsigned maxWidthInChars) {
|
||||
return getShaping(string,
|
||||
maxWidthInChars * ONE_EM,
|
||||
ONE_EM, // lineHeight
|
||||
ONE_EM, // lineHeight
|
||||
style::SymbolAnchorType::Center,
|
||||
style::TextJustifyType::Center,
|
||||
0, // spacing
|
||||
0, // spacing
|
||||
{{0.0f, 0.0f}}, // translate
|
||||
WritingModeType::Horizontal,
|
||||
bidi,
|
||||
glyphs,
|
||||
imagePositions,
|
||||
16.0,
|
||||
/*allowVerticalPlacement*/ false);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user