Issue #1620 - Use Intrinsic Aspect Ratio for Images

https://bugzilla.mozilla.org/show_bug.cgi?id=1547231
https://bugzilla.mozilla.org/show_bug.cgi?id=1559094
https://bugzilla.mozilla.org/show_bug.cgi?id=1633434
https://bugzilla.mozilla.org/show_bug.cgi?id=1565690
https://bugzilla.mozilla.org/show_bug.cgi?id=1602047

Make use of Aspect Ratios in Image frames before Images are loaded.
- Check for width and height HTML properties and create a ratio with them.
- Overwrite HTML size values with actual image dimensions on load.
- Collapse any frames with srcless images.

Comments:
dom/html/nsGenericHTMLElement.cpp:1483
layout/generic/nsImageFrame.cpp:289
This commit is contained in:
Andy 2020-08-04 13:54:01 -07:00 committed by Roy Tam
commit be1f68f39e
17 changed files with 381 additions and 143 deletions

View file

@ -1449,29 +1449,59 @@ nsGenericHTMLElement::MapImageMarginAttributeInto(const nsMappedAttributes* aAtt
void
nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
nsRuleData* aData,
bool aMapAspectRatio)
{
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)))
return;
auto* aWidth = aAttributes->GetAttr(nsGkAtoms::width);
auto* aHeight = aAttributes->GetAttr(nsGkAtoms::height);
// width: value
nsCSSValue* width = aData->ValueForWidth();
if (width->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
if (value && value->Type() == nsAttrValue::eInteger)
width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
width->SetPercentValue(value->GetPercentValue());
if (aWidth) {
nsCSSValue* cWidth = aData->ValueForWidth();
if (cWidth->GetUnit() == eCSSUnit_Null) {
if (aWidth->Type() == nsAttrValue::eInteger)
cWidth->SetFloatValue((float)aWidth->GetIntegerValue(), eCSSUnit_Pixel);
else if (aWidth->Type() == nsAttrValue::ePercent)
cWidth->SetPercentValue(aWidth->GetPercentValue());
}
}
// height: value
nsCSSValue* height = aData->ValueForHeight();
if (height->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height);
if (value && value->Type() == nsAttrValue::eInteger)
height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel);
else if (value && value->Type() == nsAttrValue::ePercent)
height->SetPercentValue(value->GetPercentValue());
if (aHeight) {
nsCSSValue* cHeight = aData->ValueForHeight();
if (cHeight->GetUnit() == eCSSUnit_Null) {
if (aHeight->Type() == nsAttrValue::eInteger)
cHeight->SetFloatValue((float)aHeight->GetIntegerValue(), eCSSUnit_Pixel);
else if (aHeight->Type() == nsAttrValue::ePercent)
cHeight->SetPercentValue(aHeight->GetPercentValue());
}
}
// 2020-07-15 (RealityRipple) Much of this is a guess based on a few sources.
// Please go over this with a fine-tooth comb before production.
if (Preferences::GetBool("layout.css.width-and-height-map-to-aspect-ratio.enabled") &&
aMapAspectRatio && aWidth && aHeight) {
Maybe<double> w;
if (aWidth->Type() == nsAttrValue::eInteger) {
w.emplace(aWidth->GetIntegerValue());
} else if (aWidth->Type() == nsAttrValue::eDoubleValue) {
w.emplace(aWidth->GetDoubleValue());
}
Maybe<double> h;
if (aHeight->Type() == nsAttrValue::eInteger) {
h.emplace(aHeight->GetIntegerValue());
} else if (aHeight->Type() == nsAttrValue::eDoubleValue) {
h.emplace(aHeight->GetDoubleValue());
}
if (w && h && *w != 0 && *h != 0) {
nsCSSValue* aspect_ratio = aData->ValueForAspectRatio();
aspect_ratio->SetFloatValue((float(*w) / float(*h)), eCSSUnit_Number);
}
}
}