2014-01-10 02:04:20 +08:00
|
|
|
/**********************************************************************
|
|
|
|
* File: stringrenderer.h
|
|
|
|
* Description: Class for rendering UTF-8 text to an image, and retrieving
|
|
|
|
* bounding boxes around each grapheme cluster.
|
|
|
|
*
|
|
|
|
* Instances are created using a font description string
|
|
|
|
* (eg. "Arial Italic 12"; see pango_font_info.h for the format)
|
|
|
|
* and the page dimensions. Other renderer properties such as
|
|
|
|
* spacing, ligaturization, as well a preprocessing behavior such
|
|
|
|
* as removal of unrenderable words and a special n-gram mode may
|
|
|
|
* be set using respective set_* methods.
|
|
|
|
*
|
|
|
|
* Author: Ranjith Unnikrishnan
|
|
|
|
*
|
|
|
|
* (C) Copyright 2013, Google Inc.
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef TESSERACT_TRAINING_STRINGRENDERER_H_
|
|
|
|
#define TESSERACT_TRAINING_STRINGRENDERER_H_
|
|
|
|
|
|
|
|
#include <string>
|
2017-01-16 06:42:34 +08:00
|
|
|
#include <unordered_map>
|
2017-01-26 08:20:19 +08:00
|
|
|
#include <vector>
|
2014-01-10 02:04:20 +08:00
|
|
|
|
|
|
|
#include "pango_font_info.h"
|
|
|
|
#include "pango/pango-layout.h"
|
|
|
|
#include "pango/pangocairo.h"
|
|
|
|
|
|
|
|
struct Boxa;
|
|
|
|
struct Pix;
|
|
|
|
|
2018-10-21 03:43:38 +08:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
# define strdup(s) _strdup(s)
|
|
|
|
#endif
|
|
|
|
|
2014-01-10 02:04:20 +08:00
|
|
|
namespace tesseract {
|
|
|
|
|
|
|
|
class BoxChar;
|
|
|
|
|
|
|
|
class StringRenderer {
|
|
|
|
public:
|
2018-03-03 21:36:28 +08:00
|
|
|
StringRenderer(const std::string& font_desc, int page_width, int page_height);
|
2014-01-10 02:04:20 +08:00
|
|
|
~StringRenderer();
|
|
|
|
|
2015-11-04 16:54:00 +08:00
|
|
|
// Renders the text with the chosen font and returns the byte offset up to
|
2014-01-10 02:04:20 +08:00
|
|
|
// which the text could be rendered so as to fit the specified page
|
|
|
|
// dimensions.
|
|
|
|
int RenderToImage(const char* text, int text_length, Pix** pix);
|
2014-08-12 07:19:06 +08:00
|
|
|
int RenderToGrayscaleImage(const char* text, int text_length, Pix** pix);
|
2014-01-10 02:04:20 +08:00
|
|
|
int RenderToBinaryImage(const char* text, int text_length, int threshold,
|
|
|
|
Pix** pix);
|
|
|
|
// Renders a line of text with all available fonts that were able to render
|
2014-05-21 23:48:48 +08:00
|
|
|
// at least min_coverage fraction of the input text. Use 1.0 to require that
|
|
|
|
// a font be able to render all the text.
|
2014-04-25 05:46:57 +08:00
|
|
|
int RenderAllFontsToImage(double min_coverage, const char* text,
|
2018-03-03 21:36:28 +08:00
|
|
|
int text_length, std::string* font_used, Pix** pix);
|
2014-01-10 02:04:20 +08:00
|
|
|
|
2018-03-03 21:36:28 +08:00
|
|
|
bool set_font(const std::string& desc);
|
2017-09-08 17:29:03 +08:00
|
|
|
// Char spacing is in PIXELS!!!!.
|
|
|
|
void set_char_spacing(int char_spacing) { char_spacing_ = char_spacing; }
|
2014-01-10 02:04:20 +08:00
|
|
|
void set_leading(int leading) {
|
|
|
|
leading_ = leading;
|
|
|
|
}
|
|
|
|
void set_resolution(const int resolution);
|
|
|
|
void set_vertical_text(bool vertical_text) {
|
|
|
|
vertical_text_ = vertical_text;
|
|
|
|
}
|
|
|
|
void set_gravity_hint_strong(bool gravity_hint_strong) {
|
|
|
|
gravity_hint_strong_ = gravity_hint_strong;
|
|
|
|
}
|
|
|
|
void set_render_fullwidth_latin(bool render_fullwidth_latin) {
|
|
|
|
render_fullwidth_latin_ = render_fullwidth_latin;
|
|
|
|
}
|
2014-08-12 07:19:06 +08:00
|
|
|
// Sets the probability (value in [0, 1]) of starting to render a word with an
|
|
|
|
// underline. This implementation consider words to be space-delimited
|
|
|
|
// sequences of characters.
|
2015-07-10 05:28:20 +08:00
|
|
|
void set_underline_start_prob(const double frac);
|
2014-08-12 07:19:06 +08:00
|
|
|
// Set the probability (value in [0, 1]) of continuing a started underline to
|
|
|
|
// the next word.
|
2015-07-10 05:28:20 +08:00
|
|
|
void set_underline_continuation_prob(const double frac);
|
2014-08-12 07:19:06 +08:00
|
|
|
void set_underline_style(const PangoUnderline style) {
|
|
|
|
underline_style_ = style;
|
|
|
|
}
|
2016-11-08 03:35:45 +08:00
|
|
|
void set_features(const char* features) {
|
2016-03-21 19:41:36 +08:00
|
|
|
free(features_);
|
|
|
|
features_ = strdup(features);
|
|
|
|
}
|
2014-01-10 02:04:20 +08:00
|
|
|
void set_page(int page) {
|
|
|
|
page_ = page;
|
|
|
|
}
|
|
|
|
void set_box_padding(int val) {
|
|
|
|
box_padding_ = val;
|
|
|
|
}
|
|
|
|
void set_drop_uncovered_chars(bool val) {
|
|
|
|
drop_uncovered_chars_ = val;
|
|
|
|
}
|
|
|
|
void set_strip_unrenderable_words(bool val) {
|
|
|
|
strip_unrenderable_words_ = val;
|
|
|
|
}
|
|
|
|
void set_output_word_boxes(bool val) {
|
|
|
|
output_word_boxes_ = val;
|
|
|
|
}
|
|
|
|
// Before rendering the string, replace latin characters with their optional
|
|
|
|
// ligatured forms (such as "fi", "ffi" etc.) if the font_ covers those
|
|
|
|
// unicodes.
|
|
|
|
void set_add_ligatures(bool add_ligatures) {
|
|
|
|
add_ligatures_ = add_ligatures;
|
|
|
|
}
|
|
|
|
// Set the rgb value of the text ink. Values range in [0, 1.0]
|
|
|
|
void set_pen_color(double r, double g, double b) {
|
|
|
|
pen_color_[0] = r;
|
|
|
|
pen_color_[1] = g;
|
|
|
|
pen_color_[2] = b;
|
|
|
|
}
|
|
|
|
void set_h_margin(const int h_margin) {
|
|
|
|
h_margin_ = h_margin;
|
|
|
|
}
|
|
|
|
void set_v_margin(const int v_margin) {
|
|
|
|
v_margin_ = v_margin;
|
|
|
|
}
|
|
|
|
const PangoFontInfo& font() const {
|
|
|
|
return font_;
|
|
|
|
}
|
2016-11-08 03:35:45 +08:00
|
|
|
int h_margin() const { return h_margin_; }
|
|
|
|
int v_margin() const { return v_margin_; }
|
2014-01-10 02:04:20 +08:00
|
|
|
|
|
|
|
// Get the boxchars of all clusters rendered thus far (or since the last call
|
|
|
|
// to ClearBoxes()).
|
2016-12-01 07:45:36 +08:00
|
|
|
const std::vector<BoxChar*>& GetBoxes() const;
|
2014-01-10 02:04:20 +08:00
|
|
|
// Get the rendered page bounding boxes of all pages created thus far (or
|
|
|
|
// since last call to ClearBoxes()).
|
|
|
|
Boxa* GetPageBoxes() const;
|
|
|
|
|
|
|
|
// Rotate the boxes on the most recent page by the given rotation.
|
|
|
|
void RotatePageBoxes(float rotation);
|
|
|
|
// Delete all boxes.
|
|
|
|
void ClearBoxes();
|
2016-11-08 03:35:45 +08:00
|
|
|
// Returns the boxes in a boxfile string.
|
2018-03-03 21:36:28 +08:00
|
|
|
std::string GetBoxesStr();
|
2016-11-08 03:35:45 +08:00
|
|
|
// Writes the boxes to a boxfile.
|
2018-03-03 21:36:28 +08:00
|
|
|
void WriteAllBoxes(const std::string& filename);
|
2014-01-10 02:04:20 +08:00
|
|
|
// Removes space-delimited words from the string that are not renderable by
|
|
|
|
// the current font and returns the count of such words.
|
2018-03-03 21:36:28 +08:00
|
|
|
int StripUnrenderableWords(std::string* utf8_text) const;
|
2014-01-10 02:04:20 +08:00
|
|
|
|
|
|
|
// Insert a Word Joiner symbol (U+2060) between adjacent characters, excluding
|
|
|
|
// spaces and combining types, in each word before rendering to ensure words
|
|
|
|
// are not broken across lines. The output boxchars will not contain the
|
|
|
|
// joiner.
|
2018-03-03 21:36:28 +08:00
|
|
|
static std::string InsertWordJoiners(const std::string& text);
|
2014-01-10 02:04:20 +08:00
|
|
|
|
|
|
|
// Helper functions to convert fullwidth Latin and halfwidth Basic Latin.
|
2018-03-03 21:36:28 +08:00
|
|
|
static std::string ConvertBasicLatinToFullwidthLatin(const std::string& text);
|
|
|
|
static std::string ConvertFullwidthLatinToBasicLatin(const std::string& text);
|
2014-01-10 02:04:20 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
// Init and free local renderer objects.
|
|
|
|
void InitPangoCairo();
|
|
|
|
void FreePangoCairo();
|
2014-08-12 07:19:06 +08:00
|
|
|
// Set rendering properties.
|
|
|
|
void SetLayoutProperties();
|
2018-03-03 21:36:28 +08:00
|
|
|
void SetWordUnderlineAttributes(const std::string& page_text);
|
2014-01-10 02:04:20 +08:00
|
|
|
// Compute bounding boxes around grapheme clusters.
|
|
|
|
void ComputeClusterBoxes();
|
2016-12-01 07:45:36 +08:00
|
|
|
void CorrectBoxPositionsToLayout(std::vector<BoxChar*>* boxchars);
|
2018-03-03 21:36:28 +08:00
|
|
|
bool GetClusterStrings(std::vector<std::string>* cluster_text);
|
2014-01-10 02:04:20 +08:00
|
|
|
int FindFirstPageBreakOffset(const char* text, int text_length);
|
|
|
|
|
|
|
|
PangoFontInfo font_;
|
|
|
|
// Page properties
|
|
|
|
int page_width_, page_height_, h_margin_, v_margin_;
|
|
|
|
// Text rendering properties
|
2017-06-02 15:54:16 +08:00
|
|
|
double pen_color_[3];
|
2017-09-08 17:29:03 +08:00
|
|
|
int char_spacing_;
|
2014-01-10 02:04:20 +08:00
|
|
|
int leading_, resolution_;
|
|
|
|
bool vertical_text_;
|
|
|
|
bool gravity_hint_strong_;
|
|
|
|
bool render_fullwidth_latin_;
|
2014-08-12 07:19:06 +08:00
|
|
|
double underline_start_prob_;
|
|
|
|
double underline_continuation_prob_;
|
|
|
|
PangoUnderline underline_style_;
|
2016-11-08 03:35:45 +08:00
|
|
|
char* features_;
|
2014-01-10 02:04:20 +08:00
|
|
|
// Text filtering options
|
|
|
|
bool drop_uncovered_chars_;
|
|
|
|
bool strip_unrenderable_words_;
|
|
|
|
bool add_ligatures_;
|
|
|
|
bool output_word_boxes_;
|
|
|
|
// Pango and cairo specific objects
|
|
|
|
cairo_surface_t* surface_;
|
|
|
|
cairo_t* cr_;
|
|
|
|
PangoLayout* layout_;
|
|
|
|
// Internal state of current page number, updated on successive calls to
|
|
|
|
// RenderToImage()
|
|
|
|
int start_box_;
|
|
|
|
int page_;
|
|
|
|
// Boxes and associated text for all pages rendered with RenderToImage() since
|
|
|
|
// the last call to ClearBoxes().
|
2016-12-01 07:45:36 +08:00
|
|
|
std::vector<BoxChar*> boxchars_;
|
2014-01-10 02:04:20 +08:00
|
|
|
int box_padding_;
|
|
|
|
// Bounding boxes for pages since the last call to ClearBoxes().
|
|
|
|
Boxa* page_boxes_;
|
|
|
|
|
|
|
|
// Objects cached for subsequent calls to RenderAllFontsToImage()
|
Use POSIX data types and macros (#878)
* api: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccmain: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccstruct: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* classify: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* cutil: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* dict: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* textord: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* training: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* wordrec: Replace Tesseract data types by POSIX data types
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccutil: Replace Tesseract data types by POSIX data types
Now all Tesseract data types which are no longer needed can be removed
from ccutil/host.h.
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccmain: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccstruct: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* classify: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* dict: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* lstm: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* textord: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* wordrec: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* ccutil: Replace Tesseract's MIN_*INT, MAX_*INT* by POSIX *INT*_MIN, *INT*_MAX
Remove the macros which are now unused from ccutil/host.h.
Remove also the obsolete history comments.
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* Fix build error caused by ambiguous ClipToRange
Error message vom Appveyor CI:
C:\projects\tesseract\ccstruct\coutln.cpp(818): error C2672: 'ClipToRange': no matching overloaded function found [C:\projects\tesseract\build\libtesseract.vcxproj]
C:\projects\tesseract\ccstruct\coutln.cpp(818): error C2782: 'T ClipToRange(const T &,const T &,const T &)': template parameter 'T' is ambiguous [C:\projects\tesseract\build\libtesseract.vcxproj]
c:\projects\tesseract\ccutil\helpers.h(122): note: see declaration of 'ClipToRange'
C:\projects\tesseract\ccstruct\coutln.cpp(818): note: could be 'char'
C:\projects\tesseract\ccstruct\coutln.cpp(818): note: or 'int'
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* unittest: Replace Tesseract's MAX_INT8 by POSIX INT8_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
* arch: Replace Tesseract's MAX_INT8 by POSIX INT8_MAX
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2018-03-14 04:36:30 +08:00
|
|
|
std::unordered_map<char32, int64_t> char_map_; // Time-saving char histogram.
|
2014-01-10 02:04:20 +08:00
|
|
|
int total_chars_; // Number in the string to be rendered.
|
2017-07-15 00:30:14 +08:00
|
|
|
unsigned int font_index_; // Index of next font to use in font list.
|
2014-01-10 02:04:20 +08:00
|
|
|
int last_offset_; // Offset returned from last successful rendering
|
|
|
|
|
|
|
|
private:
|
|
|
|
StringRenderer(const StringRenderer&);
|
|
|
|
void operator=(const StringRenderer&);
|
|
|
|
};
|
|
|
|
} // namespace tesseract
|
|
|
|
|
|
|
|
#endif // THIRD_PARTY_TESSERACT_TRAINING_STRINGRENDERER_H_
|