From 5aadea5d7b0841530b4db4d6981f5d584f113e54 Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Tue, 18 Oct 2011 14:51:57 +0200 Subject: [PATCH] Support for unicode-bidi: -moz-isolate and -moz-plaintext in style system. Bug 613149, r=dbaron --- layout/base/nsBidiPresUtils.cpp | 35 +++++++++++-------------- layout/base/nsStyleConsts.h | 8 +++--- layout/style/nsCSSKeywordList.h | 2 ++ layout/style/nsCSSParser.cpp | 30 +++++++++++++++++++++ layout/style/nsCSSPropList.h | 5 ++-- layout/style/nsCSSProps.cpp | 2 ++ layout/style/nsCSSValue.cpp | 14 ++++++++++ layout/style/nsComputedDOMStyle.cpp | 18 ++++++++++--- layout/style/test/property_database.js | 4 +-- layout/svg/base/src/nsSVGGlyphFrame.cpp | 2 +- 10 files changed, 89 insertions(+), 31 deletions(-) diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 8ea48f81b99..2275cbb2ba4 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -523,7 +523,7 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) // TraverseFrames. const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset(); PRUnichar ch = 0; - if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) { + if (text->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_OVERRIDE) { const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { ch = kRLO; @@ -833,25 +833,20 @@ nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame, if (frame->IsFrameOfType(nsIFrame::eBidiInlineContainer)) { const nsStyleVisibility* vis = frame->GetStyleVisibility(); const nsStyleTextReset* text = frame->GetStyleTextReset(); - switch (text->mUnicodeBidi) { - case NS_STYLE_UNICODE_BIDI_NORMAL: - break; - case NS_STYLE_UNICODE_BIDI_EMBED: - if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { - ch = kRLE; - } - else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { - ch = kLRE; - } - break; - case NS_STYLE_UNICODE_BIDI_OVERRIDE: - if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { - ch = kRLO; - } - else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { - ch = kLRO; - } - break; + if (text->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_OVERRIDE) { + if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { + ch = kRLO; + } + else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { + ch = kLRO; + } + } else if (text->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_EMBED) { + if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { + ch = kRLE; + } + else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { + ch = kLRE; + } } // Add a dummy frame pointer representing a bidi control code before the diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index af8beec1e4f..68985b6471d 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -717,9 +717,11 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT 0 // See nsStyleText -#define NS_STYLE_UNICODE_BIDI_NORMAL 0 -#define NS_STYLE_UNICODE_BIDI_EMBED 1 -#define NS_STYLE_UNICODE_BIDI_OVERRIDE 2 +#define NS_STYLE_UNICODE_BIDI_NORMAL 0x0 +#define NS_STYLE_UNICODE_BIDI_EMBED 0x1 +#define NS_STYLE_UNICODE_BIDI_ISOLATE 0x2 +#define NS_STYLE_UNICODE_BIDI_OVERRIDE 0x4 +#define NS_STYLE_UNICODE_BIDI_PLAINTEXT 0x8 // See nsStyleTable (here for HTML 4.0 for now, should probably change to side flags) #define NS_STYLE_TABLE_FRAME_NONE 0 diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index 84da36216d3..4da4bb5bd8d 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -127,6 +127,7 @@ CSS_KEY(-moz-initial, _moz_initial) CSS_KEY(-moz-inline-box, _moz_inline_box) CSS_KEY(-moz-inline-grid, _moz_inline_grid) CSS_KEY(-moz-inline-stack, _moz_inline_stack) +CSS_KEY(-moz-isolate, _moz_isolate) CSS_KEY(-moz-japanese-formal, _moz_japanese_formal) CSS_KEY(-moz-japanese-informal, _moz_japanese_informal) CSS_KEY(-moz-kannada, _moz_kannada) @@ -158,6 +159,7 @@ CSS_KEY(-moz-none, _moz_none) CSS_KEY(-moz-oddtreerow, _moz_oddtreerow) CSS_KEY(-moz-oriya, _moz_oriya) CSS_KEY(-moz-persian, _moz_persian) +CSS_KEY(-moz-plaintext, _moz_plaintext) CSS_KEY(-moz-popup, _moz_popup) CSS_KEY(-moz-pull-down-menu, _moz_pull_down_menu) CSS_KEY(-moz-right, _moz_right) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 65b7672a4fe..f3cca27f623 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -519,6 +519,7 @@ protected: bool ParseTextDecoration(); bool ParseTextDecorationLine(nsCSSValue& aValue); bool ParseTextOverflow(nsCSSValue& aValue); + bool ParseUnicodeBidi(nsCSSValue& aValue); bool ParseShadowItem(nsCSSValue& aValue, bool aIsBoxShadow); bool ParseShadowList(nsCSSProperty aProperty); @@ -5604,6 +5605,8 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue, return ParseTextDecorationLine(aValue); case eCSSProperty_text_overflow: return ParseTextOverflow(aValue); + case eCSSProperty_unicode_bidi: + return ParseUnicodeBidi(aValue); default: NS_ABORT_IF_FALSE(false, "should not reach here"); return false; @@ -8186,6 +8189,33 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue) return true; } +bool +CSSParserImpl::ParseUnicodeBidi(nsCSSValue& aValue) +{ + if (ParseVariant(aValue, VARIANT_HK, nsCSSProps::kUnicodeBidiKTable)) { + if (eCSSUnit_Enumerated == aValue.GetUnit()) { + PRInt32 intValue = aValue.GetIntValue(); + // unicode-bidi can have either one or two values, but the only legal + // combination of two values is 'isolate bidi-override' + if (intValue == NS_STYLE_UNICODE_BIDI_ISOLATE || + intValue == NS_STYLE_UNICODE_BIDI_OVERRIDE) { + // look for more keywords + nsCSSValue second; + if (ParseEnum(second, nsCSSProps::kUnicodeBidiKTable)) { + intValue |= second.GetIntValue(); + if (intValue != (NS_STYLE_UNICODE_BIDI_ISOLATE | + NS_STYLE_UNICODE_BIDI_OVERRIDE)) { + return false; + } + } + aValue.SetIntValue(intValue, eCSSUnit_Enumerated); + } + } + return true; + } + return false; +} + bool CSSParserImpl::ParseTransitionProperty() { diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 198b92f6818..a075798442f 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -2360,8 +2360,9 @@ CSS_PROP_TEXTRESET( unicode-bidi, unicode_bidi, UnicodeBidi, - CSS_PROPERTY_PARSE_VALUE, - VARIANT_HK, + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_VALUE_PARSER_FUNCTION, + 0, kUnicodeBidiKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 3d918e1afd5..04040880a29 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1259,6 +1259,8 @@ const PRInt32 nsCSSProps::kUnicodeBidiKTable[] = { eCSSKeyword_normal, NS_STYLE_UNICODE_BIDI_NORMAL, eCSSKeyword_embed, NS_STYLE_UNICODE_BIDI_EMBED, eCSSKeyword_bidi_override, NS_STYLE_UNICODE_BIDI_OVERRIDE, + eCSSKeyword__moz_isolate, NS_STYLE_UNICODE_BIDI_ISOLATE, + eCSSKeyword__moz_plaintext, NS_STYLE_UNICODE_BIDI_PLAINTEXT, eCSSKeyword_UNKNOWN,-1 }; diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 348e3427255..5a575aa8259 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -869,6 +869,20 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const aResult); } } + else if (eCSSProperty_unicode_bidi == aProperty) { + PR_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0); + PRInt32 intValue = GetIntValue(); + if (NS_STYLE_UNICODE_BIDI_NORMAL == intValue) { + AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), + aResult); + } else { + nsStyleUtil::AppendBitmaskCSSValue( + aProperty, intValue, + NS_STYLE_UNICODE_BIDI_EMBED, + NS_STYLE_UNICODE_BIDI_PLAINTEXT, + aResult); + } + } else { const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, GetIntValue()); AppendASCIItoUTF16(name, aResult); diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 88e95e6b0ee..7d8aa1bbb3b 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2632,13 +2632,25 @@ nsComputedDOMStyle::DoGetDirection() return val; } +PR_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0); + nsIDOMCSSValue* nsComputedDOMStyle::DoGetUnicodeBidi() { nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); - val->SetIdent( - nsCSSProps::ValueToKeywordEnum(GetStyleTextReset()->mUnicodeBidi, - nsCSSProps::kUnicodeBidiKTable)); + PRInt32 intValue = GetStyleTextReset()->mUnicodeBidi; + + if (NS_STYLE_UNICODE_BIDI_NORMAL == intValue) { + val->SetIdent(eCSSKeyword_normal); + } else { + nsAutoString unicodeBidiString; + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_unicode_bidi, intValue, + NS_STYLE_UNICODE_BIDI_EMBED, + NS_STYLE_UNICODE_BIDI_PLAINTEXT, + unicodeBidiString); + val->SetString(unicodeBidiString); + } + return val; } diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index b9123bb60af..a34f5fa8769 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -2667,8 +2667,8 @@ var gCSSProperties = { inherited: false, type: CSS_TYPE_LONGHAND, initial_values: [ "normal" ], - other_values: [ "embed", "bidi-override" ], - invalid_values: [ "auto", "none" ] + other_values: [ "embed", "bidi-override", "-moz-isolate", "-moz-plaintext", "-moz-isolate bidi-override", "bidi-override -moz-isolate" ], + invalid_values: [ "auto", "none", "normal embed", "normal bidi-override", "normal -moz-isolate", "normal -moz-plaintext", "embed normal", "embed -moz-isolate", "embed bidi-override", "embed -moz-plaintext", "bidi-override normal", "bidi-override embed", "bidi-override -moz-plaintext", "-moz-isolate normal", "-moz-isolate embed", "-moz-isolate -moz-plaintext", "-moz-plaintext normal", "-moz-plaintext embed", "-moz-plaintext bidi-override", "-moz-plaintext -moz-isolate" ] }, "vertical-align": { domProp: "verticalAlign", diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp index 31c5bbe75b5..f661a3c16a6 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -1585,7 +1585,7 @@ nsSVGGlyphFrame::EnsureTextRun(float *aDrawScale, float *aMetricsScale, // Get the unicodeBidi property from the parent, because it doesn't // inherit - bool bidiOverride = (mParent->GetStyleTextReset()->mUnicodeBidi == + bool bidiOverride = !!(mParent->GetStyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_OVERRIDE); nsBidiLevel baseDirection = GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL ?