2022-09-08 13:44:17 +03:00
/*
2023-07-29 11:54:33 +03:00
* Copyright ( c ) 2022 - 2023 , Andreas Kling < kling @ serenityos . org >
2023-01-11 23:34:59 +03:00
* Copyright ( c ) 2023 , Linus Groh < linusg @ serenityos . org >
2022-09-08 13:44:17 +03:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2023-08-02 21:01:17 +03:00
# include "FontPlugin.h"
2022-12-04 21:43:54 +03:00
# include <AK/DeprecatedString.h>
2023-01-11 23:34:59 +03:00
# include <AK/String.h>
# include <LibCore/StandardPaths.h>
2023-03-01 16:44:34 +03:00
# include <LibGfx/Font/Emoji.h>
2022-09-08 13:44:17 +03:00
# include <LibGfx/Font/FontDatabase.h>
2022-12-04 21:43:54 +03:00
extern DeprecatedString s_serenity_resource_root ;
2022-09-08 13:44:17 +03:00
namespace Ladybird {
2023-08-02 21:01:17 +03:00
FontPlugin : : FontPlugin ( bool is_layout_test_mode )
2023-05-06 13:46:14 +03:00
: m_is_layout_test_mode ( is_layout_test_mode )
2022-09-08 13:44:17 +03:00
{
// Load the default SerenityOS fonts...
2022-12-04 21:43:54 +03:00
Gfx : : FontDatabase : : set_default_fonts_lookup_path ( DeprecatedString : : formatted ( " {}/res/fonts " , s_serenity_resource_root ) ) ;
2022-09-08 13:44:17 +03:00
2023-01-11 23:34:59 +03:00
// ...and also anything we can find in the system's font directories
for ( auto const & path : Core : : StandardPaths : : font_directories ( ) . release_value_but_fixme_should_propagate_errors ( ) )
Gfx : : FontDatabase : : the ( ) . load_all_fonts_from_path ( path . to_deprecated_string ( ) ) ;
2022-09-08 13:44:17 +03:00
Gfx : : FontDatabase : : set_default_font_query ( " Katica 10 400 0 " ) ;
Gfx : : FontDatabase : : set_fixed_width_font_query ( " Csilla 10 400 0 " ) ;
2023-03-01 16:44:34 +03:00
Gfx : : Emoji : : set_emoji_lookup_path ( String : : formatted ( " {}/res/emoji " , s_serenity_resource_root ) . release_value_but_fixme_should_propagate_errors ( ) ) ;
2022-09-08 13:44:17 +03:00
update_generic_fonts ( ) ;
2022-09-17 22:25:15 +03:00
auto default_font_name = generic_font_name ( Web : : Platform : : GenericFont : : UiSansSerif ) ;
2023-09-05 21:19:33 +03:00
m_default_font = Gfx : : FontDatabase : : the ( ) . get ( MUST ( String : : from_deprecated_string ( default_font_name ) ) , 12.0 , 400 , Gfx : : FontWidth : : Normal , 0 ) ;
2022-09-17 22:25:15 +03:00
VERIFY ( m_default_font ) ;
2022-09-18 03:11:48 +03:00
auto default_fixed_width_font_name = generic_font_name ( Web : : Platform : : GenericFont : : UiMonospace ) ;
2023-09-05 21:19:33 +03:00
m_default_fixed_width_font = Gfx : : FontDatabase : : the ( ) . get ( MUST ( String : : from_deprecated_string ( default_fixed_width_font_name ) ) , 12.0 , 400 , Gfx : : FontWidth : : Normal , 0 ) ;
2022-09-18 03:11:48 +03:00
VERIFY ( m_default_fixed_width_font ) ;
2022-09-08 13:44:17 +03:00
}
2023-08-02 21:01:17 +03:00
FontPlugin : : ~ FontPlugin ( ) = default ;
2022-09-08 13:44:17 +03:00
2023-08-02 21:01:17 +03:00
Gfx : : Font & FontPlugin : : default_font ( )
2022-09-17 22:25:15 +03:00
{
return * m_default_font ;
}
2023-08-02 21:01:17 +03:00
Gfx : : Font & FontPlugin : : default_fixed_width_font ( )
2022-09-17 22:25:15 +03:00
{
return * m_default_fixed_width_font ;
}
2023-08-02 21:01:17 +03:00
void FontPlugin : : update_generic_fonts ( )
2022-09-08 13:44:17 +03:00
{
// How we choose which system font to use for each CSS font:
2023-07-29 11:54:33 +03:00
// 1. Try a list of known-suitable fonts with their names hard-coded below.
// 2. If that didn't work, fall back to Gfx::FontDatabase::default_font() (or default_fixed_width_font())
2022-09-08 13:44:17 +03:00
2023-07-29 11:54:33 +03:00
// This is rather weird, but it's how things work right now.
// We should eventually have a way to query the system for the default font.
// Furthermore, we should allow overriding via some kind of configuration mechanism.
2022-09-08 13:44:17 +03:00
m_generic_font_names . resize ( static_cast < size_t > ( Web : : Platform : : GenericFont : : __Count ) ) ;
2023-07-29 11:54:33 +03:00
auto update_mapping = [ & ] ( Web : : Platform : : GenericFont generic_font , ReadonlySpan < DeprecatedString > fallbacks ) {
2023-05-06 13:46:14 +03:00
if ( m_is_layout_test_mode ) {
m_generic_font_names [ static_cast < size_t > ( generic_font ) ] = " SerenitySans " ;
return ;
}
2023-07-29 11:54:33 +03:00
RefPtr < Gfx : : Font const > gfx_font ;
2023-04-26 15:17:40 +03:00
2023-07-29 11:54:33 +03:00
for ( auto & fallback : fallbacks ) {
2023-09-05 21:19:33 +03:00
gfx_font = Gfx : : FontDatabase : : the ( ) . get ( MUST ( String : : from_deprecated_string ( fallback ) ) , 16 , 400 , Gfx : : FontWidth : : Normal , 0 , Gfx : : Font : : AllowInexactSizeMatch : : Yes ) ;
2023-07-29 11:54:33 +03:00
if ( gfx_font )
break ;
2022-09-08 13:44:17 +03:00
}
if ( ! gfx_font ) {
if ( generic_font = = Web : : Platform : : GenericFont : : Monospace | | generic_font = = Web : : Platform : : GenericFont : : UiMonospace )
gfx_font = Gfx : : FontDatabase : : default_fixed_width_font ( ) ;
else
gfx_font = Gfx : : FontDatabase : : default_font ( ) ;
}
2023-09-05 16:32:52 +03:00
m_generic_font_names [ static_cast < size_t > ( generic_font ) ] = gfx_font - > family ( ) . to_deprecated_string ( ) ;
2022-09-08 13:44:17 +03:00
} ;
2023-08-01 02:52:36 +03:00
// Fallback fonts to look for if Gfx::Font can't load expected font
2022-09-08 13:44:17 +03:00
// The lists are basically arbitrary, taken from https://www.w3.org/Style/Examples/007/fonts.en.html
2022-12-04 21:43:54 +03:00
Vector < DeprecatedString > cursive_fallbacks { " Comic Sans MS " , " Comic Sans " , " Apple Chancery " , " Bradley Hand " , " Brush Script MT " , " Snell Roundhand " , " URW Chancery L " } ;
Vector < DeprecatedString > fantasy_fallbacks { " Impact " , " Luminari " , " Chalkduster " , " Jazz LET " , " Blippo " , " Stencil Std " , " Marker Felt " , " Trattatello " } ;
Vector < DeprecatedString > monospace_fallbacks { " Andale Mono " , " Courier New " , " Courier " , " FreeMono " , " OCR A Std " , " DejaVu Sans Mono " , " Liberation Mono " , " Csilla " } ;
Vector < DeprecatedString > sans_serif_fallbacks { " Arial " , " Helvetica " , " Verdana " , " Trebuchet MS " , " Gill Sans " , " Noto Sans " , " Avantgarde " , " Optima " , " Arial Narrow " , " Liberation Sans " , " Katica " } ;
Vector < DeprecatedString > serif_fallbacks { " Times " , " Times New Roman " , " Didot " , " Georgia " , " Palatino " , " Bookman " , " New Century Schoolbook " , " American Typewriter " , " Liberation Serif " , " Roman " } ;
2022-09-08 13:44:17 +03:00
2023-07-29 11:54:33 +03:00
update_mapping ( Web : : Platform : : GenericFont : : Cursive , cursive_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : Fantasy , fantasy_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : Monospace , monospace_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : SansSerif , sans_serif_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : Serif , serif_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : UiMonospace , monospace_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : UiRounded , sans_serif_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : UiSansSerif , sans_serif_fallbacks ) ;
update_mapping ( Web : : Platform : : GenericFont : : UiSerif , serif_fallbacks ) ;
2022-09-08 13:44:17 +03:00
}
2023-08-02 21:01:17 +03:00
DeprecatedString FontPlugin : : generic_font_name ( Web : : Platform : : GenericFont generic_font )
2022-09-08 13:44:17 +03:00
{
return m_generic_font_names [ static_cast < size_t > ( generic_font ) ] ;
}
}