private static Map<Integer, Table> buildTablesFromBuilders( Font font, Map<Integer, Table.Builder<? extends Table>> builderMap) { Map<Integer, Table> tableMap = new TreeMap<Integer, Table>(); interRelateBuilders(builderMap); long fontChecksum = 0; boolean tablesChanged = false; FontHeaderTable.Builder headerTableBuilder = null; // now build all the tables for (Table.Builder<? extends Table> builder : builderMap.values()) { Table table = null; if (Tag.isHeaderTable(builder.header().tag())) { headerTableBuilder = (FontHeaderTable.Builder) builder; continue; } if (builder.readyToBuild()) { tablesChanged |= builder.changed(); table = builder.build(); } if (table == null) { throw new RuntimeException("Unable to build table - " + builder); } long tableChecksum = table.calculatedChecksum(); fontChecksum += tableChecksum; tableMap.put(table.header().tag(), table); } // now fix up the header table Table headerTable = null; if (headerTableBuilder != null) { if (tablesChanged) { headerTableBuilder.setFontChecksum(fontChecksum); } if (headerTableBuilder.readyToBuild()) { tablesChanged |= headerTableBuilder.changed(); headerTable = headerTableBuilder.build(); } if (headerTable == null) { throw new RuntimeException("Unable to build table - " + headerTableBuilder); } fontChecksum += headerTable.calculatedChecksum(); tableMap.put(headerTable.header().tag(), headerTable); } font.checksum = fontChecksum & 0xffffffffL; return tableMap; }
/** * Build the table headers to be used for serialization. These headers will be filled out with the * data required for serialization. The headers will be sorted in the order specified and only * those specified will have headers generated. * * @param tableOrdering the tables to generate headers for and the order to sort them * @return a list of table headers ready for serialization */ private List<Header> buildTableHeadersForSerialization(List<Integer> tableOrdering) { List<Integer> finalTableOrdering = this.generateTableOrdering(tableOrdering); List<Header> tableHeaders = new ArrayList<Header>(this.numTables()); int tableOffset = Offset.tableRecordBegin.offset + this.numTables() * Offset.tableRecordSize.offset; for (Integer tag : finalTableOrdering) { Table table = this.tables.get(tag); if (table != null) { tableHeaders.add( new Header(tag, table.calculatedChecksum(), tableOffset, table.header().length())); // write on boundary of 4 bytes tableOffset += (table.dataLength() + 3) & ~3; } } return tableHeaders; }