Repository: LadybirdBrowser/ladybird
File: Libraries/LibGfx/Font/Typeface.cpp (C++)

Code before:
Typeface::Typeface() = default;

Typeface::~Typeface()
{
    if (m_harfbuzz_face)
        hb_face_destroy(m_harfbuzz_face);
    if (m_harfbuzz_blob)
        hb_blob_destroy(m_harfbuzz_blob);
}

NonnullRefPtr<Font> Typeface::font(float point_size, FontVariationSettings const& variations) const
{
    FontCacheKey key { point_size, variations.to_sorted_list() };

    if (auto it = m_fonts.find(key); it != m_fonts.end())
        return *it->value;

    // FIXME: It might be nice to have a global cap on the number of fonts we cache
    //        instead of doing it at the per-Typeface level like this.
    constexpr size_t max_cached_font_size_count = 128;
    if (m_fonts.size() > max_cached_font_size_count)
        m_fonts.remove(m_fonts.begin());

    RefPtr<Typeface> used_typeface = const_cast<Typeface*>(this);
    if (!variations.is_empty()) {
        if (auto const* skia_typeface = dynamic_cast<TypefaceSkia const*>(this))
            if (auto derived = skia_typeface->clone_with_variations(variations.to_sorted_list()))
                used_typeface = move(derived);
    }

    auto font = adopt_ref(*new Font(*used_typeface, point_size, point_size));
    m_fonts.set(key, font);
    return font;
}

hb_face_t* Typeface::harfbuzz_typeface() const
{
    if (!m_harfbuzz_blob)
        m_harfbuzz_blob = hb_blob_create(reinterpret_cast<char const*>(buffer().data()), buffer().size(), HB_MEMORY_MODE_READONLY, nullptr, [](void*) { });
    if (!m_harfbuzz_face)
        m_harfbuzz_face = hb_face_create(m_harfbuzz_blob, ttc_index());
    return m_harfbuzz_face;
}

}


Review comment (suggestion):
it should be possible to use `as_if` instead of `dynamic_cast`.

Code after:
Typeface::Typeface() = default;

Typeface::~Typeface()
{
    if (m_harfbuzz_face)
        hb_face_destroy(m_harfbuzz_face);
    if (m_harfbuzz_blob)
        hb_blob_destroy(m_harfbuzz_blob);
}

NonnullRefPtr<Font> Typeface::font(float point_size, FontVariationSettings const& variations) const
{
    FontCacheKey key { point_size, variations.to_sorted_list() };

    if (auto it = m_fonts.find(key); it != m_fonts.end())
        return *it->value;

    // FIXME: It might be nice to have a global cap on the number of fonts we cache
    //        instead of doing it at the per-Typeface level like this.
    constexpr size_t max_cached_font_size_count = 128;
    if (m_fonts.size() > max_cached_font_size_count)
        m_fonts.remove(m_fonts.begin());

    RefPtr<Typeface const> used_typeface = const_cast<Typeface*>(this);
    if (!variations.is_empty()) {
        if (auto const* skia_typeface = as_if<TypefaceSkia const>(this))
            if (auto derived = skia_typeface->clone_with_variations(variations.to_sorted_list()))
                used_typeface = move(derived);
    }

    auto font = adopt_ref(*new Font(*used_typeface, point_size, point_size, DEFAULT_DPI, DEFAULT_DPI, variations));
    m_fonts.set(key, font);
    return font;
}

hb_face_t* Typeface::harfbuzz_typeface() const
{
    if (!m_harfbuzz_blob)
        m_harfbuzz_blob = hb_blob_create(reinterpret_cast<char const*>(buffer().data()), buffer().size(), HB_MEMORY_MODE_READONLY, nullptr, [](void*) { });
    if (!m_harfbuzz_face)
        m_harfbuzz_face = hb_face_create(m_harfbuzz_blob, ttc_index());
    return m_harfbuzz_face;
}

}