blob: 2367147dbac3131e111296fe5b2f83b283ee398c [file] [log] [blame]
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/CSSResolutionUnits.h"
#include "core/layout/api/LayoutViewItem.h"
#include "core/style/ComputedStyle.h"
namespace blink {
CSSToLengthConversionData::FontSizes::FontSizes(float em,
float rem,
const Font* font)
: em_(em), rem_(rem), font_(font) {
// FIXME: Improve RAII of StyleResolverState to use const Font&.
DCHECK(font_);
}
CSSToLengthConversionData::FontSizes::FontSizes(const ComputedStyle* style,
const ComputedStyle* root_style)
: FontSizes(style->ComputedFontSize(),
root_style ? root_style->ComputedFontSize() : 1.0f,
&style->GetFont()) {}
float CSSToLengthConversionData::FontSizes::Ex() const {
DCHECK(font_);
const SimpleFontData* font_data = font_->PrimaryFont();
DCHECK(font_data);
// FIXME: We have a bug right now where the zoom will be applied twice to EX
// units. We really need to compute EX using fontMetrics for the original
// specifiedSize and not use our actual constructed layoutObject font.
if (!font_data || !font_data->GetFontMetrics().HasXHeight())
return em_ / 2.0f;
return font_data->GetFontMetrics().XHeight();
}
float CSSToLengthConversionData::FontSizes::Ch() const {
DCHECK(font_);
const SimpleFontData* font_data = font_->PrimaryFont();
DCHECK(font_data);
return font_data ? font_data->GetFontMetrics().ZeroWidth() : 0;
}
CSSToLengthConversionData::ViewportSize::ViewportSize(
const LayoutViewItem& layout_view_item)
: size_(!layout_view_item.IsNull()
? layout_view_item.ViewportSizeForViewportUnits()
: DoubleSize()) {}
CSSToLengthConversionData::CSSToLengthConversionData(
const ComputedStyle* style,
const FontSizes& font_sizes,
const ViewportSize& viewport_size,
float zoom)
: style_(style),
font_sizes_(font_sizes),
viewport_size_(viewport_size),
zoom_(clampTo<float>(zoom, std::numeric_limits<float>::denorm_min())) {}
CSSToLengthConversionData::CSSToLengthConversionData(
const ComputedStyle* style,
const ComputedStyle* root_style,
const LayoutViewItem& layout_view_item,
float zoom)
: CSSToLengthConversionData(style,
FontSizes(style, root_style),
ViewportSize(layout_view_item),
zoom) {}
double CSSToLengthConversionData::ViewportWidthPercent() const {
// FIXME: Remove style_ from this class. Plumb viewport and rem unit
// information through as output parameters on functions involved in length
// resolution.
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasViewportUnits(true);
return viewport_size_.Width() / 100;
}
double CSSToLengthConversionData::ViewportHeightPercent() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasViewportUnits(true);
return viewport_size_.Height() / 100;
}
double CSSToLengthConversionData::ViewportMinPercent() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasViewportUnits(true);
return std::min(viewport_size_.Width(), viewport_size_.Height()) / 100;
}
double CSSToLengthConversionData::ViewportMaxPercent() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasViewportUnits(true);
return std::max(viewport_size_.Width(), viewport_size_.Height()) / 100;
}
float CSSToLengthConversionData::RemFontSize() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasRemUnits();
return font_sizes_.Rem();
}
double CSSToLengthConversionData::ZoomedComputedPixels(
double value,
CSSPrimitiveValue::UnitType type) const {
// The logic in this function is duplicated in MediaValues::ComputeLength()
// because MediaValues::ComputeLength() needs nearly identical logic, but we
// haven't found a way to make ZoomedComputedPixels() more generic (to solve
// both cases) without hurting performance.
switch (type) {
case CSSPrimitiveValue::UnitType::kPixels:
case CSSPrimitiveValue::UnitType::kUserUnits:
return value * Zoom();
case CSSPrimitiveValue::UnitType::kCentimeters:
return value * kCssPixelsPerCentimeter * Zoom();
case CSSPrimitiveValue::UnitType::kMillimeters:
return value * kCssPixelsPerMillimeter * Zoom();
case CSSPrimitiveValue::UnitType::kQuarterMillimeters:
return value * kCssPixelsPerQuarterMillimeter * Zoom();
case CSSPrimitiveValue::UnitType::kInches:
return value * kCssPixelsPerInch * Zoom();
case CSSPrimitiveValue::UnitType::kPoints:
return value * kCssPixelsPerPoint * Zoom();
case CSSPrimitiveValue::UnitType::kPicas:
return value * kCssPixelsPerPica * Zoom();
case CSSPrimitiveValue::UnitType::kViewportWidth:
return value * ViewportWidthPercent() * Zoom();
case CSSPrimitiveValue::UnitType::kViewportHeight:
return value * ViewportHeightPercent() * Zoom();
case CSSPrimitiveValue::UnitType::kViewportMin:
return value * ViewportMinPercent() * Zoom();
case CSSPrimitiveValue::UnitType::kViewportMax:
return value * ViewportMaxPercent() * Zoom();
// We do not apply the zoom factor when we are computing the value of the
// font-size property. The zooming for font sizes is much more complicated,
// since we have to worry about enforcing the minimum font size preference
// as well as enforcing the implicit "smart minimum."
case CSSPrimitiveValue::UnitType::kEms:
case CSSPrimitiveValue::UnitType::kQuirkyEms:
return value * EmFontSize();
case CSSPrimitiveValue::UnitType::kExs:
return value * ExFontSize();
case CSSPrimitiveValue::UnitType::kRems:
return value * RemFontSize();
case CSSPrimitiveValue::UnitType::kChs:
return value * ChFontSize();
default:
NOTREACHED();
return 0;
}
}
} // namespace blink