You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2006/03/05 03:50:36 UTC
svn commit: r383270 - in /xmlgraphics/batik/branches/svg11: lib/
sources/org/apache/batik/css/engine/sac/ sources/org/apache/batik/gvt/text/
Author: deweese
Date: Sat Mar 4 18:50:35 2006
New Revision: 383270
URL: http://svn.apache.org/viewcvs?rev=383270&view=rev
Log:
1) Updated LICENSE.js.txt to reference license for tree table classes.
2) 38785 - Strange equals method in sac selectors. Thanks dvholten!
3) 38497 - enhancements to ArabicTextHandler (actually includes
several additional enhancements). Thanks dvholten!
Modified:
xmlgraphics/batik/branches/svg11/lib/LICENSE.js.txt
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractAttributeCondition.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractCombinatorCondition.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractDescendantSelector.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractElementSelector.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractSiblingSelector.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSAttributeCondition.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSConditionalSelector.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSLangCondition.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSPseudoClassCondition.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/text/ArabicTextHandler.java
Modified: xmlgraphics/batik/branches/svg11/lib/LICENSE.js.txt
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/lib/LICENSE.js.txt?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/lib/LICENSE.js.txt (original)
+++ xmlgraphics/batik/branches/svg11/lib/LICENSE.js.txt Sat Mar 4 18:50:35 2006
@@ -8,6 +8,57 @@
Rhino is licensed under the NPL (Netscape Public License) which
is duplicated below.
+The Rhino jar also includes four classes:
+ org.mozilla.javascript.tools.debugger.downloaded.AbstractCellEditor.java
+ org.mozilla.javascript.tools.debugger.downloaded.JTreeTable.java
+ org.mozilla.javascript.tools.debugger.downloaded.TreeTableModel.java
+ org.mozilla.javascript.tools.debugger.downloaded.TreeTableModelAdapter.java
+Which comes from:
+ http://java.sun.com/products/jfc/tsc/articles/treetable2
+
+Under the following license:
+
+Code sample
+License
+Copyright 1994-2006 Sun Microsystems, Inc. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+
+ * Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+
+Neither the name of Sun Microsystems, Inc. or the names of
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+This software is provided "AS IS," without a warranty of any kind. ALL
+EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+You acknowledge that this software is not designed, licensed or
+intended for use in the design, construction, operation or maintenance
+of any nuclear facility.
+
+
+
==============================================================================
AMENDMENTS
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractAttributeCondition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractAttributeCondition.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractAttributeCondition.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractAttributeCondition.java Sat Mar 4 18:50:35 2006
@@ -47,11 +47,11 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- AbstractAttributeCondition c = (AbstractAttributeCondition)obj;
- return c.value.equals(value);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ AbstractAttributeCondition c = (AbstractAttributeCondition)obj;
+ return c.value.equals(value);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractCombinatorCondition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractCombinatorCondition.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractCombinatorCondition.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractCombinatorCondition.java Sat Mar 4 18:50:35 2006
@@ -54,12 +54,12 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- AbstractCombinatorCondition c = (AbstractCombinatorCondition)obj;
- return c.firstCondition.equals(firstCondition) &&
- c.secondCondition.equals(secondCondition);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ AbstractCombinatorCondition c = (AbstractCombinatorCondition)obj;
+ return (c.firstCondition.equals(firstCondition) &&
+ c.secondCondition.equals(secondCondition));
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractDescendantSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractDescendantSelector.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractDescendantSelector.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractDescendantSelector.java Sat Mar 4 18:50:35 2006
@@ -56,11 +56,11 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- AbstractDescendantSelector s = (AbstractDescendantSelector)obj;
- return s.simpleSelector.equals(simpleSelector);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ AbstractDescendantSelector s = (AbstractDescendantSelector)obj;
+ return s.simpleSelector.equals(simpleSelector);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractElementSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractElementSelector.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractElementSelector.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractElementSelector.java Sat Mar 4 18:50:35 2006
@@ -46,8 +46,8 @@
* Creates a new ElementSelector object.
*/
protected AbstractElementSelector(String uri, String name) {
- namespaceURI = uri;
- localName = name;
+ namespaceURI = uri;
+ localName = name;
}
/**
@@ -55,12 +55,12 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- AbstractElementSelector s = (AbstractElementSelector)obj;
- return s.namespaceURI.equals(namespaceURI) &&
- s.localName.equals(localName);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ AbstractElementSelector s = (AbstractElementSelector)obj;
+ return (s.namespaceURI.equals(namespaceURI) &&
+ s.localName.equals(localName));
}
/**
@@ -68,7 +68,7 @@
* org.w3c.css.sac.ElementSelector#getNamespaceURI()}.
*/
public String getNamespaceURI() {
- return namespaceURI;
+ return namespaceURI;
}
/**
@@ -76,7 +76,7 @@
* org.w3c.css.sac.ElementSelector#getLocalName()}.
*/
public String getLocalName() {
- return localName;
+ return localName;
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractSiblingSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractSiblingSelector.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractSiblingSelector.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/AbstractSiblingSelector.java Sat Mar 4 18:50:35 2006
@@ -70,11 +70,11 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- AbstractSiblingSelector s = (AbstractSiblingSelector)obj;
- return s.simpleSelector.equals(simpleSelector);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ AbstractSiblingSelector s = (AbstractSiblingSelector)obj;
+ return s.simpleSelector.equals(simpleSelector);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSAttributeCondition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSAttributeCondition.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSAttributeCondition.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSAttributeCondition.java Sat Mar 4 18:50:35 2006
@@ -62,13 +62,13 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (!super.equals(obj)) {
- return false;
- }
- CSSAttributeCondition c = (CSSAttributeCondition)obj;
- return c.namespaceURI.equals(namespaceURI) &&
- c.localName.equals(localName) &&
- c.specified == specified;
+ if (!super.equals(obj)) {
+ return false;
+ }
+ CSSAttributeCondition c = (CSSAttributeCondition)obj;
+ return (c.namespaceURI.equals(namespaceURI) &&
+ c.localName.equals(localName) &&
+ c.specified == specified);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSConditionalSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSConditionalSelector.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSConditionalSelector.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSConditionalSelector.java Sat Mar 4 18:50:35 2006
@@ -58,12 +58,12 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- CSSConditionalSelector s = (CSSConditionalSelector)obj;
- return s.simpleSelector.equals(simpleSelector) &&
- s.condition.equals(condition);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ CSSConditionalSelector s = (CSSConditionalSelector)obj;
+ return (s.simpleSelector.equals(simpleSelector) &&
+ s.condition.equals(condition));
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSLangCondition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSLangCondition.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSLangCondition.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSLangCondition.java Sat Mar 4 18:50:35 2006
@@ -50,11 +50,11 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (obj == null || !(obj.getClass() != getClass())) {
- return false;
- }
- CSSLangCondition c = (CSSLangCondition)obj;
- return c.lang.equals(lang);
+ if (obj == null || (obj.getClass() != getClass())) {
+ return false;
+ }
+ CSSLangCondition c = (CSSLangCondition)obj;
+ return c.lang.equals(lang);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSPseudoClassCondition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSPseudoClassCondition.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSPseudoClassCondition.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/css/engine/sac/CSSPseudoClassCondition.java Sat Mar 4 18:50:35 2006
@@ -48,11 +48,11 @@
* @param obj the reference object with which to compare.
*/
public boolean equals(Object obj) {
- if (!super.equals(obj)) {
- return false;
- }
- CSSPseudoClassCondition c = (CSSPseudoClassCondition)obj;
- return c.namespaceURI.equals(namespaceURI);
+ if (!super.equals(obj)) {
+ return false;
+ }
+ CSSPseudoClassCondition c = (CSSPseudoClassCondition)obj;
+ return c.namespaceURI.equals(namespaceURI);
}
/**
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/text/ArabicTextHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/text/ArabicTextHandler.java?rev=383270&r1=383269&r2=383270&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/text/ArabicTextHandler.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/gvt/text/ArabicTextHandler.java Sat Mar 4 18:50:35 2006
@@ -1,6 +1,6 @@
/*
- Copyright 2001,2003 The Apache Software Foundation
+ Copyright 2001,2003,2006 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -53,12 +53,19 @@
GVTAttributedCharacterIterator.TextAttribute.ARABIC_MEDIAL;
/**
+ * private ctor prevents unnecessary instantiation of this class.
+ */
+ private ArabicTextHandler() {
+
+ }
+
+ /*
* If the AttributedString contains any arabic chars, assigns an
* arabic form attribute, i.e. initial|medial|terminal|isolated,
* to each arabic char.
*
* @param as The string to attach the arabic form attributes to.
- * @return An attributed string with arabic form attributes.
+ * @return An attributed string with arabic form attributes.
*/
public static AttributedString assignArabicForms(AttributedString as) {
@@ -73,47 +80,54 @@
// reorder that part of the string so that it becomes tAB
// construct the reordered ACI
AttributedCharacterIterator aci = as.getIterator();
- boolean didSomeReordering = false;
int numChars = aci.getEndIndex() - aci.getBeginIndex();
- int charOrder[] = new int[numChars];
- for (int i = 0; i < numChars; i++) {
- charOrder[i] = i + aci.getBeginIndex();
- }
- for (int i = 1; i < numChars-1; i++) {
- char c = aci.setIndex(aci.getBeginIndex() + i);
- if (arabicCharTransparent(c)) {
- char prevChar = aci.setIndex(aci.getBeginIndex() + i-1);
- char nextChar = aci.setIndex(aci.getBeginIndex() + i+1);
- if (charMap.get("" + prevChar + nextChar) != null) {
- // found a ligature, separated by a transparent char
- didSomeReordering = true;
- int temp = charOrder[i];
- charOrder[i] = charOrder[i-1];
- charOrder[i-1] = temp;
+ int charOrder[] = null;
+ if (numChars >= 3) {
+ char prevChar = aci.first();
+ char c = aci.next();
+ int i = 1;
+ for (char nextChar = aci.next();
+ nextChar != AttributedCharacterIterator.DONE;
+ prevChar = c, c = nextChar, nextChar = aci.next(), i++) {
+ if (arabicCharTransparent(c)) {
+ if (hasSubstitute(prevChar, nextChar)) {
+ // found a ligature, separated by a transparent char
+ if (charOrder == null) {
+ charOrder = new int[numChars];
+ for (int j = 0; j < numChars; i++) {
+ charOrder[i] = j + aci.getBeginIndex();
+ }
+ }
+ int temp = charOrder[i];
+ charOrder[i] = charOrder[i-1];
+ charOrder[i-1] = temp;
+ }
}
}
}
- if (didSomeReordering) {
+ if (charOrder != null) {
// need to reconstruct the reordered attributed string
- String reorderedString = "";
+ StringBuffer reorderedString = new StringBuffer(numChars);
char c;
for (int i = 0; i < numChars; i++) {
c = aci.setIndex(charOrder[i]);
- reorderedString += c;
+ reorderedString.append( c );
}
- AttributedString reorderedAS = new AttributedString(reorderedString);
+ AttributedString reorderedAS;
+ reorderedAS = new AttributedString(reorderedString.toString());
+
for (int i = 0; i < numChars; i++) {
aci.setIndex(charOrder[i]);
Map attributes = aci.getAttributes();
reorderedAS.addAttributes(attributes, i, i+1);
}
- if ((charOrder[0] == (aci.getBeginIndex()+1)) &&
- (charOrder[1] == aci.getBeginIndex())) {
- // have swapped the first 2 chars, may need to move
+
+ if (charOrder[0] != aci.getBeginIndex()) {
+ // have swapped the first char. Need to move
// any position attributes
- aci.first();
+ aci.setIndex(charOrder[0]);
Float x = (Float) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.X);
Float y = (Float) aci.getAttribute(
@@ -122,17 +136,17 @@
if (x != null && !x.isNaN()) {
reorderedAS.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.X,
- new Float(Float.NaN), 1, 2);
+ new Float(Float.NaN), charOrder[0], charOrder[0]+1);
reorderedAS.addAttribute
- (GVTAttributedCharacterIterator.TextAttribute.X,
+ (GVTAttributedCharacterIterator.TextAttribute.X,
x, 0, 1);
}
if (y != null && !y.isNaN()) {
reorderedAS.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.Y,
- new Float(Float.NaN), 1, 2);
+ new Float(Float.NaN), charOrder[0], charOrder[0]+1);
reorderedAS.addAttribute
- (GVTAttributedCharacterIterator.TextAttribute.Y,
+ (GVTAttributedCharacterIterator.TextAttribute.Y,
y, 0, 1);
}
}
@@ -140,15 +154,23 @@
}
// first assign none to all arabic letters
- int c;
aci = as.getIterator();
- for (int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++) {
- c = aci.setIndex(i);
+ int runStart = -1;
+ int idx = aci.getBeginIndex();
+ for (int c = aci.first();
+ c != AttributedCharacterIterator.DONE;
+ c = aci.next(), idx++) {
if ((c >= arabicStart) && (c <= arabicEnd)) {
- as.addAttribute(ARABIC_FORM, ARABIC_NONE,i, i+1);
+ if (runStart == -1)
+ runStart = idx;
+ } else if (runStart != -1) {
+ as.addAttribute(ARABIC_FORM, ARABIC_NONE, runStart, idx);
+ runStart = -1;
}
}
-
+ if (runStart != -1)
+ as.addAttribute(ARABIC_FORM, ARABIC_NONE, runStart, idx);
+
aci = as.getIterator(); // Make sure ACI tracks ARABIC_FORM
int end = aci.getBeginIndex();
@@ -162,16 +184,16 @@
if (currentForm == null) {
// only modify if the chars in the run are arabic
- continue;
+ continue;
}
-
+
int currentIndex = start;
int prevCharIndex = start-1;
while (currentIndex < end) {
char prevChar = currentChar;
currentChar= aci.setIndex(currentIndex);
- while (arabicCharTransparent(currentChar) &&
+ while (arabicCharTransparent(currentChar) &&
(currentIndex < end)) {
currentIndex++;
currentChar = aci.setIndex(currentIndex);
@@ -188,7 +210,7 @@
&& arabicCharShapesLeft(currentChar)) {
// Increment the form of the previous char
prevForm = new Integer(prevForm.intValue()+1);
- as.addAttribute(ARABIC_FORM, prevForm,
+ as.addAttribute(ARABIC_FORM, prevForm,
prevCharIndex, prevCharIndex+1);
// and set the form of the current char to INITIAL
@@ -245,9 +267,9 @@
* @return True if at least one char is arabic, false otherwise.
*/
public static boolean containsArabic(AttributedCharacterIterator aci) {
- char c;
- for (int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++) {
- c = aci.setIndex(i);
+ for (char c = aci.first();
+ c != AttributedCharacterIterator.DONE;
+ c = aci.next()) {
if (arabicChar(c)) {
return true;
}
@@ -263,7 +285,7 @@
*/
public static boolean arabicCharTransparent(char c) {
int charVal = c;
- if ((charVal < 0x064B) || (charVal > 0x06ED))
+ if ((charVal < 0x064B) || (charVal > 0x06ED))
return false;
if ((charVal <= 0x0655) ||
@@ -353,6 +375,17 @@
return arabicCharShapesRight(c);
}
+ public static boolean hasSubstitute(char ch1, char ch2) {
+ if ((ch1 < doubleCharFirst) || (ch1 > doubleCharLast)) return false;
+
+ int [][]remaps = doubleCharRemappings[ch1-doubleCharFirst];
+ if (remaps == null) return false;
+ for (int i=0; i<remaps.length; i++) {
+ if (remaps[i][0] == ch2)
+ return true;
+ }
+ return false;
+ }
/**
* Will try and find a substitute character of the specified form.
@@ -365,16 +398,29 @@
* @return The unicode value of the substutute char, or -1 if no susbtitue
* exists.
*/
- public static int getSubstituteChar(String unicode, int form) {
+ public static int getSubstituteChar(char ch1, char ch2, int form) {
if (form == 0) return -1;
- int chars[] = (int[])charMap.get(unicode);
- if (chars == null) return -1;
+ if ((ch1 < doubleCharFirst) || (ch1 > doubleCharLast)) return -1;
- if (chars[form-1] > 0)
- return chars[form-1];
+ int [][]remaps = doubleCharRemappings[ch1-doubleCharFirst];
+ if (remaps == null) return -1;
+ for (int i=0; i<remaps.length; i++) {
+ if (remaps[i][0] == ch2)
+ return remaps[i][form];
+ }
return -1;
}
+ public static int getSubstituteChar(char ch, int form) {
+ if (form == 0) return -1;
+ if ((ch < singleCharFirst) || (ch > singleCharLast)) return -1;
+
+ int chars[] = singleCharRemappings[ch-singleCharFirst];
+ if (chars == null) return -1;
+
+ return chars[form-1];
+ }
+
/**
* Where possible substitues plain arabic glyphs with their shaped
* forms. This is needed when the arabic text is rendered using
@@ -388,66 +434,68 @@
* @return A String containing the shaped versions of the arabic characters
*/
public static String createSubstituteString(AttributedCharacterIterator aci) {
-
- String substString = "";
- for (int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++) {
+ int start = aci.getBeginIndex();
+ int end = aci.getEndIndex();
+ int numChar = end-start;
+ StringBuffer substString = new StringBuffer(numChar);
+ for (int i=start; i< end; i++) {
char c = aci.setIndex(i);
- if (arabicChar(c)) {
- Integer form = (Integer)aci.getAttribute(ARABIC_FORM);
- // see if the c is the start of a ligature
- if (charStartsLigature(c) && i < aci.getEndIndex()) {
- char nextChar = aci.setIndex(i+1);
- Integer nextForm = (Integer)aci.getAttribute(ARABIC_FORM);
- if (form != null && nextForm != null) {
- if (form.equals(ARABIC_TERMINAL)
- && nextForm.equals(ARABIC_INITIAL)) {
- // look for an isolated ligature
- int substChar = ArabicTextHandler.getSubstituteChar
- ("" + c + nextChar,ARABIC_ISOLATED.intValue());
- if (substChar > -1) {
- substString += (char)substChar;
- i++;
- continue;
- }
- } else if (form.equals(ARABIC_TERMINAL)) {
- // look for a terminal ligature
- int substChar = ArabicTextHandler.getSubstituteChar
- ("" + c + nextChar,ARABIC_TERMINAL.intValue());
- if (substChar > -1) {
- substString += (char)substChar;
- i++;
- continue;
- }
- } else if (form.equals(ARABIC_MEDIAL)
- && nextForm.equals(ARABIC_MEDIAL)) {
- // look for a medial ligature
- int substChar = ArabicTextHandler.getSubstituteChar
- ("" + c + nextChar,ARABIC_MEDIAL.intValue());
- if (substChar > -1) {
- substString += (char)substChar;
- i++;
- continue;
- }
+ if (!arabicChar(c)) {
+ substString.append(c);
+ continue;
+ }
+
+ Integer form = (Integer)aci.getAttribute(ARABIC_FORM);
+ // see if the c is the start of a ligature
+ if (charStartsLigature(c) && (i+1 < end)) {
+ char nextChar = aci.setIndex(i+1);
+ Integer nextForm = (Integer)aci.getAttribute(ARABIC_FORM);
+ if (form != null && nextForm != null) {
+ if (form.equals(ARABIC_TERMINAL)
+ && nextForm.equals(ARABIC_INITIAL)) {
+ // look for an isolated ligature
+ int substChar = ArabicTextHandler.getSubstituteChar
+ (c, nextChar,ARABIC_ISOLATED.intValue());
+ if (substChar > -1) {
+ substString.append((char)substChar);
+ i++;
+ continue;
+ }
+ } else if (form.equals(ARABIC_TERMINAL)) {
+ // look for a terminal ligature
+ int substChar = ArabicTextHandler.getSubstituteChar
+ (c, nextChar,ARABIC_TERMINAL.intValue());
+ if (substChar > -1) {
+ substString.append((char)substChar);
+ i++;
+ continue;
+ }
+ } else if (form.equals(ARABIC_MEDIAL)
+ && nextForm.equals(ARABIC_MEDIAL)) {
+ // look for a medial ligature
+ int substChar = ArabicTextHandler.getSubstituteChar
+ (c, nextChar,ARABIC_MEDIAL.intValue());
+ if (substChar > -1) {
+ substString.append((char)substChar);
+ i++;
+ continue;
}
}
}
+ }
- // couln't find a matching ligature so just look for a simple substitution
- if (form != null && form.intValue() > 0) {
- int substChar = ArabicTextHandler.getSubstituteChar(""+c, form.intValue());
- if (substChar > -1) {
- substString += (char)substChar;
- } else {
- substString += c;
- }
- } else {
- substString += c;
+ // couldn't find a matching ligature so just look for a
+ // simple substitution
+ if (form != null && form.intValue() > 0) {
+ int substChar = getSubstituteChar(c, form.intValue());
+ if (substChar > -1) {
+ c = (char)substChar;
}
- } else {
- substString += c;
}
+ substString.append(c);
}
- return substString;
+
+ return substString.toString();
}
/**
@@ -493,7 +541,7 @@
*/
public static boolean isLigature(char c) {
int charVal = c;
- if ((charVal < 0xFE70) || (charVal > 0xFEFC))
+ if ((charVal < 0xFE70) || (charVal > 0xFEFC))
return false;
if ((charVal <= 0xFE72) ||
@@ -506,176 +554,114 @@
}
- static {
-
- // constructs the character map that maps arabic characters and
- // ligature to their various forms
- // NOTE: the unicode values for ligatures are stored here in
- // visual order (not logical order)
-
- int chars1[] = {0xFE70, -1, -1, -1}; // isolated, final, initial, medial
- charMap.put(new String("" + (char)0x064B + (char)0x0020), chars1);
-
- int chars2[] = {-1, -1, -1, 0xFE71};
- charMap.put(new String("" + (char)0x064B + (char)0x0640), chars2);
-
- int chars3[] = {0xFE72, -1, -1, -1};
- charMap.put(new String("" + (char)0x064C + (char)0x0020), chars3);
-
- int chars4[] = {0xFE74, -1, -1, -1};
- charMap.put(new String("" + (char)0x064D + (char)0x0020), chars4);
-
- int chars5[] = {0xFE76, -1, -1, -1};
- charMap.put(new String("" + (char)0x064E + (char)0x0020), chars5);
-
- int chars6[] = {-1, -1, -1, 0xFE77};
- charMap.put(new String("" + (char)0x064E + (char)0x0640), chars6);
-
- int chars7[] = {0xFE78, -1, -1, -1};
- charMap.put(new String("" + (char)0x064F + (char)0x0020), chars7);
-
- int chars8[] = {-1, -1, -1, 0xFE79};
- charMap.put(new String("" + (char)0x064F + (char)0x0640), chars8);
-
- int chars9[] = {0xFE7A, -1, -1, -1};
- charMap.put(new String("" + (char)0x0650 + (char)0x0020), chars9);
-
- int chars10[] = {-1, -1, -1, 0xFE7B};
- charMap.put(new String("" + (char)0x0650 + (char)0x0640), chars10);
-
- int chars11[] = {0xFE7C, -1, -1, -1};
- charMap.put(new String("" + (char)0x0651 + (char)0x0020), chars11);
-
- int chars12[] = {-1, -1, -1, 0xFE7D};
- charMap.put(new String("" + (char)0x0651 + (char)0x0640), chars12);
-
- int chars13[] = {0xFE7E, -1, -1, -1};
- charMap.put(new String("" + (char)0x0652 + (char)0x0020), chars13);
-
- int chars14[] = {-1, -1, -1, 0xFE7F};
- charMap.put(new String("" + (char)0x0652 + (char)0x0640), chars14);
-
- int chars15[] = {0xFE80, -1, -1, -1};
- charMap.put(new String("" + (char)0x0621), chars15);
-
- int chars16[] = {0xFE81, 0xFE82, -1, -1};
- charMap.put(new String("" + (char)0x0622), chars16);
-
- int chars17[] = {0xFE83, 0xFE84, -1, -1};
- charMap.put(new String("" + (char)0x0623), chars17);
-
- int chars18[] = {0xFE85, 0xFE86, -1, -1};
- charMap.put(new String("" + (char)0x0624), chars18);
-
- int chars19[] = {0xFE87, 0xFE88, -1, -1};
- charMap.put(new String("" + (char)0x0625), chars19);
-
- int chars20[] = {0xFE89, 0xFE8A, 0xFE8B, 0xFE8C};
- charMap.put(new String("" + (char)0x0626), chars20);
-
- int chars21[] = {0xFE8D, 0xFE8E, -1, -1};
- charMap.put(new String("" + (char)0x0627), chars21);
-
- int chars22[] = {0xFE8F, 0xFE90, 0xFE91, 0xFE92};
- charMap.put(new String("" + (char)0x0628), chars22);
-
- int chars23[] = {0xFE93, 0xFE94, -1, -1};
- charMap.put(new String("" + (char)0x0629), chars23);
-
- int chars24[] = {0xFE95, 0xFE96, 0xFE97, 0xFE98};
- charMap.put(new String("" + (char)0x062A), chars24);
-
- int chars25[] = {0xFE99, 0xFE9A, 0xFE9B, 0xFE9C};
- charMap.put(new String("" + (char)0x062B), chars25);
-
- int chars26[] = {0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0};
- charMap.put(new String("" + (char)0x062C), chars26);
-
- int chars27[] = {0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4};
- charMap.put(new String("" + (char)0x062D), chars27);
-
- int chars28[] = {0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8};
- charMap.put(new String("" + (char)0x062E), chars28);
-
- int chars29[] = {0xFEA9, 0xFEAA, -1, -1};
- charMap.put(new String("" + (char)0x062F), chars29);
-
- int chars30[] = {0xFEAB, 0xFEAC, -1, -1};
- charMap.put(new String("" + (char)0x0630), chars30);
-
- int chars31[] = {0xFEAD, 0xFEAE, -1, -1};
- charMap.put(new String("" + (char)0x0631), chars31);
-
- int chars32[] = {0xFEAF, 0xFEB0, -1, -1};
- charMap.put(new String("" + (char)0x0632), chars32);
-
- int chars33[] = {0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4};
- charMap.put(new String("" + (char)0x0633), chars33);
-
- int chars34[] = {0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8};
- charMap.put(new String("" + (char)0x0634), chars34);
-
- int chars35[] = {0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC};
- charMap.put(new String("" + (char)0x0635), chars35);
-
- int chars36[] = {0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0};
- charMap.put(new String("" + (char)0x0636), chars36);
-
- int chars37[] = {0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4};
- charMap.put(new String("" + (char)0x0637), chars37);
-
- int chars38[] = {0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8};
- charMap.put(new String("" + (char)0x0638), chars38);
-
- int chars39[] = {0xFEC9, 0xFECA, 0xFECB, 0xFECC};
- charMap.put(new String("" + (char)0x0639), chars39);
-
- int chars40[] = { 0xFECD, 0xFECE, 0xFECF, 0xFED0};
- charMap.put(new String("" + (char)0x063A), chars40);
-
- int chars41[] = {0xFED1, 0xFED2, 0xFED3, 0xFED4};
- charMap.put(new String("" + (char)0x0641), chars41);
-
- int chars42[] = {0xFED5, 0xFED6, 0xFED7, 0xFED8};
- charMap.put(new String("" + (char)0x0642), chars42);
-
- int chars43[] = {0xFED9, 0xFEDA, 0xFEDB, 0xFEDC};
- charMap.put(new String("" + (char)0x0643), chars43);
-
- int chars44[] = {0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0};
- charMap.put(new String("" + (char)0x0644), chars44);
-
- int chars45[] = {0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4};
- charMap.put(new String("" + (char)0x0645), chars45);
-
- int chars46[] = {0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8};
- charMap.put(new String("" + (char)0x0646), chars46);
-
- int chars47[] = {0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC};
- charMap.put(new String("" + (char)0x0647), chars47);
-
- int chars48[] = {0xFEED, 0xFEEE, -1, -1};
- charMap.put(new String("" + (char)0x0648), chars48);
-
- int chars49[] = {0xFEEF, 0xFEF0, -1, -1};
- charMap.put(new String("" + (char)0x0649), chars49);
-
- int chars50[] = {0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4};
- charMap.put(new String("" + (char)0x064A), chars50);
-
- int chars51[] = {0xFEF5, 0xFEF6, -1, -1};
- charMap.put(new String("" + (char)0x0622 + (char)0x0644), chars51);
-
- int chars52[] = {0xFEF7, 0xFEF8, -1, -1};
- charMap.put(new String("" + (char)0x0623 + (char)0x0644), chars52);
-
- int chars53[] = {0xFEF9, 0xFEFA, -1, -1};
- charMap.put(new String("" + (char)0x0625 + (char)0x0644), chars53);
-
- int chars54[] = {0xFEFB, 0xFEFC, -1, -1};
- charMap.put(new String("" + (char)0x0627 + (char)0x0644), chars54);
-
- }
-
-
+ // constructs the character map that maps arabic characters and
+ // ligature to their various forms
+ // NOTE: the unicode values for ligatures are stored here in
+ // visual order (not logical order)
+
+ // Single char remappings:
+ static int singleCharFirst=0x0621;
+ static int singleCharLast =0x064A;
+ static int [][] singleCharRemappings = {
+ // isolated, final, initial, medial
+ {0xFE80, -1, -1, -1}, // 0x0621
+ {0xFE81, 0xFE82, -1, -1}, // 0x0622
+ {0xFE83, 0xFE84, -1, -1}, // 0x0623
+ {0xFE85, 0xFE86, -1, -1}, // 0x0624
+ {0xFE87, 0xFE88, -1, -1}, // 0x0625
+ {0xFE89, 0xFE8A, 0xFE8B, 0xFE8C}, // 0x0626
+ {0xFE8D, 0xFE8E, -1, -1}, // 0x0627
+ {0xFE8F, 0xFE90, 0xFE91, 0xFE92}, // 0x0628
+ {0xFE93, 0xFE94, -1, -1}, // 0x0629
+ {0xFE95, 0xFE96, 0xFE97, 0xFE98}, // 0x062A
+ {0xFE99, 0xFE9A, 0xFE9B, 0xFE9C}, // 0x062B
+ {0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0}, // 0x062C
+ {0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4}, // 0x062D
+ {0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8}, // 0x062E
+ {0xFEA9, 0xFEAA, -1, -1}, // 0x062F
+ {0xFEAB, 0xFEAC, -1, -1}, // 0x0630
+ {0xFEAD, 0xFEAE, -1, -1}, // 0x0631
+ {0xFEAF, 0xFEB0, -1, -1}, // 0x0632
+ {0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4}, // 0x0633
+ {0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8}, // 0x0634
+ {0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC}, // 0x0635
+ {0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0}, // 0x0636
+ {0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4}, // 0x0637
+ {0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8}, // 0x0638
+ {0xFEC9, 0xFECA, 0xFECB, 0xFECC}, // 0x0639
+ {0xFECD, 0xFECE, 0xFECF, 0xFED0}, // 0x063A
+
+ null, // 0x063B
+ null, // 0x063C
+ null, // 0x063D
+ null, // 0x063E
+ null, // 0x063F
+ null, // 0x0640
+
+ {0xFED1, 0xFED2, 0xFED3, 0xFED4}, // 0x0641
+ {0xFED5, 0xFED6, 0xFED7, 0xFED8}, // 0x0642
+ {0xFED9, 0xFEDA, 0xFEDB, 0xFEDC}, // 0x0643
+ {0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0}, // 0x0644
+ {0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4}, // 0x0645
+ {0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8}, // 0x0646
+ {0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC}, // 0x0647
+ {0xFEED, 0xFEEE, -1, -1}, // 0x0648
+ {0xFEEF, 0xFEF0, -1, -1}, // 0x0649
+ {0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4}}; // 0x064A
+
+ static int doubleCharFirst=0x0622;
+ static int doubleCharLast =0x0652;
+ static int [][][] doubleCharRemappings = {
+ // 2nd Char, isolated, final, initial, medial
+ {{0x0644, 0xFEF5, 0xFEF6, -1, -1}}, // 0x0622
+ {{0x0644, 0xFEF7, 0xFEF8, -1, -1}}, // 0x0623
+ null, // 0x0624
+ {{0x0644, 0xFEF9, 0xFEFA, -1, -1}}, // 0x0625
+ null, // 0x0626
+ {{0x0644, 0xFEFB, 0xFEFC, -1, -1}}, // 0x0627
+
+ null, // 0x0628
+ null, // 0x0629
+ null, // 0x0630
+ null, // 0x0631
+ null, // 0x0632
+ null, // 0x0633
+ null, // 0x0634
+ null, // 0x0635
+ null, // 0x0636
+ null, // 0x0637
+ null, // 0x0638
+ null, // 0x0639
+ null, // 0x063A
+ null, // 0x063B
+ null, // 0x063C
+ null, // 0x063D
+ null, // 0x063E
+ null, // 0x063F
+ null, // 0x0640
+ null, // 0x0641
+ null, // 0x0642
+ null, // 0x0643
+ null, // 0x0644
+ null, // 0x0645
+ null, // 0x0646
+ null, // 0x0647
+ null, // 0x0648
+ null, // 0x0649
+ null, // 0x064A
+
+ {{0x0020, 0xFE70, -1, -1, -1}, // 0x064B
+ {0x0640, -1, -1, -1, 0xFE71}},
+ {{0x0020, 0xFE72, -1, -1, -1}}, // 0x064C
+ {{0x0020, 0xFE74, -1, -1, -1}}, // 0x064D
+ {{0x0020, 0xFE76, -1, -1, -1}, // 0x064E
+ {0x0640, -1, -1, -1, 0xFE77}},
+ {{0x0020, 0xFE78, -1, -1, -1}, // 0x064F
+ {0x0640, -1, -1, -1, 0xFE79}},
+ {{0x0020, 0xFE7A, -1, -1, -1}, // 0x0650
+ {0x0640, -1, -1, -1, 0xFE7B}},
+ {{0x0020, 0xFE7C, -1, -1, -1}, // 0x0651
+ {0x0640, -1, -1, -1, 0xFE7D}},
+ {{0x0020, 0xFE7E, -1, -1, -1}, // 0x0652
+ {0x0640, -1, -1, -1, 0xFE7F}}};
}