aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/render/txt/border
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-11-09 21:00:23 +0000
committerJeremias Maerki <jeremias@apache.org>2005-11-09 21:00:23 +0000
commit8a793a51f6ed47a62633b8ebbf63833d06da72d4 (patch)
treef521077ad088b3850c71c5add26dd95635caaf1f /src/java/org/apache/fop/render/txt/border
parent8edc1d2224e937c065b8d635f1760b62e783d8dd (diff)
downloadxmlgraphics-fop-8a793a51f6ed47a62633b8ebbf63833d06da72d4.tar.gz
xmlgraphics-fop-8a793a51f6ed47a62633b8ebbf63833d06da72d4.zip
Bugzilla #37253:
TXT Renderer resurrected with additional features. Submitted by: Sergey Simonchik <Sergey.Simonchik.at.borland.com> git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@332141 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/render/txt/border')
-rw-r--r--src/java/org/apache/fop/render/txt/border/AbstractBorderElement.java148
-rw-r--r--src/java/org/apache/fop/render/txt/border/BorderManager.java164
-rw-r--r--src/java/org/apache/fop/render/txt/border/DashedBorderElement.java141
-rw-r--r--src/java/org/apache/fop/render/txt/border/DottedBorderElement.java45
-rw-r--r--src/java/org/apache/fop/render/txt/border/SolidAndDoubleBorderElement.java276
5 files changed, 774 insertions, 0 deletions
diff --git a/src/java/org/apache/fop/render/txt/border/AbstractBorderElement.java b/src/java/org/apache/fop/render/txt/border/AbstractBorderElement.java
new file mode 100644
index 000000000..d02a8da1b
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/border/AbstractBorderElement.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.txt.border;
+
+import java.awt.Point;
+import java.util.Arrays;
+
+import org.apache.fop.area.CTM;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.render.txt.TXTState;
+
+/**
+ * This class keeps information about abstract border element, i.e. specifies
+ * border element for one text position.
+ */
+public abstract class AbstractBorderElement implements Constants {
+
+ /**
+ * Constant for a line segment, directing from a center of symbol up
+ * the the symbol boundary.
+ */
+ public static final int UP = 0;
+
+ /**
+ * Constant for a line segment, directing from a center of symbol right
+ * the the symbol boundary.
+ */
+ public static final int RIGHT = 1;
+
+ /**
+ * Constant for a line segment, directing from a center of symbol down
+ * the the symbol boundary.
+ */
+ public static final int DOWN = 2;
+
+ /**
+ * Constant for a line segment, directing from a center of symbol left
+ * the the symbol boundary.
+ */
+ public static final int LEFT = 3;
+
+ /**
+ * I-th element of this array specify, if there line from center of symbol
+ * to corresponding side (UP, RIGHT, DOWN, LEFT).
+ */
+ protected int[] data = {0, 0, 0, 0};
+
+ /**
+ * Initializes a newly created <code>AbstractBorderElement</code> object
+ * so that it represents an empty border element.
+ */
+ public AbstractBorderElement() {
+ }
+
+ /**
+ * Constructs a newly allocated <code>AbstractBorderElement</code> object.
+ * Fills array <code>data</code> using binary representation of
+ * <code>type</code>.
+ *
+ * @param type binary representation of type gives <code>data</code>
+ */
+ public AbstractBorderElement(int type) {
+ for (int i = 0; i < 4; i++) {
+ data[i] = (type >> i) & 1;
+ }
+ }
+
+ /**
+ * Returns value of side's element of <code>data</code>.
+ *
+ * @param side integer, representing side
+ * @return value of side's element
+ */
+ public int getData(int side) {
+ return data[side];
+ }
+
+ /**
+ * Sets a value for <code>data[side]</code>.
+ *
+ * @param side integer, representing side
+ * @param value a new value for <code>data[side]</code>
+ */
+ public void setData(int side, int value) {
+ data[side] = value;
+ }
+
+ /**
+ * Transform border element in according with <code>state</code>.
+ * @param state instance of TXTState
+ */
+ public void transformElement(TXTState state) {
+ // here we'll get CTM^-1 without shift
+ double[] da = state.getResultCTM().toArray();
+ CTM ctm = new CTM(da[0], -da[1], -da[2], da[3], 0, 0);
+
+ Point[] pa = new Point[4];
+ pa[0] = new Point(0, data[UP]);
+ pa[1] = new Point(data[RIGHT], 0);
+ pa[2] = new Point(0, -data[DOWN]);
+ pa[3] = new Point(-data[LEFT], 0);
+
+ Arrays.fill(data, 0);
+ for (int i = 0; i < 4; i++) {
+ Point p = state.transformPoint(pa[i], ctm);
+
+ int length = (int) p.distance(0, 0);
+ if (p.x == 0 && p.y > 0) {
+ data[UP] = length;
+ } else if (p.x == 0 && p.y < 0) {
+ data[DOWN] = length;
+ } else if (p.x > 0 && p.y == 0) {
+ data[RIGHT] = length;
+ } else if (p.x < 0 && p.y == 0) {
+ data[LEFT] = length;
+ }
+ }
+ }
+
+ /**
+ * Merges with border element.
+ * @param e instance of AbstractBorderElement
+ * @return instance of AbstractBorderElement
+ */
+ public abstract AbstractBorderElement merge(AbstractBorderElement e);
+
+ /**
+ * Convert internal representation of border element to char.
+ * @return corresponding char
+ */
+ public abstract char convert2Char();
+}
diff --git a/src/java/org/apache/fop/render/txt/border/BorderManager.java b/src/java/org/apache/fop/render/txt/border/BorderManager.java
new file mode 100644
index 000000000..2e20d0cd3
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/border/BorderManager.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.txt.border;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.render.txt.TXTState;
+
+/**
+ * This keeps all information about borders for current processed page.
+ */
+public class BorderManager {
+
+ /** Matrix for storing information about one border element. */
+ private AbstractBorderElement[][] borderInfo;
+
+ /** Width of current processed border. */
+ private int width;
+
+ /** Height of current processed border. */
+ private int height;
+
+ /** x-coordinate of upper left point of current processed border. */
+ private int startX;
+
+ /** y-coordinate of upper left point of current processed border. */
+ private int startY;
+
+ /** Stores TXTState for transforming border elements. */
+ private TXTState state;
+
+ /**
+ * Constructs BorderManger, using <code>pageWidth</code> and
+ * <code>pageHeight</code> for creating <code>borderInfo</code>.
+ *
+ * @param pageWidth page width
+ * @param pageHeight page height
+ * @param state TXTState
+ */
+ public BorderManager(int pageWidth, int pageHeight, TXTState state) {
+ this.state = state;
+ borderInfo = new AbstractBorderElement[pageHeight][pageWidth];
+ }
+
+ /**
+ * Adds border element to <code>borderInfo</code>.
+ *
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @param style border-style
+ * @param type border element type, binary representation of wich gives
+ * information about availability or absence of corresponding side.
+ */
+ public void addBorderElement(int x, int y, int style, int type) {
+ AbstractBorderElement be = null;
+
+ if (style == Constants.EN_SOLID || style == Constants.EN_DOUBLE) {
+ be = new SolidAndDoubleBorderElement(style, type);
+ } else if (style == Constants.EN_DOTTED) {
+ be = new DottedBorderElement();
+ } else if (style == Constants.EN_DASHED) {
+ be = new DashedBorderElement(type);
+ } else {
+ return;
+ }
+ be.transformElement(state);
+
+ if (borderInfo[y][x] != null) {
+ borderInfo[y][x] = borderInfo[y][x].merge(be);
+ } else {
+ borderInfo[y][x] = be;
+ }
+ }
+
+ /**
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @return if border element at point (x,y) is available, returns instance
+ * of Character, created on char, given by corresponding border element,
+ * otherwise returns null.
+ */
+ public Character getCharacter(int x, int y) {
+ Character c = null;
+ if (borderInfo[y][x] != null) {
+ c = new Character(borderInfo[y][x].convert2Char());
+ }
+ return c;
+ }
+
+ /**
+ * @return width of current processed border.
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * Sets width of current processed border.
+ * @param width width of border
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * @return height of current processed border.
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * Sets height of current processed border.
+ * @param height height of border
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ /**
+ * @return x-coordinate of upper left point of current processed border.
+ */
+ public int getStartX() {
+ return startX;
+ }
+
+ /**
+ * Sets x-coordinate of upper left point of current processed border.
+ * @param startX x-coordinate of upper left border's point.
+ */
+ public void setStartX(int startX) {
+ this.startX = startX;
+ }
+
+ /**
+ * @return y-coordinate of upper left point of current processed border.
+ */
+ public int getStartY() {
+ return startY;
+ }
+
+ /**
+ * Sets y-coordinate of upper left point of current processed border.
+ * @param startY y-coordinate of upper left border's point.
+ */
+ public void setStartY(int startY) {
+ this.startY = startY;
+ }
+}
diff --git a/src/java/org/apache/fop/render/txt/border/DashedBorderElement.java b/src/java/org/apache/fop/render/txt/border/DashedBorderElement.java
new file mode 100644
index 000000000..7e7aa7acd
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/border/DashedBorderElement.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.txt.border;
+
+import java.util.Arrays;
+
+/**
+ * This class is responsible for managing of dashed border elements.
+ */
+public class DashedBorderElement extends AbstractBorderElement {
+
+ private static final char DASH_HORIZONTAL = '-';
+
+ private static final char DASH_VERTICAL = '|';
+
+ private static final char UNDEFINED = '?';
+
+ private static final int UP2 = 1;
+
+ private static final int RIGHT2 = 2;
+
+ private static final int DOWN2 = 4;
+
+ private static final int LEFT2 = 8;
+
+ private static char[] map = new char[20];
+
+ static {
+ Arrays.fill(map, UNDEFINED);
+ map[0] = ' ';
+ map[UP2] = DASH_VERTICAL;
+ map[DOWN2] = DASH_VERTICAL;
+ map[UP2 + DOWN2] = DASH_VERTICAL;
+
+ map[LEFT2] = DASH_HORIZONTAL;
+ map[RIGHT2] = DASH_HORIZONTAL;
+ map[LEFT2 + RIGHT2] = DASH_HORIZONTAL;
+ }
+
+ /**
+ * Constructs a newly allocated <code>DashedBorderElement</code> object.
+ * Fills <code>data</code> using superclass constructor.
+ *
+ * @param type binary representation of type gives <code>data</code>
+ */
+ public DashedBorderElement(int type) {
+ super(type);
+ }
+
+ /**
+ * Merges dashed border element with instance of solid and double border
+ * element, returns instance of <code>SolidAndDoubleBorderElement</code>.
+ *
+ * @param sdb instance of <code>SolidAndDoubleBorderElement</code> to merge
+ * @return merged border element
+ */
+ private AbstractBorderElement mergeSolid(SolidAndDoubleBorderElement sdb) {
+ AbstractBorderElement e = new SolidAndDoubleBorderElement(EN_SOLID, 0);
+ for (int i = 0; i < 4; i++) {
+ e.setData(i, Math.max(data[i], sdb.getData(i)));
+ }
+ return e;
+ }
+
+ /**
+ * Merges dashed border element with dashed border element and returns
+ * instance of <code>DashedBorderElement</code>.
+ *
+ * @param dbe instance of <code>DashedBorderElement</code> to merge
+ * @return merged border element
+ */
+ private AbstractBorderElement mergeDashed(DashedBorderElement dbe) {
+ for (int i = 0; i < 4; i++) {
+ data[i] = Math.max(data[i], dbe.getData(i));
+ }
+ return this;
+ }
+
+ /**
+ * Converts dashed border element to
+ * <code>SolidAndDoubleBorderElement</code>.
+ *
+ * @return converted instance of <code>SolidAndDoubleBorderElement</code>
+ */
+ private AbstractBorderElement toSolidAndDouble() {
+ AbstractBorderElement e = new SolidAndDoubleBorderElement(EN_SOLID, 0);
+ for (int i = 0; i < 4; i++) {
+ e.setData(i, data[i]);
+ }
+ return e;
+ }
+
+ /**
+ * Merges with border element.
+ * @param e instance of AbstractBorderElement
+ * @return instance of AbstractBorderElement
+ */
+ public AbstractBorderElement merge(AbstractBorderElement e) {
+ AbstractBorderElement abe = this;
+ if (e instanceof SolidAndDoubleBorderElement) {
+ abe = mergeSolid((SolidAndDoubleBorderElement) e);
+ } else if (e instanceof DashedBorderElement) {
+ abe = mergeDashed((DashedBorderElement) e);
+ } else {
+ abe = e;
+ }
+ return abe;
+ }
+
+ /**
+ * @see org.apache.fop.render.txt.border.AbstractBorderElement#convert2Char()
+ */
+ public char convert2Char() {
+ int key = 0;
+ key += data[UP] * UP2;
+ key += data[DOWN] * DOWN2;
+ key += data[LEFT] * LEFT2;
+ key += data[RIGHT] * RIGHT2;
+ char ch = map[key];
+ if (ch == UNDEFINED) {
+ ch = toSolidAndDouble().convert2Char();
+ }
+ return ch;
+ }
+}
diff --git a/src/java/org/apache/fop/render/txt/border/DottedBorderElement.java b/src/java/org/apache/fop/render/txt/border/DottedBorderElement.java
new file mode 100644
index 000000000..8e693974b
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/border/DottedBorderElement.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.txt.border;
+
+/**
+ * This class is responsible for managing of dotted border elements.
+ */
+public class DottedBorderElement extends AbstractBorderElement {
+
+ private static final char MIDDLE_DOT = '\u00B7';
+
+ /**
+ * Merges dotted border element with another border element. Here merging
+ * is quite simple: returning <code>this</code> without any comparing.
+ *
+ * @param e instance of AbstractBorderElement
+ * @return instance of DottedBorderElement
+ */
+ public AbstractBorderElement merge(AbstractBorderElement e) {
+ return this;
+ }
+
+ /**
+ * @see org.apache.fop.render.txt.border.AbstractBorderElement#convert2Char()
+ */
+ public char convert2Char() {
+ return MIDDLE_DOT;
+ }
+}
diff --git a/src/java/org/apache/fop/render/txt/border/SolidAndDoubleBorderElement.java b/src/java/org/apache/fop/render/txt/border/SolidAndDoubleBorderElement.java
new file mode 100644
index 000000000..72ca9d2dc
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/border/SolidAndDoubleBorderElement.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.txt.border;
+
+import java.util.Arrays;
+
+/**
+ * This class is responsible for solid and double border elements managing.
+ */
+public class SolidAndDoubleBorderElement extends AbstractBorderElement {
+
+ private static final char LIGHT_HORIZONTAL = '\u2500';
+
+ private static final char LIGHT_VERTICAL = '\u2502';
+
+ private static final char LIGHT_DOWN_AND_RIGHT = '\u250C';
+
+ private static final char LIGHT_DOWN_AND_LEFT = '\u2510';
+
+ private static final char LIGHT_UP_AND_RIGHT = '\u2514';
+
+ private static final char LIGHT_UP_AND_LEFT = '\u2518';
+
+ private static final char LIGHT_VERTICAL_AND_RIGHT = '\u251C';
+
+ private static final char LIGHT_VERTICAL_AND_LEFT = '\u2524';
+
+ private static final char LIGHT_DOWN_AND_HORIZONTAL = '\u252C';
+
+ private static final char LIGHT_UP_AND_HORIZONTAL = '\u2534';
+
+ private static final char LIGHT_VERTICAL_AND_HORIZONTAL = '\u253C';
+
+ private static final char DOUBLE_HORIZONTAL = '\u2550';
+
+ private static final char DOUBLE_VERTICAL = '\u2551';
+
+ private static final char DOUBLE_DOWN_AND_RIGHT = '\u2554';
+
+ private static final char DOUBLE_DOWN_AND_LEFT = '\u2557';
+
+ private static final char DOUBLE_UP_AND_RIGHT = '\u255A';
+
+ private static final char DOUBLE_UP_AND_LEFT = '\u255D';
+
+ private static final char DOUBLE_VERTICAL_AND_RIGHT = '\u2560';
+
+ private static final char DOUBLE_VERTICAL_AND_LEFT = '\u2563';
+
+ private static final char DOUBLE_DOWN_AND_HORIZONTAL = '\u2566';
+
+ private static final char DOUBLE_UP_AND_HORIZONTAL = '\u2569';
+
+ private static final char DOUBLE_VERTICAL_AND_HORIZONTAL = '\u256C';
+
+ private static final char DOWN_SINGLE_AND_RIGHT_DOUBLE = '\u2552';
+
+ private static final char DOWN_DOUBLE_AND_RIGHT_SINGLE = '\u2553';
+
+ private static final char DOWN_SINGLE_AND_LEFT_DOUBLE = '\u2555';
+
+ private static final char DOWN_DOUBLE_AND_LEFT_SINGLE = '\u2556';
+
+ private static final char UP_SINGLE_AND_RIGHT_DOUBLE = '\u2558';
+
+ private static final char UP_DOUBLE_AND_RIGHT_SINGLE = '\u2559';
+
+ private static final char UP_SINGLE_AND_LEFT_DOUBLE = '\u255B';
+
+ private static final char UP_DOUBLE_AND_LEFT_SINGLE = '\u255C';
+
+ private static final char VERTICAL_SINGLE_AND_RIGHT_DOUBLE = '\u255E';
+
+ private static final char VERTICAL_DOUBLE_AND_RIGHT_SINGLE = '\u255F';
+
+ private static final char VERTICAL_SINGLE_AND_LEFT_DOUBLE = '\u2561';
+
+ private static final char VERTICAL_DOUBLE_AND_LEFT_SINGLE = '\u2562';
+
+ private static final char DOWN_SINGLE_AND_HORIZONTAL_DOUBLE = '\u2564';
+
+ private static final char DOWN_DOUBLE_AND_HORIZONTAL_SINGLE = '\u2565';
+
+ private static final char UP_SINGLE_AND_HORIZONTAL_DOUBLE = '\u2567';
+
+ private static final char UP_DOUBLE_AND_HORIZONTAL_SINGLE = '\u2568';
+
+ private static final char VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE = '\u256A';
+
+ private static final char VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE = '\u256B';
+
+ private static final char UNDEFINED = '?';
+
+ private static final int UP3 = 1;
+
+ private static final int DOWN3 = 3;
+
+ private static final int LEFT3 = 9;
+
+ private static final int RIGHT3 = 27;
+
+ private static final char[] MAP = new char[100];
+
+ static {
+ Arrays.fill(MAP, UNDEFINED);
+ MAP[0] = ' ';
+ MAP[UP3] = LIGHT_VERTICAL;
+ MAP[DOWN3] = LIGHT_VERTICAL;
+ MAP[RIGHT3] = LIGHT_HORIZONTAL;
+ MAP[LEFT3] = LIGHT_HORIZONTAL;
+ MAP[UP3 + DOWN3] = LIGHT_VERTICAL;
+ MAP[LEFT3 + RIGHT3] = LIGHT_HORIZONTAL;
+ MAP[UP3 + LEFT3] = LIGHT_UP_AND_LEFT;
+ MAP[LEFT3 + DOWN3] = LIGHT_DOWN_AND_LEFT;
+ MAP[DOWN3 + RIGHT3] = LIGHT_DOWN_AND_RIGHT;
+ MAP[UP3 + RIGHT3] = LIGHT_UP_AND_RIGHT;
+ MAP[UP3 + DOWN3 + RIGHT3] = LIGHT_VERTICAL_AND_RIGHT;
+ MAP[UP3 + LEFT3 + DOWN3] = LIGHT_VERTICAL_AND_LEFT;
+ MAP[LEFT3 + DOWN3 + RIGHT3] = LIGHT_DOWN_AND_HORIZONTAL;
+ MAP[UP3 + LEFT3 + RIGHT3] = LIGHT_UP_AND_HORIZONTAL;
+ MAP[UP3 + LEFT3 + DOWN3 + RIGHT3] = LIGHT_VERTICAL_AND_HORIZONTAL;
+ //DOUBLE
+ MAP[2 * UP3] = DOUBLE_VERTICAL;
+ MAP[2 * DOWN3] = DOUBLE_VERTICAL;
+ MAP[2 * RIGHT3] = DOUBLE_HORIZONTAL;
+ MAP[2 * LEFT3] = DOUBLE_HORIZONTAL;
+ MAP[2 * UP3 + 2 * DOWN3] = DOUBLE_VERTICAL;
+ MAP[2 * LEFT3 + 2 * RIGHT3] = DOUBLE_HORIZONTAL;
+ MAP[2 * UP3 + 2 * LEFT3] = DOUBLE_UP_AND_LEFT;
+ MAP[2 * LEFT3 + 2 * DOWN3] = DOUBLE_DOWN_AND_LEFT;
+ MAP[2 * DOWN3 + 2 * RIGHT3] = DOUBLE_DOWN_AND_RIGHT;
+ MAP[2 * UP3 + 2 * RIGHT3] = DOUBLE_UP_AND_RIGHT;
+ MAP[2 * UP3 + 2 * DOWN3 + 2 * RIGHT3] = DOUBLE_VERTICAL_AND_RIGHT;
+ MAP[2 * UP3 + 2 * DOWN3 + 2 * LEFT3] = DOUBLE_VERTICAL_AND_LEFT;
+ MAP[2 * DOWN3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_DOWN_AND_HORIZONTAL;
+ MAP[2 * UP3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_UP_AND_HORIZONTAL;
+ MAP[2 * UP3 + 2 * DOWN3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_VERTICAL_AND_HORIZONTAL;
+ //DOUBLE&SINGLE
+ MAP[DOWN3 + 2 * RIGHT3] = DOWN_SINGLE_AND_RIGHT_DOUBLE;
+ MAP[2 * DOWN3 + RIGHT3] = DOWN_DOUBLE_AND_RIGHT_SINGLE;
+ MAP[DOWN3 + 2 * LEFT3] = DOWN_SINGLE_AND_LEFT_DOUBLE;
+ MAP[2 * DOWN3 + LEFT3] = DOWN_DOUBLE_AND_LEFT_SINGLE;
+ MAP[UP3 + 2 * RIGHT3] = UP_SINGLE_AND_RIGHT_DOUBLE;
+ MAP[2 * UP3 + RIGHT3] = UP_DOUBLE_AND_RIGHT_SINGLE;
+ MAP[UP3 + 2 * LEFT3] = UP_SINGLE_AND_LEFT_DOUBLE;
+ MAP[2 * UP3 + LEFT3] = UP_DOUBLE_AND_LEFT_SINGLE;
+ MAP[UP3 + DOWN3 + 2 * RIGHT3] = VERTICAL_SINGLE_AND_RIGHT_DOUBLE;
+ MAP[2 * UP3 + 2 * DOWN3 + RIGHT3] = VERTICAL_DOUBLE_AND_RIGHT_SINGLE;
+ MAP[UP3 + DOWN3 + 2 * LEFT3] = VERTICAL_SINGLE_AND_LEFT_DOUBLE;
+ MAP[2 * UP3 + 2 * DOWN3 + LEFT3] = VERTICAL_DOUBLE_AND_LEFT_SINGLE;
+ MAP[DOWN3 + 2 * LEFT3 + 2 * RIGHT3] = DOWN_SINGLE_AND_HORIZONTAL_DOUBLE;
+ MAP[2 * DOWN3 + LEFT3 + RIGHT3] = DOWN_DOUBLE_AND_HORIZONTAL_SINGLE;
+ MAP[UP3 + 2 * LEFT3 + 2 * RIGHT3] = UP_SINGLE_AND_HORIZONTAL_DOUBLE;
+ MAP[2 * UP3 + LEFT3 + RIGHT3] = UP_DOUBLE_AND_HORIZONTAL_SINGLE;
+ MAP[UP3 + DOWN3 + 2 * LEFT3 + 2 * RIGHT3] = VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE;
+ MAP[2 * UP3 + 2 * DOWN3 + LEFT3 + RIGHT3] = VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE;
+ }
+
+ /**
+ * Initializes a newly created <code>SolidAndDoubleBorderElement</code>
+ * object so that it represents an empty border element.
+ */
+ public SolidAndDoubleBorderElement() {
+ }
+
+ /**
+ * Constructs a newly allocated <code>SolidAndDoubleBorderElement</code>
+ * object. Fills <code>data</code> using binary representation of
+ * <code>type</code>. If border style is EN_DOUBLE, multiplies
+ * <code>data[side]</code> by 2 for every side to distinguish EN_SOLID and
+ * EN_DOUBLE.
+ *
+ * @param style integer, representing border style.
+ * @param type binary representation of type gives <code>data</code>
+ */
+ public SolidAndDoubleBorderElement(int style, int type) {
+ super(type);
+ if (style == EN_DOUBLE) {
+ for (int i = 0; i < 4; i++) {
+ data[i] *= 2;
+ }
+ }
+ }
+
+ /**
+ * Merges with <code>sde</code>.
+ * @param sde instance of SolidAndDoubleBorderElement
+ * @return instance of AbstractBorderElement
+ */
+ public AbstractBorderElement mergeSolid(SolidAndDoubleBorderElement sde) {
+ AbstractBorderElement e = new SolidAndDoubleBorderElement(EN_SOLID, 0);
+ for (int i = 0; i < 4; i++) {
+ if (sde.getData(i) != 0) {
+ e.setData(i, sde.getData(i));
+ } else {
+ e.setData(i, data[i]);
+ }
+ }
+ return e;
+ }
+
+ /**
+ * Merges with e.
+ * @param e instance of AbstractBorderElement
+ * @return instance of AbstractBorderElement
+ */
+ public AbstractBorderElement merge(AbstractBorderElement e) {
+ AbstractBorderElement abe = this;
+ if (e instanceof SolidAndDoubleBorderElement) {
+ abe = mergeSolid((SolidAndDoubleBorderElement) e);
+ } else if (e instanceof DottedBorderElement) {
+ abe = e;
+ } else if (e instanceof DashedBorderElement) {
+ abe = e.merge(this);
+ }
+ return abe;
+ }
+
+ /**
+ * Maps to char.
+ * @return resulting mapping char
+ */
+ private char map2Char() {
+ int key = 0;
+ key += data[UP] * UP3;
+ key += data[LEFT] * LEFT3;
+ key += data[DOWN] * DOWN3;
+ key += data[RIGHT] * RIGHT3;
+ return MAP[key];
+ }
+
+ /**
+ * Modifies data to nearest normal internal representation.
+ */
+ private void modifyData() {
+ int c1 = 0;
+ int c2 = 0;
+ for (int i = 0; i < 4; i++) {
+ c1 += (data[i] == 1) ? 1 : 0;
+ c2 += (data[i] == 2) ? 1 : 0;
+ }
+ int m = c1 > c2 ? 1 : 0;
+ int[] p = {0, m, 2 * (1 - m)};
+ for (int i = 0; i < 4; i++) {
+ data[i] = p[data[i]];
+ }
+ }
+
+ /**
+ * @see org.apache.fop.render.txt.border.AbstractBorderElement#convert2Char()
+ */
+ public char convert2Char() {
+ char ch = map2Char();
+ if (ch == UNDEFINED) {
+ modifyData();
+ ch = map2Char();
+ }
+ return ch;
+ }
+}