/** Fetch the TextProp with this name, or null if it isn't present */ public TextProp findByName(String textPropName) { for (int i = 0; i < textPropList.size(); i++) { TextProp prop = textPropList.get(i); if (prop.getName().equals(textPropName)) { return prop; } } return null; }
/** Writes out to disk the header, and then all the properties */ public void writeOut(OutputStream o) throws IOException { // First goes the number of characters we affect StyleTextPropAtom.writeLittleEndian(charactersCovered, o); // Then we have the reserved field if required if (reservedField > -1) { StyleTextPropAtom.writeLittleEndian(reservedField, o); } // Then the mask field int mask = maskSpecial; for (int i = 0; i < textPropList.size(); i++) { TextProp textProp = (TextProp) textPropList.get(i); // sometimes header indicates that the bitmask is present but its value is 0 if (textProp instanceof BitMaskTextProp) { if (mask == 0) mask |= textProp.getWriteMask(); } else { mask |= textProp.getWriteMask(); } } StyleTextPropAtom.writeLittleEndian(mask, o); // Then the contents of all the properties for (int i = 0; i < textPropList.size(); i++) { TextProp textProp = textPropList.get(i); int val = textProp.getValue(); if (textProp.getSize() == 2) { StyleTextPropAtom.writeLittleEndian((short) val, o); } else if (textProp.getSize() == 4) { StyleTextPropAtom.writeLittleEndian(val, o); } } }
/** Add the TextProp with this name to the list */ public TextProp addWithName(String name) { // Find the base TextProp to base on TextProp base = null; for (int i = 0; i < StyleTextPropAtom.characterTextPropTypes.length; i++) { if (StyleTextPropAtom.characterTextPropTypes[i].getName().equals(name)) { base = StyleTextPropAtom.characterTextPropTypes[i]; } } for (int i = 0; i < StyleTextPropAtom.paragraphTextPropTypes.length; i++) { if (StyleTextPropAtom.paragraphTextPropTypes[i].getName().equals(name)) { base = StyleTextPropAtom.paragraphTextPropTypes[i]; } } if (base == null) { throw new IllegalArgumentException( "No TextProp with name " + name + " is defined to add from"); } // Add a copy of this property, in the right place to the list TextProp textProp = (TextProp) base.clone(); int pos = 0; for (int i = 0; i < textPropList.size(); i++) { TextProp curProp = textPropList.get(i); if (textProp.getMask() > curProp.getMask()) { pos++; } } textPropList.add(pos, textProp); return textProp; }
/** * For an existing set of text properties, build the list of properties coded for in a given run * of properties. * * @return the number of bytes that were used encoding the properties list */ public int buildTextPropList( int containsField, TextProp[] potentialProperties, byte[] data, int dataOffset) { int bytesPassed = 0; // For each possible entry, see if we match the mask // If we do, decode that, save it, and shuffle on for (int i = 0; i < potentialProperties.length; i++) { // Check there's still data left to read // Check if this property is found in the mask if ((containsField & potentialProperties[i].getMask()) != 0) { if (dataOffset + bytesPassed >= data.length) { // Out of data, can't be any more properties to go // remember the mask and return maskSpecial |= potentialProperties[i].getMask(); return bytesPassed; } // Bingo, data contains this property TextProp prop = (TextProp) potentialProperties[i].clone(); int val = 0; if (prop.getSize() == 2) { val = LittleEndian.getShort(data, dataOffset + bytesPassed); } else if (prop.getSize() == 4) { val = LittleEndian.getInt(data, dataOffset + bytesPassed); } else if (prop.getSize() == 0) { // remember "special" bits. maskSpecial |= potentialProperties[i].getMask(); continue; } prop.setValue(val); bytesPassed += prop.getSize(); textPropList.add(prop); } } // Return how many bytes were used return bytesPassed; }