summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Morris <mikemorris@users.noreply.github.com>2016-04-11 16:01:12 -0700
committerMike Morris <mikemorris@users.noreply.github.com>2016-04-11 16:01:12 -0700
commit4d647f9a8623eb06dd4d8b0c4e7c40a459ffb2ad (patch)
tree2015677c21768fd0694a27c6f1e3ad09abd7ed7b
parent8c7dc19e3f3656d56de82952aed06c5ac8879d50 (diff)
downloadqtlocation-mapboxgl-4d647f9a8623eb06dd4d8b0c4e7c40a459ffb2ad.tar.gz
initial integration of harfbuzz
-rw-r--r--.gitignore2
-rwxr-xr-xconfigure1
-rw-r--r--mbgl.gypi2
-rw-r--r--platform/linux/scripts/configure.sh1
-rw-r--r--platform/osx/scripts/configure.sh1
-rw-r--r--src/mbgl/text/font_stack.cpp119
6 files changed, 126 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 218297e317..0f0b3a6439 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
*.gcda
*~
offline.db
+cache.sqlite
+out.png
/platform/node/test/actual
/platform/node/test/diff
/mason_packages
diff --git a/configure b/configure
index efcf63d01f..6f820774fc 100755
--- a/configure
+++ b/configure
@@ -110,6 +110,7 @@ print_flags gtest static_libs cflags ldflags
print_flags pixelmatch static_libs cflags ldflags
print_flags webp static_libs cflags ldflags
print_flags jni.hpp static_libs cflags ldflags
+print_flags harfbuzz static_libs cflags ldflags
CONFIG+=" }
}
diff --git a/mbgl.gypi b/mbgl.gypi
index 48eb15d938..72d1f318b5 100644
--- a/mbgl.gypi
+++ b/mbgl.gypi
@@ -172,6 +172,7 @@
'<@(geojsonvt_cflags)',
'<@(rapidjson_cflags)',
'<@(variant_cflags)',
+ '<@(harfbuzz_cflags)',
],
'cflags': [
'<@(opengl_cflags)',
@@ -183,6 +184,7 @@
],
'libraries': [
'<@(geojsonvt_static_libs)',
+ '<@(harfbuzz_static_libs)',
],
},
diff --git a/platform/linux/scripts/configure.sh b/platform/linux/scripts/configure.sh
index 410faaf442..37812ba611 100644
--- a/platform/linux/scripts/configure.sh
+++ b/platform/linux/scripts/configure.sh
@@ -16,6 +16,7 @@ RAPIDJSON_VERSION=1.0.2
GTEST_VERSION=1.7.0
PIXELMATCH_VERSION=0.9.0
WEBP_VERSION=0.5.0
+HARFBUZZ_VERSION=1.2.1
function print_opengl_flags {
CONFIG+=" 'opengl_cflags%': $(quote_flags $(pkg-config gl x11 --cflags)),"$LN
diff --git a/platform/osx/scripts/configure.sh b/platform/osx/scripts/configure.sh
index e2fa095df9..6e1585ce2e 100644
--- a/platform/osx/scripts/configure.sh
+++ b/platform/osx/scripts/configure.sh
@@ -11,3 +11,4 @@ VARIANT_VERSION=1.1.0
RAPIDJSON_VERSION=1.0.2
GTEST_VERSION=1.7.0
PIXELMATCH_VERSION=0.9.0
+HARFBUZZ_VERSION=1.2.1
diff --git a/src/mbgl/text/font_stack.cpp b/src/mbgl/text/font_stack.cpp
index 60e90a77e8..c45089a933 100644
--- a/src/mbgl/text/font_stack.cpp
+++ b/src/mbgl/text/font_stack.cpp
@@ -3,6 +3,11 @@
#include <mbgl/platform/log.hpp>
#include <mbgl/util/math.hpp>
+#include <harfbuzz/hb.h>
+// #include <harfbuzz/hb-ft.h>
+#include <iostream>
+#include <codecvt>
+
namespace mbgl {
void FontStack::insert(uint32_t id, const SDFGlyph &glyph) {
@@ -41,6 +46,120 @@ const Shaping FontStack::getShaping(const std::u32string &string, const float ma
float x = 0;
const float y = yOffset;
+ // TODO: pass string through harfbuzz
+ auto hb_buffer_deleter = [](hb_buffer_t * buffer) { hb_buffer_destroy(buffer);};
+ const std::unique_ptr<hb_buffer_t, decltype(hb_buffer_deleter)> buffer(hb_buffer_create(),hb_buffer_deleter);
+ hb_buffer_pre_allocate(buffer.get(), string.length());
+
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cv;
+ std::cout << cv.to_bytes(string) << std::endl;
+
+ /*
+ mapnik::value_unicode_string const& text = itemizer.text();
+
+ for (auto const& text_item : list)
+ {
+ face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset);
+ double size = text_item.format_->text_size * scale_factor;
+ face_set->set_unscaled_character_sizes();
+ std::size_t num_faces = face_set->size();
+ std::size_t pos = 0;
+ font_feature_settings const& ff_settings = text_item.format_->ff_settings;
+ int ff_count = safe_cast<int>(ff_settings.count());
+
+ // rendering information for a single glyph
+ struct glyph_face_info
+ {
+ face_ptr face;
+ hb_glyph_info_t glyph;
+ hb_glyph_position_t position;
+ };
+ // this table is filled with information for rendering each glyph, so that
+ // several font faces can be used in a single text_item
+ std::vector<glyph_face_info> glyphinfos;
+ unsigned valid_glyphs = 0;
+
+ for (auto const& face : *face_set)
+ {
+ ++pos;
+ hb_buffer_clear_contents(buffer.get());
+ hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, static_cast<int>(text_item.end - text_item.start));
+ hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
+ hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script));
+ hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr));
+ // https://github.com/mapnik/test-data-visual/pull/25
+ #if HB_VERSION_MAJOR > 0
+ #if HB_VERSION_ATLEAST(1, 0 , 5)
+ hb_ft_font_set_load_flags(font,FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
+ #endif
+ #endif
+ hb_shape(font, buffer.get(), ff_settings.get_features(), ff_count);
+ hb_font_destroy(font);
+
+ unsigned num_glyphs = hb_buffer_get_length(buffer.get());
+
+ // if the number of rendered glyphs has increased, we need to resize the table
+ if (num_glyphs > glyphinfos.size())
+ {
+ glyphinfos.resize(num_glyphs);
+ }
+
+ hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), nullptr);
+ hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), nullptr);
+
+ // Check if all glyphs are valid.
+ for (unsigned i=0; i<num_glyphs; ++i)
+ {
+ // if we have a valid codepoint, save rendering info.
+ if (glyphs[i].codepoint)
+ {
+ if (!glyphinfos[i].glyph.codepoint)
+ {
+ ++valid_glyphs;
+ }
+ glyphinfos[i] = { face, glyphs[i], positions[i] };
+ }
+ }
+ if (valid_glyphs < num_glyphs && (pos < num_faces))
+ {
+ //Try next font in fontset
+ continue;
+ }
+
+ double max_glyph_height = 0;
+ for (unsigned i=0; i<num_glyphs; ++i)
+ {
+ auto& gpos = positions[i];
+ auto& glyph = glyphs[i];
+ face_ptr theface = face;
+ if (glyphinfos[i].glyph.codepoint)
+ {
+ gpos = glyphinfos[i].position;
+ glyph = glyphinfos[i].glyph;
+ theface = glyphinfos[i].face;
+ }
+ unsigned char_index = glyph.cluster;
+ glyph_info g(glyph.codepoint,char_index,text_item.format_);
+ if (theface->glyph_dimensions(g))
+ {
+ g.face = theface;
+ g.scale_multiplier = size / theface->get_face()->units_per_EM;
+ //Overwrite default advance with better value provided by HarfBuzz
+ g.unscaled_advance = gpos.x_advance;
+ g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);
+ double tmp_height = g.height();
+ if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
+ width_map[char_index] += g.advance();
+ line.add_glyph(std::move(g), scale_factor);
+ }
+ }
+ line.update_max_char_height(max_glyph_height);
+ break; //When we reach this point the current font had all glyphs.
+ }
+ }
+ */
+
+
// Loop through all characters of this label and shape.
for (uint32_t chr : string) {
auto it = sdfs.find(chr);