tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/ccstruct/fontinfo.cpp
Go to the documentation of this file.
00001 
00002 // File:        fontinfo.cpp
00003 // Description: Font information classes abstracted from intproto.h/cpp.
00004 // Author:      rays@google.com (Ray Smith)
00005 // Created:     Wed May 18 10:39:01 PDT 2011
00006 //
00007 // (C) Copyright 2011, Google Inc.
00008 // Licensed under the Apache License, Version 2.0 (the "License");
00009 // you may not use this file except in compliance with the License.
00010 // You may obtain a copy of the License at
00011 // http://www.apache.org/licenses/LICENSE-2.0
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 //
00019 
00020 #include "fontinfo.h"
00021 #include "bitvector.h"
00022 #include "unicity_table.h"
00023 
00024 namespace tesseract {
00025 
00026 // Writes to the given file. Returns false in case of error.
00027 bool FontInfo::Serialize(FILE* fp) const {
00028   if (!write_info(fp, *this)) return false;
00029   if (!write_spacing_info(fp, *this)) return false;
00030   return true;
00031 }
00032 // Reads from the given file. Returns false in case of error.
00033 // If swap is true, assumes a big/little-endian swap is needed.
00034 bool FontInfo::DeSerialize(bool swap, FILE* fp) {
00035   if (!read_info(fp, this, swap)) return false;
00036   if (!read_spacing_info(fp, this, swap)) return false;
00037   return true;
00038 }
00039 
00040 FontInfoTable::FontInfoTable() {
00041   set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
00042   set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
00043 }
00044 
00045 FontInfoTable::~FontInfoTable() {
00046 }
00047 
00048 // Writes to the given file. Returns false in case of error.
00049 bool FontInfoTable::Serialize(FILE* fp) const {
00050   return this->SerializeClasses(fp);
00051 }
00052 // Reads from the given file. Returns false in case of error.
00053 // If swap is true, assumes a big/little-endian swap is needed.
00054 bool FontInfoTable::DeSerialize(bool swap, FILE* fp) {
00055   truncate(0);
00056   return this->DeSerializeClasses(swap, fp);
00057 }
00058 
00059 // Returns true if the given set of fonts includes one with the same
00060 // properties as font_id.
00061 bool FontInfoTable::SetContainsFontProperties(
00062     int font_id, const GenericVector<int>& font_set) const {
00063   uinT32 properties = get(font_id).properties;
00064   for (int f = 0; f < font_set.size(); ++f) {
00065     if (get(font_set[f]).properties == properties)
00066       return true;
00067   }
00068   return false;
00069 }
00070 
00071 // Returns true if the given set of fonts includes multiple properties.
00072 bool FontInfoTable::SetContainsMultipleFontProperties(
00073     const GenericVector<int>& font_set) const {
00074   if (font_set.empty()) return false;
00075   int first_font = font_set[0];
00076   uinT32 properties = get(first_font).properties;
00077   for (int f = 1; f < font_set.size(); ++f) {
00078     if (get(font_set[f]).properties != properties)
00079       return true;
00080   }
00081   return false;
00082 }
00083 
00084 // Moves any non-empty FontSpacingInfo entries from other to this.
00085 void FontInfoTable::MoveSpacingInfoFrom(FontInfoTable* other) {
00086   set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
00087   set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
00088   for (int i = 0; i < other->size(); ++i) {
00089     GenericVector<FontSpacingInfo*>* spacing_vec = other->get(i).spacing_vec;
00090     if (spacing_vec != NULL) {
00091       int target_index = get_index(other->get(i));
00092       if (target_index < 0) {
00093         // Bit copy the FontInfo and steal all the pointers.
00094         push_back(other->get(i));
00095         other->get(i).name = NULL;
00096       } else {
00097         delete [] get(target_index).spacing_vec;
00098         get(target_index).spacing_vec = other->get(i).spacing_vec;
00099       }
00100       other->get(i).spacing_vec = NULL;
00101     }
00102   }
00103 }
00104 
00105 // Moves this to the target unicity table.
00106 void FontInfoTable::MoveTo(UnicityTable<FontInfo>* target) {
00107   target->clear();
00108   target->set_compare_callback(NewPermanentTessCallback(CompareFontInfo));
00109   target->set_clear_callback(NewPermanentTessCallback(FontInfoDeleteCallback));
00110   for (int i = 0; i < size(); ++i) {
00111     // Bit copy the FontInfo and steal all the pointers.
00112     target->push_back(get(i));
00113     get(i).name = NULL;
00114     get(i).spacing_vec = NULL;
00115   }
00116 }
00117 
00118 
00119 // Compare FontInfo structures.
00120 bool CompareFontInfo(const FontInfo& fi1, const FontInfo& fi2) {
00121   // The font properties are required to be the same for two font with the same
00122   // name, so there is no need to test them.
00123   // Consequently, querying the table with only its font name as information is
00124   // enough to retrieve its properties.
00125   return strcmp(fi1.name, fi2.name) == 0;
00126 }
00127 // Compare FontSet structures.
00128 bool CompareFontSet(const FontSet& fs1, const FontSet& fs2) {
00129   if (fs1.size != fs2.size)
00130     return false;
00131   for (int i = 0; i < fs1.size; ++i) {
00132     if (fs1.configs[i] != fs2.configs[i])
00133       return false;
00134   }
00135   return true;
00136 }
00137 
00138 // Callbacks for GenericVector.
00139 void FontInfoDeleteCallback(FontInfo f) {
00140   if (f.spacing_vec != NULL) {
00141     f.spacing_vec->delete_data_pointers();
00142     delete f.spacing_vec;
00143   }
00144   delete[] f.name;
00145 }
00146 void FontSetDeleteCallback(FontSet fs) {
00147   delete[] fs.configs;
00148 }
00149 
00150 /*---------------------------------------------------------------------------*/
00151 // Callbacks used by UnicityTable to read/write FontInfo/FontSet structures.
00152 bool read_info(FILE* f, FontInfo* fi, bool swap) {
00153   inT32 size;
00154   if (fread(&size, sizeof(size), 1, f) != 1) return false;
00155   if (swap)
00156     Reverse32(&size);
00157   char* font_name = new char[size + 1];
00158   fi->name = font_name;
00159   if (static_cast<int>(fread(font_name, sizeof(*font_name), size, f)) != size)
00160     return false;
00161   font_name[size] = '\0';
00162   if (fread(&fi->properties, sizeof(fi->properties), 1, f) != 1) return false;
00163   if (swap)
00164     Reverse32(&fi->properties);
00165   return true;
00166 }
00167 
00168 bool write_info(FILE* f, const FontInfo& fi) {
00169   inT32 size = strlen(fi.name);
00170   if (fwrite(&size, sizeof(size), 1, f) != 1) return false;
00171   if (static_cast<int>(fwrite(fi.name, sizeof(*fi.name), size, f)) != size)
00172     return false;
00173   if (fwrite(&fi.properties, sizeof(fi.properties), 1, f) != 1) return false;
00174   return true;
00175 }
00176 
00177 bool read_spacing_info(FILE *f, FontInfo* fi, bool swap) {
00178   inT32 vec_size, kern_size;
00179   if (fread(&vec_size, sizeof(vec_size), 1, f) != 1) return false;
00180   if (swap) Reverse32(&vec_size);
00181   ASSERT_HOST(vec_size >= 0);
00182   if (vec_size == 0) return true;
00183   fi->init_spacing(vec_size);
00184   for (int i = 0; i < vec_size; ++i) {
00185     FontSpacingInfo *fs = new FontSpacingInfo();
00186     if (fread(&fs->x_gap_before, sizeof(fs->x_gap_before), 1, f) != 1 ||
00187         fread(&fs->x_gap_after, sizeof(fs->x_gap_after), 1, f) != 1 ||
00188         fread(&kern_size, sizeof(kern_size), 1, f) != 1) {
00189       return false;
00190     }
00191     if (swap) {
00192       ReverseN(&(fs->x_gap_before), sizeof(fs->x_gap_before));
00193       ReverseN(&(fs->x_gap_after), sizeof(fs->x_gap_after));
00194       Reverse32(&kern_size);
00195     }
00196     if (kern_size < 0) {  // indication of a NULL entry in fi->spacing_vec
00197       delete fs;
00198       continue;
00199     }
00200     if (kern_size > 0 && (!fs->kerned_unichar_ids.DeSerialize(swap, f) ||
00201                           !fs->kerned_x_gaps.DeSerialize(swap, f))) {
00202       return false;
00203     }
00204     fi->add_spacing(i, fs);
00205   }
00206   return true;
00207 }
00208 
00209 bool write_spacing_info(FILE* f, const FontInfo& fi) {
00210   inT32 vec_size = (fi.spacing_vec == NULL) ? 0 : fi.spacing_vec->size();
00211   if (fwrite(&vec_size,  sizeof(vec_size), 1, f) != 1) return false;
00212   inT16 x_gap_invalid = -1;
00213   for (int i = 0; i < vec_size; ++i) {
00214     FontSpacingInfo *fs = fi.spacing_vec->get(i);
00215     inT32 kern_size = (fs == NULL) ? -1 : fs->kerned_x_gaps.size();
00216     if (fs == NULL) {
00217       // Valid to have the identical fwrites. Writing invalid x-gaps.
00218       if (fwrite(&(x_gap_invalid), sizeof(x_gap_invalid), 1, f) != 1 ||
00219           fwrite(&(x_gap_invalid), sizeof(x_gap_invalid), 1, f) != 1 ||
00220           fwrite(&kern_size, sizeof(kern_size), 1, f) != 1) {
00221         return false;
00222       }
00223     } else {
00224       if (fwrite(&(fs->x_gap_before), sizeof(fs->x_gap_before), 1, f) != 1 ||
00225           fwrite(&(fs->x_gap_after), sizeof(fs->x_gap_after), 1, f) != 1 ||
00226           fwrite(&kern_size, sizeof(kern_size), 1, f) != 1) {
00227         return false;
00228       }
00229     }
00230     if (kern_size > 0 && (!fs->kerned_unichar_ids.Serialize(f) ||
00231                           !fs->kerned_x_gaps.Serialize(f))) {
00232       return false;
00233     }
00234   }
00235   return true;
00236 }
00237 
00238 bool read_set(FILE* f, FontSet* fs, bool swap) {
00239   if (fread(&fs->size, sizeof(fs->size), 1, f) != 1) return false;
00240   if (swap)
00241     Reverse32(&fs->size);
00242   fs->configs = new int[fs->size];
00243   for (int i = 0; i < fs->size; ++i) {
00244     if (fread(&fs->configs[i], sizeof(fs->configs[i]), 1, f) != 1) return false;
00245     if (swap)
00246       Reverse32(&fs->configs[i]);
00247   }
00248   return true;
00249 }
00250 
00251 bool write_set(FILE* f, const FontSet& fs) {
00252   if (fwrite(&fs.size, sizeof(fs.size), 1, f) != 1) return false;
00253   for (int i = 0; i < fs.size; ++i) {
00254     if (fwrite(&fs.configs[i], sizeof(fs.configs[i]), 1, f) != 1) return false;
00255   }
00256   return true;
00257 }
00258 
00259 }  // namespace tesseract.
00260 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines