Changeset 12078 in josm for trunk/src


Ignore:
Timestamp:
2017-05-07T00:13:32+02:00 (7 years ago)
Author:
michael2402
Message:

See #14485: Fix and test MapCSS sorting.

This adds support for real floating point values instead of fixed point decimal and tests for corner cases (infinity, nan, ...)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java

    r12058 r12078  
    112112
    113113            order <<= 24;
    114             order |= floatToFixed(this.style.majorZIndex, 24, 8);
     114            order |= floatToFixed(this.style.majorZIndex, 24);
    115115
    116116            // selected on top of member of selected on top of unselected
     
    120120
    121121            order <<= 24;
    122             order |= floatToFixed(this.style.zIndex, 24, 8);
     122            order |= floatToFixed(this.style.zIndex, 24);
    123123
    124124            order <<= 1;
     
    132132
    133133        /**
    134          * Converts a float to a fixed pointdecimal so that the order stays the same.
     134         * Converts a float to a fixed point decimal so that the order stays the same.
    135135         *
    136136         * @param number The float to convert
    137137         * @param totalBits
    138          *            Total number of bits. 1 sign bit, then the bits before the
    139          *            decimal point, then those after.
    140          * @param afterDecimalBits
    141          *            Number of fixed bits after the decimal point.
     138         *            Total number of bits. 1 sign bit. There should be at least 15 bits.
    142139         * @return The float converted to an integer.
    143140         */
    144         private static long floatToFixed(double number, int totalBits, int afterDecimalBits) {
    145             long value = (long) (number * (1L << afterDecimalBits));
    146             long highestBitMask = 1L << totalBits - 1;
    147             long valueMask = highestBitMask - 1;
    148             long signBit = number < 0 ? 0 : highestBitMask;
    149             return signBit | value & valueMask;
     141        protected static long floatToFixed(float number, int totalBits) {
     142            long value = Float.floatToIntBits(number) & 0xffffffffL;
     143
     144            boolean negative = (value & 0x80000000L) != 0;
     145            // Invert the sign bit, so that negative numbers are lower
     146            value ^= 0x80000000L;
     147            // Now do the shift. Do it before accounting for negative numbers (symetry)
     148            if (totalBits < 32) {
     149                value >>= (32 - totalBits);
     150            }
     151            // positive numbers are sorted now. Negative ones the wrong way.
     152            if (negative) {
     153                // Negative number: re-map it
     154                value = (1L << (totalBits - 1)) - value;
     155            }
     156            return value;
    150157        }
    151158
Note: See TracChangeset for help on using the changeset viewer.