#include "chrome/common/read_anything/read_anything_util.h"
#include <algorithm>
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/fixed_flat_map.h"
#include "base/containers/fixed_flat_set.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
namespace {
constexpr double kMinScale = 0.5;
constexpr double kMaxScale = 4.5;
constexpr double kScaleStepSize = 0.25;
int AsSteps(double font_scale) {
return base::ClampRound((font_scale - kMinScale) / kScaleStepSize);
}
}
std::vector<std::string> GetSupportedFonts(std::string_view language_code) {
static constexpr auto kPoppinsLangs =
base::MakeFixedFlatSet<std::string_view>(
{"af", "ca", "cs", "da", "de", "en", "es", "et", "fi", "fil",
"fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "mr", "ms",
"nl", "pl", "pt", "ro", "sk", "sl", "sv", "sw", "tr"});
static constexpr auto kComicNeueLangs =
base::MakeFixedFlatSet<std::string_view>(
{"af", "ca", "cs", "da", "de", "en", "es", "et",
"fi", "fil", "fr", "hr", "hu", "id", "it", "ms",
"nl", "pl", "pt", "sk", "sl", "sv", "sw"});
static constexpr auto kLexendDecaLangs =
base::MakeFixedFlatSet<std::string_view>(
{"af", "ca", "cs", "da", "de", "en", "es", "et", "fi", "fil",
"fr", "hr", "hu", "id", "it", "lt", "lv", "ms", "nl", "pl",
"pt", "ro", "sk", "sl", "sv", "sw", "tr", "vi"});
static constexpr auto kEbGaramondLangs =
base::MakeFixedFlatSet<std::string_view>(
{"af", "bg", "ca", "cs", "da", "de", "en", "es", "et", "fi", "fil",
"fr", "hr", "hu", "id", "it", "lt", "lv", "ms", "nl", "pl", "pt",
"ro", "ru", "sk", "sl", "sr", "sv", "sw", "tr", "uk", "vi"});
static constexpr auto kStixTwoTextLangs =
base::MakeFixedFlatSet<std::string_view>(
{"af", "bg", "ca", "cs", "da", "de", "en", "es", "et", "fi", "fil",
"fr", "hr", "hu", "id", "it", "lt", "lv", "ms", "nl", "pl", "pt",
"ro", "ru", "sk", "sl", "sr", "sv", "sw", "tr", "uk", "vi"});
static constexpr auto kAndikaLangs = base::MakeFixedFlatSet<std::string_view>(
{"af", "bg", "ca", "cs", "da", "de", "en", "es", "et",
"fi", "fil", "fr", "hr", "hu", "id", "it", "kr", "lt",
"lu", "lv", "ms", "nd", "nl", "nr", "pl", "pt", "ro",
"ru", "sk", "sl", "sr", "sv", "sw", "tr", "uk", "vi"});
static constexpr auto kAtkinsonHyperlegibleNextLangs =
base::MakeFixedFlatSet<std::string_view>(
{"aa", "aat", "abq", "af", "ami", "an", "are", "ast", "aud", "ay",
"ba", "bi", "bik", "br", "bs", "cak", "cbk", "ceb", "ch", "cic",
"cim", "co", "con", "crh", "crs", "cs", "csb", "cy", "da", "de",
"del", "dhu", "en", "es", "et", "eu", "fi", "fil", "fj", "fo",
"fol", "fr", "fur", "fy", "ga", "gag", "gcf", "gd", "gil", "gl",
"gni", "gsw", "guc", "gv", "gwi", "haa", "hil", "hop", "hr", "ht",
"hu", "ia", "id", "ie", "igl", "ilo", "io", "is", "it", "jam",
"jbo", "jer", "jv", "kaa", "krl", "kea", "kek", "kg", "kj", "la",
"lb", "lij", "lld", "lmo", "lt", "lua", "luo", "moh", "moe", "mrq",
"ms", "mt", "mus", "mwf", "mwp", "nag", "nap", "nd", "nds", "ngy",
"nl", "no", "nov", "oc", "om", "os", "pam", "pap", "pau", "pl",
"pms", "pot", "pt", "qu", "rar", "rm", "rn", "ro", "roo", "rup",
"ruo", "ruq", "rw", "sc", "scn", "se", "sei", "sg", "shw", "sl",
"slv", "sm", "sn", "so", "sq", "sr", "srm", "srn", "ss", "st",
"su", "sv", "sw", "szl", "tet", "tkl", "tl", "tlh", "tn", "tpi",
"tr", "ts", "ttm", "tum", "tzo", "ulk", "uz", "vec", "vep", "vmw",
"vo", "vro", "wa", "war", "wbp", "wen", "wim", "win", "wir", "xh",
"yap", "yij", "zap", "zu", "zun"});
std::vector<std::string> font_choices = {"Sans-serif", "Serif"};
if (language_code.empty() || kPoppinsLangs.contains(language_code)) {
font_choices.insert(font_choices.begin(), "Poppins");
}
if (language_code.empty() || kComicNeueLangs.contains(language_code)) {
font_choices.push_back("Comic Neue");
}
if (language_code.empty() || kLexendDecaLangs.contains(language_code)) {
font_choices.push_back("Lexend Deca");
}
if (language_code.empty() || kEbGaramondLangs.contains(language_code)) {
font_choices.push_back("EB Garamond");
}
if (language_code.empty() || kStixTwoTextLangs.contains(language_code)) {
font_choices.push_back("STIX Two Text");
}
if (language_code.empty() || kAndikaLangs.contains(language_code)) {
font_choices.push_back("Andika");
}
if (language_code.empty() ||
kAtkinsonHyperlegibleNextLangs.contains(language_code)) {
font_choices.push_back("Atkinson Hyperlegible Next");
}
return font_choices;
}
void LogFontName(std::string_view font_name) {
enum class ReadAnythingFont {
kPoppins = 0,
kSansSerif = 1,
kSerif = 2,
kComicNeue = 3,
kLexendDeca = 4,
kEbGaramond = 5,
kStixTwoText = 6,
kAndika = 7,
kAtkinsonHyperlegibleNext = 8,
kMaxValue = kAtkinsonHyperlegibleNext,
};
static constexpr auto kFontMap =
base::MakeFixedFlatMap<std::string_view, ReadAnythingFont>(
{{"Poppins", ReadAnythingFont::kPoppins},
{"Sans-serif", ReadAnythingFont::kSansSerif},
{"Serif", ReadAnythingFont::kSerif},
{"Comic Neue", ReadAnythingFont::kComicNeue},
{"Lexend Deca", ReadAnythingFont::kLexendDeca},
{"EB Garamond", ReadAnythingFont::kEbGaramond},
{"STIX Two Text", ReadAnythingFont::kStixTwoText},
{"Andika", ReadAnythingFont::kAndika},
{"Atkinson Hyperlegible Next",
ReadAnythingFont::kAtkinsonHyperlegibleNext}});
if (const auto it = kFontMap.find(font_name); it != kFontMap.end()) {
base::UmaHistogramEnumeration("Accessibility.ReadAnything.FontName",
it->second);
}
}
double AdjustFontScale(double font_scale, int increment) {
return std::clamp(
kMinScale + (AsSteps(font_scale) + increment) * kScaleStepSize, kMinScale,
kMaxScale);
}
void LogFontScale(double font_scale) {
base::UmaHistogramExactLinear("Accessibility.ReadAnything.FontScale",
AsSteps(font_scale), AsSteps(kMaxScale) + 1);
}