/******************************************************************************* * Copyright (c) 2009, Adobe Systems Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * · Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * · Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * · Neither the name of Adobe Systems Incorporated nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ package com.adobe.dp.office.metafile; import java.util.Stack; public class GDISurface { // text alignment public static final int TA_TOP = 0; public static final int TA_CENTER = 6; public static final int TA_BOTTOM = 8; public static final int TA_BASELINE = 24; public static final int TA_LEFT = 0; public static final int TA_RIGHT = 2; public static final int TA_RTLREADING = 256; public static final int TA_NOUPDATECP = 0; public static final int TA_UPDATECP = 1; // PolyFill public static final int ALTERNATE = 1; public static final int WINDING = 2; class GDIState implements Cloneable { GDIBrush currentBrush; GDIPen currentPen; GDIFont currentFont; int windowOrgX; int windowOrgY; int windowExtX; int windowExtY; int viewportOrgX; int viewportOrgY; int viewportExtX; int viewportExtY; int textColor; int mapMode; int bkColor; int rop2; int bkMode; int textAlign; int polyFillMode = WINDING; int miterLimit; GDIState cloneState() { try { return (GDIState) clone(); } catch (CloneNotSupportedException e) { throw new Error("Unexpected exception: CloneNotSupportedException"); } } }; Stack saved = new Stack(); GDIState state = new GDIState(); int boundsLeft; int boundsTop; int boundsRight; int boundsBottom; // -------------------------- setup --------------------------------- public void setBounds(int left, int top, int right, int bottom) { boundsLeft = left; boundsTop = top; boundsRight = right; boundsBottom = bottom; } // --------------------------- GDI functions ------------------------- public void setWindowOrg(int x, int y) { state.windowOrgX = x; state.windowOrgY = y; } public void setWindowExt(int x, int y) { state.windowExtX = x; state.windowExtY = y; if( boundsLeft == boundsRight ) boundsRight = boundsRight + (x>0?x:-x); if( boundsTop == boundsBottom ) boundsBottom = boundsTop + (y>0?y:-y); } public void setViewportOrg(int x, int y) { state.viewportOrgX = x; state.viewportOrgY = y; } public void setViewportExt(int x, int y) { state.viewportExtX = x; state.viewportExtY = y; } public void setTextColor(int rgb) { state.textColor = rgb; } public void setMapMode(int mode) { state.mapMode = mode; } public void setBkColor(int rgb) { state.bkColor = rgb; } public void setROP2(int mode) { state.rop2 = mode; } public void setBkMode(int mode) { state.bkMode = mode; } public void setTextAlign(int mode) { state.textAlign = mode; } public void setMiterLimit(int miterLimit) { state.miterLimit = miterLimit; } public void selectObject(GDIObject obj) { if (obj instanceof GDIPen) { state.currentPen = (GDIPen) obj; } else if (obj instanceof GDIBrush) { state.currentBrush = (GDIBrush) obj; } else if (obj instanceof GDIFont) { state.currentFont = (GDIFont) obj; } } public void deleteObject(GDIObject obj) { GDIState s = state; int si = saved.size(); while (true) { if (obj == s.currentPen) s.currentPen = null; else if (obj == s.currentBrush) s.currentBrush = null; else if (obj == s.currentFont) s.currentFont = null; si--; if (si < 0) break; s = (GDIState) saved.get(si); } } public void setPolyFillMode(int mode) { state.polyFillMode = mode; } public void saveDC() { saved.push(state); state = state.cloneState(); } public void restoreDC() { state = (GDIState) saved.pop(); } public void moveTo(int x, int y) { } public void lineTo(int x, int y) { } public void rectangle(int x1, int y1, int x2, int y2) { } public void ellipse(int x1, int y1, int x2, int y2) { } public void polygon(int[] points, int offset, int len) { } public void polyline(int[] points, int offset, int len) { } public void polyPolyline(int[] lens, int points[]) { int offset = 0; for (int i = 0; i < lens.length; i++) { int len = lens[i] * 2; polyline(points, offset, len); offset += len; } } public void polyPolygon(int[] lens, int points[]) { int offset = 0; for (int i = 0; i < lens.length; i++) { int len = lens[i] * 2; polygon(points, offset, len); offset += len; } } public void extTextOut(int x, int y, String text, int flags, int[] clipRect, int[] adj) { } public GDIPen createPenIndirect(int style, int width, int rgb) { return new GDIPen(style, width, rgb); } public GDIPen extCreatePen(int extStyle, int width, int rgb) { return new GDIPen(GDIPen.PS_SOLID, width, rgb); } public GDIBrush createBrushIndirect(int style, int rgb, int hatch) { return new GDIBrush(style, rgb, hatch); } public GDIFont createFontIndirect(int fontHeight, int width, int esc, int orientation, int weight, String name, boolean italic, boolean underline, boolean strikeout, int charset, int quality, int pitchAndFamily) { return new GDIFont(name, fontHeight, weight, italic, underline, strikeout, charset, quality); } public void stretchDIB(GDIBitmap bitmap, int destX, int destY, int destWidth, int destHeight, int srcX, int srcY, int srcWidth, int srcHeight) { } public void commentMetafile(int version, byte[] data, int offset, int len ) { } public void commentBeginGroup( int left, int top, int right, int bottom, String desc ) { } public void commentEndGroup() { } public void commentEMFPlus(byte[] data, int offset, int len) { } public void commentGDIC(int type, byte[] data, int offset, int len) { } public void comment(byte[] data, int offset, int len) { } // ------------------------- utility functions ------------------------- public GDIBrush getCurrentBrush() { return state.currentBrush; } public GDIFont getCurrentFont() { return state.currentFont; } public GDIPen getCurrentPen() { return state.currentPen; } public int getBkColor() { return state.bkColor; } public int getBkMode() { return state.bkMode; } public int getMapMode() { return state.mapMode; } public int getPolyFillMode() { return state.polyFillMode; } public int getROP2() { return state.rop2; } public int getTextAlign() { return state.textAlign; } public int getTextColor() { return state.textColor; } public int getWindowExtX() { return state.windowExtX; } public int getWindowExtY() { return state.windowExtY; } public int getWindowOrgX() { return state.windowOrgX; } public int getWindowOrgY() { return state.windowOrgY; } public int getBoundsBottom() { return boundsBottom; } public int getBoundsLeft() { return boundsLeft; } public int getBoundsRight() { return boundsRight; } public int getBoundsTop() { return boundsTop; } public int getViewportExtX() { return state.viewportExtX; } public int getViewportExtY() { return state.viewportExtY; } public int getViewportOrgX() { return state.viewportOrgX; } public int getViewportOrgY() { return state.viewportOrgY; } public int getMiterLimit() { return state.miterLimit; } public GDIMatrix getViewportMatrix() { double sx = 1; double sy = 1; // viewport int viewX = state.viewportOrgX; int viewY = state.viewportOrgY; int viewWidth = state.viewportExtX; if( viewWidth == 0 ) { viewX = boundsLeft; viewWidth = boundsRight - boundsLeft; } int viewHeight = state.viewportExtY; if( viewHeight == 0 ) { viewY = boundsTop; viewHeight = boundsBottom - boundsTop; } // device units double x = viewX - boundsLeft; double y = viewY - boundsTop; // scaling if (state.windowExtX != 0 && state.windowExtY != 0 && viewWidth != 0 && viewHeight != 0) { sx = viewWidth/((double) state.windowExtX); sy = viewHeight/((double) state.windowExtY); } // logical units x -= sx * state.windowOrgX; y -= sy * state.windowOrgY; return new GDIMatrix(sx, 0, 0, sy, x, y); } }