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/FrameSetView.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/text/html/FrameSetView.java+322−0
@@ -0,0 +1,322 @@
1+/*
2+ * Copyright (c) 1998, 2003, 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.awt.*;
28+import java.util.*;
29+import javax.swing.*;
30+import javax.swing.text.*;
31+import javax.swing.event.*;
32+
33+/**
34+ * Implements a FrameSetView, intended to support the HTML
35+ * <FRAMESET> tag. Supports the ROWS and COLS attributes.
36+ *
37+ * @author Sunita Mani
38+ *
39+ * Credit also to the hotjava browser engineers that
40+ * worked on making the allocation of space algorithms
41+ * conform to the HTML 4.0 standard and also be netscape
42+ * compatible.
43+ *
44+ */
45+
46+class FrameSetView extends javax.swing.text.BoxView {
47+
48+ String[] children;
49+ int[] percentChildren;
50+ int[] absoluteChildren;
51+ int[] relativeChildren;
52+ int percentTotals;
53+ int absoluteTotals;
54+ int relativeTotals;
55+
56+ /**
57+ * Constructs a FrameSetView for the given element.
58+ *
59+ * @param elem the element that this view is responsible for
60+ */
61+ public FrameSetView(Element elem, int axis) {
62+ super(elem, axis);
63+ children = null;
64+ }
65+
66+ /**
67+ * Parses the ROW or COL attributes and returns
68+ * an array of strings that represent the space
69+ * distribution.
70+ *
71+ */
72+ private String[] parseRowColSpec(HTML.Attribute key) {
73+
74+ AttributeSet attributes = getElement().getAttributes();
75+ String spec = "*";
76+ if (attributes != null) {
77+ if (attributes.getAttribute(key) != null) {
78+ spec = (String)attributes.getAttribute(key);
79+ }
80+ }
81+
82+ StringTokenizer tokenizer = new StringTokenizer(spec, ",");
83+ int nTokens = tokenizer.countTokens();
84+ int n = getViewCount();
85+ String[] items = new String[Math.max(nTokens, n)];
86+ int i = 0;
87+ for (; i < nTokens; i++) {
88+ items[i] = tokenizer.nextToken().trim();
89+ // As per the spec, 100% is the same as *
90+ // hence the mapping.
91+ //
92+ if (items[i].equals("100%")) {
93+ items[i] = "*";
94+ }
95+ }
96+ // extend spec if we have more children than specified
97+ // in ROWS or COLS attribute
98+ for (; i < items.length; i++) {
99+ items[i] = "*";
100+ }
101+ return items;
102+ }
103+
104+
105+ /**
106+ * Initializes a number of internal state variables
107+ * that store information about space allocation
108+ * for the frames contained within the frameset.
109+ */
110+ private void init() {
111+ if (getAxis() == View.Y_AXIS) {
112+ children = parseRowColSpec(HTML.Attribute.ROWS);
113+ } else {
114+ children = parseRowColSpec(HTML.Attribute.COLS);
115+ }
116+ percentChildren = new int[children.length];
117+ relativeChildren = new int[children.length];
118+ absoluteChildren = new int[children.length];
119+
120+ for (int i = 0; i < children.length; i++) {
121+ percentChildren[i] = -1;
122+ relativeChildren[i] = -1;
123+ absoluteChildren[i] = -1;
124+
125+ if (children[i].endsWith("*")) {
126+ if (children[i].length() > 1) {
127+ relativeChildren[i] =
128+ Integer.parseInt(children[i].substring(
129+ 0, children[i].length()-1));
130+ relativeTotals += relativeChildren[i];
131+ } else {
132+ relativeChildren[i] = 1;
133+ relativeTotals += 1;
134+ }
135+ } else if (children[i].indexOf('%') != -1) {
136+ percentChildren[i] = parseDigits(children[i]);
137+ percentTotals += percentChildren[i];
138+ } else {
139+ absoluteChildren[i] = Integer.parseInt(children[i]);
140+ }
141+ }
142+ if (percentTotals > 100) {
143+ for (int i = 0; i < percentChildren.length; i++) {
144+ if (percentChildren[i] > 0) {
145+ percentChildren[i] =
146+ (percentChildren[i] * 100) / percentTotals;
147+ }
148+ }
149+ percentTotals = 100;
150+ }
151+ }
152+
153+ /**
154+ * Perform layout for the major axis of the box (i.e. the
155+ * axis that it represents). The results of the layout should
156+ * be placed in the given arrays which represent the allocations
157+ * to the children along the major axis.
158+ *
159+ * @param targetSpan the total span given to the view, which
160+ * whould be used to layout the children
161+ * @param axis the axis being layed out
162+ * @param offsets the offsets from the origin of the view for
163+ * each of the child views; this is a return value and is
164+ * filled in by the implementation of this method
165+ * @param spans the span of each child view; this is a return
166+ * value and is filled in by the implementation of this method
167+ * @return the offset and span for each child view in the
168+ * offsets and spans parameters
169+ */
170+ protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
171+ int[] spans) {
172+ if (children == null) {
173+ init();
174+ }
175+ SizeRequirements.calculateTiledPositions(targetSpan, null,
176+ getChildRequests(targetSpan,
177+ axis),
178+ offsets, spans);
179+ }
180+
181+ protected SizeRequirements[] getChildRequests(int targetSpan, int axis) {
182+
183+ int span[] = new int[children.length];
184+
185+ spread(targetSpan, span);
186+ int n = getViewCount();
187+ SizeRequirements[] reqs = new SizeRequirements[n];
188+ for (int i = 0, sIndex = 0; i < n; i++) {
189+ View v = getView(i);
190+ if ((v instanceof FrameView) || (v instanceof FrameSetView)) {
191+ reqs[i] = new SizeRequirements((int) v.getMinimumSpan(axis),
192+ span[sIndex],
193+ (int) v.getMaximumSpan(axis),
194+ 0.5f);
195+ sIndex++;
196+ } else {
197+ int min = (int) v.getMinimumSpan(axis);
198+ int pref = (int) v.getPreferredSpan(axis);
199+ int max = (int) v.getMaximumSpan(axis);
200+ float a = v.getAlignment(axis);
201+ reqs[i] = new SizeRequirements(min, pref, max, a);
202+ }
203+ }
204+ return reqs;
205+ }
206+
207+
208+ /**
209+ * This method is responsible for returning in span[] the
210+ * span for each child view along the major axis. it
211+ * computes this based on the information that extracted
212+ * from the value of the ROW/COL attribute.
213+ */
214+ private void spread(int targetSpan, int span[]) {
215+
216+ if (targetSpan == 0) {
217+ return;
218+ }
219+
220+ int tempSpace = 0;
221+ int remainingSpace = targetSpan;
222+
223+ // allocate the absolute's first, they have
224+ // precedence
225+ //
226+ for (int i = 0; i < span.length; i++) {
227+ if (absoluteChildren[i] > 0) {
228+ span[i] = absoluteChildren[i];
229+ remainingSpace -= span[i];
230+ }
231+ }
232+
233+ // then deal with percents.
234+ //
235+ tempSpace = remainingSpace;
236+ for (int i = 0; i < span.length; i++) {
237+ if (percentChildren[i] > 0 && tempSpace > 0) {
238+ span[i] = (percentChildren[i] * tempSpace) / 100;
239+ remainingSpace -= span[i];
240+ } else if (percentChildren[i] > 0 && tempSpace <= 0) {
241+ span[i] = targetSpan / span.length;
242+ remainingSpace -= span[i];
243+ }
244+ }
245+
246+ // allocate remainingSpace to relative
247+ if (remainingSpace > 0 && relativeTotals > 0) {
248+ for (int i = 0; i < span.length; i++) {
249+ if (relativeChildren[i] > 0) {
250+ span[i] = (remainingSpace *
251+ relativeChildren[i]) / relativeTotals;
252+ }
253+ }
254+ } else if (remainingSpace > 0) {
255+ // There are no relative columns and the space has been
256+ // under- or overallocated. In this case, turn all the
257+ // percentage and pixel specified columns to percentage
258+ // columns based on the ratio of their pixel count to the
259+ // total "virtual" size. (In the case of percentage columns,
260+ // the pixel count would equal the specified percentage
261+ // of the screen size.
262+
263+ // This action is in accordance with the HTML
264+ // 4.0 spec (see section 8.3, the end of the discussion of
265+ // the FRAMESET tag). The precedence of percentage and pixel
266+ // specified columns is unclear (spec seems to indicate that
267+ // they share priority, however, unspecified what happens when
268+ // overallocation occurs.)
269+
270+ // addendum is that we behave similiar to netscape in that specified
271+ // widths have precedance over percentage widths...
272+
273+ float vTotal = (float)(targetSpan - remainingSpace);
274+ float[] tempPercents = new float[span.length];
275+ remainingSpace = targetSpan;
276+ for (int i = 0; i < span.length; i++) {
277+ // ok we know what our total space is, and we know how large each
278+ // column should be relative to each other... therefore we can use
279+ // that relative information to deduce their percentages of a whole
280+ // and then scale them appropriately for the correct size
281+ tempPercents[i] = ((float)span[i] / vTotal) * 100.00f;
282+ span[i] = (int) ( ((float)targetSpan * tempPercents[i]) / 100.00f);
283+ remainingSpace -= span[i];
284+ }
285+
286+
287+ // this is for just in case there is something left over.. if there is we just
288+ // add it one pixel at a time to the frames in order.. We shouldn't really ever get
289+ // here and if we do it shouldn't be with more than 1 pixel, maybe two.
290+ int i = 0;
291+ while (remainingSpace != 0) {
292+ if (remainingSpace < 0) {
293+ span[i++]--;
294+ remainingSpace++;
295+ }
296+ else {
297+ span[i++]++;
298+ remainingSpace--;
299+ }
300+
301+ // just in case there are more pixels than frames...should never happen..
302+ if (i == span.length)i = 0;
303+ }
304+ }
305+ }
306+
307+ /*
308+ * Users have been known to type things like "%25" and "25 %". Deal
309+ * with it.
310+ */
311+ private int parseDigits(String mixedStr) {
312+ int result = 0;
313+ for (int i = 0; i < mixedStr.length(); i++) {
314+ char ch = mixedStr.charAt(i);
315+ if (Character.isDigit(ch)) {
316+ result = (result * 10) + Character.digit(ch, 10);
317+ }
318+ }
319+ return result;
320+ }
321+
322+}