Package org.apache.harmony.x.swing

Source Code of org.apache.harmony.x.swing.SizeRequirementsHelper

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Alexander T. Simbirtsev
* @version $Revision$
*/
package org.apache.harmony.x.swing;

import javax.swing.SizeRequirements;

/**
* Helper object which wraps functionality of javax.swing.SizeRequirements
* so that it can be easily used by javax.swing.text.BoxView.
*
*/
public final class SizeRequirementsHelper {
    /**
     * @see javax.swing.SizeRequirements#getTiledSizeRequirements(SizeRequirements[])
     *
     * @param sr SizeRequirements where results to be copied. If sr is null, new object is created
     *
     * @return SizeRequirements sr or newly created object
     */
    public static SizeRequirements
        getTiledSizeRequirements(final SizeRequirements[] children,
                                 final SizeRequirements sr) {

        SizeRequirements result = (sr != null) ? sr : new SizeRequirements();
        result.minimum   = 0;
        result.preferred = 0;
        result.maximum   = 0;
        result.alignment = 0.5f;

        for (int iChild = 0; iChild < children.length; iChild++) {
            result.minimum = Utilities.safeIntSum(children[iChild].minimum, result.minimum);
            result.preferred = Utilities.safeIntSum(children[iChild].preferred, result.preferred);
            result.maximum = Utilities.safeIntSum(children[iChild].maximum, result.maximum);
        }

        return result;
    }

    /**
     * @see javax.swing.SizeRequirements#getAlignedSizeRequirements(SizeRequirements[])
     *
     * @param sr SizeRequirements where results to be copied. If sr is null, new object is created
     * @param alignByPreferred boolean value representing which size (preferred or minimal) should be used for alignment calculation
     *
     * @return SizeRequirements sr or newly created object
     */
    public static SizeRequirements
        getAlignedSizeRequirements(final SizeRequirements[] children,
                                   final SizeRequirements sr,
                                   final boolean alignByPreferred) {

        int minRight = 0;
        int minLeft = 0;
        int prefRight = 0;
        int prefLeft = 0;
        int maxRight = 0;
        int maxLeft = 0;

        for (int iChild = 0; iChild < children.length; iChild++) {
            int alignedMin = (int)(children[iChild].alignment * children[iChild].minimum);
            minLeft = Math.max(minLeft, alignedMin);
            minRight = Math.max(minRight, children[iChild].minimum - alignedMin);

            int alignedPref = (int)(children[iChild].alignment * children[iChild].preferred);
            prefLeft = Math.max(prefLeft, alignedPref);
            prefRight = Math.max(prefRight, children[iChild].preferred - alignedPref);

            int alignedMax = (int)(children[iChild].alignment * children[iChild].maximum);
            maxLeft = Math.max(maxLeft, alignedMax);
            maxRight = Math.max(maxRight, children[iChild].maximum - alignedMax);
        }

        SizeRequirements result = (sr != null) ? sr : new SizeRequirements();
        result.minimum   = Utilities.safeIntSum(minRight,  minLeft);
        result.preferred = Utilities.safeIntSum(prefRight, prefLeft);
        result.maximum   = Utilities.safeIntSum(maxRight,  maxLeft);
        if (alignByPreferred) {
            result.alignment = (result.preferred != 0) ? (float)prefLeft/result.preferred : 0;
        } else {
            result.alignment = (result.minimum != 0) ? (float)minLeft/result.minimum : 0;
        }

        return result;
    }

    /**
     * @see javax.swing.SizeRequirements#calculateTiledPositions(int, SizeRequirements, SizeRequirements[], int[], int[], boolean)
     */
    public static void calculateTiledPositions(final int allocated,
                                final SizeRequirements total,
                                final SizeRequirements[] children,
                                final int[] offsets,
                                final int[] spans,
                                final boolean normal) {

        calculateTiledSpans(allocated, total, children, spans);

        if (normal) {
            int curOffset = 0;
            for (int iChild = 0; iChild < children.length; iChild++) {
                offsets[iChild] = curOffset;
                curOffset += spans[iChild];
            }
        } else {
            int curOffset = allocated;
            for (int iChild = 0; iChild < children.length; iChild++) {
                curOffset -= spans[iChild];
                offsets[iChild] = curOffset;
            }
        }
    }

    /**
     * @see javax.swing.SizeRequirements#calculateAlignedPositions(int, SizeRequirements, SizeRequirements[], int[], int[], boolean)
     */
    public static void calculateAlignedPositions(final int allocated,
                                  final SizeRequirements total,
                                  final SizeRequirements[] children,
                                  final int[] offsets,
                                  final int[] spans,
                                  final boolean normal) {

        final int alignedAllocated = (int)(allocated * total.alignment);
        for (int iChild = 0; iChild < children.length; iChild++) {
            spans[iChild] = children[iChild].maximum;
            offsets[iChild] = alignedAllocated
                - (int)(children[iChild].maximum * children[iChild].alignment);

            if (offsets[iChild] < 0) {
                spans[iChild] = spans[iChild] + offsets[iChild];
                offsets[iChild] = 0;
            }
            if (offsets[iChild] + spans[iChild] > allocated) {
                spans[iChild] = allocated - offsets[iChild];
            }
        }
        if (!normal) {
            for (int iChild = 0; iChild < children.length; iChild++) {
                offsets[iChild] = allocated - offsets[iChild] - spans[iChild];
            }
        }
    }

    /**
     * @see javax.swing.SizeRequirements#calculateAlignedPositions(int, SizeRequirements, SizeRequirements[], int[], int[])
     */
    public static void calculateAlignedPositions(final int allocated,
                              final SizeRequirements total,
                              final SizeRequirements[] children,
                              final int[] offsets,
                              final int[] spans) {

        int baseLineOffset = (int)(allocated * total.alignment);
        int childMinRequirement;

        for (int iChild = 0; iChild < children.length; iChild++) {
            childMinRequirement = children[iChild].minimum;

            if (children[iChild].alignment == 0) {
                offsets[iChild] = baseLineOffset;
                if (allocated - baseLineOffset > childMinRequirement) {
                    spans[iChild] = Math.min(children[iChild].maximum,
                                             allocated - baseLineOffset);
                } else {
                    spans[iChild] = childMinRequirement;
                }
                continue;
            }

            if (children[iChild].alignment == 1) {
                if (baseLineOffset < childMinRequirement) {
                    spans[iChild] = childMinRequirement;
                } else {
                    spans[iChild] = Math.min(children[iChild].maximum,
                                             baseLineOffset);
                }
                offsets[iChild] = baseLineOffset - spans[iChild];
                continue;
            }

            int upperSpan = (int)(baseLineOffset / children[iChild].alignment);
            int bottomSpan = (int)((allocated - baseLineOffset) / (1 - children[iChild].alignment));

            spans[iChild] = childMinRequirement;
            if (childMinRequirement <= upperSpan
                && childMinRequirement <= bottomSpan) {
                spans[iChild] = Math.min(children[iChild].maximum, Math
                    .min(upperSpan, bottomSpan));
            }
            offsets[iChild] = baseLineOffset
                              - (int)(spans[iChild] * children[iChild].alignment);
        }
    }

    private static void calculateTiledSpans(final int allocated,
                                            final SizeRequirements total,
                                            final SizeRequirements[] children,
                                            final int[] spans) {

        if (total.preferred <= allocated) {
            if (total.maximum <= allocated) {
                for (int iChild = 0; iChild < children.length; iChild++) {
                    spans[iChild] = children[iChild].maximum;
                }
            } else {
                int allocatedDelta = allocated - total.preferred;
                long maxDelta = 0;
                for (int iChild = 0; iChild < children.length; iChild++) {
                    maxDelta += children[iChild].maximum - children[iChild].preferred;
                }
                for (int iChild = 0; iChild < children.length; iChild++) {
                    spans[iChild] = children[iChild].preferred
                        + safeIntRatio(allocatedDelta,
                                       children[iChild].maximum
                                       - children[iChild].preferred,
                                       maxDelta);
                }
            }
        } else {
            if (total.minimum < allocated) {
                int allocatedDelta = allocated - total.minimum;
                long prefDelta = 0;
                for (int iChild = 0; iChild < children.length; iChild++) {
                    prefDelta += children[iChild].preferred - children[iChild].minimum;
                }
                for (int iChild = 0; iChild < children.length; iChild++) {
                    spans[iChild] = children[iChild].minimum
                        + safeIntRatio(allocatedDelta,
                                       children[iChild].preferred
                                       - children[iChild].minimum, prefDelta);
                }
            } else {
                for (int iChild = 0; iChild < children.length; iChild++) {
                    spans[iChild] = children[iChild].minimum;
                }
            }
        }
    }

    /**
     * Returns ratio of two integers multiplied by the third one.
     * Avoid "division by zero" problem if the divider is 0.
     * This function prevents wrong results when arguments are close
     * to Integer.MAX_VALUE
     *
     * @param item1 the first multiplier
     * @param item2 the second multiplier
     * @param item3 divisor
     * @return the ratio of (item1 * item2 / item3)
     */
    private static int safeIntRatio(final long item1, final long item2, final long item3) {
        return (item3 != 0) ? (int)((item1 * item2) / item3) : 0;
    }
}
TOP

Related Classes of org.apache.harmony.x.swing.SizeRequirementsHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.