You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TTFFile.java 7.0KB

Improved font auto-detection and handling of AWT-supplied fonts in order to achieve better results when using multiple output formats. Whenever possible, the font names appearing in the operating system can also be used in XSL-FO. Better distinction between Font Family Name ("Arial"), Full Font Name ("Arial Bold") and PostScript Name ("Arial-BoldMT"). This allows a better generation of FontTriplets. The same is done for AWT fonts where I have switch from font-family detection to enumerating all java.awt.Font instances so I can extract Family Name, Full Name and PostScript Name. FontInfoFinder and AWT's FontSetup are synchronized as well as possible at this time. Register "extra-bold" (weight 800) and "light" (weight 200) in triplets when detected. Tweaked FontInfo.fontLookup() for better fallback behaviour. This approach is rapidly nearing its flexibility limits. We should rethink the FontTriplet structure. Fixed font-autodetection so fonts with uppercase extensions are detected, too. Made the way TrueType fonts are embedded in PDF compliant to the specification so viewers correctly identify subset fonts. The name prefix in MultiByteFont was incorrect. Support the detection of the special Type 1 Symbol font. Symbol used to be detected with "ExpertSubsetEncoding" instead of "SymbolEncoding". Type1FontLoader tries to construct a "full name" from the PostScript name. This is a temporary hack until we have a PFB or PFA parser. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@593189 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
Improved font auto-detection and handling of AWT-supplied fonts in order to achieve better results when using multiple output formats. Whenever possible, the font names appearing in the operating system can also be used in XSL-FO. Better distinction between Font Family Name ("Arial"), Full Font Name ("Arial Bold") and PostScript Name ("Arial-BoldMT"). This allows a better generation of FontTriplets. The same is done for AWT fonts where I have switch from font-family detection to enumerating all java.awt.Font instances so I can extract Family Name, Full Name and PostScript Name. FontInfoFinder and AWT's FontSetup are synchronized as well as possible at this time. Register "extra-bold" (weight 800) and "light" (weight 200) in triplets when detected. Tweaked FontInfo.fontLookup() for better fallback behaviour. This approach is rapidly nearing its flexibility limits. We should rethink the FontTriplet structure. Fixed font-autodetection so fonts with uppercase extensions are detected, too. Made the way TrueType fonts are embedded in PDF compliant to the specification so viewers correctly identify subset fonts. The name prefix in MultiByteFont was incorrect. Support the detection of the special Type 1 Symbol font. Symbol used to be detected with "ExpertSubsetEncoding" instead of "SymbolEncoding". Type1FontLoader tries to construct a "full name" from the PostScript name. This is a temporary hack until we have a PFB or PFA parser. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@593189 13f79535-47bb-0310-9956-ffa450edef68
16 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.fonts.truetype;
  19. import java.io.IOException;
  20. /**
  21. * Reads a TrueType file or a TrueType Collection.
  22. * The TrueType spec can be found at the Microsoft.
  23. * Typography site: http://www.microsoft.com/truetype/
  24. */
  25. public class TTFFile extends OpenFont {
  26. public TTFFile() {
  27. this(true, false);
  28. }
  29. /**
  30. * Constructor
  31. * @param useKerning true if kerning data should be loaded
  32. * @param useAdvanced true if advanced typographic tables should be loaded
  33. */
  34. public TTFFile(boolean useKerning, boolean useAdvanced) {
  35. super(useKerning, useAdvanced);
  36. }
  37. /**
  38. * Read the "name" table.
  39. * @throws IOException In case of a I/O problem
  40. */
  41. protected void readName() throws IOException {
  42. seekTab(fontFile, OFTableName.NAME, 2);
  43. int i = fontFile.getCurrentPos();
  44. int n = fontFile.readTTFUShort();
  45. int j = fontFile.readTTFUShort() + i - 2;
  46. i += 2 * 2;
  47. while (n-- > 0) {
  48. // getLogger().debug("Iteration: " + n);
  49. fontFile.seekSet(i);
  50. final int platformID = fontFile.readTTFUShort();
  51. final int encodingID = fontFile.readTTFUShort();
  52. final int languageID = fontFile.readTTFUShort();
  53. int k = fontFile.readTTFUShort();
  54. int l = fontFile.readTTFUShort();
  55. if (((platformID == 1 || platformID == 3)
  56. && (encodingID == 0 || encodingID == 1))) {
  57. fontFile.seekSet(j + fontFile.readTTFUShort());
  58. String txt;
  59. if (platformID == 3) {
  60. txt = fontFile.readTTFString(l, encodingID);
  61. } else {
  62. txt = fontFile.readTTFString(l);
  63. }
  64. if (log.isDebugEnabled()) {
  65. log.debug(platformID + " "
  66. + encodingID + " "
  67. + languageID + " "
  68. + k + " " + txt);
  69. }
  70. switch (k) {
  71. case 0:
  72. if (notice.length() == 0) {
  73. notice = txt;
  74. }
  75. break;
  76. case 1: //Font Family Name
  77. case 16: //Preferred Family
  78. familyNames.add(txt);
  79. break;
  80. case 2:
  81. if (subFamilyName.length() == 0) {
  82. subFamilyName = txt;
  83. }
  84. break;
  85. case 4:
  86. if (fullName.length() == 0 || (platformID == 3 && languageID == 1033)) {
  87. fullName = txt;
  88. }
  89. break;
  90. case 6:
  91. if (postScriptName.length() == 0) {
  92. postScriptName = txt;
  93. }
  94. break;
  95. default:
  96. break;
  97. }
  98. }
  99. i += 6 * 2;
  100. }
  101. }
  102. /**
  103. * Read the "glyf" table to find the bounding boxes.
  104. * @throws IOException In case of a I/O problem
  105. */
  106. private void readGlyf() throws IOException {
  107. OFDirTabEntry dirTab = dirTabs.get(OFTableName.GLYF);
  108. if (dirTab == null) {
  109. throw new IOException("glyf table not found, cannot continue");
  110. }
  111. for (int i = 0; i < (numberOfGlyphs - 1); i++) {
  112. if (mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
  113. fontFile.seekSet(dirTab.getOffset() + mtxTab[i].getOffset());
  114. fontFile.skip(2);
  115. final int[] bbox = {
  116. fontFile.readTTFShort(),
  117. fontFile.readTTFShort(),
  118. fontFile.readTTFShort(),
  119. fontFile.readTTFShort()};
  120. mtxTab[i].setBoundingBox(bbox);
  121. } else {
  122. mtxTab[i].setBoundingBox(mtxTab[0].getBoundingBox());
  123. }
  124. }
  125. long n = (dirTabs.get(OFTableName.GLYF)).getOffset();
  126. for (int i = 0; i < numberOfGlyphs; i++) {
  127. if ((i + 1) >= mtxTab.length
  128. || mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
  129. fontFile.seekSet(n + mtxTab[i].getOffset());
  130. fontFile.skip(2);
  131. final int[] bbox = {
  132. fontFile.readTTFShort(),
  133. fontFile.readTTFShort(),
  134. fontFile.readTTFShort(),
  135. fontFile.readTTFShort()};
  136. mtxTab[i].setBoundingBox(bbox);
  137. } else {
  138. /**@todo Verify that this is correct, looks like a copy/paste bug (jm)*/
  139. final int bbox0 = mtxTab[0].getBoundingBox()[0];
  140. final int[] bbox = {bbox0, bbox0, bbox0, bbox0};
  141. mtxTab[i].setBoundingBox(bbox);
  142. /* Original code
  143. mtxTab[i].bbox[0] = mtxTab[0].bbox[0];
  144. mtxTab[i].bbox[1] = mtxTab[0].bbox[0];
  145. mtxTab[i].bbox[2] = mtxTab[0].bbox[0];
  146. mtxTab[i].bbox[3] = mtxTab[0].bbox[0]; */
  147. }
  148. if (log.isTraceEnabled()) {
  149. log.trace(mtxTab[i].toString(this));
  150. }
  151. }
  152. }
  153. @Override
  154. protected void updateBBoxAndOffset() throws IOException {
  155. readIndexToLocation();
  156. readGlyf();
  157. }
  158. /**
  159. * Read the "loca" table.
  160. * @throws IOException In case of a I/O problem
  161. */
  162. protected final void readIndexToLocation()
  163. throws IOException {
  164. if (!seekTab(fontFile, OFTableName.LOCA, 0)) {
  165. throw new IOException("'loca' table not found, happens when the font file doesn't"
  166. + " contain TrueType outlines (trying to read an OpenType CFF font maybe?)");
  167. }
  168. for (int i = 0; i < numberOfGlyphs; i++) {
  169. mtxTab[i].setOffset(locaFormat == 1 ? fontFile.readTTFULong()
  170. : (fontFile.readTTFUShort() << 1));
  171. }
  172. lastLoca = (locaFormat == 1 ? fontFile.readTTFULong()
  173. : (fontFile.readTTFUShort() << 1));
  174. }
  175. @Override
  176. protected void initializeFont(FontFileReader in) throws IOException {
  177. fontFile = in;
  178. }
  179. }