| /* ==================================================================== |
| 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.hslf.usermodel; |
| |
| import java.awt.Color; |
| import java.io.ByteArrayInputStream; |
| import java.io.InputStream; |
| import java.util.List; |
| |
| import org.apache.poi.ddf.*; |
| import org.apache.poi.hslf.record.Document; |
| import org.apache.poi.sl.usermodel.*; |
| import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; |
| import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; |
| import org.apache.poi.util.POILogFactory; |
| import org.apache.poi.util.POILogger; |
| |
| /** |
| * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint. |
| * |
| * @author Yegor Kozlov |
| */ |
| public final class HSLFFill { |
| // For logging |
| protected POILogger logger = POILogFactory.getLogger(this.getClass()); |
| |
| /** |
| * Fill with a solid color |
| */ |
| public static final int FILL_SOLID = 0; |
| |
| /** |
| * Fill with a pattern (bitmap) |
| */ |
| public static final int FILL_PATTERN = 1; |
| |
| /** |
| * A texture (pattern with its own color map) |
| */ |
| public static final int FILL_TEXTURE = 2; |
| |
| /** |
| * Center a picture in the shape |
| */ |
| public static final int FILL_PICTURE = 3; |
| |
| /** |
| * Shade from start to end points |
| */ |
| public static final int FILL_SHADE = 4; |
| |
| /** |
| * Shade from bounding rectangle to end point |
| */ |
| public static final int FILL_SHADE_CENTER = 5; |
| |
| /** |
| * Shade from shape outline to end point |
| */ |
| public static final int FILL_SHADE_SHAPE = 6; |
| |
| /** |
| * Similar to FILL_SHADE, but the fill angle |
| * is additionally scaled by the aspect ratio of |
| * the shape. If shape is square, it is the same as FILL_SHADE |
| */ |
| public static final int FILL_SHADE_SCALE = 7; |
| |
| /** |
| * shade to title |
| */ |
| public static final int FILL_SHADE_TITLE = 8; |
| |
| /** |
| * Use the background fill color/pattern |
| */ |
| public static final int FILL_BACKGROUND = 9; |
| |
| |
| |
| /** |
| * The shape this background applies to |
| */ |
| protected HSLFShape shape; |
| |
| /** |
| * Construct a <code>Fill</code> object for a shape. |
| * Fill information will be read from shape's escher properties. |
| * |
| * @param shape the shape this background applies to |
| */ |
| public HSLFFill(HSLFShape shape){ |
| this.shape = shape; |
| } |
| |
| |
| public FillStyle getFillStyle() { |
| return new FillStyle() { |
| public PaintStyle getPaint() { |
| switch (getFillType()) { |
| case FILL_SOLID: { |
| return new SolidPaint() { |
| public ColorStyle getSolidColor() { |
| return new ColorStyle() { |
| public Color getColor() { return getForegroundColor(); } |
| public int getAlpha() { return -1; } |
| public int getLumOff() { return -1; } |
| public int getLumMod() { return -1; } |
| public int getShade() { return -1; } |
| public int getTint() { return -1; } |
| }; |
| } |
| }; |
| } |
| case FILL_PICTURE: { |
| final HSLFPictureData pd = getPictureData(); |
| if (pd == null) break; |
| |
| return new TexturePaint() { |
| public InputStream getImageData() { |
| return new ByteArrayInputStream(pd.getData()); |
| } |
| |
| public String getContentType() { |
| return pd.getContentType(); |
| } |
| |
| public int getAlpha() { |
| return (int)(shape.getAlpha(EscherProperties.FILL__FILLOPACITY)*100000.0); |
| } |
| }; |
| } |
| default: |
| logger.log(POILogger.WARN, "unsuported fill type: " + getFillType()); |
| break; |
| } |
| return PaintStyle.TRANSPARENT_PAINT; |
| } |
| }; |
| } |
| |
| /** |
| * Returns fill type. |
| * Must be one of the <code>FILL_*</code> constants defined in this class. |
| * |
| * @return type of fill |
| */ |
| public int getFillType(){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| EscherSimpleProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE); |
| return prop == null ? FILL_SOLID : prop.getPropertyValue(); |
| } |
| |
| /** |
| */ |
| protected void afterInsert(HSLFSheet sh){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); |
| if(p != null) { |
| int idx = p.getPropertyValue(); |
| EscherBSERecord bse = getEscherBSERecord(idx); |
| bse.setRef(bse.getRef() + 1); |
| } |
| } |
| |
| protected EscherBSERecord getEscherBSERecord(int idx){ |
| HSLFSheet sheet = shape.getSheet(); |
| if(sheet == null) { |
| logger.log(POILogger.DEBUG, "Fill has not yet been assigned to a sheet"); |
| return null; |
| } |
| HSLFSlideShow ppt = sheet.getSlideShow(); |
| Document doc = ppt.getDocumentRecord(); |
| EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); |
| EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); |
| if(bstore == null) { |
| logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found "); |
| return null; |
| } |
| List<EscherRecord> lst = bstore.getChildRecords(); |
| return (EscherBSERecord)lst.get(idx-1); |
| } |
| |
| /** |
| * Sets fill type. |
| * Must be one of the <code>FILL_*</code> constants defined in this class. |
| * |
| * @param type type of the fill |
| */ |
| public void setFillType(int type){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); |
| } |
| |
| /** |
| * Foreground color |
| */ |
| public Color getForegroundColor(){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); |
| |
| if(p != null && (p.getPropertyValue() & 0x10) == 0) return null; |
| |
| return shape.getColor(EscherProperties.FILL__FILLCOLOR, EscherProperties.FILL__FILLOPACITY, -1); |
| |
| } |
| |
| /** |
| * Foreground color |
| */ |
| public void setForegroundColor(Color color){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| if (color == null) { |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000); |
| } |
| else { |
| int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011); |
| } |
| } |
| |
| /** |
| * Background color |
| */ |
| public Color getBackgroundColor(){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); |
| |
| if(p != null && (p.getPropertyValue() & 0x10) == 0) return null; |
| |
| return shape.getColor(EscherProperties.FILL__FILLBACKCOLOR, EscherProperties.FILL__FILLOPACITY, -1); |
| } |
| |
| /** |
| * Background color |
| */ |
| public void setBackgroundColor(Color color){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| if (color == null) { |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1); |
| } |
| else { |
| int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); |
| HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); |
| } |
| } |
| |
| /** |
| * <code>PictureData</code> object used in a texture, pattern of picture fill. |
| */ |
| public HSLFPictureData getPictureData(){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); |
| if (p == null) return null; |
| |
| HSLFSlideShow ppt = shape.getSheet().getSlideShow(); |
| HSLFPictureData[] pict = ppt.getPictureData(); |
| Document doc = ppt.getDocumentRecord(); |
| |
| EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); |
| EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); |
| |
| java.util.List<EscherRecord> lst = bstore.getChildRecords(); |
| int idx = p.getPropertyValue(); |
| if (idx == 0){ |
| logger.log(POILogger.WARN, "no reference to picture data found "); |
| } else { |
| EscherBSERecord bse = (EscherBSERecord)lst.get(idx - 1); |
| for ( int i = 0; i < pict.length; i++ ) { |
| if (pict[i].getOffset() == bse.getOffset()){ |
| return pict[i]; |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Assign picture used to fill the underlying shape. |
| * |
| * @param idx 0-based index of the picture added to this ppt by <code>SlideShow.addPicture</code> method. |
| */ |
| public void setPictureData(int idx){ |
| EscherOptRecord opt = shape.getEscherOptRecord(); |
| HSLFShape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx); |
| if( idx != 0 ) { |
| if( shape.getSheet() != null ) { |
| EscherBSERecord bse = getEscherBSERecord(idx); |
| bse.setRef(bse.getRef() + 1); |
| } |
| } |
| } |
| |
| } |