/** * Sets the anchor (the bounding box rectangle) of this shape. All coordinates should be expressed * in Master units (576 dpi). * * @param anchor new anchor */ public void setAnchor(java.awt.Rectangle anchor) { EscherContainerRecord spContainer = (EscherContainerRecord) _escherContainer.getChildRecords().get(0); EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord) getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID); // hack. internal variable EscherClientAnchorRecord.shortRecord can be // initialized only in fillFields(). We need to set shortRecord=false; byte[] header = new byte[16]; LittleEndian.putUShort(header, 0, 0); LittleEndian.putUShort(header, 2, 0); LittleEndian.putInt(header, 4, 8); clientAnchor.fillFields(header, 0, null); clientAnchor.setFlag((short) (anchor.y * MASTER_DPI / POINT_DPI)); clientAnchor.setCol1((short) (anchor.x * MASTER_DPI / POINT_DPI)); clientAnchor.setDx1((short) ((anchor.width + anchor.x) * MASTER_DPI / POINT_DPI)); clientAnchor.setRow1((short) ((anchor.height + anchor.y) * MASTER_DPI / POINT_DPI)); EscherSpgrRecord spgr = (EscherSpgrRecord) getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID); spgr.setRectX1(anchor.x * MASTER_DPI / POINT_DPI); spgr.setRectY1(anchor.y * MASTER_DPI / POINT_DPI); spgr.setRectX2((anchor.x + anchor.width) * MASTER_DPI / POINT_DPI); spgr.setRectY2((anchor.y + anchor.height) * MASTER_DPI / POINT_DPI); }
/** Create a new TextHeader Atom, for an unknown type of text */ public TextHeaderAtom() { _header = new byte[8]; LittleEndian.putUShort(_header, 0, 0); LittleEndian.putUShort(_header, 2, (int) _type); LittleEndian.putInt(_header, 4, 4); textType = OTHER_TYPE; }
static void write(Sttb sttb, HWPFOutputStream tableStream) throws IOException { final int headerSize = sttb.cDataLength == 2 ? 6 : 8; byte[] header = new byte[headerSize]; LittleEndian.putShort(header, 0, (short) 0xffff); if (sttb.data == null || sttb.data.length == 0) { if (sttb.cDataLength == 4) { LittleEndian.putInt(header, 2, 0); LittleEndian.putUShort(header, 6, sttb.cbExtra); tableStream.write(header); return; } LittleEndian.putUShort(header, 2, 0); LittleEndian.putUShort(header, 4, sttb.cbExtra); tableStream.write(header); return; } if (sttb.cDataLength == 4) { LittleEndian.putInt(header, 2, sttb.data.length); LittleEndian.putUShort(header, 6, sttb.cbExtra); tableStream.write(header); } else { LittleEndian.putUShort(header, 2, sttb.data.length); LittleEndian.putUShort(header, 4, sttb.cbExtra); tableStream.write(header); } for (int i = 0; i < sttb.data.length; i++) { String entry = sttb.data[i]; if (entry == null) { // is it correct? tableStream.write(new byte[] {-1, 0}); continue; } byte[] buf = new byte[entry.length() * 2 + sttb.cbExtra + 2]; LittleEndian.putShort(buf, 0, (short) entry.length()); StringUtil.putUnicodeLE(entry, buf, 2); if (sttb.extraData != null && i < sttb.extraData.length && sttb.extraData[i] != null) System.arraycopy( sttb.extraData[i], 0, buf, entry.length() * 2, Math.min(sttb.extraData[i].length, sttb.cbExtra)); tableStream.write(buf); } }
/** * Creates a byte array representation of this data structure. Suitable for writing to a Word * document. * * @param fcMin The file offset in the main stream where text begins. * @return A byte array representing this data structure. */ protected byte[] toByteArray(int fcMin) { byte[] buf = new byte[512]; int size = _papxList.size(); int grpprlOffset = 0; int bxOffset = 0; int fcOffset = 0; byte[] lastGrpprl = new byte[0]; // total size is currently the size of one FC int totalSize = FC_SIZE; int index = 0; for (; index < size; index++) { byte[] grpprl = ((PAPX) _papxList.get(index)).getGrpprl(); int grpprlLength = grpprl.length; // is grpprl huge? if (grpprlLength > 488) { grpprlLength = 8; // set equal to size of sprmPHugePapx grpprl } // check to see if we have enough room for an FC, a BX, and the grpprl // and the 1 byte size of the grpprl. int addition = 0; if (!Arrays.equals(grpprl, lastGrpprl)) { addition = (FC_SIZE + BX_SIZE + grpprlLength + 1); } else { addition = (FC_SIZE + BX_SIZE); } totalSize += addition; // if size is uneven we will have to add one so the first grpprl falls // on a word boundary if (totalSize > 511 + (index % 2)) { totalSize -= addition; break; } // grpprls must fall on word boundaries if (grpprlLength % 2 > 0) { totalSize += 1; } else { totalSize += 2; } lastGrpprl = grpprl; } // see if we couldn't fit some if (index != size) { _overFlow = new ArrayList(); _overFlow.addAll(_papxList.subList(index, size)); } // index should equal number of papxs that will be in this fkp now. buf[511] = (byte) index; bxOffset = (FC_SIZE * index) + FC_SIZE; grpprlOffset = 511; PAPX papx = null; lastGrpprl = new byte[0]; for (int x = 0; x < index; x++) { papx = (PAPX) _papxList.get(x); byte[] phe = papx.getParagraphHeight().toByteArray(); byte[] grpprl = papx.getGrpprl(); // is grpprl huge? if (grpprl.length > 488) { // if so do we have storage at getHugeGrpprlOffset() int hugeGrpprlOffset = papx.getHugeGrpprlOffset(); if (hugeGrpprlOffset == -1) // then we have no storage... { throw new UnsupportedOperationException("This Paragraph has no dataStream storage."); } else // we have some storage... { // get the size of the existing storage int maxHugeGrpprlSize = LittleEndian.getUShort(_dataStream, hugeGrpprlOffset); if (maxHugeGrpprlSize < grpprl.length - 2) // grpprl.length-2 because we don't store the istd throw new UnsupportedOperationException( "This Paragraph's dataStream storage is too small."); } // store grpprl at hugeGrpprlOffset System.arraycopy( grpprl, 2, _dataStream, hugeGrpprlOffset + 2, grpprl.length - 2); // grpprl.length-2 because we don't store the istd LittleEndian.putUShort(_dataStream, hugeGrpprlOffset, grpprl.length - 2); // grpprl = grpprl containing only a sprmPHugePapx2 int istd = LittleEndian.getUShort(grpprl, 0); grpprl = new byte[8]; LittleEndian.putUShort(grpprl, 0, istd); LittleEndian.putUShort(grpprl, 2, 0x6646); // sprmPHugePapx2 LittleEndian.putInt(grpprl, 4, hugeGrpprlOffset); } boolean same = Arrays.equals(lastGrpprl, grpprl); if (!same) { grpprlOffset -= (grpprl.length + (2 - grpprl.length % 2)); grpprlOffset -= (grpprlOffset % 2); } LittleEndian.putInt(buf, fcOffset, papx.getStartBytes() + fcMin); buf[bxOffset] = (byte) (grpprlOffset / 2); System.arraycopy(phe, 0, buf, bxOffset + 1, phe.length); // refer to the section on PAPX in the spec. Places a size on the front // of the PAPX. Has to do with how the grpprl stays on word // boundaries. if (!same) { int copyOffset = grpprlOffset; if ((grpprl.length % 2) > 0) { buf[copyOffset++] = (byte) ((grpprl.length + 1) / 2); } else { buf[++copyOffset] = (byte) ((grpprl.length) / 2); copyOffset++; } System.arraycopy(grpprl, 0, buf, copyOffset, grpprl.length); lastGrpprl = grpprl; } bxOffset += BX_SIZE; fcOffset += FC_SIZE; } LittleEndian.putInt(buf, fcOffset, papx.getEndBytes() + fcMin); return buf; }