blob: 3b749bb4939db65f49181987adc258e7d1227586 [file] [log] [blame]
/*******************************************************************************
* 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:
* <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>
* </p>
*/
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.
*/
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.
*/
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;
}
}