diff --git a/include/flatui/font_buffer.h b/include/flatui/font_buffer.h index 6fb7c9e..9b1f460 100644 --- a/include/flatui/font_buffer.h +++ b/include/flatui/font_buffer.h @@ -595,11 +595,11 @@ struct FontVertex { /// @param[in] u A float representing the `u` value in the UV mapping. /// @param[in] v A float representing the `v` value in the UV mapping. FontVertex(float x, float y, float z, float u, float v) { - position_.data[0] = x; - position_.data[1] = y; - position_.data[2] = z; - uv_.data[0] = u; - uv_.data[1] = v; + position_.data_[0] = x; + position_.data_[1] = y; + position_.data_[2] = z; + uv_.data_[0] = u; + uv_.data_[1] = v; } /// @cond FONT_MANAGER_INTERNAL diff --git a/include/flatui/internal/hb_complex_font.h b/include/flatui/internal/hb_complex_font.h index 609a4bb..9792263 100644 --- a/include/flatui/internal/hb_complex_font.h +++ b/include/flatui/internal/hb_complex_font.h @@ -94,8 +94,7 @@ class FaceData { /// @param[in] offset An offset of the file contents to map. /// @param[in/out] size A size to map. A size of 0 indicates to map /// whole file. returns a mapped size of the file. - const void* OpenFontByName(const char *font_name, - int32_t offset, + const void *OpenFontByName(const char *font_name, int32_t offset, int32_t *size); /// @brief Open specified font by name and return the raw data. @@ -128,6 +127,15 @@ class FaceData { int32_t Release() { return --ref_count_; } private: + /// @brief Creates the harfbuzz font from the ft font. If it fails the + /// FaceData is Closed. + /// + /// @return true if the hb font is successfully created. + bool CreateHbFont(); + + /// @brief Destroys the harfbuzz font. + void DestroyHbFont(); + /// @var face_ /// /// @brief freetype's fontface instance. @@ -303,8 +311,11 @@ class HbFont { class HbComplexFont : public HbFont { public: HbComplexFont() - : complex_font_id_(kNullHash), current_face_index_(0), pixel_size_(0) {} - virtual ~HbComplexFont() {}; + : complex_font_id_(kNullHash), + current_face_index_(0), + pixel_size_(0), + prefer_long_run_(false) {} + virtual ~HbComplexFont(){}; /// @brief Create an instance of HbFont. If a HbFont with same FaceData has /// already been initialized, the API returns a pointer of the @@ -407,8 +418,14 @@ class HbComplexFont : public HbFont { /// @var pixel_size_ /// - /// @brief Pixel sizse of the complex font. + /// @brief Pixel size of the complex font. uint32_t pixel_size_; + + /// @var prefer_long_run_ + /// + /// @brief A flag to indicate prefering longer font face run rather than + /// switching font faces. + bool prefer_long_run_; }; } // namespace flatui diff --git a/sample/animation/flatuianim.cpp b/sample/animation/flatuianim.cpp index 1510bb6..e52ca29 100644 --- a/sample/animation/flatuianim.cpp +++ b/sample/animation/flatuianim.cpp @@ -18,9 +18,7 @@ #include "fplbase/input.h" #include "fplbase/renderer.h" #include "fplbase/utilities.h" - #include "motive/engine.h" -#include "motive/init.h" using flatui::kAlignCenter; using flatui::AnimCurveDescription; diff --git a/sample/corgui/corgui.cpp b/sample/corgui/corgui.cpp index 5be4779..4df2053 100644 --- a/sample/corgui/corgui.cpp +++ b/sample/corgui/corgui.cpp @@ -21,7 +21,6 @@ #include "fplbase/renderer.h" #include "fplbase/utilities.h" #include "motive/engine.h" -#include "motive/init.h" using flatui::AnimCurveDescription; using flatui::kAnimEaseInEaseOut; diff --git a/sample/sample_3d/flatuisample_3d.cpp b/sample/sample_3d/flatuisample_3d.cpp index 319319c..56bc3d2 100644 --- a/sample/sample_3d/flatuisample_3d.cpp +++ b/sample/sample_3d/flatuisample_3d.cpp @@ -14,9 +14,10 @@ // Demo showing off how to use FlatUI in 3D, for use in e.g. VR. -#include "fplbase/renderer.h" -#include "fplbase/render_target.h" #include "fplbase/input.h" +#include "fplbase/render_target.h" +#include "fplbase/render_utils.h" +#include "fplbase/renderer.h" #include "fplbase/utilities.h" #include "flatui/flatui.h" @@ -130,17 +131,16 @@ extern "C" int FPL_main(int /*argc*/, char **argv) { // Now place the UI in the space we computed before. renderer.set_model_view_projection(mvp); - tex_shader->Set(renderer); + renderer.SetShader(tex_shader); render_target.BindAsTexture(0); // Render UI as a quad, with object-space coordinates the same as pixels, // that way our projected coordinates match. - fplbase::Mesh::RenderAAQuadAlongX( - mathfu::kZeros3f, - mathfu::vec3(render_target_size.x, render_target_size.y, 0), - mathfu::vec2(0, 0), - mathfu::vec2(1, 1)); + fplbase::RenderAAQuadAlongX( + mathfu::kZeros3f, + mathfu::vec3(render_target_size.x, render_target_size.y, 0), + mathfu::vec2(0, 0), mathfu::vec2(1, 1)); } return 0; diff --git a/src/flatui.cpp b/src/flatui.cpp index a394f85..a15e732 100644 --- a/src/flatui.cpp +++ b/src/flatui.cpp @@ -621,9 +621,9 @@ class InternalState : public LayoutManager { .at(info.end_vertex_index_ * kVerticesPerGlyph + kVerticesPerGlyph - 1) .position_; - auto p = vec2i(start_pos.data[0] + pos.x, info.y_pos_.x + pos.y); + auto p = vec2i(start_pos.data_[0] + pos.x, info.y_pos_.x + pos.y); // NOTE: Use abs value for a size to account with RTL. - auto size = vec2i(std::abs(end_pos.data[0] - start_pos.data[0]), + auto size = vec2i(std::abs(end_pos.data_[0] - start_pos.data_[0]), info.y_pos_.y); RenderQuad(color_shader_, color, p, size); } diff --git a/src/font_buffer.cpp b/src/font_buffer.cpp index 24af26c..f3dbfbc 100644 --- a/src/font_buffer.cpp +++ b/src/font_buffer.cpp @@ -230,7 +230,7 @@ void FontBuffer::UpdateLine(const FontBufferParameters ¶meters, } auto it = vertices_.begin() + idx * kVerticesPerCodePoint; for (auto i = 0; i < kVerticesPerCodePoint; ++i) { - it->position_.data[0] += offset; + it->position_.data_[0] += offset; it++; } } @@ -272,7 +272,7 @@ float FontBuffer::AdjustCurrentLine(const FontBufferParameters ¶meters, ++idx) { auto it = vertices_.begin() + idx * kVerticesPerCodePoint; for (auto i = 0; i < kVerticesPerCodePoint; ++i) { - it->position_.data[1] += offset; + it->position_.data_[1] += offset; it++; } } @@ -287,7 +287,7 @@ static void VertexExtents(const FontVertex *v, vec2 *min_position, vec2 min(kInfinity); vec2 max(-kInfinity); for (auto i = 0; i < FontBuffer::kVerticesPerCodePoint; ++i) { - const vec2 position(v[i].position_.data); + const vec2 position(v[i].position_.data_); min = vec2::Min(min, position); max = vec2::Max(max, position); } diff --git a/src/font_manager.cpp b/src/font_manager.cpp index 5897675..1ba856b 100644 --- a/src/font_manager.cpp +++ b/src/font_manager.cpp @@ -118,13 +118,6 @@ class WordEnumerator { auto current_face_index = GetFaceIndex(index); while (index < buffer_->size()) { - auto word_info = (*buffer_)[index]; - if (word_info == LINEBREAK_MUSTBREAK || - word_info == LINEBREAK_ALLOWBREAK) { - current_length_ = index - current_index_ + 1; - break; - } - // Check if the font face needs to be switched. if (!face_index_buffer_->empty()) { auto i = GetFaceIndex(index); @@ -133,6 +126,13 @@ class WordEnumerator { break; } } + + auto word_info = (*buffer_)[index]; + if (word_info == LINEBREAK_MUSTBREAK || + word_info == LINEBREAK_ALLOWBREAK) { + current_length_ = index - current_index_ + 1; + break; + } index++; } return true; @@ -937,7 +937,7 @@ bool FontManager::NeedToRemoveEntries(const FontBufferParameters ¶meters, vert_index = entry_index * kVerticesPerGlyph + kVertexOfRightEdge; } - const auto x = vertices.at(vert_index).position_.data[0]; + const auto x = vertices.at(vert_index).position_.data_[0]; auto width = 0.f; // Width needs to be (more positive x value - less positive x value). if (layout_direction_ == kTextLayoutDirectionRTL) { @@ -1013,10 +1013,10 @@ void FontManager::RemoveEntries(const FontBufferParameters ¶meters, if (layout_direction_ == kTextLayoutDirectionRTL) { // Get the right edge of the glyph because that's closest to the // remaining glyphs in RTL. - pos->x = (buffer->vertices_.end() + kVertexOfRightEdge)->position_.data[0]; + pos->x = (buffer->vertices_.end() + kVertexOfRightEdge)->position_.data_[0]; } else { // In LTR the left edge is closest to the remaining glyphs. - pos->x = (buffer->vertices_.end() + kVertexOfLeftEdge)->position_.data[0]; + pos->x = (buffer->vertices_.end() + kVertexOfLeftEdge)->position_.data_[0]; } // Remove vertices. @@ -1032,10 +1032,10 @@ void FontManager::RemoveEntries(const FontBufferParameters ¶meters, if (layout_direction_ == kTextLayoutDirectionRTL) { // Get the left edge of the last glyph because that's farthest edge in // RTL. - last_x = (buffer->vertices_.end() + kVertexOfLeftEdge)->position_.data[0]; + last_x = (buffer->vertices_.end() + kVertexOfLeftEdge)->position_.data_[0]; } else { // In LTR the right edge is the farthest. - last_x = (buffer->vertices_.end() + kVertexOfRightEdge)->position_.data[0]; + last_x = (buffer->vertices_.end() + kVertexOfRightEdge)->position_.data_[0]; } pos->x = pos->x - (pos->x - last_x) * kSpacingBeforeEllipsis; } diff --git a/src/hb_complex_font.cpp b/src/hb_complex_font.cpp index 3f2a179..972ff4b 100644 --- a/src/hb_complex_font.cpp +++ b/src/hb_complex_font.cpp @@ -116,14 +116,14 @@ int32_t HbComplexFont::AnalyzeFontFaceRun(const char *text, size_t length, length, &i); // Current face has a priority since we want to have longer run for a font. if (current_face != static_cast(kIndexInvalid) && - FT_Get_Char_Index(faces_[current_face]->get_face(), unicode)) { + FT_Get_Char_Index(faces_[current_face]->get_face(), unicode) && + prefer_long_run_) { (*font_data_index)[text_idx] = current_face; } else { // Check if any font has the glyph. size_t face_idx = 0; for (face_idx = 0; face_idx < faces_.size(); ++face_idx) { - if (face_idx != current_face && - FT_Get_Char_Index(faces_[face_idx]->get_face(), unicode)) { + if (FT_Get_Char_Index(faces_[face_idx]->get_face(), unicode)) { (*font_data_index)[text_idx] = face_idx; if (face_idx != current_face) { run++; @@ -508,9 +508,7 @@ bool FaceData::Open(FT_Library ft, const FontFamily &family) { } // Create harfbuzz font information from the FreeType face. - harfbuzz_font_ = hb_ft_font_create(face_, NULL); - if (!harfbuzz_font_) { - Close(); + if (!CreateHbFont()) { return false; } @@ -527,10 +525,7 @@ void FaceData::Close() { } // Remove the font data associated to this face data. - if (harfbuzz_font_) { - hb_font_destroy(harfbuzz_font_); - harfbuzz_font_ = nullptr; - } + DestroyHbFont(); if (face_) { FT_Done_Face(face_); @@ -556,6 +551,27 @@ void FaceData::SetSize(uint32_t size) { available_size); } current_size_ = size; + + // Harfbuzz caches size information, so we need to recreate it. + DestroyHbFont(); + CreateHbFont(); +} + +bool FaceData::CreateHbFont() { + harfbuzz_font_ = hb_ft_font_create(face_, NULL); + if (!harfbuzz_font_) { + Close(); + return false; + } + + return true; +} + +void FaceData::DestroyHbFont() { + if (harfbuzz_font_) { + hb_font_destroy(harfbuzz_font_); + harfbuzz_font_ = nullptr; + } } } // namespace flatui