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

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. }