mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-06 04:24:29 +00:00
Compare commits
3 Commits
60b1ad232a
...
b5354fd1e3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5354fd1e3 | ||
|
|
964f82510a | ||
|
|
faf49fc574 |
@@ -81,7 +81,7 @@ public:
|
|||||||
QPainter painter(device);
|
QPainter painter(device);
|
||||||
painter.fillRect(QRectF(0.0, 0.0, device->width(), device->height()), Qt::white);
|
painter.fillRect(QRectF(0.0, 0.0, device->width(), device->height()), Qt::white);
|
||||||
|
|
||||||
auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize, m_lang);
|
auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize);
|
||||||
|
|
||||||
std::cout << "Total width: " << shapedText.m_lineWidthInPixels << '\n';
|
std::cout << "Total width: " << shapedText.m_lineWidthInPixels << '\n';
|
||||||
std::cout << "Max height: " << shapedText.m_maxLineHeightInPixels << '\n';
|
std::cout << "Max height: " << shapedText.m_maxLineHeightInPixels << '\n';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "drape/harfbuzz_shaping.hpp"
|
#include "drape/harfbuzz_shaping.hpp"
|
||||||
|
|
||||||
#include "platform/platform.hpp"
|
#include "platform/platform.hpp"
|
||||||
|
#include "platform/preferred_languages.hpp"
|
||||||
|
|
||||||
#include "coding/hex.hpp"
|
#include "coding/hex.hpp"
|
||||||
#include "coding/reader.hpp"
|
#include "coding/reader.hpp"
|
||||||
@@ -328,6 +329,9 @@ FreetypeError constexpr g_FT_Errors[] =
|
|||||||
TUniBlockIter m_lastUsedBlock;
|
TUniBlockIter m_lastUsedBlock;
|
||||||
std::vector<std::unique_ptr<Font>> m_fonts;
|
std::vector<std::unique_ptr<Font>> m_fonts;
|
||||||
|
|
||||||
|
std::string const lang = languages::GetCurrentOrig();
|
||||||
|
hb_language_t const m_language = hb_language_from_string(lang.data(), static_cast<int>(lang.size()));
|
||||||
|
|
||||||
// Required to use std::string_view as a search key for std::unordered_map::find().
|
// Required to use std::string_view as a search key for std::unordered_map::find().
|
||||||
struct StringHash : public std::hash<std::string_view>
|
struct StringHash : public std::hash<std::string_view>
|
||||||
{
|
{
|
||||||
@@ -563,21 +567,8 @@ FreetypeError constexpr g_FT_Errors[] =
|
|||||||
return m_impl->m_fonts[key.m_fontIndex]->GetGlyphImage(key.m_glyphId, pixelHeight, sdf);
|
return m_impl->m_fonts[key.m_fontIndex]->GetGlyphImage(key.m_glyphId, pixelHeight, sdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
hb_language_t OrganicMapsLanguageToHarfbuzzLanguage(int8_t lang)
|
|
||||||
{
|
|
||||||
// TODO(AB): can langs be converted faster?
|
|
||||||
auto const svLang = StringUtf8Multilang::GetLangByCode(lang);
|
|
||||||
auto const hbLanguage = hb_language_from_string(svLang.data(), static_cast<int>(svLang.size()));
|
|
||||||
if (hbLanguage == HB_LANGUAGE_INVALID)
|
|
||||||
return hb_language_get_default();
|
|
||||||
return hbLanguage;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// This method is NOT multithreading-safe.
|
// This method is NOT multithreading-safe.
|
||||||
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang)
|
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int const fontSize = fontPixelHeight;
|
static int const fontSize = fontPixelHeight;
|
||||||
@@ -591,9 +582,6 @@ FreetypeError constexpr g_FT_Errors[] =
|
|||||||
|
|
||||||
auto const [text, segments] = harfbuzz_shaping::GetTextSegments(utf8);
|
auto const [text, segments] = harfbuzz_shaping::GetTextSegments(utf8);
|
||||||
|
|
||||||
// TODO(AB): Optimize language conversion.
|
|
||||||
hb_language_t const hbLanguage = OrganicMapsLanguageToHarfbuzzLanguage(lang);
|
|
||||||
|
|
||||||
text::TextMetrics allGlyphs;
|
text::TextMetrics allGlyphs;
|
||||||
// For SplitText it's enough to know if the last visual (first logical) segment is RTL.
|
// For SplitText it's enough to know if the last visual (first logical) segment is RTL.
|
||||||
allGlyphs.m_isRTL = segments.back().m_direction == HB_DIRECTION_RTL;
|
allGlyphs.m_isRTL = segments.back().m_direction == HB_DIRECTION_RTL;
|
||||||
@@ -609,7 +597,8 @@ FreetypeError constexpr g_FT_Errors[] =
|
|||||||
static_cast<int>(text.size()), substring.m_start, substring.m_length);
|
static_cast<int>(text.size()), substring.m_start, substring.m_length);
|
||||||
hb_buffer_set_direction(m_impl->m_harfbuzzBuffer, substring.m_direction);
|
hb_buffer_set_direction(m_impl->m_harfbuzzBuffer, substring.m_direction);
|
||||||
hb_buffer_set_script(m_impl->m_harfbuzzBuffer, substring.m_script);
|
hb_buffer_set_script(m_impl->m_harfbuzzBuffer, substring.m_script);
|
||||||
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, hbLanguage);
|
// TODO: This property is static, is it possible to set it only once?
|
||||||
|
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, m_impl->m_language);
|
||||||
|
|
||||||
auto u32CharacterIter{text.begin() + substring.m_start};
|
auto u32CharacterIter{text.begin() + substring.m_start};
|
||||||
auto const end{u32CharacterIter + substring.m_length};
|
auto const end{u32CharacterIter + substring.m_length};
|
||||||
@@ -646,10 +635,4 @@ FreetypeError constexpr g_FT_Errors[] =
|
|||||||
|
|
||||||
return allGlyphs;
|
return allGlyphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang)
|
|
||||||
{
|
|
||||||
return ShapeText(utf8, fontPixelHeight, StringUtf8Multilang::GetLangIndex(lang));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dp
|
} // namespace dp
|
||||||
|
|||||||
@@ -73,8 +73,7 @@ public:
|
|||||||
int GetFontIndex(strings::UniChar unicodePoint);
|
int GetFontIndex(strings::UniChar unicodePoint);
|
||||||
int GetFontIndex(std::u16string_view sv);
|
int GetFontIndex(std::u16string_view sv);
|
||||||
|
|
||||||
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang);
|
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight);
|
||||||
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang);
|
|
||||||
|
|
||||||
GlyphImage GetGlyphImage(GlyphFontAndId key, int pixelHeight, bool sdf) const;
|
GlyphImage GetGlyphImage(GlyphFontAndId key, int pixelHeight, bool sdf) const;
|
||||||
|
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
|
|||||||
m_maxGlypsCount = static_cast<uint32_t>(ceil(kGlyphAreaCoverage * textureSquare / averageGlyphSquare));
|
m_maxGlypsCount = static_cast<uint32_t>(ceil(kGlyphAreaCoverage * textureSquare / averageGlyphSquare));
|
||||||
|
|
||||||
std::string_view constexpr kSpace{" "};
|
std::string_view constexpr kSpace{" "};
|
||||||
m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels, "en").m_glyphs.front().m_key;
|
m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels).m_glyphs.front().m_key;
|
||||||
|
|
||||||
LOG(LDEBUG, ("Glyphs texture size =", kGlyphsTextureSize, "with max glyphs count =", m_maxGlypsCount));
|
LOG(LDEBUG, ("Glyphs texture size =", kGlyphsTextureSize, "with max glyphs count =", m_maxGlypsCount));
|
||||||
|
|
||||||
@@ -467,8 +467,7 @@ text::TextMetrics TextureManager::ShapeSingleTextLine(float fontPixelHeight, std
|
|||||||
// TODO(AB): Is this mutex too slow?
|
// TODO(AB): Is this mutex too slow?
|
||||||
std::lock_guard lock(m_calcGlyphsMutex);
|
std::lock_guard lock(m_calcGlyphsMutex);
|
||||||
|
|
||||||
// TODO(AB): Fix hard-coded lang.
|
auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight);
|
||||||
auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight, "en");
|
|
||||||
|
|
||||||
auto const & glyphs = textMetrics.m_glyphs;
|
auto const & glyphs = textMetrics.m_glyphs;
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ static std::pair<UniString, UniString> const kPreprocessReplacements[] = {
|
|||||||
{MakeUniString("ff. cc."), MakeUniString("ferrocarrís")},
|
{MakeUniString("ff. cc."), MakeUniString("ferrocarrís")},
|
||||||
{MakeUniString("f.ta"), MakeUniString("fondamenta")},
|
{MakeUniString("f.ta"), MakeUniString("fondamenta")},
|
||||||
{MakeUniString("g.n.r."), MakeUniString("guarda nacional republicana")},
|
{MakeUniString("g.n.r."), MakeUniString("guarda nacional republicana")},
|
||||||
|
{MakeUniString("g-ral"), MakeUniString("general")}
|
||||||
{MakeUniString("g. v."), MakeUniString("gran vía")},
|
{MakeUniString("g. v."), MakeUniString("gran vía")},
|
||||||
{MakeUniString("i.d."), MakeUniString("in der")},
|
{MakeUniString("i.d."), MakeUniString("in der")},
|
||||||
{MakeUniString("k/s"), MakeUniString("khách sạn")},
|
{MakeUniString("k/s"), MakeUniString("khách sạn")},
|
||||||
|
|||||||
@@ -244,12 +244,12 @@ void NotificationManager::SetLengthUnits(measurement_utils::Units units)
|
|||||||
switch (units)
|
switch (units)
|
||||||
{
|
{
|
||||||
case measurement_utils::Units::Metric:
|
case measurement_utils::Units::Metric:
|
||||||
m_settings.SetState(30 /* notificationTimeSeconds */, 400 /* minNotificationDistanceUnits */,
|
m_settings.SetState(30 /* notificationTimeSeconds */, 200 /* minNotificationDistanceUnits */,
|
||||||
2000 /* maxNotificationDistanceUnits */, GetSoundedDistMeters() /* soundedDistancesUnits */,
|
2000 /* maxNotificationDistanceUnits */, GetSoundedDistMeters() /* soundedDistancesUnits */,
|
||||||
measurement_utils::Units::Metric /* lengthUnits */);
|
measurement_utils::Units::Metric /* lengthUnits */);
|
||||||
return;
|
return;
|
||||||
case measurement_utils::Units::Imperial:
|
case measurement_utils::Units::Imperial:
|
||||||
m_settings.SetState(30 /* notificationTimeSeconds */, 1000 /* minNotificationDistanceUnits */,
|
m_settings.SetState(30 /* notificationTimeSeconds */, 500 /* minNotificationDistanceUnits */,
|
||||||
5000 /* maxNotificationDistanceUnits */, GetSoundedDistFeet() /* soundedDistancesUnits */,
|
5000 /* maxNotificationDistanceUnits */, GetSoundedDistFeet() /* soundedDistancesUnits */,
|
||||||
measurement_utils::Units::Imperial /* lengthUnits */);
|
measurement_utils::Units::Imperial /* lengthUnits */);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
|||||||
{"low", {"lower"}},
|
{"low", {"lower"}},
|
||||||
{"lp", {"loop"}},
|
{"lp", {"loop"}},
|
||||||
{"lr", {"lower"}},
|
{"lr", {"lower"}},
|
||||||
{"lt", {"lote", "lieutenant", "little"}},
|
{"lt", {"lote", "lieutenant", "little", "locotelent"}},
|
||||||
{"lug", {"lugar"}},
|
{"lug", {"lugar"}},
|
||||||
{"luit", {"luitenant"}},
|
{"luit", {"luitenant"}},
|
||||||
{"lung", {"lungsod"}},
|
{"lung", {"lungsod"}},
|
||||||
@@ -1111,6 +1111,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
|||||||
{"seventh", {"7th"}},
|
{"seventh", {"7th"}},
|
||||||
{"sexta", {"6", "6a"}},
|
{"sexta", {"6", "6a"}},
|
||||||
{"sexto", {"6", "6o"}},
|
{"sexto", {"6", "6o"}},
|
||||||
|
{"sf", {"sfântul", "sfânta", "sfinții"}},
|
||||||
{"sgda", {"sagrada"}},
|
{"sgda", {"sagrada"}},
|
||||||
{"sg", {"schottergrube", "sungai", "sandgrube"}},
|
{"sg", {"schottergrube", "sungai", "sandgrube"}},
|
||||||
{"sgt", {"sagrat", "sergeant"}},
|
{"sgt", {"sagrat", "sergeant"}},
|
||||||
@@ -1390,6 +1391,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
|||||||
{"б", {"большая", "большой"}},
|
{"б", {"большая", "большой"}},
|
||||||
{"бл", {"блок"}},
|
{"бл", {"блок"}},
|
||||||
{"бол", {"большая", "большой"}},
|
{"бол", {"большая", "большой"}},
|
||||||
|
{"буд", {"будинок"}},
|
||||||
{"бул", {"булевард", "бульвар"}},
|
{"бул", {"булевард", "бульвар"}},
|
||||||
{"вул", {"вулиця"}},
|
{"вул", {"вулиця"}},
|
||||||
{"вх", {"вход"}},
|
{"вх", {"вход"}},
|
||||||
@@ -1402,7 +1404,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
|||||||
{"кв", {"квартал"}},
|
{"кв", {"квартал"}},
|
||||||
{"мал", {"малый", "малая"}},
|
{"мал", {"малый", "малая"}},
|
||||||
{"мит", {"митрополит"}},
|
{"мит", {"митрополит"}},
|
||||||
{"м", {"малый", "малая"}},
|
{"м", {"малый", "малая", "місто"}},
|
||||||
{"наб", {"набережная", "набережна", "набярэжная"}},
|
{"наб", {"набережная", "набережна", "набярэжная"}},
|
||||||
{"нов", {"новый", "новая"}},
|
{"нов", {"новый", "новая"}},
|
||||||
{"обл", {"область"}},
|
{"обл", {"область"}},
|
||||||
@@ -1416,6 +1418,7 @@ unordered_map<string, vector<string>> const kSynonyms = {
|
|||||||
{"с", {"село"}},
|
{"с", {"село"}},
|
||||||
{"стар", {"старая", "старый"}},
|
{"стар", {"старая", "старый"}},
|
||||||
{"туп", {"тупик", "тупік"}},
|
{"туп", {"тупик", "тупік"}},
|
||||||
|
{"узв", {"узвіз"}},
|
||||||
{"ул", {"улица"}},
|
{"ул", {"улица"}},
|
||||||
{"ш", {"шаша", "шосе", "шоссе"}},
|
{"ш", {"шаша", "шосе", "шоссе"}},
|
||||||
{"اثنان", {"2"}},
|
{"اثنان", {"2"}},
|
||||||
|
|||||||
Reference in New Issue
Block a user