1 /********************************************************************** 2 * File: stringrenderer.h 3 * Description: Class for rendering UTF-8 text to an image, and retrieving 4 * bounding boxes around each grapheme cluster. 5 * 6 * Instances are created using a font description string 7 * (eg. "Arial Italic 12"; see pango_font_info.h for the format) 8 * and the page dimensions. Other renderer properties such as 9 * spacing, ligaturization, as well a preprocessing behavior such 10 * as removal of unrenderable words and a special n-gram mode may 11 * be set using respective set_* methods. 12 * 13 * Author: Ranjith Unnikrishnan 14 * 15 * (C) Copyright 2013, Google Inc. 16 * Licensed under the Apache License, Version 2.0 (the "License"); 17 * you may not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * http://www.apache.org/licenses/LICENSE-2.0 20 * Unless required by applicable law or agreed to in writing, software 21 * distributed under the License is distributed on an "AS IS" BASIS, 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 * See the License for the specific language governing permissions and 24 * limitations under the License. 25 * 26 **********************************************************************/ 27 28 #ifndef TESSERACT_TRAINING_STRINGRENDERER_H_ 29 #define TESSERACT_TRAINING_STRINGRENDERER_H_ 30 31 #include "export.h" 32 33 #include "pango/pango-layout.h" 34 #include "pango/pangocairo.h" 35 #include "pango_font_info.h" 36 37 #include "image.h" 38 39 #include <string> 40 #include <unordered_map> 41 #include <vector> 42 43 struct Boxa; 44 struct Pix; 45 46 namespace tesseract { 47 48 class BoxChar; 49 50 class TESS_PANGO_TRAINING_API StringRenderer { 51 public: 52 StringRenderer(const std::string &font_desc, int page_width, int page_height); 53 ~StringRenderer(); 54 55 // Renders the text with the chosen font and returns the byte offset up to 56 // which the text could be rendered so as to fit the specified page 57 // dimensions. 58 int RenderToImage(const char *text, int text_length, Image *pix); 59 int RenderToGrayscaleImage(const char *text, int text_length, Image *pix); 60 int RenderToBinaryImage(const char *text, int text_length, int threshold, Image *pix); 61 // Renders a line of text with all available fonts that were able to render 62 // at least min_coverage fraction of the input text. Use 1.0 to require that 63 // a font be able to render all the text. 64 int RenderAllFontsToImage(double min_coverage, const char *text, int text_length, 65 std::string *font_used, Image *pix); 66 67 bool set_font(const std::string &desc); 68 // Char spacing is in PIXELS!!!!. set_char_spacing(int char_spacing)69 void set_char_spacing(int char_spacing) { 70 char_spacing_ = char_spacing; 71 } set_leading(int leading)72 void set_leading(int leading) { 73 leading_ = leading; 74 } 75 void set_resolution(const int resolution); set_vertical_text(bool vertical_text)76 void set_vertical_text(bool vertical_text) { 77 vertical_text_ = vertical_text; 78 } set_gravity_hint_strong(bool gravity_hint_strong)79 void set_gravity_hint_strong(bool gravity_hint_strong) { 80 gravity_hint_strong_ = gravity_hint_strong; 81 } set_render_fullwidth_latin(bool render_fullwidth_latin)82 void set_render_fullwidth_latin(bool render_fullwidth_latin) { 83 render_fullwidth_latin_ = render_fullwidth_latin; 84 } 85 // Sets the probability (value in [0, 1]) of starting to render a word with an 86 // underline. This implementation consider words to be space-delimited 87 // sequences of characters. 88 void set_underline_start_prob(const double frac); 89 // Set the probability (value in [0, 1]) of continuing a started underline to 90 // the next word. 91 void set_underline_continuation_prob(const double frac); set_underline_style(const PangoUnderline style)92 void set_underline_style(const PangoUnderline style) { 93 underline_style_ = style; 94 } set_features(const char * features)95 void set_features(const char *features) { 96 features_ = features; 97 } set_page(int page)98 void set_page(int page) { 99 page_ = page; 100 } set_box_padding(int val)101 void set_box_padding(int val) { 102 box_padding_ = val; 103 } set_drop_uncovered_chars(bool val)104 void set_drop_uncovered_chars(bool val) { 105 drop_uncovered_chars_ = val; 106 } set_strip_unrenderable_words(bool val)107 void set_strip_unrenderable_words(bool val) { 108 strip_unrenderable_words_ = val; 109 } set_output_word_boxes(bool val)110 void set_output_word_boxes(bool val) { 111 output_word_boxes_ = val; 112 } 113 // Before rendering the string, replace latin characters with their optional 114 // ligatured forms (such as "fi", "ffi" etc.) if the font_ covers those 115 // unicodes. set_add_ligatures(bool add_ligatures)116 void set_add_ligatures(bool add_ligatures) { 117 add_ligatures_ = add_ligatures; 118 } 119 // Set the rgb value of the text ink. Values range in [0, 1.0] set_pen_color(double r,double g,double b)120 void set_pen_color(double r, double g, double b) { 121 pen_color_[0] = r; 122 pen_color_[1] = g; 123 pen_color_[2] = b; 124 } set_h_margin(const int h_margin)125 void set_h_margin(const int h_margin) { 126 h_margin_ = h_margin; 127 } set_v_margin(const int v_margin)128 void set_v_margin(const int v_margin) { 129 v_margin_ = v_margin; 130 } font()131 const PangoFontInfo &font() const { 132 return font_; 133 } h_margin()134 int h_margin() const { 135 return h_margin_; 136 } v_margin()137 int v_margin() const { 138 return v_margin_; 139 } 140 141 // Get the boxchars of all clusters rendered thus far (or since the last call 142 // to ClearBoxes()). 143 const std::vector<BoxChar *> &GetBoxes() const; 144 // Get the rendered page bounding boxes of all pages created thus far (or 145 // since last call to ClearBoxes()). 146 Boxa *GetPageBoxes() const; 147 148 // Rotate the boxes on the most recent page by the given rotation. 149 void RotatePageBoxes(float rotation); 150 // Delete all boxes. 151 void ClearBoxes(); 152 // Returns the boxes in a boxfile string. 153 std::string GetBoxesStr(); 154 // Writes the boxes to a boxfile. 155 void WriteAllBoxes(const std::string &filename); 156 // Removes space-delimited words from the string that are not renderable by 157 // the current font and returns the count of such words. 158 int StripUnrenderableWords(std::string *utf8_text) const; 159 160 // Insert a Word Joiner symbol (U+2060) between adjacent characters, excluding 161 // spaces and combining types, in each word before rendering to ensure words 162 // are not broken across lines. The output boxchars will not contain the 163 // joiner. 164 static std::string InsertWordJoiners(const std::string &text); 165 166 // Helper functions to convert fullwidth Latin and halfwidth Basic Latin. 167 static std::string ConvertBasicLatinToFullwidthLatin(const std::string &text); 168 static std::string ConvertFullwidthLatinToBasicLatin(const std::string &text); 169 170 protected: 171 // Init and free local renderer objects. 172 void InitPangoCairo(); 173 void FreePangoCairo(); 174 // Set rendering properties. 175 void SetLayoutProperties(); 176 void SetWordUnderlineAttributes(const std::string &page_text); 177 // Compute bounding boxes around grapheme clusters. 178 void ComputeClusterBoxes(); 179 void CorrectBoxPositionsToLayout(std::vector<BoxChar *> *boxchars); 180 bool GetClusterStrings(std::vector<std::string> *cluster_text); 181 int FindFirstPageBreakOffset(const char *text, int text_length); 182 183 PangoFontInfo font_; 184 // Page properties 185 int page_width_, page_height_, h_margin_, v_margin_; 186 // Text rendering properties 187 double pen_color_[3]; 188 int char_spacing_; 189 int leading_, resolution_; 190 bool vertical_text_; 191 bool gravity_hint_strong_; 192 bool render_fullwidth_latin_; 193 double underline_start_prob_; 194 double underline_continuation_prob_; 195 PangoUnderline underline_style_; 196 std::string features_; 197 // Text filtering options 198 bool drop_uncovered_chars_; 199 bool strip_unrenderable_words_; 200 bool add_ligatures_; 201 bool output_word_boxes_; 202 // Pango and cairo specific objects 203 cairo_surface_t *surface_; 204 cairo_t *cr_; 205 PangoLayout *layout_; 206 // Internal state of current page number, updated on successive calls to 207 // RenderToImage() 208 int start_box_; 209 int page_; 210 // Boxes and associated text for all pages rendered with RenderToImage() since 211 // the last call to ClearBoxes(). 212 std::vector<BoxChar *> boxchars_; 213 int box_padding_; 214 // Bounding boxes for pages since the last call to ClearBoxes(). 215 Boxa *page_boxes_; 216 217 // Objects cached for subsequent calls to RenderAllFontsToImage() 218 std::unordered_map<char32, int64_t> char_map_; // Time-saving char histogram. 219 int total_chars_; // Number in the string to be rendered. 220 unsigned int font_index_; // Index of next font to use in font list. 221 int last_offset_; // Offset returned from last successful rendering 222 223 private: 224 StringRenderer(const StringRenderer &) = delete; 225 void operator=(const StringRenderer &) = delete; 226 }; 227 } // namespace tesseract 228 229 #endif // THIRD_PARTY_TESSERACT_TRAINING_STRINGRENDERER_H_ 230