History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/text/html/BlockView.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/text/html/BlockView.java+443−0
@@ -0,0 +1,443 @@
1+/*
2+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package javax.swing.text.html;
26+
27+import java.util.Enumeration;
28+import java.awt.*;
29+import javax.swing.SizeRequirements;
30+import javax.swing.border.*;
31+import javax.swing.event.DocumentEvent;
32+import javax.swing.text.*;
33+
34+/**
35+ * A view implementation to display a block (as a box)
36+ * with CSS specifications.
37+ *
38+ * @author Timothy Prinzing
39+ */
40+public class BlockView extends BoxView {
41+
42+ /**
43+ * Creates a new view that represents an
44+ * html box. This can be used for a number
45+ * of elements.
46+ *
47+ * @param elem the element to create a view for
48+ * @param axis either View.X_AXIS or View.Y_AXIS
49+ */
50+ public BlockView(Element elem, int axis) {
51+ super(elem, axis);
52+ }
53+
54+ /**
55+ * Establishes the parent view for this view. This is
56+ * guaranteed to be called before any other methods if the
57+ * parent view is functioning properly.
58+ * <p>
59+ * This is implemented
60+ * to forward to the superclass as well as call the
61+ * {@link #setPropertiesFromAttributes()}
62+ * method to set the paragraph properties from the css
63+ * attributes. The call is made at this time to ensure
64+ * the ability to resolve upward through the parents
65+ * view attributes.
66+ *
67+ * @param parent the new parent, or null if the view is
68+ * being removed from a parent it was previously added
69+ * to
70+ */
71+ public void setParent(View parent) {
72+ super.setParent(parent);
73+ if (parent != null) {
74+ setPropertiesFromAttributes();
75+ }
76+ }
77+
78+ /**
79+ * Calculate the requirements of the block along the major
80+ * axis (i.e. the axis along with it tiles). This is implemented
81+ * to provide the superclass behavior and then adjust it if the
82+ * CSS width or height attribute is specified and applicable to
83+ * the axis.
84+ */
85+ protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {
86+ if (r == null) {
87+ r = new SizeRequirements();
88+ }
89+ if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
90+ r = super.calculateMajorAxisRequirements(axis, r);
91+ }
92+ else {
93+ // Offset by the margins so that pref/min/max return the
94+ // right value.
95+ SizeRequirements parentR = super.calculateMajorAxisRequirements(
96+ axis, null);
97+ int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
98+ getTopInset() + getBottomInset();
99+ r.minimum -= margin;
100+ r.preferred -= margin;
101+ r.maximum -= margin;
102+ constrainSize(axis, r, parentR);
103+ }
104+ return r;
105+ }
106+
107+ /**
108+ * Calculate the requirements of the block along the minor
109+ * axis (i.e. the axis orthoginal to the axis along with it tiles).
110+ * This is implemented
111+ * to provide the superclass behavior and then adjust it if the
112+ * CSS width or height attribute is specified and applicable to
113+ * the axis.
114+ */
115+ protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
116+ if (r == null) {
117+ r = new SizeRequirements();
118+ }
119+
120+ if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
121+
122+ /*
123+ * The requirements were not directly specified by attributes, so
124+ * compute the aggregate of the requirements of the children. The
125+ * children that have a percentage value specified will be treated
126+ * as completely stretchable since that child is not limited in any
127+ * way.
128+ */
129+/*
130+ int min = 0;
131+ long pref = 0;
132+ int max = 0;
133+ int n = getViewCount();
134+ for (int i = 0; i < n; i++) {
135+ View v = getView(i);
136+ min = Math.max((int) v.getMinimumSpan(axis), min);
137+ pref = Math.max((int) v.getPreferredSpan(axis), pref);
138+ if (
139+ max = Math.max((int) v.getMaximumSpan(axis), max);
140+
141+ }
142+ r.preferred = (int) pref;
143+ r.minimum = min;
144+ r.maximum = max;
145+ */
146+ r = super.calculateMinorAxisRequirements(axis, r);
147+ }
148+ else {
149+ // Offset by the margins so that pref/min/max return the
150+ // right value.
151+ SizeRequirements parentR = super.calculateMinorAxisRequirements(
152+ axis, null);
153+ int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
154+ getTopInset() + getBottomInset();
155+ r.minimum -= margin;
156+ r.preferred -= margin;
157+ r.maximum -= margin;
158+ constrainSize(axis, r, parentR);
159+ }
160+
161+ /*
162+ * Set the alignment based upon the CSS properties if it is
163+ * specified. For X_AXIS this would be text-align, for
164+ * Y_AXIS this would be vertical-align.
165+ */
166+ if (axis == X_AXIS) {
167+ Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
168+ if (o != null) {
169+ String align = o.toString();
170+ if (align.equals("center")) {
171+ r.alignment = 0.5f;
172+ } else if (align.equals("right")) {
173+ r.alignment = 1.0f;
174+ } else {
175+ r.alignment = 0.0f;
176+ }
177+ }
178+ }
179+ // Y_AXIS TBD
180+ return r;
181+ }
182+
183+ boolean isPercentage(int axis, AttributeSet a) {
184+ if (axis == X_AXIS) {
185+ if (cssWidth != null) {
186+ return cssWidth.isPercentage();
187+ }
188+ } else {
189+ if (cssHeight != null) {
190+ return cssHeight.isPercentage();
191+ }
192+ }
193+ return false;
194+ }
195+
196+ /**
197+ * Adjust the given requirements to the CSS width or height if
198+ * it is specified along the applicable axis. Return true if the
199+ * size is exactly specified, false if the span is not specified
200+ * in an attribute or the size specified is a percentage.
201+ */
202+ static boolean spanSetFromAttributes(int axis, SizeRequirements r,
203+ CSS.LengthValue cssWidth,
204+ CSS.LengthValue cssHeight) {
205+ if (axis == X_AXIS) {
206+ if ((cssWidth != null) && (! cssWidth.isPercentage())) {
207+ r.minimum = r.preferred = r.maximum = (int) cssWidth.getValue();
208+ return true;
209+ }
210+ } else {
211+ if ((cssHeight != null) && (! cssHeight.isPercentage())) {
212+ r.minimum = r.preferred = r.maximum = (int) cssHeight.getValue();
213+ return true;
214+ }
215+ }
216+ return false;
217+ }
218+
219+ /**
220+ * Performs layout for the minor axis of the box (i.e. the
221+ * axis orthoginal to the axis that it represents). The results
222+ * of the layout (the offset and span for each children) are
223+ * placed in the given arrays which represent the allocations to
224+ * the children along the minor axis.
225+ *
226+ * @param targetSpan the total span given to the view, which
227+ * whould be used to layout the childre.
228+ * @param axis the axis being layed out
229+ * @param offsets the offsets from the origin of the view for
230+ * each of the child views; this is a return value and is
231+ * filled in by the implementation of this method
232+ * @param spans the span of each child view; this is a return
233+ * value and is filled in by the implementation of this method
234+ */
235+ protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
236+ int n = getViewCount();
237+ Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT;
238+ for (int i = 0; i < n; i++) {
239+ View v = getView(i);
240+ int min = (int) v.getMinimumSpan(axis);
241+ int max;
242+
243+ // check for percentage span
244+ AttributeSet a = v.getAttributes();
245+ CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key);
246+ if ((lv != null) && lv.isPercentage()) {
247+ // bound the span to the percentage specified
248+ min = Math.max((int) lv.getValue(targetSpan), min);
249+ max = min;
250+ } else {
251+ max = (int)v.getMaximumSpan(axis);
252+ }
253+
254+ // assign the offset and span for the child
255+ if (max < targetSpan) {
256+ // can't make the child this wide, align it
257+ float align = v.getAlignment(axis);
258+ offsets[i] = (int) ((targetSpan - max) * align);
259+ spans[i] = max;
260+ } else {
261+ // make it the target width, or as small as it can get.
262+ offsets[i] = 0;
263+ spans[i] = Math.max(min, targetSpan);
264+ }
265+ }
266+ }
267+
268+
269+ /**
270+ * Renders using the given rendering surface and area on that
271+ * surface. This is implemented to delegate to the css box
272+ * painter to paint the border and background prior to the
273+ * interior.
274+ *
275+ * @param g the rendering surface to use
276+ * @param allocation the allocated region to render into
277+ * @see View#paint
278+ */
279+ public void paint(Graphics g, Shape allocation) {
280+ Rectangle a = (Rectangle) allocation;
281+ painter.paint(g, a.x, a.y, a.width, a.height, this);
282+ super.paint(g, a);
283+ }
284+
285+ /**
286+ * Fetches the attributes to use when rendering. This is
287+ * implemented to multiplex the attributes specified in the
288+ * model with a StyleSheet.
289+ */
290+ public AttributeSet getAttributes() {
291+ if (attr == null) {
292+ StyleSheet sheet = getStyleSheet();
293+ attr = sheet.getViewAttributes(this);
294+ }
295+ return attr;
296+ }
297+
298+ /**
299+ * Gets the resize weight.
300+ *
301+ * @param axis may be either X_AXIS or Y_AXIS
302+ * @return the weight
303+ * @exception IllegalArgumentException for an invalid axis
304+ */
305+ public int getResizeWeight(int axis) {
306+ switch (axis) {
307+ case View.X_AXIS:
308+ return 1;
309+ case View.Y_AXIS:
310+ return 0;
311+ default:
312+ throw new IllegalArgumentException("Invalid axis: " + axis);
313+ }
314+ }
315+
316+ /**
317+ * Gets the alignment.
318+ *
319+ * @param axis may be either X_AXIS or Y_AXIS
320+ * @return the alignment
321+ */
322+ public float getAlignment(int axis) {
323+ switch (axis) {
324+ case View.X_AXIS:
325+ return 0;
326+ case View.Y_AXIS:
327+ if (getViewCount() == 0) {
328+ return 0;
329+ }
330+ float span = getPreferredSpan(View.Y_AXIS);
331+ View v = getView(0);
332+ float above = v.getPreferredSpan(View.Y_AXIS);
333+ float a = (((int)span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span: 0;
334+ return a;
335+ default:
336+ throw new IllegalArgumentException("Invalid axis: " + axis);
337+ }
338+ }
339+
340+ public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
341+ super.changedUpdate(changes, a, f);
342+ int pos = changes.getOffset();
343+ if (pos <= getStartOffset() && (pos + changes.getLength()) >=
344+ getEndOffset()) {
345+ setPropertiesFromAttributes();
346+ }
347+ }
348+
349+ /**
350+ * Determines the preferred span for this view along an
351+ * axis.
352+ *
353+ * @param axis may be either <code>View.X_AXIS</code>
354+ * or <code>View.Y_AXIS</code>
355+ * @return the span the view would like to be rendered into >= 0;
356+ * typically the view is told to render into the span
357+ * that is returned, although there is no guarantee;
358+ * the parent may choose to resize or break the view
359+ * @exception IllegalArgumentException for an invalid axis type
360+ */
361+ public float getPreferredSpan(int axis) {
362+ return super.getPreferredSpan(axis);
363+ }
364+
365+ /**
366+ * Determines the minimum span for this view along an
367+ * axis.
368+ *
369+ * @param axis may be either <code>View.X_AXIS</code>
370+ * or <code>View.Y_AXIS</code>
371+ * @return the span the view would like to be rendered into >= 0;
372+ * typically the view is told to render into the span
373+ * that is returned, although there is no guarantee;
374+ * the parent may choose to resize or break the view
375+ * @exception IllegalArgumentException for an invalid axis type
376+ */
377+ public float getMinimumSpan(int axis) {
378+ return super.getMinimumSpan(axis);
379+ }
380+
381+ /**
382+ * Determines the maximum span for this view along an
383+ * axis.
384+ *
385+ * @param axis may be either <code>View.X_AXIS</code>
386+ * or <code>View.Y_AXIS</code>
387+ * @return the span the view would like to be rendered into >= 0;
388+ * typically the view is told to render into the span
389+ * that is returned, although there is no guarantee;
390+ * the parent may choose to resize or break the view
391+ * @exception IllegalArgumentException for an invalid axis type
392+ */
393+ public float getMaximumSpan(int axis) {
394+ return super.getMaximumSpan(axis);
395+ }
396+
397+ /**
398+ * Update any cached values that come from attributes.
399+ */
400+ protected void setPropertiesFromAttributes() {
401+
402+ // update attributes
403+ StyleSheet sheet = getStyleSheet();
404+ attr = sheet.getViewAttributes(this);
405+
406+ // Reset the painter
407+ painter = sheet.getBoxPainter(attr);
408+ if (attr != null) {
409+ setInsets((short) painter.getInset(TOP, this),
410+ (short) painter.getInset(LEFT, this),
411+ (short) painter.getInset(BOTTOM, this),
412+ (short) painter.getInset(RIGHT, this));
413+ }
414+
415+ // Get the width/height
416+ cssWidth = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.WIDTH);
417+ cssHeight = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.HEIGHT);
418+ }
419+
420+ protected StyleSheet getStyleSheet() {
421+ HTMLDocument doc = (HTMLDocument) getDocument();
422+ return doc.getStyleSheet();
423+ }
424+
425+ /**
426+ * Constrains <code>want</code> to fit in the minimum size specified
427+ * by <code>min</code>.
428+ */
429+ private void constrainSize(int axis, SizeRequirements want,
430+ SizeRequirements min) {
431+ if (min.minimum > want.minimum) {
432+ want.minimum = want.preferred = min.minimum;
433+ want.maximum = Math.max(want.maximum, min.maximum);
434+ }
435+ }
436+
437+ private AttributeSet attr;
438+ private StyleSheet.BoxPainter painter;
439+
440+ private CSS.LengthValue cssWidth;
441+ private CSS.LengthValue cssHeight;
442+
443+}