1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* $Id: SolidAndDoubleBorderElement.java 679326 2008-07-24 09:35:34Z vhennebert $ */ 19 20 package org.apache.fop.render.txt.border; 21 22 import java.util.Arrays; 23 24 /** 25 * This class is responsible for solid and double border elements managing. 26 */ 27 public class SolidAndDoubleBorderElement extends AbstractBorderElement { 28 29 private static final char LIGHT_HORIZONTAL = '\u2500'; 30 31 private static final char LIGHT_VERTICAL = '\u2502'; 32 33 private static final char LIGHT_DOWN_AND_RIGHT = '\u250C'; 34 35 private static final char LIGHT_DOWN_AND_LEFT = '\u2510'; 36 37 private static final char LIGHT_UP_AND_RIGHT = '\u2514'; 38 39 private static final char LIGHT_UP_AND_LEFT = '\u2518'; 40 41 private static final char LIGHT_VERTICAL_AND_RIGHT = '\u251C'; 42 43 private static final char LIGHT_VERTICAL_AND_LEFT = '\u2524'; 44 45 private static final char LIGHT_DOWN_AND_HORIZONTAL = '\u252C'; 46 47 private static final char LIGHT_UP_AND_HORIZONTAL = '\u2534'; 48 49 private static final char LIGHT_VERTICAL_AND_HORIZONTAL = '\u253C'; 50 51 private static final char DOUBLE_HORIZONTAL = '\u2550'; 52 53 private static final char DOUBLE_VERTICAL = '\u2551'; 54 55 private static final char DOUBLE_DOWN_AND_RIGHT = '\u2554'; 56 57 private static final char DOUBLE_DOWN_AND_LEFT = '\u2557'; 58 59 private static final char DOUBLE_UP_AND_RIGHT = '\u255A'; 60 61 private static final char DOUBLE_UP_AND_LEFT = '\u255D'; 62 63 private static final char DOUBLE_VERTICAL_AND_RIGHT = '\u2560'; 64 65 private static final char DOUBLE_VERTICAL_AND_LEFT = '\u2563'; 66 67 private static final char DOUBLE_DOWN_AND_HORIZONTAL = '\u2566'; 68 69 private static final char DOUBLE_UP_AND_HORIZONTAL = '\u2569'; 70 71 private static final char DOUBLE_VERTICAL_AND_HORIZONTAL = '\u256C'; 72 73 private static final char DOWN_SINGLE_AND_RIGHT_DOUBLE = '\u2552'; 74 75 private static final char DOWN_DOUBLE_AND_RIGHT_SINGLE = '\u2553'; 76 77 private static final char DOWN_SINGLE_AND_LEFT_DOUBLE = '\u2555'; 78 79 private static final char DOWN_DOUBLE_AND_LEFT_SINGLE = '\u2556'; 80 81 private static final char UP_SINGLE_AND_RIGHT_DOUBLE = '\u2558'; 82 83 private static final char UP_DOUBLE_AND_RIGHT_SINGLE = '\u2559'; 84 85 private static final char UP_SINGLE_AND_LEFT_DOUBLE = '\u255B'; 86 87 private static final char UP_DOUBLE_AND_LEFT_SINGLE = '\u255C'; 88 89 private static final char VERTICAL_SINGLE_AND_RIGHT_DOUBLE = '\u255E'; 90 91 private static final char VERTICAL_DOUBLE_AND_RIGHT_SINGLE = '\u255F'; 92 93 private static final char VERTICAL_SINGLE_AND_LEFT_DOUBLE = '\u2561'; 94 95 private static final char VERTICAL_DOUBLE_AND_LEFT_SINGLE = '\u2562'; 96 97 private static final char DOWN_SINGLE_AND_HORIZONTAL_DOUBLE = '\u2564'; 98 99 private static final char DOWN_DOUBLE_AND_HORIZONTAL_SINGLE = '\u2565'; 100 101 private static final char UP_SINGLE_AND_HORIZONTAL_DOUBLE = '\u2567'; 102 103 private static final char UP_DOUBLE_AND_HORIZONTAL_SINGLE = '\u2568'; 104 105 private static final char VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE = '\u256A'; 106 107 private static final char VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE = '\u256B'; 108 109 private static final char UNDEFINED = '?'; 110 111 private static final int UP3 = 1; 112 113 private static final int DOWN3 = 3; 114 115 private static final int LEFT3 = 9; 116 117 private static final int RIGHT3 = 27; 118 119 private static final char[] MAP = new char[100]; 120 121 static { Arrays.fill(MAP, UNDEFINED)122 Arrays.fill(MAP, UNDEFINED); 123 MAP[0] = ' '; 124 MAP[UP3] = LIGHT_VERTICAL; 125 MAP[DOWN3] = LIGHT_VERTICAL; 126 MAP[RIGHT3] = LIGHT_HORIZONTAL; 127 MAP[LEFT3] = LIGHT_HORIZONTAL; 128 MAP[UP3 + DOWN3] = LIGHT_VERTICAL; 129 MAP[LEFT3 + RIGHT3] = LIGHT_HORIZONTAL; 130 MAP[UP3 + LEFT3] = LIGHT_UP_AND_LEFT; 131 MAP[LEFT3 + DOWN3] = LIGHT_DOWN_AND_LEFT; 132 MAP[DOWN3 + RIGHT3] = LIGHT_DOWN_AND_RIGHT; 133 MAP[UP3 + RIGHT3] = LIGHT_UP_AND_RIGHT; 134 MAP[UP3 + DOWN3 + RIGHT3] = LIGHT_VERTICAL_AND_RIGHT; 135 MAP[UP3 + LEFT3 + DOWN3] = LIGHT_VERTICAL_AND_LEFT; 136 MAP[LEFT3 + DOWN3 + RIGHT3] = LIGHT_DOWN_AND_HORIZONTAL; 137 MAP[UP3 + LEFT3 + RIGHT3] = LIGHT_UP_AND_HORIZONTAL; 138 MAP[UP3 + LEFT3 + DOWN3 + RIGHT3] = LIGHT_VERTICAL_AND_HORIZONTAL; 139 //DOUBLE 140 MAP[2 * UP3] = DOUBLE_VERTICAL; 141 MAP[2 * DOWN3] = DOUBLE_VERTICAL; 142 MAP[2 * RIGHT3] = DOUBLE_HORIZONTAL; 143 MAP[2 * LEFT3] = DOUBLE_HORIZONTAL; 144 MAP[2 * UP3 + 2 * DOWN3] = DOUBLE_VERTICAL; 145 MAP[2 * LEFT3 + 2 * RIGHT3] = DOUBLE_HORIZONTAL; 146 MAP[2 * UP3 + 2 * LEFT3] = DOUBLE_UP_AND_LEFT; 147 MAP[2 * LEFT3 + 2 * DOWN3] = DOUBLE_DOWN_AND_LEFT; 148 MAP[2 * DOWN3 + 2 * RIGHT3] = DOUBLE_DOWN_AND_RIGHT; 149 MAP[2 * UP3 + 2 * RIGHT3] = DOUBLE_UP_AND_RIGHT; 150 MAP[2 * UP3 + 2 * DOWN3 + 2 * RIGHT3] = DOUBLE_VERTICAL_AND_RIGHT; 151 MAP[2 * UP3 + 2 * DOWN3 + 2 * LEFT3] = DOUBLE_VERTICAL_AND_LEFT; 152 MAP[2 * DOWN3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_DOWN_AND_HORIZONTAL; 153 MAP[2 * UP3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_UP_AND_HORIZONTAL; 154 MAP[2 * UP3 + 2 * DOWN3 + 2 * RIGHT3 + 2 * LEFT3] = DOUBLE_VERTICAL_AND_HORIZONTAL; 155 //DOUBLE&SINGLE 156 MAP[DOWN3 + 2 * RIGHT3] = DOWN_SINGLE_AND_RIGHT_DOUBLE; 157 MAP[2 * DOWN3 + RIGHT3] = DOWN_DOUBLE_AND_RIGHT_SINGLE; 158 MAP[DOWN3 + 2 * LEFT3] = DOWN_SINGLE_AND_LEFT_DOUBLE; 159 MAP[2 * DOWN3 + LEFT3] = DOWN_DOUBLE_AND_LEFT_SINGLE; 160 MAP[UP3 + 2 * RIGHT3] = UP_SINGLE_AND_RIGHT_DOUBLE; 161 MAP[2 * UP3 + RIGHT3] = UP_DOUBLE_AND_RIGHT_SINGLE; 162 MAP[UP3 + 2 * LEFT3] = UP_SINGLE_AND_LEFT_DOUBLE; 163 MAP[2 * UP3 + LEFT3] = UP_DOUBLE_AND_LEFT_SINGLE; 164 MAP[UP3 + DOWN3 + 2 * RIGHT3] = VERTICAL_SINGLE_AND_RIGHT_DOUBLE; 165 MAP[2 * UP3 + 2 * DOWN3 + RIGHT3] = VERTICAL_DOUBLE_AND_RIGHT_SINGLE; 166 MAP[UP3 + DOWN3 + 2 * LEFT3] = VERTICAL_SINGLE_AND_LEFT_DOUBLE; 167 MAP[2 * UP3 + 2 * DOWN3 + LEFT3] = VERTICAL_DOUBLE_AND_LEFT_SINGLE; 168 MAP[DOWN3 + 2 * LEFT3 + 2 * RIGHT3] = DOWN_SINGLE_AND_HORIZONTAL_DOUBLE; 169 MAP[2 * DOWN3 + LEFT3 + RIGHT3] = DOWN_DOUBLE_AND_HORIZONTAL_SINGLE; 170 MAP[UP3 + 2 * LEFT3 + 2 * RIGHT3] = UP_SINGLE_AND_HORIZONTAL_DOUBLE; 171 MAP[2 * UP3 + LEFT3 + RIGHT3] = UP_DOUBLE_AND_HORIZONTAL_SINGLE; 172 MAP[UP3 + DOWN3 + 2 * LEFT3 + 2 * RIGHT3] = VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE; 173 MAP[2 * UP3 + 2 * DOWN3 + LEFT3 + RIGHT3] = VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE; 174 } 175 176 /** 177 * Initializes a newly created <code>SolidAndDoubleBorderElement</code> 178 * object so that it represents an empty border element. 179 */ SolidAndDoubleBorderElement()180 public SolidAndDoubleBorderElement() { 181 } 182 183 /** 184 * Constructs a newly allocated <code>SolidAndDoubleBorderElement</code> 185 * object. Fills <code>data</code> using binary representation of 186 * <code>type</code>. If border style is EN_DOUBLE, multiplies 187 * <code>data[side]</code> by 2 for every side to distinguish EN_SOLID and 188 * EN_DOUBLE. 189 * 190 * @param style integer, representing border style. 191 * @param type binary representation of type gives <code>data</code> 192 */ SolidAndDoubleBorderElement(int style, int type)193 public SolidAndDoubleBorderElement(int style, int type) { 194 super(type); 195 if (style == EN_DOUBLE) { 196 for (int i = 0; i < 4; i++) { 197 data[i] *= 2; 198 } 199 } 200 } 201 202 /** 203 * Merges with <code>sde</code>. 204 * @param sde instance of SolidAndDoubleBorderElement 205 * @return instance of AbstractBorderElement 206 */ mergeSolid(SolidAndDoubleBorderElement sde)207 public AbstractBorderElement mergeSolid(SolidAndDoubleBorderElement sde) { 208 AbstractBorderElement e = new SolidAndDoubleBorderElement(EN_SOLID, 0); 209 for (int i = 0; i < 4; i++) { 210 if (sde.getData(i) != 0) { 211 e.setData(i, sde.getData(i)); 212 } else { 213 e.setData(i, data[i]); 214 } 215 } 216 return e; 217 } 218 219 /** 220 * Merges with e. 221 * @param e instance of AbstractBorderElement 222 * @return instance of AbstractBorderElement 223 */ merge(AbstractBorderElement e)224 public AbstractBorderElement merge(AbstractBorderElement e) { 225 AbstractBorderElement abe = this; 226 if (e instanceof SolidAndDoubleBorderElement) { 227 abe = mergeSolid((SolidAndDoubleBorderElement) e); 228 } else if (e instanceof DottedBorderElement) { 229 abe = e; 230 } else if (e instanceof DashedBorderElement) { 231 abe = e.merge(this); 232 } 233 return abe; 234 } 235 236 /** 237 * Maps to char. 238 * @return resulting mapping char 239 */ map2Char()240 private char map2Char() { 241 int key = 0; 242 key += data[UP] * UP3; 243 key += data[LEFT] * LEFT3; 244 key += data[DOWN] * DOWN3; 245 key += data[RIGHT] * RIGHT3; 246 return MAP[key]; 247 } 248 249 /** 250 * Modifies data to nearest normal internal representation. 251 */ modifyData()252 private void modifyData() { 253 int c1 = 0; 254 int c2 = 0; 255 for (int i = 0; i < 4; i++) { 256 c1 += (data[i] == 1) ? 1 : 0; 257 c2 += (data[i] == 2) ? 1 : 0; 258 } 259 int m = c1 > c2 ? 1 : 0; 260 int[] p = {0, m, 2 * (1 - m)}; 261 for (int i = 0; i < 4; i++) { 262 data[i] = p[data[i]]; 263 } 264 } 265 266 /** 267 * {@inheritDoc} 268 */ convert2Char()269 public char convert2Char() { 270 char ch = map2Char(); 271 if (ch == UNDEFINED) { 272 modifyData(); 273 ch = map2Char(); 274 } 275 return ch; 276 } 277 } 278