| | |
| | | package com.ximple.io.dgn7; |
| | | |
| | | import com.vividsolutions.jts.geom.Coordinate; |
| | | import com.vividsolutions.jts.geom.CoordinateList; |
| | | import com.vividsolutions.jts.geom.Geometry; |
| | | import com.vividsolutions.jts.geom.GeometryFactory; |
| | | import com.ximple.util.DgnUtility; |
| | | import org.apache.log4j.Logger; |
| | | |
| | | import java.awt.geom.AffineTransform; |
| | | import java.nio.ByteBuffer; |
| | | import java.nio.CharBuffer; |
| | |
| | | import java.nio.charset.Charset; |
| | | import java.nio.charset.CharsetDecoder; |
| | | |
| | | import org.apache.log4j.Logger; |
| | | |
| | | import com.vividsolutions.jts.geom.Coordinate; |
| | | import com.vividsolutions.jts.geom.Geometry; |
| | | import com.vividsolutions.jts.geom.GeometryFactory; |
| | | import com.vividsolutions.jts.geom.CoordinateList; |
| | | |
| | | import com.ximple.util.DgnUtility; |
| | | |
| | | /** |
| | | * TextElement |
| | | * |
| | | * @author Ulysses |
| | | * @version 0.1 |
| | | * @since 2006/5/18 ¤W¤È 11:45:29 |
| | | * @since 2006/5/18 |
| | | */ |
| | | public class TextElement extends Element implements GeometryConverter |
| | | { |
| | | public class TextElement extends Element implements GeometryConverter { |
| | | private static final Logger logger = Logger.getLogger(TextElement.class); |
| | | |
| | | public static final int ED_CENTERJUSTIFICATION = 0; |
| | |
| | | public static final int TXTJUST_RD = 24; /* Right Descender */ |
| | | public static final int TXTJUST_NONE = 127;/* no justfication */ |
| | | |
| | | public TextElement(byte[] raw) |
| | | { |
| | | TextElement(byte[] raw) { |
| | | super(raw); |
| | | } |
| | | |
| | | public Coordinate getOrigin() |
| | | { |
| | | public Coordinate getOrigin() { |
| | | int x = (raw[25] << 16 & 0xffff0000); |
| | | |
| | | x += raw[26] & 0x0000ffff; |
| | |
| | | return new Coordinate(dx, dy); |
| | | } |
| | | |
| | | public int getFontIndex() |
| | | { |
| | | public int getFontIndex() { |
| | | return (int) raw[18] & 0x00000000ff; |
| | | } |
| | | |
| | | public boolean hasSlant() |
| | | { |
| | | public boolean hasSlant() { |
| | | return true; |
| | | } |
| | | |
| | | public boolean hasUnderline() |
| | | { |
| | | public boolean hasUnderline() { |
| | | return true; |
| | | } |
| | | |
| | | public boolean isFixedWidthSpacing() |
| | | { |
| | | public boolean isFixedWidthSpacing() { |
| | | return true; |
| | | } |
| | | |
| | | public boolean isPlanar() |
| | | { |
| | | public boolean isPlanar() { |
| | | return true; |
| | | } |
| | | |
| | | public boolean isVertical() |
| | | { |
| | | public boolean isVertical() { |
| | | return true; |
| | | } |
| | | |
| | | public double getTextHeight() |
| | | { |
| | | public double getTextHeight() { |
| | | int height = ((raw[21] << 16) & 0xffff0000); |
| | | |
| | | height += raw[22] & 0x0000ffff; |
| | |
| | | return DgnUtility.converIntToDouble(height); |
| | | } |
| | | |
| | | public double getTextWidth() |
| | | { |
| | | public double getTextWidth() { |
| | | int length = (raw[19] << 16 & 0xffff0000); |
| | | |
| | | length += raw[20] & 0x0000ffff; |
| | |
| | | return DgnUtility.converIntToDouble(length); |
| | | } |
| | | |
| | | public int getJustification() |
| | | { |
| | | public int getJustification() { |
| | | return ((raw[18] >>> 8) & 0x00000000ff); |
| | | } |
| | | |
| | | public double getRotationAngle() |
| | | { |
| | | public double getRotationAngle() { |
| | | int totation = ((raw[23] & 0x0000ffff) << 16) | (raw[24] & 0x0000ffff); |
| | | return DgnUtility.converIntToRotation(totation); |
| | | } |
| | | |
| | | public boolean isChinese() |
| | | { |
| | | public boolean isChinese() { |
| | | if (raw.length < 31) return false; |
| | | int isChinese = raw[30] & 0x0000ffff; |
| | | |
| | | return (isChinese == 0xfdff); |
| | | } |
| | | |
| | | public int getTextLength() |
| | | { |
| | | public int getTextLength() { |
| | | int num = raw[29]; |
| | | |
| | | if (isChinese()) |
| | | { |
| | | if (isChinese()) { |
| | | num = (num / 2) - 1; |
| | | } |
| | | |
| | | return num; |
| | | } |
| | | |
| | | public String getText() |
| | | { |
| | | public String getText() { |
| | | StringBuilder val = new StringBuilder(); |
| | | char[] temp; |
| | | int num = getTextLength(); |
| | | if (num < 0) { |
| | | logger.warn("getTextLength() return Negative Value."); |
| | | return ""; |
| | | } |
| | | |
| | | if (!isChinese()) |
| | | { |
| | | if (30 + num / 2 > raw.length) { |
| | | logger.warn("getTextLength() too long."); |
| | | return ""; |
| | | } |
| | | |
| | | if (!isChinese()) { |
| | | temp = new char[num]; |
| | | |
| | | for (int i = 0; i < temp.length; i++) |
| | | { |
| | | if ((i % 2) == 0) |
| | | { |
| | | for (int i = 0; i < temp.length; i++) { |
| | | if ((i % 2) == 0) { |
| | | temp[i] = (char) (raw[30 + (int) (i / 2)] & (short) 0x00ff); |
| | | } else |
| | | { |
| | | } else { |
| | | temp[i] = (char) ((raw[30 + (int) (i / 2)] >> 8) & (short) 0x00ff); |
| | | } |
| | | |
| | | val.append(temp[i]); |
| | | } |
| | | } else |
| | | { |
| | | } else { |
| | | byte[] strRaw = new byte[num * 2]; |
| | | for (int i = 0; i < num; i++) |
| | | { |
| | | for (int i = 0; i < num; i++) { |
| | | short charValue = raw[i + 31]; |
| | | byte hi = (byte) (charValue >>> 8); |
| | | byte lo = (byte) charValue; |
| | |
| | | strRaw[i * 2 + 1] = lo; |
| | | } |
| | | |
| | | try |
| | | { |
| | | try { |
| | | Charset charsetBig5 = Charset.forName("Big5"); |
| | | CharsetDecoder decoder = charsetBig5.newDecoder(); |
| | | CharBuffer cb = decoder.decode(ByteBuffer.wrap(strRaw)); |
| | | val.append(cb); |
| | | } catch (CharacterCodingException e) |
| | | { |
| | | } catch (CharacterCodingException e) { |
| | | logger.warn(e.getMessage(), e); |
| | | return val.toString(); |
| | | } finally |
| | | { |
| | | } finally { |
| | | // rawBuffer.position(pos); |
| | | // rawBuffer.order(order); |
| | | } |
| | |
| | | return val.toString(); |
| | | } |
| | | |
| | | protected byte[] convertDBCSToUnicode(byte[] buffer) |
| | | { |
| | | protected byte[] convertDBCSToUnicode(byte[] buffer) { |
| | | byte[] charBuffer = new byte[4]; |
| | | charBuffer[0] = (byte) ((byte) ((buffer[1] & 0xc0) >>> 6) | 0xc0); |
| | | charBuffer[1] = (byte) (buffer[1] & 0x3f | 0x80); |
| | |
| | | return charBuffer; |
| | | } |
| | | |
| | | public Geometry toGeometry(GeometryFactory factory) |
| | | { |
| | | public Geometry toGeometry(GeometryFactory factory) { |
| | | return factory.createPoint(getUserOrigin()); |
| | | } |
| | | |
| | | public Geometry toAnchorGeometry(GeometryFactory factory) |
| | | { |
| | | if (getText() == null) |
| | | { |
| | | return factory.createMultiPoint(new Coordinate[] {}); |
| | | public Geometry toAnchorGeometry(GeometryFactory factory) { |
| | | if (getText() == null) { |
| | | return factory.createMultiPoint(new Coordinate[]{}); |
| | | } |
| | | |
| | | return factory.createMultiPoint(toAnchorCoordinates()); |
| | | } |
| | | |
| | | public Coordinate[] toAnchorCoordinates() |
| | | { |
| | | public Coordinate[] toAnchorCoordinates() { |
| | | CoordinateList result = new CoordinateList(); |
| | | int len = getText().trim().length(); |
| | | if (len == 0) return result.toCoordinateArray(); |
| | |
| | | at.setToRotation(angle, p.x, p.y); |
| | | at.scale(1, 1); |
| | | |
| | | for (int i = 0; i < len; i++) |
| | | { |
| | | for (int i = 0; i < len; i++) { |
| | | double[] srcPt = new double[2]; |
| | | double[] dstPt = new double[2]; |
| | | |
| | |
| | | return result.toCoordinateArray(); |
| | | } |
| | | |
| | | private double getUserWidth() |
| | | { |
| | | private double getUserWidth() { |
| | | int just = getJustification(); |
| | | // Envelope range = getRange(); // case -1 |
| | | // double width = (range.getWidth()); // case -1 |
| | | // double width = this.getTextWidth() * this.getTextLength() * 1000.0; // case -2 |
| | | double width = (this.getTextWidth() * this.getTextLength()); |
| | | |
| | | switch (just) |
| | | { |
| | | switch (just) { |
| | | case TXTJUST_LT: |
| | | case TXTJUST_LC: |
| | | case TXTJUST_LB: |
| | |
| | | return width; |
| | | } |
| | | |
| | | private double getUserHeight() |
| | | { |
| | | private double getUserHeight() { |
| | | int just = getJustification(); |
| | | double height = getTextHeight(); |
| | | |
| | | switch (just) |
| | | { |
| | | switch (just) { |
| | | case TXTJUST_LB: |
| | | case TXTJUST_CB: |
| | | case TXTJUST_RB: // bottom |
| | |
| | | return height; |
| | | } |
| | | |
| | | public Coordinate getUserOrigin() |
| | | { |
| | | public Coordinate getUserOrigin() { |
| | | double width = getUserWidth(); |
| | | double height = getUserHeight(); |
| | | double angle = Math.toRadians(getRotationAngle()); |
| | |
| | | return new Coordinate(dstPt[0], dstPt[1]); |
| | | } |
| | | |
| | | public Object clone() throws CloneNotSupportedException |
| | | { |
| | | public Object clone() throws CloneNotSupportedException { |
| | | int pos = this.rawBuffer.position(); |
| | | this.rawBuffer.position(0); |
| | | byte[] rawBytes = this.rawBuffer.array(); |
| | |
| | | return other; |
| | | } |
| | | |
| | | public static class ElementHandler extends Element.ElementHandler |
| | | { |
| | | public static class ElementHandler extends Element.ElementHandler { |
| | | private static ElementHandler instance = null; |
| | | |
| | | public ElementHandler() |
| | | { |
| | | public ElementHandler() { |
| | | super(ElementType.TEXT); |
| | | } |
| | | |
| | | public static IElementHandler getInstance() |
| | | { |
| | | if (instance == null) |
| | | { |
| | | public static IElementHandler getInstance() { |
| | | if (instance == null) { |
| | | instance = new ElementHandler(); |
| | | } |
| | | |
| | | return instance; |
| | | } |
| | | |
| | | protected Element createElement(byte[] raw) |
| | | { |
| | | protected Element createElement(byte[] raw) { |
| | | return new TextElement(raw); |
| | | } |
| | | } |