diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-11-09 21:00:23 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-11-09 21:00:23 +0000 |
commit | 8a793a51f6ed47a62633b8ebbf63833d06da72d4 (patch) | |
tree | f521077ad088b3850c71c5add26dd95635caaf1f /src/java/org/apache/fop/render/txt/border | |
parent | 8edc1d2224e937c065b8d635f1760b62e783d8dd (diff) | |
download | xmlgraphics-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')
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; + } +} |