|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
SHTMLBoxPainter.java | 0% | 0% | 0% | 0% |
|
1 |
/*
|
|
2 |
* SimplyHTML, a word processor based on Java, HTML and CSS
|
|
3 |
* Copyright (C) 2002 Ulrich Hilger
|
|
4 |
*
|
|
5 |
* This program is free software; you can redistribute it and/or
|
|
6 |
* modify it under the terms of the GNU General Public License
|
|
7 |
* as published by the Free Software Foundation; either version 2
|
|
8 |
* of the License, or (at your option) any later version.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18 |
*/
|
|
19 |
|
|
20 |
import javax.swing.text.AttributeSet;
|
|
21 |
import javax.swing.text.html.CSS;
|
|
22 |
import java.awt.Graphics;
|
|
23 |
import javax.swing.text.View;
|
|
24 |
import javax.swing.border.Border;
|
|
25 |
import java.awt.Color;
|
|
26 |
import java.awt.Insets;
|
|
27 |
import javax.swing.text.html.CSS;
|
|
28 |
import javax.swing.ImageIcon;
|
|
29 |
import java.awt.Rectangle;
|
|
30 |
import java.util.Hashtable;
|
|
31 |
import java.util.Enumeration;
|
|
32 |
import javax.swing.text.Element;
|
|
33 |
import javax.swing.text.SimpleAttributeSet;
|
|
34 |
import javax.swing.text.html.StyleSheet;
|
|
35 |
import javax.swing.text.Style;
|
|
36 |
|
|
37 |
/**
|
|
38 |
* <p>A box painter to support individual border rendering, i.e. border width
|
|
39 |
* and color of each side of a cell are painted independently according
|
|
40 |
* to CSS attributes border-width and border-color.</p>
|
|
41 |
*
|
|
42 |
* <p>Only border-style solid is supported.</p>
|
|
43 |
*
|
|
44 |
* @author Ulrich Hilger
|
|
45 |
* @author Light Development
|
|
46 |
* @author <a href="http://www.lightdev.com">http://www.lightdev.com</a>
|
|
47 |
* @author <a href="mailto:info@lightdev.com">info@lightdev.com</a>
|
|
48 |
* @author published under the terms and conditions of the
|
|
49 |
* GNU General Public License,
|
|
50 |
* for details see file gpl.txt in the distribution
|
|
51 |
* package of this software
|
|
52 |
*
|
|
53 |
* @version stage 11, April 27, 2003
|
|
54 |
*/
|
|
55 |
|
|
56 |
public class SHTMLBoxPainter { |
|
57 |
|
|
58 |
private float topMargin; |
|
59 |
private float bottomMargin; |
|
60 |
private float leftMargin; |
|
61 |
private float rightMargin; |
|
62 |
// Bitmask, used to indicate what margins are relative:
|
|
63 |
// bit 0 for top, 1 for bottom, 2 for left and 3 for right.
|
|
64 |
private short marginFlags; |
|
65 |
private CombinedAttribute borderWidth;
|
|
66 |
private CombinedAttribute borderColor;
|
|
67 |
private CombinedAttribute padding;
|
|
68 |
private CombinedAttribute margin;
|
|
69 |
private Color bg;
|
|
70 |
|
|
71 |
/**
|
|
72 |
* construct an SHTMLBoxPainter
|
|
73 |
*/
|
|
74 | 0 |
public SHTMLBoxPainter(AttributeSet a) {
|
75 | 0 |
borderWidth = new CombinedAttribute(CSS.Attribute.BORDER_WIDTH, a, true); |
76 | 0 |
borderColor = new CombinedAttribute(CSS.Attribute.BORDER_COLOR, a, true); |
77 | 0 |
padding = new CombinedAttribute(CSS.Attribute.PADDING, a, true); |
78 | 0 |
margin = new CombinedAttribute(CSS.Attribute.MARGIN, a, true); |
79 | 0 |
leftMargin = Util.getPtValue(margin.getAttribute(CombinedAttribute.ATTR_LEFT)); |
80 | 0 |
rightMargin = Util.getPtValue(margin.getAttribute(CombinedAttribute.ATTR_RIGHT)); |
81 | 0 |
topMargin = Util.getPtValue(margin.getAttribute(CombinedAttribute.ATTR_TOP)); |
82 | 0 |
bottomMargin = Util.getPtValue(margin.getAttribute(CombinedAttribute.ATTR_BOTTOM)); |
83 | 0 |
bg = Util.styleSheet().getBackground(a); |
84 |
} |
|
85 |
|
|
86 | 0 |
public Color getColor(String value) {
|
87 | 0 |
try {
|
88 | 0 |
if (value != null) { |
89 | 0 |
return new Color(Integer.parseInt( |
90 |
value.toString().substring(1).toUpperCase(), 16)); |
|
91 |
} |
|
92 |
else {
|
|
93 | 0 |
return Color.black;
|
94 |
} |
|
95 |
} |
|
96 |
catch(Exception e) {
|
|
97 | 0 |
try {
|
98 | 0 |
return Color.getColor(value);
|
99 |
} |
|
100 |
catch (Exception e2) {
|
|
101 | 0 |
return Color.black;
|
102 |
} |
|
103 |
} |
|
104 |
} |
|
105 |
|
|
106 |
/**
|
|
107 |
* Fetches the inset needed on a given side to
|
|
108 |
* account for the margin, border, and padding.
|
|
109 |
*
|
|
110 |
* @param side The size of the box to fetch the
|
|
111 |
* inset for. This can be View.TOP,
|
|
112 |
* View.LEFT, View.BOTTOM, or View.RIGHT.
|
|
113 |
* @param v the view making the request. This is
|
|
114 |
* used to get the AttributeSet, and may be used to
|
|
115 |
* resolve percentage arguments.
|
|
116 |
* @exception IllegalArgumentException for an invalid direction
|
|
117 |
*/
|
|
118 | 0 |
public float getInset(int side, View v) { |
119 | 0 |
AttributeSet a = v.getAttributes(); |
120 | 0 |
float inset = 0;
|
121 | 0 |
switch(side) {
|
122 | 0 |
case View.LEFT:
|
123 | 0 |
inset += leftMargin; |
124 | 0 |
inset += Util.getPtValue(borderWidth.getAttribute(CombinedAttribute.ATTR_LEFT)); |
125 | 0 |
inset += Util.getPtValue(padding.getAttribute(CombinedAttribute.ATTR_LEFT)); |
126 | 0 |
break;
|
127 | 0 |
case View.RIGHT:
|
128 | 0 |
inset += rightMargin; |
129 | 0 |
inset += Util.getPtValue(borderWidth.getAttribute(CombinedAttribute.ATTR_RIGHT)); |
130 | 0 |
inset += Util.getPtValue(padding.getAttribute(CombinedAttribute.ATTR_RIGHT)); |
131 | 0 |
break;
|
132 | 0 |
case View.TOP:
|
133 | 0 |
inset += topMargin; |
134 | 0 |
inset += Util.getPtValue(borderWidth.getAttribute(CombinedAttribute.ATTR_TOP)); |
135 | 0 |
inset += Util.getPtValue(padding.getAttribute(CombinedAttribute.ATTR_TOP)); |
136 | 0 |
break;
|
137 | 0 |
case View.BOTTOM:
|
138 | 0 |
inset += bottomMargin; |
139 | 0 |
inset += Util.getPtValue(borderWidth.getAttribute(CombinedAttribute.ATTR_BOTTOM)); |
140 | 0 |
inset += Util.getPtValue(padding.getAttribute(CombinedAttribute.ATTR_BOTTOM)); |
141 | 0 |
break;
|
142 | 0 |
default:
|
143 | 0 |
throw new IllegalArgumentException("Invalid side: " + side); |
144 |
} |
|
145 |
//System.out.println("getInset side=" + side + " inset=" + inset);
|
|
146 | 0 |
return inset;
|
147 |
} |
|
148 |
|
|
149 |
/**
|
|
150 |
* Paints the CSS box according to the attributes
|
|
151 |
* given. This should paint the border, padding,
|
|
152 |
* and background.
|
|
153 |
*
|
|
154 |
* @param g the rendering surface.
|
|
155 |
* @param x the x coordinate of the allocated area to
|
|
156 |
* render into.
|
|
157 |
* @param y the y coordinate of the allocated area to
|
|
158 |
* render into.
|
|
159 |
* @param w the width of the allocated area to render into.
|
|
160 |
* @param h the height of the allocated area to render into.
|
|
161 |
* @param v the view making the request. This is
|
|
162 |
* used to get the AttributeSet, and may be used to
|
|
163 |
* resolve percentage arguments.
|
|
164 |
*/
|
|
165 | 0 |
public void paint(Graphics g, float x, float y, float w, float h, View v) { |
166 |
//de.calcom.cclib.html.HTMLDiag hd = new de.calcom.cclib.html.HTMLDiag();
|
|
167 |
//hd.listAttributes(v.getAttributes(), 2);
|
|
168 | 0 |
Element cell = v.getElement(); |
169 | 0 |
Element thisRow = cell.getParentElement(); |
170 | 0 |
Element table = thisRow.getParentElement(); |
171 | 0 |
int rowIndex = Util.getRowIndex(cell);
|
172 | 0 |
int cellIndex = Util.getElementIndex(cell);
|
173 | 0 |
x += leftMargin; |
174 | 0 |
y += topMargin; |
175 | 0 |
w -= leftMargin + rightMargin; |
176 | 0 |
h -= topMargin + bottomMargin; |
177 | 0 |
if (bg != null) { |
178 | 0 |
g.setColor(bg); |
179 | 0 |
g.fillRect((int) x, (int) y, (int) w, (int) h); |
180 |
} |
|
181 | 0 |
if((rowIndex == 0) ||
|
182 |
canPaintBorder(cell, |
|
183 |
table.getElement(rowIndex-1).getElement(cellIndex), |
|
184 |
CombinedAttribute.ATTR_TOP, v)) |
|
185 |
{ |
|
186 | 0 |
paintBorder(g, x, y, w, h, CombinedAttribute.ATTR_TOP); |
187 |
} |
|
188 | 0 |
if((cellIndex == 0) ||
|
189 |
canPaintBorder(cell, |
|
190 |
table.getElement(rowIndex).getElement(cellIndex-1), |
|
191 |
CombinedAttribute.ATTR_LEFT, v)) |
|
192 |
{ |
|
193 | 0 |
paintBorder(g, x, y, w, h, CombinedAttribute.ATTR_LEFT); |
194 |
} |
|
195 | 0 |
paintBorder(g, x, y, w, h, CombinedAttribute.ATTR_BOTTOM); |
196 | 0 |
paintBorder(g, x, y, w, h, CombinedAttribute.ATTR_RIGHT); |
197 |
} |
|
198 |
|
|
199 |
/**
|
|
200 |
* paint a border for a given side of a table cell
|
|
201 |
*
|
|
202 |
* @param g the rendering surface.
|
|
203 |
* @param x the x coordinate of the allocated area to
|
|
204 |
* render into.
|
|
205 |
* @param y the y coordinate of the allocated area to
|
|
206 |
* render into.
|
|
207 |
* @param w the width of the allocated area to render into.
|
|
208 |
* @param h the height of the allocated area to render into.
|
|
209 |
* @param side the side to render
|
|
210 |
*/
|
|
211 | 0 |
private void paintBorder(Graphics g, float x, float y, float w, float h, |
212 |
int side)
|
|
213 |
{ |
|
214 | 0 |
int thickness;
|
215 | 0 |
g.setColor(getColor(borderColor.getAttribute( |
216 |
side))); |
|
217 | 0 |
thickness = (int) Util.getPtValue(borderWidth.getAttribute(
|
218 |
side)); |
|
219 | 0 |
switch(side) {
|
220 | 0 |
case CombinedAttribute.ATTR_TOP:
|
221 | 0 |
g.fillRect((int) x, (int) y, (int) w, thickness); |
222 | 0 |
break;
|
223 | 0 |
case CombinedAttribute.ATTR_RIGHT:
|
224 | 0 |
g.fillRect((int) x + (int) w - thickness, (int) y, thickness, (int) h); |
225 | 0 |
break;
|
226 | 0 |
case CombinedAttribute.ATTR_BOTTOM:
|
227 | 0 |
g.fillRect((int) x, (int) y + (int) h - thickness, (int) w, thickness); |
228 | 0 |
break;
|
229 | 0 |
case CombinedAttribute.ATTR_LEFT:
|
230 | 0 |
g.fillRect((int) x, (int) y, thickness, (int) h); |
231 | 0 |
break;
|
232 |
} |
|
233 |
} |
|
234 |
|
|
235 |
/**
|
|
236 |
* find out whether or not the border of a given side of table cell can
|
|
237 |
* be painted.
|
|
238 |
*
|
|
239 |
* @param cell the cell element to adjust a border for
|
|
240 |
* @param oCell the other cell to look for border and margin settings
|
|
241 |
* @param side the side of 'cell' to adjust adjust a border for, one of
|
|
242 |
* CombinedAttribute.ATTR_TOP, CombinedAttribute.ATTR_RIGHT,
|
|
243 |
* CombinedAttribute.ATTR_BOTTOM and CombinedAttribute.ATTR_LEFT
|
|
244 |
* @see CombinedAttribute
|
|
245 |
*/
|
|
246 | 0 |
private boolean canPaintBorder(Element cell, Element oCell, int side, View v) |
247 |
{ |
|
248 | 0 |
boolean canPaint = true; |
249 | 0 |
try {
|
250 | 0 |
AttributeSet vSet = v.getAttributes(); |
251 | 0 |
SimpleAttributeSet set = new SimpleAttributeSet(vSet);
|
252 | 0 |
set.addAttributes(cell.getAttributes()); |
253 | 0 |
SimpleAttributeSet oSet = new SimpleAttributeSet(vSet);
|
254 | 0 |
oSet.addAttributes(oCell.getAttributes()); |
255 | 0 |
CombinedAttribute otherMargin = new CombinedAttribute(
|
256 |
CSS.Attribute.MARGIN, oSet, true);
|
|
257 | 0 |
CombinedAttribute otherBorderWidth = new CombinedAttribute(
|
258 |
CSS.Attribute.BORDER_WIDTH, oSet, true);
|
|
259 | 0 |
CombinedAttribute thisMargin = new CombinedAttribute(
|
260 |
CSS.Attribute.MARGIN, set, true);
|
|
261 | 0 |
int oppositeSide = otherMargin.getOppositeSide(side);
|
262 | 0 |
if(intFromCA(otherMargin, oppositeSide) == 0 &&
|
263 |
intFromCA(thisMargin, side) == 0 && |
|
264 |
intFromCA(otherBorderWidth, oppositeSide) > 0) |
|
265 |
{ |
|
266 | 0 |
canPaint = false;
|
267 |
} |
|
268 |
} |
|
269 |
catch(Exception ex) {
|
|
270 | 0 |
canPaint = false;
|
271 |
//Util.errMsg(null, null, ex);
|
|
272 |
} |
|
273 | 0 |
return canPaint;
|
274 |
} |
|
275 |
|
|
276 |
/**
|
|
277 |
* get an integer value from a CombinedAttribute
|
|
278 |
*
|
|
279 |
* Caution: This only works for width values in pt
|
|
280 |
*
|
|
281 |
* @param attr the CombinedAttribute to get an integer value from
|
|
282 |
* @param side the side of the CombinedAttribute to get the vlaue for
|
|
283 |
*
|
|
284 |
* @return the integer value of the given side
|
|
285 |
*/
|
|
286 | 0 |
private int intFromCA(CombinedAttribute attr, int side) { |
287 | 0 |
String val = attr.getAttribute(side); |
288 | 0 |
int iVal = 0;
|
289 | 0 |
if(val != null) { |
290 | 0 |
iVal = (int) Util.getPtValue(val);
|
291 |
//System.out.println("SHTMLBoxPainter intFromCA val=" + val + " iVal=" + iVal);
|
|
292 |
} |
|
293 | 0 |
return iVal;
|
294 |
} |
|
295 |
} |
|