1 /*
2 * Copyright (c) 1998, 2017, 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
3356
3357 /**
3358 * Calculate a tiled layout for the given iterator.
3359 * This should be done collapsing the neighboring
3360 * margins to be a total of the maximum of the two
3361 * neighboring margin areas as described in the CSS spec.
3362 */
3363 static void calculateTiledLayout(LayoutIterator iter, int targetSpan) {
3364
3365 /*
3366 * first pass, calculate the preferred sizes, adjustments needed because
3367 * of margin collapsing, and the flexibility to adjust the sizes.
3368 */
3369 long preferred = 0;
3370 long currentPreferred;
3371 int lastMargin = 0;
3372 int totalSpacing = 0;
3373 int n = iter.getCount();
3374 int adjustmentWeightsCount = LayoutIterator.WorstAdjustmentWeight + 1;
3375 //max gain we can get adjusting elements with adjustmentWeight <= i
3376 long gain[] = new long[adjustmentWeightsCount];
3377 //max loss we can get adjusting elements with adjustmentWeight <= i
3378 long loss[] = new long[adjustmentWeightsCount];
3379
3380 for (int i = 0; i < adjustmentWeightsCount; i++) {
3381 gain[i] = loss[i] = 0;
3382 }
3383 for (int i = 0; i < n; i++) {
3384 iter.setIndex(i);
3385 int margin0 = lastMargin;
3386 int margin1 = (int) iter.getLeadingCollapseSpan();
3387
3388 iter.setOffset(Math.max(margin0, margin1));
3389 totalSpacing += iter.getOffset();
3390
3391 currentPreferred = (long)iter.getPreferredSpan(targetSpan);
3392 iter.setSpan((int) currentPreferred);
3393 preferred += currentPreferred;
3394 gain[iter.getAdjustmentWeight()] +=
3395 (long)iter.getMaximumSpan(targetSpan) - currentPreferred;
3396 loss[iter.getAdjustmentWeight()] +=
3397 currentPreferred - (long)iter.getMinimumSpan(targetSpan);
3398 lastMargin = (int) iter.getTrailingCollapseSpan();
3399 }
3400 totalSpacing += lastMargin;
3401 totalSpacing += 2 * iter.getBorderWidth();
3402
3403 for (int i = 1; i < adjustmentWeightsCount; i++) {
3404 gain[i] += gain[i - 1];
3405 loss[i] += loss[i - 1];
3406 }
3407
3408 /*
3409 * Second pass, expand or contract by as much as possible to reach
3410 * the target span. This takes the margin collapsing into account
3411 * prior to adjusting the span.
3412 */
3413
3414 // determine the adjustment to be made
3415 int allocated = targetSpan - totalSpacing;
3416 long desiredAdjustment = allocated - preferred;
3417 long adjustmentsArray[] = (desiredAdjustment > 0) ? gain : loss;
3418 desiredAdjustment = Math.abs(desiredAdjustment);
3419 int adjustmentLevel = 0;
3420 for (;adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight;
3421 adjustmentLevel++) {
3422 // adjustmentsArray[] is sorted. I do not bother about
3423 // binary search though
3424 if (adjustmentsArray[adjustmentLevel] >= desiredAdjustment) {
3425 break;
3426 }
3427 }
3428 float adjustmentFactor = 0.0f;
3429 if (adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight) {
3430 desiredAdjustment -= (adjustmentLevel > 0) ?
3431 adjustmentsArray[adjustmentLevel - 1] : 0;
3432 if (desiredAdjustment != 0) {
3433 float maximumAdjustment =
3434 adjustmentsArray[adjustmentLevel] -
3435 ((adjustmentLevel > 0) ?
3436 adjustmentsArray[adjustmentLevel - 1] : 0
3437 );
|
1 /*
2 * Copyright (c) 1998, 2018, 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
3356
3357 /**
3358 * Calculate a tiled layout for the given iterator.
3359 * This should be done collapsing the neighboring
3360 * margins to be a total of the maximum of the two
3361 * neighboring margin areas as described in the CSS spec.
3362 */
3363 static void calculateTiledLayout(LayoutIterator iter, int targetSpan) {
3364
3365 /*
3366 * first pass, calculate the preferred sizes, adjustments needed because
3367 * of margin collapsing, and the flexibility to adjust the sizes.
3368 */
3369 long preferred = 0;
3370 long currentPreferred;
3371 int lastMargin = 0;
3372 int totalSpacing = 0;
3373 int n = iter.getCount();
3374 int adjustmentWeightsCount = LayoutIterator.WorstAdjustmentWeight + 1;
3375 //max gain we can get adjusting elements with adjustmentWeight <= i
3376 long[] gain = new long[adjustmentWeightsCount];
3377 //max loss we can get adjusting elements with adjustmentWeight <= i
3378 long[] loss = new long[adjustmentWeightsCount];
3379
3380 for (int i = 0; i < adjustmentWeightsCount; i++) {
3381 gain[i] = loss[i] = 0;
3382 }
3383 for (int i = 0; i < n; i++) {
3384 iter.setIndex(i);
3385 int margin0 = lastMargin;
3386 int margin1 = (int) iter.getLeadingCollapseSpan();
3387
3388 iter.setOffset(Math.max(margin0, margin1));
3389 totalSpacing += iter.getOffset();
3390
3391 currentPreferred = (long)iter.getPreferredSpan(targetSpan);
3392 iter.setSpan((int) currentPreferred);
3393 preferred += currentPreferred;
3394 gain[iter.getAdjustmentWeight()] +=
3395 (long)iter.getMaximumSpan(targetSpan) - currentPreferred;
3396 loss[iter.getAdjustmentWeight()] +=
3397 currentPreferred - (long)iter.getMinimumSpan(targetSpan);
3398 lastMargin = (int) iter.getTrailingCollapseSpan();
3399 }
3400 totalSpacing += lastMargin;
3401 totalSpacing += 2 * iter.getBorderWidth();
3402
3403 for (int i = 1; i < adjustmentWeightsCount; i++) {
3404 gain[i] += gain[i - 1];
3405 loss[i] += loss[i - 1];
3406 }
3407
3408 /*
3409 * Second pass, expand or contract by as much as possible to reach
3410 * the target span. This takes the margin collapsing into account
3411 * prior to adjusting the span.
3412 */
3413
3414 // determine the adjustment to be made
3415 int allocated = targetSpan - totalSpacing;
3416 long desiredAdjustment = allocated - preferred;
3417 long[] adjustmentsArray = (desiredAdjustment > 0) ? gain : loss;
3418 desiredAdjustment = Math.abs(desiredAdjustment);
3419 int adjustmentLevel = 0;
3420 for (;adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight;
3421 adjustmentLevel++) {
3422 // adjustmentsArray[] is sorted. I do not bother about
3423 // binary search though
3424 if (adjustmentsArray[adjustmentLevel] >= desiredAdjustment) {
3425 break;
3426 }
3427 }
3428 float adjustmentFactor = 0.0f;
3429 if (adjustmentLevel <= LayoutIterator.WorstAdjustmentWeight) {
3430 desiredAdjustment -= (adjustmentLevel > 0) ?
3431 adjustmentsArray[adjustmentLevel - 1] : 0;
3432 if (desiredAdjustment != 0) {
3433 float maximumAdjustment =
3434 adjustmentsArray[adjustmentLevel] -
3435 ((adjustmentLevel > 0) ?
3436 adjustmentsArray[adjustmentLevel - 1] : 0
3437 );
|