PageRenderTime 34ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/MRI-J/jdk/src/solaris/classes/sun/font/XMap.java

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