/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkFloatToDecimal.h"

#include <cfloat>
#include <climits>
#include <cmath>

//#include "SkTypes.h"
#include <cassert>
#define SkASSERT assert

// Return pow(10.0, e), optimized for common cases.
static double pow10(int e) {
    switch (e) {
        case 0:  return 1.0;  // common cases
        case 1:  return 10.0;
        case 2:  return 100.0;
        case 3:  return 1e+03;
        case 4:  return 1e+04;
        case 5:  return 1e+05;
        case 6:  return 1e+06;
        case 7:  return 1e+07;
        case 8:  return 1e+08;
        case 9:  return 1e+09;
        case 10: return 1e+10;
        case 11: return 1e+11;
        case 12: return 1e+12;
        case 13: return 1e+13;
        case 14: return 1e+14;
        case 15: return 1e+15;
        default:
            if (e > 15) {
                double value = 1e+15;
                while (e-- > 15) { value *= 10.0; }
                return value;
            } else {
                SkASSERT(e < 0);
                double value = 1.0;
                while (e++ < 0) { value /= 10.0; }
                return value;
            }
    }
}

namespace pdfium {
namespace skia {
/** Write a string into result, includeing a terminating '\0' (for
    unit testing).  Return strlen(result) (for SkWStream::write) The
    resulting string will be in the form /[-]?([0-9]*.)?[0-9]+/ and
    sscanf(result, "%f", &x) will return the original value iff the
    value is finite. This function accepts all possible input values.

    Motivation: "PDF does not support [numbers] in exponential format
    (such as 6.02e23)."  Otherwise, this function would rely on a
    sprintf-type function from the standard library. */
unsigned SkFloatToDecimal(float value, char result[kMaximumSkFloatToDecimalLength]) {
    /* The longest result is -FLT_MIN.
       We serialize it as "-.0000000000000000000000000000000000000117549435"
       which has 48 characters plus a terminating '\0'. */

    static_assert(kMaximumSkFloatToDecimalLength == 49, "");
    // 3 = '-', '.', and '\0' characters.
    // 9 = number of significant digits
    // abs(FLT_MIN_10_EXP) = number of zeros in FLT_MIN
    static_assert(kMaximumSkFloatToDecimalLength == 3 + 9 - FLT_MIN_10_EXP, "");

    /* section C.1 of the PDF1.4 spec (http://goo.gl/0SCswJ) says that
       most PDF rasterizers will use fixed-point scalars that lack the
       dynamic range of floats.  Even if this is the case, I want to
       serialize these (uncommon) very small and very large scalar
       values with enough precision to allow a floating-point
       rasterizer to read them in with perfect accuracy.
       Experimentally, rasterizers such as pdfium do seem to benefit
       from this.  Rasterizers that rely on fixed-point scalars should
       gracefully ignore these values that they can not parse. */
    char* output = &result[0];
    const char* const end = &result[kMaximumSkFloatToDecimalLength - 1];
    // subtract one to leave space for '\0'.

    /* This function is written to accept any possible input value,
       including non-finite values such as INF and NAN.  In that case,
       we ignore value-correctness and and output a syntacticly-valid
       number. */
    if (value == INFINITY) {
        value = FLT_MAX;  // nearest finite float.
    }
    if (value == -INFINITY) {
        value = -FLT_MAX;  // nearest finite float.
    }
    if (!std::isfinite(value) || value == 0.0f) {
        // NAN is unsupported in PDF.  Always output a valid number.
        // Also catch zero here, as a special case.
        *output++ = '0';
        *output = '\0';
        return static_cast<unsigned>(output - result);
    }
    if (value < 0.0) {
        *output++ = '-';
        value = -value;
    }
    SkASSERT(value >= 0.0f);

    int binaryExponent;
    (void)std::frexp(value, &binaryExponent);
    static const double kLog2 = 0.3010299956639812;  // log10(2.0);
    int decimalExponent = static_cast<int>(std::floor(kLog2 * binaryExponent));
    int decimalShift = decimalExponent - 8;
    double power = pow10(-decimalShift);
    SkASSERT(value * power <= (double)INT_MAX);
    int d = static_cast<int>(value * power + 0.5);
    // SkASSERT(value == (float)(d * pow(10.0, decimalShift)));
    SkASSERT(d <= 999999999);
    if (d > 167772159) {  // floor(pow(10,1+log10(1<<24)))
       // need one fewer decimal digits for 24-bit precision.
       decimalShift = decimalExponent - 7;
       // SkASSERT(power * 0.1 = pow10(-decimalShift));
       // recalculate to get rounding right.
       d = static_cast<int>(value * (power * 0.1) + 0.5);
       SkASSERT(d <= 99999999);
    }
    while (d % 10 == 0) {
        d /= 10;
        ++decimalShift;
    }
    SkASSERT(d > 0);
    // SkASSERT(value == (float)(d * pow(10.0, decimalShift)));
    unsigned char buffer[9]; // decimal value buffer.
    int bufferIndex = 0;
    do {
        buffer[bufferIndex++] = d % 10;
        d /= 10;
    } while (d != 0);
    SkASSERT(bufferIndex <= (int)sizeof(buffer) && bufferIndex > 0);
    if (decimalShift >= 0) {
        do {
            --bufferIndex;
            *output++ = '0' + buffer[bufferIndex];
        } while (bufferIndex);
        for (int i = 0; i < decimalShift; ++i) {
            *output++ = '0';
        }
    } else {
        int placesBeforeDecimal = bufferIndex + decimalShift;
        if (placesBeforeDecimal > 0) {
            while (placesBeforeDecimal-- > 0) {
                --bufferIndex;
                *output++ = '0' + buffer[bufferIndex];
            }
            *output++ = '.';
        } else {
            *output++ = '.';
            int placesAfterDecimal = -placesBeforeDecimal;
            while (placesAfterDecimal-- > 0) {
                *output++ = '0';
            }
        }
        while (bufferIndex > 0) {
            --bufferIndex;
            *output++ = '0' + buffer[bufferIndex];
            if (output == end) {
                break;  // denormalized: don't need extra precision.
                // Note: denormalized numbers will not have the same number of
                // significantDigits, but do not need them to round-trip.
            }
        }
    }
    SkASSERT(output <= end);
    *output = '\0';
    return static_cast<unsigned>(output - result);
}
}  // namespace skia
}  // namespace pdfium
