/* * @(#)GranularityRangeModel.java * * Copyright 2002 EGANTT LLP. All rights reserved. * PROPRIETARY/QPL. Use is subject to license terms. */ package com.egantt.drawing.painter.range.model; import java.awt.Graphics; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import com.egantt.awt.graphics.GraphicsContext; import com.egantt.awt.graphics.context.CompoundContext; import com.egantt.awt.graphics.context.compound.SubCompoundContext; import com.egantt.drawing.painter.range.RangeIterator; import com.egantt.drawing.painter.range.RangeModel; import com.egantt.drawing.painter.range.RangeTransform; import com.egantt.drawing.painter.range.iterator.BasicRangeIterator; import com.egantt.drawing.painter.range.transform.CompoundRangeTransform; import com.egantt.model.drawing.DrawingGranularity; import com.egantt.model.drawing.DrawingTransform; import com.egantt.model.drawing.StateResources; import com.egantt.model.drawing.painter.PainterResources; import com.egantt.model.drawing.painter.PainterState; /** * This is an OffScreen plotter, unlike other plotters it attempts to calculate * the required granularity for a plotter by painting in a virtual buffer and then * guessing the range */ public abstract class GranularityRangeModel implements RangeModel { protected final int axisKey; protected final int offset; public GranularityRangeModel(int axisKey, int offset) { this.axisKey = axisKey; this.offset = Math.abs(offset); } // _________________________________________________________________________ public GraphicsContext getContext(Object gran, GraphicsContext context) { return gran != null && context instanceof CompoundContext ? new SubCompoundContext(gran, (CompoundContext) context) : context; } // _________________________________________________________________________ public RangeIterator iterator(Object key, Graphics g, Rectangle bounds, PainterState state, GraphicsContext context) { DrawingGranularity granularity = (DrawingGranularity) context.get(key, PainterResources.GRANULARITY); RangeTransform transform = new CompoundRangeTransform(axisKey, (DrawingTransform []) state.get(StateResources.TRANSFORMS)); Object gran = state.get(StateResources.GRANULARITY_KEY); gran = gran != null ? gran : calculateGranularity(granularity, g, state, transform, bounds); return iterator(gran, granularity, transform, bounds); } // __________________________________________________________________________ protected Object calculateGranularity(DrawingGranularity granularity, Graphics g, PainterState state, RangeTransform transform, Rectangle bounds) { ArrayList <Object> granularities = new ArrayList<Object>(); Rectangle rect = new Rectangle(); // try to cache the rect's they are to expensive for (Iterator iter = granularity.keys(); iter.hasNext();) { Object gran = iter.next(); granularities.add(gran); rect.setBounds(0,0, (int) granularity.width(gran, transform, bounds.width),bounds.height); if (!interateGranularities(granularity.values(gran, transform, bounds.width), gran, g, rect)) { Object lastGran = granularities.get(Math.max(granularities.size() - offset -1, 0)); state.put(StateResources.GRANULARITY_KEY, lastGran); return lastGran; } } return null; } protected boolean interateGranularities(Iterator iter, Object gran, Graphics g, Rectangle rect) { while (iter.hasNext()) { if (accepts(iter.next(), gran, g, rect)) return true; } return false; } // __________________________________________________________________________ protected abstract boolean accepts(Object key, Object gran, Graphics g, Rectangle bounds); // __________________________________________________________________________ protected RangeIterator iterator(Object value, DrawingGranularity granularity, RangeTransform transform, Rectangle bounds) { Iterator inner = value != null ? granularity.values(value, transform, bounds.width) : Collections.EMPTY_SET.iterator(); return new BasicRangeIterator(inner, transform, bounds.width, bounds.height); } }