52 |
52 |
53 package sun.text.bidi; |
53 package sun.text.bidi; |
54 |
54 |
55 import java.io.IOException; |
55 import java.io.IOException; |
56 import java.lang.reflect.Array; |
56 import java.lang.reflect.Array; |
57 import java.lang.reflect.Field; |
|
58 import java.lang.reflect.Method; |
|
59 import java.lang.reflect.InvocationTargetException; |
|
60 import java.text.AttributedCharacterIterator; |
57 import java.text.AttributedCharacterIterator; |
61 import java.text.Bidi; |
58 import java.text.Bidi; |
62 import java.util.Arrays; |
59 import java.util.Arrays; |
63 import java.util.MissingResourceException; |
60 import java.util.MissingResourceException; |
|
61 import sun.misc.JavaAWTFontAccess; |
|
62 import sun.misc.SharedSecrets; |
64 import sun.text.normalizer.UBiDiProps; |
63 import sun.text.normalizer.UBiDiProps; |
65 import sun.text.normalizer.UCharacter; |
64 import sun.text.normalizer.UCharacter; |
66 import sun.text.normalizer.UTF16; |
65 import sun.text.normalizer.UTF16; |
67 |
66 |
68 /** |
67 /** |
3444 /** |
3443 /** |
3445 * A class that provides access to constants defined by |
3444 * A class that provides access to constants defined by |
3446 * java.awt.font.TextAttribute without creating a static dependency. |
3445 * java.awt.font.TextAttribute without creating a static dependency. |
3447 */ |
3446 */ |
3448 private static class TextAttributeConstants { |
3447 private static class TextAttributeConstants { |
3449 private static final Class<?> clazz = getClass("java.awt.font.TextAttribute"); |
3448 // Make sure to load the AWT's TextAttribute class before using the constants, if any. |
|
3449 static { |
|
3450 try { |
|
3451 Class.forName("java.awt.font.TextAttribute", true, null); |
|
3452 } catch (ClassNotFoundException e) {} |
|
3453 } |
|
3454 static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess(); |
3450 |
3455 |
3451 /** |
3456 /** |
3452 * TextAttribute instances (or a fake Attribute type if |
3457 * TextAttribute instances (or a fake Attribute type if |
3453 * java.awt.font.TextAttribute is not present) |
3458 * java.awt.font.TextAttribute is not present) |
3454 */ |
3459 */ |
3460 getTextAttribute("BIDI_EMBEDDING"); |
3465 getTextAttribute("BIDI_EMBEDDING"); |
3461 |
3466 |
3462 /** |
3467 /** |
3463 * TextAttribute.RUN_DIRECTION_LTR |
3468 * TextAttribute.RUN_DIRECTION_LTR |
3464 */ |
3469 */ |
3465 static final Boolean RUN_DIRECTION_LTR = (clazz == null) ? |
3470 static final Boolean RUN_DIRECTION_LTR = (jafa == null) ? |
3466 Boolean.FALSE : (Boolean)getStaticField(clazz, "RUN_DIRECTION_LTR"); |
3471 Boolean.FALSE : (Boolean)jafa.getTextAttributeConstant("RUN_DIRECTION_LTR"); |
3467 |
|
3468 |
|
3469 private static Class<?> getClass(String name) { |
|
3470 try { |
|
3471 return Class.forName(name, true, null); |
|
3472 } catch (ClassNotFoundException e) { |
|
3473 return null; |
|
3474 } |
|
3475 } |
|
3476 |
|
3477 private static Object getStaticField(Class<?> clazz, String name) { |
|
3478 try { |
|
3479 Field f = clazz.getField(name); |
|
3480 return f.get(null); |
|
3481 } catch (NoSuchFieldException | IllegalAccessException x) { |
|
3482 throw new AssertionError(x); |
|
3483 } |
|
3484 } |
|
3485 |
3472 |
3486 @SuppressWarnings("serial") |
3473 @SuppressWarnings("serial") |
3487 private static AttributedCharacterIterator.Attribute |
3474 private static AttributedCharacterIterator.Attribute |
3488 getTextAttribute(String name) |
3475 getTextAttribute(String name) |
3489 { |
3476 { |
3490 if (clazz == null) { |
3477 if (jafa == null) { |
3491 // fake attribute |
3478 // fake attribute |
3492 return new AttributedCharacterIterator.Attribute(name) { }; |
3479 return new AttributedCharacterIterator.Attribute(name) { }; |
3493 } else { |
3480 } else { |
3494 return (AttributedCharacterIterator.Attribute)getStaticField(clazz, name); |
3481 return (AttributedCharacterIterator.Attribute)jafa.getTextAttributeConstant(name); |
3495 } |
3482 } |
3496 } |
3483 } |
3497 } |
3484 } |
3498 |
3485 |
3499 /** |
3486 /** |
3500 * A class that provides access to java.awt.font.NumericShaping without |
3487 * A class that provides access to java.awt.font.NumericShaper without |
3501 * creating a static dependency. |
3488 * creating a static dependency. |
3502 */ |
3489 */ |
3503 private static class NumericShapings { |
3490 private static class NumericShapings { |
3504 private static final Class<?> clazz = |
3491 // Make sure to load the AWT's NumericShaper class before calling shape, if any. |
3505 getClass("java.awt.font.NumericShaper"); |
3492 static { |
3506 private static final Method shapeMethod = |
|
3507 getMethod(clazz, "shape", char[].class, int.class, int.class); |
|
3508 |
|
3509 private static Class<?> getClass(String name) { |
|
3510 try { |
3493 try { |
3511 return Class.forName(name, true, null); |
3494 Class.forName("java.awt.font.NumericShaper", true, null); |
3512 } catch (ClassNotFoundException e) { |
3495 } catch (ClassNotFoundException e) {} |
3513 return null; |
3496 } |
3514 } |
3497 static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess(); |
3515 } |
|
3516 |
|
3517 private static Method getMethod(Class<?> clazz, |
|
3518 String name, |
|
3519 Class<?>... paramTypes) |
|
3520 { |
|
3521 if (clazz != null) { |
|
3522 try { |
|
3523 return clazz.getMethod(name, paramTypes); |
|
3524 } catch (NoSuchMethodException e) { |
|
3525 throw new AssertionError(e); |
|
3526 } |
|
3527 } else { |
|
3528 return null; |
|
3529 } |
|
3530 } |
|
3531 |
3498 |
3532 /** |
3499 /** |
3533 * Invokes NumericShaping shape(text,start,count) method. |
3500 * Invokes NumericShaping shape(text,start,count) method. |
3534 */ |
3501 */ |
3535 static void shape(Object shaper, char[] text, int start, int count) { |
3502 static void shape(Object shaper, char[] text, int start, int count) { |
3536 if (shapeMethod == null) |
3503 if (jafa != null) { |
3537 throw new AssertionError("Should not get here"); |
3504 jafa.shape(shaper, text, start, count); |
3538 try { |
|
3539 shapeMethod.invoke(shaper, text, start, count); |
|
3540 } catch (InvocationTargetException e) { |
|
3541 Throwable cause = e.getCause(); |
|
3542 if (cause instanceof RuntimeException) |
|
3543 throw (RuntimeException)cause; |
|
3544 throw new AssertionError(e); |
|
3545 } catch (IllegalAccessException iae) { |
|
3546 throw new AssertionError(iae); |
|
3547 } |
3505 } |
3548 } |
3506 } |
3549 } |
3507 } |
3550 } |
3508 } |