001/* 002 * $Id: MetaState.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf.codec.wmf; 045 046import java.util.ArrayList; 047import java.util.Stack; 048 049import com.itextpdf.text.BaseColor; 050import com.itextpdf.text.pdf.PdfContentByte; 051 052public class MetaState { 053 054 public static final int TA_NOUPDATECP = 0; 055 public static final int TA_UPDATECP = 1; 056 public static final int TA_LEFT = 0; 057 public static final int TA_RIGHT = 2; 058 public static final int TA_CENTER = 6; 059 public static final int TA_TOP = 0; 060 public static final int TA_BOTTOM = 8; 061 public static final int TA_BASELINE = 24; 062 063 public static final int TRANSPARENT = 1; 064 public static final int OPAQUE = 2; 065 066 public static final int ALTERNATE = 1; 067 public static final int WINDING = 2; 068 069 public Stack<MetaState> savedStates; 070 public ArrayList<MetaObject> MetaObjects; 071 public Point currentPoint; 072 public MetaPen currentPen; 073 public MetaBrush currentBrush; 074 public MetaFont currentFont; 075 public BaseColor currentBackgroundColor = BaseColor.WHITE; 076 public BaseColor currentTextColor = BaseColor.BLACK; 077 public int backgroundMode = OPAQUE; 078 public int polyFillMode = ALTERNATE; 079 public int lineJoin = 1; 080 public int textAlign; 081 public int offsetWx; 082 public int offsetWy; 083 public int extentWx; 084 public int extentWy; 085 public float scalingX; 086 public float scalingY; 087 088 089 /** Creates new MetaState */ 090 public MetaState() { 091 savedStates = new Stack<MetaState>(); 092 MetaObjects = new ArrayList<MetaObject>(); 093 currentPoint = new Point(0, 0); 094 currentPen = new MetaPen(); 095 currentBrush = new MetaBrush(); 096 currentFont = new MetaFont(); 097 } 098 099 public MetaState(MetaState state) { 100 setMetaState(state); 101 } 102 103 public void setMetaState(MetaState state) { 104 savedStates = state.savedStates; 105 MetaObjects = state.MetaObjects; 106 currentPoint = state.currentPoint; 107 currentPen = state.currentPen; 108 currentBrush = state.currentBrush; 109 currentFont = state.currentFont; 110 currentBackgroundColor = state.currentBackgroundColor; 111 currentTextColor = state.currentTextColor; 112 backgroundMode = state.backgroundMode; 113 polyFillMode = state.polyFillMode; 114 textAlign = state.textAlign; 115 lineJoin = state.lineJoin; 116 offsetWx = state.offsetWx; 117 offsetWy = state.offsetWy; 118 extentWx = state.extentWx; 119 extentWy = state.extentWy; 120 scalingX = state.scalingX; 121 scalingY = state.scalingY; 122 } 123 124 public void addMetaObject(MetaObject object) { 125 for (int k = 0; k < MetaObjects.size(); ++k) { 126 if (MetaObjects.get(k) == null) { 127 MetaObjects.set(k, object); 128 return; 129 } 130 } 131 MetaObjects.add(object); 132 } 133 134 public void selectMetaObject(int index, PdfContentByte cb) { 135 MetaObject obj = MetaObjects.get(index); 136 if (obj == null) 137 return; 138 int style; 139 switch (obj.getType()) { 140 case MetaObject.META_BRUSH: 141 currentBrush = (MetaBrush)obj; 142 style = currentBrush.getStyle(); 143 if (style == MetaBrush.BS_SOLID) { 144 BaseColor color = currentBrush.getColor(); 145 cb.setColorFill(color); 146 } 147 else if (style == MetaBrush.BS_HATCHED) { 148 BaseColor color = currentBackgroundColor; 149 cb.setColorFill(color); 150 } 151 break; 152 case MetaObject.META_PEN: 153 { 154 currentPen = (MetaPen)obj; 155 style = currentPen.getStyle(); 156 if (style != MetaPen.PS_NULL) { 157 BaseColor color = currentPen.getColor(); 158 cb.setColorStroke(color); 159 cb.setLineWidth(Math.abs(currentPen.getPenWidth() * scalingX / extentWx)); 160 switch (style) { 161 case MetaPen.PS_DASH: 162 cb.setLineDash(18, 6, 0); 163 break; 164 case MetaPen.PS_DASHDOT: 165 cb.setLiteral("[9 6 3 6]0 d\n"); 166 break; 167 case MetaPen.PS_DASHDOTDOT: 168 cb.setLiteral("[9 3 3 3 3 3]0 d\n"); 169 break; 170 case MetaPen.PS_DOT: 171 cb.setLineDash(3, 0); 172 break; 173 default: 174 cb.setLineDash(0); 175 break; 176 } 177 } 178 break; 179 } 180 case MetaObject.META_FONT: 181 { 182 currentFont = (MetaFont)obj; 183 break; 184 } 185 } 186 } 187 188 public void deleteMetaObject(int index) { 189 MetaObjects.set(index, null); 190 } 191 192 public void saveState(PdfContentByte cb) { 193 cb.saveState(); 194 MetaState state = new MetaState(this); 195 savedStates.push(state); 196 } 197 198 public void restoreState(int index, PdfContentByte cb) { 199 int pops; 200 if (index < 0) 201 pops = Math.min(-index, savedStates.size()); 202 else 203 pops = Math.max(savedStates.size() - index, 0); 204 if (pops == 0) 205 return; 206 MetaState state = null; 207 while (pops-- != 0) { 208 cb.restoreState(); 209 state = savedStates.pop(); 210 } 211 setMetaState(state); 212 } 213 214 public void cleanup(PdfContentByte cb) { 215 int k = savedStates.size(); 216 while (k-- > 0) 217 cb.restoreState(); 218 } 219 220 public float transformX(int x) { 221 return ((float)x - offsetWx) * scalingX / extentWx; 222 } 223 224 public float transformY(int y) { 225 return (1f - ((float)y - offsetWy) / extentWy) * scalingY; 226 } 227 228 public void setScalingX(float scalingX) { 229 this.scalingX = scalingX; 230 } 231 232 public void setScalingY(float scalingY) { 233 this.scalingY = scalingY; 234 } 235 236 public void setOffsetWx(int offsetWx) { 237 this.offsetWx = offsetWx; 238 } 239 240 public void setOffsetWy(int offsetWy) { 241 this.offsetWy = offsetWy; 242 } 243 244 public void setExtentWx(int extentWx) { 245 this.extentWx = extentWx; 246 } 247 248 public void setExtentWy(int extentWy) { 249 this.extentWy = extentWy; 250 } 251 252 public float transformAngle(float angle) { 253 float ta = scalingY < 0 ? -angle : angle; 254 return (float)(scalingX < 0 ? Math.PI - ta : ta); 255 } 256 257 public void setCurrentPoint(Point p) { 258 currentPoint = p; 259 } 260 261 public Point getCurrentPoint() { 262 return currentPoint; 263 } 264 265 public MetaBrush getCurrentBrush() { 266 return currentBrush; 267 } 268 269 public MetaPen getCurrentPen() { 270 return currentPen; 271 } 272 273 public MetaFont getCurrentFont() { 274 return currentFont; 275 } 276 277 /** Getter for property currentBackgroundColor. 278 * @return Value of property currentBackgroundColor. 279 */ 280 public BaseColor getCurrentBackgroundColor() { 281 return currentBackgroundColor; 282 } 283 284 /** Setter for property currentBackgroundColor. 285 * @param currentBackgroundColor New value of property currentBackgroundColor. 286 */ 287 public void setCurrentBackgroundColor(BaseColor currentBackgroundColor) { 288 this.currentBackgroundColor = currentBackgroundColor; 289 } 290 291 /** Getter for property currentTextColor. 292 * @return Value of property currentTextColor. 293 */ 294 public BaseColor getCurrentTextColor() { 295 return currentTextColor; 296 } 297 298 /** Setter for property currentTextColor. 299 * @param currentTextColor New value of property currentTextColor. 300 */ 301 public void setCurrentTextColor(BaseColor currentTextColor) { 302 this.currentTextColor = currentTextColor; 303 } 304 305 /** Getter for property backgroundMode. 306 * @return Value of property backgroundMode. 307 */ 308 public int getBackgroundMode() { 309 return backgroundMode; 310 } 311 312 /** Setter for property backgroundMode. 313 * @param backgroundMode New value of property backgroundMode. 314 */ 315 public void setBackgroundMode(int backgroundMode) { 316 this.backgroundMode = backgroundMode; 317 } 318 319 /** Getter for property textAlign. 320 * @return Value of property textAlign. 321 */ 322 public int getTextAlign() { 323 return textAlign; 324 } 325 326 /** Setter for property textAlign. 327 * @param textAlign New value of property textAlign. 328 */ 329 public void setTextAlign(int textAlign) { 330 this.textAlign = textAlign; 331 } 332 333 /** Getter for property polyFillMode. 334 * @return Value of property polyFillMode. 335 */ 336 public int getPolyFillMode() { 337 return polyFillMode; 338 } 339 340 /** Setter for property polyFillMode. 341 * @param polyFillMode New value of property polyFillMode. 342 */ 343 public void setPolyFillMode(int polyFillMode) { 344 this.polyFillMode = polyFillMode; 345 } 346 347 public void setLineJoinRectangle(PdfContentByte cb) { 348 if (lineJoin != 0) { 349 lineJoin = 0; 350 cb.setLineJoin(0); 351 } 352 } 353 354 public void setLineJoinPolygon(PdfContentByte cb) { 355 if (lineJoin == 0) { 356 lineJoin = 1; 357 cb.setLineJoin(1); 358 } 359 } 360 361 public boolean getLineNeutral() { 362 return lineJoin == 0; 363 } 364 365}