std::shared_ptr<alfons::Font> FontContext::getFont(const std::string& _family, const std::string& _style, const std::string& _weight, float _size) { // Pick the smallest font that does not scale down too much float fontSize = s_fontRasterSizes.back(); size_t sizeIndex = s_fontRasterSizes.size() - 1; auto fontSizeItr = std::lower_bound(s_fontRasterSizes.begin(), s_fontRasterSizes.end(), _size); if (fontSizeItr != s_fontRasterSizes.end()) { fontSize = *fontSizeItr; sizeIndex = fontSizeItr - s_fontRasterSizes.begin(); } std::lock_guard<std::mutex> lock(m_fontMutex); auto font = m_alfons.getFont(FontDescription::Alias(_family, _style, _weight), fontSize); if (font->hasFaces()) { return font; } // First, try to load from the system fonts. bool useFallbackFont = false; auto systemFontHandle = m_platform->systemFont(_family, _weight, _style); alfons::InputSource source; switch (systemFontHandle.tag) { case FontSourceHandle::FontPath: source = alfons::InputSource(systemFontHandle.fontPath.path()); break; case FontSourceHandle::FontName: source = alfons::InputSource(systemFontHandle.fontName, true); break; case FontSourceHandle::FontLoader: { auto& loader = systemFontHandle.fontLoader; auto fontData = loader(); if (fontData.size() > 0) { source = alfons::InputSource(loader); } else { useFallbackFont = true; } break; } case FontSourceHandle::None: default: useFallbackFont = true; } if (!useFallbackFont) { font->addFace(m_alfons.addFontFace(source, fontSize)); if (m_font[sizeIndex]) { font->addFaces(*m_font[sizeIndex]); } } else { LOGD("Loading fallback font for Family: %s, Style: %s, Weight: %s, Size %f", _family.c_str(), _style.c_str(), _weight.c_str(), _size); // Add fallbacks from default font. if (m_font[sizeIndex]) { font->addFaces(*m_font[sizeIndex]); } } return font; }
TYPED_TEST (TestQuadMesh, NineQuads) { typedef typename TestFixture::Mesh Mesh; const int int_max = std::numeric_limits <int>::max (); // Order // - - - // // | 0 | 1 | 2 | // // - - - // // | 3 | 4 | 5 | // // - - - // // | 6 | 7 | 8 | // // - - - // // Add the configuration in different orders. Some of them create non-manifold states. std::vector <std::vector <int> > order_vec; std::vector <int> non_manifold; // When is the first non-manifold quad added? std::vector <int> order_tmp; // Configuration 0 order_tmp.push_back (0); order_tmp.push_back (1); order_tmp.push_back (2); order_tmp.push_back (3); order_tmp.push_back (5); order_tmp.push_back (4); order_tmp.push_back (7); order_tmp.push_back (6); order_tmp.push_back (8); order_vec.push_back (order_tmp); non_manifold.push_back (int_max); order_tmp.clear (); // Configuration 1 order_tmp.push_back (0); order_tmp.push_back (1); order_tmp.push_back (6); order_tmp.push_back (8); order_tmp.push_back (2); order_tmp.push_back (3); order_tmp.push_back (7); order_tmp.push_back (5); order_tmp.push_back (4); order_vec.push_back (order_tmp); non_manifold.push_back (int_max); order_tmp.clear (); // Configuration 2 order_tmp.push_back (0); order_tmp.push_back (1); order_tmp.push_back (6); order_tmp.push_back (8); order_tmp.push_back (5); order_tmp.push_back (2); order_tmp.push_back (3); order_tmp.push_back (7); order_tmp.push_back (4); order_vec.push_back (order_tmp); non_manifold.push_back (4); order_tmp.clear (); // Configuration 3 order_tmp.push_back (1); order_tmp.push_back (3); order_tmp.push_back (5); order_tmp.push_back (7); order_tmp.push_back (4); order_tmp.push_back (0); order_tmp.push_back (2); order_tmp.push_back (6); order_tmp.push_back (8); order_vec.push_back (order_tmp); non_manifold.push_back (1); order_tmp.clear (); // Configuration 4 order_tmp.push_back (1); order_tmp.push_back (3); order_tmp.push_back (5); order_tmp.push_back (7); order_tmp.push_back (0); order_tmp.push_back (2); order_tmp.push_back (6); order_tmp.push_back (8); order_tmp.push_back (4); order_vec.push_back (order_tmp); non_manifold.push_back (1); order_tmp.clear (); // Configuration 5 order_tmp.push_back (0); order_tmp.push_back (4); order_tmp.push_back (8); order_tmp.push_back (2); order_tmp.push_back (6); order_tmp.push_back (1); order_tmp.push_back (7); order_tmp.push_back (5); order_tmp.push_back (3); order_vec.push_back (order_tmp); non_manifold.push_back (1); order_tmp.clear (); // 00 - 01 - 02 - 03 // // | | | | // // 04 - 05 - 06 - 07 // // | | | | // // 08 - 09 - 10 - 11 // // | | | | // // 12 - 13 - 14 - 15 // typedef VertexIndex VI; std::vector <VertexIndices> faces; VertexIndices vi; vi.push_back (VI ( 0)); vi.push_back (VI ( 4)); vi.push_back (VI ( 5)); vi.push_back (VI ( 1)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 1)); vi.push_back (VI ( 5)); vi.push_back (VI ( 6)); vi.push_back (VI ( 2)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 2)); vi.push_back (VI ( 6)); vi.push_back (VI ( 7)); vi.push_back (VI ( 3)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 4)); vi.push_back (VI ( 8)); vi.push_back (VI ( 9)); vi.push_back (VI ( 5)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 5)); vi.push_back (VI ( 9)); vi.push_back (VI (10)); vi.push_back (VI ( 6)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 6)); vi.push_back (VI (10)); vi.push_back (VI (11)); vi.push_back (VI ( 7)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 8)); vi.push_back (VI (12)); vi.push_back (VI (13)); vi.push_back (VI ( 9)); faces.push_back (vi); vi.clear (); vi.push_back (VI ( 9)); vi.push_back (VI (13)); vi.push_back (VI (14)); vi.push_back (VI (10)); faces.push_back (vi); vi.clear (); vi.push_back (VI (10)); vi.push_back (VI (14)); vi.push_back (VI (15)); vi.push_back (VI (11)); faces.push_back (vi); vi.clear (); ASSERT_EQ (order_vec.size (), non_manifold.size ()); ASSERT_EQ (9, faces.size ()); for (unsigned int i=0; i<order_vec.size (); ++i) { std::stringstream ss; ss << "Configuration " << i; SCOPED_TRACE (ss.str ()); const std::vector <int> order = order_vec [i]; EXPECT_EQ (9, order.size ()); // No assert so the other cases can run as well if (9 != order.size ()) continue; Mesh mesh; for (unsigned int j=0; j<16; ++j) mesh.addVertex (j); std::vector <VertexIndices> ordered_faces; for (unsigned int j=0; j<faces.size (); ++j) { ordered_faces.push_back (faces [order [j]]); } bool check_has_faces = true; for (unsigned int j=0; j<faces.size (); ++j) { const FaceIndex index = mesh.addFace (ordered_faces [j]); if (j < static_cast<unsigned int> (non_manifold [i]) || !Mesh::IsManifold::value) { EXPECT_TRUE (index.isValid ()); } else { EXPECT_FALSE (index.isValid ()); check_has_faces = false; break; } } if (check_has_faces) { EXPECT_TRUE (hasFaces (mesh, ordered_faces)); } } }