001 /** 002 * =========================================== 003 * LibFonts : a free Java font reading library 004 * =========================================== 005 * 006 * Project Info: http://reporting.pentaho.org/libfonts/ 007 * 008 * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors. 009 * 010 * This library is free software; you can redistribute it and/or modify it under the terms 011 * of the GNU Lesser General Public License as published by the Free Software Foundation; 012 * either version 2.1 of the License, or (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 016 * See the GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public License along with this 019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 020 * Boston, MA 02111-1307, USA. 021 * 022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 023 * in the United States and other countries.] 024 * 025 * ------------ 026 * $Id: ByteAccessUtilities.java 3523 2007-10-16 11:03:09Z tmorgner $ 027 * ------------ 028 * (C) Copyright 2006-2007, by Pentaho Corporation. 029 */ 030 package org.jfree.fonts; 031 032 import org.jfree.fonts.encoding.ByteBuffer; 033 import org.jfree.fonts.encoding.CodePointBuffer; 034 import org.jfree.fonts.encoding.Encoding; 035 import org.jfree.fonts.encoding.EncodingException; 036 import org.jfree.fonts.encoding.EncodingRegistry; 037 import org.jfree.fonts.encoding.manual.Utf16LE; 038 039 /** 040 * Reads byte-data using a Big-Endian access schema. Big-Endian is used for TrueType fonts. 041 * 042 * @author Thomas Morgner 043 */ 044 public class ByteAccessUtilities 045 { 046 private ByteAccessUtilities() 047 { 048 } 049 050 public static int readUShort (final byte[] data, final int pos) 051 { 052 return ((data[pos] & 0xff) << 8) | (data[pos + 1] & 0xff); 053 } 054 055 public static long readULong (final byte[] data, final int pos) 056 { 057 final int c1 = (data[pos] & 0xff); 058 final int c2 = (data[pos + 1] & 0xff); 059 final int c3 = (data[pos + 2] & 0xff); 060 final int c4 = (data[pos + 3] & 0xff); 061 062 long retval = ((long) c1 << 24); 063 retval |= (long)c2 << 16; 064 retval |= (long)c3 << 8; 065 retval |= (long)c4; 066 return retval; 067 } 068 069 public static float readFixed (final byte[] data, final int pos) 070 { 071 final short mantissa = readShort(data, pos); 072 final int fraction = readUShort(data, pos + 2); 073 if (fraction == 0 || mantissa == 0) 074 { 075 return 0; 076 } 077 return (float) mantissa / (fraction / 16384.0f); 078 } 079 080 public static long readLongDateTime (final byte[] data, final int pos) 081 { 082 final int c1 = (data[pos] & 0xff); 083 final int c2 = (data[pos + 1] & 0xff); 084 final int c3 = (data[pos + 2] & 0xff); 085 final int c4 = (data[pos + 3] & 0xff); 086 final int c5 = (data[pos + 4] & 0xff); 087 final int c6 = (data[pos + 5] & 0xff); 088 final int c7 = (data[pos + 6] & 0xff); 089 final int c8 = (data[pos + 7] & 0xff); 090 091 long retval = ((long) c1 << 56); 092 retval |= (long)c2 << 48; 093 retval |= (long)c3 << 40; 094 retval |= (long)c4 << 32; 095 retval |= (long)c5 << 24; 096 retval |= (long)c6 << 16; 097 retval |= (long)c7 << 8; 098 retval |= (long)c8; 099 return retval; 100 } 101 102 public static byte[] readBytes (final byte[] data, 103 final int pos, final int length) 104 { 105 final byte[] retval = new byte[length]; 106 System.arraycopy(data, pos, retval, 0, length); 107 return retval; 108 } 109 110 public static short readShort (final byte[] data, final int pos) 111 { 112 return (short) ((data[pos] & 0xff) << 8 | (data[pos + 1] & 0xff)); 113 } 114 115 public static int readLong (final byte[] data, final int pos) 116 { 117 int retval = 0; 118 retval |= (long)(data[pos] & 0xff) << 24; 119 retval |= (long)(data[pos + 1] & 0xff) << 16; 120 retval |= (long)(data[pos + 2] & 0xff) << 8; 121 retval |= (long)(data[pos + 3] & 0xff); 122 return retval; 123 } 124 125 public static int readZStringOffset (final byte[] data, final int pos, final int maxLength) 126 { 127 final int lastPos = Math.min (pos + maxLength, pos + data.length); 128 for (int i = pos; i < lastPos; i++) 129 { 130 if (data[i] == 0) 131 { 132 return i; 133 } 134 } 135 136 return lastPos; 137 } 138 139 public static String readZString (final byte[] data, final int pos, final int maxLength, final String encoding) 140 throws EncodingException 141 { 142 final int lastPos = Math.min (pos + maxLength, pos + data.length); 143 for (int i = pos; i < lastPos; i++) 144 { 145 if (data[i] == 0) 146 { 147 return readString(data, pos, i - pos, encoding); 148 } 149 } 150 151 return readString(data, pos, lastPos, encoding); 152 } 153 154 public static String readString (final byte[] data, final int pos, 155 final int length, final String encoding) 156 throws EncodingException 157 { 158 final Encoding enc; 159 if ("UTF-16".equals(encoding)) 160 { 161 enc = EncodingRegistry.getInstance().getEncoding("UTF-16LE"); 162 } 163 else 164 { 165 enc = EncodingRegistry.getInstance().getEncoding(encoding); 166 } 167 final ByteBuffer byteBuffer = new ByteBuffer(data, pos, length); 168 final CodePointBuffer cp = enc.decode(byteBuffer, null); 169 return Utf16LE.getInstance().encodeString(cp); 170 } 171 }