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
.ownerCode() == ERT_CODE
|| par
.ownerCode() == LISTINGS_CODE
) {
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))
112 Font font
= par
.getFontSettings(bufparams
, pos
);
113 if (pos
!= lpos
&& 0 < lpos
&& rtl0
&& font
.isRightToLeft() &&
114 font
.fontInfo().number() == FONT_ON
&&
115 par
.getFontSettings(bufparams
, lpos
- 1).fontInfo().number()
117 font
= par
.getFontSettings(bufparams
, lpos
);
121 bool new_rtl
= font
.isVisibleRightToLeft();
122 bool new_rtl0
= font
.isRightToLeft();
125 if (lpos
== body_pos
- 1
126 && row
.pos() < body_pos
- 1
128 new_level
= rtl_par
? 1 : 0;
131 } else if (new_rtl0
) {
132 new_level
= new_rtl
? 1 : 2;
134 new_level
= rtl_par
? 2 : 0;
137 if (is_space
&& new_level
>= lev
) {
143 int new_level2
= new_level
;
145 if (lev
== new_level
&& rtl0
!= new_rtl0
) {
147 log2vis_list_
[lpos
- start_
] = rtl
? 1 : -1;
148 } else if (lev
< new_level
) {
149 log2vis_list_
[lpos
- start_
] = rtl
? -1 : 1;
150 if (new_level
> 0 && !rtl_par
)
151 same_direction_
= false;
153 log2vis_list_
[lpos
- start_
] = new_rtl
? -1 : 1;
157 levels_
[lpos
- start_
] = new_level
;
159 while (lev
> new_level2
) {
160 pos_type old_lpos
= stack
[--lev
];
161 int delta
= lpos
- old_lpos
- 1;
164 log2vis_list_
[lpos
- start_
] += delta
;
165 log2vis_list_
[old_lpos
- start_
] += delta
;
167 while (lev
< new_level
)
172 pos_type
const old_lpos
= stack
[--lev
];
173 int delta
= end_
- old_lpos
;
176 log2vis_list_
[old_lpos
- start_
] += delta
;
179 pos_type vpos
= start_
- 1;
180 for (pos_type lpos
= start_
; lpos
<= end_
; ++lpos
) {
181 vpos
+= log2vis_list_
[lpos
- start_
];
182 vis2log_list_
[vpos
- start_
] = lpos
;
183 log2vis_list_
[lpos
- start_
] = vpos
;
188 // This method requires a previous call to computeTables()
189 bool Bidi::isBoundary(Buffer
const & buf
, Paragraph
const & par
,
192 if (!lyxrc
.rtl_support
|| pos
== 0)
195 if (!inRange(pos
- 1)) {
196 // This can happen if pos is the first char of a row.
197 // Returning false in this case is incorrect!
201 bool const rtl
= level(pos
- 1) % 2;
202 bool const rtl2
= inRange(pos
)
204 : par
.isRTL(buf
.params());
209 bool Bidi::isBoundary(Buffer
const & buf
, Paragraph
const & par
,
210 pos_type pos
, Font
const & font
) const
212 if (!lyxrc
.rtl_support
)
213 return false; // This is just for speedup
215 bool const rtl
= font
.isVisibleRightToLeft();
216 bool const rtl2
= inRange(pos
)
218 : par
.isRTL(buf
.params());
223 bool reverseDirectionNeeded(Cursor
const & cur
)
226 * We determine the directions based on the direction of the
227 * bottom() --- i.e., outermost --- paragraph, because that is
228 * the only way to achieve consistency of the arrow's movements
229 * within a paragraph, and thus avoid situations in which the
232 return cur
.bottom().paragraph().isRTL(cur
.bv().buffer().params());
236 bool isWithinRtlParagraph(Cursor
const & cur
)
238 return cur
.innerParagraph().isRTL(cur
.bv().buffer().params());