Commit 1c0065a8 authored by Joel Hockey's avatar Joel Hockey Committed by Commit Bot

Render tofu using first candidate font rather than last resort

When all fonts have been exhausted and we must render tofu / notdef, we
use the first candidate font rather than the system or last resort font.

This helps in the case where a user has specified a monospace font such
as for the terminal system app. We want to use the uniform width tofu,
rather than the system or last resort font.

Renamed is_last_resort to is_last_font in HarfBuzzShaper to reduce
confusion since the final font used may not be the system last
resort font.

Some tests required updating since they are now rendering .notdef from
the preferred font rather than the last resort font. I have added
SansNotoTibetan-Regular.ttf font which is required in test
external/wpt/css/css-text/word-break/word-break-break-all-005.html.

Cq-Include-Trybots: luci.chromium.try:linux-blink-rel;luci.chromium.try:mac10.10-blink-rel;luci.chromium.try:mac10.11-blink-rel;luci.chromium.try:mac10.12-blink-rel;luci.chromium.try:mac10.13-blink-rel;luci.chromium.try:mac10.13_retina-blink-rel;luci.chromium.try:mac10.14-blink-rel;luci.chromium.try:mac10.15-blink-rel;luci.chromium.try:win7-blink-rel;luci.chromium.try:win10-blink-rel
Bug: 1090566
Change-Id: Ifca2800e6296adac3e40e3dae16008959b669337
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2227711Reviewed-by: default avatarRobert Ma <robertma@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarDominik Röttsches <drott@chromium.org>
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776171}
parent a777e611
......@@ -381,4 +381,5 @@ additional system fonts pulled in to the shaping process.
In summary, `FontFallbackIterator` feeds fonts from the CSS `font-family` list
as well as system fallback fonts to `HarfBuzzShaper` for use in the shaping
iterations until ideally all gaps are filled and the full text run can be drawn
with the correct glyphs.
with the correct glyphs. When there are gaps, and the .notdef tofu character
must be rendered, the primary font is used for this.
......@@ -56,6 +56,9 @@ void FontFallbackIterator::WillUseRange(const AtomicString& family,
scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
scoped_refptr<FontDataForRangeSet> candidate,
const Vector<UChar32>& hint_list) {
if (!candidate->HasFontData())
return Next(hint_list);
SkTypeface* candidate_typeface =
candidate->FontData()->PlatformData().Typeface();
if (!candidate_typeface)
......@@ -70,6 +73,11 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::UniqueOrNext(
// depends on the subsetting.
if (candidate->IsEntireRange())
unique_font_data_for_range_sets_returned_.insert(candidate_id);
// Save first candidate to be returned if all other fonts fail, and we need
// it to render the .notdef glyph.
if (!first_candidate_)
first_candidate_ = candidate;
return candidate;
}
......@@ -121,14 +129,19 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
// resort font that has glyphs for everything, for example the Unicode
// LastResort font, not just Times or Arial.
FontCache* font_cache = FontCache::GetFontCache();
fallback_stage_ = kOutOfLuck;
fallback_stage_ = kFirstCandidateForNotdefGlyph;
scoped_refptr<SimpleFontData> last_resort =
font_cache->GetLastResortFallbackFont(font_description_).get();
if (!last_resort)
return UniqueOrNext(
base::AdoptRef(new FontDataForRangeSetFromCache(last_resort)),
hint_list);
}
if (fallback_stage_ == kFirstCandidateForNotdefGlyph) {
fallback_stage_ = kOutOfLuck;
if (!first_candidate_)
FontCache::CrashWithFontInfo(&font_description_);
// Don't skip the LastResort font in uniqueOrNext() since HarfBuzzShaper
// needs to use this one to place missing glyph boxes.
return base::AdoptRef(new FontDataForRangeSetFromCache(last_resort));
return first_candidate_;
}
DCHECK(fallback_stage_ == kFontGroupFonts ||
......
......@@ -70,6 +70,7 @@ class FontFallbackIterator {
kSegmentedFace,
kPreferencesFonts,
kSystemFonts,
kFirstCandidateForNotdefGlyph,
kOutOfLuck
};
......@@ -77,10 +78,13 @@ class FontFallbackIterator {
HashSet<UChar32> previously_asked_for_hint_;
// FontFallbackIterator is meant for single use by HarfBuzzShaper,
// traversing through the fonts for shaping only once. We must not return
// duplicate FontDataForRangeSet objects from the next() iteration functions
// duplicate FontDataForRangeSet objects from the Next() iteration function
// as returning a duplicate value causes a shaping run that won't return any
// results.
// results. The exception is that if all fonts fail, we return the first
// candidate to be used for rendering the .notdef glyph, and set HasNext() to
// false.
HashSet<uint32_t> unique_font_data_for_range_sets_returned_;
scoped_refptr<FontDataForRangeSet> first_candidate_ = nullptr;
Vector<scoped_refptr<FontDataForRangeSet>> tracked_loading_range_sets_;
FontFallbackPriority font_fallback_priority_;
};
......
......@@ -319,7 +319,7 @@ void HarfBuzzShaper::CommitGlyphs(RangeData* range_data,
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical canvas_rotation,
bool is_last_resort,
bool is_last_font,
const BufferSlice& slice,
ShapeResult* shape_result) const {
hb_direction_t direction = range_data->HarfBuzzDirection(canvas_rotation);
......@@ -346,7 +346,7 @@ void HarfBuzzShaper::CommitGlyphs(RangeData* range_data,
current_slice->num_glyphs - num_glyphs_inserted};
current_slice = &next_slice;
}
if (is_last_resort)
if (is_last_font)
range_data->font->ReportNotDefGlyph();
}
......@@ -357,7 +357,7 @@ void HarfBuzzShaper::ExtractShapeResults(
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical canvas_rotation,
bool is_last_resort,
bool is_last_font,
ShapeResult* shape_result) const {
enum ClusterResult { kShaped, kNotDef, kUnknown };
ClusterResult current_cluster_result = kUnknown;
......@@ -397,7 +397,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// If the most recent cluster is shaped and there is a state change,
// it means the previous ones were unshaped, so we queue them, unless
// we're using the last resort font.
if (current_cluster_result == kShaped && !is_last_resort) {
if (current_cluster_result == kShaped && !is_last_font) {
QueueCharacters(range_data, current_font, font_cycle_queued, slice);
} else {
// If the most recent cluster is unshaped and there is a state
......@@ -405,7 +405,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// the glyphs. We also commit when we've reached the last resort
// font.
CommitGlyphs(range_data, current_font, current_run_script,
canvas_rotation, is_last_resort, slice, shape_result);
canvas_rotation, is_last_font, slice, shape_result);
}
last_change_glyph_index = previous_cluster_start_glyph_index;
}
......@@ -427,7 +427,7 @@ void HarfBuzzShaper::ExtractShapeResults(
// End of the run.
if (current_cluster_result != previous_cluster_result &&
previous_cluster_result != kUnknown && !is_last_resort) {
previous_cluster_result != kUnknown && !is_last_font) {
// The last cluster in the run still had shaping status different from
// the cluster(s) before it, we need to submit one shaped and one
// unshaped segment.
......@@ -440,13 +440,13 @@ void HarfBuzzShaper::ExtractShapeResults(
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
previous_cluster_start_glyph_index, num_glyphs);
CommitGlyphs(range_data, current_font, current_run_script,
canvas_rotation, is_last_resort, slice, shape_result);
canvas_rotation, is_last_font, slice, shape_result);
} else {
BufferSlice slice = ComputeSlice(
range_data, current_queue_item, glyph_info, num_glyphs,
last_change_glyph_index, previous_cluster_start_glyph_index);
CommitGlyphs(range_data, current_font, current_run_script,
canvas_rotation, is_last_resort, slice, shape_result);
canvas_rotation, is_last_font, slice, shape_result);
slice =
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
previous_cluster_start_glyph_index, num_glyphs);
......@@ -458,11 +458,11 @@ void HarfBuzzShaper::ExtractShapeResults(
BufferSlice slice =
ComputeSlice(range_data, current_queue_item, glyph_info, num_glyphs,
last_change_glyph_index, num_glyphs);
if (current_cluster_result == kNotDef && !is_last_resort) {
if (current_cluster_result == kNotDef && !is_last_font) {
QueueCharacters(range_data, current_font, font_cycle_queued, slice);
} else {
CommitGlyphs(range_data, current_font, current_run_script,
canvas_rotation, is_last_resort, slice, shape_result);
canvas_rotation, is_last_font, slice, shape_result);
}
}
}
......
......@@ -105,7 +105,7 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
const SimpleFontData*,
UScriptCode,
CanvasRotationInVertical,
bool is_last_resort,
bool is_last_font,
ShapeResult*) const;
bool CollectFallbackHintChars(const Deque<ReshapeQueueItem>&,
......@@ -116,7 +116,7 @@ class PLATFORM_EXPORT HarfBuzzShaper final {
const SimpleFontData* current_font,
UScriptCode current_run_script,
CanvasRotationInVertical,
bool is_last_resort,
bool is_last_font,
const BufferSlice&,
ShapeResult*) const;
......
......@@ -90,6 +90,7 @@ FONT_FILES = [
[[CONTENT_SHELL_FONTS_DIR], 'NotoSansCJKjp-Regular.otf', None],
[[CONTENT_SHELL_FONTS_DIR], 'NotoSansKhmer-Regular.ttf', None],
[[CONTENT_SHELL_FONTS_DIR], 'NotoSansSymbols2-Regular.ttf', None],
[[CONTENT_SHELL_FONTS_DIR], 'NotoSansTibetan-Regular.ttf', None],
[[CONTENT_SHELL_FONTS_DIR], 'Tinos-Bold.ttf', None],
[[CONTENT_SHELL_FONTS_DIR], 'Tinos-BoldItalic.ttf', None],
[[CONTENT_SHELL_FONTS_DIR], 'Tinos-Italic.ttf', None],
......
Verify that exposing devtools protocol yields a functional protocol.
Protocol responses: 2
Protocol events: 5
Protocol events: 6
Test passes if the fallback font selected for the Unicode Private Use Area test text is the priority font.
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_mono:
"Cousine" : 14
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_serif:
"Tinos" : 14
PASS
......@@ -6,19 +6,16 @@
<body>
<div class="test">
<!-- Private use area Ranges: U+E000..U+F8FF, U+F0000..U+FFFFF, U+100000..U+10FFFF -->
<div id="pua_test_run">&#xE000;&#xE401;&#xE402;&#xE403;&#xF8FF;&#xF0000;&#xFAAAA;&#xFFFFF;&#x100000;&#x10AAAA;&#x10FFFF;</div>
<div id="pua_test_mono" style="font-family: monospace;">abc&#xE000;&#xE401;&#xE402;&#xE403;&#xF8FF;&#xF0000;&#xFAAAA;&#xFFFFF;&#x100000;&#x10AAAA;&#x10FFFF;</div>
<div id="pua_test_serif" style="font-family: serif;">abc&#xE000;&#xE401;&#xE402;&#xE403;&#xF8FF;&#xF0000;&#xFAAAA;&#xFFFFF;&#x100000;&#x10AAAA;&#x10FFFF;</div>
</div>
</body>
</html>
`);
var session = await page.createSession();
testRunner.log(`Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.`);
testRunner.log(`Test passes if the fallback font selected for the Unicode Private Use Area test text is the priority font.`);
var helper = await testRunner.loadScript('./resources/layout-font-test.js');
var results = await helper(testRunner, session);
var pua_used_fonts = results.find(x => x.selector === '#pua_test_run').usedFonts;
var passed = pua_used_fonts.length === 1 && /^(Times New Roman|Times|DejaVu Sans|Arial)$/.test(pua_used_fonts[0].familyName) && pua_used_fonts[0].glyphCount == 11;
testRunner.log(passed ? 'PASS' : 'FAIL');
testRunner.completeTest();
})
Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.
󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_run:
"DejaVu Sans" : 11
PASS
Test passes if the fallback font selected for the Unicode Private Use Area test text is the priority font.
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_mono:
"Cousine" : 14
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_serif:
"Tinos" : 14
Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.
󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_run:
"DejaVu Sans" : 11
PASS
......@@ -16,7 +16,7 @@
ᨀᨁ
#bug:
"DejaVu Sans" : 2
"Tinos" : 2
ᐐᐑ
#cans:
......@@ -24,23 +24,23 @@
𐊠𐊡
#xcr:
"DejaVu Sans" : 2
"Tinos" : 2
ᎡᎢ
#chr:
"DejaVu Sans" : 2
"Tinos" : 2
ⲁⲂ
#copt:
"DejaVu Sans" : 2
"Tinos" : 2
𒀀𒀌
#akk:
"DejaVu Sans" : 2
"Tinos" : 2
𐠀𐠁
#ecy:
"DejaVu Sans" : 2
"Tinos" : 2
АБВ
#ru:
......@@ -48,7 +48,7 @@
𐐀𐐁
#en:
"DejaVu Sans" : 2
"Tinos" : 2
अआ
#hi:
......@@ -56,7 +56,7 @@
ሁሂ
#am:
"DejaVu Sans" : 2
"Tinos" : 2
ႠႡ
#ka:
......@@ -104,27 +104,27 @@
𐡁𐡂
#arc:
"DejaVu Sans" : 2
"Tinos" : 2
𐭡𐭢
#pal:
"DejaVu Sans" : 2
"Tinos" : 2
𐭁𐭂
#xpr:
"DejaVu Sans" : 2
"Tinos" : 2
ꦑꦒ
#jv:
"DejaVu Sans" : 2
"Tinos" : 2
ಡಢ
#kn:
"DejaVu Sans" : 2
"Tinos" : 2
𐨐𐨑
#sa:
"DejaVu Sans" : 2
"Tinos" : 2
໐໑
#lo:
......@@ -136,27 +136,27 @@
𐊁𐊂
#xlc:
"DejaVu Sans" : 2
"Tinos" : 2
𐤡𐤢
#xld:
"DejaVu Sans" : 2
"Tinos" : 2
ഡഢ
#ml:
"DejaVu Sans" : 2
"Tinos" : 2
𐦡𐦢
#script_meroitic:
"DejaVu Sans" : 2
"Tinos" : 2
ကခ
#my:
"DejaVu Sans" : 2
"Tinos" : 2
ᦁᦂ
#script_new_tai_lue:
"DejaVu Sans" : 2
"Tinos" : 2
߁߂
#nko:
......@@ -168,7 +168,7 @@
᱑᱒
#script_ol_chiki:
"DejaVu Sans" : 2
"Tinos" : 2
𐌁𐌂
#script_old_italic:
......@@ -176,43 +176,43 @@
𐎡𐎢
#peo:
"DejaVu Sans" : 2
"Tinos" : 2
𐩡𐩢
#script_old_south_arabian:
"DejaVu Sans" : 2
"Tinos" : 2
ଡଢ
#or:
"DejaVu Sans" : 2
"Tinos" : 2
ꡁꡂ
#script_phags_pa:
"DejaVu Sans" : 2
"Tinos" : 2
ᚠᚡ
#script_runic:
"DejaVu Sans" : 2
"Tinos" : 2
𐑑𐑒
#script_shavian:
"DejaVu Sans" : 2
"Tinos" : 2
එඒ
#si:
"DejaVu Sans" : 2
"Tinos" : 2
𑃑𑃒
#script_sora_sompeng:
"DejaVu Sans" : 2
"Tinos" : 2
ܑܒ
#syr:
"DejaVu Sans" : 2
"Tinos" : 2
ᥑᥒ
#script_tai_le:
"DejaVu Sans" : 2
"Tinos" : 2
றல
#ta:
......@@ -220,11 +220,11 @@
డఢ
#te:
"DejaVu Sans" : 2
"Tinos" : 2
ށނ
#script_thaana:
"DejaVu Sans" : 2
"Tinos" : 2
กข
#th:
......@@ -232,7 +232,7 @@
༁༂
#bo:
"DejaVu Sans" : 2
"Noto Sans Tibetan" : 2
ⴱⴲ
#script_tifinagh:
......@@ -240,10 +240,10 @@
ꔁꔂ
#vai:
"DejaVu Sans" : 2
"Tinos" : 2
ꀀꀁ
#yi:
"DejaVu Sans" : 2
"Tinos" : 2
......@@ -30,7 +30,7 @@
𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏
#egyptian_hieroglyphs:
"DejaVu Sans" : 16
"Tinos" : 16
ខ្ញុំអាចញុំកញ្ចក់បាន ដោយគ្មានបញ្ហារ
#khmer:
......@@ -39,15 +39,16 @@
𐌲𐌿𐍄𐌹𐍃𐌺
#gothic:
"DejaVu Sans" : 6
"Tinos" : 6
ܐܬܘܪܝܐ
#syriac:
"DejaVu Sans" : 6
"Tinos" : 6
⇦⇧⇨⇩←↑→↓⟀
#text_presentation_arrows_maths:
"DejaVu Sans" : 5,
"Noto Sans CJK JP Regular" : 4
"Noto Sans CJK JP Regular" : 4,
"DejaVu Sans" : 4,
"Tinos" : 1
Verify that exposing devtools protocol yields a functional protocol.
Protocol responses: 2
Protocol events: 5
Verify that exposing devtools protocol yields a functional protocol.
Protocol responses: 2
Protocol events: 6
Test passes if the fallback font selected for the Unicode Private Use Area test text is the priority font.
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_mono:
"Courier" : 14
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_serif:
"Times" : 14
Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.
󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_run:
"Times" : 11
PASS
Test passes if the fallback font selected for the Unicode Private Use Area test text is the priority font.
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_mono:
"Courier New" : 14
abc󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_serif:
"Times New Roman" : 14
Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.
󰀀󺪪󿿿􀀀􊪪􏿿
#pua_test_run:
"Arial" : 11
PASS
Test passes if a maxmium of the two first glyphs are notdef's (for Myanmar fonts that do not combine a left quote with a Myanmar spacing mark and the rest of the run is shaped, given a system Myanmar font is available.
‘ေရွးျမန္မာမင္းေတြလက္ထက္က
#myanmar:
"Arial" : 25
"Times New Roman" : 25
FAIL
......@@ -16,7 +16,7 @@
ᨀᨁ
#bug:
"Arial" : 2
"Times New Roman" : 2
ᐐᐑ
#cans:
......@@ -24,23 +24,23 @@
𐊠𐊡
#xcr:
"Arial" : 2
"Times New Roman" : 2
ᎡᎢ
#chr:
"Arial" : 2
"Times New Roman" : 2
ⲁⲂ
#copt:
"Arial" : 2
"Times New Roman" : 2
𒀀𒀌
#akk:
"Arial" : 2
"Times New Roman" : 2
𐠀𐠁
#ecy:
"Arial" : 2
"Times New Roman" : 2
АБВ
#ru:
......@@ -48,7 +48,7 @@
𐐀𐐁
#en:
"Arial" : 2
"Times New Roman" : 2
अआ
#hi:
......@@ -60,7 +60,7 @@
ႠႡ
#ka:
"Arial" : 2
"Times New Roman" : 2
ΑΒ
#el:
......@@ -104,19 +104,19 @@
𐡁𐡂
#arc:
"Arial" : 2
"Times New Roman" : 2
𐭡𐭢
#pal:
"Arial" : 2
"Times New Roman" : 2
𐭁𐭂
#xpr:
"Arial" : 2
"Times New Roman" : 2
ꦑꦒ
#jv:
"Arial" : 2
"Times New Roman" : 2
ಡಢ
#kn:
......@@ -124,7 +124,7 @@
𐨐𐨑
#sa:
"Arial" : 2
"Times New Roman" : 2
໐໑
#lo:
......@@ -132,15 +132,15 @@
ꓐꓑ
#lis:
"Arial" : 2
"Times New Roman" : 2
𐊁𐊂
#xlc:
"Arial" : 2
"Times New Roman" : 2
𐤡𐤢
#xld:
"Arial" : 2
"Times New Roman" : 2
ഡഢ
#ml:
......@@ -148,11 +148,11 @@
𐦡𐦢
#script_meroitic:
"Arial" : 2
"Times New Roman" : 2
ကခ
#my:
"Arial" : 2
"Times New Roman" : 2
ᦁᦂ
#script_new_tai_lue:
......@@ -168,19 +168,19 @@
᱑᱒
#script_ol_chiki:
"Arial" : 2
"Times New Roman" : 2
𐌁𐌂
#script_old_italic:
"Arial" : 2
"Times New Roman" : 2
𐎡𐎢
#peo:
"Arial" : 2
"Times New Roman" : 2
𐩡𐩢
#script_old_south_arabian:
"Arial" : 2
"Times New Roman" : 2
ଡଢ
#or:
......@@ -196,7 +196,7 @@
𐑑𐑒
#script_shavian:
"Arial" : 2
"Times New Roman" : 2
එඒ
#si:
......@@ -204,7 +204,7 @@
𑃑𑃒
#script_sora_sompeng:
"Arial" : 2
"Times New Roman" : 2
ܑܒ
#syr:
......
......@@ -25,12 +25,11 @@
🌱🌲🌳🌴🌵🌷🌸🌹🌺🌻🌼💐🌾🌿🍀🍁🍂🍃🍄🌰☺️😀👪
#emoji:
"Segoe UI Symbol" : 19,
"Arial" : 3,
"Times New Roman" : 2
"Times New Roman" : 5
𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏
#egyptian_hieroglyphs:
"Arial" : 16
"Times New Roman" : 16
ខ្ញុំអាចញុំកញ្ចក់បាន ដោយគ្មានបញ្ហារ
#khmer:
......@@ -49,6 +48,6 @@
#text_presentation_arrows_maths:
"MS PGothic" : 4,
"Cambria Math" : 4,
"Arial" : 1
"Times New Roman" : 1
......@@ -31,6 +31,7 @@ copy("test_fonts") {
"test_fonts/NotoSansCJKjp-Regular.otf",
"test_fonts/NotoSansKhmer-Regular.ttf",
"test_fonts/NotoSansSymbols2-Regular.ttf",
"test_fonts/NotoSansTibetan-Regular.ttf",
"test_fonts/Tinos-Bold.ttf",
"test_fonts/Tinos-BoldItalic.ttf",
"test_fonts/Tinos-Italic.ttf",
......
......@@ -36,32 +36,33 @@ https://chromium.googlesource.com/infra/infra/+/master/doc/users/contacting_troo
Font Origins:
Ahem.ttf https://web-platform-tests.org/writing-tests/ahem.html
Arimo-Bold.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-Italic.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-Regular.ttf https://github.com/google/fonts/tree/master/apache/arimo
Cousine-Bold.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-Italic.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-Regular.ttf https://github.com/google/fonts/tree/master/apache/cousine
DejaVuSans.ttf https://dejavu-fonts.github.io/Download.html
GardinerModBug.ttf See README_GardinerMod.txt
GardinerModCat.ttf See README_GardinerMod.txt
Garuda.ttf https://linux.thai.net/projects/fonts-tlwg
Gelasio-Bold.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-BoldItalic.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-Italic.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-Regular.ttf https://fontlibrary.org/en/font/gelasio
Lohit-Devanagari.ttf https://pagure.io/lohit
Lohit-Gurmukhi.ttf https://pagure.io/lohit
Lohit-Tamil.ttf https://pagure.io/lohit
MuktiNarrow.ttf http://www.nongnu.org/freebangfont/downloads.html#mukti
NotoColorEmoji.ttf https://github.com/googlefonts/noto-emoji
NotoSansCJKjp-Regular.otf https://www.google.com/get/noto/#sans-jpan
NotoSansKhmer-Regular.ttf https://www.google.com/get/noto/#sans-khmr
NotoSansSymbols2-Regular.ttf https://github.com/googlefonts/noto-fonts/tree/master/hinted/NotoSansSymbols2
Tinos-Bold.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-Italic.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-Regular.ttf https://github.com/google/fonts/tree/master/apache/tinos
Ahem.ttf https://web-platform-tests.org/writing-tests/ahem.html
Arimo-Bold.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-Italic.ttf https://github.com/google/fonts/tree/master/apache/arimo
Arimo-Regular.ttf https://github.com/google/fonts/tree/master/apache/arimo
Cousine-Bold.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-Italic.ttf https://github.com/google/fonts/tree/master/apache/cousine
Cousine-Regular.ttf https://github.com/google/fonts/tree/master/apache/cousine
DejaVuSans.ttf https://dejavu-fonts.github.io/Download.html
GardinerModBug.ttf See README_GardinerMod.txt
GardinerModCat.ttf See README_GardinerMod.txt
Garuda.ttf https://linux.thai.net/projects/fonts-tlwg
Gelasio-Bold.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-BoldItalic.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-Italic.ttf https://fontlibrary.org/en/font/gelasio
Gelasio-Regular.ttf https://fontlibrary.org/en/font/gelasio
Lohit-Devanagari.ttf https://pagure.io/lohit
Lohit-Gurmukhi.ttf https://pagure.io/lohit
Lohit-Tamil.ttf https://pagure.io/lohit
MuktiNarrow.ttf http://www.nongnu.org/freebangfont/downloads.html#mukti
NotoColorEmoji.ttf https://github.com/googlefonts/noto-emoji
NotoSansCJKjp-Regular.otf https://www.google.com/get/noto/#sans-jpan
NotoSansKhmer-Regular.ttf https://www.google.com/get/noto/#sans-khmr
NotoSansSymbols2-Regular.ttf https://github.com/googlefonts/noto-fonts/tree/master/hinted/NotoSansSymbols2
NotoSansTibetan-Regular.ttf https://github.com/googlefonts/noto-fonts/tree/master/hinted/NotoSansTibetan
Tinos-Bold.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-BoldItalic.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-Italic.ttf https://github.com/google/fonts/tree/master/apache/tinos
Tinos-Regular.ttf https://github.com/google/fonts/tree/master/apache/tinos
d60a406cd5d35c4f01ead05a43ae8c6d7de9b39e
\ No newline at end of file
cd96fc55dc243f6c6f4cb63ad117cad6cd48dceb
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment