123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- /* ====================================================================
- 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.usermodel;
-
- import java.awt.Dimension;
- import java.io.ByteArrayInputStream;
- import java.io.UnsupportedEncodingException;
-
- import org.apache.poi.ddf.*;
- import org.apache.poi.hssf.record.EscherAggregate;
- import org.apache.poi.hssf.record.ObjRecord;
- import org.apache.poi.ss.usermodel.Picture;
- import org.apache.poi.ss.util.ImageUtils;
- import org.apache.poi.hssf.model.InternalWorkbook;
-
- /**
- * Represents a escher picture. Eg. A GIF, JPEG etc...
- *
- * @author Glen Stampoultzis
- * @author Yegor Kozlov (yegor at apache.org)
- */
- public class HSSFPicture extends HSSFSimpleShape implements Picture {
- public static final int PICTURE_TYPE_EMF = HSSFWorkbook.PICTURE_TYPE_EMF; // Windows Enhanced Metafile
- public static final int PICTURE_TYPE_WMF = HSSFWorkbook.PICTURE_TYPE_WMF; // Windows Metafile
- public static final int PICTURE_TYPE_PICT = HSSFWorkbook.PICTURE_TYPE_PICT; // Macintosh PICT
- public static final int PICTURE_TYPE_JPEG = HSSFWorkbook.PICTURE_TYPE_JPEG; // JFIF
- public static final int PICTURE_TYPE_PNG = HSSFWorkbook.PICTURE_TYPE_PNG; // PNG
- public static final int PICTURE_TYPE_DIB = HSSFWorkbook.PICTURE_TYPE_DIB; // Windows DIB
-
- /**
- * width of 1px in columns with default width in units of 1/256 of a character width
- */
- private static final float PX_DEFAULT = 32.00f;
- /**
- * width of 1px in columns with overridden width in units of 1/256 of a character width
- */
- private static final float PX_MODIFIED = 36.56f;
-
- /**
- * Height of 1px of a row
- */
- private static final int PX_ROW = 15;
-
- public HSSFPicture(EscherContainerRecord spContainer, ObjRecord objRecord) {
- super(spContainer, objRecord);
- }
-
- /**
- * Constructs a picture object.
- */
- public HSSFPicture( HSSFShape parent, HSSFAnchor anchor )
- {
- super( parent, anchor );
- super.setShapeType(OBJECT_TYPE_PICTURE);
- }
-
- public int getPictureIndex()
- {
- EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.BLIP__BLIPTODISPLAY);
- if (null == property){
- return -1;
- }
- return property.getPropertyValue();
- }
-
- public void setPictureIndex( int pictureIndex )
- {
- setPropertyValue(new EscherSimpleProperty( EscherProperties.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
- }
-
- @Override
- protected EscherContainerRecord createSpContainer() {
- EscherContainerRecord spContainer = super.createSpContainer();
- EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
- removeEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
- removeEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
- spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
- return spContainer;
- }
-
- /**
- * Resize the image
- * <p>
- * Please note, that this method works correctly only for workbooks
- * with default font size (Arial 10pt for .xls).
- * If the default font is changed the resized image can be streched vertically or horizontally.
- * </p>
- *
- * @param scale the amount by which image dimensions are multiplied relative to the original size.
- * <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original,
- * <code>resize(2.0)</code> resizes to 200% of the original.
- */
- public void resize(double scale){
- HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
- anchor.setAnchorType(2);
-
- HSSFClientAnchor pref = getPreferredSize(scale);
-
- int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
- int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
-
- anchor.setCol2((short)col2);
- anchor.setDx1(0);
- anchor.setDx2(pref.getDx2());
-
- anchor.setRow2(row2);
- anchor.setDy1(0);
- anchor.setDy2(pref.getDy2());
- }
-
- /**
- * Reset the image to the original size.
- *
- * <p>
- * Please note, that this method works correctly only for workbooks
- * with default font size (Arial 10pt for .xls).
- * If the default font is changed the resized image can be streched vertically or horizontally.
- * </p>
- */
- public void resize(){
- resize(1.0);
- }
-
- /**
- * Calculate the preferred size for this picture.
- *
- * @return HSSFClientAnchor with the preferred size for this image
- * @since POI 3.0.2
- */
- public HSSFClientAnchor getPreferredSize(){
- return getPreferredSize(1.0);
- }
-
- /**
- * Calculate the preferred size for this picture.
- *
- * @param scale the amount by which image dimensions are multiplied relative to the original size.
- * @return HSSFClientAnchor with the preferred size for this image
- * @since POI 3.0.2
- */
- public HSSFClientAnchor getPreferredSize(double scale){
- HSSFClientAnchor anchor = (HSSFClientAnchor)getAnchor();
-
- Dimension size = getImageDimension();
- double scaledWidth = size.getWidth() * scale;
- double scaledHeight = size.getHeight() * scale;
-
- float w = 0;
-
- //space in the leftmost cell
- w += getColumnWidthInPixels(anchor.getCol1())*(1 - (float)anchor.getDx1()/1024);
- short col2 = (short)(anchor.getCol1() + 1);
- int dx2 = 0;
-
- while(w < scaledWidth){
- w += getColumnWidthInPixels(col2++);
- }
-
- if(w > scaledWidth) {
- //calculate dx2, offset in the rightmost cell
- col2--;
- double cw = getColumnWidthInPixels(col2);
- double delta = w - scaledWidth;
- dx2 = (int)((cw-delta)/cw*1024);
- }
- anchor.setCol2(col2);
- anchor.setDx2(dx2);
-
- float h = 0;
- h += (1 - (float)anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1());
- int row2 = anchor.getRow1() + 1;
- int dy2 = 0;
-
- while(h < scaledHeight){
- h += getRowHeightInPixels(row2++);
- }
- if(h > scaledHeight) {
- row2--;
- double ch = getRowHeightInPixels(row2);
- double delta = h - scaledHeight;
- dy2 = (int)((ch-delta)/ch*256);
- }
- anchor.setRow2(row2);
- anchor.setDy2(dy2);
-
- return anchor;
- }
-
- private float getColumnWidthInPixels(int column){
-
- int cw = _patriarch.getSheet().getColumnWidth(column);
- float px = getPixelWidth(column);
-
- return cw/px;
- }
-
- private float getRowHeightInPixels(int i){
-
- HSSFRow row = _patriarch.getSheet().getRow(i);
- float height;
- if(row != null) height = row.getHeight();
- else height = _patriarch.getSheet().getDefaultRowHeight();
-
- return height/PX_ROW;
- }
-
- private float getPixelWidth(int column){
-
- int def = _patriarch.getSheet().getDefaultColumnWidth()*256;
- int cw = _patriarch.getSheet().getColumnWidth(column);
-
- return cw == def ? PX_DEFAULT : PX_MODIFIED;
- }
-
- /**
- * Return the dimension of this image
- *
- * @return image dimension
- */
- public Dimension getImageDimension(){
- EscherBSERecord bse = _patriarch.getSheet()._book.getBSERecord(getPictureIndex());
- byte[] data = bse.getBlipRecord().getPicturedata();
- int type = bse.getBlipTypeWin32();
- return ImageUtils.getImageDimension(new ByteArrayInputStream(data), type);
- }
-
- /**
- * Return picture data for this shape
- *
- * @return picture data for this shape
- */
- public HSSFPictureData getPictureData(){
- InternalWorkbook iwb = _patriarch.getSheet().getWorkbook().getWorkbook();
- EscherBlipRecord blipRecord = iwb.getBSERecord(getPictureIndex()).getBlipRecord();
- return new HSSFPictureData(blipRecord);
- }
-
- @Override
- void afterInsert(HSSFPatriarch patriarch) {
- EscherAggregate agg = patriarch._getBoundAggregate();
- agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
- EscherBSERecord bse =
- patriarch.getSheet().getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
- bse.setRef(bse.getRef() + 1);
- }
-
- /**
- * The color applied to the lines of this shape.
- */
- public String getFileName() {
- EscherComplexProperty propFile = (EscherComplexProperty) getOptRecord().lookup(
- EscherProperties.BLIP__BLIPFILENAME);
- try {
- if (null == propFile){
- return "";
- }
- return new String(propFile.getComplexData(), "UTF-16LE").trim();
- } catch (UnsupportedEncodingException e) {
- return "";
- }
- }
-
- public void setFileName(String data){
- try {
- EscherComplexProperty prop = new EscherComplexProperty(EscherProperties.BLIP__BLIPFILENAME, true, data.getBytes("UTF-16LE"));
- setPropertyValue(prop);
- } catch (UnsupportedEncodingException e) {
- System.out.println("Unsupported encoding: UTF-16LE");
- }
- }
-
- @Override
- public void setShapeType(int shapeType) {
- throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
- }
-
- @Override
- public HSSFShape cloneShape() {
- EscherContainerRecord spContainer = new EscherContainerRecord();
- byte [] inSp = getEscherContainer().serialize();
- spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
- ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
- return new HSSFPicture(spContainer, obj);
- }
- }
|