From 03504b26844e1c1e52b1f2d885f60a5614174907 Mon Sep 17 00:00:00 2001 From: John Daggett Date: Mon, 19 Aug 2013 19:26:44 +0900 Subject: [PATCH] Bug 875250 - implement CSS parsing of text-orientation, text-combine-horizontal properties. r=dholbert --- layout/style/nsCSSKeywordList.h | 3 ++ layout/style/nsCSSParser.cpp | 40 +++++++++++++++++++++++++ layout/style/nsCSSPropList.h | 41 +++++++++++++++++++------- layout/style/nsCSSProps.cpp | 14 +++++++++ layout/style/nsCSSProps.h | 2 ++ layout/style/nsCSSValue.cpp | 14 +++++++++ layout/style/nsComputedDOMStyle.cpp | 33 +++++++++++++++++++++ layout/style/nsComputedDOMStyle.h | 2 ++ layout/style/nsRuleNode.cpp | 13 ++++++++ layout/style/nsStyleConsts.h | 12 ++++++++ layout/style/nsStyleStruct.cpp | 9 ++++++ layout/style/nsStyleStruct.h | 2 ++ layout/style/test/property_database.js | 18 +++++++++++ 13 files changed, 193 insertions(+), 10 deletions(-) diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index a2538d271e99..6074ca12a8e8 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -242,6 +242,7 @@ CSS_KEY(deg, deg) CSS_KEY(diagonal-fractions, diagonal_fractions) CSS_KEY(dialog, dialog) CSS_KEY(difference, difference) +CSS_KEY(digits, digits) CSS_KEY(disabled, disabled) CSS_KEY(disc, disc) CSS_KEY(discretionary-ligatures, discretionary_ligatures) @@ -460,6 +461,7 @@ CSS_KEY(semi-expanded, semi_expanded) CSS_KEY(separate, separate) CSS_KEY(sepia, sepia) CSS_KEY(show, show) +CSS_KEY(sideways, sideways) CSS_KEY(simplified, simplified) CSS_KEY(skew, skew) CSS_KEY(skewx, skewx) @@ -531,6 +533,7 @@ CSS_KEY(upper-alpha, upper_alpha) CSS_KEY(upper-latin, upper_latin) CSS_KEY(upper-roman, upper_roman) CSS_KEY(uppercase, uppercase) +CSS_KEY(upright, upright) CSS_KEY(vertical, vertical) CSS_KEY(vertical-lr, vertical_lr) CSS_KEY(vertical-rl, vertical_rl) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 61156046af16..f236cbcaed49 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -509,6 +509,7 @@ protected: bool ParseSize(); bool ParseTextDecoration(); bool ParseTextDecorationLine(nsCSSValue& aValue); + bool ParseTextCombineHorizontal(nsCSSValue& aValue); bool ParseTextOverflow(nsCSSValue& aValue); bool ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow); @@ -6608,6 +6609,8 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue, return ParseMarks(aValue); case eCSSProperty_text_decoration_line: return ParseTextDecorationLine(aValue); + case eCSSProperty_text_combine_horizontal: + return ParseTextCombineHorizontal(aValue); case eCSSProperty_text_overflow: return ParseTextOverflow(aValue); default: @@ -9669,6 +9672,43 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue) return true; } +bool +CSSParserImpl::ParseTextCombineHorizontal(nsCSSValue& aValue) +{ + if (!ParseVariant(aValue, VARIANT_HK, + nsCSSProps::kTextCombineHorizontalKTable)) { + return false; + } + + // if 'digits', need to check for an explicit number [2, 3, 4] + if (eCSSUnit_Enumerated == aValue.GetUnit() && + aValue.GetIntValue() == NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_2) { + if (!GetToken(true)) { + return true; + } + if (mToken.mType == eCSSToken_Number && mToken.mIntegerValid) { + switch (mToken.mInteger) { + case 2: // already set, nothing to do + break; + case 3: + aValue.SetIntValue(NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_3, + eCSSUnit_Enumerated); + break; + case 4: + aValue.SetIntValue(NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_4, + eCSSUnit_Enumerated); + break; + default: + // invalid digits value + return false; + } + } else { + UngetToken(); + } + } + return true; +} + /////////////////////////////////////////////////////// // transform Parsing Implementation diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 122571af8557..feb03a594b9b 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2643,16 +2643,6 @@ CSS_PROP_VISIBILITY( kPointerEventsKTable, offsetof(nsStyleVisibility, mPointerEvents), eStyleAnimType_EnumU8) -CSS_PROP_VISIBILITY( - writing-mode, - writing_mode, - WritingMode, - CSS_PROPERTY_PARSE_VALUE, - "layout.css.vertical-text.enabled", - VARIANT_HK, - kWritingModeKTable, - offsetof(nsStyleVisibility, mWritingMode), - eStyleAnimType_EnumU8) CSS_PROP_DISPLAY( position, position, @@ -2745,6 +2735,17 @@ CSS_PROP_SHORTHAND( TextDecoration, CSS_PROPERTY_PARSE_FUNCTION, "") +CSS_PROP_TEXT( + text-combine-horizontal, + text_combine_horizontal, + TextCombineHorizontal, + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_VALUE_PARSER_FUNCTION, + "layout.css.vertical-text.enabled", + 0, + kTextCombineHorizontalKTable, + offsetof(nsStyleText, mTextCombineHorizontal), + eStyleAnimType_EnumU8) CSS_PROP_TEXTRESET( -moz-text-decoration-color, text_decoration_color, @@ -2794,6 +2795,16 @@ CSS_PROP_TEXT( nullptr, offsetof(nsStyleText, mTextIndent), eStyleAnimType_Coord) +CSS_PROP_TEXT( + text-orientation, + text_orientation, + TextOrientation, + CSS_PROPERTY_PARSE_VALUE, + "layout.css.vertical-text.enabled", + VARIANT_HK, + kTextOrientationKTable, + offsetof(nsStyleText, mTextOrientation), + eStyleAnimType_EnumU8) CSS_PROP_TEXTRESET( text-overflow, text_overflow, @@ -3130,6 +3141,16 @@ CSS_PROP_TEXT( kHyphensKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) +CSS_PROP_VISIBILITY( + writing-mode, + writing_mode, + WritingMode, + CSS_PROPERTY_PARSE_VALUE, + "layout.css.vertical-text.enabled", + VARIANT_HK, + kWritingModeKTable, + offsetof(nsStyleVisibility, mWritingMode), + eStyleAnimType_EnumU8) CSS_PROP_POSITION( z-index, z_index, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index c5b2777b3e3f..4ff692147912 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1438,6 +1438,13 @@ const int32_t nsCSSProps::kTextAlignLastKTable[] = { eCSSKeyword_UNKNOWN,-1 }; +const int32_t nsCSSProps::kTextCombineHorizontalKTable[] = { + eCSSKeyword_none, NS_STYLE_TEXT_COMBINE_HORIZ_NONE, + eCSSKeyword_all, NS_STYLE_TEXT_COMBINE_HORIZ_ALL, + eCSSKeyword_digits, NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_2, // w/o number ==> 2 + eCSSKeyword_UNKNOWN,-1 +}; + const int32_t nsCSSProps::kTextDecorationLineKTable[] = { eCSSKeyword_none, NS_STYLE_TEXT_DECORATION_LINE_NONE, eCSSKeyword_underline, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, @@ -1458,6 +1465,13 @@ const int32_t nsCSSProps::kTextDecorationStyleKTable[] = { eCSSKeyword_UNKNOWN,-1 }; +const int32_t nsCSSProps::kTextOrientationKTable[] = { + eCSSKeyword_auto, NS_STYLE_TEXT_ORIENTATION_AUTO, + eCSSKeyword_upright, NS_STYLE_TEXT_ORIENTATION_UPRIGHT, + eCSSKeyword_sideways, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS, + eCSSKeyword_UNKNOWN, -1 +}; + const int32_t nsCSSProps::kTextOverflowKTable[] = { eCSSKeyword_clip, NS_STYLE_TEXT_OVERFLOW_CLIP, eCSSKeyword_ellipsis, NS_STYLE_TEXT_OVERFLOW_ELLIPSIS, diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 3611cacb4d8b..4ad7a7cf03a7 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -530,8 +530,10 @@ public: static const int32_t kTableLayoutKTable[]; static const int32_t kTextAlignKTable[]; static const int32_t kTextAlignLastKTable[]; + static const int32_t kTextCombineHorizontalKTable[]; static const int32_t kTextDecorationLineKTable[]; static const int32_t kTextDecorationStyleKTable[]; + static const int32_t kTextOrientationKTable[]; static const int32_t kTextOverflowKTable[]; static const int32_t kTextTransformKTable[]; static const int32_t kTransitionTimingFunctionKTable[]; diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 8024e541e385..8f8a7fd0da78 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -833,6 +833,20 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const int32_t intValue = GetIntValue(); switch(aProperty) { + + case eCSSProperty_text_combine_horizontal: + if (intValue <= NS_STYLE_TEXT_COMBINE_HORIZ_ALL) { + AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), + aResult); + } else if (intValue == NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_2) { + aResult.AppendLiteral("digits 2"); + } else if (intValue == NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_3) { + aResult.AppendLiteral("digits 3"); + } else { + aResult.AppendLiteral("digits 4"); + } + break; + case eCSSProperty_text_decoration_line: if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) { AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 62dabbc49347..737159aff7bc 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2644,6 +2644,27 @@ nsComputedDOMStyle::DoGetTextAlignLast() return val; } +CSSValue* +nsComputedDOMStyle::DoGetTextCombineHorizontal() +{ + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + uint8_t tch = StyleText()->mTextCombineHorizontal; + + if (tch <= NS_STYLE_TEXT_COMBINE_HORIZ_ALL) { + val->SetIdent( + nsCSSProps::ValueToKeywordEnum(tch, + nsCSSProps::kTextCombineHorizontalKTable)); + } else if (tch <= NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_2) { + val->SetString(NS_LITERAL_STRING("digits 2")); + } else if (tch <= NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_3) { + val->SetString(NS_LITERAL_STRING("digits 3")); + } else { + val->SetString(NS_LITERAL_STRING("digits 4")); + } + + return val; +} + CSSValue* nsComputedDOMStyle::DoGetTextDecoration() { @@ -2750,6 +2771,16 @@ nsComputedDOMStyle::DoGetTextIndent() return val; } +CSSValue* +nsComputedDOMStyle::DoGetTextOrientation() +{ + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; + val->SetIdent( + nsCSSProps::ValueToKeywordEnum(StyleText()->mTextOrientation, + nsCSSProps::kTextOrientationKTable)); + return val; +} + CSSValue* nsComputedDOMStyle::DoGetTextOverflow() { @@ -5050,8 +5081,10 @@ nsComputedDOMStyle::GetQueryablePropertyMap(uint32_t* aLength) //// COMPUTED_STYLE_MAP_ENTRY(size, Size), COMPUTED_STYLE_MAP_ENTRY(table_layout, TableLayout), COMPUTED_STYLE_MAP_ENTRY(text_align, TextAlign), + COMPUTED_STYLE_MAP_ENTRY(text_combine_horizontal, TextCombineHorizontal), COMPUTED_STYLE_MAP_ENTRY(text_decoration, TextDecoration), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(text_indent, TextIndent), + COMPUTED_STYLE_MAP_ENTRY(text_orientation, TextOrientation), COMPUTED_STYLE_MAP_ENTRY(text_overflow, TextOverflow), COMPUTED_STYLE_MAP_ENTRY(text_shadow, TextShadow), COMPUTED_STYLE_MAP_ENTRY(text_transform, TextTransform), diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 6610af2f279a..dc5369c19bfb 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -308,11 +308,13 @@ private: mozilla::dom::CSSValue* DoGetLineHeight(); mozilla::dom::CSSValue* DoGetTextAlign(); mozilla::dom::CSSValue* DoGetTextAlignLast(); + mozilla::dom::CSSValue* DoGetTextCombineHorizontal(); mozilla::dom::CSSValue* DoGetTextDecoration(); mozilla::dom::CSSValue* DoGetTextDecorationColor(); mozilla::dom::CSSValue* DoGetTextDecorationLine(); mozilla::dom::CSSValue* DoGetTextDecorationStyle(); mozilla::dom::CSSValue* DoGetTextIndent(); + mozilla::dom::CSSValue* DoGetTextOrientation(); mozilla::dom::CSSValue* DoGetTextOverflow(); mozilla::dom::CSSValue* DoGetTextTransform(); mozilla::dom::CSSValue* DoGetTextShadow(); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index eb8168ffe588..7a075804307a 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -3987,6 +3987,19 @@ nsRuleNode::ComputeTextData(void* aStartStruct, NS_STYLE_TEXT_SIZE_ADJUST_NONE, // none value 0, 0); + // text-orientation: enum, inherit, initial + SetDiscrete(*aRuleData->ValueForTextOrientation(), text->mTextOrientation, + canStoreInRuleTree, SETDSC_ENUMERATED, + parentText->mTextOrientation, + NS_STYLE_TEXT_ORIENTATION_AUTO, 0, 0, 0, 0); + + // text-combine-horizontal: enum, inherit, initial + SetDiscrete(*aRuleData->ValueForTextCombineHorizontal(), + text->mTextCombineHorizontal, + canStoreInRuleTree, SETDSC_ENUMERATED, + parentText->mTextCombineHorizontal, + NS_STYLE_TEXT_COMBINE_HORIZ_NONE, 0, 0, 0, 0); + COMPUTE_END_INHERITED(Text, text) } diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 0b9c1c9d05bb..503f5887895b 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -749,6 +749,18 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_TEXT_SIZE_ADJUST_NONE 0 #define NS_STYLE_TEXT_SIZE_ADJUST_AUTO 1 +// See nsStyleText +#define NS_STYLE_TEXT_ORIENTATION_AUTO 0 +#define NS_STYLE_TEXT_ORIENTATION_UPRIGHT 1 +#define NS_STYLE_TEXT_ORIENTATION_SIDEWAYS 2 + +// See nsStyleText +#define NS_STYLE_TEXT_COMBINE_HORIZ_NONE 0 +#define NS_STYLE_TEXT_COMBINE_HORIZ_ALL 1 +#define NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_2 2 +#define NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_3 3 +#define NS_STYLE_TEXT_COMBINE_HORIZ_DIGITS_4 4 + // See nsStyleText #define NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT 0 diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 8e17deb2c448..9de5e2d3288b 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2918,6 +2918,8 @@ nsStyleText::nsStyleText(void) mWordWrap = NS_STYLE_WORDWRAP_NORMAL; mHyphens = NS_STYLE_HYPHENS_MANUAL; mTextSizeAdjust = NS_STYLE_TEXT_SIZE_ADJUST_AUTO; + mTextOrientation = NS_STYLE_TEXT_ORIENTATION_AUTO; + mTextCombineHorizontal = NS_STYLE_TEXT_COMBINE_HORIZ_NONE; mLetterSpacing.SetNormalValue(); mLineHeight.SetNormalValue(); @@ -2937,6 +2939,8 @@ nsStyleText::nsStyleText(const nsStyleText& aSource) mWordWrap(aSource.mWordWrap), mHyphens(aSource.mHyphens), mTextSizeAdjust(aSource.mTextSizeAdjust), + mTextOrientation(aSource.mTextOrientation), + mTextCombineHorizontal(aSource.mTextCombineHorizontal), mTabSize(aSource.mTabSize), mWordSpacing(aSource.mWordSpacing), mLetterSpacing(aSource.mLetterSpacing), @@ -2960,6 +2964,10 @@ nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const return NS_STYLE_HINT_FRAMECHANGE; } + if (mTextCombineHorizontal != aOther.mTextCombineHorizontal) { + return nsChangeHint_ReconstructFrame; + } + if ((mTextAlign != aOther.mTextAlign) || (mTextAlignLast != aOther.mTextAlignLast) || (mTextTransform != aOther.mTextTransform) || @@ -2968,6 +2976,7 @@ nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const (mWordWrap != aOther.mWordWrap) || (mHyphens != aOther.mHyphens) || (mTextSizeAdjust != aOther.mTextSizeAdjust) || + (mTextOrientation != aOther.mTextOrientation) || (mLetterSpacing != aOther.mLetterSpacing) || (mLineHeight != aOther.mLineHeight) || (mTextIndent != aOther.mTextIndent) || diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 0d986cc958dc..7885965d4bf2 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1315,6 +1315,8 @@ struct nsStyleText { uint8_t mWordWrap; // [inherited] see nsStyleConsts.h uint8_t mHyphens; // [inherited] see nsStyleConsts.h uint8_t mTextSizeAdjust; // [inherited] see nsStyleConsts.h + uint8_t mTextOrientation; // [inherited] see nsStyleConsts.h + uint8_t mTextCombineHorizontal; // [inherited] see nsStyleConsts.h int32_t mTabSize; // [inherited] see nsStyleConsts.h nscoord mWordSpacing; // [inherited] diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index f95023e74b7c..c3c7b84c0bc8 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4253,6 +4253,24 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { initial_values: [ "horizontal-tb" ], other_values: [ "vertical-lr", "vertical-rl" ], invalid_values: [ "10px", "30%", "justify", "auto", "1em" ] + }, + "text-orientation": { + domProp: "textOrientation", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: [ "upright", "sideways" ], + invalid_values: [ "none", "3em" ] + }, + "text-combine-horizontal": { + domProp: "textCombineHorizontal", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "none" ], + other_values: [ "all", "digits", "digits 2", "digits 3", "digits 4", "digits 3" ], + invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0", + "digits 12", "none 3", "digits 3.1415", "digits3", + "digits 3 all", "digits foo", "digits all", "digits 3.0" ] } }; for (var prop in verticalTextProperties) {