Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 200742 Details for
Bug 183164
[Implementation for] Display of Complex Expressions Containing Bidirectional Text
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Change STextEngine to STextHandler which can be instantiated
patch_bidi_20110802.txt (text/plain), 137.39 KB, created by
Matitiahu Allouche
on 2011-08-02 11:55:06 EDT
(
hide
)
Description:
Change STextEngine to STextHandler which can be instantiated
Filename:
MIME Type:
Creator:
Matitiahu Allouche
Created:
2011-08-02 11:55:06 EDT
Size:
137.39 KB
patch
obsolete
>diff --git src/org/eclipse/equinox/bidi/STextEngine.java src/org/eclipse/equinox/bidi/STextEngine.java >deleted file mode 100644 >index 0bc0021..0000000 100644 >--- src/org/eclipse/equinox/bidi/STextEngine.java >+++ /dev/null >@@ -1,318 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2010, 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; >- >-import org.eclipse.equinox.bidi.custom.STextProcessor; >-import org.eclipse.equinox.bidi.internal.STextImpl; >- >-/** >- * For a general introduction to structured text, see >- * {@link <a href="package-summary.html"> the package documentation</a>}. >- * <p> >- * Several common processors are included in <b>STextEngine</b>. For processors >- * supplied by other packages, a processor instance can be obtained using the >- * {@link org.eclipse.equinox.bidi.STextProcessorFactory#getProcessor} >- * method for the registered processors, or by instantiating a private processor. >- * </p><p> >- * Most of the methods in this class have a <code>text</code> >- * argument which may be just a part of a larger body of text. >- * When it is the case that the text is submitted in parts with >- * repeated calls, there may be a need to pass information from >- * one invocation to the next one. For instance, one invocation >- * may detect that a comment or a literal has been started but >- * has not been completed. In such cases, a <code>state</code> >- * argument must be used. >- * </p><p> >- * The <code>state</code> argument must be an array of integers >- * with at least one element. Only the first element is used by >- * the methods of this class. >- * </p><p> >- * When submitting the initial part of the text, the first element >- * of <code>state</code> must contain the value {@link #STATE_INITIAL} >- * or any value <= 0. >- * </p><p> >- * After calling a method with a non-null <code>state</code> argument, >- * a value is returned in the first element of <code>state</code>. This >- * value should be passed unmodified to the method when calling it again >- * with the text which is the continuation of the text submitted in the >- * last call. >- * </p><p> >- * When the text submitted to a method is not a continuation and is not >- * expected to have a continuation , e.g. it is processed all by itself, >- * the <code>state</code> argument should be specified as <code>null</code>. >- * </p><p> >- * <b>Code Samples</b> >- * </p><p> >- * The following code shows how to transform a certain type of structured text >- * (directory and file paths) in order to obtain the <i>full</i> >- * text corresponding to the given <i>lean</i> text. >- * <pre> >- * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; >- * String fullText = STextEngine.leanToFullText(STextEngine.PROC_FILE, null, leanText, null); >- * System.out.println("full text = " + fullText); >- * </pre> >- * </p><p> >- * The following code shows how to transform successive lines of Java >- * code in order to obtain the <i>full</i> >- * text corresponding to the <i>lean</i> text of each line. >- * <pre> >- * int[] state = new int[1]; >- * state[0] = STextEngine.STATE_INITIAL; >- * String leanText = "int i = 3; // first Java statement"; >- * String fullText = STextEngine.leanToFullText(STextEngine.PROC_JAVA, null, leanText, state); >- * System.out.println("full text = " + fullText); >- * leanText = "i += 4; // next Java statement"; >- * fullText = STextEngine.leanToFullText(STextEngine.PROC_JAVA, null, leanText, state); >- * System.out.println("full text = " + fullText); >- * </pre> >- * </p> >- * @author Matitiahu Allouche >- * >- */ >-public class STextEngine { >- >- /** >- * Constant specifying that the base direction of a structured text is LTR. >- * The base direction may depend on whether the GUI is >- * {@link STextEnvironment#getMirrored mirrored} and may >- * may be different for Arabic and for Hebrew. >- * This constant can appear as value returned by the >- * {@link #getCurDirection getCurDirection} method. >- */ >- public static final int DIR_LTR = 0; >- >- /** >- * Constant specifying that the base direction of a structured text is RTL. >- * The base direction may depend on whether the GUI is >- * {@link STextEnvironment#getMirrored mirrored} and may >- * may be different for Arabic and for Hebrew. >- * This constant can appear as value returned by the >- * {@link #getCurDirection getCurDirection} method. >- */ >- public static final int DIR_RTL = 1; >- >- /** >- * Constant to use in the first element of the <code>state</code> >- * argument when calling most methods of this class >- * to indicate that there is no context of previous lines which >- * should be initialized before performing the operation. >- */ >- public static final int STATE_INITIAL = 0; >- >- private static final int[] EMPTY_INT_ARRAY = new int[0]; >- >- /** >- * Prevent creation of a STextEngine instance >- */ >- private STextEngine() { >- // nothing to do >- } >- >- /** >- * Add directional formatting characters to a structured text >- * to ensure correct presentation. >- * >- * @param processor the processor applicable to the text. If <code>null</code>, >- * the method returns unmodified text. >- * >- * @param environment a bidi environment. If <code>null</code>, the default environment >- * is used. >- * >- * @param text is the structured text string >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return the structured text with directional formatting characters added to ensure >- * correct presentation. >- */ >- public static String leanToFullText(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) >- return text; >- return STextImpl.leanToFullText(processor, environment, text, state); >- } >- >- /** >- * Given a <i>lean</i> string, compute the positions of each of its >- * characters within the corresponding <i>full</i> string. >- * >- * @param processor designates a processor instance. If <code>null</code>, this >- * method returns an identity map. >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string. >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return an array which specifies offsets of the <code>text</code> characters >- * in the <i>full</i> string >- */ >- public static int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) { >- int[] map = new int[text.length()]; >- for (int i = 0; i < map.length; i++) >- map[i] = i; >- return map; >- } >- return STextImpl.leanToFullMap(processor, environment, text, state); >- } >- >- /** >- * Given a <i>lean</i> string, compute the offsets of characters >- * before which directional formatting characters must be added >- * in order to ensure correct presentation. >- * <p> >- * Only LRMs (for a string with LTR base direction) and RLMs (for >- * a string with RTL base direction) are considered. Leading and >- * trailing LRE, RLE and PDF which might be prefixed or suffixed >- * depending on the {@link STextEnvironment#getOrientation orientation} of the >- * GUI component used for display are not reflected in this method. >- * </p> >- * @param processor designates a processor instance >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return an array of offsets to the characters in the <code>text</code> argument >- * before which directional marks must be added to ensure correct presentation. >- * The offsets are sorted in ascending order. >- */ >- public static int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) >- return EMPTY_INT_ARRAY; >- return STextImpl.leanBidiCharOffsets(processor, environment, text, state); >- } >- >- /** >- * Remove directional formatting characters which were added to a >- * structured text string to ensure correct presentation. >- * >- * @param processor designates a processor instance >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string including directional formatting characters. >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return the structured text string without directional formatting characters >- * which might have been added by processing it with {@link #leanToFullText}. >- * >- */ >- public static String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) >- return text; >- return STextImpl.fullToLeanText(processor, environment, text, state); >- } >- >- /** >- * Given a <i>full</i> string, compute the positions of each of its >- * characters within the corresponding <i>lean</i> string. >- * >- * @param processor designates a processor instance >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string including directional formatting characters. >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return an array of integers with one element for each of the characters >- * in the <code>text</code> argument, equal to the offset of the corresponding character >- * in the <i>lean</i> string. If there is no corresponding character in the <i>lean</i> string >- * (because the specified character is a directional formatting character added when invoking >- * {@link #leanToFullText}), the value returned for this character is -1. >- */ >- public static int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) { >- int[] map = new int[text.length()]; >- for (int i = 0; i < map.length; i++) >- map[i] = i; >- return map; >- } >- return STextImpl.fullToLeanMap(processor, environment, text, state); >- } >- >- /** >- * Given a <i>full</i> string, return the offsets of characters >- * which are directional formatting characters that have been added >- * in order to ensure correct presentation. >- * <p> >- * LRMs (for a string with LTR base direction), RLMs (for a string with RTL base direction) >- * are considered as well as leading and trailing LRE, RLE and PDF which might be prefixed >- * or suffixed depending on the {@link STextEnvironment#getOrientation orientation} >- * of the GUI component used for display. >- * </p> >- * @param processor designates a processor instance >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string including directional formatting characters >- * >- * @param state can be used to specify that the <code>text</code> argument is >- * the continuation of text submitted in a previous call and/or to receive information >- * to pass to continuation calls. If all calls to this method are independent from one another, >- * this argument should be specified as <code>null</code>. >- * >- * @return an array of offsets to the characters in the <code>text</code> argument which >- * are directional formatting characters added to ensure correct presentation. The offsets >- * are sorted in ascending order. >- */ >- public static int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >- if (processor == null) >- return EMPTY_INT_ARRAY; >- return STextImpl.fullBidiCharOffsets(processor, environment, text, state); >- } >- >- /** >- * Get the base direction of a structured text. This base direction may depend on >- * whether the text contains Arabic or Hebrew words. If the text contains both, >- * the first Arabic or Hebrew letter in the text determines which is the governing script. >- * >- * @param processor designates a processor instance >- * >- * @param environment specifies an environment whose characteristics may affect >- * the processor's behavior. If <code>null</code>, the default environment is used. >- * >- * @param text is the structured text string >- * >- * @return the base direction of the structured text, {@link #DIR_LTR} or {@link #DIR_RTL} >- */ >- public static int getCurDirection(STextProcessor processor, STextEnvironment environment, String text) { >- if (processor == null) >- return DIR_LTR; >- return processor.getDirection(environment, text); >- } >- >-} >diff --git src/org/eclipse/equinox/bidi/STextEnvironment.java src/org/eclipse/equinox/bidi/STextEnvironment.java >index 0755826..3a7387e 100644 >--- src/org/eclipse/equinox/bidi/STextEnvironment.java >+++ src/org/eclipse/equinox/bidi/STextEnvironment.java >@@ -13,8 +13,8 @@ > import org.eclipse.equinox.bidi.internal.STextActivator; > > /** >- * This class describes environment within which structured text strings are >- * processed. It includes, for example: >+ * This class describes the environment within which structured text strings >+ * are processed. It includes: > * <ul> > * <li>locale,</li> > * <li>desired orientation,</li> >diff --git src/org/eclipse/equinox/bidi/STextHandler.java src/org/eclipse/equinox/bidi/STextHandler.java >new file mode 0 >index 0000000..468ecf0 0 >--- /dev/null >+++ src/org/eclipse/equinox/bidi/STextHandler.java >@@ -0,0 +1,316 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 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; >+ >+import org.eclipse.equinox.bidi.custom.*; >+import org.eclipse.equinox.bidi.internal.STextImpl; >+ >+/** >+ * For a general introduction to structured text, see >+ * {@link <a href="package-summary.html"> the package documentation</a>}. >+ * <p> >+ * Several common processors are included in >+ * {@link org.eclipse.equinox.bidi.STextProcessorFactory}. >+ * For processors >+ * supplied by other packages, a processor instance can be obtained using the >+ * {@link org.eclipse.equinox.bidi.STextProcessorFactory#getProcessor} >+ * method for the registered processors, or by instantiating a private processor. >+ * </p><p> >+ * Most of the methods in this class have a <code>text</code> >+ * argument which may be just a part of a larger body of text. >+ * When it is the case that the text is submitted in parts with >+ * repeated calls, there may be a need to pass information from >+ * one invocation to the next one. For instance, one invocation >+ * may detect that a comment or a literal has been started but >+ * has not been completed. >+ * </p><p> >+ * This information is summarized as one integer, the "<b>state</b>". >+ * The <b>state</b> can be queried using {@link #getState} after any >+ * operation, and it can be set before an operation using >+ * {@link #setState}. >+ * </p><p> >+ * When submitting the initial part of the text, the <b>state</b> >+ * must contain the value {@link #STATE_INITIAL} or any value <= 0. >+ * </p><p> >+ * When calling a method repeatedly, the <b>state</b> is automatically >+ * passed from one invocation to the next unless it is reset >+ * by the caller using {@link #setState}. >+ * </p><p> >+ * <b>Code Samples</b> >+ * </p><p> >+ * The following code shows how to transform a certain type of structured text >+ * (directory and file paths) in order to obtain the <i>full</i> >+ * text corresponding to the given <i>lean</i> text. >+ * <pre> >+ * STextHandler handler = new STextHandler(STextProcessorFactory.PROC_FILE); >+ * String leanText = "D:\\\u05d0\u05d1\\\u05d2\\\u05d3.ext"; >+ * String fullText = handler.leanToFullText(null, leanText); >+ * System.out.println("full text = " + fullText); >+ * </pre> >+ * </p><p> >+ * The following code shows how to transform successive lines of Java >+ * code in order to obtain the <i>full</i> >+ * text corresponding to the <i>lean</i> text of each line. >+ * <pre> >+ * STextHandler handler = new STextHandler(STextProcessorFactory.PROC_JAVA); >+* String leanText = "int i = 3; // first Java statement"; >+ * String fullText = handler.leanToFullText(null, leanText); >+ * System.out.println("full text = " + fullText); >+ * leanText = "i += 4; // next Java statement"; >+ * fullText = handler.leanToFullText(null, leanText); >+ * System.out.println("full text = " + fullText); >+ * </pre> >+ * </p> >+ * @author Matitiahu Allouche >+ * >+ */ >+public class STextHandler { >+ >+ /** >+ * Constant specifying that the base direction of a structured text is LTR. >+ * The base direction may depend on whether the GUI is >+ * {@link STextEnvironment#getMirrored mirrored} and may >+ * may be different for Arabic and for Hebrew. >+ * This constant can appear as value returned by the >+ * {@link #getCurDirection getCurDirection} method. >+ */ >+ public static final int DIR_LTR = 0; >+ >+ /** >+ * Constant specifying that the base direction of a structured text is RTL. >+ * The base direction may depend on whether the GUI is >+ * {@link STextEnvironment#getMirrored mirrored} and may >+ * may be different for Arabic and for Hebrew. >+ * This constant can appear as value returned by the >+ * {@link #getCurDirection getCurDirection} method. >+ */ >+ public static final int DIR_RTL = 1; >+ >+ /** >+ * Constant to use in {@link #setState} >+ * to indicate that there is no context of previous lines >+ * to consider before performing the next operation. >+ */ >+ public static final int STATE_INITIAL = 0; >+ >+ private static final int[] EMPTY_INT_ARRAY = new int[0]; >+ >+ private STextProcessorData procData; >+ private int state; >+ >+ /** >+ * Constructor >+ * >+ * @param processor is the processor which will transform the >+ * submitted text. >+ */ >+ public STextHandler(STextProcessor processor) { >+ procData = new STextProcessorData(); >+ setProcessor(processor); >+ procData.handler = this; >+ procData.offsets = new STextOffsets(); >+ } >+ >+ /** >+ * Replace the processor of an existing handler. This operation >+ * resets the state to {@link #STATE_INITIAL}. >+ * >+ * @param processor is the new processor. >+ */ >+ public void setProcessor(STextProcessor processor) { >+ procData.processor = processor; >+ state = STATE_INITIAL; >+ } >+ >+ /** >+ * Set the state for the next operation. >+ * >+ * @param state is the new value. >+ */ >+ public void setState(int state) { >+ this.state = state; >+ } >+ >+ /** >+ * Get the value of the state after the last operation. >+ * >+ * @return the last value of the state. >+ */ >+ public int getState() { >+ return state; >+ } >+ >+ /** >+ * Add directional formatting characters to a structured text >+ * to ensure correct presentation. >+ * >+ * @param environment a bidi environment. If <code>null</code>, the default environment >+ * is used. >+ * >+ * @param text is the structured text string >+ * >+ * @return the structured text with directional formatting characters added to ensure >+ * correct presentation. >+ */ >+ public String leanToFullText(STextEnvironment environment, String text) { >+ if (procData.processor == null) >+ return text; >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.leanToFullText(procData); >+ } >+ >+ /** >+ * Given a <i>lean</i> string, compute the positions of each of its >+ * characters within the corresponding <i>full</i> string. >+ * >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string. >+ * >+ * @return an array which specifies offsets of the <code>text</code> characters >+ * in the <i>full</i> string >+ */ >+ public int[] leanToFullMap(STextEnvironment environment, String text) { >+ if (procData.processor == null) { >+ int[] map = new int[text.length()]; >+ for (int i = 0; i < map.length; i++) >+ map[i] = i; >+ return map; >+ } >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.leanToFullMap(procData); >+ } >+ >+ /** >+ * Given a <i>lean</i> string, compute the offsets of characters >+ * before which directional formatting characters must be added >+ * in order to ensure correct presentation. >+ * <p> >+ * Only LRMs (for a string with LTR base direction) and RLMs (for >+ * a string with RTL base direction) are considered. Leading and >+ * trailing LRE, RLE and PDF which might be prefixed or suffixed >+ * depending on the {@link STextEnvironment#getOrientation orientation} of the >+ * GUI component used for display are not reflected in this method. >+ * </p> >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string >+ * >+ * @return an array of offsets to the characters in the <code>text</code> argument >+ * before which directional marks must be added to ensure correct presentation. >+ * The offsets are sorted in ascending order. >+ */ >+ public int[] leanBidiCharOffsets(STextEnvironment environment, String text) { >+ if (procData.processor == null) >+ return EMPTY_INT_ARRAY; >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.leanBidiCharOffsets(procData); >+ } >+ >+ /** >+ * Remove directional formatting characters which were added to a >+ * structured text string to ensure correct presentation. >+ * >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string including directional formatting characters. >+ * >+ * @return the structured text string without directional formatting characters >+ * which might have been added by processing it with {@link #leanToFullText}. >+ * >+ */ >+ public String fullToLeanText(STextEnvironment environment, String text) { >+ if (procData.processor == null) >+ return text; >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.fullToLeanText(procData); >+ } >+ >+ /** >+ * Given a <i>full</i> string, compute the positions of each of its >+ * characters within the corresponding <i>lean</i> string. >+ * >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string including directional formatting characters. >+ * >+ * @return an array of integers with one element for each of the characters >+ * in the <code>text</code> argument, equal to the offset of the corresponding character >+ * in the <i>lean</i> string. If there is no corresponding character in the <i>lean</i> string >+ * (because the specified character is a directional formatting character added when invoking >+ * {@link #leanToFullText}), the value returned for this character is -1. >+ */ >+ public int[] fullToLeanMap(STextEnvironment environment, String text) { >+ if (procData.processor == null) { >+ int[] map = new int[text.length()]; >+ for (int i = 0; i < map.length; i++) >+ map[i] = i; >+ return map; >+ } >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.fullToLeanMap(procData); >+ } >+ >+ /** >+ * Given a <i>full</i> string, return the offsets of characters >+ * which are directional formatting characters that have been added >+ * in order to ensure correct presentation. >+ * <p> >+ * LRMs (for a string with LTR base direction), RLMs (for a string with RTL base direction) >+ * are considered as well as leading and trailing LRE, RLE and PDF which might be prefixed >+ * or suffixed depending on the {@link STextEnvironment#getOrientation orientation} >+ * of the GUI component used for display. >+ * </p> >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string including directional formatting characters >+ * >+ * @return an array of offsets to the characters in the <code>text</code> argument which >+ * are directional formatting characters added to ensure correct presentation. The offsets >+ * are sorted in ascending order. >+ */ >+ public int[] fullBidiCharOffsets(STextEnvironment environment, String text) { >+ if (procData.processor == null) >+ return EMPTY_INT_ARRAY; >+ procData.environment = environment; >+ procData.text = text; >+ return STextImpl.fullBidiCharOffsets(procData); >+ } >+ >+ /** >+ * Get the base direction of a structured text. This base direction may depend on >+ * whether the text contains Arabic or Hebrew words. If the text contains both, >+ * the first Arabic or Hebrew letter in the text determines which is the governing script. >+ * >+ * @param environment specifies an environment whose characteristics may affect >+ * the processor's behavior. If <code>null</code>, the default environment is used. >+ * >+ * @param text is the structured text string >+ * >+ * @return the base direction of the structured text, {@link #DIR_LTR} or {@link #DIR_RTL} >+ */ >+ public int getCurDirection(STextEnvironment environment, String text) { >+ if (procData.processor == null) >+ return DIR_LTR; >+ return procData.processor.getDirection(environment, text); >+ } >+ >+} >diff --git src/org/eclipse/equinox/bidi/STextProcessorFactory.java src/org/eclipse/equinox/bidi/STextProcessorFactory.java >index 5338c38..f545a14 100644 >--- src/org/eclipse/equinox/bidi/STextProcessorFactory.java >+++ src/org/eclipse/equinox/bidi/STextProcessorFactory.java >@@ -14,9 +14,7 @@ > import org.eclipse.equinox.bidi.internal.STextTypesCollector; > > /** >- * This class provides access to registered structured text processors. >- * >- * @noinstantiate This class is not intended to be instantiated by clients. >+ * This class provides access to registered structured text processors. > */ > final public class STextProcessorFactory { > >diff --git src/org/eclipse/equinox/bidi/STextProcessorMultipass.java src/org/eclipse/equinox/bidi/STextProcessorMultipass.java >index 70c5abc..2889fb1 100644 >--- src/org/eclipse/equinox/bidi/STextProcessorMultipass.java >+++ src/org/eclipse/equinox/bidi/STextProcessorMultipass.java >@@ -11,38 +11,38 @@ > package org.eclipse.equinox.bidi; > > import org.eclipse.equinox.bidi.custom.STextProcessor; >-import org.eclipse.equinox.bidi.internal.STextImpl; > > // TBD experimental > public class STextProcessorMultipass extends STextProcessor { > >- private int[] state = new int[] {0}; >+ // private int[] state = new int[] {0}; > > public STextProcessorMultipass() { > > } >+ /* >+ public String leanToFullText(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.leanToFullText(processor, environment, text, state); >+ } > >- public String leanToFullText(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.leanToFullText(processor, environment, text, state); >- } >+ public int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.leanToFullMap(processor, environment, text, state); >+ } > >- public int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.leanToFullMap(processor, environment, text, state); >- } >+ public int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.leanBidiCharOffsets(processor, environment, text, state); >+ } > >- public int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.leanBidiCharOffsets(processor, environment, text, state); >- } >- >- public String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.fullToLeanText(processor, environment, text, state); >- } >+ public String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.fullToLeanText(processor, environment, text, state); >+ } > >- public int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.fullToLeanMap(processor, environment, text, state); >- } >+ public int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.fullToLeanMap(processor, environment, text, state); >+ } > >- public int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text) { >- return STextImpl.fullBidiCharOffsets(processor, environment, text, state); >- } >+ public int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text) { >+ return STextImpl.fullBidiCharOffsets(processor, environment, text, state); >+ } >+ */ > } >diff --git src/org/eclipse/equinox/bidi/STextStringRecord.java src/org/eclipse/equinox/bidi/STextStringRecord.java >index 6dfa2a1..46a5342 100644 >--- src/org/eclipse/equinox/bidi/STextStringRecord.java >+++ src/org/eclipse/equinox/bidi/STextStringRecord.java >@@ -86,7 +86,7 @@ > * @param processor the processor appropriate to handle the type > * of structured text present in the first segment. > * It may be one of the pre-defined processor instances >- * appearing in {@link STextEngine}, or it may be an instance >+ * appearing in {@link STextHandler}, or it may be an instance > * created by a plug-in or by the application. > * > * @param start offset in the string of the starting character of the first >@@ -144,7 +144,7 @@ > * @param processor the processor appropriate to handle the type > * of structured text present in this segment. > * It may be one of the pre-defined processor instances >- * appearing in {@link STextEngine}, or it may be an instance >+ * appearing in {@link STextHandler}, or it may be an instance > * created by a plug-in or by the application. > * > * @param start offset in the string of the starting character of the >diff --git src/org/eclipse/equinox/bidi/STextUtil.java src/org/eclipse/equinox/bidi/STextUtil.java >index 32c4859..30fac78 100644 >--- src/org/eclipse/equinox/bidi/STextUtil.java >+++ src/org/eclipse/equinox/bidi/STextUtil.java >@@ -16,9 +16,6 @@ > * This class provides a number of convenience functions facilitating the > * processing of structured text. > * >- * @noextend This class is not intended to be subclassed by clients. >- * @noinstantiate This class is not intended to be instantiated by clients. >- * > * @author Matitiahu Allouche > */ > public final class STextUtil { >@@ -61,7 +58,7 @@ > * If necessary, leading and trailing directional markers (LRE, RLE and PDF) can > * be added depending on the value of the <code>affix</code> argument. > * </p> >- * @see STextEngine#leanBidiCharOffsets(STextProcessor, STextEnvironment, String, int[]) >+ * @see STextHandler#leanBidiCharOffsets leanBidiCharOffsets > * > * @param text the structured text string > * @param offsets an array of offsets to characters in <code>text</code> >@@ -69,8 +66,8 @@ > * The array must be sorted in ascending order without duplicates. > * This argument may be <code>null</code> if there are no marks to add. > * @param direction the base direction of the structured text. >- * It must be one of the values {@link STextEngine#DIR_LTR}, or >- * {@link STextEngine#DIR_RTL}. >+ * It must be one of the values {@link STextHandler#DIR_LTR}, or >+ * {@link STextHandler#DIR_RTL}. > * @param affix specifies if a prefix and a suffix should be added to > * the result > * @return a string corresponding to the source <code>text</code> with >@@ -86,7 +83,7 @@ > String curPrefix, curSuffix, full; > char curMark, c; > char[] fullChars; >- if (direction == STextEngine.DIR_LTR) { >+ if (direction == STextHandler.DIR_LTR) { > curMark = LRM; > curPrefix = "\u202a\u200e"; /* LRE+LRM *///$NON-NLS-1$ > curSuffix = "\u200e\u202c"; /* LRM+PDF *///$NON-NLS-1$ >@@ -187,8 +184,8 @@ > separators = defaultSeparators; > > // make sure that LRE/PDF are added around the string >- STextProcessor processor = new STextProcessor(separators); >- return STextEngine.leanToFullText(processor, env, str, null); >+ STextHandler handler = new STextHandler(new STextProcessor(separators)); >+ return handler.leanToFullText(env, str); > } > > /** >@@ -212,7 +209,8 @@ > STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN); > if (!env.isProcessingNeeded()) > return str; >- return STextEngine.leanToFullText(processor, env, str, null); >+ STextHandler handler = new STextHandler(processor); >+ return handler.leanToFullText(env, str); > } > > /** >@@ -259,7 +257,7 @@ > STextEnvironment env = new STextEnvironment(null, false, STextEnvironment.ORIENT_UNKNOWN); > if (!env.isProcessingNeeded()) > return str; >- return STextEngine.fullToLeanText(processor, env, str, null); >+ STextHandler handler = new STextHandler(processor); >+ return handler.fullToLeanText(env, str); > } >- > } >diff --git src/org/eclipse/equinox/bidi/custom/STextCharTypes.java src/org/eclipse/equinox/bidi/custom/STextCharTypes.java >index 50d768d..1e863fa 100644 >--- src/org/eclipse/equinox/bidi/custom/STextCharTypes.java >+++ src/org/eclipse/equinox/bidi/custom/STextCharTypes.java >@@ -43,6 +43,11 @@ > // current orientation > private int orientation = -1; // "-1" means "unknown" > >+ /** >+ * Constructor >+ * >+ * @param text is the text whose characters are analyzed. >+ */ > public STextCharTypes(String text) { > this.text = text; > dirProps = new byte[text.length()]; >@@ -57,14 +62,15 @@ > } > > /** >- * @param dirProp bidirectional class of the character. It must be >- * one of the values which can be returned by >- * <code>java.lang.Character.getDirectionality</code>. >+ * Get the orientation of the component in which the text will >+ * be displayed. >+ * >+ * @param environment >+ * >+ * @return the orientation as either >+ * {@link STextEnvironment#ORIENT_LTR} or >+ * {@link STextEnvironment#ORIENT_RTL}. > */ >- public void setBidiTypeAt(int i, byte dirProp) { >- dirProps[i] = (byte) (dirProp + DIRPROPS_ADD); >- } >- > public int getOrientation(STextEnvironment environment) { > int result; > int orient = environment.getOrientation(); >@@ -98,11 +104,14 @@ > } > > /** >- * Returns directionality of the character in the original string at >- * the specified index. >- * @param index position of the character in the <i>lean</i> text >- * @return the bidirectional class of the character. It is one of the >- * values which can be returned by {@link Character#getDirectionality(char)} >+ * Returns directionality of the character in the original string at >+ * the specified index. >+ * >+ * @param index position of the character in the <i>lean</i> text >+ * >+ * @return the bidi type of the character. It is one of the >+ * values which can be returned by >+ * {@link Character#getDirectionality(char)}. > */ > public byte getBidiTypeAt(int index) { > if (hasCachedDirectionAt(index)) >@@ -115,4 +124,16 @@ > return dirProp; > } > >+ /** >+ * Force a bidi type on a character. >+ * >+ * @param index is the index of the character whose bidi type is set. >+ * >+ * @param dirProp bidirectional type of the character. It must be >+ * one of the values which can be returned by >+ * <code>java.lang.Character.getDirectionality</code>. >+ */ >+ public void setBidiTypeAt(int index, byte dirProp) { >+ dirProps[index] = (byte) (dirProp + DIRPROPS_ADD); >+ } > } >diff --git src/org/eclipse/equinox/bidi/custom/STextOffsets.java src/org/eclipse/equinox/bidi/custom/STextOffsets.java >new file mode 0 >index 0000000..b33221a 0 >--- /dev/null >+++ src/org/eclipse/equinox/bidi/custom/STextOffsets.java >@@ -0,0 +1,109 @@ >+package org.eclipse.equinox.bidi.custom; >+ >+public class STextOffsets { >+ static final byte L = Character.DIRECTIONALITY_LEFT_TO_RIGHT; >+ static final byte R = Character.DIRECTIONALITY_RIGHT_TO_LEFT; >+ static final byte AL = Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC; >+ static final byte AN = Character.DIRECTIONALITY_ARABIC_NUMBER; >+ static final byte EN = Character.DIRECTIONALITY_EUROPEAN_NUMBER; >+ static final byte[] STRONGS = {L, R}; >+ static final int OFFSET_SIZE = 20; >+ int[] offsets = new int[OFFSET_SIZE]; >+ int count; // number of used entries >+ >+ /** >+ * @return the number of used entries in the offsets array. >+ */ >+ public int getCount() { >+ return count; >+ } >+ >+ /** >+ * Mark that all entries in the offsets array are unused. >+ */ >+ public void resetCount() { >+ count = 0; >+ } >+ >+ /** >+ * Get the value of a specified entry in the offsets array. >+ * >+ * @param index is the index of the entry of interest. >+ * >+ * @return the value of the specified entry. >+ */ >+ public int getOffset(int index) { >+ return offsets[index]; >+ } >+ >+ /** >+ * Insert an offset value in the offset array so that the array >+ * stays in ascending order. >+ * >+ * @param procData is a group of data accessible to processors. >+ * >+ * @param offset is the value to insert. >+ */ >+ public void insertOffset(STextProcessorData procData, int offset) { >+ 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; >+ STextCharTypes dirProps = procData.dirProps; >+ if (dirProps == null) >+ return; >+ >+ byte dirProp = dirProps.getBidiTypeAt(offset); >+ // if the current char is a strong one or a digit, we change the >+ // dirProp of the previous char to account for the inserted mark. >+ if (dirProp == L || dirProp == R || dirProp == AL || dirProp == EN || dirProp == AN) >+ index = offset - 1; >+ else >+ // if the current char is a neutral, we change its own dirProp >+ index = offset; >+ >+ dirProps.setBidiTypeAt(index, STRONGS[procData.direction]); >+ return; >+ >+ } >+ >+ /** >+ * Make sure that there is at least 3 free entries in the offsets array. >+ */ >+ public void ensureRoom() { >+ // make sure there are at least 3 empty slots in offsets >+ if ((offsets.length - count) < 3) { >+ int[] newOffsets = new int[offsets.length * 2]; >+ System.arraycopy(offsets, 0, newOffsets, 0, count); >+ offsets = newOffsets; >+ } >+ } >+ >+ /** >+ * Get all and only the used offset entries. >+ * >+ * @return the current used entries of the offsets array. >+ */ >+ public int[] getArray() { >+ if (count == offsets.length) >+ return offsets; >+ int[] array = new int[count]; >+ System.arraycopy(offsets, 0, array, 0, count); >+ return array; >+ } >+} >diff --git src/org/eclipse/equinox/bidi/custom/STextProcessor.java src/org/eclipse/equinox/bidi/custom/STextProcessor.java >index f24d84c..418d131 100644 >--- src/org/eclipse/equinox/bidi/custom/STextProcessor.java >+++ src/org/eclipse/equinox/bidi/custom/STextProcessor.java >@@ -10,8 +10,8 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.custom; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >+import org.eclipse.equinox.bidi.STextHandler; > import org.eclipse.equinox.bidi.internal.STextImpl; > > /** >@@ -23,10 +23,8 @@ > * <ul> > * <li>Processor instances may be accessed simultaneously by > * several threads. They should have no instance variables.</li> >- * <li>All the user methods in {@link STextEngine} implement a logic >+ * <li>All the user methods in {@link STextHandler} implement a logic > * common to all processors, located in {@link STextImpl}. >- * These methods all have a first argument which is a processor >- * instance. > * The common logic uses processor methods to query the > * characteristics of the specific processor: > * <ul> >@@ -49,15 +47,15 @@ > * method, the common logic will repeatedly invoke the processor's > * {@link #indexOfSpecial indexOfSpecial} method to let it signal the > * presence of special strings which may further delimit the source text.</li> >- * <li>When such a special case is signalled by the processor, the common >+ * <li>When such a special case is signaled by the processor, the common > * logic will call the processor's {@link #processSpecial processSpecial} > * method to give it the opportunity to handle it as needed. Typical > * actions that the processor may perform are to add directional marks >- * inconditionally (by calling {@link #insertMark insertMark} or >+ * unconditionally (by calling {@link #insertMark insertMark} or > * conditionally (by calling {@link #processSeparator processSeparator}).</li> > * </ul> > * >- * @see STextEngine >+ * @see STextHandler > * @author Matitiahu Allouche > */ > public class STextProcessor { >@@ -65,325 +63,256 @@ > final private String separators; > > /** >- * Creates a new instance of the STextProcessor class. >+ * Creates a new instance of the STextProcessor class. > */ > public STextProcessor() { > separators = ""; //$NON-NLS-1$ > } > > /** >- * Creates a new instance of the STextProcessor class. >- * @param separators string consisting of characters that split the text into fragments >+ * Creates a new instance of the STextProcessor class. >+ * >+ * @param separators string consisting of characters that split >+ * the text into fragments > */ > public STextProcessor(String separators) { > this.separators = separators; > } > > /** >- * Locate occurrences of special strings within a structured text >- * and return their indexes one after the other in successive calls. >- * <p> >- * This method is called repeatedly from the code implementing >- * {@link STextEngine#leanToFullText} if the number of special cases >- * returned by {@link #getSpecialsCount} is greater than zero. >- * </p><p> >- * A processor handling special cases must override this method. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >+ * Locate occurrences of special strings within a structured text >+ * and return their indexes one after the other in successive calls. >+ * <p> >+ * This method is called repeatedly from the code implementing >+ * {@link STextHandler#leanToFullText} if the number of special cases >+ * returned by {@link #getSpecialsCount} is greater than zero. >+ * </p><p> >+ * A processor handling special cases must override this method. >+ * </p> >+ * @param procData is a group of data accessible by the processor. > * >- * @param text is the structured text string before >- * addition of any directional formatting characters. >- * >- * @param dirProps is a parameter received by <code>indexOfSpecial</code> >- * uniquely to be used as argument for calls to methods which >- * need it. >- * >- * @param offsets is a parameter received by <code>indexOfSpecial</code> >- * uniquely to be used as argument for calls to methods which >- * need it. >- * >- * @param caseNumber number of the special case to locate. >- * This number varies from 1 to the number of special cases >- * returned by {@link #getSpecialsCount getSpecialsCount} >- * for this processor. >- * The meaning of this number is internal to the class >- * implementing <code>indexOfSpecial</code>. >+ * @param caseNumber is the number of the special case to locate. >+ * This number varies from 1 to the number of special cases >+ * returned by {@link #getSpecialsCount getSpecialsCount} >+ * for this processor. >+ * The meaning of this number is internal to the class >+ * implementing <code>indexOfSpecial</code>. > * >- * @param fromIndex the index within <code>text</code> to start >- * the search from. >+ * @param fromIndex is the index within <code>text</code> to start >+ * the search from. > * >- * @return the position where the start of the special case >- * corresponding to <code>caseNumber</code> was located. >- * The method must return the first occurrence of whatever >- * identifies the start of the special case starting from >- * <code>fromIndex</code>. The method does not have to check if >- * this occurrence appears within the scope of another special >- * case (e.g. a comment starting delimiter within the scope of >- * a literal or vice-versa). >- * <br>If no occurrence is found, the method must return -1. >+ * @return the position where the start of the special case >+ * corresponding to <code>caseNumber</code> was located. >+ * The method must return the first occurrence of whatever >+ * identifies the start of the special case starting from >+ * <code>fromIndex</code>. The method does not have to check if >+ * this occurrence appears within the scope of another special >+ * case (e.g. a comment starting delimiter within the scope of >+ * a literal or vice-versa). >+ * <br>If no occurrence is found, the method must return -1. > * >- * @throws IllegalStateException If not overridden, this method throws an >- * <code>IllegalStateException</code>. This is appropriate behavior >- * (and does not need to be overridden) for processors whose >- * number of special cases is zero, which means that >- * <code>indexOfSpecial</code> should never be called for them. >+ * @throws IllegalStateException If not overridden, this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * number of special cases is zero, which means that >+ * <code>indexOfSpecial</code> should never be called for them. > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { > // This method must be overridden by all subclasses with special cases. > throw new IllegalStateException("A processor with specialsCount > 0 must have an indexOfSpecial() method."); //$NON-NLS-1$ > } > > /** >- * This method handles special cases specific to this processor. >- * It is called by {@link STextEngine#leanToFullText} when a special case occurrence >- * is located by {@link #indexOfSpecial}. >- * <p> >- * If a special processing cannot be completed within a current call to >- * <code>processSpecial</code> (for instance, a comment has been started >- * in the current line but its end appears in a following line), >- * <code>processSpecial</code> should specify a final state by >- * putting its value in the first element of the <code>state</code> >- * parameter. >- * The meaning of this state is internal to the processor. >- * On a later call to {@link STextEngine#leanToFullText} specifying that >- * state value, <code>processSpecial</code> will be called with that value >- * for parameter <code>caseNumber</code> and <code>-1</code> for parameter >- * <code>separLocation</code> and should perform whatever initializations are required >- * depending on the state. >- * </p><p> >- * A processor handling special cases (with a number of >- * special cases greater than zero) must override this method. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >- * >- * @param text is the structured text string before >- * addition of any directional formatting characters. >- * >- * @param dirProps is a parameter received by <code>processSpecial</code> >- * uniquely to be used as argument for calls to methods which >- * need it. >- * >- * @param offsets is a parameter received by <code>processSpecial</code> >- * uniquely to be used as argument for calls to methods which >- * need it. >- * >- * @param state is an integer array with at least one element. >- * If the processor needs to signal the occurrence of a >- * special case which must be passed to the next call to >- * <code>leanToFullText</code> (for instance, a comment or a >- * literal started but not closed in the current >- * <code>text</code>), it must put a value in the first element >- * of the <code>state</code> parameter. >- * This number must be >= 1 and less or equal to the number of special >- * cases returned by {@link #getSpecialsCount getSpecialsCount} >- * by this processor. >- * This number is passed back to the caller >- * and should be specified as <code>state</code> argument >- * in the next call to <code>leanToFullText</code> together >- * with the continuation text. >- * The meaning of this number is internal to the processor. >+ * This method handles special cases specific to this processor. >+ * It is called by {@link STextHandler#leanToFullText} when a special case occurrence >+ * is located by {@link #indexOfSpecial}. >+ * <p> >+ * If a special processing cannot be completed within a current call to >+ * <code>processSpecial</code> (for instance, a comment has been started >+ * in the current line but its end appears in a following line), >+ * <code>processSpecial</code> should specify a final <b>state</b> by >+ * calling {@link STextHandler#setState}. >+ * The meaning of this <b>state</b> is internal to the processor. >+ * On a later call to {@link STextHandler#leanToFullText}, >+ * <code>processSpecial</code> will be called with that value >+ * for parameter <code>caseNumber</code> and <code>-1</code> for parameter >+ * <code>separLocation</code> and should perform whatever initializations are required >+ * depending on the <b>state</b>. >+ * </p><p> >+ * A processor handling special cases (with a number of >+ * special cases greater than zero) must override this method. >+ * </p> >+ * @param procData is a group of data accessible to the processor. > * >- * @param caseNumber number of the special case to handle. >+ * @param caseNumber number of the special case to handle. > * >- * @param separLocation the position returned by >- * {@link #indexOfSpecial indexOfSpecial}. In calls to >- * {@link STextEngine#leanToFullText leanToFullText} and other >- * methods of {@link STextEngine} specifying a non-null >- * <code>state</code> parameter, <code>processSpecial</code> is >- * called when initializing the processing with the value of >- * <code>caseNumber</code> equal to the value returned in the >- * first element of <code>state</code> and the value of >- * <code>separLocation</code> equal to <code>-1</code>. >+ * @param separLocation the position returned by >+ * {@link #indexOfSpecial indexOfSpecial}. In calls to >+ * {@link STextHandler#leanToFullText leanToFullText} and other >+ * methods of {@link STextHandler} setting a non-null >+ * <b>state</b> value, <code>processSpecial</code> is >+ * called when initializing the processing with the value of >+ * <code>caseNumber</code> equal to the value returned >+ * as <b>state</b> and the value of >+ * <code>separLocation</code> equal to <code>-1</code>. > * >- * @return the position after the scope of the special case ends. >- * For instance, the position after the end of a comment, >- * the position after the end of a literal. >- * <br>A value greater or equal to the length of <code>text</code> >- * means that there is no further occurrence of this case in the >- * current structured text. >+ * @return the position after the scope of the special case ends. >+ * For instance, the position after the end of a comment, >+ * the position after the end of a literal. >+ * <br>A value greater or equal to the length of <code>text</code> >+ * means that there is no further occurrence of this case in the >+ * current structured text. > * >- * @throws IllegalStateException If not overridden, this method throws an >- * <code>IllegalStateException</code>. This is appropriate behavior >- * (and does not need to be overridden) for processors whose >- * number of special cases is zero, which means that >- * <code>processSpecial</code> should never be called for them. >+ * @throws IllegalStateException If not overridden, this method throws an >+ * <code>IllegalStateException</code>. This is appropriate behavior >+ * (and does not need to be overridden) for processors whose >+ * number of special cases is zero, which means that >+ * <code>processSpecial</code> should never be called for them. > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { > // This method must be overridden by all subclasses with any special case. > throw new IllegalStateException("A processor with specialsCount > 0 must have a processSpecial() method."); //$NON-NLS-1$ > } > > /** >- * This method can be called from within {@link #indexOfSpecial} or >- * {@link #processSpecial} in extensions of <code>STextProcessor</code> >- * to specify that a mark character must be added before the character >- * at the specified position of the <i>lean</i> text when generating the >- * <i>full</i> text. The mark character will be LRM for structured text >- * with a LTR base direction, and RLM for structured text with RTL >- * base direction. The mark character is not added physically by this >- * method, but its position is noted and will be used when generating >- * the <i>full</i> text. >+ * This method can be called from within {@link #indexOfSpecial} or >+ * {@link #processSpecial} in extensions of <code>STextProcessor</code> >+ * to specify that a mark character must be added before the character >+ * at the specified position of the <i>lean</i> text when generating the >+ * <i>full</i> text. The mark character will be LRM for structured text >+ * with a LTR base direction, and RLM for structured text with RTL >+ * base direction. The mark character is not added physically by this >+ * method, but its position is noted and will be used when generating >+ * the <i>full</i> text. > * >- * @param text is the structured text string received as >- * parameter to <code>indexOfSpecial</code> or >- * <code>processSpecial</code>. >+ * @param procData is a group of data accessible to the processor. > * >- * @param dirProps is a parameter received by <code>indexOfSpecial</code> >- * or <code>processSpecial</code>, uniquely to be used as argument >- * for calls to <code>insertMark</code> and other methods used >- * by processors. >- * >- * @param offsets is a parameter received by <code>indexOfSpecial</code> >- * or <code>processSpecial</code>, uniquely to be used as argument >- * for calls to <code>insertMark</code> and other methods used >- * by processors. >- * >- * @param offset position of the character in the <i>lean</i> text. >- * It must be a non-negative number smaller than the length >- * of the <i>lean</i> text. >- * For the benefit of efficiency, it is better to insert >- * multiple marks in ascending order of the offsets. >+ * @param offset position of the character in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. >+ * For the benefit of efficiency, it is better to insert >+ * multiple marks in ascending order of the offsets. > */ >- public static final void insertMark(String text, STextCharTypes dirProps, int[] offsets, int offset) { >- STextImpl.insertMark(text, dirProps, offsets, offset); >+ public static final void insertMark(STextProcessorData procData, int offset) { >+ procData.offsets.insertOffset(procData, offset); > } > > /** >- * This method can be called from within {@link #indexOfSpecial} or >- * {@link #processSpecial} in extensions of <code>STextProcessor</code> to add >- * a directional mark before a separator if needed for correct display, >- * depending on the base direction of the text and on the class of the >- * characters in the <i>lean</i> text preceding and following the separator itself. >- * <p> >- * The logic implemented in this method considers the text before >- * <code>separLocation</code> and the text following it. If, and only if, >- * a directional mark is needed to insure that the two parts of text >- * will be laid out according to the base direction, a mark will be >- * added when generating the <i>full</i> text. >- * </p> >- * @param text is the structured text string received as >- * parameter to <code>indexOfSpecial</code> or >- * <code>processSpecial</code>. >- * >- * @param dirProps is a parameter received by <code>indexOfSpecial</code> >- * or <code>processSpecial</code>, uniquely to be used as argument >- * for calls to <code>processSeparator</code> and other methods used >- * by processors. >- * >- * @param offsets is a parameter received by <code>indexOfSpecial</code> >- * or <code>processSpecial</code>, uniquely to be used as argument >- * for calls to <code>processSeparator</code> and other methods used >- * by processors. >+ * This method can be called from within {@link #indexOfSpecial} or >+ * {@link #processSpecial} in extensions of <code>STextProcessor</code> to add >+ * a directional mark before a separator if needed for correct display, >+ * depending on the base direction of the text and on the type of the >+ * characters in the <i>lean</i> text preceding and following the separator itself. >+ * <p> >+ * The logic implemented in this method considers the text before >+ * <code>separLocation</code> and the text following it. If, and only if, >+ * a directional mark is needed to insure that the two parts of text >+ * will be laid out according to the base direction, a mark will be >+ * added when generating the <i>full</i> text. >+ * </p> >+ * @param procData is a group of data accessible to the processor. > * >- * @param separLocation offset of the separator in the <i>lean</i> text. >- * It must be a non-negative number smaller than the length >- * of the <i>lean</i> text. >+ * @param separLocation offset of the separator in the <i>lean</i> text. >+ * It must be a non-negative number smaller than the length >+ * of the <i>lean</i> text. > */ >- public static final void processSeparator(String text, STextCharTypes dirProps, int[] offsets, int separLocation) { >- STextImpl.processSeparator(text, dirProps, offsets, separLocation); >+ public static final void processSeparator(STextProcessorData procData, int separLocation) { >+ STextImpl.processSeparator(procData, separLocation); > } > > /** >- * Indicate the separators to use for the current processor. >- * This method is invoked before starting the processing. >- * <p> >- * If no separators are specified, this method returns an empty string. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >+ * Indicate the separators to use for the current processor. >+ * This method is invoked before starting the processing. >+ * <p> >+ * If no separators are specified, this method returns an empty string. >+ * </p> >+ * @param environment the current environment, which may affect the behavior of >+ * the processor. This parameter may be specified as >+ * <code>null</code>, in which case the >+ * {@link STextEnvironment#DEFAULT DEFAULT} >+ * environment should be assumed. > * >- * @return a string grouping one-character separators which separate >- * the structured text into tokens. >+ * @return a string grouping one-character separators which separate >+ * the structured text into tokens. > */ > public String getSeparators(STextEnvironment environment) { > return separators; > } > > /** >- * Indicate the base text direction appropriate for an instance of structured text. >- * This method is invoked before starting the processing. >- * <p> >- * If not overridden, this method returns <code>DIR_LTR</code>. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >+ * Indicate the base text direction appropriate for an instance of structured text. >+ * This method is invoked before starting the processing. >+ * <p> >+ * If not overridden, this method returns <code>DIR_LTR</code>. >+ * </p> >+ * @param environment the current environment, which may affect the behavior of >+ * the processor. This parameter may be specified as >+ * <code>null</code>, in which case the >+ * {@link STextEnvironment#DEFAULT DEFAULT} >+ * environment should be assumed. > * >- * @param text is the structured text string to process. >+ * @param text is the structured text string to process. > * >- * @return the base direction of the structured text. This direction >- * may not be the same depending on the environment and on >- * whether the structured text contains Arabic or Hebrew >- * letters.<br> >- * The value returned is either >- * {@link STextEngine#DIR_LTR DIR_LTR} or {@link STextEngine#DIR_RTL DIR_RTL}. >+ * @return the base direction of the structured text. This direction >+ * may not be the same depending on the environment and on >+ * whether the structured text contains Arabic or Hebrew >+ * letters.<br> >+ * The value returned is either >+ * {@link STextHandler#DIR_LTR DIR_LTR} or {@link STextHandler#DIR_RTL DIR_RTL}. > */ > public int getDirection(STextEnvironment environment, String text) { >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > } > > /** >- * Indicate the base text direction appropriate for an instance of structured text. >- * This method is invoked before starting the processing. >- * <p> >- * If not overridden, this method returns <code>DIR_LTR</code>. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >+ * Indicate the base text direction appropriate for an instance of structured text. >+ * This method is invoked before starting the processing. >+ * <p> >+ * If not overridden, this method returns <code>DIR_LTR</code>. >+ * </p> >+ * @param environment the current environment, which may affect the behavior of >+ * the processor. This parameter may be specified as >+ * <code>null</code>, in which case the >+ * {@link STextEnvironment#DEFAULT DEFAULT} >+ * environment should be assumed. > * >- * @param text is the structured text string to process. >+ * @param text is the structured text string to process. > * >- * @param dirProps is a parameter received uniquely to be used as argument >- * for calls to <code>getDirProp</code> and other methods used >- * by processors. >+ * @param dirProps is a parameter received uniquely to be used as argument >+ * for calls to {@link STextCharTypes#getBidiTypeAt} >+ * and other methods used by processors. > * >- * @return the base direction of the structured text. This direction >- * may not be the same depending on the environment and on >- * whether the structured text contains Arabic or Hebrew >- * letters.<br> >- * The value returned is either >- * {@link STextEngine#DIR_LTR DIR_LTR} or {@link STextEngine#DIR_RTL DIR_RTL}. >+ * @return the base direction of the structured text. This direction >+ * may not be the same depending on the environment and on >+ * whether the structured text contains Arabic or Hebrew >+ * letters.<br> >+ * The value returned is either >+ * {@link STextHandler#DIR_LTR DIR_LTR} or {@link STextHandler#DIR_RTL DIR_RTL}. > */ > public int getDirection(STextEnvironment environment, String text, STextCharTypes dirProps) { >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > } > > /** >- * Indicate the number of special cases handled by the current processor. >- * This method is invoked before starting the processing. >- * If the number returned is zero, {@link #indexOfSpecial} and >- * {@link #processSpecial} will not be invoked. >- * <p> >- * If not overridden, this method returns <code>zero</code>. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >+ * Indicate the number of special cases handled by the current processor. >+ * This method is invoked before starting the processing. >+ * If the number returned is zero, {@link #indexOfSpecial} and >+ * {@link #processSpecial} will not be invoked. >+ * <p> >+ * If not overridden, this method returns <code>zero</code>. >+ * </p> >+ * @param environment the current environment, which may affect the behavior of >+ * the processor. This parameter may be specified as >+ * <code>null</code>, in which case the >+ * {@link STextEnvironment#DEFAULT DEFAULT} >+ * environment should be assumed. > * >- * @return the number of special cases for the associated processor. >- * Special cases exist for some types of structured text >- * processors. They are implemented by overriding methods >- * {@link STextProcessor#indexOfSpecial} and {@link STextProcessor#processSpecial}. >- * Examples of special cases are comments, literals, or >- * anything which is not identified by a one-character separator. >+ * @return the number of special cases for the associated processor. >+ * Special cases exist for some types of structured text >+ * processors. They are implemented by overriding methods >+ * {@link STextProcessor#indexOfSpecial} and {@link STextProcessor#processSpecial}. >+ * Examples of special cases are comments, literals, or >+ * anything which is not identified by a one-character separator. > * > */ > public int getSpecialsCount(STextEnvironment environment) { >@@ -391,32 +320,20 @@ > } > > /** >- * Checks if there is a need for processing structured text. >- * This method is invoked before starting the processing. If the >- * processor returns <code>true</code>, no directional formatting >- * characters are added to the <i>lean</i> text and the processing >- * is shortened. >- * <p> >- * If not overridden, this method returns <code>false</code>. >- * </p> >- * @param environment the current environment, which may affect the behavior of >- * the processor. This parameter may be specified as >- * <code>null</code>, in which case the >- * {@link STextEnvironment#DEFAULT DEFAULT} >- * environment should be assumed. >- * >- * @param text is the structured text string to process. >- * >- * @param dirProps is a parameter received uniquely to be used as argument >- * for calls to <code>getDirProp</code> and other methods used >- * by processors. >- * >- * @return a flag indicating if there is no need to process the structured >- * text to add directional formatting characters. >+ * Checks if there is a need for processing structured text. >+ * This method is invoked before starting the processing. If the >+ * processor returns <code>true</code>, no directional formatting >+ * characters are added to the <i>lean</i> text and the processing >+ * is shortened. >+ * <p> >+ * If not overridden, this method returns <code>false</code>. >+ * </p> >+ >+ * @return a flag indicating if there is no need to process the structured >+ * text to add directional formatting characters. > * > */ >- public boolean skipProcessing(STextEnvironment environment, String text, STextCharTypes dirProps) { >+ public boolean skipProcessing(STextProcessorData procData) { > return false; > } >- > } >diff --git src/org/eclipse/equinox/bidi/custom/STextProcessorData.java src/org/eclipse/equinox/bidi/custom/STextProcessorData.java >new file mode 0 >index 0000000..00f5f54 0 >--- /dev/null >+++ src/org/eclipse/equinox/bidi/custom/STextProcessorData.java >@@ -0,0 +1,52 @@ >+package org.eclipse.equinox.bidi.custom; >+ >+import org.eclipse.equinox.bidi.STextEnvironment; >+import org.eclipse.equinox.bidi.STextHandler; >+ >+/** >+ * This class regroups core information related to structured text operations. >+ * It is convenient to pass information between caller and called method. >+ * >+ * @author Matitiahu Allouche >+ * >+ */ >+public class STextProcessorData { >+ /** >+ * The handler >+ */ >+ public STextHandler handler; >+ /** >+ * The processor >+ */ >+ public STextProcessor processor; >+ /** >+ * The environment >+ */ >+ public STextEnvironment environment; >+ /** >+ * The class instance to get and set the bidi type of characters >+ */ >+ public STextCharTypes dirProps; >+ /** >+ * The class instance to manipulate the array of offsets to >+ * directional control characters >+ */ >+ public STextOffsets offsets; >+ /** >+ * The source text >+ */ >+ public String text; >+ /** >+ * The base direction of the source text >+ */ >+ public int direction; >+ /** >+ * The orientation of the component which is to display the text >+ */ >+ public int orientation; >+ /** >+ * The length of the prefix (LRE, RLE, LRM or RLM) to be prepended >+ * to the text >+ */ >+ public int prefixLength; >+} >diff --git src/org/eclipse/equinox/bidi/custom/package.html src/org/eclipse/equinox/bidi/custom/package.html >index 382a502..84f9c54 100644 >--- src/org/eclipse/equinox/bidi/custom/package.html >+++ src/org/eclipse/equinox/bidi/custom/package.html >@@ -1,25 +1,29 @@ >-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >-<html> >-<head> >-<META name="Author" content="Matitiahu Allouche"> >-</head> >-<body bgcolor="white"> >- >-This package provides classes for >-developing structured text processors. >- >-<ul> >- <li>{@link <a href="STextProcessor.html">STextProcessor</a>} >- is a generic processor to be used as superclass for specific >- processors.</li> >- <li>{@link <a href="STextStringProcessor.html">STextStringProcessor</a>} >- is a class which allows retrieval of the defined processor types and of the >- corresponding processors.</li> >-</ul> >- >-This package is to be used together with package >-{@link <a href="..\package-summary.html"> >-org.eclipse.equinox.bidi</a>}. >- >-</body> >-</html> >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >+<html> >+<head> >+<META name="Author" content="Matitiahu Allouche"> >+</head> >+<body bgcolor="white"> >+ >+This package provides classes for >+developing structured text processors. >+ >+<ul> >+ <li>{@link <a href="STextProcessor.html">STextProcessor</a>} >+ is a generic processor to be used as superclass for specific >+ processors.</li> >+ <li>{@link <a href="STextProcessorData.html">STextProcessorData</a>} >+ regroups data which can be used by processors.</li> >+ <li>{@link <a href="STextCharTypes.html">STextStringCharTypes</a>} >+ allows getting and setting the bidi class of characters.</li> >+ <li>{@link <a href="STextOffsets.html">STextStringOffsets</a>} >+ allows manipulation of offsets at which directional control >+ characters are inserted.</li> >+</ul> >+ >+This package is to be used together with package >+{@link <a href="..\package-summary.html"> >+org.eclipse.equinox.bidi</a>}. >+ >+</body> >+</html> >diff --git src/org/eclipse/equinox/bidi/internal/STextDelims.java src/org/eclipse/equinox/bidi/internal/STextDelims.java >index 3a0cc7a..1c8db82 100644 >--- src/org/eclipse/equinox/bidi/internal/STextDelims.java >+++ src/org/eclipse/equinox/bidi/internal/STextDelims.java >@@ -10,9 +10,8 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal; > >-import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; > import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.custom.STextProcessorData; > > /** > * A base processor for structured text composed of text segments separated >@@ -44,9 +43,9 @@ > * > * @see #getDelimiters > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { > char delim = getDelimiters().charAt((caseNumber - 1) * 2); >- return text.indexOf(delim, fromIndex); >+ return procData.text.indexOf(delim, fromIndex); > } > > /** >@@ -59,13 +58,13 @@ > * @return the position after the matching end delimiter, or the length > * of <code>text</code> if no end delimiter is found. > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { >+ STextProcessor.processSeparator(procData, separLocation); > int loc = separLocation + 1; > char delim = getDelimiters().charAt((caseNumber * 2) - 1); >- loc = text.indexOf(delim, loc); >+ loc = procData.text.indexOf(delim, loc); > if (loc < 0) >- return text.length(); >+ return procData.text.length(); > return loc + 1; > } > >diff --git src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java >index e583e9e..c2ebba1 100644 >--- src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java >+++ src/org/eclipse/equinox/bidi/internal/STextDelimsEsc.java >@@ -10,9 +10,8 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal; > >-import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; > import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.custom.STextProcessorData; > > /** > * A base processor for structured text composed of text segments separated >@@ -50,10 +49,11 @@ > * and skips until after the matching end delimiter, > * ignoring possibly escaped end delimiters. > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { >+ STextProcessor.processSeparator(procData, separLocation); > int location = separLocation + 1; > char delim = getDelimiters().charAt((caseNumber * 2) - 1); >+ String text = procData.text; > while (true) { > location = text.indexOf(delim, location); > if (location < 0) >diff --git src/org/eclipse/equinox/bidi/internal/STextImpl.java src/org/eclipse/equinox/bidi/internal/STextImpl.java >index 5a40645..cc5d5d6 100644 >--- src/org/eclipse/equinox/bidi/internal/STextImpl.java >+++ src/org/eclipse/equinox/bidi/internal/STextImpl.java >@@ -10,16 +10,15 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; >-import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.STextHandler; >+import org.eclipse.equinox.bidi.custom.*; > > /** > * <code>STextImpl</code> provides the code which implements the API in >- * {@link STextEngine}. All its public methods are shadows of similarly >- * signed methods of <code>STextEngine</code>, and their documentation >- * is by reference to the methods in <code>STextEngine</code>. >+ * {@link STextHandler}. All its public methods are shadows of similarly >+ * signed methods of <code>STextHandler</code>, and their documentation >+ * is by reference to the methods in <code>STextHandler</code>. > * > * @author Matitiahu Allouche > */ >@@ -50,7 +49,6 @@ > static final char PDF = 0x202C; > static final char[] MARKS = {LRM, RLM}; > static final char[] EMBEDS = {LRE, RLE}; >- static final byte[] STRONGS = {L, R}; > static final int PREFIX_LENGTH = 2; > static final int SUFFIX_LENGTH = 2; > static final int FIXES_LENGTH = PREFIX_LENGTH + SUFFIX_LENGTH; >@@ -59,16 +57,18 @@ > static final STextEnvironment IGNORE_ENVIRONMENT = new STextEnvironment(null, false, STextEnvironment.ORIENT_IGNORE); > > /** >- * Prevent creation of a STextEngine instance >+ * Prevent creation of a STextHandler instance > */ > private STextImpl() { > // nothing to do > } > >- static long computeNextLocation(STextProcessor processor, STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] locations, int[] state, int curPos) { >- String separators = processor.getSeparators(environment); >+ static long computeNextLocation(STextProcessorData procData, int[] locations, int curPos) { >+ STextProcessor processor = procData.processor; >+ String separators = processor.getSeparators(procData.environment); > int separCount = separators.length(); >- int specialsCount = processor.getSpecialsCount(environment); >+ int specialsCount = processor.getSpecialsCount(procData.environment); >+ String text = procData.text; > int len = text.length(); > int nextLocation = len; > int idxLocation = 0; >@@ -77,8 +77,8 @@ > for (int i = 0; i < specialsCount; i++) { > int location = locations[separCount + i]; > if (location < curPos) { >- offsets = ensureRoomInOffsets(offsets); >- location = processor.indexOfSpecial(environment, text, dirProps, offsets, i + 1, curPos); >+ procData.offsets.ensureRoom(); >+ location = processor.indexOfSpecial(procData, i + 1, curPos); > if (location < 0) > location = len; > locations[separCount + i] = location; >@@ -107,10 +107,12 @@ > /** > * @see STextProcessor#processSeparator STextProcessor.processSeparator > */ >- public static void processSeparator(String text, STextCharTypes dirProps, int[] offsets, int separLocation) { >+ public static void processSeparator(STextProcessorData procData, int separLocation) { >+ String text = procData.text; > int len = text.length(); >- // offsets[2] contains the structured text direction >- if (offsets[2] == STextEngine.DIR_RTL) { >+ STextCharTypes dirProps = procData.dirProps; >+ STextOffsets offsets = procData.offsets; >+ if (procData.direction == STextHandler.DIR_RTL) { > // the structured text base direction is RTL > for (int i = separLocation - 1; i >= 0; i--) { > byte dirProp = dirProps.getBidiTypeAt(i); >@@ -122,7 +124,7 @@ > if (dirProp == R || dirProp == AL) > return; > if (dirProp == L || dirProp == EN) { >- insertMark(text, dirProps, offsets, separLocation); >+ offsets.insertOffset(procData, separLocation); > return; > } > } >@@ -144,7 +146,7 @@ > if (dirProp == L) > return; > if (dirProp == R || dirProp == EN || dirProp == AL || dirProp == AN) { >- insertMark(text, dirProps, offsets, separLocation); >+ offsets.insertOffset(procData, separLocation); > return; > } > } >@@ -156,7 +158,7 @@ > if (dirProp == L) > return; > if (dirProp == AL || dirProp == AN || dirProp == R) { >- insertMark(text, dirProps, offsets, separLocation); >+ offsets.insertOffset(procData, separLocation); > return; > } > } >@@ -168,85 +170,83 @@ > /** > * When the orientation is <code>ORIENT_LTR</code> and the > * structured text has a RTL base direction, >- * {@link STextEngine#leanToFullText leanToFullText} >+ * {@link STextHandler#leanToFullText leanToFullText} > * adds RLE+RLM at the head of the <i>full</i> text and RLM+PDF at its > * end. > * <p> > * When the orientation is <code>ORIENT_RTL</code> and the > * structured text has a LTR base direction, >- * {@link STextEngine#leanToFullText leanToFullText} >+ * {@link STextHandler#leanToFullText leanToFullText} > * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its > * end. > * <p> > * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or > * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve > * to a RTL orientation while the structured text has a LTR base >- * direction, {@link STextEngine#leanToFullText leanToFullText} >+ * direction, {@link STextHandler#leanToFullText leanToFullText} > * adds LRM at the head of the <i>full</i> text. > * <p> > * When the orientation is <code>ORIENT_CONTEXTUAL_LTR</code> or > * <code>ORIENT_CONTEXTUAL_RTL</code> and the data content would resolve > * to a LTR orientation while the structured text has a RTL base >- * direction, {@link STextEngine#leanToFullText leanToFullText} >+ * direction, {@link STextHandler#leanToFullText leanToFullText} > * adds RLM at the head of the <i>full</i> text. > * <p> > * When the orientation is <code>ORIENT_UNKNOWN</code> and the > * structured text has a LTR base direction, >- * {@link STextEngine#leanToFullText leanToFullText} >+ * {@link STextHandler#leanToFullText leanToFullText} > * adds LRE+LRM at the head of the <i>full</i> text and LRM+PDF at its > * end. > * <p> > * When the orientation is <code>ORIENT_UNKNOWN</code> and the > * structured text has a RTL base direction, >- * {@link STextEngine#leanToFullText leanToFullText} >+ * {@link STextHandler#leanToFullText leanToFullText} > * adds RLE+RLM at the head of the <i>full</i> text and RLM+PDF at its > * end. > * <p> > * When the orientation is <code>ORIENT_IGNORE</code>, >- * {@link STextEngine#leanToFullText leanToFullText} does not add any directional >+ * {@link STextHandler#leanToFullText leanToFullText} does not add any directional > * formatting characters as either prefix or suffix of the <i>full</i> text. > * <p> >- * @see STextEngine#leanToFullText STextEngine.leanToFullText >+ * @see STextHandler#leanToFullText STextHandler.leanToFullText > */ >- public static String leanToFullText(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >+ public static String leanToFullText(STextProcessorData procData) { >+ String text = procData.text; > int len = text.length(); > if (len == 0) > return text; >- STextCharTypes dirProps = new STextCharTypes(text); >- int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps); >- int prefixLength = offsets[1]; >- int count = offsets[0] - OFFSETS_SHIFT; >- if (count == 0 && prefixLength == 0) >+ leanToFullCommon(procData); >+ STextOffsets offsets = procData.offsets; >+ int count = offsets.getCount(); >+ if (count == 0 && procData.prefixLength == 0) > return text; > int newLen = len + count; >- if (prefixLength == 1) >+ if (procData.prefixLength == 1) > newLen++; /* +1 for a mark char */ >- else if (prefixLength == 2) >+ else if (procData.prefixLength == 2) > newLen += FIXES_LENGTH; > char[] fullChars = new char[newLen]; >- int added = prefixLength; >+ int added = procData.prefixLength; > // add marks at offsets >- int direction = offsets[2]; >- char curMark = MARKS[direction]; >- for (int i = 0, j = OFFSETS_SHIFT; i < len; i++) { >+ char curMark = MARKS[procData.direction]; >+ for (int i = 0, j = 0; i < len; i++) { > char c = text.charAt(i); >- // offsets[0] contains the number of used entries >- if (j < offsets[0] && i == offsets[j]) { >+ if (j < count && i == offsets.getOffset(j)) { > fullChars[i + added] = curMark; > added++; > j++; > } > fullChars[i + added] = c; > } >- if (prefixLength > 0) { /* add prefix/suffix ? */ >- if (prefixLength == 1) { /* contextual orientation */ >+ if (procData.prefixLength > 0) { /* add prefix/suffix ? */ >+ if (procData.prefixLength == 1) { /* contextual orientation */ > fullChars[0] = curMark; > } else { > // When the orientation is RTL, we need to add EMBED at the > // start of the text and PDF at its end. > // However, because of a bug in Windows' handling of LRE/PDF, > // we add EMBED_PREFIX at the start and EMBED_SUFFIX at the end. >- char curEmbed = EMBEDS[direction]; >+ char curEmbed = EMBEDS[procData.direction]; > fullChars[0] = curEmbed; > fullChars[1] = curMark; > fullChars[newLen - 1] = PDF; >@@ -257,20 +257,20 @@ > } > > /** >- * @see STextEngine#leanToFullMap STextEngine.leanToFullMap >+ * @see STextHandler#leanToFullMap STextHandler.leanToFullMap > */ >- public static int[] leanToFullMap(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >+ public static int[] leanToFullMap(STextProcessorData procData) { >+ String text = procData.text; > int len = text.length(); > if (len == 0) > return EMPTY_INT_ARRAY; >- STextCharTypes dirProps = new STextCharTypes(text); >- int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps); >- int prefixLength = offsets[1]; >+ leanToFullCommon(procData); >+ STextOffsets offsets = procData.offsets; > int[] map = new int[len]; >- int count = offsets[0]; // number of used entries >- int added = prefixLength; >- for (int pos = 0, i = OFFSETS_SHIFT; pos < len; pos++) { >- if (i < count && pos == offsets[i]) { >+ int count = procData.offsets.getCount(); >+ int added = procData.prefixLength; >+ for (int pos = 0, i = 0; pos < len; pos++) { >+ if (i < count && pos == offsets.getOffset(i)) { > added++; > i++; > } >@@ -280,38 +280,31 @@ > } > > /** >- * @see STextEngine#leanBidiCharOffsets STextEngine.leanBidiCharOffsets >+ * @see STextHandler#leanBidiCharOffsets STextHandler.leanBidiCharOffsets > */ >- public static int[] leanBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >+ public static int[] leanBidiCharOffsets(STextProcessorData procData) { >+ String text = procData.text; > int len = text.length(); > if (len == 0) > return EMPTY_INT_ARRAY; >- STextCharTypes dirProps = new STextCharTypes(text); >- int[] offsets = leanToFullCommon(processor, environment, text, state, dirProps); >- // offsets[0] contains the number of used entries >- int count = offsets[0] - OFFSETS_SHIFT; >- int[] result = new int[count]; >- System.arraycopy(offsets, OFFSETS_SHIFT, result, 0, count); >- return result; >+ leanToFullCommon(procData); >+ return procData.offsets.getArray(); > } > >- static int[] leanToFullCommon(STextProcessor processor, STextEnvironment environment, String text, int[] state, STextCharTypes dirProps) { >- if (environment == null) >- environment = STextEnvironment.DEFAULT; >- if (state == null) { >- state = new int[1]; >- state[0] = STextEngine.STATE_INITIAL; >- } >+ static void leanToFullCommon(STextProcessorData procData) { >+ if (procData.environment == null) >+ procData.environment = STextEnvironment.DEFAULT; >+ String text = procData.text; > int len = text.length(); >- int orient = dirProps.getOrientation(environment); >- int direction = processor.getDirection(environment, text, dirProps); >- // offsets of marks to add. Entry 0 is the number of used slots; >- // entry 1 is reserved to pass prefixLength. >- // entry 2 is reserved to pass direction.. >- int[] offsets = new int[20]; >- offsets[0] = OFFSETS_SHIFT; >- offsets[2] = direction; >- if (!processor.skipProcessing(environment, text, dirProps)) { >+ STextHandler handler = procData.handler; >+ STextProcessor processor = procData.processor; >+ STextEnvironment environment = procData.environment; >+ STextOffsets offsets = procData.offsets; >+ STextCharTypes dirProps = procData.dirProps = new STextCharTypes(text); >+ procData.orientation = dirProps.getOrientation(environment); >+ procData.direction = processor.getDirection(environment, text, dirProps); >+ offsets.resetCount(); >+ if (!processor.skipProcessing(procData)) { > // initialize locations > int separCount = processor.getSeparators(environment).length(); > int[] locations = new int[separCount + processor.getSpecialsCount(environment)]; >@@ -320,63 +313,58 @@ > } > // current position > int curPos = 0; >- if (state[0] > STextEngine.STATE_INITIAL) { >- offsets = ensureRoomInOffsets(offsets); >- int initState = state[0]; >- state[0] = STextEngine.STATE_INITIAL; >- curPos = processor.processSpecial(environment, text, dirProps, offsets, state, initState, -1); >+ int state = handler.getState(); >+ if (state > STextHandler.STATE_INITIAL) { >+ offsets.ensureRoom(); >+ handler.setState(STextHandler.STATE_INITIAL); >+ curPos = processor.processSpecial(procData, state, -1); > } > while (true) { > // location of next token to handle > int nextLocation; > // index of next token to handle (if < separCount, this is a separator; otherwise a special case > int idxLocation; >- long res = computeNextLocation(processor, environment, text, dirProps, offsets, locations, state, curPos); >+ long res = computeNextLocation(procData, locations, curPos); > nextLocation = (int) (res & 0x00000000FFFFFFFF); /* low word */ > if (nextLocation >= len) > break; >+ offsets.ensureRoom(); > idxLocation = (int) (res >> 32); /* high word */ > if (idxLocation < separCount) { >- offsets = ensureRoomInOffsets(offsets); >- processSeparator(text, dirProps, offsets, nextLocation); >+ processSeparator(procData, nextLocation); > curPos = nextLocation + 1; > } else { >- offsets = ensureRoomInOffsets(offsets); > idxLocation -= (separCount - 1); // because caseNumber starts from 1 >- curPos = processor.processSpecial(environment, text, dirProps, offsets, state, idxLocation, nextLocation); >+ curPos = processor.processSpecial(procData, idxLocation, nextLocation); > } > if (curPos >= len) > break; > } // end while > } // end if (!processor.skipProcessing()) >- if (orient == STextEnvironment.ORIENT_IGNORE) >- offsets[1] = 0; >+ if (procData.orientation == STextEnvironment.ORIENT_IGNORE) >+ procData.prefixLength = 0; > else { > // recompute orient since it may have changed if contextual >- orient = dirProps.getOrientation(environment); >- if (orient == direction && orient != STextEnvironment.ORIENT_UNKNOWN) >- offsets[1] = 0; >+ procData.orientation = dirProps.getOrientation(environment); >+ if (procData.orientation == procData.direction && procData.orientation != STextEnvironment.ORIENT_UNKNOWN) >+ procData.prefixLength = 0; > else if ((environment.getOrientation() & STextEnvironment.ORIENT_CONTEXTUAL_LTR) != 0) >- offsets[1] = 1; >+ procData.prefixLength = 1; > else >- offsets[1] = 2; >+ procData.prefixLength = 2; > } >- return offsets; > } > > /** >- * @see STextEngine#fullToLeanText STextEngine.fullToLeanText >+ * @see STextHandler#fullToLeanText STextHandler.fullToLeanText > */ >- public static String fullToLeanText(STextProcessor processor, STextEnvironment environment, String text, int[] state) { >+ public static String fullToLeanText(STextProcessorData procData) { >+ String text = procData.text; > if (text.length() == 0) > return text; >- if (environment == null) >- environment = STextEnvironment.DEFAULT; >- if (state == null) { >- state = new int[1]; >- state[0] = STextEngine.STATE_INITIAL; >- } >- int dir = processor.getDirection(environment, text); >+ if (procData.environment == null) >+ procData.environment = STextEnvironment.DEFAULT; >+ int dir = procData.processor.getDirection(procData.environment, text); > char curMark = MARKS[dir]; > char curEmbed = EMBEDS[dir]; > int i; // used as loop index >@@ -414,7 +402,7 @@ > chars[i - cnt] = c; > } > String lean = new String(chars, 0, lenText - cnt); >- String full = leanToFullText(processor, IGNORE_ENVIRONMENT, lean, state); >+ String full = procData.handler.leanToFullText(IGNORE_ENVIRONMENT, lean); > if (full.equals(text)) > return lean; > >@@ -460,15 +448,16 @@ > } > > /** >- * @see STextEngine#fullToLeanMap STextEngine.fullToLeanMap >+ * @see STextHandler#fullToLeanMap STextHandler.fullToLeanMap > */ >- public static int[] fullToLeanMap(STextProcessor processor, STextEnvironment environment, String full, int[] state) { >+ public static int[] fullToLeanMap(STextProcessorData procData) { >+ String full = procData.text; > int lenFull = full.length(); > if (lenFull == 0) > return EMPTY_INT_ARRAY; >- String lean = fullToLeanText(processor, environment, full, state); >+ String lean = procData.handler.fullToLeanText(procData.environment, full); > int lenLean = lean.length(); >- int dir = processor.getDirection(environment, lean); >+ int dir = procData.processor.getDirection(procData.environment, lean); > char curMark = MARKS[dir]; > char curEmbed = EMBEDS[dir]; > int[] map = new int[lenFull]; >@@ -494,15 +483,18 @@ > } > > /** >- * @see STextEngine#fullBidiCharOffsets STextEngine.fullBidiCharOffsets >+ * @see STextHandler#fullBidiCharOffsets STextHandler.fullBidiCharOffsets > */ >- public static int[] fullBidiCharOffsets(STextProcessor processor, STextEnvironment environment, String full, int[] state) { >+ public static int[] fullBidiCharOffsets(STextProcessorData procData) { >+ String full = procData.text; > int lenFull = full.length(); > if (lenFull == 0) > return EMPTY_INT_ARRAY; >- String lean = fullToLeanText(processor, environment, full, state); >- int[] offsets = new int[20]; >- offsets[0] = OFFSETS_SHIFT; >+ String lean = procData.handler.fullToLeanText(procData.environment, full); >+ procData.text = full; >+ procData.dirProps = new STextCharTypes(full); >+ STextOffsets offsets = procData.offsets; >+ offsets.resetCount(); > int lenLean = lean.length(); > int idxLean, idxFull; > // lean must be a subset of Full, so we only check on iLean < leanLen >@@ -510,66 +502,14 @@ > if (full.charAt(idxFull) == lean.charAt(idxLean)) > idxLean++; > else { >- offsets = ensureRoomInOffsets(offsets); >- insertMark(lean, null, offsets, idxFull); >+ offsets.ensureRoom(); >+ offsets.insertOffset(procData, idxFull); > } > } > for (; idxFull < lenFull; idxFull++) { >- offsets = ensureRoomInOffsets(offsets); >- insertMark(lean, null, offsets, idxFull); >+ offsets.ensureRoom(); >+ offsets.insertOffset(procData, idxFull); > } >- int[] result = new int[offsets[0] - OFFSETS_SHIFT]; >- System.arraycopy(offsets, OFFSETS_SHIFT, result, 0, result.length); >- return result; >- } >- >- static int[] ensureRoomInOffsets(int[] offsets) { >- // make sure >- if ((offsets.length - offsets[0]) < 3) { >- int[] newOffsets = new int[offsets.length * 2]; >- System.arraycopy(offsets, 0, newOffsets, 0, offsets[0]); >- return newOffsets; >- } >- return offsets; >- } >- >- /** >- * @see STextProcessor#insertMark STextProcessor.insertMark >- */ >- public static void insertMark(String text, STextCharTypes dirProps, int[] offsets, int offset) { >- int count = offsets[0];// number of used entries >- int index = count - 1; // index of greatest member <= offset >- // look up after which member the new offset should be inserted >- while (index >= OFFSETS_SHIFT) { >- 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; >- offsets[0]++; // number of used entries >- // if the offset is 0, adding a mark does not change anything >- if (dirProps == null || offset < 1) >- return; >- >- byte dirProp = dirProps.getBidiTypeAt(offset); >- // if the current char is a strong one or a digit, we change the >- // dirProp of the previous char to account for the inserted mark. >- if (dirProp == L || dirProp == R || dirProp == AL || dirProp == EN || dirProp == AN) >- index = offset - 1; >- else >- // if the current char is a neutral, we change its own dirProp >- index = offset; >- >- int dir = offsets[2]; // current structured text direction >- dirProps.setBidiTypeAt(index, STRONGS[dir]); >- return; >+ return offsets.getArray(); > } >- > } >diff --git src/org/eclipse/equinox/bidi/internal/STextSingle.java src/org/eclipse/equinox/bidi/internal/STextSingle.java >index 4f6e3b1..f4e9fac 100644 >--- src/org/eclipse/equinox/bidi/internal/STextSingle.java >+++ src/org/eclipse/equinox/bidi/internal/STextSingle.java >@@ -11,8 +11,8 @@ > package org.eclipse.equinox.bidi.internal; > > import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; > import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.custom.STextProcessorData; > > /** > * A base processor for structured text composed of two parts separated by a separator. >@@ -41,8 +41,8 @@ > * > * @see #getSeparators getSeparators > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >- return text.indexOf(this.getSeparators(environment).charAt(0), fromIndex); >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { >+ return procData.text.indexOf(this.getSeparators(procData.environment).charAt(0), fromIndex); > } > > /** >@@ -51,9 +51,9 @@ > * > * @return the length of <code>text</code>. > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >- return text.length(); >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { >+ STextProcessor.processSeparator(procData, separLocation); >+ return procData.text.length(); > } > > /** >@@ -64,5 +64,4 @@ > public int getSpecialsCount(STextEnvironment environment) { > return 1; > } >- > } >diff --git src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java >index cc8a1d2..4257284 100644 >--- src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java >+++ src/org/eclipse/equinox/bidi/internal/consumable/STextEmail.java >@@ -10,8 +10,8 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal.consumable; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >+import org.eclipse.equinox.bidi.STextHandler; > import org.eclipse.equinox.bidi.custom.STextCharTypes; > import org.eclipse.equinox.bidi.internal.STextDelimsEsc; > >@@ -27,12 +27,23 @@ > super("<>.:,;@"); //$NON-NLS-1$ > } > >+ /** >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following >+ * conditions are satisfied: >+ * <ul> >+ * <li>The current locale (as expressed by the environment >+ * language) is Arabic.</li> >+ * <li>The domain part of the email address contains >+ * at least one RTL character.</li> >+ * </ul> >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. >+ */ > public int getDirection(STextEnvironment environment, String text) { > return getDirection(environment, text, new STextCharTypes(text)); > } > > /** >- * @return {@link STextEngine#DIR_RTL DIR_RTL} if the following >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following > * conditions are satisfied: > * <ul> > * <li>The current locale (as expressed by the environment >@@ -40,12 +51,14 @@ > * <li>The domain part of the email address contains > * at least one RTL character.</li> > * </ul> >- * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}. >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. > */ > public int getDirection(STextEnvironment environment, String text, STextCharTypes dirProps) { >+ if (environment == null) >+ environment = STextEnvironment.DEFAULT; > String language = environment.getLanguage(); > if (!language.equals("ar")) //$NON-NLS-1$ >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > int domainStart; > domainStart = text.indexOf('@'); > if (domainStart < 0) >@@ -53,9 +66,9 @@ > for (int i = domainStart; i < text.length(); i++) { > byte dirProp = dirProps.getBidiTypeAt(i); > if (dirProp == AL || dirProp == R) >- return STextEngine.DIR_RTL; >+ return STextHandler.DIR_RTL; > } >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > } > > /** >@@ -71,5 +84,4 @@ > protected String getDelimiters() { > return "()\"\""; //$NON-NLS-1$ > } >- > } >diff --git src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java >index 81b3b41..30602c7 100644 >--- src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java >+++ src/org/eclipse/equinox/bidi/internal/consumable/STextJava.java >@@ -10,10 +10,10 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal.consumable; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; >+import org.eclipse.equinox.bidi.STextHandler; > import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.custom.STextProcessorData; > import org.eclipse.equinox.bidi.internal.STextActivator; > > /** >@@ -23,15 +23,13 @@ > * <p> > * In applications like an editor where parts of the text might be modified > * while other parts are not, the user may want to call >- * {@link STextEngine#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved using >- * the value returned in the first element of the <code>state</code> argument). >- * If both the content >- * of a line and its initial state have not changed, the user can be sure that >+ * {@link STextHandler#leanToFullText leanToFullText} >+ * separately on each line and save the initial <b>state</b> of each line (this is >+ * the final <b>state</b> of the previous line which can be retrieved using >+ * {@link STextHandler#getState}. >+ * If both the content of a line and its initial >+ * <b>state</b> have not changed, the user can be sure that > * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see STextEngine#leanToFullText explanation of state in leanToFullText > * > * @author Matitiahu Allouche > */ >@@ -59,7 +57,8 @@ > * <li>comments starting with slash-slash</li> > * </ol> > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { >+ String text = procData.text; > switch (caseNumber) { > case 1 : /* space */ > return text.indexOf(' ', fromIndex); >@@ -83,15 +82,16 @@ > * <li>skip until after a line separator</li> > * </ol> > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { > int location, counter, i; > >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); >+ String text = procData.text; > switch (caseNumber) { > case 1 : /* space */ > separLocation++; > while (separLocation < text.length() && text.charAt(separLocation) == ' ') { >- dirProps.setBidiTypeAt(separLocation, WS); >+ procData.dirProps.setBidiTypeAt(separLocation, WS); > separLocation++; > } > return separLocation; >@@ -115,12 +115,12 @@ > location = separLocation + 2; // skip the opening slash-aster > location = text.indexOf("*/", location); //$NON-NLS-1$ > if (location < 0) { >- state[0] = caseNumber; >+ procData.handler.setState(caseNumber); > return text.length(); > } > // we need to call processSeparator since text may follow the > // end of comment immediately without even a space >- STextProcessor.processSeparator(text, dirProps, offsets, location); >+ STextProcessor.processSeparator(procData, location); > return location + 2; > case 4 : /* slash-slash comment */ > location = text.indexOf(lineSep, separLocation + 2); >diff --git src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java >index 69d7a28..9f06938 100644 >--- src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java >+++ src/org/eclipse/equinox/bidi/internal/consumable/STextMath.java >@@ -10,8 +10,8 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal.consumable; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >+import org.eclipse.equinox.bidi.STextHandler; > import org.eclipse.equinox.bidi.custom.STextCharTypes; > import org.eclipse.equinox.bidi.custom.STextProcessor; > >@@ -29,12 +29,24 @@ > super("+-/*()="); //$NON-NLS-1$ > } > >+ /** >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following >+ * conditions are satisfied: >+ * <ul> >+ * <li>The current locale (as expressed by the environment >+ * language) is Arabic.</li> >+ * <li>The first strong character is an Arabic letter.</li> >+ * <li>If there is no strong character in the text, there is >+ * at least one Arabic-Indic digit in the text.</li> >+ * </ul> >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. >+ */ > public int getDirection(STextEnvironment environment, String text) { > return getDirection(environment, text, new STextCharTypes(text)); > } > > /** >- * @return {@link STextEngine#DIR_RTL DIR_RTL} if the following >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following > * conditions are satisfied: > * <ul> > * <li>The current locale (as expressed by the environment >@@ -43,25 +55,26 @@ > * <li>If there is no strong character in the text, there is > * at least one Arabic-Indic digit in the text.</li> > * </ul> >- * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}. >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. > */ > public int getDirection(STextEnvironment environment, String text, STextCharTypes dirProps) { >+ if (environment == null) >+ environment = STextEnvironment.DEFAULT; > String language = environment.getLanguage(); > if (!language.equals("ar")) //$NON-NLS-1$ >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > boolean flagAN = false; > for (int i = 0; i < text.length(); i++) { > byte dirProp = dirProps.getBidiTypeAt(i); > if (dirProp == AL) >- return STextEngine.DIR_RTL; >+ return STextHandler.DIR_RTL; > if (dirProp == L || dirProp == R) >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > if (dirProp == AN) > flagAN = true; > } > if (flagAN) >- return STextEngine.DIR_RTL; >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_RTL; >+ return STextHandler.DIR_LTR; > } >- > } >diff --git src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java >index 56b1baa..d38974b 100644 >--- src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java >+++ src/org/eclipse/equinox/bidi/internal/consumable/STextRegex.java >@@ -10,10 +10,9 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal.consumable; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; >-import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.STextHandler; >+import org.eclipse.equinox.bidi.custom.*; > > /** > * <code>STextRegex</code> is a processor for regular expressions. >@@ -21,15 +20,13 @@ > * <p> > * In applications like an editor where parts of the text might be modified > * while other parts are not, the user may want to call >- * {@link STextEngine#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved using >- * the value returned in the first element of the <code>state</code> argument). >- * If both the content >- * of a line and its initial state have not changed, the user can be sure that >+ * {@link STextHandler#leanToFullText leanToFullText} >+ * separately on each line and save the initial <b>state</b> of each line (this is >+ * the final <b>state</b> of the previous line which can be retrieved using >+ * {@link STextHandler#getState}. >+ * If both the content of a line and its initial >+ * <b>state</b> have not changed, the user can be sure that > * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see STextEngine#leanToFullText explanation of state in leanToFullText > * > * @author Matitiahu Allouche > */ >@@ -77,7 +74,7 @@ > * This method locates occurrences of the syntactic strings and of > * R, AL, EN, AN characters. > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { > // In this method, L, R, AL, AN and EN represent bidi categories > // as defined in the Unicode Bidirectional Algorithm > // ( http://www.unicode.org/reports/tr9/ ). >@@ -87,6 +84,7 @@ > // AN represents the category Arabic Number. > // EN represents the category European Number. > byte dirProp; >+ String text = procData.text; > > if (caseNumber < numberOfStrings) { > /* 1 *//* comment (?#...) */ >@@ -111,6 +109,7 @@ > // there never is a need for a mark before the first char > if (fromIndex <= 0) > fromIndex = 1; >+ STextCharTypes dirProps = procData.dirProps; > // look for R, AL, AN, EN which are potentially needing a mark > for (; fromIndex < text.length(); fromIndex++) { > dirProp = dirProps.getBidiTypeAt(fromIndex); >@@ -145,8 +144,9 @@ > /** > * This method process the special cases. > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { > int location; >+ String text = procData.text; > > switch (caseNumber) { > case 1 : /* comment (?#...) */ >@@ -154,13 +154,13 @@ > // initial state from previous line > location = 0; > } else { >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); > // skip the opening "(?#" > location = separLocation + 3; > } > location = text.indexOf(')', location); > if (location < 0) { >- state[0] = caseNumber; >+ procData.handler.setState(caseNumber); > return text.length(); > } > return location + 1; >@@ -170,7 +170,7 @@ > case 5 : /* conditional named back reference (?(<name>) */ > case 6 : /* conditional named back reference (?('name') */ > case 7 : /* named parentheses reference (?&name) */ >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); > // no need for calling processSeparator() for the following cases > // since the starting string contains a L char > case 8 : /* named group (?P<name> */ >@@ -194,20 +194,20 @@ > // initial state from previous line > location = 0; > } else { >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); > // skip the opening "\Q" > location = separLocation + 2; > } > location = text.indexOf("\\E", location); //$NON-NLS-1$ > if (location < 0) { >- state[0] = caseNumber; >+ procData.handler.setState(caseNumber); > return text.length(); > } > // set the dirProp for the "E" to L (Left to Right character) >- dirProps.setBidiTypeAt(location + 1, L); >+ procData.dirProps.setBidiTypeAt(location + 1, L); > return location + 2; > case 18 : /* R, AL, AN, EN */ >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); > return separLocation + 1; > > } >@@ -215,12 +215,24 @@ > return text.length(); > } > >+ /** >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following >+ * conditions are satisfied: >+ * <ul> >+ * <li>The current locale (as expressed by the environment >+ * language) is Arabic.</li> >+ * <li>The first strong character is an Arabic letter.</li> >+ * <li>If there is no strong character in the text, there is >+ * at least one Arabic-Indic digit in the text.</li> >+ * </ul> >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. >+ */ > public int getDirection(STextEnvironment environment, String text) { > return getDirection(environment, text, new STextCharTypes(text)); > } > > /** >- * @return {@link STextEngine#DIR_RTL DIR_RTL} if the following >+ * @return {@link STextHandler#DIR_RTL DIR_RTL} if the following > * conditions are satisfied: > * <ul> > * <li>The current locale (as expressed by the environment >@@ -229,22 +241,23 @@ > * <li>If there is no strong character in the text, the > * GUI is mirrored. > * </ul> >- * Otherwise, returns {@link STextEngine#DIR_LTR DIR_LTR}. >+ * Otherwise, returns {@link STextHandler#DIR_LTR DIR_LTR}. > */ > public int getDirection(STextEnvironment environment, String text, STextCharTypes dirProps) { >+ if (environment == null) >+ environment = STextEnvironment.DEFAULT; > String language = environment.getLanguage(); > if (!language.equals("ar")) //$NON-NLS-1$ >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > for (int i = 0; i < text.length(); i++) { > byte dirProp = dirProps.getBidiTypeAt(i); > if (dirProp == AL || dirProp == R) >- return STextEngine.DIR_RTL; >+ return STextHandler.DIR_RTL; > if (dirProp == L) >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_LTR; > } > if (environment.getMirrored()) >- return STextEngine.DIR_RTL; >- return STextEngine.DIR_LTR; >+ return STextHandler.DIR_RTL; >+ return STextHandler.DIR_LTR; > } >- > } >diff --git src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java >index 426d732..b31224e 100644 >--- src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java >+++ src/org/eclipse/equinox/bidi/internal/consumable/STextSql.java >@@ -10,10 +10,10 @@ > ******************************************************************************/ > package org.eclipse.equinox.bidi.internal.consumable; > >-import org.eclipse.equinox.bidi.STextEngine; > import org.eclipse.equinox.bidi.STextEnvironment; >-import org.eclipse.equinox.bidi.custom.STextCharTypes; >+import org.eclipse.equinox.bidi.STextHandler; > import org.eclipse.equinox.bidi.custom.STextProcessor; >+import org.eclipse.equinox.bidi.custom.STextProcessorData; > import org.eclipse.equinox.bidi.internal.STextActivator; > > /** >@@ -23,15 +23,13 @@ > * <p> > * In applications like an editor where parts of the text might be modified > * while other parts are not, the user may want to call >- * {@link STextEngine#leanToFullText leanToFullText} >- * separately on each line and save the initial state of each line (this is >- * the final state of the previous line which can be retrieved from the >- * value returned in the first element of the <code>state</code> argument). >- * If both the content >- * of a line and its initial state have not changed, the user can be sure that >+ * {@link STextHandler#leanToFullText leanToFullText} >+ * separately on each line and save the initial <b>state</b> of each line (this is >+ * the final <b>state</b> of the previous line which can be retrieved using >+ * {@link STextHandler#getState}. >+ * If both the content of a line and its initial >+ * <b>state</b> have not changed, the user can be sure that > * the last <i>full</i> text computed for this line has not changed either. >- * >- * @see STextEngine#leanToFullText explanation of state in leanToFullText > * > * @author Matitiahu Allouche > */ >@@ -60,7 +58,8 @@ > * <li>comments starting with hyphen-hyphen</li> > * </ol> > */ >- public int indexOfSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int caseNumber, int fromIndex) { >+ public int indexOfSpecial(STextProcessorData procData, int caseNumber, int fromIndex) { >+ String text = procData.text; > switch (caseNumber) { > case 1 : /* space */ > return text.indexOf(" ", fromIndex); //$NON-NLS-1$ >@@ -87,15 +86,16 @@ > * <li>skip until after a line separator</li> > * </ol> > */ >- public int processSpecial(STextEnvironment environment, String text, STextCharTypes dirProps, int[] offsets, int[] state, int caseNumber, int separLocation) { >+ public int processSpecial(STextProcessorData procData, int caseNumber, int separLocation) { > int location; >+ String text = procData.text; > >- STextProcessor.processSeparator(text, dirProps, offsets, separLocation); >+ STextProcessor.processSeparator(procData, separLocation); > switch (caseNumber) { > case 1 : /* space */ > separLocation++; > while (separLocation < text.length() && text.charAt(separLocation) == ' ') { >- dirProps.setBidiTypeAt(separLocation, WS); >+ procData.dirProps.setBidiTypeAt(separLocation, WS); > separLocation++; > } > return separLocation; >@@ -104,7 +104,7 @@ > while (true) { > location = text.indexOf('\'', location); > if (location < 0) { >- state[0] = caseNumber; >+ procData.handler.setState(caseNumber); > return text.length(); > } > if ((location + 1) < text.length() && text.charAt(location + 1) == '\'') { >@@ -133,12 +133,12 @@ > location = separLocation + 2; // skip the opening slash-aster > location = text.indexOf("*/", location); //$NON-NLS-1$ > if (location < 0) { >- state[0] = caseNumber; >+ procData.handler.setState(caseNumber); > return text.length(); > } > // we need to call processSeparator since text may follow the > // end of comment immediately without even a space >- STextProcessor.processSeparator(text, dirProps, offsets, location); >+ STextProcessor.processSeparator(procData, location); > return location + 2; > case 5 : /* hyphen-hyphen comment */ > location = text.indexOf(lineSep, separLocation + 2); >diff --git src/org/eclipse/equinox/bidi/package.html src/org/eclipse/equinox/bidi/package.html >index 611dee1..757eadc 100644 >--- src/org/eclipse/equinox/bidi/package.html >+++ src/org/eclipse/equinox/bidi/package.html >@@ -1,183 +1,191 @@ >-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >-<html> >-<head> >-<META name="Author" content="Matitiahu Allouche"> >-</head> >-<body bgcolor="white"> >- >-This package provides classes for >-processing structured text. >-<p> >-There are various types of structured text. Each type should >-be handled by a specific <i>processor</i>. A number of standard >-processors are supplied in the associated package >-{@link <a href="internal\consumable\package-summary.html"> >-org.eclipse.equinox.bidi.internal.consumable</a>}. >- >-<h2>Introduction to Structured Text</h2> >-<p> >-Bidirectional text offers interesting challenges to presentation systems. >-For plain text, the Unicode Bidirectional Algorithm >-(<a href="http://www.unicode.org/reports/tr9/">UBA</a>) >-generally specifies satisfactorily how to reorder bidirectional text for >-display. This algorithm is implemented in Java's presentation system. >-</p><p> >-However, all bidirectional text is not necessarily plain text. There >-are also instances of text structured to follow a given syntax, which >-should be reflected in the display order. The general algorithm, which >-has no awareness of these special cases, often gives incorrect results >-when displaying such structured text. >-</p><p> >-The general idea in handling structured text is to add directional >-formatting characters at proper locations in the text to supplement the >-standard algorithm, so that the final result is correctly displayed >-using the UBA. >-</p><p> >-A class which handles structured text is thus essentially a >-transformation engine which receives text without directional formatting >-characters as input and produces as output the same text with added >-directional formatting characters, hopefully in the minimum quantity >-which is sufficient to ensure correct display, considering the type of >-structured text involved. >-</p><p> >-In this package, text without directional formatting characters is >-called <b><i>lean</i></b> text while the text with added directional >-formatting characters is called <b><i>full</i></b> text. >-</p><p> >-The class {@link >-<a href="STextEngine.html"><b>STextEngine</b></a>} >-is the main tool for processing structured text. It facilitates >-handling several types of structured text, each type being handled >-by a specific >-{@link <a href="custom\STextProcessor.html"><b><i>processor</i></b></a>} :</p> >-<ul> >- <li>property (name=value)</li> >- <li>compound name (xxx_yy_zzzz)</li> >- <li>comma delimited list</li> >- <li>system(user)</li> >- <li>directory and file path</li> >- <li>e-mail address</li> >- <li>URL</li> >- <li>regular expression</li> >- <li>Xpath</li> >- <li>Java code</li> >- <li>SQL statements</li> >- <li>RTL arithmetic expressions</li> >-</ul> >-<p> >-For each of these types, a static instance is defined in <b>STextEngine</b>. >-These pre-defined instances can be used as argument in the methods of >-<b>STextEngine</b>. >-</p><p> >-Other classes in this package may be used to >-complement and facilitate the action of >-{@link <a href="STextEngine.html">STextEngine</a>}: >-<ul> >- <li>{@link <a href="STextEnvironment.html">STextEnvironment</a>} >- regroups details about the environment</li>. >- <li>{@link <a href="STextUtil.html">STextUtil</a>} >- provides a number of convenience methods to process some common types of >- structured text. When using methods in this class, there is no need >- to use other classes of this package. However, the other classes allow >- more precise control and possibly better performance.</li> >- <li>{@link <a href="STextStringRecord.html">STextStringRecord</a>} >- allows to record strings which are structured text with the >- type of the appropriate processor, >- so that another module can check if a given string has been recorded >- as a structured text string and run its processor.</li> >-</ul> >-<p> >-{@link <a href="STextEngine.html">STextEngine</a>} and the >-other classes mentioned above are intended for users who >-need to process structured text for which there already exist >-processors. >-<p> >-Developers who want to develop new processors to support types of structured text >-not currently supported can use the following components of the >-package {@link <a href="custom\package-summary.html"> >-org.eclipse.equinox.bidi.custom</a>}: >-<ul> >- <li>{@link <a href="custom\STextProcessor.html">STextProcessor</a>} >- is a generic processor to be used as superclass for specific >- processors.</li> >- <li>{@link <a href="custom\STextStringProcessor.html">STextStringProcessor</a>} >- allows retrieval of the defined processor types and of the >- corresponding processors.</li> >-</ul> >-<p> >-There are two other packages associated with the current one: >-<ul> >- <li>{@link <a href="internal\package-summary.html"> >- org.eclipse.equinox.bidi.internal</a>}</li> >- <li>{@link <a href="internal\consumable\package-summary.html"> >- org.eclipse.equinox.bidi.internal.consumable</a>}</li> >-</ul> >-The tools in the first package can serve as example of how to develop >-processors for currently unsupported types of structured text.<br> >-The latter package contains classes for the processors implementing >-the currently supported types of structured text. >-<p> >-However, users wishing to process the currently supported types of >-structured text typically don't need to interact with these >-two packages. >- >-<p> </p> >- >-<h2>Abbreviations used in the documentation of this package</h2> >- >-<dl> >-<dt><b>UBA</b><dd>Unicode Bidirectional Algorithm >- >-<dt><b>Bidi</b><dd>Bidirectional >- >-<dt><b>GUI</b><dd>Graphical User Interface >- >-<dt><b>UI</b><dd>User Interface >- >-<dt><b>LTR</b><dd>Left to Right >- >-<dt><b>RTL</b><dd>Right to Left >- >-<dt><b>LRM</b><dd>Left-to-Right Mark >- >-<dt><b>RLM</b><dd>Right-to-Left Mark >- >-<dt><b>LRE</b><dd>Left-to-Right Embedding >- >-<dt><b>RLE</b><dd>Right-to-Left Embedding >- >-<dt><b>PDF</b><dd>Pop Directional Formatting >-</dl> >- >-<p> </p> >- >-<h2>Known Limitations</h2> >- >-<p>The proposed solution is making extensive usage of LRM, RLM, LRE, RLE >-and PDF directional controls which are invisible but affect the way bidi >-text is displayed. The following related key points merit special >-attention:</p> >- >-<ul> >-<li>Implementations of the UBA on various platforms (e.g., Windows and >-Linux) are very similar but nevertheless have known differences. Those >-differences are minor and will not have a visible effect in most cases. >-However there might be cases in which the same bidi text on two >-platforms might look different. These differences will surface in Java >-applications when they use the platform visual components for their UI >-(e.g., AWT, SWT).</li> >- >-<li>It is assumed that the presentation engine supports LRE, RLE and >-PDF directional formatting characters.</li> >- >-<li>Because some presentation engines are not strictly conformant to the >-UBA, the implementation of structured text in this package adds LRM >-or RLM characters in association with LRE, RLE or PDF in cases where >-this would not be needed if the presentation engine was fully conformant >-to the UBA. Such added marks will not have harmful effects on >-conformant presentation engines and will help less conformant engines to >-achieve the desired presentation.</li> >-</ul> >- >-</body> >-</html> >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> >+<html> >+<head> >+<META name="Author" content="Matitiahu Allouche"> >+</head> >+<body bgcolor="white"> >+ >+This package provides classes for >+processing structured text. >+<p> >+There are various types of structured text. Each type should >+be handled by a specific <i>processor</i>. A number of standard >+processors are supplied in the associated package >+{@link <a href="internal\consumable\package-summary.html"> >+org.eclipse.equinox.bidi.internal.consumable</a>}. >+ >+<h2>Introduction to Structured Text</h2> >+<p> >+Bidirectional text offers interesting challenges to presentation systems. >+For plain text, the Unicode Bidirectional Algorithm >+(<a href="http://www.unicode.org/reports/tr9/">UBA</a>) >+generally specifies satisfactorily how to reorder bidirectional text for >+display. This algorithm is implemented in Java's presentation system. >+</p><p> >+However, all bidirectional text is not necessarily plain text. There >+are also instances of text structured to follow a given syntax, which >+should be reflected in the display order. The general algorithm, which >+has no awareness of these special cases, often gives incorrect results >+when displaying such structured text. >+</p><p> >+The general idea in handling structured text is to add directional >+formatting characters at proper locations in the text to supplement the >+standard algorithm, so that the final result is correctly displayed >+using the UBA. >+</p><p> >+A class which handles structured text is thus essentially a >+transformation engine which receives text without directional formatting >+characters as input and produces as output the same text with added >+directional formatting characters, hopefully in the minimum quantity >+which is sufficient to ensure correct display, considering the type of >+structured text involved. >+</p><p> >+In this package, text without directional formatting characters is >+called <b><i>lean</i></b> text while the text with added directional >+formatting characters is called <b><i>full</i></b> text. >+</p><p> >+The class {@link >+<a href="STextHandler.html"><b>STextHandler</b></a>} >+is the main tool for processing structured text. It facilitates >+handling several types of structured text, each type being handled >+by a specific >+{@link <a href="custom\STextProcessor.html"><b><i>processor</i></b></a>} :</p> >+<ul> >+ <li>property (name=value)</li> >+ <li>compound name (xxx_yy_zzzz)</li> >+ <li>comma delimited list</li> >+ <li>system(user)</li> >+ <li>directory and file path</li> >+ <li>e-mail address</li> >+ <li>URL</li> >+ <li>regular expression</li> >+ <li>Xpath</li> >+ <li>Java code</li> >+ <li>SQL statements</li> >+ <li>RTL arithmetic expressions</li> >+</ul> >+<p> >+For each of these types, a static instance is defined in >+{@link <a href="STextProcessorFactory.html">STextProcessorFactory</a>}. >+These pre-defined instances can be used as argument when initiating a >+<b>STextHandler</b>. >+</p><p> >+Other classes in this package may be used to >+complement and facilitate the action of >+{@link <a href="STextHandler.html">STextHandler</a>}: >+<ul> >+ <li>{@link <a href="STextEnvironment.html">STextEnvironment</a>} >+ regroups details about the environment.</li> >+ <li>{@link <a href="STextProcessorFactory.html">STextProcessorFactory</a>} >+ allows retrieval of the defined processor types and of the >+ corresponding processors.</li> >+ <li>{@link <a href="STextUtil.html">STextUtil</a>} >+ provides a number of convenience methods to process some common types of >+ structured text. When using methods in this class, there is no need >+ to use other classes of this package. However, the other classes allow >+ more precise control and possibly better performance.</li> >+ <li>{@link <a href="STextStringRecord.html">STextStringRecord</a>} >+ allows to record strings which are structured text with the >+ type of the appropriate processor, >+ so that another module can check if a given string has been recorded >+ as a structured text string and run its processor.</li> >+</ul> >+<p> >+{@link <a href="STextHandler.html">STextHandler</a>} and the >+other classes mentioned above are intended for users who >+need to process structured text for which there already exist >+processors. >+<p> >+Developers who want to develop new processors to support types of structured text >+not currently supported can use the following components of the >+package {@link <a href="custom\package-summary.html"> >+org.eclipse.equinox.bidi.custom</a>}: >+<ul> >+ <li>{@link <a href="custom\STextProcessor.html">STextProcessor</a>} >+ is a generic processor to be used as superclass for specific >+ processors.</li> >+ <li>{@link <a href="custom\STextProcessorData.html">STextProcessorData</a>} >+ regroups data which can be used by processors.</li> >+ <li>{@link <a href="custom\STextCharTypes.html">STextStringCharTypes</a>} >+ allows getting and setting the bidi class of characters.</li> >+ <li>{@link <a href="custom\STextOffsets.html">STextStringOffsets</a>} >+ allows manipulation of offsets at which directional control >+ characters are inserted.</li> >+</ul> >+<p> >+There are two other packages associated with the current one: >+<ul> >+ <li>{@link <a href="internal\package-summary.html"> >+ org.eclipse.equinox.bidi.internal</a>}</li> >+ <li>{@link <a href="internal\consumable\package-summary.html"> >+ org.eclipse.equinox.bidi.internal.consumable</a>}</li> >+</ul> >+The tools in the first package can serve as example of how to develop >+processors for currently unsupported types of structured text.<br> >+The latter package contains classes for the processors implementing >+the currently supported types of structured text. >+<p> >+However, users wishing to process the currently supported types of >+structured text typically don't need to interact with these >+two packages. >+ >+<p> </p> >+ >+<h2>Abbreviations used in the documentation of this package</h2> >+ >+<dl> >+<dt><b>UBA</b><dd>Unicode Bidirectional Algorithm >+ >+<dt><b>Bidi</b><dd>Bidirectional >+ >+<dt><b>GUI</b><dd>Graphical User Interface >+ >+<dt><b>UI</b><dd>User Interface >+ >+<dt><b>LTR</b><dd>Left to Right >+ >+<dt><b>RTL</b><dd>Right to Left >+ >+<dt><b>LRM</b><dd>Left-to-Right Mark >+ >+<dt><b>RLM</b><dd>Right-to-Left Mark >+ >+<dt><b>LRE</b><dd>Left-to-Right Embedding >+ >+<dt><b>RLE</b><dd>Right-to-Left Embedding >+ >+<dt><b>PDF</b><dd>Pop Directional Formatting >+</dl> >+ >+<p> </p> >+ >+<h2>Known Limitations</h2> >+ >+<p>The proposed solution is making extensive usage of LRM, RLM, LRE, RLE >+and PDF directional controls which are invisible but affect the way bidi >+text is displayed. The following related key points merit special >+attention:</p> >+ >+<ul> >+<li>Implementations of the UBA on various platforms (e.g., Windows and >+Linux) are very similar but nevertheless have known differences. Those >+differences are minor and will not have a visible effect in most cases. >+However there might be cases in which the same bidi text on two >+platforms might look different. These differences will surface in Java >+applications when they use the platform visual components for their UI >+(e.g., AWT, SWT).</li> >+ >+<li>It is assumed that the presentation engine supports LRE, RLE and >+PDF directional formatting characters.</li> >+ >+<li>Because some presentation engines are not strictly conformant to the >+UBA, the implementation of structured text in this package adds LRM >+or RLM characters in association with LRE, RLE or PDF in cases where >+this would not be needed if the presentation engine was fully conformant >+to the UBA. Such added marks will not have harmful effects on >+conformant presentation engines and will help less conformant engines to >+achieve the desired presentation.</li> >+</ul> >+ >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 183164
:
148967
|
157821
|
158092
|
158531
|
160015
|
160017
|
160081
|
160698
|
160858
|
162228
|
162229
|
164476
|
186038
|
186054
|
186488
|
186490
|
188406
|
188407
|
188408
|
188627
|
194078
|
194079
|
195082
|
195084
|
196575
|
196576
|
199068
|
199070
|
199113
|
199855
|
200008
|
200389
|
200629
|
200630
|
200631
|
200742
|
200743
|
200803
|
200805
|
200905
|
200907
|
201464
|
201465
|
201467
|
201468
|
201469
|
201470
|
201676
|
201677
|
201785
|
201787
|
202172
|
202173
|
205767
|
205768
|
206588
|
210657