Skip to content

Commit a74a5b3

Browse files
committed
unicode/bidi: fix Direction zero value to Neutral
The Direction constants had LeftToRight as iota (value 0), making it indistinguishable from the zero value of an unset Direction field. This caused DefaultDirection(LeftToRight) to be silently ignored in Paragraph.Order(), as the code could not distinguish between "user explicitly set LTR" and "no direction was set." Reorder the Direction constants so that Neutral is the zero value, and add an explicit case for LeftToRight in Order() to set the paragraph embedding level to 0. Fixes golang/go#71809
1 parent 7ca2c6d commit a74a5b3

2 files changed

Lines changed: 41 additions & 6 deletions

File tree

unicode/bidi/bidi.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ import (
2929
type Direction int
3030

3131
const (
32+
// Neutral means that text contains no left-to-right and right-to-left
33+
// characters and that no default direction has been set.
34+
Neutral Direction = iota
35+
3236
// LeftToRight indicates the text contains no right-to-left characters and
3337
// that either there are some left-to-right characters or the option
3438
// DefaultDirection(LeftToRight) was passed.
35-
LeftToRight Direction = iota
39+
LeftToRight
3640

3741
// RightToLeft indicates the text contains no left-to-right characters and
3842
// that either there are some right-to-left characters or the option
@@ -42,10 +46,6 @@ const (
4246
// Mixed indicates text contains both left-to-right and right-to-left
4347
// characters.
4448
Mixed
45-
46-
// Neutral means that text contains no left-to-right and right-to-left
47-
// characters and that no default direction has been set.
48-
Neutral
4949
)
5050

5151
type options struct {
@@ -219,8 +219,11 @@ func (p *Paragraph) Order() (Ordering, error) {
219219
fn(&p.options)
220220
}
221221
lvl := level(-1)
222-
if p.options.defaultDirection == RightToLeft {
222+
switch p.options.defaultDirection {
223+
case RightToLeft:
223224
lvl = 1
225+
case LeftToRight:
226+
lvl = 0
224227
}
225228
para, err := newParagraph(p.types, p.pairTypes, p.pairValues, lvl)
226229
if err != nil {

unicode/bidi/bidi_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,38 @@ func TestMixedSimple(t *testing.T) {
254254
}
255255
}
256256

257+
func TestDirectionLTR(t *testing.T) {
258+
str := "ع a"
259+
p := Paragraph{}
260+
p.SetString(str, DefaultDirection(LeftToRight))
261+
order, err := p.Order()
262+
if err != nil {
263+
log.Fatal(err)
264+
}
265+
266+
expectedRuns := []runInformation{
267+
{"ع", RightToLeft, 0, 0},
268+
{" a", LeftToRight, 1, 2},
269+
}
270+
271+
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
272+
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
273+
}
274+
275+
for i, want := range expectedRuns {
276+
r := order.Run(i)
277+
if got := r.String(); got != want.str {
278+
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
279+
}
280+
if s, e := r.Pos(); s != want.start || e != want.end {
281+
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
282+
}
283+
if d := r.Direction(); d != want.dir {
284+
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
285+
}
286+
}
287+
}
288+
257289
func TestDefaultDirection(t *testing.T) {
258290
str := "+"
259291
p := Paragraph{}

0 commit comments

Comments
 (0)