1 /********************************************************************** 2 * File: boxchar.h 3 * Description: Simple class to associate a Tesseract classification unit with 4 * its bounding box so that the boxes can be rotated as the image 5 * is rotated for degradation. Also includes routines to output 6 * the character-tagged boxes to a boxfile. 7 * Author: Ray Smith 8 * Created: Mon Nov 18 2013 9 * 10 * (C) Copyright 2013, Google Inc. 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 **********************************************************************/ 22 23 #ifndef TESSERACT_TRAINING_BOXCHAR_H_ 24 #define TESSERACT_TRAINING_BOXCHAR_H_ 25 26 #include <string> 27 #include <vector> 28 29 #include <allheaders.h> // from Leptonica 30 #include <tesseract/export.h> 31 32 struct Box; 33 34 namespace tesseract { 35 36 class BoxChar { 37 public: 38 BoxChar(const char *utf8_str, int len); 39 40 ~BoxChar(); 41 42 // Accessors. ch()43 const std::string &ch() const { 44 return ch_; 45 } box()46 const Box *box() const { 47 return box_; 48 } page()49 const int &page() const { 50 return page_; 51 } set_rtl_index(int index)52 void set_rtl_index(int index) { 53 rtl_index_ = index; 54 } rtl_index()55 const int &rtl_index() const { 56 return rtl_index_; 57 } 58 59 // Set the box_ member. 60 void AddBox(int x, int y, int width, int height); 61 set_page(int page)62 void set_page(int page) { 63 page_ = page; 64 } 65 mutable_ch()66 std::string *mutable_ch() { 67 return &ch_; 68 } mutable_box()69 Box *mutable_box() { 70 return box_; 71 } 72 73 // Sort function for sorting by left edge of box. Note that this will not 74 // work properly until after InsertNewlines and InsertSpaces. 75 bool operator<(const BoxChar &other) const { 76 if (box_ == nullptr) { 77 return true; 78 } 79 if (other.box_ == nullptr) { 80 return false; 81 } 82 return box_->x < other.box_->x; 83 } 84 // Increments *num_rtl and *num_ltr according to the directionality of 85 // characters in the box. 86 void GetDirection(int *num_rtl, int *num_ltr) const; 87 // Reverses the order of unicodes within the box. If Pango generates a 88 // ligature, these will get reversed on output, so reverse now. 89 void ReverseUnicodesInBox(); 90 91 static void TranslateBoxes(int xshift, int yshift, std::vector<BoxChar *> *boxes); 92 93 // Prepares for writing the boxes to a file by inserting newlines, spaces, 94 // and re-ordering so the boxes are strictly left-to-right. 95 static void PrepareToWrite(std::vector<BoxChar *> *boxes); 96 // Inserts newline (tab) characters into the vector at newline positions. 97 static void InsertNewlines(bool rtl_rules, bool vertical_rules, std::vector<BoxChar *> *boxes); 98 // Converts nullptr boxes to space characters, with appropriate bounding 99 // boxes. 100 static void InsertSpaces(bool rtl_rules, bool vertical_rules, std::vector<BoxChar *> *boxes); 101 // Reorders text in a right-to-left script in left-to-right order. 102 static void ReorderRTLText(std::vector<BoxChar *> *boxes); 103 // Returns true if the vector contains mostly RTL characters. 104 static bool ContainsMostlyRTL(const std::vector<BoxChar *> &boxes); 105 // Returns true if the text is mostly laid out vertically. 106 static bool MostlyVertical(const std::vector<BoxChar *> &boxes); 107 108 // Returns the total length of all the strings in the boxes. 109 static int TotalByteLength(const std::vector<BoxChar *> &boxes); 110 111 // Rotate the vector of boxes between start and end by the given rotation. 112 // The rotation is in radians clockwise about the given center. 113 static void RotateBoxes(float rotation, int xcenter, int ycenter, int start_box, int end_box, 114 std::vector<BoxChar *> *boxes); 115 116 // Create a tesseract box file from the vector of boxes. The image height 117 // is needed to convert to tesseract coordinates. 118 static void WriteTesseractBoxFile(const std::string &name, int height, 119 const std::vector<BoxChar *> &boxes); 120 // Gets the tesseract box file as a string from the vector of boxes. 121 // The image height is needed to convert to tesseract coordinates. 122 static std::string GetTesseractBoxStr(int height, const std::vector<BoxChar *> &boxes); 123 124 private: 125 std::string ch_; 126 Box *box_; 127 int page_; 128 // If the box is an RTL character, contains the original position in the 129 // array of boxes (before reversal), otherwise -1. 130 int rtl_index_; 131 }; 132 133 // Sort predicate to sort a vector of BoxChar*. 134 struct BoxCharPtrSort { operatorBoxCharPtrSort135 bool operator()(const BoxChar *box1, const BoxChar *box2) const { 136 if (box1->rtl_index() >= 0 && box2->rtl_index() >= 0) { 137 return box2->rtl_index() < box1->rtl_index(); 138 } 139 return *box1 < *box2; 140 } 141 }; 142 143 } // namespace tesseract 144 145 #endif // TESSERACT_TRAINING_BOXCHAR_H_ 146