3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
15 #include "BufferView.h"
20 #include "Paragraph.h"
26 pos_type
Bidi::log2vis(pos_type pos
) const
28 return (start_
== -1) ? pos
: log2vis_list_
[pos
- start_
];
32 pos_type
Bidi::vis2log(pos_type pos
) const
34 return (start_
== -1) ? pos
: vis2log_list_
[pos
- start_
];
38 pos_type
Bidi::level(pos_type pos
) const
40 return (start_
== -1) ? 0 : levels_
[pos
- start_
];
44 bool Bidi::inRange(pos_type pos
) const
46 return start_
== -1 || (start_
<= pos
&& pos
<= end_
);
49 bool Bidi::same_direction() const
51 return same_direction_
;
55 void Bidi::computeTables(Paragraph
const & par
,
56 Buffer
const & buf
, Row
const & row
)
58 same_direction_
= true;
59 if (!lyxrc
.rtl_support
) {
64 if (par
.inInset().forceLTR()) {
70 end_
= row
.endpos() - 1;
77 if (end_
+ 2 - start_
>
78 static_cast<pos_type
>(log2vis_list_
.size())) {
80 (end_
+ 2 - start_
< 500) ?
81 500 : 2 * (end_
+ 2 - start_
);
82 log2vis_list_
.resize(new_size
);
83 vis2log_list_
.resize(new_size
);
84 levels_
.resize(new_size
);
87 vis2log_list_
[end_
+ 1 - start_
] = -1;
88 log2vis_list_
[end_
+ 1 - start_
] = -1;
90 BufferParams
const & bufparams
= buf
.params();
92 bool const rtl_par
= par
.isRTL(bufparams
);
96 pos_type
const body_pos
= par
.beginOfBody();
98 for (pos_type lpos
= start_
; lpos
<= end_
; ++lpos
) {
99 bool is_space
= false;
100 // We do not handle spaces around an RTL segment in a special way anymore.
101 // Neither do we do so when generating the LaTeX, so setting is_space
102 // to false makes the view in the GUI consistent with the output of LaTeX
103 // later. The old setting was:
104 //bool is_space = par.isLineSeparator(lpos);
105 // FIXME: once we're sure that this is what we really want, we should just
106 // get rid of this variable...
108 (is_space
&& lpos
+ 1 <= end_
&&
109 !par
.isLineSeparator(lpos
+ 1) &&
110 !par
.isNewline(lpos
+ 1))
113 Font
const * font
= &(par
.getFontSettings(bufparams
, pos
));
114 if (pos
!= lpos
&& 0 < lpos
&& rtl0
&& font
->isRightToLeft() &&
115 font
->fontInfo().number() == FONT_ON
&&
116 par
.getFontSettings(bufparams
, lpos
- 1).fontInfo().number()
118 font
= &(par
.getFontSettings(bufparams
, lpos
));
121 bool new_rtl
= font
->isVisibleRightToLeft();
122 bool new_rtl0
= font
->isRightToLeft();
126 if (lpos
== body_pos
- 1
127 && row
.pos() < body_pos
- 1
129 new_level
= rtl_par
? 1 : 0;
132 } else if (new_rtl0
) {
133 new_level
= new_rtl
? 1 : 2;
135 new_level
= rtl_par
? 2 : 0;
138 if (is_space
&& new_level
>= lev
) {
144 int new_level2
= new_level
;
146 if (lev
== new_level
&& rtl0
!= new_rtl0
) {
148 log2vis_list_
[lpos
- start_
] = rtl
? 1 : -1;
149 } else if (lev
< new_level
) {
150 log2vis_list_
[lpos
- start_
] = rtl
? -1 : 1;
151 if (new_level
> 0 && !rtl_par
)
152 same_direction_
= false;
154 log2vis_list_
[lpos
- start_
] = new_rtl
? -1 : 1;
158 levels_
[lpos
- start_
] = new_level
;
160 while (lev
> new_level2
) {
161 pos_type old_lpos
= stack
[--lev
];
162 int delta
= lpos
- old_lpos
- 1;
165 log2vis_list_
[lpos
- start_
] += delta
;
166 log2vis_list_
[old_lpos
- start_
] += delta
;
168 while (lev
< new_level
)
173 pos_type
const old_lpos
= stack
[--lev
];
174 int delta
= end_
- old_lpos
;
177 log2vis_list_
[old_lpos
- start_
] += delta
;
180 pos_type vpos
= start_
- 1;
181 for (pos_type lpos
= start_
; lpos
<= end_
; ++lpos
) {
182 vpos
+= log2vis_list_
[lpos
- start_
];
183 vis2log_list_
[vpos
- start_
] = lpos
;
184 log2vis_list_
[lpos
- start_
] = vpos
;
189 // This method requires a previous call to computeTables()
190 bool Bidi::isBoundary(Buffer
const & buf
, Paragraph
const & par
,
193 if (!lyxrc
.rtl_support
|| pos
== 0)
196 if (!inRange(pos
- 1)) {
197 // This can happen if pos is the first char of a row.
198 // Returning false in this case is incorrect!
202 bool const rtl
= level(pos
- 1) % 2;
203 bool const rtl2
= inRange(pos
)
205 : par
.isRTL(buf
.params());
210 bool Bidi::isBoundary(Buffer
const & buf
, Paragraph
const & par
,
211 pos_type pos
, Font
const & font
) const
213 if (!lyxrc
.rtl_support
)
214 return false; // This is just for speedup
216 bool const rtl
= font
.isVisibleRightToLeft();
217 bool const rtl2
= inRange(pos
)
219 : par
.isRTL(buf
.params());
224 bool reverseDirectionNeeded(Cursor
const & cur
)
227 * We determine the directions based on the direction of the
228 * bottom() --- i.e., outermost --- paragraph, because that is
229 * the only way to achieve consistency of the arrow's movements
230 * within a paragraph, and thus avoid situations in which the
233 return cur
.bottom().paragraph().isRTL(cur
.bv().buffer().params());
237 bool isWithinRtlParagraph(Cursor
const & cur
)
239 return cur
.innerParagraph().isRTL(cur
.bv().buffer().params());