1 | /* | |
2 | * $Id: TrueTypeFontSubSet.java 4066 2009-09-19 12:44:47Z psoares33 $ | |
3 | * | |
4 | * Copyright 2001, 2002 Paulo Soares | |
5 | * | |
6 | * The contents of this file are subject to the Mozilla Public License Version 1.1 | |
7 | * (the "License"); you may not use this file except in compliance with the License. | |
8 | * You may obtain a copy of the License at http://www.mozilla.org/MPL/ | |
9 | * | |
10 | * Software distributed under the License is distributed on an "AS IS" basis, | |
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 | * for the specific language governing rights and limitations under the License. | |
13 | * | |
14 | * The Original Code is 'iText, a free JAVA-PDF library'. | |
15 | * | |
16 | * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by | |
17 | * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. | |
18 | * All Rights Reserved. | |
19 | * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer | |
20 | * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. | |
21 | * | |
22 | * Contributor(s): all the names of the contributors are added in the source code | |
23 | * where applicable. | |
24 | * | |
25 | * Alternatively, the contents of this file may be used under the terms of the | |
26 | * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the | |
27 | * provisions of LGPL are applicable instead of those above. If you wish to | |
28 | * allow use of your version of this file only under the terms of the LGPL | |
29 | * License and not to allow others to use your version of this file under | |
30 | * the MPL, indicate your decision by deleting the provisions above and | |
31 | * replace them with the notice and other provisions required by the LGPL. | |
32 | * If you do not delete the provisions above, a recipient may use your version | |
33 | * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. | |
34 | * | |
35 | * This library is free software; you can redistribute it and/or modify it | |
36 | * under the terms of the MPL as stated above or under the terms of the GNU | |
37 | * Library General Public License as published by the Free Software Foundation; | |
38 | * either version 2 of the License, or any later version. | |
39 | * | |
40 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
41 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
42 | * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more | |
43 | * details. | |
44 | * | |
45 | * If you didn't download this code from the following link, you should check if | |
46 | * you aren't using an obsolete version: | |
47 | * http://www.lowagie.com/iText/ | |
48 | */ | |
49 | ||
50 | package com.lowagie.text.pdf; | |
51 | ||
52 | import com.lowagie.text.DocumentException; | |
53 | import com.lowagie.text.ExceptionConverter; | |
54 | import com.lowagie.text.error_messages.MessageLocalization; | |
55 | ||
56 | import java.io.IOException; | |
57 | import java.util.ArrayList; | |
58 | import java.util.Arrays; | |
59 | import java.util.HashMap; | |
60 | ||
61 | ||
62 | /** | |
63 | * Subsets a True Type font by removing the unneeded glyphs from | |
64 | * the font. | |
65 | * | |
66 | * @author Paulo Soares (psoares@consiste.pt) | |
67 | */ | |
68 | class TrueTypeFontSubSet { | |
69 | static final String[] tableNamesSimple = {"cvt ", "fpgm", "glyf", "head", | |
70 | "hhea", "hmtx", "loca", "maxp", "prep"}; | |
71 | static final String[] tableNamesCmap = {"cmap", "cvt ", "fpgm", "glyf", "head", | |
72 | "hhea", "hmtx", "loca", "maxp", "prep"}; | |
73 | static final String[] tableNamesExtra = {"OS/2", "cmap", "cvt ", "fpgm", "glyf", "head", | |
74 | "hhea", "hmtx", "loca", "maxp", "name, prep"}; | |
75 | static final int[] entrySelectors = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4}; | |
76 | static final int TABLE_CHECKSUM = 0; | |
77 | static final int TABLE_OFFSET = 1; | |
78 | static final int TABLE_LENGTH = 2; | |
79 | static final int HEAD_LOCA_FORMAT_OFFSET = 51; | |
80 | ||
81 | static final int ARG_1_AND_2_ARE_WORDS = 1; | |
82 | static final int WE_HAVE_A_SCALE = 8; | |
83 | static final int MORE_COMPONENTS = 32; | |
84 | static final int WE_HAVE_AN_X_AND_Y_SCALE = 64; | |
85 | static final int WE_HAVE_A_TWO_BY_TWO = 128; | |
86 | ||
87 | ||
88 | /** | |
89 | * Contains the location of the several tables. The key is the name of | |
90 | * the table and the value is an <CODE>int[3]</CODE> where position 0 | |
91 | * is the checksum, position 1 is the offset from the start of the file | |
92 | * and position 2 is the length of the table. | |
93 | */ | |
94 | protected HashMap tableDirectory; | |
95 | /** | |
96 | * The file in use. | |
97 | */ | |
98 | protected RandomAccessFileOrArray rf; | |
99 | /** | |
100 | * The file name. | |
101 | */ | |
102 | protected String fileName; | |
103 | protected boolean includeCmap; | |
104 | protected boolean includeExtras; | |
105 | protected boolean locaShortTable; | |
106 | protected int[] locaTable; | |
107 | protected HashMap glyphsUsed; | |
108 | protected ArrayList glyphsInList; | |
109 | protected int tableGlyphOffset; | |
110 | protected int[] newLocaTable; | |
111 | protected byte[] newLocaTableOut; | |
112 | protected byte[] newGlyfTable; | |
113 | protected int glyfTableRealSize; | |
114 | protected int locaTableRealSize; | |
115 | protected byte[] outFont; | |
116 | protected int fontPtr; | |
117 | protected int directoryOffset; | |
118 | ||
119 | /** | |
120 | * Creates a new TrueTypeFontSubSet | |
121 | * | |
122 | * @param directoryOffset The offset from the start of the file to the table directory | |
123 | * @param fileName the file name of the font | |
124 | * @param glyphsUsed the glyphs used | |
125 | * @param includeCmap <CODE>true</CODE> if the table cmap is to be included in the generated font | |
126 | */ | |
127 | TrueTypeFontSubSet(String fileName, RandomAccessFileOrArray rf, HashMap glyphsUsed, int directoryOffset, boolean includeCmap, boolean includeExtras) { | |
128 | this.fileName = fileName; | |
129 | this.rf = rf; | |
130 | this.glyphsUsed = glyphsUsed; | |
131 | this.includeCmap = includeCmap; | |
132 | this.includeExtras = includeExtras; | |
133 | this.directoryOffset = directoryOffset; | |
134 | glyphsInList = new ArrayList(glyphsUsed.keySet()); | |
135 | } | |
136 | ||
137 | /** | |
138 | * Does the actual work of subsetting the font. | |
139 | * | |
140 | * @return the subset font | |
141 | * @throws IOException on error | |
142 | * @throws DocumentException on error | |
143 | */ | |
144 | byte[] process() throws IOException, DocumentException { | |
145 | try { | |
146 |
1
1. process : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::reOpen → NO_COVERAGE |
rf.reOpen(); |
147 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::createTableDirectory → NO_COVERAGE |
createTableDirectory(); |
148 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::readLoca → NO_COVERAGE |
readLoca(); |
149 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::flatGlyphs → NO_COVERAGE |
flatGlyphs(); |
150 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::createNewGlyphTables → NO_COVERAGE |
createNewGlyphTables(); |
151 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::locaTobytes → NO_COVERAGE |
locaTobytes(); |
152 |
1
1. process : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::assembleFont → NO_COVERAGE |
assembleFont(); |
153 |
1
1. process : mutated return of Object value for com/lowagie/text/pdf/TrueTypeFontSubSet::process to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return outFont; |
154 | } finally { | |
155 | try { | |
156 |
1
1. process : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::close → NO_COVERAGE |
rf.close(); |
157 | } catch (Exception e) { | |
158 | // empty on purpose | |
159 | } | |
160 | } | |
161 | } | |
162 | ||
163 | protected void assembleFont() throws IOException { | |
164 | int[] tableLocation; | |
165 | int fullFontSize = 0; | |
166 | String[] tableNames; | |
167 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (includeExtras) |
168 | tableNames = tableNamesExtra; | |
169 | else { | |
170 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (includeCmap) |
171 | tableNames = tableNamesCmap; | |
172 | else | |
173 | tableNames = tableNamesSimple; | |
174 | } | |
175 | int tablesUsed = 2; | |
176 | int len = 0; | |
177 | for (String name : tableNames) { | |
178 |
2
1. assembleFont : negated conditional → NO_COVERAGE 2. assembleFont : negated conditional → NO_COVERAGE |
if (name.equals("glyf") || name.equals("loca")) |
179 | continue; | |
180 | tableLocation = (int[]) tableDirectory.get(name); | |
181 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
182 | continue; | |
183 |
1
1. assembleFont : Changed increment from 1 to -1 → NO_COVERAGE |
++tablesUsed; |
184 |
3
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE 2. assembleFont : Replaced bitwise AND with OR → NO_COVERAGE 3. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fullFontSize += (tableLocation[TABLE_LENGTH] + 3) & (~3); |
185 | } | |
186 |
1
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fullFontSize += newLocaTableOut.length; |
187 |
1
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fullFontSize += newGlyfTable.length; |
188 |
2
1. assembleFont : Replaced integer multiplication with division → NO_COVERAGE 2. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
int ref = 16 * tablesUsed + 12; |
189 |
1
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fullFontSize += ref; |
190 | outFont = new byte[fullFontSize]; | |
191 | fontPtr = 0; | |
192 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(0x00010000); |
193 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontShort → NO_COVERAGE |
writeFontShort(tablesUsed); |
194 | int selector = entrySelectors[tablesUsed]; | |
195 |
3
1. assembleFont : Replaced Shift Left with Shift Right → NO_COVERAGE 2. assembleFont : Replaced integer multiplication with division → NO_COVERAGE 3. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontShort → NO_COVERAGE |
writeFontShort((1 << selector) * 16); |
196 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontShort → NO_COVERAGE |
writeFontShort(selector); |
197 |
4
1. assembleFont : Replaced Shift Left with Shift Right → NO_COVERAGE 2. assembleFont : Replaced integer subtraction with addition → NO_COVERAGE 3. assembleFont : Replaced integer multiplication with division → NO_COVERAGE 4. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontShort → NO_COVERAGE |
writeFontShort((tablesUsed - (1 << selector)) * 16); |
198 | for (String name : tableNames) { | |
199 | tableLocation = (int[]) tableDirectory.get(name); | |
200 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
201 | continue; | |
202 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontString → NO_COVERAGE |
writeFontString(name); |
203 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (name.equals("glyf")) { |
204 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(calculateChecksum(newGlyfTable)); |
205 | len = glyfTableRealSize; | |
206 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
} else if (name.equals("loca")) { |
207 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(calculateChecksum(newLocaTableOut)); |
208 | len = locaTableRealSize; | |
209 | } else { | |
210 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(tableLocation[TABLE_CHECKSUM]); |
211 | len = tableLocation[TABLE_LENGTH]; | |
212 | } | |
213 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(ref); |
214 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(len); |
215 |
3
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE 2. assembleFont : Replaced bitwise AND with OR → NO_COVERAGE 3. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
ref += (len + 3) & (~3); |
216 | } | |
217 | for (String name : tableNames) { | |
218 | tableLocation = (int[]) tableDirectory.get(name); | |
219 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
220 | continue; | |
221 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
if (name.equals("glyf")) { |
222 |
1
1. assembleFont : removed call to java/lang/System::arraycopy → NO_COVERAGE |
System.arraycopy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.length); |
223 |
1
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fontPtr += newGlyfTable.length; |
224 | newGlyfTable = null; | |
225 |
1
1. assembleFont : negated conditional → NO_COVERAGE |
} else if (name.equals("loca")) { |
226 |
1
1. assembleFont : removed call to java/lang/System::arraycopy → NO_COVERAGE |
System.arraycopy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.length); |
227 |
1
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fontPtr += newLocaTableOut.length; |
228 | newLocaTableOut = null; | |
229 | } else { | |
230 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(tableLocation[TABLE_OFFSET]); |
231 |
1
1. assembleFont : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::readFully → NO_COVERAGE |
rf.readFully(outFont, fontPtr, tableLocation[TABLE_LENGTH]); |
232 |
3
1. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE 2. assembleFont : Replaced bitwise AND with OR → NO_COVERAGE 3. assembleFont : Replaced integer addition with subtraction → NO_COVERAGE |
fontPtr += (tableLocation[TABLE_LENGTH] + 3) & (~3); |
233 | } | |
234 | } | |
235 | } | |
236 | ||
237 | protected void createTableDirectory() throws IOException, DocumentException { | |
238 | tableDirectory = new HashMap(); | |
239 |
1
1. createTableDirectory : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(directoryOffset); |
240 | int id = rf.readInt(); | |
241 |
1
1. createTableDirectory : negated conditional → NO_COVERAGE |
if (id != 0x00010000) |
242 | throw new DocumentException(MessageLocalization.getComposedMessage("1.is.not.a.true.type.file", fileName)); | |
243 | int num_tables = rf.readUnsignedShort(); | |
244 | rf.skipBytes(6); | |
245 |
3
1. createTableDirectory : changed conditional boundary → NO_COVERAGE 2. createTableDirectory : Changed increment from 1 to -1 → NO_COVERAGE 3. createTableDirectory : negated conditional → NO_COVERAGE |
for (int k = 0; k < num_tables; ++k) { |
246 | String tag = readStandardString(4); | |
247 | int[] tableLocation = new int[3]; | |
248 | tableLocation[TABLE_CHECKSUM] = rf.readInt(); | |
249 | tableLocation[TABLE_OFFSET] = rf.readInt(); | |
250 | tableLocation[TABLE_LENGTH] = rf.readInt(); | |
251 | tableDirectory.put(tag, tableLocation); | |
252 | } | |
253 | } | |
254 | ||
255 | protected void readLoca() throws IOException, DocumentException { | |
256 | int[] tableLocation; | |
257 | tableLocation = (int[]) tableDirectory.get("head"); | |
258 |
1
1. readLoca : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
259 | throw new DocumentException(MessageLocalization.getComposedMessage("table.1.does.not.exist.in.2", "head", fileName)); | |
260 |
2
1. readLoca : Replaced integer addition with subtraction → NO_COVERAGE 2. readLoca : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(tableLocation[TABLE_OFFSET] + HEAD_LOCA_FORMAT_OFFSET); |
261 |
1
1. readLoca : negated conditional → NO_COVERAGE |
locaShortTable = (rf.readUnsignedShort() == 0); |
262 | tableLocation = (int[]) tableDirectory.get("loca"); | |
263 |
1
1. readLoca : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
264 | throw new DocumentException(MessageLocalization.getComposedMessage("table.1.does.not.exist.in.2", "loca", fileName)); | |
265 |
1
1. readLoca : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(tableLocation[TABLE_OFFSET]); |
266 |
1
1. readLoca : negated conditional → NO_COVERAGE |
if (locaShortTable) { |
267 |
1
1. readLoca : Replaced integer division with multiplication → NO_COVERAGE |
int entries = tableLocation[TABLE_LENGTH] / 2; |
268 | locaTable = new int[entries]; | |
269 |
3
1. readLoca : changed conditional boundary → NO_COVERAGE 2. readLoca : Changed increment from 1 to -1 → NO_COVERAGE 3. readLoca : negated conditional → NO_COVERAGE |
for (int k = 0; k < entries; ++k) |
270 |
1
1. readLoca : Replaced integer multiplication with division → NO_COVERAGE |
locaTable[k] = rf.readUnsignedShort() * 2; |
271 | } else { | |
272 |
1
1. readLoca : Replaced integer division with multiplication → NO_COVERAGE |
int entries = tableLocation[TABLE_LENGTH] / 4; |
273 | locaTable = new int[entries]; | |
274 |
3
1. readLoca : changed conditional boundary → NO_COVERAGE 2. readLoca : Changed increment from 1 to -1 → NO_COVERAGE 3. readLoca : negated conditional → NO_COVERAGE |
for (int k = 0; k < entries; ++k) |
275 | locaTable[k] = rf.readInt(); | |
276 | } | |
277 | } | |
278 | ||
279 | protected void createNewGlyphTables() throws IOException { | |
280 | newLocaTable = new int[locaTable.length]; | |
281 | int[] activeGlyphs = new int[glyphsInList.size()]; | |
282 |
2
1. createNewGlyphTables : changed conditional boundary → NO_COVERAGE 2. createNewGlyphTables : negated conditional → NO_COVERAGE |
for (int k = 0; k < activeGlyphs.length; ++k) |
283 | activeGlyphs[k] = (Integer) glyphsInList.get(k); | |
284 |
1
1. createNewGlyphTables : removed call to java/util/Arrays::sort → NO_COVERAGE |
Arrays.sort(activeGlyphs); |
285 | int glyfSize = 0; | |
286 | for (int glyph : activeGlyphs) { | |
287 |
3
1. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE 2. createNewGlyphTables : Replaced integer subtraction with addition → NO_COVERAGE 3. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE |
glyfSize += locaTable[glyph + 1] - locaTable[glyph]; |
288 | } | |
289 | glyfTableRealSize = glyfSize; | |
290 |
2
1. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE 2. createNewGlyphTables : Replaced bitwise AND with OR → NO_COVERAGE |
glyfSize = (glyfSize + 3) & (~3); |
291 | newGlyfTable = new byte[glyfSize]; | |
292 | int glyfPtr = 0; | |
293 | int listGlyf = 0; | |
294 |
2
1. createNewGlyphTables : changed conditional boundary → NO_COVERAGE 2. createNewGlyphTables : negated conditional → NO_COVERAGE |
for (int k = 0; k < newLocaTable.length; ++k) { |
295 | newLocaTable[k] = glyfPtr; | |
296 |
3
1. createNewGlyphTables : changed conditional boundary → NO_COVERAGE 2. createNewGlyphTables : negated conditional → NO_COVERAGE 3. createNewGlyphTables : negated conditional → NO_COVERAGE |
if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) { |
297 |
1
1. createNewGlyphTables : Changed increment from 1 to -1 → NO_COVERAGE |
++listGlyf; |
298 | newLocaTable[k] = glyfPtr; | |
299 | int start = locaTable[k]; | |
300 |
2
1. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE 2. createNewGlyphTables : Replaced integer subtraction with addition → NO_COVERAGE |
int len = locaTable[k + 1] - start; |
301 |
2
1. createNewGlyphTables : changed conditional boundary → NO_COVERAGE 2. createNewGlyphTables : negated conditional → NO_COVERAGE |
if (len > 0) { |
302 |
2
1. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE 2. createNewGlyphTables : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(tableGlyphOffset + start); |
303 |
1
1. createNewGlyphTables : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::readFully → NO_COVERAGE |
rf.readFully(newGlyfTable, glyfPtr, len); |
304 |
1
1. createNewGlyphTables : Replaced integer addition with subtraction → NO_COVERAGE |
glyfPtr += len; |
305 | } | |
306 | } | |
307 | } | |
308 | } | |
309 | ||
310 | protected void locaTobytes() { | |
311 |
1
1. locaTobytes : negated conditional → NO_COVERAGE |
if (locaShortTable) |
312 |
1
1. locaTobytes : Replaced integer multiplication with division → NO_COVERAGE |
locaTableRealSize = newLocaTable.length * 2; |
313 | else | |
314 |
1
1. locaTobytes : Replaced integer multiplication with division → NO_COVERAGE |
locaTableRealSize = newLocaTable.length * 4; |
315 |
2
1. locaTobytes : Replaced integer addition with subtraction → NO_COVERAGE 2. locaTobytes : Replaced bitwise AND with OR → NO_COVERAGE |
newLocaTableOut = new byte[(locaTableRealSize + 3) & (~3)]; |
316 | outFont = newLocaTableOut; | |
317 | fontPtr = 0; | |
318 | for (int i : newLocaTable) { | |
319 |
1
1. locaTobytes : negated conditional → NO_COVERAGE |
if (locaShortTable) |
320 |
2
1. locaTobytes : Replaced integer division with multiplication → NO_COVERAGE 2. locaTobytes : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontShort → NO_COVERAGE |
writeFontShort(i / 2); |
321 | else | |
322 |
1
1. locaTobytes : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::writeFontInt → NO_COVERAGE |
writeFontInt(i); |
323 | } | |
324 | ||
325 | } | |
326 | ||
327 | protected void flatGlyphs() throws IOException, DocumentException { | |
328 | int[] tableLocation; | |
329 | tableLocation = (int[]) tableDirectory.get("glyf"); | |
330 |
1
1. flatGlyphs : negated conditional → NO_COVERAGE |
if (tableLocation == null) |
331 | throw new DocumentException(MessageLocalization.getComposedMessage("table.1.does.not.exist.in.2", "glyf", fileName)); | |
332 | Integer glyph0 = 0; | |
333 |
1
1. flatGlyphs : negated conditional → NO_COVERAGE |
if (!glyphsUsed.containsKey(glyph0)) { |
334 | glyphsUsed.put(glyph0, null); | |
335 | glyphsInList.add(glyph0); | |
336 | } | |
337 | tableGlyphOffset = tableLocation[TABLE_OFFSET]; | |
338 |
3
1. flatGlyphs : changed conditional boundary → NO_COVERAGE 2. flatGlyphs : Changed increment from 1 to -1 → NO_COVERAGE 3. flatGlyphs : negated conditional → NO_COVERAGE |
for (int k = 0; k < glyphsInList.size(); ++k) { // TODO: concurrent List modification error in checkGlyphComposite(glyph) |
339 | int glyph = (Integer) glyphsInList.get(k); | |
340 |
1
1. flatGlyphs : removed call to com/lowagie/text/pdf/TrueTypeFontSubSet::checkGlyphComposite → NO_COVERAGE |
checkGlyphComposite(glyph); |
341 | } | |
342 | } | |
343 | ||
344 | protected void checkGlyphComposite(int glyph) throws IOException { | |
345 | int start = locaTable[glyph]; | |
346 |
2
1. checkGlyphComposite : Replaced integer addition with subtraction → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if (start == locaTable[glyph + 1]) // no contour |
347 | return; | |
348 |
2
1. checkGlyphComposite : Replaced integer addition with subtraction → NO_COVERAGE 2. checkGlyphComposite : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::seek → NO_COVERAGE |
rf.seek(tableGlyphOffset + start); |
349 | int numContours = rf.readShort(); | |
350 |
2
1. checkGlyphComposite : changed conditional boundary → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if (numContours >= 0) |
351 | return; | |
352 | rf.skipBytes(8); | |
353 | for (; ; ) { | |
354 | int flags = rf.readUnsignedShort(); | |
355 | Integer cGlyph = rf.readUnsignedShort(); | |
356 |
1
1. checkGlyphComposite : negated conditional → NO_COVERAGE |
if (!glyphsUsed.containsKey(cGlyph)) { |
357 | glyphsUsed.put(cGlyph, null); | |
358 | glyphsInList.add(cGlyph); | |
359 | } | |
360 |
2
1. checkGlyphComposite : Replaced bitwise AND with OR → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if ((flags & MORE_COMPONENTS) == 0) |
361 | return; | |
362 | int skip; | |
363 |
2
1. checkGlyphComposite : Replaced bitwise AND with OR → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if ((flags & ARG_1_AND_2_ARE_WORDS) != 0) |
364 | skip = 4; | |
365 | else | |
366 | skip = 2; | |
367 |
2
1. checkGlyphComposite : Replaced bitwise AND with OR → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if ((flags & WE_HAVE_A_SCALE) != 0) |
368 |
1
1. checkGlyphComposite : Changed increment from 2 to -2 → NO_COVERAGE |
skip += 2; |
369 |
2
1. checkGlyphComposite : Replaced bitwise AND with OR → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0) |
370 |
1
1. checkGlyphComposite : Changed increment from 4 to -4 → NO_COVERAGE |
skip += 4; |
371 |
2
1. checkGlyphComposite : Replaced bitwise AND with OR → NO_COVERAGE 2. checkGlyphComposite : negated conditional → NO_COVERAGE |
if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0) |
372 |
1
1. checkGlyphComposite : Changed increment from 8 to -8 → NO_COVERAGE |
skip += 8; |
373 | rf.skipBytes(skip); | |
374 | } | |
375 | } | |
376 | ||
377 | /** | |
378 | * Reads a <CODE>String</CODE> from the font file as bytes using the Cp1252 | |
379 | * encoding. | |
380 | * | |
381 | * @param length the length of bytes to read | |
382 | * @return the <CODE>String</CODE> read | |
383 | * @throws IOException the font file could not be read | |
384 | */ | |
385 | protected String readStandardString(int length) throws IOException { | |
386 | byte[] buf = new byte[length]; | |
387 |
1
1. readStandardString : removed call to com/lowagie/text/pdf/RandomAccessFileOrArray::readFully → NO_COVERAGE |
rf.readFully(buf); |
388 | try { | |
389 |
1
1. readStandardString : mutated return of Object value for com/lowagie/text/pdf/TrueTypeFontSubSet::readStandardString to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return new String(buf, BaseFont.WINANSI); |
390 | } catch (Exception e) { | |
391 | throw new ExceptionConverter(e); | |
392 | } | |
393 | } | |
394 | ||
395 | protected void writeFontShort(int n) { | |
396 |
2
1. writeFontShort : Replaced integer addition with subtraction → NO_COVERAGE 2. writeFontShort : Replaced Shift Right with Shift Left → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n >> 8); |
397 |
1
1. writeFontShort : Replaced integer addition with subtraction → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n); |
398 | } | |
399 | ||
400 | protected void writeFontInt(int n) { | |
401 |
2
1. writeFontInt : Replaced integer addition with subtraction → NO_COVERAGE 2. writeFontInt : Replaced Shift Right with Shift Left → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n >> 24); |
402 |
2
1. writeFontInt : Replaced integer addition with subtraction → NO_COVERAGE 2. writeFontInt : Replaced Shift Right with Shift Left → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n >> 16); |
403 |
2
1. writeFontInt : Replaced integer addition with subtraction → NO_COVERAGE 2. writeFontInt : Replaced Shift Right with Shift Left → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n >> 8); |
404 |
1
1. writeFontInt : Replaced integer addition with subtraction → NO_COVERAGE |
outFont[fontPtr++] = (byte) (n); |
405 | } | |
406 | ||
407 | protected void writeFontString(String s) { | |
408 | byte[] b = PdfEncodings.convertToBytes(s, BaseFont.WINANSI); | |
409 |
1
1. writeFontString : removed call to java/lang/System::arraycopy → NO_COVERAGE |
System.arraycopy(b, 0, outFont, fontPtr, b.length); |
410 |
1
1. writeFontString : Replaced integer addition with subtraction → NO_COVERAGE |
fontPtr += b.length; |
411 | } | |
412 | ||
413 | protected int calculateChecksum(byte[] b) { | |
414 |
1
1. calculateChecksum : Replaced integer division with multiplication → NO_COVERAGE |
int len = b.length / 4; |
415 | int v0 = 0; | |
416 | int v1 = 0; | |
417 | int v2 = 0; | |
418 | int v3 = 0; | |
419 | int ptr = 0; | |
420 |
3
1. calculateChecksum : changed conditional boundary → NO_COVERAGE 2. calculateChecksum : Changed increment from 1 to -1 → NO_COVERAGE 3. calculateChecksum : negated conditional → NO_COVERAGE |
for (int k = 0; k < len; ++k) { |
421 |
3
1. calculateChecksum : Changed increment from 1 to -1 → NO_COVERAGE 2. calculateChecksum : Replaced bitwise AND with OR → NO_COVERAGE 3. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE |
v3 += b[ptr++] & 0xff; |
422 |
3
1. calculateChecksum : Changed increment from 1 to -1 → NO_COVERAGE 2. calculateChecksum : Replaced bitwise AND with OR → NO_COVERAGE 3. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE |
v2 += b[ptr++] & 0xff; |
423 |
3
1. calculateChecksum : Changed increment from 1 to -1 → NO_COVERAGE 2. calculateChecksum : Replaced bitwise AND with OR → NO_COVERAGE 3. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE |
v1 += b[ptr++] & 0xff; |
424 |
3
1. calculateChecksum : Changed increment from 1 to -1 → NO_COVERAGE 2. calculateChecksum : Replaced bitwise AND with OR → NO_COVERAGE 3. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE |
v0 += b[ptr++] & 0xff; |
425 | } | |
426 |
7
1. calculateChecksum : Replaced Shift Left with Shift Right → NO_COVERAGE 2. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE 3. calculateChecksum : Replaced Shift Left with Shift Right → NO_COVERAGE 4. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE 5. calculateChecksum : Replaced Shift Left with Shift Right → NO_COVERAGE 6. calculateChecksum : Replaced integer addition with subtraction → NO_COVERAGE 7. calculateChecksum : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return v0 + (v1 << 8) + (v2 << 16) + (v3 << 24); |
427 | } | |
428 | } | |
Mutations | ||
146 |
1.1 |
|
147 |
1.1 |
|
148 |
1.1 |
|
149 |
1.1 |
|
150 |
1.1 |
|
151 |
1.1 |
|
152 |
1.1 |
|
153 |
1.1 |
|
156 |
1.1 |
|
167 |
1.1 |
|
170 |
1.1 |
|
178 |
1.1 2.2 |
|
181 |
1.1 |
|
183 |
1.1 |
|
184 |
1.1 2.2 3.3 |
|
186 |
1.1 |
|
187 |
1.1 |
|
188 |
1.1 2.2 |
|
189 |
1.1 |
|
192 |
1.1 |
|
193 |
1.1 |
|
195 |
1.1 2.2 3.3 |
|
196 |
1.1 |
|
197 |
1.1 2.2 3.3 4.4 |
|
200 |
1.1 |
|
202 |
1.1 |
|
203 |
1.1 |
|
204 |
1.1 |
|
206 |
1.1 |
|
207 |
1.1 |
|
210 |
1.1 |
|
213 |
1.1 |
|
214 |
1.1 |
|
215 |
1.1 2.2 3.3 |
|
219 |
1.1 |
|
221 |
1.1 |
|
222 |
1.1 |
|
223 |
1.1 |
|
225 |
1.1 |
|
226 |
1.1 |
|
227 |
1.1 |
|
230 |
1.1 |
|
231 |
1.1 |
|
232 |
1.1 2.2 3.3 |
|
239 |
1.1 |
|
241 |
1.1 |
|
245 |
1.1 2.2 3.3 |
|
258 |
1.1 |
|
260 |
1.1 2.2 |
|
261 |
1.1 |
|
263 |
1.1 |
|
265 |
1.1 |
|
266 |
1.1 |
|
267 |
1.1 |
|
269 |
1.1 2.2 3.3 |
|
270 |
1.1 |
|
272 |
1.1 |
|
274 |
1.1 2.2 3.3 |
|
282 |
1.1 2.2 |
|
284 |
1.1 |
|
287 |
1.1 2.2 3.3 |
|
290 |
1.1 2.2 |
|
294 |
1.1 2.2 |
|
296 |
1.1 2.2 3.3 |
|
297 |
1.1 |
|
300 |
1.1 2.2 |
|
301 |
1.1 2.2 |
|
302 |
1.1 2.2 |
|
303 |
1.1 |
|
304 |
1.1 |
|
311 |
1.1 |
|
312 |
1.1 |
|
314 |
1.1 |
|
315 |
1.1 2.2 |
|
319 |
1.1 |
|
320 |
1.1 2.2 |
|
322 |
1.1 |
|
330 |
1.1 |
|
333 |
1.1 |
|
338 |
1.1 2.2 3.3 |
|
340 |
1.1 |
|
346 |
1.1 2.2 |
|
348 |
1.1 2.2 |
|
350 |
1.1 2.2 |
|
356 |
1.1 |
|
360 |
1.1 2.2 |
|
363 |
1.1 2.2 |
|
367 |
1.1 2.2 |
|
368 |
1.1 |
|
369 |
1.1 2.2 |
|
370 |
1.1 |
|
371 |
1.1 2.2 |
|
372 |
1.1 |
|
387 |
1.1 |
|
389 |
1.1 |
|
396 |
1.1 2.2 |
|
397 |
1.1 |
|
401 |
1.1 2.2 |
|
402 |
1.1 2.2 |
|
403 |
1.1 2.2 |
|
404 |
1.1 |
|
409 |
1.1 |
|
410 |
1.1 |
|
414 |
1.1 |
|
420 |
1.1 2.2 3.3 |
|
421 |
1.1 2.2 3.3 |
|
422 |
1.1 2.2 3.3 |
|
423 |
1.1 2.2 3.3 |
|
424 |
1.1 2.2 3.3 |
|
426 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |