Bug 505115 - Part 10 - Implement the backface-visibility CSS property. r=dbaron

This commit is contained in:
Matt Woodrow 2011-08-03 15:04:22 +12:00
parent b4bfd8dd6a
commit 7a41f6a8a2
14 changed files with 85 additions and 4 deletions

View File

@ -51,7 +51,7 @@
* http://www.w3.org/TR/DOM-Level-2-Style
*/
[scriptable, uuid(1ca298f0-4eaf-4483-8aa2-587f392f84bb)]
[scriptable, uuid(63a0afd0-b322-11e0-aff2-0800200c9a66)]
interface nsIDOMCSS2Properties : nsISupports
{
attribute DOMString background;
@ -684,6 +684,9 @@ interface nsIDOMCSS2Properties : nsISupports
attribute DOMString MozPerspective;
// raises(DOMException) on setting
attribute DOMString MozBackfaceVisibility;
// raises(DOMException) on setting
attribute DOMString MozWindowShadow;
// raises(DOMException) on setting

View File

@ -392,3 +392,17 @@ gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
}
gfxPoint3D gfx3DMatrix::GetNormalVector() const
{
// Define a plane in transformed space as the transformations
// of 3 points on the z=0 screen plane.
gfxPoint3D a = Transform3D(gfxPoint3D(0, 0, 0));
gfxPoint3D b = Transform3D(gfxPoint3D(0, 1, 0));
gfxPoint3D c = Transform3D(gfxPoint3D(1, 0, 0));
// Convert to two vectors on the surface of the plane.
gfxPoint3D ab = b - a;
gfxPoint3D ac = c - a;
return ac.CrossProduct(ab);
}

View File

@ -134,6 +134,12 @@ public:
return temp;
}
/**
* Returns a unit vector that is perpendicular to the plane formed
* by transform the screen plane (z=0) by this matrix.
*/
gfxPoint3D GetNormalVector() const;
/**
* Check if matrix is singular (no inverse exists).
*/

View File

@ -2418,8 +2418,12 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
{
const gfx3DMatrix& newTransformMatrix =
GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
if (newTransformMatrix.IsSingular())
if (newTransformMatrix.IsSingular() ||
(mFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
newTransformMatrix.GetNormalVector().z <= 0.0)) {
return nsnull;
}
return aBuilder->LayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetList(),
@ -2487,8 +2491,12 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
float factor = nsPresContext::AppUnitsPerCSSPixel();
gfx3DMatrix matrix = GetTransform(factor);
if (matrix.IsSingular())
return;
/* If the matrix is singular, or a hidden backface is shown, we didn't hit anything. */
if (matrix.IsSingular() ||
(mFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
matrix.GetNormalVector().z <= 0.0)) {
return;
}
/* We want to go from transformed-space to regular space.
* Thus we have to invert the matrix, which normally does

View File

@ -858,6 +858,10 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
#define NS_STYLE_COLOR_INTERPOLATION_SRGB 1
#define NS_STYLE_COLOR_INTERPOLATION_LINEARRGB 2
// 3d Transforms - Backface visibility
#define NS_STYLE_BACKFACE_VISIBILITY_VISIBLE 1
#define NS_STYLE_BACKFACE_VISIBILITY_HIDDEN 0
/*****************************************************************************
* Constants for media features. *
*****************************************************************************/

View File

@ -2267,6 +2267,15 @@ CSS_PROP_DISPLAY(
nsnull,
offsetof(nsStyleDisplay, mChildPerspective),
eStyleAnimType_Coord)
CSS_PROP_DISPLAY(
-moz-backface-visibility,
backface_visibility,
CSS_PROP_DOMPROP_PREFIXED(BackfaceVisibility),
CSS_PROPERTY_PARSE_VALUE,
VARIANT_HK,
kBackfaceVisibilityKTable,
offsetof(nsStyleDisplay, mBackfaceVisibility),
eStyleAnimType_None)
CSS_PROP_POSITION(
top,
top,

View File

@ -581,6 +581,11 @@ const PRInt32 nsCSSProps::kAppearanceKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
const PRInt32 nsCSSProps::kBackfaceVisibilityKTable[] = {
eCSSKeyword_visible, NS_STYLE_BACKFACE_VISIBILITY_VISIBLE,
eCSSKeyword_hidden, NS_STYLE_BACKFACE_VISIBILITY_HIDDEN
};
const PRInt32 nsCSSProps::kBackgroundAttachmentKTable[] = {
eCSSKeyword_fixed, NS_STYLE_BG_ATTACHMENT_FIXED,
eCSSKeyword_scroll, NS_STYLE_BG_ATTACHMENT_SCROLL,

View File

@ -333,6 +333,7 @@ public:
static const PRInt32 kAnimationTimingFunctionKTable[];
static const PRInt32 kAppearanceKTable[];
static const PRInt32 kAzimuthKTable[];
static const PRInt32 kBackfaceVisibilityKTable[];
static const PRInt32 kBackgroundAttachmentKTable[];
static const PRInt32 kBackgroundInlinePolicyKTable[];
static const PRInt32 kBackgroundOriginKTable[];

View File

@ -954,6 +954,16 @@ nsComputedDOMStyle::DoGetMozPerspective()
return val;
}
nsIDOMCSSValue*
nsComputedDOMStyle::DoGetMozBackfaceVisibility()
{
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(GetStyleDisplay()->mBackfaceVisibility,
nsCSSProps::kBackfaceVisibilityKTable));
return val;
}
/* If the property is "none", hand back "none" wrapped in a value.
* Otherwise, compute the aggregate transform matrix and hands it back in a
* "matrix" wrapper.
@ -4378,6 +4388,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
COMPUTED_STYLE_MAP_ENTRY(animation_play_state, AnimationPlayState),
COMPUTED_STYLE_MAP_ENTRY(animation_timing_function, AnimationTimingFunction),
COMPUTED_STYLE_MAP_ENTRY(appearance, Appearance),
COMPUTED_STYLE_MAP_ENTRY(backface_visibility, MozBackfaceVisibility),
COMPUTED_STYLE_MAP_ENTRY(_moz_background_inline_policy, BackgroundInlinePolicy),
COMPUTED_STYLE_MAP_ENTRY(binding, Binding),
COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors, BorderBottomColors),

View File

@ -348,6 +348,7 @@ private:
nsIDOMCSSValue* DoGetMozTransform();
nsIDOMCSSValue* DoGetMozTransformOrigin();
nsIDOMCSSValue* DoGetMozPerspective();
nsIDOMCSSValue* DoGetMozBackfaceVisibility();
nsIDOMCSSValue* DoGetOrient();
/* User interface properties */

View File

@ -4489,6 +4489,11 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
SETCOORD_LAH | SETCOORD_INITIAL_ZERO | SETCOORD_NONE,
aContext, mPresContext, canStoreInRuleTree);
SetDiscrete(*aRuleData->ValueForBackfaceVisibility(),
display->mBackfaceVisibility, canStoreInRuleTree,
SETDSC_ENUMERATED, parentDisplay->mBackfaceVisibility,
NS_STYLE_BACKFACE_VISIBILITY_VISIBLE, 0, 0, 0, 0);
// orient: enum, inherit, initial
SetDiscrete(*aRuleData->ValueForOrient(),
display->mOrient, canStoreInRuleTree,

View File

@ -2034,6 +2034,7 @@ nsStyleDisplay::nsStyleDisplay()
mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin
mTransformOrigin[1].SetPercentValue(0.5f);
mChildPerspective.SetCoordValue(0);
mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE;
mOrient = NS_STYLE_ORIENT_HORIZONTAL;
mTransitions.AppendElement();
@ -2100,6 +2101,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
mTransformOrigin[0] = aSource.mTransformOrigin[0];
mTransformOrigin[1] = aSource.mTransformOrigin[1];
mChildPerspective = aSource.mChildPerspective;
mBackfaceVisibility = aSource.mBackfaceVisibility;
}
nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
@ -2165,6 +2167,9 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
if (mChildPerspective != aOther.mChildPerspective)
NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_ReflowFrame,
nsChangeHint_RepaintFrame));
if (mBackfaceVisibility != aOther.mBackfaceVisibility)
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
}
// Note: Our current behavior for handling changes to the

View File

@ -1516,6 +1516,7 @@ struct nsStyleDisplay {
const nsCSSValueList *mSpecifiedTransform; // [reset]
nsStyleCoord mTransformOrigin[2]; // [reset] percent, coord, calc
nsStyleCoord mChildPerspective; // [reset] coord
PRUint8 mBackfaceVisibility;
nsAutoTArray<nsTransition, 1> mTransitions; // [reset]
// The number of elements in mTransitions that are not from repeating

View File

@ -975,6 +975,14 @@ var gCSSProperties = {
other_values: [ "1000px", "500.2px", "-100px", "-27.2em" ],
invalid_values: [ "pants", "200" ]
},
"-moz-backface-visibility": {
domProp: "MozBackfaceVisibility",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "visible" ],
other_values: [ "hidden" ],
invalid_values: [ "collapse" ]
},
"-moz-user-focus": {
domProp: "MozUserFocus",
inherited: true,