/MRI-J/jdk/src/solaris/classes/sun/font/XMap.java
Java | 253 lines | 192 code | 14 blank | 47 comment | 85 complexity | 919bab8224629ec66e6fd23108fc93a7 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-3.0
- /*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
- package sun.font;
- import java.awt.FontFormatException;
- import java.awt.font.FontRenderContext;
- import java.awt.geom.GeneralPath;
- import java.awt.geom.Rectangle2D;
- import java.util.HashMap;
- import java.util.Locale;
- import java.nio.charset.*;
- import java.nio.CharBuffer;
- import java.nio.ByteBuffer;
- class XMap {
- private static HashMap xMappers = new HashMap();
- /* ConvertedGlyphs has unicode code points as indexes and values
- * are platform-encoded multi-bytes chars packed into java chars.
- * These platform-encoded characters are equated to glyph ids, although
- * that's not strictly true, as X11 only supports using chars.
- * The assumption carried over from the native implementation that
- * a char is big enough to hold an X11 glyph id (ie platform char).
- */
- char[] convertedGlyphs;
- static synchronized XMap getXMapper(String encoding) {
- XMap mapper = (XMap)xMappers.get(encoding);
- if (mapper == null) {
- mapper = getXMapperInternal(encoding);
- xMappers.put(encoding, mapper);
- }
- return mapper;
- }
- static final int SINGLE_BYTE = 1;
- static final int DOUBLE_BYTE = 2;
- private static XMap getXMapperInternal(String encoding) {
- String jclass = null;
- int nBytes = SINGLE_BYTE;
- int maxU = 0xffff;
- int minU = 0;
- boolean addAscii = false;
- boolean lowPartOnly = false;
- if (encoding.equals("dingbats")) {
- jclass = "sun.awt.motif.X11Dingbats";
- minU = 0x2701;
- maxU = 0x27be;
- } else if (encoding.equals("symbol")){
- jclass = "sun.awt.Symbol";
- minU = 0x0391;
- maxU = 0x22ef;
- } else if (encoding.equals("iso8859-1")) {
- maxU = 0xff;
- } else if (encoding.equals("iso8859-2")) {
- jclass = "ISO8859_2";
- } else if (encoding.equals("jisx0208.1983-0")) {
- jclass = "sun.awt.motif.X11JIS0208";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals("jisx0201.1976-0")) {
- jclass = "sun.awt.motif.X11JIS0201";
- // this is mapping the latin supplement range 128->255 which
- // doesn't exist in JIS0201. This needs examination.
- // it was also overwriting a couple of the mappings of
- // 7E and A5 which in JIS201 are different chars than in
- // Latin 1. I have revised AddAscii to not overwrite chars
- // which are already converted.
- addAscii = true;
- lowPartOnly = true;
- } else if (encoding.equals("jisx0212.1990-0")) {
- jclass = "sun.awt.motif.X11JIS0212";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals("iso8859-4")) {
- jclass = "ISO8859_4";
- } else if (encoding.equals("iso8859-5")) {
- jclass = "ISO8859_5";
- } else if (encoding.equals("koi8-r")) {
- jclass = "KOI8_R";
- } else if (encoding.equals("ansi-1251")) {
- jclass = "windows-1251";
- } else if (encoding.equals("iso8859-6")) {
- jclass = "ISO8859_6";
- } else if (encoding.equals("iso8859-7")) {
- jclass = "ISO8859_7";
- } else if (encoding.equals("iso8859-8")) {
- jclass = "ISO8859_8";
- } else if (encoding.equals("iso8859-9")) {
- jclass = "ISO8859_9";
- } else if (encoding.equals("iso8859-13")) {
- jclass = "ISO8859_13";
- } else if (encoding.equals("iso8859-15")) {
- jclass = "ISO8859_15";
- } else if (encoding.equals("ksc5601.1987-0")) {
- jclass ="sun.awt.motif.X11KSC5601";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals( "ksc5601.1992-3")) {
- jclass ="sun.awt.motif.X11Johab";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals( "ksc5601.1987-1")) {
- jclass ="EUC_KR";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals( "cns11643-1")) {
- jclass = "sun.awt.motif.X11CNS11643P1";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals("cns11643-2")) {
- jclass = "sun.awt.motif.X11CNS11643P2";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals("cns11643-3")) {
- jclass = "sun.awt.motif.X11CNS11643P3";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.equals("gb2312.1980-0")) {
- jclass = "sun.awt.motif.X11GB2312";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.indexOf("big5") >= 0) {
- jclass = "Big5";
- nBytes = DOUBLE_BYTE;
- addAscii = true;
- } else if (encoding.equals("tis620.2533-0")) {
- jclass = "TIS620";
- } else if (encoding.equals("gbk-0")) {
- jclass = "sun.awt.motif.X11GBK";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.indexOf("sun.unicode-0") >= 0) {
- jclass = "sun.awt.motif.X11SunUnicode_0";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.indexOf("gb18030.2000-1") >= 0) {
- jclass = "sun.awt.motif.X11GB18030_1";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.indexOf( "gb18030.2000-0") >= 0) {
- jclass = "sun.awt.motif.X11GB18030_0";
- nBytes = DOUBLE_BYTE;
- } else if (encoding.indexOf("hkscs") >= 0) {
- jclass = "sun.awt.HKSCS";
- nBytes = DOUBLE_BYTE;
- }
- return new XMap(jclass, minU, maxU, nBytes, addAscii, lowPartOnly);
- }
- private static final char SURR_MIN = '\uD800';
- private static final char SURR_MAX = '\uDFFF';
- private XMap(String className, int minU, int maxU, int nBytes,
- boolean addAscii, boolean lowPartOnly) {
- CharsetEncoder enc = null;
- if (className != null) {
- try {
- if (className.startsWith("sun.awt")) {
- enc = ((Charset)Class.forName(className).newInstance()).newEncoder();
- } else {
- enc = Charset.forName(className).newEncoder();
- }
- } catch (Exception x) {x.printStackTrace();}
- }
- if (enc == null) {
- convertedGlyphs = new char[256];
- for (int i=0; i<256; i++) {
- convertedGlyphs[i] = (char)i;
- }
- return;
- } else {
- /* chars is set to the unicode values to convert,
- * bytes is where the X11 character codes will be output.
- * Finally we pack the byte pairs into chars.
- */
- int count = maxU - minU + 1;
- byte[] bytes = new byte[count*nBytes];
- char[] chars = new char[count];
- for (int i=0; i<count; i++) {
- chars[i] = (char)(minU+i);
- }
- int startCharIndex = 0;
- /* For multi-byte encodings, single byte chars should be skipped */
- if (nBytes > SINGLE_BYTE && minU < 256) {
- startCharIndex = 256-minU;
- }
- byte[] rbytes = new byte[nBytes];
- try {
- int cbLen = 0;
- int bbLen = 0;
- // Since we dont support surrogates in any X11 encoding, skip
- // the surrogate area, otherwise the sequence of "Oxdbff0xdc00"
- // will accidently cause the surrogate-aware nio charset to treat
- // them as a legal pair and then undesirablly skip 2 "chars"
- // for one "unmappable character"
- if (startCharIndex < SURR_MIN && startCharIndex + count >SURR_MAX) {
- cbLen = SURR_MIN - startCharIndex;
- bbLen = cbLen * nBytes;
- enc.onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE)
- .replaceWith(rbytes)
- .encode(CharBuffer.wrap(chars, startCharIndex, cbLen),
- ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),
- true);
- startCharIndex = SURR_MAX + 1;
- }
- cbLen = count - startCharIndex;
- bbLen = cbLen * nBytes;
- enc.onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE)
- .replaceWith(rbytes)
- .encode(CharBuffer.wrap(chars, startCharIndex, cbLen),
- ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),
- true);
- } catch (Exception e) { e.printStackTrace();}
- convertedGlyphs = new char[65536];
- for (int i=0; i<count; i++) {
- if (nBytes == 1) {
- convertedGlyphs[i+minU] = (char)(bytes[i]&0xff);
- } else {
- convertedGlyphs[i+minU] =
- (char)(((bytes[i*2]&0xff) << 8) + (bytes[i*2+1]&0xff));
- }
- }
- }
- int max = (lowPartOnly) ? 128 : 256;
- if (addAscii && convertedGlyphs.length >= 256) {
- for (int i=0;i<max;i++) {
- if (convertedGlyphs[i] == 0) {
- convertedGlyphs[i] = (char)i;
- }
- }
- }
- }
- }