| /******************************************************************************* |
| * Copyright (c) 2010, 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.advanced; |
| |
| import java.util.Locale; |
| import org.eclipse.equinox.bidi.internal.StructuredTextActivator; |
| |
| /** |
| * Describes the environment within which structured text strings are |
| * processed. It includes: |
| * <ul> |
| * <li>locale,</li> |
| * <li>desired orientation,</li> |
| * <li>text mirroring attributes.</li> |
| * </ul> |
| */ |
| public class StructuredTextEnvironment { |
| |
| /** |
| * Specifies that a GUI component should display text Left-To-Right (value is 0). |
| */ |
| public static final int ORIENT_LTR = 0; |
| |
| /** |
| * Specifies that a GUI component should display text Right-To-Left (value is 1). |
| */ |
| public static final int ORIENT_RTL = 1; |
| |
| /** |
| * Specifies that a GUI component should display text depending on the context |
| * (value is 2). |
| */ |
| public static final int ORIENT_CONTEXTUAL = 1 << 1; |
| |
| /** |
| * Specifies that a GUI component should display text depending on the context |
| * with default orientation being Left-To-Right (value is 2). |
| */ |
| public static final int ORIENT_CONTEXTUAL_LTR = ORIENT_CONTEXTUAL | ORIENT_LTR; |
| |
| /** |
| * Specifies that a GUI component should display text depending on the context |
| * with default orientation being Right-To-Left (value is 3). |
| */ |
| public static final int ORIENT_CONTEXTUAL_RTL = ORIENT_CONTEXTUAL | ORIENT_RTL; |
| |
| /** |
| * Used when the orientation of a GUI component is not known (value is 4). |
| */ |
| public static final int ORIENT_UNKNOWN = 1 << 2; |
| |
| /** |
| * Used to specify that no directional formatting characters |
| * should be added as prefix or suffix (value is 8). |
| */ |
| public static final int ORIENT_IGNORE = 1 << 3; |
| |
| /** |
| * Pre-defined {@link StructuredTextEnvironment} instance which uses default locale, |
| * non-mirrored environment, and a Left-to-Right presentation component. |
| */ |
| public static final StructuredTextEnvironment DEFAULT = new StructuredTextEnvironment(null, false, ORIENT_LTR); |
| |
| /** |
| * This string is a 2-letters code representing a language as defined by |
| * ISO-639. |
| */ |
| final private String language; |
| |
| /** |
| * Flag specifying that structured text processed under this environment |
| * should assume that the GUI is mirrored (globally going from right to left). |
| */ |
| final private boolean mirrored; |
| |
| /** |
| * Specify the orientation (a.k.a. base direction) of the GUI |
| * component in which the <i>full</i> structured text will |
| * be displayed. |
| */ |
| final private int orientation; |
| |
| /** |
| * Cached value that determines if the Bidi processing is needed |
| * in this environment. |
| */ |
| private Boolean processingNeeded; |
| |
| /** |
| * Creates an instance of a structured text environment. |
| * |
| * @param lang the language of the environment, encoded as specified |
| * in ISO-639. Might be <code>null</code>, in which case the default |
| * locale is used. |
| * @param mirrored specifies if the environment is mirrored. |
| * @param orientation the orientation of the GUI component, one of the values: |
| * {@link #ORIENT_LTR ORIENT_LTR}, |
| * {@link #ORIENT_LTR ORIENT_RTL}, |
| * {@link #ORIENT_CONTEXTUAL_LTR ORIENT_CONTEXTUAL_LTR}, |
| * {@link #ORIENT_CONTEXTUAL_RTL ORIENT_CONTEXTUAL_RTL}, |
| * {@link #ORIENT_UNKNOWN ORIENT_UNKNOWN}, or |
| * {@link #ORIENT_IGNORE ORIENT_IGNORE}. |
| */ |
| public StructuredTextEnvironment(String lang, boolean mirrored, int orientation) { |
| if (lang != null) { |
| if (lang.length() > 2) |
| language = lang.substring(0, 2); |
| else |
| language = lang; |
| } else { |
| Locale defaultLocale = StructuredTextActivator.getInstance() != null ? StructuredTextActivator.getInstance().getDefaultLocale() : Locale.getDefault(); |
| language = defaultLocale.getLanguage(); |
| } |
| this.mirrored = mirrored; |
| this.orientation = orientation >= ORIENT_LTR && orientation <= ORIENT_IGNORE ? orientation : ORIENT_UNKNOWN; |
| } |
| |
| /** |
| * Returns a 2-letters code representing a language as defined by |
| * ISO-639. |
| * |
| * @return language of the environment |
| */ |
| public String getLanguage() { |
| return language; |
| } |
| |
| /** |
| * Returns a flag indicating that structured text processed |
| * within this environment should assume that the GUI is mirrored |
| * (globally going from right to left). |
| * |
| * @return <code>true</code> if environment is mirrored |
| */ |
| public boolean getMirrored() { |
| return mirrored; |
| } |
| |
| /** |
| * Returns the orientation (a.k.a. base direction) of the GUI |
| * component in which the <i>full</i> structured text |
| * will be displayed. |
| * <p> |
| * The orientation value is one of the following: |
| * </p> |
| * <ul> |
| * <li>{@link #ORIENT_LTR ORIENT_LTR},</li> |
| * <li>{@link #ORIENT_LTR ORIENT_RTL},</li> |
| * <li>{@link #ORIENT_CONTEXTUAL_LTR ORIENT_CONTEXTUAL_LTR},</li> |
| * <li>{@link #ORIENT_CONTEXTUAL_RTL ORIENT_CONTEXTUAL_RTL},</li> |
| * <li>{@link #ORIENT_UNKNOWN ORIENT_UNKNOWN}, or</li> |
| * <li>{@link #ORIENT_IGNORE ORIENT_IGNORE}</li> |
| * </ul> |
| */ |
| public int getOrientation() { |
| return orientation; |
| } |
| |
| /** |
| * Checks if bidi processing is needed in this environment. The result |
| * depends on the operating system (must be supported by this package) |
| * and on the language supplied when constructing the instance (it |
| * must be a language using a bidirectional script). |
| * <p> |
| * Note: This API is rarely used any more. E.g. in Eclipse/JFace, |
| * bidi support is typically controlled by the application via |
| * {@code org.eclipse.jface.util.BidiUtils#setBidiSupport(boolean)}. |
| * </p> |
| * |
| * @return <code>true</code> if bidi processing is needed in this environment. |
| * |
| * @deprecated let users control bidi processing independent of the locale |
| */ |
| public boolean isProcessingNeeded() { |
| if (processingNeeded == null) { |
| String osName = StructuredTextActivator.getProperty("os.name"); //$NON-NLS-1$/ |
| if (osName != null) |
| osName = osName.toLowerCase(); |
| boolean supportedOS = osName.startsWith("windows") || osName.startsWith("linux") || osName.startsWith("mac"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| if (supportedOS) { |
| // Check whether the current language uses a bidi script (Arabic, Hebrew, Farsi or Urdu) |
| boolean isBidi = "iw".equals(language) || //$NON-NLS-1$ |
| "he".equals(language) || //$NON-NLS-1$ |
| "ar".equals(language) || //$NON-NLS-1$ |
| "fa".equals(language) || //$NON-NLS-1$ |
| "ur".equals(language); //$NON-NLS-1$ |
| processingNeeded = Boolean.valueOf(isBidi); |
| } else { |
| processingNeeded = Boolean.FALSE; |
| } |
| } |
| return processingNeeded.booleanValue(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * Computes the hashCode based on the values supplied when constructing |
| * the instance and on the result of {@link #isProcessingNeeded()}. |
| * |
| * @return the hash code. |
| */ |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = 1; |
| result = prime * result + ((language == null) ? 0 : language.hashCode()); |
| result = prime * result + (mirrored ? 1231 : 1237); |
| result = prime * result + orientation; |
| result = prime * result + ((processingNeeded == null) ? 0 : processingNeeded.hashCode()); |
| return result; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * Compare 2 environment instances and returns true if both instances |
| * were constructed with the same arguments. |
| * |
| * @return true if the 2 instances can be used interchangeably. |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| if (obj == null) |
| return false; |
| if (getClass() != obj.getClass()) |
| return false; |
| StructuredTextEnvironment other = (StructuredTextEnvironment) obj; |
| if (language == null) { |
| if (other.language != null) |
| return false; |
| } else if (!language.equals(other.language)) |
| return false; |
| if (mirrored != other.mirrored) |
| return false; |
| if (orientation != other.orientation) |
| return false; |
| if (processingNeeded == null) { |
| if (other.processingNeeded != null) |
| return false; |
| } else if (!processingNeeded.equals(other.processingNeeded)) |
| return false; |
| return true; |
| } |
| |
| } |