blob: 5e905931a3cb2865cba019ae5278bb9514ec675f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id$ */
package org.apache.fop.complexscripts.util;
import java.util.Arrays;
/**
* <p>Mirror related utilities.</p>
*
* <p>This work was originally authored by Glenn Adams (gadams@apache.org).</p>
*/
public final class CharMirror {
private CharMirror() {
}
/**
* Mirror characters that are designated as having the bidi mirrorred property.
* @param s a string whose characters are to be mirrored
* @return the resulting string
*/
public static String mirror(String s) {
StringBuffer sb = new StringBuffer(s);
for (int i = 0, n = sb.length(); i < n; ++i) {
sb.setCharAt(i, (char) mirror(sb.charAt(i)));
}
return sb.toString();
}
/**
* Determine if string has a mirrorable character.
* @param s a string whose characters are to be tested for mirrorability
* @return true if some character can be mirrored
*/
public static boolean hasMirrorable(String s) {
for (int i = 0, n = s.length(); i < n; ++i) {
char c = s.charAt(i);
if (Arrays.binarySearch(mirroredCharacters, c) >= 0) {
return true;
}
}
return false;
}
private static int[] mirroredCharacters = {
0x0028,
0x0029,
0x003C,
0x003E,
0x005B,
0x005D,
0x007B,
0x007D,
0x00AB,
0x00BB,
0x0F3A,
0x0F3B,
0x0F3C,
0x0F3D,
0x169B,
0x169C,
0x2039,
0x203A,
0x2045,
0x2046,
0x207D,
0x207E,
0x208D,
0x208E,
0x2208,
0x2209,
0x220A,
0x220B,
0x220C,
0x220D,
0x2215,
0x223C,
0x223D,
0x2243,
0x2252,
0x2253,
0x2254,
0x2255,
0x2264,
0x2265,
0x2266,
0x2267,
0x2268,
0x2269,
0x226A,
0x226B,
0x226E,
0x226F,
0x2270,
0x2271,
0x2272,
0x2273,
0x2274,
0x2275,
0x2276,
0x2277,
0x2278,
0x2279,
0x227A,
0x227B,
0x227C,
0x227D,
0x227E,
0x227F,
0x2280,
0x2281,
0x2282,
0x2283,
0x2284,
0x2285,
0x2286,
0x2287,
0x2288,
0x2289,
0x228A,
0x228B,
0x228F,
0x2290,
0x2291,
0x2292,
0x2298,
0x22A2,
0x22A3,
0x22A6,
0x22A8,
0x22A9,
0x22AB,
0x22B0,
0x22B1,
0x22B2,
0x22B3,
0x22B4,
0x22B5,
0x22B6,
0x22B7,
0x22C9,
0x22CA,
0x22CB,
0x22CC,
0x22CD,
0x22D0,
0x22D1,
0x22D6,
0x22D7,
0x22D8,
0x22D9,
0x22DA,
0x22DB,
0x22DC,
0x22DD,
0x22DE,
0x22DF,
0x22E0,
0x22E1,
0x22E2,
0x22E3,
0x22E4,
0x22E5,
0x22E6,
0x22E7,
0x22E8,
0x22E9,
0x22EA,
0x22EB,
0x22EC,
0x22ED,
0x22F0,
0x22F1,
0x22F2,
0x22F3,
0x22F4,
0x22F6,
0x22F7,
0x22FA,
0x22FB,
0x22FC,
0x22FD,
0x22FE,
0x2308,
0x2309,
0x230A,
0x230B,
0x2329,
0x232A,
0x2768,
0x2769,
0x276A,
0x276B,
0x276C,
0x276D,
0x276E,
0x276F,
0x2770,
0x2771,
0x2772,
0x2773,
0x2774,
0x2775,
0x27C3,
0x27C4,
0x27C5,
0x27C6,
0x27C8,
0x27C9,
0x27D5,
0x27D6,
0x27DD,
0x27DE,
0x27E2,
0x27E3,
0x27E4,
0x27E5,
0x27E6,
0x27E7,
0x27E8,
0x27E9,
0x27EA,
0x27EB,
0x27EC,
0x27ED,
0x27EE,
0x27EF,
0x2983,
0x2984,
0x2985,
0x2986,
0x2987,
0x2988,
0x2989,
0x298A,
0x298B,
0x298C,
0x298D,
0x298E,
0x298F,
0x2990,
0x2991,
0x2992,
0x2993,
0x2994,
0x2995,
0x2996,
0x2997,
0x2998,
0x29B8,
0x29C0,
0x29C1,
0x29C4,
0x29C5,
0x29CF,
0x29D0,
0x29D1,
0x29D2,
0x29D4,
0x29D5,
0x29D8,
0x29D9,
0x29DA,
0x29DB,
0x29F5,
0x29F8,
0x29F9,
0x29FC,
0x29FD,
0x2A2B,
0x2A2C,
0x2A2D,
0x2A2E,
0x2A34,
0x2A35,
0x2A3C,
0x2A3D,
0x2A64,
0x2A65,
0x2A79,
0x2A7A,
0x2A7D,
0x2A7E,
0x2A7F,
0x2A80,
0x2A81,
0x2A82,
0x2A83,
0x2A84,
0x2A8B,
0x2A8C,
0x2A91,
0x2A92,
0x2A93,
0x2A94,
0x2A95,
0x2A96,
0x2A97,
0x2A98,
0x2A99,
0x2A9A,
0x2A9B,
0x2A9C,
0x2AA1,
0x2AA2,
0x2AA6,
0x2AA7,
0x2AA8,
0x2AA9,
0x2AAA,
0x2AAB,
0x2AAC,
0x2AAD,
0x2AAF,
0x2AB0,
0x2AB3,
0x2AB4,
0x2AC3,
0x2AC4,
0x2AC5,
0x2AC6,
0x2ACD,
0x2ACE,
0x2ACF,
0x2AD0,
0x2AD1,
0x2AD2,
0x2AD3,
0x2AD4,
0x2AD5,
0x2AD6,
0x2ADE,
0x2AE3,
0x2E02,
0x2E03,
0x2E04,
0x2E05,
0x2E09,
0x2E0A,
0x2E0C,
0x2E0D,
0x2E1C,
0x2E1D,
0x2E20,
0x2E21,
0x2E22,
0x2E23,
0x2E24,
0x2E25,
0x2E26,
0x300E,
0x300F,
0x3010,
0x3011,
0x3014,
0x3015,
0x3016,
0x3017,
0x3018,
0x3019,
0x301A,
0x301B,
0xFE59,
0xFE5A,
0xFF3B,
0xFF3D,
0xFF5B,
0xFF5D,
0xFF5F,
0xFF60,
0xFF62,
0xFF63
};
private static int[] mirroredCharactersMapping = {
0x0029,
0x0028,
0x003E,
0x003C,
0x005D,
0x005B,
0x007D,
0x007B,
0x00BB,
0x00AB,
0x0F3B,
0x0F3A,
0x0F3D,
0x0F3C,
0x169C,
0x169B,
0x203A,
0x2039,
0x2046,
0x2045,
0x207E,
0x207D,
0x208E,
0x208D,
0x220B,
0x220C,
0x220D,
0x2208,
0x2209,
0x220A,
0x29F5,
0x223D,
0x223C,
0x22CD,
0x2253,
0x2252,
0x2255,
0x2254,
0x2265,
0x2264,
0x2267,
0x2266,
0x2269,
0x2268,
0x226B,
0x226A,
0x226F,
0x226E,
0x2271,
0x2270,
0x2273,
0x2272,
0x2275,
0x2274,
0x2277,
0x2276,
0x2279,
0x2278,
0x227B,
0x227A,
0x227D,
0x227C,
0x227F,
0x227E,
0x2281,
0x2280,
0x2283,
0x2282,
0x2285,
0x2284,
0x2287,
0x2286,
0x2289,
0x2288,
0x228B,
0x228A,
0x2290,
0x228F,
0x2292,
0x2291,
0x29B8,
0x22A3,
0x22A2,
0x2ADE,
0x2AE4,
0x2AE3,
0x2AE5,
0x22B1,
0x22B0,
0x22B3,
0x22B2,
0x22B5,
0x22B4,
0x22B7,
0x22B6,
0x22CA,
0x22C9,
0x22CC,
0x22CB,
0x2243,
0x22D1,
0x22D0,
0x22D7,
0x22D6,
0x22D9,
0x22D8,
0x22DB,
0x22DA,
0x22DD,
0x22DC,
0x22DF,
0x22DE,
0x22E1,
0x22E0,
0x22E3,
0x22E2,
0x22E5,
0x22E4,
0x22E7,
0x22E6,
0x22E9,
0x22E8,
0x22EB,
0x22EA,
0x22ED,
0x22EC,
0x22F1,
0x22F0,
0x22FA,
0x22FB,
0x22FC,
0x22FD,
0x22FE,
0x22F2,
0x22F3,
0x22F4,
0x22F6,
0x22F7,
0x2309,
0x2308,
0x230B,
0x230A,
0x232A,
0x2329,
0x2769,
0x2768,
0x276B,
0x276A,
0x276D,
0x276C,
0x276F,
0x276E,
0x2771,
0x2770,
0x2773,
0x2772,
0x2775,
0x2774,
0x27C4,
0x27C3,
0x27C6,
0x27C5,
0x27C9,
0x27C8,
0x27D6,
0x27D5,
0x27DE,
0x27DD,
0x27E3,
0x27E2,
0x27E5,
0x27E4,
0x27E7,
0x27E6,
0x27E9,
0x27E8,
0x27EB,
0x27EA,
0x27ED,
0x27EC,
0x27EF,
0x27EE,
0x2984,
0x2983,
0x2986,
0x2985,
0x2988,
0x2987,
0x298A,
0x2989,
0x298C,
0x298B,
0x2990,
0x298F,
0x298E,
0x298D,
0x2992,
0x2991,
0x2994,
0x2993,
0x2996,
0x2995,
0x2998,
0x2997,
0x2298,
0x29C1,
0x29C0,
0x29C5,
0x29C4,
0x29D0,
0x29CF,
0x29D2,
0x29D1,
0x29D5,
0x29D4,
0x29D9,
0x29D8,
0x29DB,
0x29DA,
0x2215,
0x29F9,
0x29F8,
0x29FD,
0x29FC,
0x2A2C,
0x2A2B,
0x2A2E,
0x2A2D,
0x2A35,
0x2A34,
0x2A3D,
0x2A3C,
0x2A65,
0x2A64,
0x2A7A,
0x2A79,
0x2A7E,
0x2A7D,
0x2A80,
0x2A7F,
0x2A82,
0x2A81,
0x2A84,
0x2A83,
0x2A8C,
0x2A8B,
0x2A92,
0x2A91,
0x2A94,
0x2A93,
0x2A96,
0x2A95,
0x2A98,
0x2A97,
0x2A9A,
0x2A99,
0x2A9C,
0x2A9B,
0x2AA2,
0x2AA1,
0x2AA7,
0x2AA6,
0x2AA9,
0x2AA8,
0x2AAB,
0x2AAA,
0x2AAD,
0x2AAC,
0x2AB0,
0x2AAF,
0x2AB4,
0x2AB3,
0x2AC4,
0x2AC3,
0x2AC6,
0x2AC5,
0x2ACE,
0x2ACD,
0x2AD0,
0x2ACF,
0x2AD2,
0x2AD1,
0x2AD4,
0x2AD3,
0x2AD6,
0x2AD5,
0x22A6,
0x22A9,
0x2E03,
0x2E02,
0x2E05,
0x2E04,
0x2E0A,
0x2E09,
0x2E0D,
0x2E0C,
0x2E1D,
0x2E1C,
0x2E21,
0x2E20,
0x2E23,
0x2E22,
0x2E25,
0x2E24,
0x2E27,
0x300F,
0x300E,
0x3011,
0x3010,
0x3015,
0x3014,
0x3017,
0x3016,
0x3019,
0x3018,
0x301B,
0x301A,
0xFE5A,
0xFE59,
0xFF3D,
0xFF3B,
0xFF5D,
0xFF5B,
0xFF60,
0xFF5F,
0xFF63,
0xFF62
};
private static int mirror(int c) {
int i = Arrays.binarySearch(mirroredCharacters, c);
if (i < 0) {
return c;
} else {
return mirroredCharactersMapping [ i ];
}
}
}