Cherry-pick arabic text to release branch v3.6.0 (#9071)
* [core] Throttle tiles to redo symbol placement at most once every 300ms. Fixes issue #8435 and prepares for pitch-scaling changes in issue #8967. * [core] Disable letter-spacing for Arabic labels (issue #9057)
This commit is contained in:
committed by
GitHub
parent
71b6865172
commit
fe17f7e8db
@@ -583,6 +583,8 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/util/thread_context.cpp
|
||||
src/mbgl/util/thread_context.hpp
|
||||
src/mbgl/util/thread_local.hpp
|
||||
src/mbgl/util/throttler.cpp
|
||||
src/mbgl/util/throttler.hpp
|
||||
src/mbgl/util/tile_coordinate.hpp
|
||||
src/mbgl/util/tile_cover.cpp
|
||||
src/mbgl/util/tile_cover.hpp
|
||||
|
||||
@@ -237,7 +237,7 @@ void SymbolLayout::prepare(const GlyphPositionMap& glyphs, const IconMap& icons)
|
||||
/* horizontalAlign */ horizontalAlign,
|
||||
/* verticalAlign */ verticalAlign,
|
||||
/* justify */ justify,
|
||||
/* spacing: ems */ layout.get<TextLetterSpacing>() * oneEm,
|
||||
/* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get<TextLetterSpacing>() * oneEm : 0.0f,
|
||||
/* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm),
|
||||
/* verticalHeight */ oneEm,
|
||||
/* writingMode */ writingMode,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <mbgl/map/query.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <iostream>
|
||||
@@ -41,7 +42,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
|
||||
obsolete,
|
||||
parameters.mode),
|
||||
glyphAtlas(glyphAtlas_),
|
||||
spriteAtlas(spriteAtlas_) {
|
||||
spriteAtlas(spriteAtlas_),
|
||||
placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) {
|
||||
}
|
||||
|
||||
GeometryTile::~GeometryTile() {
|
||||
@@ -81,7 +83,13 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
|
||||
|
||||
++correlationID;
|
||||
requestedConfig = desiredConfig;
|
||||
worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID);
|
||||
placementThrottler.invoke();
|
||||
}
|
||||
|
||||
void GeometryTile::invokePlacement() {
|
||||
if (requestedConfig) {
|
||||
worker.invoke(&GeometryTileWorker::setPlacementConfig, *requestedConfig, correlationID);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryTile::redoLayout() {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/text/glyph_atlas.hpp>
|
||||
#include <mbgl/text/placement_config.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/throttler.hpp>
|
||||
#include <mbgl/actor/actor.hpp>
|
||||
|
||||
#include <atomic>
|
||||
@@ -87,6 +88,8 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
void invokePlacement();
|
||||
|
||||
const std::string sourceID;
|
||||
style::Style& style;
|
||||
|
||||
@@ -108,6 +111,8 @@ private:
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
|
||||
std::unique_ptr<CollisionTile> collisionTile;
|
||||
|
||||
util::Throttler placementThrottler;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "i18n.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
namespace {
|
||||
@@ -29,14 +30,14 @@ DEFINE_IS_IN_UNICODE_BLOCK(Latin1Supplement, 0x0080, 0x00FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(CyrillicSupplement, 0x0500, 0x052F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Armenian, 0x0530, 0x058F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Hebrew, 0x0590, 0x05FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Arabic, 0x0600, 0x06FF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(Arabic, 0x0600, 0x06FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Syriac, 0x0700, 0x074F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Thaana, 0x0780, 0x07BF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(NKo, 0x07C0, 0x07FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Samaritan, 0x0800, 0x083F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Mandaic, 0x0840, 0x085F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Devanagari, 0x0900, 0x097F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Bengali, 0x0980, 0x09FF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Gurmukhi, 0x0A00, 0x0A7F)
|
||||
@@ -169,13 +170,13 @@ DEFINE_IS_IN_UNICODE_BLOCK(HangulJamoExtendedB, 0xD7B0, 0xD7FF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(PrivateUseArea, 0xE000, 0xF8FF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityIdeographs, 0xF900, 0xFAFF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(AlphabeticPresentationForms, 0xFB00, 0xFB4F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsA, 0xFB50, 0xFDFF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsA, 0xFB50, 0xFDFF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(VariationSelectors, 0xFE00, 0xFE0F)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(VerticalForms, 0xFE10, 0xFE1F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(CombiningHalfMarks, 0xFE20, 0xFE2F)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityForms, 0xFE30, 0xFE4F)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(SmallFormVariants, 0xFE50, 0xFE6F)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsB, 0xFE70, 0xFEFF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsB, 0xFE70, 0xFEFF)
|
||||
DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(Specials, 0xFFF0, 0xFFFF)
|
||||
// DEFINE_IS_IN_UNICODE_BLOCK(LinearBSyllabary, 0x10000, 0x1007F)
|
||||
@@ -332,6 +333,14 @@ bool allowsWordBreaking(char16_t chr) {
|
||||
|| chr == 0x2013 /* en dash */);
|
||||
}
|
||||
|
||||
bool charAllowsLetterSpacing(char16_t chr) {
|
||||
return !(isInArabic(chr) || isInArabicSupplement(chr) || isInArabicExtendedA(chr) || isInArabicPresentationFormsA(chr) || isInArabicPresentationFormsB(chr));
|
||||
}
|
||||
|
||||
bool allowsLetterSpacing(const std::u16string& string) {
|
||||
return std::all_of(string.begin(), string.end(), charAllowsLetterSpacing);
|
||||
}
|
||||
|
||||
bool allowsIdeographicBreaking(const std::u16string& string) {
|
||||
for (char16_t chr : string) {
|
||||
if (!allowsIdeographicBreaking(chr)) {
|
||||
|
||||
@@ -10,6 +10,10 @@ namespace i18n {
|
||||
by the given Unicode codepoint due to word breaking. */
|
||||
bool allowsWordBreaking(char16_t chr);
|
||||
|
||||
/** Returns whether the given string can be displayed with letter-spacing.
|
||||
False for Arabic scripts, where letter-spacing will break ligatures. */
|
||||
bool allowsLetterSpacing(const std::u16string& string);
|
||||
|
||||
/** Returns whether a line break can be inserted after any character in the
|
||||
given string. If false, line breaking should occur on word boundaries
|
||||
instead. */
|
||||
|
||||
36
src/mbgl/util/throttler.cpp
Normal file
36
src/mbgl/util/throttler.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/util/throttler.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
Throttler::Throttler(Duration frequency_, std::function<void()>&& function_)
|
||||
: frequency(frequency_)
|
||||
, function(std::move(function_))
|
||||
, pendingInvocation(false)
|
||||
, lastInvocation(TimePoint::min())
|
||||
{}
|
||||
|
||||
void Throttler::invoke() {
|
||||
if (pendingInvocation) {
|
||||
return;
|
||||
}
|
||||
|
||||
Duration timeToNextInvocation = lastInvocation == TimePoint::min()
|
||||
? Duration::zero()
|
||||
: (lastInvocation + frequency) - Clock::now();
|
||||
|
||||
if (timeToNextInvocation <= Duration::zero()) {
|
||||
lastInvocation = Clock::now();
|
||||
function();
|
||||
} else {
|
||||
pendingInvocation = true;
|
||||
timer.start(timeToNextInvocation, Duration::zero(), [this]{
|
||||
pendingInvocation = false;
|
||||
lastInvocation = Clock::now();
|
||||
function();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
22
src/mbgl/util/throttler.hpp
Normal file
22
src/mbgl/util/throttler.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/timer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
class Throttler {
|
||||
public:
|
||||
Throttler(Duration frequency, std::function<void()>&& function);
|
||||
|
||||
void invoke();
|
||||
private:
|
||||
Duration frequency;
|
||||
std::function<void()> function;
|
||||
|
||||
Timer timer;
|
||||
bool pendingInvocation;
|
||||
TimePoint lastInvocation;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user