Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 64e2c0b70c3d1aefeda33e96822e287505166a6c (plain) (blame)
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;
	}

}

Back to the top