1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.equinox.bidi.custom;
/**
* Provides various services related to managing the array of
* offsets where directional formatting characters will be inserted.
*
* @author Matitiahu Allouche
*
*/
public class STextOffsets {
private static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT;
private static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
private static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
private static final byte AN = Character.DIRECTIONALITY_ARABIC_NUMBER;
private static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
private static final byte[] STRONGS = {L, R};
private static final int OFFSET_SIZE = 20;
private int[] offsets = new int[OFFSET_SIZE];
private int count; // number of used entries
private int direction = -1; // STT direction
private int prefixLength;
/**
* @return the stored prefix length
*/
public int getPrefixLength() {
return prefixLength;
}
/**
* Stores the prefix length
*
* @param prefLen value assigned to the prefix length
*/
public void setPrefixLength(int prefLen) {
prefixLength = prefLen;
}
/**
* Gets the number of used entries in the offsets array.
*
* @return the number of used entries in the offsets array.
*/
public int getCount() {
return count;
}
/**
* Marks that all entries in the offsets array are unused.
*/
public void clear() {
count = 0;
}
/**
* Gets the value of a specified entry in the offsets array.
*
* @param index the index of the entry of interest.
*
* @return the value of the specified entry.
*/
public int getOffset(int index) {
return offsets[index];
}
/**
* Inserts an offset value in the offset array so that the array
* stays in ascending order.
*
* @param charTypes an object whose methods can be useful to the
* handler.
*
* @param offset the value to insert.
*/
public void insertOffset(STextCharTypes charTypes, int offset) {
if (count >= offsets.length) {
int[] newOffsets = new int[offsets.length * 2];
System.arraycopy(offsets, 0, newOffsets, 0, count);
offsets = newOffsets;
}
int index = count - 1; // index of greatest member <= offset
// look up after which member the new offset should be inserted
while (index >= 0) {
int wrkOffset = offsets[index];
if (offset > wrkOffset)
break;
if (offset == wrkOffset)
return; // avoid duplicates
index--;
}
index++; // index now points at where to insert
int length = count - index; // number of members to move up
if (length > 0) // shift right all members greater than offset
System.arraycopy(offsets, index, offsets, index + 1, length);
offsets[index] = offset;
count++; // number of used entries
// if the offset is 0, adding a mark does not change anything
if (offset < 1)
return;
if (charTypes == null)
return;
byte charType = charTypes.getBidiTypeAt(offset);
// if the current char is a strong one or a digit, we change the
// charType of the previous char to account for the inserted mark.
if (charType == L || charType == R || charType == AL || charType == EN || charType == AN)
index = offset - 1;
else
// if the current char is a neutral, we change its own charType
index = offset;
if (direction < 0)
direction = charTypes.getDirection();
charTypes.setBidiTypeAt(index, STRONGS[direction]);
return;
}
/**
* Gets all and only the used offset entries.
*
* @return the current used entries of the offsets array.
*/
public int[] getOffsets() {
if (count == offsets.length)
return offsets;
int[] array = new int[count];
System.arraycopy(offsets, 0, array, 0, count);
return array;
}
}
|