package org.eclipse.nebula.paperclips.core.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.nebula.paperclips.core.CompositeEntry; import org.eclipse.nebula.paperclips.core.CompositePiece; import org.eclipse.nebula.paperclips.core.LayerEntry; import org.eclipse.nebula.paperclips.core.LayerEntryIterator; import org.eclipse.nebula.paperclips.core.LayerPrint; import org.eclipse.nebula.paperclips.core.PaperClips; import org.eclipse.nebula.paperclips.core.PrintIterator; import org.eclipse.nebula.paperclips.core.PrintPiece; import org.eclipse.nebula.paperclips.core.internal.util.PrintSizeStrategy; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; public class LayerIterator implements PrintIterator { LayerEntryIterator[] entries; public LayerIterator(LayerPrint print, Device device, GC gc) { entries = new LayerEntryIteratorImpl[print.getEntries().length]; LayerEntry[] e = print.getEntries(); for (int i = 0; i < entries.length; i++) { entries[i] = e[i].iterator(device, gc); } } public LayerIterator(LayerIterator that) { this.entries = (LayerEntryIterator[]) that.entries.clone(); for (int i = 0; i < entries.length; i++) if (entries[i].getTarget().hasNext()) entries[i] = entries[i].copy(); } public boolean hasNext() { for (int i = 0; i < entries.length; i++) if (entries[i].getTarget().hasNext()) return true; return false; } public PrintPiece next(int width, int height) { if (!hasNext()) PaperClips.error("No more content"); //$NON-NLS-1$ PrintPiece[] pieces = nextPieces(width, height); if (pieces == null) return null; CompositeEntry[] entries = new CompositeEntry[pieces.length]; for (int i = 0; i < entries.length; i++) { PrintPiece piece = pieces[i]; int offset = getHorzAlignmentOffset(this.entries[i].getAlignment(), piece.getSize().x, width); entries[i] = new CompositeEntry(piece, new Point(offset, 0)); } return new CompositePiece(entries); } private PrintPiece[] nextPieces(int width, int height) { LayerEntryIteratorImpl[] entries = (LayerEntryIteratorImpl[]) this.entries .clone(); List pieces = new ArrayList(); for (int i = 0; i < entries.length; i++) { LayerEntryIteratorImpl entry = entries[i]; if (entry.target.hasNext()) { PrintPiece piece = PaperClips.next(entry.target, width, height); if (piece == null) { for (Iterator iter = pieces.iterator(); iter.hasNext();) ((PrintPiece) iter.next()).dispose(); return null; } pieces.add(piece); } } // Replace instance entries with the entries that were just consumed. this.entries = entries; return (PrintPiece[]) pieces.toArray(new PrintPiece[pieces.size()]); } private int getHorzAlignmentOffset(int alignment, int pieceWidth, int totalWidth) { int offset = 0; switch (alignment) { case SWT.CENTER: offset = (totalWidth - pieceWidth) / 2; break; case SWT.RIGHT: offset = totalWidth - pieceWidth; break; } return offset; } Point computeSize(PrintSizeStrategy strategy) { Point size = new Point(0, 0); for (int i = 0; i < entries.length; i++) { LayerEntryIterator entry = entries[i]; Point entrySize = strategy.computeSize(entry.getTarget()); size.x = Math.max(size.x, entrySize.x); size.y = Math.max(size.y, entrySize.y); } return size; } public Point minimumSize() { return computeSize(PrintSizeStrategy.MINIMUM); } public Point preferredSize() { return computeSize(PrintSizeStrategy.PREFERRED); } public PrintIterator copy() { return new LayerIterator(this); } }