Bug 1038663 (part 6) - Allow percentage values for 'word-spacing'. r=heycam.

--HG--
extra : rebase_source : b7220e3c156dfef451e79b2911fbba7dec93850d
This commit is contained in:
Nicholas Nethercote 2015-11-05 17:25:46 -08:00
Родитель 90b8e844aa
Коммит b7bd8564c0
6 изменённых файлов: 33 добавлений и 13 удалений

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -1628,8 +1629,10 @@ LetterSpacing(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
return 0;
}
// This function converts non-coord values (e.g. percentages) to nscoord.
static nscoord
WordSpacing(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
WordSpacing(nsIFrame* aFrame, gfxTextRun* aTextRun,
const nsStyleText* aStyleText = nullptr)
{
if (aFrame->IsSVGText()) {
return 0;
@ -1642,6 +1645,11 @@ WordSpacing(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
if (eStyleUnit_Coord == coord.GetUnit()) {
return coord.GetCoordValue();
}
if (eStyleUnit_Percent == coord.GetUnit() ||
eStyleUnit_Calc == coord.GetUnit()) {
return nsRuleNode::ComputeCoordPercentCalc(coord,
GetSpaceWidthAppUnits(aTextRun));
}
return 0;
}
@ -1658,9 +1666,15 @@ GetSpacingFlags(nsIFrame* aFrame, const nsStyleText* aStyleText = nullptr)
const nsStyleCoord& ls = styleText->mLetterSpacing;
const nsStyleCoord& ws = styleText->mWordSpacing;
// It's possible to have a calc() value that computes to zero but for which
// IsDefinitelyZero() is false, in which case we'll return
// TEXT_ENABLE_SPACING unnecessarily. That's ok because such cases are likely
// to be rare, and avoiding TEXT_ENABLE_SPACING is just an optimization.
bool nonStandardSpacing =
(eStyleUnit_Coord == ls.GetUnit() && ls.GetCoordValue() != 0) ||
(eStyleUnit_Coord == ws.GetUnit() && ws.GetCoordValue() != 0);
(eStyleUnit_Coord == ws.GetUnit() && ws.GetCoordValue() != 0) ||
(eStyleUnit_Percent == ws.GetUnit() && ws.GetPercentValue() != 0) ||
(eStyleUnit_Calc == ws.GetUnit() && !ws.GetCalcValue()->IsDefinitelyZero());
return nonStandardSpacing ? gfxTextRunFactory::TEXT_ENABLE_SPACING : 0;
}
@ -2902,7 +2916,7 @@ public:
mFrame(aFrame), mStart(aStart), mTempIterator(aStart),
mTabWidths(nullptr), mTabWidthsAnalyzedLimit(0),
mLength(aLength),
mWordSpacing(WordSpacing(aFrame, aTextStyle)),
mWordSpacing(WordSpacing(aFrame, mTextRun, aTextStyle)),
mLetterSpacing(LetterSpacing(aFrame, aTextStyle)),
mHyphenWidth(-1),
mOffsetFromBlockOriginForTabs(aOffsetFromBlockOriginForTabs),
@ -2927,7 +2941,7 @@ public:
mFrame(aFrame), mStart(aStart), mTempIterator(aStart),
mTabWidths(nullptr), mTabWidthsAnalyzedLimit(0),
mLength(aFrame->GetContentLength()),
mWordSpacing(WordSpacing(aFrame)),
mWordSpacing(WordSpacing(aFrame, mTextRun)),
mLetterSpacing(LetterSpacing(aFrame)),
mHyphenWidth(-1),
mOffsetFromBlockOriginForTabs(0),

Просмотреть файл

@ -3623,9 +3623,10 @@ CSS_PROP_TEXT(
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK,
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
CSS_PROPERTY_STORES_CALC,
"",
VARIANT_HL | VARIANT_NORMAL | VARIANT_CALC,
VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC,
nullptr,
offsetof(nsStyleText, mWordSpacing),
eStyleAnimType_Coord)

Просмотреть файл

@ -4408,7 +4408,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
parentText->mWordBreak,
NS_STYLE_WORDBREAK_NORMAL, 0, 0, 0, 0);
// word-spacing: normal, length, inherit
// word-spacing: normal, length, percent, inherit
const nsCSSValue* wordSpacingValue = aRuleData->ValueForWordSpacing();
if (wordSpacingValue->GetUnit() == eCSSUnit_Normal) {
// Do this so that "normal" computes to 0px, as the CSS 2.1 spec requires.
@ -4416,8 +4416,8 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
} else {
SetCoord(*aRuleData->ValueForWordSpacing(),
text->mWordSpacing, parentText->mWordSpacing,
SETCOORD_LH | SETCOORD_INITIAL_ZERO |
SETCOORD_CALC_LENGTH_ONLY | SETCOORD_UNSET_INHERIT,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO |
SETCOORD_STORE_CALC | SETCOORD_UNSET_INHERIT,
aContext, mPresContext, conditions);
}

Просмотреть файл

@ -90,6 +90,10 @@ public:
bool operator!=(const CalcValue& aOther) const {
return !(*this == aOther);
}
// If this returns true the value is definitely zero. It it returns false
// it might be zero. So it's best used for conservative optimization.
bool IsDefinitelyZero() const { return mLength == 0 && mPercent == 0; }
};
// Reference counted calc() value. This is the type that is used to store

Просмотреть файл

@ -1736,7 +1736,7 @@ struct nsStyleText {
uint8_t mControlCharacterVisibility; // [inherited] see nsStyleConsts.h
int32_t mTabSize; // [inherited] see nsStyleConsts.h
nsStyleCoord mWordSpacing; // [inherited] coord
nsStyleCoord mWordSpacing; // [inherited] coord, percent, calc
nsStyleCoord mLetterSpacing; // [inherited] coord, normal
nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
nsStyleCoord mTextIndent; // [inherited] coord, percent, calc

Просмотреть файл

@ -3737,10 +3737,11 @@ var gCSSProperties = {
initial_values: [ "normal", "0", "0px", "-0em",
"calc(-0px)", "calc(0em)"
],
other_values: [ "1em", "2px", "-3px",
other_values: [ "1em", "2px", "-3px", "0%", "50%", "-120%",
"calc(1em)", "calc(1em + 3px)",
"calc(15px / 2)", "calc(15px/2)",
"calc(-2em)"
"calc(-2em)", "calc(0% + 0px)",
"calc(-10%/2 - 1em)"
],
invalid_values: [],
quirks_values: { "5": "5px" },