613 {
614 const double kMinOKFraction = 0.99;
615
616
617 const double kMinWeightedFraction = 0.99995;
618
619 fonts->clear();
620 std::vector<std::vector<bool>> font_flags;
621 std::vector<int> font_scores;
622 std::vector<int> raw_scores;
623 int most_ok_chars = 0;
624 int best_raw_score = 0;
626 for (const auto &font_name : font_names) {
627 std::vector<bool> ch_flags;
628 int raw_score = 0;
629 int ok_chars =
FontScore(ch_map, font_name, &raw_score, &ch_flags);
630 most_ok_chars = std::max(ok_chars, most_ok_chars);
631 best_raw_score = std::max(raw_score, best_raw_score);
632
633 font_flags.push_back(ch_flags);
634 font_scores.push_back(ok_chars);
635 raw_scores.push_back(raw_score);
636 }
637
638
639
640
641
642
643
644
645
646 int least_good_enough = static_cast<int>(most_ok_chars * kMinOKFraction);
647 int least_raw_enough = static_cast<int>(best_raw_score * kMinOKFraction);
648 int override_enough = static_cast<int>(most_ok_chars * kMinWeightedFraction);
649
650 std::string font_list;
651 for (
unsigned i = 0;
i < font_names.size(); ++
i) {
652 int score = font_scores[
i];
653 int raw_score = raw_scores[
i];
654 if ((score >= least_good_enough && raw_score >= least_raw_enough) || score >= override_enough) {
655 fonts->push_back(std::make_pair(font_names[
i].c_str(), font_flags[
i]));
656 tlog(1,
"OK font %s = %.4f%%, raw = %d = %.2f%%\n", font_names[
i].c_str(),
657 100.0 * score / most_ok_chars, raw_score, 100.0 * raw_score / best_raw_score);
658 font_list += font_names[
i];
659 font_list += "\n";
660 } else if (score >= least_good_enough || raw_score >= least_raw_enough) {
661 tlog(1,
"Runner-up font %s = %.4f%%, raw = %d = %.2f%%\n", font_names[
i].c_str(),
662 100.0 * score / most_ok_chars, raw_score, 100.0 * raw_score / best_raw_score);
663 }
664 }
665 return font_list;
666}
static int FontScore(const std::unordered_map< char32, int64_t > &ch_map, const std::string &fontname, int *raw_score, std::vector< bool > *ch_flags)
static const std::vector< std::string > & ListAvailableFonts()