< prev index next >

src/java.desktop/share/classes/sun/font/TrueTypeFont.java

Print this page
rev 60042 : 8248802: Add log helper methods to FontUtilities.java


 226                 throw new FontFormatException("Unexpected runtime exception.");
 227             }
 228         }
 229         Disposer.addObjectRecord(this, disposerRecord);
 230     }
 231 
 232     private synchronized FileChannel open() throws FontFormatException {
 233         return open(true);
 234     }
 235 
 236     /* This is intended to be called, and the returned value used,
 237      * from within a block synchronized on this font object.
 238      * ie the channel returned may be nulled out at any time by "close()"
 239      * unless the caller holds a lock.
 240      * Deadlock warning: FontManager.addToPool(..) acquires a global lock,
 241      * which means nested locks may be in effect.
 242      */
 243     private synchronized FileChannel open(boolean usePool)
 244                                      throws FontFormatException {
 245         if (disposerRecord.channel == null) {
 246             if (FontUtilities.isLogging()) {
 247                 FontUtilities.getLogger().info("open TTF: " + platName);
 248             }
 249             try {
 250                 RandomAccessFile raf = AccessController.doPrivileged(
 251                     new PrivilegedExceptionAction<RandomAccessFile>() {
 252                         public RandomAccessFile run() throws FileNotFoundException {
 253                             return new RandomAccessFile(platName, "r");
 254                     }
 255                 });
 256                 disposerRecord.channel = raf.getChannel();
 257                 fileSize = (int)disposerRecord.channel.size();
 258                 if (usePool) {
 259                     FontManager fm = FontManagerFactory.getInstance();
 260                     if (fm instanceof SunFontManager) {
 261                         ((SunFontManager) fm).addToPool(this);
 262                     }
 263                 }
 264             } catch (PrivilegedActionException e) {
 265                 close();
 266                 Throwable reason = e.getCause();
 267                 if (reason == null) {
 268                     reason = e;


 291 
 292 
 293     int readBlock(ByteBuffer buffer, int offset, int length) {
 294         int bread = 0;
 295         try {
 296             synchronized (this) {
 297                 if (disposerRecord.channel == null) {
 298                     open();
 299                 }
 300                 if (offset + length > fileSize) {
 301                     if (offset >= fileSize) {
 302                         /* Since the caller ensures that offset is < fileSize
 303                          * this condition suggests that fileSize is now
 304                          * different than the value we originally provided
 305                          * to native when the scaler was created.
 306                          * Also fileSize is updated every time we
 307                          * open() the file here, but in native the value
 308                          * isn't updated. If the file has changed whilst we
 309                          * are executing we want to bail, not spin.
 310                          */
 311                         if (FontUtilities.isLogging()) {
 312                             String msg = "Read offset is " + offset +
 313                                 " file size is " + fileSize+
 314                                 " file is " + platName;
 315                             FontUtilities.getLogger().severe(msg);
 316                         }
 317                         return -1;
 318                     } else {
 319                         length = fileSize - offset;
 320                     }
 321                 }
 322                 buffer.clear();
 323                 disposerRecord.channel.position(offset);
 324                 while (bread < length) {
 325                     int cnt = disposerRecord.channel.read(buffer);
 326                     if (cnt == -1) {
 327                         String msg = "Unexpected EOF " + this;
 328                         int currSize = (int)disposerRecord.channel.size();
 329                         if (currSize != fileSize) {
 330                             msg += " File size was " + fileSize +
 331                                 " and now is " + currSize;
 332                         }
 333                         if (FontUtilities.isLogging()) {
 334                             FontUtilities.getLogger().severe(msg);
 335                         }
 336                         // We could still flip() the buffer here because
 337                         // it's possible that we did read some data in
 338                         // an earlier loop, and we probably should
 339                         // return that to the caller. Although if
 340                         // the caller expected 8K of data and we return
 341                         // only a few bytes then maybe it's better instead to
 342                         // set bread = -1 to indicate failure.
 343                         // The following is therefore using arbitrary values
 344                         // but is meant to allow cases where enough
 345                         // data was read to probably continue.
 346                         if (bread > length/2 || bread > 16384) {
 347                             buffer.flip();
 348                             if (FontUtilities.isLogging()) {
 349                                 msg = "Returning " + bread +
 350                                     " bytes instead of " + length;
 351                                 FontUtilities.getLogger().severe(msg);
 352                             }
 353                         } else {
 354                             bread = -1;
 355                         }
 356                         throw new IOException(msg);
 357                     }
 358                     bread += cnt;
 359                 }
 360                 buffer.flip();
 361                 if (bread > length) { // possible if buffer.size() > length
 362                     bread = length;
 363                 }
 364             }
 365         } catch (FontFormatException e) {
 366             if (FontUtilities.isLogging()) {
 367                 FontUtilities.getLogger().severe(
 368                                        "While reading " + platName, e);
 369             }
 370             bread = -1; // signal EOF
 371             deregisterFontAndClearStrikeCache();
 372         } catch (ClosedChannelException e) {


 505                 /* checksum */ ibuffer.get();
 506                 table.offset = ibuffer.get();
 507                 table.length = ibuffer.get();
 508                 if (table.offset + table.length > fileSize) {
 509                     throw new FontFormatException("bad table, tag="+table.tag);
 510                 }
 511             }
 512 
 513             if (getDirectoryEntry(headTag) == null) {
 514                 throw new FontFormatException("missing head table");
 515             }
 516             if (getDirectoryEntry(maxpTag) == null) {
 517                 throw new FontFormatException("missing maxp table");
 518             }
 519             if (getDirectoryEntry(hmtxTag) != null
 520                     && getDirectoryEntry(hheaTag) == null) {
 521                 throw new FontFormatException("missing hhea table");
 522             }
 523             initNames();
 524         } catch (Exception e) {
 525             if (FontUtilities.isLogging()) {
 526                 FontUtilities.getLogger().severe(e.toString());
 527             }
 528             if (e instanceof FontFormatException) {
 529                 throw (FontFormatException)e;
 530             } else {
 531                 throw new FontFormatException(e.toString());
 532             }
 533         }
 534         if (familyName == null || fullName == null) {
 535             throw new FontFormatException("Font name not found");
 536         }
 537         /* The os2_Table is needed to gather some info, but we don't
 538          * want to keep it around (as a field) so obtain it once and
 539          * pass it to the code that needs it.
 540          */
 541         ByteBuffer os2_Table = getTableBuffer(os_2Tag);
 542         setStyle(os2_Table);
 543         setCJKSupport(os2_Table);
 544     }
 545 
 546     /* The array index corresponds to a bit offset in the TrueType
 547      * font's OS/2 compatibility table's code page ranges fields.


1055                  }
1056              }
1057          }
1058 
1059         String charset;
1060         switch (encoding) {
1061             case -1: charset = "US-ASCII";break;
1062             case 1:  charset = "UTF-16";  break; // most common case first.
1063             case 0:  charset = "UTF-16";  break; // symbol uses this
1064             case 2:  charset = "SJIS";    break;
1065             case 3:  charset = "GBK";     break;
1066             case 4:  charset = "MS950";   break;
1067             case 5:  charset = "EUC_KR";  break;
1068             case 6:  charset = "Johab";   break;
1069             default: charset = "UTF-16";  break;
1070         }
1071 
1072         try {
1073             return new String(bytes, 0, len, charset);
1074         } catch (UnsupportedEncodingException e) {
1075             if (FontUtilities.isLogging()) {
1076                 FontUtilities.getLogger().warning(e + " EncodingID=" + encoding);
1077             }
1078             return new String(bytes, 0, len);
1079         } catch (Throwable t) {
1080             return null;
1081         }
1082     }
1083 
1084     protected void initNames() {
1085 
1086         byte[] name = new byte[256];
1087         ByteBuffer buffer = getTableBuffer(nameTag);
1088 
1089         if (buffer != null) {
1090             ShortBuffer sbuffer = buffer.asShortBuffer();
1091             sbuffer.get(); // format - not needed.
1092             short numRecords = sbuffer.get();
1093             /* The name table uses unsigned shorts. Many of these
1094              * are known small values that fit in a short.
1095              * The values that are sizes or offsets into the table could be
1096              * greater than 32767, so read and store those as ints
1097              */




 226                 throw new FontFormatException("Unexpected runtime exception.");
 227             }
 228         }
 229         Disposer.addObjectRecord(this, disposerRecord);
 230     }
 231 
 232     private synchronized FileChannel open() throws FontFormatException {
 233         return open(true);
 234     }
 235 
 236     /* This is intended to be called, and the returned value used,
 237      * from within a block synchronized on this font object.
 238      * ie the channel returned may be nulled out at any time by "close()"
 239      * unless the caller holds a lock.
 240      * Deadlock warning: FontManager.addToPool(..) acquires a global lock,
 241      * which means nested locks may be in effect.
 242      */
 243     private synchronized FileChannel open(boolean usePool)
 244                                      throws FontFormatException {
 245         if (disposerRecord.channel == null) {
 246             FontUtilities.logInfo("open TTF: " + platName);


 247             try {
 248                 RandomAccessFile raf = AccessController.doPrivileged(
 249                     new PrivilegedExceptionAction<RandomAccessFile>() {
 250                         public RandomAccessFile run() throws FileNotFoundException {
 251                             return new RandomAccessFile(platName, "r");
 252                     }
 253                 });
 254                 disposerRecord.channel = raf.getChannel();
 255                 fileSize = (int)disposerRecord.channel.size();
 256                 if (usePool) {
 257                     FontManager fm = FontManagerFactory.getInstance();
 258                     if (fm instanceof SunFontManager) {
 259                         ((SunFontManager) fm).addToPool(this);
 260                     }
 261                 }
 262             } catch (PrivilegedActionException e) {
 263                 close();
 264                 Throwable reason = e.getCause();
 265                 if (reason == null) {
 266                     reason = e;


 289 
 290 
 291     int readBlock(ByteBuffer buffer, int offset, int length) {
 292         int bread = 0;
 293         try {
 294             synchronized (this) {
 295                 if (disposerRecord.channel == null) {
 296                     open();
 297                 }
 298                 if (offset + length > fileSize) {
 299                     if (offset >= fileSize) {
 300                         /* Since the caller ensures that offset is < fileSize
 301                          * this condition suggests that fileSize is now
 302                          * different than the value we originally provided
 303                          * to native when the scaler was created.
 304                          * Also fileSize is updated every time we
 305                          * open() the file here, but in native the value
 306                          * isn't updated. If the file has changed whilst we
 307                          * are executing we want to bail, not spin.
 308                          */

 309                         String msg = "Read offset is " + offset +
 310                                 " file size is " + fileSize+
 311                                 " file is " + platName;
 312                         FontUtilities.logSevere(msg);

 313                         return -1;
 314                     } else {
 315                         length = fileSize - offset;
 316                     }
 317                 }
 318                 buffer.clear();
 319                 disposerRecord.channel.position(offset);
 320                 while (bread < length) {
 321                     int cnt = disposerRecord.channel.read(buffer);
 322                     if (cnt == -1) {
 323                         String msg = "Unexpected EOF " + this;
 324                         int currSize = (int)disposerRecord.channel.size();
 325                         if (currSize != fileSize) {
 326                             msg += " File size was " + fileSize +
 327                                 " and now is " + currSize;
 328                         }
 329                         FontUtilities.logSevere(msg);


 330                         // We could still flip() the buffer here because
 331                         // it's possible that we did read some data in
 332                         // an earlier loop, and we probably should
 333                         // return that to the caller. Although if
 334                         // the caller expected 8K of data and we return
 335                         // only a few bytes then maybe it's better instead to
 336                         // set bread = -1 to indicate failure.
 337                         // The following is therefore using arbitrary values
 338                         // but is meant to allow cases where enough
 339                         // data was read to probably continue.
 340                         if (bread > length/2 || bread > 16384) {
 341                             buffer.flip();
 342                             msg = "Returning " + bread + " bytes instead of " + length;
 343                             FontUtilities.logSevere(msg);



 344                         } else {
 345                             bread = -1;
 346                         }
 347                         throw new IOException(msg);
 348                     }
 349                     bread += cnt;
 350                 }
 351                 buffer.flip();
 352                 if (bread > length) { // possible if buffer.size() > length
 353                     bread = length;
 354                 }
 355             }
 356         } catch (FontFormatException e) {
 357             if (FontUtilities.isLogging()) {
 358                 FontUtilities.getLogger().severe(
 359                                        "While reading " + platName, e);
 360             }
 361             bread = -1; // signal EOF
 362             deregisterFontAndClearStrikeCache();
 363         } catch (ClosedChannelException e) {


 496                 /* checksum */ ibuffer.get();
 497                 table.offset = ibuffer.get();
 498                 table.length = ibuffer.get();
 499                 if (table.offset + table.length > fileSize) {
 500                     throw new FontFormatException("bad table, tag="+table.tag);
 501                 }
 502             }
 503 
 504             if (getDirectoryEntry(headTag) == null) {
 505                 throw new FontFormatException("missing head table");
 506             }
 507             if (getDirectoryEntry(maxpTag) == null) {
 508                 throw new FontFormatException("missing maxp table");
 509             }
 510             if (getDirectoryEntry(hmtxTag) != null
 511                     && getDirectoryEntry(hheaTag) == null) {
 512                 throw new FontFormatException("missing hhea table");
 513             }
 514             initNames();
 515         } catch (Exception e) {
 516             FontUtilities.logSevere(e.toString());


 517             if (e instanceof FontFormatException) {
 518                 throw (FontFormatException)e;
 519             } else {
 520                 throw new FontFormatException(e.toString());
 521             }
 522         }
 523         if (familyName == null || fullName == null) {
 524             throw new FontFormatException("Font name not found");
 525         }
 526         /* The os2_Table is needed to gather some info, but we don't
 527          * want to keep it around (as a field) so obtain it once and
 528          * pass it to the code that needs it.
 529          */
 530         ByteBuffer os2_Table = getTableBuffer(os_2Tag);
 531         setStyle(os2_Table);
 532         setCJKSupport(os2_Table);
 533     }
 534 
 535     /* The array index corresponds to a bit offset in the TrueType
 536      * font's OS/2 compatibility table's code page ranges fields.


1044                  }
1045              }
1046          }
1047 
1048         String charset;
1049         switch (encoding) {
1050             case -1: charset = "US-ASCII";break;
1051             case 1:  charset = "UTF-16";  break; // most common case first.
1052             case 0:  charset = "UTF-16";  break; // symbol uses this
1053             case 2:  charset = "SJIS";    break;
1054             case 3:  charset = "GBK";     break;
1055             case 4:  charset = "MS950";   break;
1056             case 5:  charset = "EUC_KR";  break;
1057             case 6:  charset = "Johab";   break;
1058             default: charset = "UTF-16";  break;
1059         }
1060 
1061         try {
1062             return new String(bytes, 0, len, charset);
1063         } catch (UnsupportedEncodingException e) {
1064             FontUtilities.logWarning(e + " EncodingID=" + encoding);


1065             return new String(bytes, 0, len);
1066         } catch (Throwable t) {
1067             return null;
1068         }
1069     }
1070 
1071     protected void initNames() {
1072 
1073         byte[] name = new byte[256];
1074         ByteBuffer buffer = getTableBuffer(nameTag);
1075 
1076         if (buffer != null) {
1077             ShortBuffer sbuffer = buffer.asShortBuffer();
1078             sbuffer.get(); // format - not needed.
1079             short numRecords = sbuffer.get();
1080             /* The name table uses unsigned shorts. Many of these
1081              * are known small values that fit in a short.
1082              * The values that are sizes or offsets into the table could be
1083              * greater than 32767, so read and store those as ints
1084              */


< prev index next >