Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/ccstruct/fontinfo.cpp @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /////////////////////////////////////////////////////////////////////// | |
| 2 // File: fontinfo.cpp | |
| 3 // Description: Font information classes abstracted from intproto.h/cpp. | |
| 4 // Author: rays@google.com (Ray Smith) | |
| 5 // | |
| 6 // (C) Copyright 2011, Google Inc. | |
| 7 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 8 // you may not use this file except in compliance with the License. | |
| 9 // You may obtain a copy of the License at | |
| 10 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 // Unless required by applicable law or agreed to in writing, software | |
| 12 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 // See the License for the specific language governing permissions and | |
| 15 // limitations under the License. | |
| 16 // | |
| 17 /////////////////////////////////////////////////////////////////////// | |
| 18 | |
| 19 #include "fontinfo.h" | |
| 20 #include "bitvector.h" | |
| 21 #include "unicity_table.h" | |
| 22 | |
| 23 namespace tesseract { | |
| 24 | |
| 25 // Writes to the given file. Returns false in case of error. | |
| 26 bool FontInfo::Serialize(FILE *fp) const { | |
| 27 if (!write_info(fp, *this)) { | |
| 28 return false; | |
| 29 } | |
| 30 if (!write_spacing_info(fp, *this)) { | |
| 31 return false; | |
| 32 } | |
| 33 return true; | |
| 34 } | |
| 35 // Reads from the given file. Returns false in case of error. | |
| 36 // If swap is true, assumes a big/little-endian swap is needed. | |
| 37 bool FontInfo::DeSerialize(TFile *fp) { | |
| 38 if (!read_info(fp, this)) { | |
| 39 return false; | |
| 40 } | |
| 41 if (!read_spacing_info(fp, this)) { | |
| 42 return false; | |
| 43 } | |
| 44 return true; | |
| 45 } | |
| 46 | |
| 47 FontInfoTable::FontInfoTable() { | |
| 48 using namespace std::placeholders; // for _1, _2 | |
| 49 set_clear_callback(std::bind(FontInfoDeleteCallback, _1)); | |
| 50 } | |
| 51 | |
| 52 FontInfoTable::~FontInfoTable() = default; | |
| 53 | |
| 54 // Writes to the given file. Returns false in case of error. | |
| 55 bool FontInfoTable::Serialize(FILE *fp) const { | |
| 56 return this->SerializeClasses(fp); | |
| 57 } | |
| 58 // Reads from the given file. Returns false in case of error. | |
| 59 // If swap is true, assumes a big/little-endian swap is needed. | |
| 60 bool FontInfoTable::DeSerialize(TFile *fp) { | |
| 61 truncate(0); | |
| 62 return this->DeSerializeClasses(fp); | |
| 63 } | |
| 64 | |
| 65 // Returns true if the given set of fonts includes one with the same | |
| 66 // properties as font_id. | |
| 67 bool FontInfoTable::SetContainsFontProperties(int font_id, | |
| 68 const std::vector<ScoredFont> &font_set) const { | |
| 69 uint32_t properties = at(font_id).properties; | |
| 70 for (auto &&f : font_set) { | |
| 71 if (at(f.fontinfo_id).properties == properties) { | |
| 72 return true; | |
| 73 } | |
| 74 } | |
| 75 return false; | |
| 76 } | |
| 77 | |
| 78 // Returns true if the given set of fonts includes multiple properties. | |
| 79 bool FontInfoTable::SetContainsMultipleFontProperties( | |
| 80 const std::vector<ScoredFont> &font_set) const { | |
| 81 if (font_set.empty()) { | |
| 82 return false; | |
| 83 } | |
| 84 int first_font = font_set[0].fontinfo_id; | |
| 85 uint32_t properties = at(first_font).properties; | |
| 86 for (unsigned f = 1; f < font_set.size(); ++f) { | |
| 87 if (at(font_set[f].fontinfo_id).properties != properties) { | |
| 88 return true; | |
| 89 } | |
| 90 } | |
| 91 return false; | |
| 92 } | |
| 93 | |
| 94 // Moves any non-empty FontSpacingInfo entries from other to this. | |
| 95 void FontInfoTable::MoveSpacingInfoFrom(FontInfoTable *other) { | |
| 96 using namespace std::placeholders; // for _1, _2 | |
| 97 set_clear_callback(std::bind(FontInfoDeleteCallback, _1)); | |
| 98 for (unsigned i = 0; i < other->size(); ++i) { | |
| 99 std::vector<FontSpacingInfo *> *spacing_vec = other->at(i).spacing_vec; | |
| 100 if (spacing_vec != nullptr) { | |
| 101 int target_index = get_index(other->at(i)); | |
| 102 if (target_index < 0) { | |
| 103 // Bit copy the FontInfo and steal all the pointers. | |
| 104 push_back(other->at(i)); | |
| 105 other->at(i).name = nullptr; | |
| 106 } else { | |
| 107 delete at(target_index).spacing_vec; | |
| 108 at(target_index).spacing_vec = other->at(i).spacing_vec; | |
| 109 } | |
| 110 other->at(i).spacing_vec = nullptr; | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 // Moves this to the target unicity table. | |
| 116 void FontInfoTable::MoveTo(UnicityTable<FontInfo> *target) { | |
| 117 target->clear(); | |
| 118 using namespace std::placeholders; // for _1, _2 | |
| 119 target->set_clear_callback(std::bind(FontInfoDeleteCallback, _1)); | |
| 120 for (unsigned i = 0; i < size(); ++i) { | |
| 121 // Bit copy the FontInfo and steal all the pointers. | |
| 122 target->push_back(at(i)); | |
| 123 at(i).name = nullptr; | |
| 124 at(i).spacing_vec = nullptr; | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 // Callbacks for GenericVector. | |
| 129 void FontInfoDeleteCallback(FontInfo f) { | |
| 130 if (f.spacing_vec != nullptr) { | |
| 131 for (auto data : *f.spacing_vec) { | |
| 132 delete data; | |
| 133 } | |
| 134 delete f.spacing_vec; | |
| 135 f.spacing_vec = nullptr; | |
| 136 } | |
| 137 delete[] f.name; | |
| 138 f.name = nullptr; | |
| 139 } | |
| 140 | |
| 141 /*---------------------------------------------------------------------------*/ | |
| 142 // Callbacks used by UnicityTable to read/write FontInfo/FontSet structures. | |
| 143 bool read_info(TFile *f, FontInfo *fi) { | |
| 144 uint32_t size; | |
| 145 if (!f->DeSerialize(&size)) { | |
| 146 return false; | |
| 147 } | |
| 148 char *font_name = new char[size + 1]; | |
| 149 fi->name = font_name; | |
| 150 if (!f->DeSerialize(font_name, size)) { | |
| 151 return false; | |
| 152 } | |
| 153 font_name[size] = '\0'; | |
| 154 return f->DeSerialize(&fi->properties); | |
| 155 } | |
| 156 | |
| 157 bool write_info(FILE *f, const FontInfo &fi) { | |
| 158 int32_t size = strlen(fi.name); | |
| 159 return tesseract::Serialize(f, &size) && tesseract::Serialize(f, &fi.name[0], size) && | |
| 160 tesseract::Serialize(f, &fi.properties); | |
| 161 } | |
| 162 | |
| 163 bool read_spacing_info(TFile *f, FontInfo *fi) { | |
| 164 int32_t vec_size, kern_size; | |
| 165 if (!f->DeSerialize(&vec_size)) { | |
| 166 return false; | |
| 167 } | |
| 168 ASSERT_HOST(vec_size >= 0); | |
| 169 if (vec_size == 0) { | |
| 170 return true; | |
| 171 } | |
| 172 fi->init_spacing(vec_size); | |
| 173 for (int i = 0; i < vec_size; ++i) { | |
| 174 auto *fs = new FontSpacingInfo(); | |
| 175 if (!f->DeSerialize(&fs->x_gap_before) || !f->DeSerialize(&fs->x_gap_after) || | |
| 176 !f->DeSerialize(&kern_size)) { | |
| 177 delete fs; | |
| 178 return false; | |
| 179 } | |
| 180 if (kern_size < 0) { // indication of a nullptr entry in fi->spacing_vec | |
| 181 delete fs; | |
| 182 continue; | |
| 183 } | |
| 184 if (kern_size > 0 && | |
| 185 (!f->DeSerialize(fs->kerned_unichar_ids) || !f->DeSerialize(fs->kerned_x_gaps))) { | |
| 186 delete fs; | |
| 187 return false; | |
| 188 } | |
| 189 fi->add_spacing(i, fs); | |
| 190 } | |
| 191 return true; | |
| 192 } | |
| 193 | |
| 194 bool write_spacing_info(FILE *f, const FontInfo &fi) { | |
| 195 int32_t vec_size = (fi.spacing_vec == nullptr) ? 0 : fi.spacing_vec->size(); | |
| 196 if (!tesseract::Serialize(f, &vec_size)) { | |
| 197 return false; | |
| 198 } | |
| 199 int16_t x_gap_invalid = -1; | |
| 200 for (int i = 0; i < vec_size; ++i) { | |
| 201 FontSpacingInfo *fs = fi.spacing_vec->at(i); | |
| 202 int32_t kern_size = (fs == nullptr) ? -1 : fs->kerned_x_gaps.size(); | |
| 203 if (fs == nullptr) { | |
| 204 // Writing two invalid x-gaps. | |
| 205 if (!tesseract::Serialize(f, &x_gap_invalid, 2) || !tesseract::Serialize(f, &kern_size)) { | |
| 206 return false; | |
| 207 } | |
| 208 } else { | |
| 209 if (!tesseract::Serialize(f, &fs->x_gap_before) || | |
| 210 !tesseract::Serialize(f, &fs->x_gap_after) || !tesseract::Serialize(f, &kern_size)) { | |
| 211 return false; | |
| 212 } | |
| 213 } | |
| 214 if (kern_size > 0 && | |
| 215 (!Serialize(f, fs->kerned_unichar_ids) || !Serialize(f, fs->kerned_x_gaps))) { | |
| 216 return false; | |
| 217 } | |
| 218 } | |
| 219 return true; | |
| 220 } | |
| 221 | |
| 222 bool write_set(FILE *f, const FontSet &fs) { | |
| 223 int size = fs.size(); | |
| 224 return tesseract::Serialize(f, &size) && | |
| 225 (size > 0 ? tesseract::Serialize(f, &fs[0], size) : true); | |
| 226 } | |
| 227 | |
| 228 } // namespace tesseract. |
