34 if (line_pix_ != NULL && own_pix_ ==
true) {
35 pixDestroy(&line_pix_);
39 if (phrases_ != NULL) {
40 for (
int phrase_idx = 0; phrase_idx < phrase_cnt_; phrase_idx++) {
41 if (phrases_[phrase_idx] != NULL) {
42 delete phrases_[phrase_idx];
52 bool CubeLineObject::Process() {
59 if (line_pix_ == NULL || cntxt_ == NULL) {
67 if (char_samp == NULL) {
73 ConComp **con_comps = char_samp->FindConComps(&con_comp_cnt,
78 if (con_comp_cnt <= 0 || con_comps == NULL) {
84 qsort(con_comps, con_comp_cnt,
sizeof(*con_comps), rtl ?
89 int word_break_threshold = ComputeWordBreakThreshold(con_comp_cnt, con_comps,
91 if (word_break_threshold > 0) {
93 phrases_ =
new CubeObject *[con_comp_cnt];
96 int start_con_idx = 0;
97 int current_phrase_limit = rtl ? con_comps[0]->Left() :
98 con_comps[0]->Right();
100 for (
int con_idx = 1; con_idx <= con_comp_cnt; con_idx++) {
101 bool create_new_phrase =
true;
104 if (con_idx < con_comp_cnt) {
107 dist = current_phrase_limit - con_comps[con_idx]->Right();
109 dist = con_comps[con_idx]->Left() - current_phrase_limit;
111 create_new_phrase = (dist > word_break_threshold);
115 if (create_new_phrase) {
119 CharSamp *phrase_char_samp =
121 con_idx - start_con_idx, NULL,
122 &left_most, &right_most,
124 if (phrase_char_samp == NULL) {
127 phrases_[phrase_cnt_] =
new CubeObject(cntxt_, phrase_char_samp);
132 start_con_idx = con_idx;
134 if (con_idx < con_comp_cnt) {
135 current_phrase_limit = rtl ? con_comps[con_idx]->Left() :
136 con_comps[con_idx]->Right();
141 current_phrase_limit =
MIN(current_phrase_limit,
142 con_comps[con_idx]->Left());
144 current_phrase_limit =
MAX(current_phrase_limit,
145 con_comps[con_idx]->Right());
153 for (
int con_idx = 0; con_idx < con_comp_cnt; con_idx++) {
154 delete con_comps[con_idx];
166 int CubeLineObject::ComputeWordBreakThreshold(
int con_comp_cnt,
167 ConComp **con_comps,
bool rtl) {
169 int word_break_threshold =
176 int start_con_idx = 0;
177 int current_phrase_limit = (rtl ? con_comps[0]->Left() :
178 con_comps[0]->Right());
179 int min_x = con_comps[0]->Left();
180 int max_x = con_comps[0]->Right();
181 int min_y = con_comps[0]->Top();
182 int max_y = con_comps[0]->Bottom();
184 for (
int con_idx = 1; con_idx <= con_comp_cnt; con_idx++) {
185 bool create_new_phrase =
true;
188 if (con_idx < con_comp_cnt) {
191 dist = current_phrase_limit - con_comps[con_idx]->Right();
193 dist = con_comps[con_idx]->Left() - current_phrase_limit;
195 create_new_phrase = (dist > word_break_threshold);
199 if (create_new_phrase) {
201 if ((max_x - min_x + 1) >
207 start_con_idx = con_idx;
209 if (con_idx < con_comp_cnt) {
210 current_phrase_limit = rtl ? con_comps[con_idx]->Left() :
211 con_comps[con_idx]->Right();
213 min_x = con_comps[con_idx]->Left();
214 max_x = con_comps[con_idx]->Right();
215 min_y = con_comps[con_idx]->Top();
216 max_y = con_comps[con_idx]->Bottom();
221 current_phrase_limit =
MIN(current_phrase_limit,
222 con_comps[con_idx]->Left());
224 current_phrase_limit =
MAX(current_phrase_limit,
225 con_comps[con_idx]->Right());
229 con_comps[con_idx]->Right(), &min_x, &max_x);
231 con_comps[con_idx]->Bottom(), &min_y, &max_y);
237 return word_break_threshold;
241 word_break_threshold--;
242 }
while (!valid && word_break_threshold > 0);
246 return static_cast<int>(line_pix_->h *
double MaxSpaceHeightRatio() const
static int Right2LeftComparer(const void *comp1, const void *comp2)
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
ReadOrder ReadingOrder() const
TuningParams * Params() const
double MaxWordAspectRatio() const
void SetCharSampOwnership(bool own_char_samp)
CubeLineObject(CubeRecoContext *cntxt, Pix *pix)
static CharSamp * FromConComps(ConComp **concomp_array, int strt_concomp, int seg_flags_size, int *seg_flags, bool *left_most, bool *right_most, int word_hgt)
int MinConCompSize() const
static int Left2RightComparer(const void *comp1, const void *comp2)
static CharSamp * CharSampleFromPix(Pix *pix, int left, int top, int wid, int hgt)