40 for (
unsigned r = 0; r < results.size(); ++r) {
41 const auto shape_id = results[r].shape_id;
56 for (
unsigned r = 0; r < results.size(); ++r) {
87 uint8_t sorted = unichars_sorted_;
97 unichars_sorted_ = sorted != 0;
104 for (
auto &unichar : unichars_) {
105 if (unichar.unichar_id == unichar_id) {
107 std::vector<int> &font_list = unichar.font_ids;
108 for (
int f : font_list) {
113 font_list.push_back(font_id);
118 unichars_.emplace_back(unichar_id, font_id);
119 unichars_sorted_ = unichars_.size() <= 1;
124 for (
const auto &unichar : other.unichars_) {
125 for (
unsigned f = 0; f < unichar.font_ids.size(); ++f) {
126 AddToShape(unichar.unichar_id, unichar.font_ids[f]);
129 unichars_sorted_ = unichars_.size() <= 1;
134 for (
const auto &unichar : unichars_) {
135 if (unichar.unichar_id == unichar_id) {
137 auto &font_list = unichar.font_ids;
138 for (
int f : font_list) {
151 for (
const auto &unichar : unichars_) {
152 if (unichar.unichar_id == unichar_id) {
161 for (
const auto &unichar : unichars_) {
162 auto &font_list = unichar.font_ids;
163 for (
int f : font_list) {
174 for (
const auto &unichar : unichars_) {
175 auto &font_list = unichar.font_ids;
176 for (
int f : font_list) {
187 uint32_t properties = font_table.
at(unichars_[0].font_ids[0]).
properties;
188 for (
const auto &unichar : unichars_) {
189 auto &font_list = unichar.font_ids;
190 for (
int f : font_list) {
207 for (
const auto &unichar : unichars_) {
208 int unichar_id = unichar.unichar_id;
209 const std::vector<int> &font_list = unichar.font_ids;
210 for (
int f : font_list) {
223 if (unichars_.size() != other->unichars_.size()) {
226 if (!unichars_sorted_) {
229 if (!other->unichars_sorted_) {
230 other->SortUnichars();
232 for (
unsigned c = 0; c < unichars_.size(); ++c) {
233 if (unichars_[c].unichar_id != other->unichars_[c].unichar_id) {
241void Shape::SortUnichars() {
243 unichars_sorted_ =
true;
266 if (num_fonts_ <= 0) {
267 for (
auto shape_id : shape_table_) {
268 const Shape &shape = *shape_id;
269 for (
int c = 0; c < shape.
size(); ++c) {
270 for (
int font_id : shape[c].font_ids) {
271 if (font_id >= num_fonts_) {
272 num_fonts_ = font_id + 1;
284 for (
auto shape : shape_table_) {
285 for (
int c = 0; c < shape->size(); ++c) {
286 shape->SetUnicharId(c, unicharset_map[(*shape)[c].unichar_id]);
293 if (shape_id >= shape_table_.size()) {
294 return "INVALID_UNICHAR_ID";
298 result +=
"Shape" + std::to_string(shape_id);
299 if (shape.
size() > 100) {
300 result +=
" Num unichars=" + std::to_string(shape.
size());
303 for (
int c = 0; c < shape.
size(); ++c) {
304 result +=
" c_id=" + std::to_string(shape[c].unichar_id);
307 if (shape.
size() < 10) {
308 result +=
", " + std::to_string(shape[c].font_ids.
size());
309 result +=
" fonts =";
310 int num_fonts = shape[c].font_ids.
size();
311 if (num_fonts > 10) {
312 result +=
" " + std::to_string(shape[c].font_ids[0]);
313 result +=
" ... " + std::to_string(shape[c].font_ids[num_fonts - 1]);
315 for (
int f = 0; f < num_fonts; ++f) {
316 result +=
" " + std::to_string(shape[c].font_ids[f]);
326 int max_unichars = 0;
327 int num_multi_shapes = 0;
328 int num_master_shapes = 0;
329 for (
unsigned s = 0; s < shape_table_.size(); ++s) {
335 if (shape_size > 1) {
338 if (shape_size > max_unichars) {
339 max_unichars = shape_size;
343 result +=
"Number of shapes = " + std::to_string(num_master_shapes);
344 result +=
" max unichars = " + std::to_string(max_unichars);
345 result +=
" number with multiple unichars = " + std::to_string(num_multi_shapes);
352 auto index = shape_table_.size();
353 auto *shape =
new Shape;
355 shape_table_.push_back(shape);
356 num_fonts_ = std::max(num_fonts_, font_id + 1);
364 for (index = 0; index < shape_table_.size() && !(other == *shape_table_[index]); ++index) {
367 if (index == shape_table_.size()) {
368 auto *shape =
new Shape(other);
369 shape_table_.push_back(shape);
377 delete shape_table_[shape_id];
378 shape_table_.erase(shape_table_.begin() + shape_id);
384 Shape &shape = *shape_table_[shape_id];
386 num_fonts_ = std::max(num_fonts_, font_id + 1);
391 Shape &shape = *shape_table_[shape_id];
401 for (
unsigned s = 0; s < shape_table_.size(); ++s) {
403 for (
int c = 0; c < shape.
size(); ++c) {
404 if (shape[c].unichar_id == unichar_id) {
408 for (
int f : shape[c].font_ids) {
421 const UnicharAndFonts &unichar_and_fonts = (*shape_table_[shape_id])[0];
423 *font_id = unichar_and_fonts.
font_ids[0];
430 for (
int u_ind = 0; u_ind < shape.
size(); ++u_ind) {
431 for (
unsigned f_ind = 0; f_ind < shape[u_ind].font_ids.
size(); ++f_ind) {
432 int c = shape[u_ind].unichar_id;
433 int f = shape[u_ind].font_ids[f_ind];
434 int master_id = master_shapes.
FindShape(c, f);
435 if (master_id >= 0) {
436 shape_map.
SetBit(master_id);
443 for (
unsigned s = 0; s < master_shapes.
NumShapes(); ++s) {
460 for (
unsigned s1 = 0; s1 < num_shapes; ++s1) {
473 int max_num_unichars = 0;
475 for (
int s = 0; s < num_shapes; ++s) {
476 if (
GetShape(s).size() > max_num_unichars) {
480 return max_num_unichars;
486 for (
unsigned s1 = start; s1 < end; ++s1) {
488 int unichar_id =
GetShape(s1)[0].unichar_id;
489 for (
auto s2 = s1 + 1; s2 < end; ++s2) {
491 unichar_id ==
GetShape(s2)[0].unichar_id) {
513 for (
int c = 0; c < shape.
size(); ++c) {
514 font_count += shape[c].font_ids.
size();
524 Shape combined_shape(*shape_table_[master_id1]);
525 combined_shape.
AddShape(*shape_table_[master_id2]);
526 return combined_shape.
size();
534 shape_table_[master_id2]->set_destination_index(master_id1);
536 shape_table_[master_id1]->AddShape(*shape_table_[master_id2]);
541 Shape *tmp = shape_table_[shape_id1];
542 shape_table_[shape_id1] = shape_table_[shape_id2];
543 shape_table_[shape_id2] = tmp;
549 auto dest_id = shape_table_[shape_id]->destination_index();
550 if (
static_cast<unsigned>(dest_id) == shape_id || dest_id < 0) {
553 auto master_id = shape_table_[dest_id]->destination_index();
554 if (master_id == dest_id || master_id < 0) {
566 for (c1 = 0; c1 < shape1.
size(); ++c1) {
567 int unichar_id1 = shape1[c1].unichar_id;
572 for (c2 = 0; c2 < shape2.
size(); ++c2) {
573 int unichar_id2 = shape2[c2].unichar_id;
578 return c1 == shape1.
size() || c2 == shape2.
size();
587 for (cs = 0; cs < shape.
size(); ++cs) {
588 int unichar_id = shape[cs].unichar_id;
593 for (cm1 = 0; cm1 < merge1.
size(); ++cm1) {
594 int unichar_id1 = merge1[cm1].unichar_id;
599 for (cm2 = 0; cm2 < merge2.
size(); ++cm2) {
600 int unichar_id2 = merge2[cm2].unichar_id;
605 return cs == shape.
size() || (cm1 == merge1.
size() && cm2 == merge2.
size());
612 for (
int c1 = 0; c1 < shape1.
size(); ++c1) {
613 int unichar_id1 = shape1[c1].unichar_id;
618 for (
int c2 = 0; c2 < shape2.
size(); ++c2) {
619 int unichar_id2 = shape2[c2].unichar_id;
632 for (
int cs = 0; cs < shape.
size(); ++cs) {
633 int unichar_id = shape[cs].unichar_id;
638 for (
int cm1 = 0; cm1 < merge1.
size(); ++cm1) {
639 int unichar_id1 = merge1[cm1].unichar_id;
644 for (
int cm2 = 0; cm2 < merge2.
size(); ++cm2) {
645 int unichar_id2 = merge2[cm2].unichar_id;
657 for (
int c1 = 0; c1 < shape1.
size(); ++c1) {
658 int unichar_id1 = shape1[c1].unichar_id;
670 for (
int c1 = 0; c1 < shape1.
size(); ++c1) {
671 const std::vector<int> &font_list1 = shape1[c1].font_ids;
672 for (
int f : font_list1) {
684 if (shape_map !=
nullptr) {
686 shape_map->resize(other.
NumShapes(), -1);
688 for (
unsigned s = 0; s < other.shape_table_.size(); ++s) {
689 if (other.shape_table_[s]->destination_index() < 0) {
690 int index =
AddShape(*other.shape_table_[s]);
691 if (shape_map !=
nullptr) {
692 (*shape_map)[s] = index;
701 for (
auto s : shape_table_) {
702 if (s->destination_index() < 0) {
717 std::vector<UnicharRating> *results)
const {
718 if (shape_rating.
joined) {
721 if (shape_rating.
broken) {
725 for (
int u = 0; u < shape.
size(); ++u) {
727 AddUnicharToResults(shape[u].unichar_id, shape_rating.
rating, unichar_map, results);
728 for (
int font_id : shape[u].font_ids) {
729 (*results)[result_index].fonts.emplace_back(font_id,
737int ShapeTable::AddUnicharToResults(
int unichar_id,
float rating, std::vector<int> *unichar_map,
738 std::vector<UnicharRating> *results)
const {
739 int result_index = unichar_map->at(unichar_id);
740 if (result_index < 0) {
742 result_index = results->size();
743 results->push_back(result);
744 (*unichar_map)[unichar_id] = result_index;
int IntCastRounded(double x)
bool Serialize(FILE *fp, const std::vector< T > &data)
bool DeSerialize(std::string &data)
const char * id_to_unichar(UNICHAR_ID id) const
static int FirstResultWithUnichar(const std::vector< UnicharRating > &results, UNICHAR_ID unichar_id)
static int FirstResultWithUnichar(const std::vector< ShapeRating > &results, const ShapeTable &shape_table, UNICHAR_ID unichar_id)
static bool StdSortByUnicharId(const UnicharAndFonts &v1, const UnicharAndFonts &v2)
std::vector< int32_t > font_ids
static int SortByUnicharId(const void *v1, const void *v2)
bool DeSerialize(TFile *fp)
bool Serialize(FILE *fp) const
bool IsSubsetOf(const Shape &other) const
bool ContainsMultipleFontProperties(const FontInfoTable &font_table) const
bool ContainsUnicharAndFont(int unichar_id, int font_id) const
bool ContainsFont(int font_id) const
void AddToShape(int unichar_id, int font_id)
bool Serialize(FILE *fp) const
void AddShape(const Shape &other)
bool IsEqualUnichars(Shape *other)
bool ContainsFontProperties(const FontInfoTable &font_table, uint32_t properties) const
bool DeSerialize(TFile *fp)
bool ContainsUnichar(int unichar_id) const
bool operator==(const Shape &other) const
void SwapShapes(unsigned shape_id1, unsigned shape_id2)
void AddToShape(unsigned shape_id, int unichar_id, int font_id)
bool AnyMultipleUnichars() const
bool DeSerialize(TFile *fp)
int MergedUnicharCount(unsigned shape_id1, unsigned shape_id2) const
bool MergeEqualUnichars(int merge_id1, int merge_id2, unsigned shape_id) const
void ReMapClassIds(const std::vector< int > &unicharset_map)
bool MergeSubsetUnichar(int merge_id1, int merge_id2, unsigned shape_id) const
std::string DebugStr(unsigned shape_id) const
unsigned AddShape(int unichar_id, int font_id)
int NumMasterShapes() const
std::string SummaryStr() const
unsigned MasterDestinationIndex(unsigned shape_id) const
bool Serialize(FILE *fp) const
int MasterFontCount(unsigned shape_id) const
unsigned NumShapes() const
void DeleteShape(unsigned shape_id)
bool AlreadyMerged(unsigned shape_id1, unsigned shape_id2) const
const Shape & GetShape(unsigned shape_id) const
void AddShapeToShape(unsigned shape_id, const Shape &other)
void AddShapeToResults(const ShapeRating &shape_rating, std::vector< int > *unichar_map, std::vector< UnicharRating > *results) const
int MaxNumUnichars() const
int BuildFromShape(const Shape &shape, const ShapeTable &master_shapes)
bool EqualUnichars(unsigned shape_id1, unsigned shape_id2) const
void MergeShapes(unsigned shape_id1, unsigned shape_id2)
unsigned MasterUnicharCount(unsigned shape_id) const
void GetFirstUnicharAndFont(unsigned shape_id, int *unichar_id, int *font_id) const
bool SubsetUnichar(unsigned shape_id1, unsigned shape_id2) const
bool CommonFont(unsigned shape_id1, unsigned shape_id2) const
void ForceFontMerges(unsigned start, unsigned end)
bool CommonUnichars(unsigned shape_id1, unsigned shape_id2) const
int FindShape(int unichar_id, int font_id) const
void AppendMasterShapes(const ShapeTable &other, std::vector< int > *shape_map)