5#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
13#include "core/fxcrt/compiler_specific.h"
14#include "core/fxcrt/span.h"
18constexpr unsigned kMaximumSkFloatToDecimalLength = 49;
102unsigned SkFloatToDecimal(
104 pdfium::span<
char, kMaximumSkFloatToDecimalLength> output) {
108 static_assert(kMaximumSkFloatToDecimalLength == 49,
"");
113 static_assert(kMaximumSkFloatToDecimalLength == 3 + 9 - FLT_MIN_10_EXP,
"");
124 char* output_ptr = output.data();
127 const char*
const end = output.last(1u).data();
133 if (value == INFINITY) {
136 if (value == -INFINITY) {
140 if (!
std::isfinite(value) || value == 0.0f) {
145 return static_cast<
unsigned>(output_ptr - output.data());
154 (
void)
std::frexp(value, &binaryExponent);
155 static const double kLog2 = 0.3010299956639812;
156 int decimalExponent =
static_cast<
int>(
std::floor(kLog2 * binaryExponent));
157 int decimalShift = decimalExponent - 8;
158 double power = pow10(-decimalShift);
159 assert(value * power <= (
double)INT_MAX);
160 int d =
static_cast<
int>(value * power + 0.5);
165 decimalShift = decimalExponent - 7;
168 d =
static_cast<
int>(value * (power * 0.1) + 0.5);
171 while (d % 10 == 0) {
177 unsigned char buffer[9];
180 buffer[bufferIndex++] = d % 10;
183 assert(bufferIndex <= (
int)
sizeof(buffer) && bufferIndex > 0);
184 if (decimalShift >= 0) {
187 *output_ptr++ =
'0' + buffer[bufferIndex];
188 }
while (bufferIndex);
189 for (
int i = 0; i < decimalShift; ++i) {
193 int placesBeforeDecimal = bufferIndex + decimalShift;
194 if (placesBeforeDecimal > 0) {
195 while (placesBeforeDecimal-- > 0) {
197 *output_ptr++ =
'0' + buffer[bufferIndex];
202 int placesAfterDecimal = -placesBeforeDecimal;
203 while (placesAfterDecimal-- > 0) {
207 while (bufferIndex > 0) {
209 *output_ptr++ =
'0' + buffer[bufferIndex];
210 if (output_ptr == end) {
217 assert(output_ptr <= end);
219 return static_cast<
unsigned>(output_ptr - output.data());
226 char buffer[kMaximumSkFloatToDecimalLength];
227 unsigned size = SkFloatToDecimal(value, buffer);
228 stream.write(buffer, size);
243 WriteFloat(stream, point.x) <<
" ";
244 WriteFloat(stream, point.y);
std::ostream & WritePoint(std::ostream &stream, const CFX_PointF &point)
std::ostream & WriteFloat(std::ostream &stream, float value)
std::ostream & WriteRect(std::ostream &stream, const CFX_FloatRect &rect)
std::ostream & WriteMatrix(std::ostream &stream, const CFX_Matrix &matrix)
CFX_PTemplate< float > CFX_PointF