Beispiel #1
0
  /**
   * 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;
  }
Beispiel #3
0
  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;
  }