ladybird/Libraries/LibGfx/Font/FontDatabase.h
Tim Ledbetter 57103da08d LibGfx+LibWeb: Make emoji font fallback presentation-aware
Previously, font selection ignored the Unicode emoji presentation of a
code point. Emoji-capable code points were always resolved through
pre-baked color emoji and symbol fonts. Text-default code points which
lacked the `Emoji_Presentation` property, were therefore rendered as
color emoji rather than text. We now classify each code point's default
presentation from its `Emoji_Presentation` property and any trailing
variation selector.
2026-06-20 23:51:46 +02:00

78 lines
2.5 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/FlyString.h>
#include <AK/Function.h>
#include <AK/HashFunctions.h>
#include <AK/OwnPtr.h>
#include <AK/RefPtr.h>
#include <LibGfx/Font/Typeface.h>
#include <LibGfx/Forward.h>
namespace Gfx {
struct CodePointFallbackKey {
u32 code_point { 0 };
u16 weight { 0 };
u16 width { 0 };
u8 slope { 0 };
bool prefer_color_emoji { false };
bool operator==(CodePointFallbackKey const&) const = default;
unsigned hash() const
{
return pair_int_hash(
pair_int_hash(code_point, weight),
pair_int_hash(pair_int_hash(width, slope), prefer_color_emoji));
}
};
class SystemFontProvider {
public:
virtual ~SystemFontProvider();
virtual StringView name() const = 0;
virtual RefPtr<Gfx::Font> get_font(FlyString const& family, float point_size, unsigned weight, unsigned width, unsigned slope, Optional<FontVariationSettings> const& font_variation_settings = {}, Optional<Gfx::ShapeFeatures> const& shape_features = {}) = 0;
virtual void for_each_typeface_with_family_name(FlyString const& family_name, Function<void(Typeface const&)>) = 0;
};
class FontDatabase {
public:
static FontDatabase& the();
SystemFontProvider& install_system_font_provider(NonnullOwnPtr<SystemFontProvider>);
RefPtr<Gfx::Font> get(FlyString const& family, float point_size, unsigned weight, unsigned width, unsigned slope, Optional<FontVariationSettings> const& font_variation_settings = {}, Optional<Gfx::ShapeFeatures> const& shape_features = {});
RefPtr<Gfx::Font> get_font_for_code_point(u32 code_point, float point_size, u16 weight, u16 width, u8 slope, bool prefer_color_emoji);
void for_each_typeface_with_family_name(FlyString const& family_name, Function<void(Typeface const&)>);
[[nodiscard]] StringView system_font_provider_name() const;
static ErrorOr<Vector<String>> font_directories();
private:
FontDatabase();
~FontDatabase() = default;
OwnPtr<SystemFontProvider> m_system_font_provider;
struct CodePointFallbackEntry {
FlyString family_name;
RefPtr<Typeface const> typeface;
};
HashMap<CodePointFallbackKey, CodePointFallbackEntry> m_code_point_fallback_cache;
};
}
template<>
struct AK::Traits<Gfx::CodePointFallbackKey> : public AK::DefaultTraits<Gfx::CodePointFallbackKey> {
static unsigned hash(Gfx::CodePointFallbackKey const& key)
{
return key.hash();
}
};