Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/font/XMap.java
32287 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.font;2627import java.awt.FontFormatException;28import java.awt.font.FontRenderContext;29import java.awt.geom.GeneralPath;30import java.awt.geom.Rectangle2D;31import java.util.HashMap;32import java.util.Locale;33import java.nio.charset.*;34import java.nio.CharBuffer;35import java.nio.ByteBuffer;3637class XMap {3839private static HashMap xMappers = new HashMap();4041/* ConvertedGlyphs has unicode code points as indexes and values42* are platform-encoded multi-bytes chars packed into java chars.43* These platform-encoded characters are equated to glyph ids, although44* that's not strictly true, as X11 only supports using chars.45* The assumption carried over from the native implementation that46* a char is big enough to hold an X11 glyph id (ie platform char).47*/48char[] convertedGlyphs;4950static synchronized XMap getXMapper(String encoding) {51XMap mapper = (XMap)xMappers.get(encoding);52if (mapper == null) {53mapper = getXMapperInternal(encoding);54xMappers.put(encoding, mapper);55}56return mapper;57}5859static final int SINGLE_BYTE = 1;60static final int DOUBLE_BYTE = 2;6162private static XMap getXMapperInternal(String encoding) {6364String jclass = null;65int nBytes = SINGLE_BYTE;66int maxU = 0xffff;67int minU = 0;68boolean addAscii = false;69boolean lowPartOnly = false;70if (encoding.equals("dingbats")) {71jclass = "sun.awt.motif.X11Dingbats";72minU = 0x2701;73maxU = 0x27be;74} else if (encoding.equals("symbol")){75jclass = "sun.awt.Symbol";76minU = 0x0391;77maxU = 0x22ef;78} else if (encoding.equals("iso8859-1")) {79maxU = 0xff;80} else if (encoding.equals("iso8859-2")) {81jclass = "ISO8859_2";82} else if (encoding.equals("jisx0208.1983-0")) {83jclass = "sun.awt.motif.X11JIS0208";84nBytes = DOUBLE_BYTE;85} else if (encoding.equals("jisx0201.1976-0")) {86jclass = "sun.awt.motif.X11JIS0201";87// this is mapping the latin supplement range 128->255 which88// doesn't exist in JIS0201. This needs examination.89// it was also overwriting a couple of the mappings of90// 7E and A5 which in JIS201 are different chars than in91// Latin 1. I have revised AddAscii to not overwrite chars92// which are already converted.93addAscii = true;94lowPartOnly = true;95} else if (encoding.equals("jisx0212.1990-0")) {96jclass = "sun.awt.motif.X11JIS0212";97nBytes = DOUBLE_BYTE;98} else if (encoding.equals("iso8859-4")) {99jclass = "ISO8859_4";100} else if (encoding.equals("iso8859-5")) {101jclass = "ISO8859_5";102} else if (encoding.equals("koi8-r")) {103jclass = "KOI8_R";104} else if (encoding.equals("ansi-1251")) {105jclass = "windows-1251";106} else if (encoding.equals("iso8859-6")) {107jclass = "ISO8859_6";108} else if (encoding.equals("iso8859-7")) {109jclass = "ISO8859_7";110} else if (encoding.equals("iso8859-8")) {111jclass = "ISO8859_8";112} else if (encoding.equals("iso8859-9")) {113jclass = "ISO8859_9";114} else if (encoding.equals("iso8859-13")) {115jclass = "ISO8859_13";116} else if (encoding.equals("iso8859-15")) {117jclass = "ISO8859_15";118} else if (encoding.equals("ksc5601.1987-0")) {119jclass ="sun.awt.motif.X11KSC5601";120nBytes = DOUBLE_BYTE;121} else if (encoding.equals( "ksc5601.1992-3")) {122jclass ="sun.awt.motif.X11Johab";123nBytes = DOUBLE_BYTE;124} else if (encoding.equals( "ksc5601.1987-1")) {125jclass ="EUC_KR";126nBytes = DOUBLE_BYTE;127} else if (encoding.equals( "cns11643-1")) {128jclass = "sun.awt.motif.X11CNS11643P1";129nBytes = DOUBLE_BYTE;130} else if (encoding.equals("cns11643-2")) {131jclass = "sun.awt.motif.X11CNS11643P2";132nBytes = DOUBLE_BYTE;133} else if (encoding.equals("cns11643-3")) {134jclass = "sun.awt.motif.X11CNS11643P3";135nBytes = DOUBLE_BYTE;136} else if (encoding.equals("gb2312.1980-0")) {137jclass = "sun.awt.motif.X11GB2312";138nBytes = DOUBLE_BYTE;139} else if (encoding.indexOf("big5") >= 0) {140jclass = "Big5";141nBytes = DOUBLE_BYTE;142addAscii = true;143} else if (encoding.equals("tis620.2533-0")) {144jclass = "TIS620";145} else if (encoding.equals("gbk-0")) {146jclass = "sun.awt.motif.X11GBK";147nBytes = DOUBLE_BYTE;148} else if (encoding.indexOf("sun.unicode-0") >= 0) {149jclass = "sun.awt.motif.X11SunUnicode_0";150nBytes = DOUBLE_BYTE;151} else if (encoding.indexOf("gb18030.2000-1") >= 0) {152jclass = "sun.awt.motif.X11GB18030_1";153nBytes = DOUBLE_BYTE;154} else if (encoding.indexOf( "gb18030.2000-0") >= 0) {155jclass = "sun.awt.motif.X11GB18030_0";156nBytes = DOUBLE_BYTE;157} else if (encoding.indexOf("hkscs") >= 0) {158jclass = "sun.awt.HKSCS";159nBytes = DOUBLE_BYTE;160}161return new XMap(jclass, minU, maxU, nBytes, addAscii, lowPartOnly);162}163164private static final char SURR_MIN = '\uD800';165private static final char SURR_MAX = '\uDFFF';166167private XMap(String className, int minU, int maxU, int nBytes,168boolean addAscii, boolean lowPartOnly) {169170CharsetEncoder enc = null;171if (className != null) {172try {173if (className.startsWith("sun.awt")) {174enc = ((Charset)Class.forName(className).newInstance()).newEncoder();175} else {176enc = Charset.forName(className).newEncoder();177}178} catch (Exception x) {x.printStackTrace();}179}180if (enc == null) {181convertedGlyphs = new char[256];182for (int i=0; i<256; i++) {183convertedGlyphs[i] = (char)i;184}185return;186} else {187/* chars is set to the unicode values to convert,188* bytes is where the X11 character codes will be output.189* Finally we pack the byte pairs into chars.190*/191int count = maxU - minU + 1;192byte[] bytes = new byte[count*nBytes];193char[] chars = new char[count];194for (int i=0; i<count; i++) {195chars[i] = (char)(minU+i);196}197int startCharIndex = 0;198/* For multi-byte encodings, single byte chars should be skipped */199if (nBytes > SINGLE_BYTE && minU < 256) {200startCharIndex = 256-minU;201}202byte[] rbytes = new byte[nBytes];203try {204int cbLen = 0;205int bbLen = 0;206// Since we don't support surrogates in any X11 encoding, skip207// the surrogate area, otherwise the sequence of "Oxdbff0xdc00"208// will accidently cause the surrogate-aware nio charset to treat209// them as a legal pair and then undesirablly skip 2 "chars"210// for one "unmappable character"211if (startCharIndex < SURR_MIN && startCharIndex + count >SURR_MAX) {212cbLen = SURR_MIN - startCharIndex;213bbLen = cbLen * nBytes;214enc.onMalformedInput(CodingErrorAction.REPLACE)215.onUnmappableCharacter(CodingErrorAction.REPLACE)216.replaceWith(rbytes)217.encode(CharBuffer.wrap(chars, startCharIndex, cbLen),218ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),219true);220startCharIndex = SURR_MAX + 1;221}222cbLen = count - startCharIndex;223bbLen = cbLen * nBytes;224enc.onMalformedInput(CodingErrorAction.REPLACE)225.onUnmappableCharacter(CodingErrorAction.REPLACE)226.replaceWith(rbytes)227.encode(CharBuffer.wrap(chars, startCharIndex, cbLen),228ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),229true);230} catch (Exception e) { e.printStackTrace();}231232convertedGlyphs = new char[65536];233for (int i=0; i<count; i++) {234if (nBytes == 1) {235convertedGlyphs[i+minU] = (char)(bytes[i]&0xff);236} else {237convertedGlyphs[i+minU] =238(char)(((bytes[i*2]&0xff) << 8) + (bytes[i*2+1]&0xff));239}240}241}242243int max = (lowPartOnly) ? 128 : 256;244if (addAscii && convertedGlyphs.length >= 256) {245for (int i=0;i<max;i++) {246if (convertedGlyphs[i] == 0) {247convertedGlyphs[i] = (char)i;248}249}250}251}252}253254255