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.

OTFFile.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. import java.util.ArrayList;
  21. import java.util.Collection;
  22. import java.util.HashMap;
  23. import java.util.Iterator;
  24. import java.util.List;
  25. import java.util.Map;
  26. import org.apache.fontbox.cff.CFFDataInput;
  27. import org.apache.fontbox.cff.CFFFont;
  28. import org.apache.fontbox.cff.CFFParser;
  29. import org.apache.fontbox.cff.charset.CFFCharset;
  30. public class OTFFile extends OpenFont {
  31. protected CFFFont fileFont;
  32. public OTFFile() throws IOException {
  33. checkForFontbox();
  34. }
  35. private void checkForFontbox() throws IOException {
  36. try {
  37. Class.forName("org.apache.fontbox.cff.CFFFont");
  38. } catch (ClassNotFoundException ex) {
  39. throw new IOException("The Fontbox jar was not found in the classpath. This is "
  40. + "required for OTF CFF ssupport.");
  41. }
  42. }
  43. @Override
  44. protected void updateBBoxAndOffset() throws IOException {
  45. List<Mapping> gidMappings = getGIDMappings(fileFont);
  46. Map<Integer, String> sidNames = constructNameMap(gidMappings);
  47. UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[0]);
  48. for (int i = 0; i < mappings.length; i++) {
  49. int glyphIdx = mappings[i].getGlyphIndex();
  50. Mapping m = gidMappings.get(glyphIdx);
  51. String name = sidNames.get(m.getSID());
  52. mtxTab[glyphIdx].setName(name);
  53. }
  54. }
  55. private List<Mapping> getGIDMappings(CFFFont font) {
  56. List<Mapping> gidMappings = new ArrayList<Mapping>();
  57. Mapping notdef = new Mapping();
  58. gidMappings.add(notdef);
  59. for (CFFCharset.Entry entry : font.getCharset().getEntries()) {
  60. String name = entry.getName();
  61. byte[] bytes = font.getCharStringsDict().get(name);
  62. if (bytes == null) {
  63. continue;
  64. }
  65. Mapping mapping = new Mapping();
  66. mapping.setSID(entry.getSID());
  67. mapping.setName(name);
  68. mapping.setBytes(bytes);
  69. gidMappings.add(mapping);
  70. }
  71. return gidMappings;
  72. }
  73. private Map<Integer, String> constructNameMap(Collection<Mapping> mappings) {
  74. Map<Integer, String> sidNames = new HashMap<Integer, String>();
  75. Iterator<Mapping> it = mappings.iterator();
  76. while (it.hasNext()) {
  77. Mapping mapping = it.next();
  78. sidNames.put(mapping.getSID(), mapping.getName());
  79. }
  80. return sidNames;
  81. }
  82. private static class Mapping {
  83. private int sid;
  84. private String name;
  85. private byte[] bytes;
  86. public void setSID(int sid) {
  87. this.sid = sid;
  88. }
  89. public int getSID() {
  90. return sid;
  91. }
  92. public void setName(String name) {
  93. this.name = name;
  94. }
  95. public String getName() {
  96. return name;
  97. }
  98. public void setBytes(byte[] bytes) {
  99. this.bytes = bytes;
  100. }
  101. public byte[] getBytes() {
  102. return bytes;
  103. }
  104. }
  105. @Override
  106. protected void initializeFont(FontFileReader in) throws IOException {
  107. fontFile = in;
  108. fontFile.seekSet(0);
  109. CFFParser parser = new CFFParser();
  110. fileFont = parser.parse(in.getAllBytes()).get(0);
  111. }
  112. protected void readName() throws IOException {
  113. Object familyName = fileFont.getProperty("FamilyName");
  114. if (familyName != null && !familyName.equals("")) {
  115. familyNames.add(familyName.toString());
  116. fullName = familyName.toString();
  117. } else {
  118. fullName = fileFont.getName();
  119. familyNames.add(fullName);
  120. }
  121. }
  122. /**
  123. * Reads the CFFData from a given font file
  124. * @param fontFile The font file being read
  125. * @return The byte data found in the CFF table
  126. */
  127. public static byte[] getCFFData(FontFileReader fontFile) throws IOException {
  128. byte[] cff = fontFile.getAllBytes();
  129. CFFDataInput input = new CFFDataInput(fontFile.getAllBytes());
  130. input.readBytes(4); //OTTO
  131. short numTables = input.readShort();
  132. input.readShort(); //searchRange
  133. input.readShort(); //entrySelector
  134. input.readShort(); //rangeShift
  135. for (int q = 0; q < numTables; q++) {
  136. String tagName = new String(input.readBytes(4));
  137. readLong(input); //Checksum
  138. long offset = readLong(input);
  139. long length = readLong(input);
  140. if (tagName.equals("CFF ")) {
  141. cff = new byte[(int)length];
  142. System.arraycopy(fontFile.getAllBytes(), (int)offset, cff, 0, cff.length);
  143. break;
  144. }
  145. }
  146. return cff;
  147. }
  148. private static long readLong(CFFDataInput input) throws IOException {
  149. return (input.readCard16() << 16) | input.readCard16();
  150. }
  151. }