| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.hssf.model; |
| |
| import org.apache.poi.ddf.EscherDggRecord; |
| import org.apache.poi.ddf.EscherDgRecord; |
| |
| import java.util.Map; |
| import java.util.HashMap; |
| |
| /** |
| * Provides utilities to manage drawing groups. |
| * |
| * @deprecated in POI 3.15-beta2, scheduled for removal in 3.17, use DrawingManager2 instead |
| */ |
| @Deprecated |
| public class DrawingManager |
| { |
| EscherDggRecord dgg; |
| Map<Short, EscherDgRecord> dgMap = new HashMap<Short, EscherDgRecord>(); // key = Short(drawingId), value=EscherDgRecord |
| |
| public DrawingManager( EscherDggRecord dgg ) |
| { |
| this.dgg = dgg; |
| } |
| |
| public EscherDgRecord createDgRecord() |
| { |
| EscherDgRecord dg = new EscherDgRecord(); |
| dg.setRecordId( EscherDgRecord.RECORD_ID ); |
| short dgId = findNewDrawingGroupId(); |
| dg.setOptions( (short) ( dgId << 4 ) ); |
| dg.setNumShapes( 0 ); |
| dg.setLastMSOSPID( -1 ); |
| dgg.addCluster( dgId, 0 ); |
| dgg.setDrawingsSaved( dgg.getDrawingsSaved() + 1 ); |
| dgMap.put( dgId, dg ); |
| return dg; |
| } |
| |
| /** |
| * Allocates new shape id for the new drawing group id. |
| * |
| * @param drawingGroupId The drawing group id |
| * @return a new shape id. |
| */ |
| public int allocateShapeId(short drawingGroupId) |
| { |
| // Get the last shape id for this drawing group. |
| EscherDgRecord dg = dgMap.get(drawingGroupId); |
| int lastShapeId = dg.getLastMSOSPID(); |
| |
| |
| // Have we run out of shapes for this cluster? |
| int newShapeId = 0; |
| if (lastShapeId % 1024 == 1023) |
| { |
| // Yes: |
| // Find the starting shape id of the next free cluster |
| newShapeId = findFreeSPIDBlock(); |
| // Create a new cluster in the dgg record. |
| dgg.addCluster(drawingGroupId, 1); |
| } |
| else |
| { |
| // No: |
| // Find the cluster for this drawing group with free space. |
| for (int i = 0; i < dgg.getFileIdClusters().length; i++) |
| { |
| EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i]; |
| if (c.getDrawingGroupId() == drawingGroupId) |
| { |
| if (c.getNumShapeIdsUsed() != 1024) |
| { |
| // Increment the number of shapes used for this cluster. |
| c.incrementShapeId(); |
| } |
| } |
| // If the last shape id = -1 then we know to find a free block; |
| if (dg.getLastMSOSPID() == -1) |
| { |
| newShapeId = findFreeSPIDBlock(); |
| } |
| else |
| { |
| // The new shape id to be the last shapeid of this cluster + 1 |
| newShapeId = dg.getLastMSOSPID() + 1; |
| } |
| } |
| } |
| // Increment the total number of shapes used in the dgg. |
| dgg.setNumShapesSaved(dgg.getNumShapesSaved() + 1); |
| // Is the new shape id >= max shape id for dgg? |
| if (newShapeId >= dgg.getShapeIdMax()) |
| { |
| // Yes: |
| // Set the max shape id = new shape id + 1 |
| dgg.setShapeIdMax(newShapeId + 1); |
| } |
| // Set last shape id for this drawing group. |
| dg.setLastMSOSPID(newShapeId); |
| // Increased the number of shapes used for this drawing group. |
| dg.incrementShapeCount(); |
| |
| |
| return newShapeId; |
| } |
| |
| //////////// Non-public methods ///////////// |
| short findNewDrawingGroupId() |
| { |
| short dgId = 1; |
| while ( drawingGroupExists( dgId ) ) |
| dgId++; |
| return dgId; |
| } |
| |
| boolean drawingGroupExists( short dgId ) |
| { |
| for ( int i = 0; i < dgg.getFileIdClusters().length; i++ ) |
| { |
| if ( dgg.getFileIdClusters()[i].getDrawingGroupId() == dgId ) |
| return true; |
| } |
| return false; |
| } |
| |
| int findFreeSPIDBlock() |
| { |
| int max = dgg.getShapeIdMax(); |
| int next = ( ( max / 1024 ) + 1 ) * 1024; |
| return next; |
| } |
| |
| public EscherDggRecord getDgg() |
| { |
| return dgg; |
| } |
| |
| } |