24 #include "allheaders.h"
35 in_minor_direction_ =
false;
36 at_beginning_of_minor_run_ =
false;
37 current_paragraph_is_ltr_ = CurrentParagraphIsLtr();
38 MoveToLogicalStartOfTextline();
47 return current_paragraph_is_ltr_;
50 bool ResultIterator::CurrentParagraphIsLtr()
const {
54 it.RestartParagraph();
80 num_rtl = leftmost_rtl ? 1 : 0;
88 num_ltr += rightmost_ltr ? 1 : 0;
100 return num_ltr >= num_rtl;
107 void ResultIterator::CalculateBlobOrder(
109 bool context_is_ltr = current_paragraph_is_ltr_ ^ in_minor_direction_;
110 blob_indices->
clear();
137 if (letter_types[i] == U_EURO_NUM && letter_types[i + 2] == U_EURO_NUM &&
138 (letter_types[i + 1] == U_EURO_NUM_SEP ||
139 letter_types[i + 1] == U_COMMON_NUM_SEP)) {
140 letter_types[i + 1] = U_EURO_NUM;
146 if (letter_types[i] == U_EURO_NUM_TERM) {
148 while (j < word_length_ && letter_types[j] == U_EURO_NUM_TERM) { j++; }
149 if (j < word_length_ && letter_types[j] == U_EURO_NUM) {
151 for (
int k = i; k < j; k++) letter_types[k] = U_EURO_NUM;
154 while (j > -1 && letter_types[j] == U_EURO_NUM_TERM) { j--; }
155 if (j > -1 && letter_types[j] == U_EURO_NUM) {
157 for (
int k = j; k <= i; k++) letter_types[k] = U_EURO_NUM;
165 int ti = letter_types[i];
166 if (ti == U_LTR || ti == U_EURO_NUM) {
170 int tj = letter_types[j];
171 if (tj == U_LTR || tj == U_EURO_NUM) {
173 }
else if (tj == U_COMMON_NUM_SEP || tj == U_OTHER_NEUTRAL) {
180 for (
int k = i; k <= last_good; k++) letter_types[k] = U_LTR;
183 letter_types[i] = U_RTL;
189 for (
int i = word_length_ - 1; i >= 0;) {
190 if (letter_types[i] == U_RTL) {
196 for (; j >= 0 && letter_types[j] != U_RTL; j--) { }
198 for (
int k = j + 1; k <= i; k++) blob_indices->
push_back(k);
206 for (
int i = 0; i < dirs.
size(); i++) {
219 bool paragraph_is_ltr,
220 const LTRResultIterator &resit,
227 bool paragraph_is_ltr,
228 const LTRResultIterator &resit,
233 directions = (dirs_arg !=
NULL) ? dirs_arg : &dirs;
241 directions->
push_back(ltr_it.WordDirection());
249 bool paragraph_is_ltr,
253 if (word_dirs.
size() == 0)
return;
257 int minor_direction, major_direction, major_step, start, end;
258 if (paragraph_is_ltr) {
260 end = word_dirs.
size();
265 start = word_dirs.
size() - 1;
274 int neutral_end = start;
275 while (neutral_end > 0 && word_dirs[neutral_end] ==
DIR_NEUTRAL) {
281 int left = neutral_end;
286 for (
int i = left; i < word_dirs.
size(); i++) {
295 for (
int i = start; i != end;) {
296 if (word_dirs[i] == minor_direction) {
298 while (j != end && word_dirs[j] != major_direction)
300 if (j == end) j -= major_step;
301 while (j != i && word_dirs[j] != minor_direction)
305 for (
int k = j; k != i; k -= major_step) {
319 int ResultIterator::LTRWordIndex()
const {
320 int this_word_index = 0;
322 textline.RestartRow();
323 while (!textline.PositionedAtSameWord(
it_)) {
327 return this_word_index;
330 void ResultIterator::MoveToLogicalStartOfWord() {
331 if (word_length_ == 0) {
336 CalculateBlobOrder(&blob_order);
337 if (blob_order.
size() == 0 || blob_order[0] == 0)
return;
341 bool ResultIterator::IsAtFinalSymbolOfWord()
const {
344 CalculateBlobOrder(&blob_order);
348 bool ResultIterator::IsAtFirstSymbolOfWord()
const {
351 CalculateBlobOrder(&blob_order);
355 void ResultIterator::AppendSuffixMarks(
STRING *text)
const {
357 bool reading_direction_is_ltr =
358 current_paragraph_is_ltr_ ^ in_minor_direction_;
366 *
this, &textline_order);
367 int this_word_index = LTRWordIndex();
368 int i = textline_order.
get_index(this_word_index);
371 int last_non_word_mark = 0;
372 for (i++; i < textline_order.
size() && textline_order[i] < 0; i++) {
373 last_non_word_mark = textline_order[i];
376 *text += reading_direction_is_ltr ?
kLRM :
kRLM;
378 if (current_paragraph_is_ltr_) {
388 void ResultIterator::MoveToLogicalStartOfTextline() {
392 dynamic_cast<const LTRResultIterator&>(*
this),
395 for (; i < word_indices.
size() && word_indices[i] < 0; i++) {
396 if (word_indices[i] ==
kMinorRunStart) in_minor_direction_ =
true;
397 else if (word_indices[i] ==
kMinorRunEnd) in_minor_direction_ =
false;
399 if (in_minor_direction_) at_beginning_of_minor_run_ =
true;
400 if (i >= word_indices.
size())
return;
401 int first_word_index = word_indices[i];
402 for (
int j = 0; j < first_word_index; j++) {
405 MoveToLogicalStartOfWord();
410 current_paragraph_is_ltr_ = CurrentParagraphIsLtr();
411 in_minor_direction_ =
false;
412 at_beginning_of_minor_run_ =
false;
413 MoveToLogicalStartOfTextline();
426 current_paragraph_is_ltr_ = CurrentParagraphIsLtr();
428 in_minor_direction_ =
false;
429 MoveToLogicalStartOfTextline();
434 CalculateBlobOrder(&blob_order);
436 while (next_blob < blob_order.
size() &&
440 if (next_blob < blob_order.
size()) {
443 at_beginning_of_minor_run_ =
false;
452 int this_word_index = LTRWordIndex();
456 int final_real_index = word_indices.
size() - 1;
457 while (final_real_index > 0 && word_indices[final_real_index] < 0)
459 for (
int i = 0; i < final_real_index; i++) {
460 if (word_indices[i] == this_word_index) {
462 for (; j < final_real_index && word_indices[j] < 0; j++) {
463 if (word_indices[j] ==
kMinorRunStart) in_minor_direction_ =
true;
464 if (word_indices[j] ==
kMinorRunEnd) in_minor_direction_ =
false;
466 at_beginning_of_minor_run_ = (word_indices[j - 1] ==
kMinorRunStart);
469 tprintf(
"Next(RIL_WORD): %d -> %d\n",
470 this_word_index, word_indices[j]);
473 for (
int k = 0; k < word_indices[j]; k++) {
476 MoveToLogicalStartOfWord();
481 tprintf(
"Next(RIL_WORD): %d -> EOL\n", this_word_index);
496 bool at_word_start = IsAtFirstSymbolOfWord();
497 if (level ==
RIL_WORD)
return at_word_start;
501 line_start.MoveToLogicalStartOfTextline();
503 bool at_textline_start = at_word_start && *line_start.
it_ == *
it_;
508 bool at_block_start = at_textline_start &&
510 if (level ==
RIL_BLOCK)
return at_block_start;
512 bool at_para_start = at_block_start ||
513 (at_textline_start &&
516 if (level ==
RIL_PARA)
return at_para_start;
529 if (
Empty(element))
return true;
538 if (next.
Empty(element))
return true;
539 while (element > level) {
559 pp.AppendUTF8ParagraphText(&text);
564 AppendUTF8ParagraphText(&text);
569 it.MoveToLogicalStartOfTextline();
570 it.IterateAndAppendUTF8TextlineText(&text);
574 AppendUTF8WordText(&text);
578 bool reading_direction_is_ltr =
579 current_paragraph_is_ltr_ ^ in_minor_direction_;
580 if (at_beginning_of_minor_run_) {
581 text += reading_direction_is_ltr ?
kLRM :
kRLM;
584 if (IsAtFinalSymbolOfWord()) AppendSuffixMarks(&text);
588 int length = text.
length() + 1;
589 char* result =
new char[length];
590 strncpy(result, text.
string(), length);
594 void ResultIterator::AppendUTF8WordText(
STRING *text)
const {
597 bool reading_direction_is_ltr =
598 current_paragraph_is_ltr_ ^ in_minor_direction_;
599 if (at_beginning_of_minor_run_) {
600 *text += reading_direction_is_ltr ?
kLRM :
kRLM;
604 CalculateBlobOrder(&blob_order);
605 for (
int i = 0; i < blob_order.
size(); i++) {
606 *text +=
it_->
word()->
BestUTF8(blob_order[i], !reading_direction_is_ltr);
608 AppendSuffixMarks(text);
611 void ResultIterator::IterateAndAppendUTF8TextlineText(
STRING *text) {
620 *
this, &dirs, &textline_order);
622 current_paragraph_is_ltr_ ?
"ltr" :
"rtl");
623 PrintScriptDirs(dirs);
625 current_paragraph_is_ltr_ ?
"ltr" :
"rtl");
626 for (
int i = 0; i < textline_order.
size(); i++) {
627 tprintf(
"%d ", textline_order[i]);
632 int words_appended = 0;
634 AppendUTF8WordText(text);
639 tprintf(
"%d words printed\n", words_appended);
648 void ResultIterator::AppendUTF8ParagraphText(
STRING *text)
const {
650 it.RestartParagraph();
651 it.MoveToLogicalStartOfTextline();
654 it.IterateAndAppendUTF8TextlineText(text);
655 }
while (it.it_->block() !=
NULL && !it.IsAtBeginningOf(
RIL_PARA));
658 bool ResultIterator::BidiDebug(
int min_level)
const {
660 IntParam *p = ParamUtils::FindParam<IntParam>(
663 if (p !=
NULL) debug_level = (
inT32)(*p);
664 return debug_level >= min_level;