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];
94 if (phrases_ !=
NULL) {
97 int start_con_idx = 0;
98 int current_phrase_limit = rtl ? con_comps[0]->Left() :
99 con_comps[0]->Right();
101 for (
int con_idx = 1; con_idx <= con_comp_cnt; con_idx++) {
102 bool create_new_phrase =
true;
105 if (con_idx < con_comp_cnt) {
108 dist = current_phrase_limit - con_comps[con_idx]->Right();
110 dist = con_comps[con_idx]->Left() - current_phrase_limit;
112 create_new_phrase = (dist > word_break_threshold);
116 if (create_new_phrase) {
120 CharSamp *phrase_char_samp =
122 con_idx - start_con_idx,
NULL,
123 &left_most, &right_most,
125 if (phrase_char_samp ==
NULL) {
128 phrases_[phrase_cnt_] =
new CubeObject(cntxt_, phrase_char_samp);
129 if (phrases_[phrase_cnt_] ==
NULL) {
130 delete phrase_char_samp;
137 start_con_idx = con_idx;
139 if (con_idx < con_comp_cnt) {
140 current_phrase_limit = rtl ? con_comps[con_idx]->Left() :
141 con_comps[con_idx]->Right();
146 current_phrase_limit =
MIN(current_phrase_limit,
147 con_comps[con_idx]->Left());
149 current_phrase_limit =
MAX(current_phrase_limit,
150 con_comps[con_idx]->Right());
159 for (
int con_idx = 0; con_idx < con_comp_cnt; con_idx++) {
160 delete con_comps[con_idx];
172 int CubeLineObject::ComputeWordBreakThreshold(
int con_comp_cnt,
173 ConComp **con_comps,
bool rtl) {
175 int word_break_threshold =
182 int start_con_idx = 0;
183 int current_phrase_limit = (rtl ? con_comps[0]->Left() :
184 con_comps[0]->Right());
185 int min_x = con_comps[0]->Left();
186 int max_x = con_comps[0]->Right();
187 int min_y = con_comps[0]->Top();
188 int max_y = con_comps[0]->Bottom();
190 for (
int con_idx = 1; con_idx <= con_comp_cnt; con_idx++) {
191 bool create_new_phrase =
true;
194 if (con_idx < con_comp_cnt) {
197 dist = current_phrase_limit - con_comps[con_idx]->Right();
199 dist = con_comps[con_idx]->Left() - current_phrase_limit;
201 create_new_phrase = (dist > word_break_threshold);
205 if (create_new_phrase) {
207 if ((max_x - min_x + 1) >
213 start_con_idx = con_idx;
215 if (con_idx < con_comp_cnt) {
216 current_phrase_limit = rtl ? con_comps[con_idx]->Left() :
217 con_comps[con_idx]->Right();
219 min_x = con_comps[con_idx]->Left();
220 max_x = con_comps[con_idx]->Right();
221 min_y = con_comps[con_idx]->Top();
222 max_y = con_comps[con_idx]->Bottom();
227 current_phrase_limit =
MIN(current_phrase_limit,
228 con_comps[con_idx]->Left());
230 current_phrase_limit =
MAX(current_phrase_limit,
231 con_comps[con_idx]->Right());
235 con_comps[con_idx]->Right(), &min_x, &max_x);
237 con_comps[con_idx]->Bottom(), &min_y, &max_y);
243 return word_break_threshold;
247 word_break_threshold--;
248 }
while (!valid && word_break_threshold > 0);
252 return static_cast<int>(line_pix_->h *
double MaxSpaceHeightRatio() const
ReadOrder ReadingOrder() const
static int Left2RightComparer(const void *comp1, const void *comp2)
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)
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
static int Right2LeftComparer(const void *comp1, const void *comp2)
CubeLineObject(CubeRecoContext *cntxt, Pix *pix)
TuningParams * Params() const
void SetCharSampOwnership(bool own_char_samp)
int MinConCompSize() const
double MaxWordAspectRatio() const
static CharSamp * CharSampleFromPix(Pix *pix, int left, int top, int wid, int hgt)