| /******************************************************************************* |
| * Copyright (c) 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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 should be inserted |
| * in a source string. |
| */ |
| public class StructuredTextOffsets { |
| |
| 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; |
| |
| /** |
| * Default constructor |
| */ |
| public StructuredTextOffsets() { |
| } |
| |
| /** |
| * @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(StructuredTextCharTypes 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; |
| } |
| |
| } |