summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--layout/generic/nsTextFrame.cpp74
-rw-r--r--layout/style/nsCSSPropList.h2
-rw-r--r--layout/style/nsComputedDOMStyle.cpp2
-rw-r--r--layout/style/nsRuleNode.cpp96
-rw-r--r--layout/style/nsStyleStruct.cpp4
-rw-r--r--layout/style/nsStyleStruct.h2
-rw-r--r--layout/style/test/property_database.js6
7 files changed, 124 insertions, 62 deletions
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index 4decdc8ec9..663002ba13 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -3176,7 +3176,7 @@ public:
return mFontMetrics;
}
- void CalcTabWidths(Range aTransformedRange);
+ void CalcTabWidths(Range aTransformedRange, gfxFloat aTabWidth);
const gfxSkipCharsIterator& GetEndHint() { return mTempIterator; }
@@ -3362,6 +3362,28 @@ CanAddSpacingAfter(const gfxTextRun* aTextRun, uint32_t aOffset)
aTextRun->IsLigatureGroupStart(aOffset + 1);
}
+static gfxFloat
+ComputeTabWidthAppUnits(nsIFrame* aFrame, gfxTextRun* aTextRun)
+{
+ const nsStyleText* textStyle = aFrame->StyleText();
+ if (textStyle->mTabSize.GetUnit() != eStyleUnit_Factor) {
+ nscoord w = textStyle->mTabSize.GetCoordValue();
+ MOZ_ASSERT(w >= 0);
+ return w;
+ }
+
+ gfxFloat spaces = textStyle->mTabSize.GetFactorValue();
+ MOZ_ASSERT(spaces >= 0);
+
+ // Round the space width when converting to appunits the same way
+ // textruns do.
+ gfxFloat spaceWidthAppUnits =
+ NS_round(GetFirstFontMetrics(aTextRun->GetFontGroup(),
+ aTextRun->IsVertical()).spaceWidth *
+ aTextRun->GetAppUnitsPerDevUnit());
+ return spaces * spaceWidthAppUnits;
+}
+
void
PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
bool aIgnoreTabs)
@@ -3409,17 +3431,16 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
}
}
- // Ignore tab spacing rather than computing it, if the tab size is 0
- if (!aIgnoreTabs)
- aIgnoreTabs = mFrame->StyleText()->mTabSize == 0;
-
// Now add tab spacing, if there is any
if (!aIgnoreTabs) {
- CalcTabWidths(aRange);
- if (mTabWidths) {
- mTabWidths->ApplySpacing(aSpacing,
- aRange.start - mStart.GetSkippedOffset(),
- aRange.Length());
+ gfxFloat tabWidth = ComputeTabWidthAppUnits(mFrame, mTextRun);
+ if (tabWidth > 0) {
+ CalcTabWidths(aRange);
+ if (mTabWidths) {
+ mTabWidths->ApplySpacing(aSpacing,
+ aRange.start - mStart.GetSkippedOffset(),
+ aRange.Length());
+ }
}
}
@@ -3442,33 +3463,23 @@ PropertyProvider::GetSpacingInternal(Range aRange, Spacing* aSpacing,
}
}
-static gfxFloat
-ComputeTabWidthAppUnits(nsIFrame* aFrame, const gfxTextRun* aTextRun)
-{
- // Get the number of spaces from CSS -moz-tab-size
- const nsStyleText* textStyle = aFrame->StyleText();
-
- return textStyle->mTabSize * GetSpaceWidthAppUnits(aTextRun);
-}
-
// aX and the result are in whole appunits.
static gfxFloat
AdvanceToNextTab(gfxFloat aX, nsIFrame* aFrame,
- const gfxTextRun* aTextRun, gfxFloat* aCachedTabWidth)
+ gfxTextRun* aTextRun, gfxFloat* aTabWidth)
{
- if (*aCachedTabWidth < 0) {
- *aCachedTabWidth = ComputeTabWidthAppUnits(aFrame, aTextRun);
- }
// Advance aX to the next multiple of *aCachedTabWidth. We must advance
// by at least 1 appunit.
// XXX should we make this 1 CSS pixel?
- return ceil((aX + 1)/(*aCachedTabWidth))*(*aCachedTabWidth);
+ return ceil((aX + 1)/ aTabWidth) * aTabWidth;
}
void
-PropertyProvider::CalcTabWidths(Range aRange)
+PropertyProvider::CalcTabWidths(Range aRange, gfxFloat aTabWidth)
{
+ MOZ_ASSERT(aTabWidth > 0);
+
if (!mTabWidths) {
if (mReflowing && !mLineContainer) {
// Intrinsic width computation does its own tab processing. We
@@ -3503,7 +3514,6 @@ PropertyProvider::CalcTabWidths(Range aRange)
NS_ASSERTION(mReflowing,
"We need precomputed tab widths, but don't have enough.");
- gfxFloat tabWidth = -1;
for (uint32_t i = tabsEnd; i < aRange.end; ++i) {
Spacing spacing;
GetSpacingInternal(Range(i, i + 1), &spacing, true);
@@ -3525,7 +3535,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
mFrame->SetProperty(TabWidthProperty(), mTabWidths);
}
double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
- mFrame, mTextRun, &tabWidth);
+ mFrame, mTextRun, aTabWidth);
mTabWidths->mWidths.AppendElement(TabWidth(i - startOffset,
NSToIntRound(nextTab - mOffsetFromBlockOriginForTabs)));
mOffsetFromBlockOriginForTabs = nextTab;
@@ -8319,9 +8329,12 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext,
PropertyProvider::Spacing spacing;
provider.GetSpacing(Range(i, i + 1), &spacing);
aData->mCurrentLine += nscoord(spacing.mBefore);
+ if (tabWidth < 0) {
+ tabWidth = ComputeTabWidthAppUnits(this, textRun);
+ }
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, this,
- textRun, &tabWidth);
+ textRun, tabWidth);
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
wordStart = i + 1;
} else if (i < flowEndInTextRun ||
@@ -8478,9 +8491,12 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext,
PropertyProvider::Spacing spacing;
provider.GetSpacing(Range(i, i + 1), &spacing);
aData->mCurrentLine += nscoord(spacing.mBefore);
+ if (tabWidth < 0) {
+ tabWidth = ComputeTabWidthAppUnits(this, textRun);
+ }
gfxFloat afterTab =
AdvanceToNextTab(aData->mCurrentLine, this,
- textRun, &tabWidth);
+ textRun, tabWidth);
aData->mCurrentLine = nscoord(afterTab + spacing.mAfter);
lineStart = i + 1;
} else if (preformattedNewline) {
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index 4f79db5a55..5c5cfcda1c 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3885,7 +3885,7 @@ CSS_PROP_TEXT(
CSS_PROPERTY_PARSE_VALUE |
CSS_PROPERTY_VALUE_NONNEGATIVE,
"",
- VARIANT_HI,
+ VARIANT_INHERIT | VARIANT_LNCALC,
nullptr,
offsetof(nsStyleText, mTabSize),
eStyleAnimType_Discrete)
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index 080932af23..748f990b77 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4013,7 +4013,7 @@ already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetTabSize()
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
- val->SetNumber(StyleText()->mTabSize);
+ SetValueToCoord(val, StyleText()->mTabSize, true);
return val.forget();
}
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index c32369e9bb..e41857db76 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -4507,20 +4507,20 @@ TruncateStringToSingleGrapheme(nsAString& aStr)
}
}
-struct LineHeightCalcObj
+struct LengthNumberCalcObj
{
- float mLineHeight;
+ float LengthNumberCalcObj;
bool mIsNumber;
};
-struct SetLineHeightCalcOps : public css::NumbersAlreadyNormalizedOps
+struct LengthNumberCalcOps : public css::FloatCoeffsAlreadyNormalizedOps
{
- typedef LineHeightCalcObj result_type;
+ typedef LengthNumberCalcObj result_type;
nsStyleContext* const mStyleContext;
nsPresContext* const mPresContext;
RuleNodeCacheConditions& mConditions;
- SetLineHeightCalcOps(nsStyleContext* aStyleContext,
+ LengthNumberCalcOps(nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
: mStyleContext(aStyleContext),
@@ -4535,15 +4535,15 @@ struct SetLineHeightCalcOps : public css::NumbersAlreadyNormalizedOps
{
MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber);
- LineHeightCalcObj result;
+ LengthNumberCalcObj result;
result.mIsNumber = aValue1.mIsNumber;
if (aCalcFunction == eCSSUnit_Calc_Plus) {
- result.mLineHeight = aValue1.mLineHeight + aValue2.mLineHeight;
+ result.mValue = aValue1.mValue + aValue2.mValue;
return result;
}
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Minus,
"unexpected unit");
- result.mLineHeight = aValue1.mLineHeight - aValue2.mLineHeight;
+ result.mValue = aValue1.mValue - aValue2.mValue;
return result;
}
@@ -4553,9 +4553,9 @@ struct SetLineHeightCalcOps : public css::NumbersAlreadyNormalizedOps
{
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L,
"unexpected unit");
- LineHeightCalcObj result;
+ LengthNumberCalcObj result;
result.mIsNumber = aValue2.mIsNumber;
- result.mLineHeight = aValue1 * aValue2.mLineHeight;
+ result.mValue = aValue1 * aValue2.mValue;
return result;
}
@@ -4563,39 +4563,69 @@ struct SetLineHeightCalcOps : public css::NumbersAlreadyNormalizedOps
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
result_type aValue1, float aValue2)
{
- LineHeightCalcObj result;
+ LengthNumberCalcObj result;
result.mIsNumber = aValue1.mIsNumber;
if (aCalcFunction == eCSSUnit_Calc_Times_R) {
- result.mLineHeight = aValue1.mLineHeight * aValue2;
+ result.mValue = aValue1.mValue * aValue2;
return result;
}
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Divided,
"unexpected unit");
- result.mLineHeight = aValue1.mLineHeight / aValue2;
+ result.mValue = aValue1.mValue / aValue2;
return result;
}
result_type ComputeLeafValue(const nsCSSValue& aValue)
{
- LineHeightCalcObj result;
+ LengthNumberCalcObj result;
if (aValue.IsLengthUnit()) {
result.mIsNumber = false;
- result.mLineHeight = CalcLength(aValue, mStyleContext,
+ result.mValue = CalcLength(aValue, mStyleContext,
+ mPresContext, mConditions);
+ }
+ else if (eCSSUnit_Number == aValue.GetUnit()) {
+ result.mIsNumber = true;
+ result.mValue = aValue.GetFloatValue();
+ } else {
+ MOZ_ASSERT(false, "unexpected value");
+ result.mIsNumber = true;
+ result.mValue = 1.0f;
+ }
+
+ return result;
+ }
+};
+
+struct SetLineHeightCalcOps : public LengthNumberCalcOps
+{
+ SetLineHeightCalcOps(nsStyleContext* aStyleContext,
+ nsPresContext* aPresContext,
+ RuleNodeCacheConditions& aConditions)
+ : LengthNumberCalcOps(aStyleContext, aPresContext, aConditions)
+ {
+ }
+
+ result_type ComputeLeafValue(const nsCSSValue& aValue)
+ {
+ LengthNumberCalcObj result;
+ if (aValue.IsLengthUnit()) {
+ result.mIsNumber = false;
+ result.mValue = CalcLength(aValue, mStyleContext,
mPresContext, mConditions);
}
else if (eCSSUnit_Percent == aValue.GetUnit()) {
mConditions.SetUncacheable();
result.mIsNumber = false;
nscoord fontSize = mStyleContext->StyleFont()->mFont.size;
- result.mLineHeight = fontSize * aValue.GetPercentValue();
+ result.mValue = fontSize * aValue.GetPercentValue();
}
else if (eCSSUnit_Number == aValue.GetUnit()) {
result.mIsNumber = true;
- result.mLineHeight = aValue.GetFloatValue();
+ result.mValue = aValue.GetFloatValue();
} else {
MOZ_ASSERT(false, "unexpected value");
result.mIsNumber = true;
- result.mLineHeight = 1.0f;
+ result.mValue = 1.0f;
}
return result;
@@ -4619,11 +4649,25 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
mPresContext, text->*aField, conditions);
};
- // tab-size: integer, inherit
- SetValue(*aRuleData->ValueForTabSize(),
- text->mTabSize, conditions,
- SETVAL_INTEGER | SETVAL_UNSET_INHERIT, parentText->mTabSize,
- NS_STYLE_TABSIZE_INITIAL);
+ // tab-size: number, length, calc, inherit
+ const nsCSSValue* tabSizeValue = aRuleData->ValueForTabSize();
+ if (tabSizeValue->GetUnit() == eCSSUnit_Initial) {
+ text->mTabSize = nsStyleCoord(float(NS_STYLE_TABSIZE_INITIAL), eStyleUnit_Factor);
+ } else if (eCSSUnit_Calc == tabSizeValue->GetUnit()) {
+ LengthNumberCalcOps ops(aContext, mPresContext, conditions);
+ LengthNumberCalcObj obj = css::ComputeCalc(*tabSizeValue, ops);
+ float value = obj.mValue < 0 ? 0 : obj.mValue;
+ if (obj.mIsNumber) {
+ text->mTabSize.SetFactorValue(value);
+ } else {
+ text->mTabSize.SetCoordValue(
+ NSToCoordRoundWithClamp(value));
+ }
+ } else {
+ SetCoord(*tabSizeValue, text->mTabSize, parentText->mTabSize,
+ SETCOORD_LH | SETCOORD_FACTOR | SETCOORD_UNSET_INHERIT,
+ aContext, mPresContext, conditions);
+ }
// letter-spacing: normal, length, inherit
SetCoord(*aRuleData->ValueForLetterSpacing(),
@@ -4666,12 +4710,12 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
}
else if (eCSSUnit_Calc == lineHeightValue->GetUnit()) {
SetLineHeightCalcOps ops(aContext, mPresContext, conditions);
- LineHeightCalcObj obj = css::ComputeCalc(*lineHeightValue, ops);
+ LengthNumberCalcObj obj = css::ComputeCalc(*lineHeightValue, ops);
if (obj.mIsNumber) {
- text->mLineHeight.SetFactorValue(obj.mLineHeight);
+ text->mLineHeight.SetFactorValue(obj.mValue);
} else {
text->mLineHeight.SetCoordValue(
- NSToCoordRoundWithClamp(obj.mLineHeight));
+ NSToCoordRoundWithClamp(obj.mValue));
}
}
else {
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index c0ea9c256c..073cfcd5e7 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3806,10 +3806,10 @@ nsStyleText::nsStyleText(StyleStructContext aContext)
, mControlCharacterVisibility(nsCSSParser::ControlCharVisibilityDefault())
, mTextEmphasisStyle(NS_STYLE_TEXT_EMPHASIS_STYLE_NONE)
, mTextRendering(NS_STYLE_TEXT_RENDERING_AUTO)
- , mTabSize(NS_STYLE_TABSIZE_INITIAL)
, mTextEmphasisColor(StyleComplexColor::CurrentColor())
, mWebkitTextFillColor(StyleComplexColor::CurrentColor())
, mWebkitTextStrokeColor(StyleComplexColor::CurrentColor())
+ , mTabSize(float(NS_STYLE_TABSIZE_INITIAL), eStyleUnit_Factor)
, mWordSpacing(0, nsStyleCoord::CoordConstructor)
, mLetterSpacing(eStyleUnit_Normal)
, mLineHeight(eStyleUnit_Normal)
@@ -3844,10 +3844,10 @@ nsStyleText::nsStyleText(const nsStyleText& aSource)
, mTextEmphasisPosition(aSource.mTextEmphasisPosition)
, mTextEmphasisStyle(aSource.mTextEmphasisStyle)
, mTextRendering(aSource.mTextRendering)
- , mTabSize(aSource.mTabSize)
, mTextEmphasisColor(aSource.mTextEmphasisColor)
, mWebkitTextFillColor(aSource.mWebkitTextFillColor)
, mWebkitTextStrokeColor(aSource.mWebkitTextStrokeColor)
+ , mTabSize(aSource.mTabSize)
, mWordSpacing(aSource.mWordSpacing)
, mLetterSpacing(aSource.mLetterSpacing)
, mLineHeight(aSource.mLineHeight)
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 88000c722a..831808edfd 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2087,11 +2087,11 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText
uint8_t mTextEmphasisPosition; // [inherited] see nsStyleConsts.h
uint8_t mTextEmphasisStyle; // [inherited] see nsStyleConsts.h
uint8_t mTextRendering; // [inherited] see nsStyleConsts.h
- int32_t mTabSize; // [inherited] see nsStyleConsts.h
mozilla::StyleComplexColor mTextEmphasisColor; // [inherited]
mozilla::StyleComplexColor mWebkitTextFillColor; // [inherited]
mozilla::StyleComplexColor mWebkitTextStrokeColor; // [inherited]
+ nsStyleCoord mTabSize; // [inherited] coord, factor, calc
nsStyleCoord mWordSpacing; // [inherited] coord, percent, calc
nsStyleCoord mLetterSpacing; // [inherited] coord, normal
nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index d647b57161..5182dd89c1 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -2032,8 +2032,10 @@ var gCSSProperties = {
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "8" ],
- other_values: [ "0", "3", "99", "12000" ],
- invalid_values: [ "-1", "-808", "3.0", "17.5" ]
+ other_values: [ "0", "2.5", "3", "99", "12000", "0px", "1em",
+ "calc(1px + 1em)", "calc(1px - 2px)", "calc(1 + 1)", "calc(-2.5)" ],
+ invalid_values: [ "9%", "calc(9% + 1px)", "calc(1 + 1em)", "-1", "-808",
+ "auto" ]
},
"-moz-text-size-adjust": {
domProp: "MozTextSizeAdjust",