blob: 71ebb903877f5bf1aed8dc0642ad84df6a48d2f3 [file] [log] [blame]
// 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.
#include "CSSLength.h"
#include "DFCommon.h"
#include <stdio.h>
#include <string.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Units //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
#define POINTS_PER_PC 12
#define POINTS_PER_PX 0.75
#define POINTS_PER_IN 72
#define POINTS_PER_CM (POINTS_PER_IN/2.54)
#define POINTS_PER_MM (POINTS_PER_CM/10)
double convertBetweenUnits(double value, Units from, Units to)
{
if (from == to)
return value;
double valueInPoints = 0;
switch (from) {
case UnitsIn: valueInPoints = value * POINTS_PER_IN; break;
case UnitsCm: valueInPoints = value * POINTS_PER_CM; break;
case UnitsMm: valueInPoints = value * POINTS_PER_MM; break;
case UnitsPt: valueInPoints = value; break;
case UnitsPc: valueInPoints = value * POINTS_PER_PC; break;
case UnitsPx: valueInPoints = value * POINTS_PER_PX; break;
default: return 1;
}
switch (to) {
case UnitsIn: return valueInPoints / POINTS_PER_IN;
case UnitsCm: return valueInPoints / POINTS_PER_CM;
case UnitsMm: return valueInPoints / POINTS_PER_MM;
case UnitsPt: return valueInPoints;
case UnitsPc: return valueInPoints / POINTS_PER_PC;
case UnitsPx: return valueInPoints / POINTS_PER_PX;
default: return 1;
}
}
static Units stringToUnits(const char *str)
{
if (str == NULL)
return UnitsUnspecified;
else if (!strcmp(str,"%"))
return UnitsPct;
else if (!strcmp(str,"in"))
return UnitsIn;
else if (!strcmp(str,"cm"))
return UnitsCm;
else if (!strcmp(str,"mm"))
return UnitsMm;
else if (!strcmp(str,"pt"))
return UnitsPt;
else if (!strcmp(str,"pc"))
return UnitsPc;
else if (!strcmp(str,"px"))
return UnitsPx;
else
return UnitsUnspecified;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// CSSLength //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
CSSLength CSSLengthNull = { 0, UnitsUnspecified, 0, 0 };
CSSLength CSSLengthFromValue(double value, Units units)
{
CSSLength length;
length.value = value;
length.units = units;
length.valueValid = 1;
length.unitsValid = (units != UnitsUnspecified);
return length;
}
CSSLength CSSLengthFromString(const char *str)
{
if (str == NULL)
return CSSLengthNull;
double svalue;
char sunits[11];
if (sscanf(str,"%lf%10s",&svalue,sunits) != 2)
return CSSLengthNull;;
CSSLength length;
length.valueValid = 1;
length.value = svalue;
length.units = stringToUnits(sunits);
length.unitsValid = (length.units != UnitsUnspecified);
return length;
}
int CSSLengthIsValid(CSSLength length)
{
return (length.valueValid && length.unitsValid);
}
int CSSLengthIsPercentage(CSSLength length)
{
return (CSSLengthIsValid(length) && (length.units == UnitsPct));
}
int CSSLengthIsAbsolute(CSSLength length)
{
if (!CSSLengthIsValid(length))
return 0;
switch (length.units) {
case UnitsIn:
case UnitsCm:
case UnitsMm:
case UnitsPt:
case UnitsPc:
case UnitsPx:
return 1;
default:
return 0;
}
}
double CSSLengthToAbsolute(CSSLength length, double total, double valueUnits)
{
switch (length.units) {
case UnitsIn:
case UnitsCm:
case UnitsMm:
case UnitsPt:
case UnitsPc:
case UnitsPx:
return convertBetweenUnits(length.value,length.units,valueUnits);
case UnitsPct:
return (length.value/100.0)*total;
default:
return 0;
}
}
double CSSLengthToPts(CSSLength length, double total)
{
return CSSLengthToAbsolute(length,total,UnitsPt);
}