diff --git a/gfx/2d/Matrix.cpp b/gfx/2d/Matrix.cpp index 0e1d8c8bc9..ec553b6495 100644 --- a/gfx/2d/Matrix.cpp +++ b/gfx/2d/Matrix.cpp @@ -272,6 +272,81 @@ Rect Matrix4x4::ProjectRectBounds(const Rect& aRect, const Rect &aClip) const return Rect(min_x, min_y, max_x - min_x, max_y - min_y); } +size_t +Matrix4x4::TransformAndClipRect(const Rect& aRect, const Rect& aClip, + Point* aVerts) const +{ + // Initialize a double-buffered array of points in homogenous space with + // the input rectangle, aRect. + Point4D points[2][kTransformAndClipRectMaxVerts]; + Point4D* dstPoint = points[0]; + *dstPoint++ = *this * Point4D(aRect.x, aRect.y, 0, 1); + *dstPoint++ = *this * Point4D(aRect.XMost(), aRect.y, 0, 1); + *dstPoint++ = *this * Point4D(aRect.XMost(), aRect.YMost(), 0, 1); + *dstPoint++ = *this * Point4D(aRect.x, aRect.YMost(), 0, 1); + + // View frustum clipping planes are described as normals originating from + // the 0,0,0,0 origin. + Point4D planeNormals[4]; + planeNormals[0] = Point4D(1.0, 0.0, 0.0, -aClip.x); + planeNormals[1] = Point4D(-1.0, 0.0, 0.0, aClip.XMost()); + planeNormals[2] = Point4D(0.0, 1.0, 0.0, -aClip.y); + planeNormals[3] = Point4D(0.0, -1.0, 0.0, aClip.YMost()); + + // Iterate through each clipping plane and clip the polygon. + // In each pass, we double buffer, alternating between points[0] and + // points[1]. + for (int plane=0; plane < 4; plane++) { + planeNormals[plane].Normalize(); + + Point4D* srcPoint = points[plane & 1]; + Point4D* srcPointEnd = dstPoint; + dstPoint = points[~plane & 1]; + + Point4D* prevPoint = srcPointEnd - 1; + float prevDot = planeNormals[plane].DotProduct(*prevPoint); + while (srcPoint < srcPointEnd) { + float nextDot = planeNormals[plane].DotProduct(*srcPoint); + + if ((nextDot >= 0.0) != (prevDot >= 0.0)) { + // An intersection with the clipping plane has been detected. + // Interpolate to find the intersecting point and emit it. + float t = -prevDot / (nextDot - prevDot); + *dstPoint++ = *srcPoint * t + *prevPoint * (1.0 - t); + } + + if (nextDot >= 0.0) { + // Emit any source points that are on the positive side of the + // clipping plane. + *dstPoint++ = *srcPoint; + } + + prevPoint = srcPoint++; + prevDot = nextDot; + } + } + + size_t dstPointCount = 0; + size_t srcPointCount = dstPoint - points[0]; + for (Point4D* srcPoint = points[0]; srcPoint < points[0] + srcPointCount; srcPoint++) { + + Point p; + if (srcPoint->w == 0.0) { + // If a point lies on the intersection of the clipping planes at + // (0,0,0,0), we must avoid a division by zero w component. + p = Point(0.0, 0.0); + } else { + p = srcPoint->As2DPoint(); + } + // Emit only unique points + if (dstPointCount == 0 || p != aVerts[dstPointCount - 1]) { + aVerts[dstPointCount++] = p; + } + } + + return dstPointCount; +} + bool Matrix4x4::Invert() { diff --git a/gfx/2d/Matrix.h b/gfx/2d/Matrix.h index fc9af4bd0e..c316c0986f 100644 --- a/gfx/2d/Matrix.h +++ b/gfx/2d/Matrix.h @@ -485,6 +485,19 @@ public: Rect ProjectRectBounds(const Rect& aRect, const Rect &aClip) const; + /** + * TransformAndClipRect projects a rectangle and clips against view frustum + * clipping planes in homogenous space so that its projected vertices are + * constrained within the 2d rectangle passed in aClip. + * The resulting vertices are populated in aVerts. aVerts must be + * pre-allocated to hold at least kTransformAndClipRectMaxVerts Points. + * The vertex count is returned by TransformAndClipRect. It is possible to + * emit fewer that 3 vertices, indicating that aRect will not be visible + * within aClip. + */ + size_t TransformAndClipRect(const Rect& aRect, const Rect& aClip, Point* aVerts) const; + static const size_t kTransformAndClipRectMaxVerts = 32; + static Matrix4x4 From2D(const Matrix &aMatrix) { Matrix4x4 matrix; matrix._11 = aMatrix._11; diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index a8ae58b9fd..3d0de9ac9c 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -297,10 +297,24 @@ public: * drawn is specified by aEffectChain. aRect is the quad to draw, in user space. * aTransform transforms from user space to screen space. If texture coords are * required, these will be in the primary effect in the effect chain. + * aVisibleRect is used to determine which edges should be antialiased, + * without applying the effect to the inner edges of a tiled layer. */ virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain& aEffectChain, - gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) = 0; + gfx::Float aOpacity, const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) = 0; + + /** + * Overload of DrawQuad, with aVisibleRect defaulted to the value of aRect. + * Use this when you are drawing a single quad that is not part of a tiled + * layer. + */ + void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, + const EffectChain& aEffectChain, + gfx::Float aOpacity, const gfx::Matrix4x4& aTransform) { + DrawQuad(aRect, aClipRect, aEffectChain, aOpacity, aTransform, aRect); + } /* * Clear aRect on current render target. diff --git a/gfx/layers/LayerMetricsWrapper.h b/gfx/layers/LayerMetricsWrapper.h index 4c35b7bbc1..e00301fd9b 100644 --- a/gfx/layers/LayerMetricsWrapper.h +++ b/gfx/layers/LayerMetricsWrapper.h @@ -337,7 +337,7 @@ public: return mLayer->GetVisibleRegion(); } nsIntRegion region = mLayer->GetVisibleRegion(); - region.Transform(gfx::To3DMatrix(mLayer->GetTransform())); + region.Transform(mLayer->GetTransform()); return region; } diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index f78a55d50c..65afab2dd7 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -586,7 +586,7 @@ public: protected: uint64_t mLayerRef; uint32_t mColor; - nsIntSize mSize; + IntSize mSize; }; class DebugGLLayersData final: public DebugGLData { diff --git a/gfx/layers/LayerSorter.cpp b/gfx/layers/LayerSorter.cpp index c6e3d97009..08dd91a794 100644 --- a/gfx/layers/LayerSorter.cpp +++ b/gfx/layers/LayerSorter.cpp @@ -10,7 +10,6 @@ #include // for getenv #include "DirectedGraph.h" // for DirectedGraph #include "Layers.h" // for Layer -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxLineSegment.h" // for gfxLineSegment #include "gfxPoint.h" // for gfxPoint #include "gfxQuad.h" // for gfxQuad @@ -41,11 +40,11 @@ enum LayerSortOrder { * * point = normal . (p0 - l0) / normal . l */ -static gfxFloat RecoverZDepth(const gfx3DMatrix& aTransform, const gfxPoint& aPoint) +static gfxFloat RecoverZDepth(const Matrix4x4& aTransform, const gfxPoint& aPoint) { const Point3D l(0, 0, 1); Point3D l0 = Point3D(aPoint.x, aPoint.y, 0); - Point3D p0 = aTransform.Transform3D(Point3D(0, 0, 0)); + Point3D p0 = aTransform * Point3D(0, 0, 0); Point3D normal = aTransform.GetNormalVector(); gfxFloat n = normal.DotProduct(p0 - l0); @@ -79,12 +78,12 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) { gfxRect ourRect = aOne->GetEffectiveVisibleRegion().GetBounds(); gfxRect otherRect = aTwo->GetEffectiveVisibleRegion().GetBounds(); - gfx3DMatrix ourTransform = To3DMatrix(aOne->GetTransform()); - gfx3DMatrix otherTransform = To3DMatrix(aTwo->GetTransform()); + Matrix4x4 ourTransform = aOne->GetTransform(); + Matrix4x4 otherTransform = aTwo->GetTransform(); // Transform both rectangles and project into 2d space. - gfxQuad ourTransformedRect = ourTransform.TransformRect(ourRect); - gfxQuad otherTransformedRect = otherTransform.TransformRect(otherRect); + gfxQuad ourTransformedRect = ourRect.TransformToQuad(ourTransform); + gfxQuad otherTransformedRect = otherRect.TransformToQuad(otherTransform); gfxRect ourBounds = ourTransformedRect.GetBounds(); gfxRect otherBounds = otherTransformedRect.GetBounds(); diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index da69db054c..50ed176a44 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -341,7 +341,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase container->SetChildrenChanged(true); } - result.Transform(gfx::To3DMatrix(mLayer->GetLocalTransform())); + result.Transform(mLayer->GetLocalTransform()); return result; } diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 416b6881c9..b747872768 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -2196,7 +2196,7 @@ public: uint32_t mFrontbufferGLTex; // The size of the canvas content - nsIntSize mSize; + gfx::IntSize mSize; // Whether the canvas drawingbuffer has an alpha channel. bool mHasAlpha; diff --git a/gfx/layers/LayersTypes.h b/gfx/layers/LayersTypes.h index 479554ca9d..d6c32cb26a 100644 --- a/gfx/layers/LayersTypes.h +++ b/gfx/layers/LayersTypes.h @@ -7,7 +7,7 @@ #define GFX_LAYERSTYPES_H #include // for uint32_t -#include "nsPoint.h" // for nsIntPoint +#include "mozilla/gfx/Point.h" // for IntPoint #include "nsRegion.h" #include "mozilla/TypedEnumBits.h" @@ -97,7 +97,7 @@ struct LayerRenderState { #ifdef MOZ_WIDGET_GONK LayerRenderState(android::GraphicBuffer* aSurface, - const nsIntSize& aSize, + const gfx::IntSize& aSize, LayerRenderStateFlags aFlags, TextureHost* aTexture) : mFlags(aFlags) @@ -138,7 +138,7 @@ struct LayerRenderState { android::sp mSurface; int32_t mOverlayId; // size of mSurface - nsIntSize mSize; + gfx::IntSize mSize; TextureHost* mTexture; #endif }; @@ -221,7 +221,7 @@ struct EventRegions { mVerticalPanRegion.MoveBy(aXTrans, aYTrans); } - void Transform(const gfx3DMatrix& aTransform) + void Transform(const gfx::Matrix4x4& aTransform) { mHitRegion.Transform(aTransform); mDispatchToContentHitRegion.Transform(aTransform); diff --git a/gfx/layers/ReadbackProcessor.cpp b/gfx/layers/ReadbackProcessor.cpp index 808bac377b..f70e1666be 100644 --- a/gfx/layers/ReadbackProcessor.cpp +++ b/gfx/layers/ReadbackProcessor.cpp @@ -120,7 +120,7 @@ ReadbackProcessor::BuildUpdatesForLayer(ReadbackLayer* aLayer) aLayer->AllocateSequenceNumber()); if (ctx) { ColorPattern color(ToDeviceColor(aLayer->mBackgroundColor)); - nsIntSize size = aLayer->GetSize(); + IntSize size = aLayer->GetSize(); ctx->GetDrawTarget()->FillRect(Rect(0, 0, size.width, size.height), color); aLayer->mSink->EndUpdate(ctx, aLayer->GetRect()); diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp index 1bce95d9ff..17f8ca8f37 100644 --- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -330,7 +330,7 @@ RotatedContentBuffer::BufferContentType() } bool -RotatedContentBuffer::BufferSizeOkFor(const nsIntSize& aSize) +RotatedContentBuffer::BufferSizeOkFor(const IntSize& aSize) { return (aSize == mBufferRect.Size() || (SizedToVisibleBounds != mBufferSizePolicy && diff --git a/gfx/layers/TiledLayerBuffer.h b/gfx/layers/TiledLayerBuffer.h index 606e4fbd08..1c741184f3 100644 --- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -60,11 +60,6 @@ static inline int floor_div(int a, int b) } } -// An abstract implementation of a tile buffer. This code covers the logic of -// moving and reusing tiles and leaves the validation up to the implementor. To -// avoid the overhead of virtual dispatch, we employ the curiously recurring -// template pattern. -// // Tiles are aligned to a grid with one of the grid points at (0,0) and other // grid points spaced evenly in the x- and y-directions by GetTileSize() // multiplied by mResolution. GetScaledTileSize() provides convenience for @@ -82,30 +77,6 @@ static inline int floor_div(int a, int b) // the tile type should be a reference or some other type with an efficient // copy constructor. // -// It is required that the derived class specify the base class as a friend. It -// must also implement the following public method: -// -// Tile GetPlaceholderTile() const; -// -// Returns a temporary placeholder tile used as a marker. This placeholder tile -// must never be returned by validateTile and must be == to every instance -// of a placeholder tile. -// -// Additionally, it must implement the following protected methods: -// -// Tile ValidateTile(Tile aTile, const nsIntPoint& aTileOrigin, -// const nsIntRegion& aDirtyRect); -// -// Validates the dirtyRect. The returned Tile will replace the tile. -// -// void ReleaseTile(Tile aTile); -// -// Destroys the given tile. -// -// void SwapTiles(Tile& aTileA, Tile& aTileB); -// -// Swaps two tiles. -// // The contents of the tile buffer will be rendered at the resolution specified // in mResolution, which can be altered with SetResolution. The resolution // should always be a factor of the tile length, to avoid tiles covering @@ -146,12 +117,23 @@ struct TilesPlacement { ); } - bool HasTile(TileIntPoint aPosition) { + bool HasTile(TileIntPoint aPosition) const { return aPosition.x >= mFirst.x && aPosition.x < mFirst.x + mSize.width && aPosition.y >= mFirst.y && aPosition.y < mFirst.y + mSize.height; } }; + +// Given a position i, this function returns the position inside the current tile. +inline int GetTileStart(int i, int aTileLength) { + return (i >= 0) ? (i % aTileLength) + : ((aTileLength - (-i % aTileLength)) % + aTileLength); +} + +// Rounds the given coordinate down to the nearest tile boundary. +inline int RoundDownToTileEdge(int aX, int aTileLength) { return aX - GetTileStart(aX, aTileLength); } + template class TiledLayerBuffer { @@ -165,61 +147,26 @@ public: ~TiledLayerBuffer() {} - // Given a tile origin aligned to a multiple of GetScaledTileSize, - // return the tile that describes that region. - // NOTE: To get the valid area of that tile you must intersect - // (aTileOrigin.x, aTileOrigin.y, - // GetScaledTileSize().width, GetScaledTileSize().height) - // and GetValidRegion() to get the area of the tile that is valid. - Tile& GetTile(const gfx::IntPoint& aTileOrigin); - // Given a tile x, y relative to the top left of the layer, this function - // will return the tile for - // (x*GetScaledTileSize().width, y*GetScaledTileSize().height, - // GetScaledTileSize().width, GetScaledTileSize().height) - Tile& GetTile(int x, int y); - - int TileIndex(const gfx::IntPoint& aTileOrigin) const; - int TileIndex(int x, int y) const { return x * mTiles.mSize.height + y; } - - bool HasTile(int index) const { return index >= 0 && index < (int)mRetainedTiles.Length(); } - bool HasTile(const gfx::IntPoint& aTileOrigin) const; - bool HasTile(int x, int y) const { - return x >= 0 && x < mTiles.mSize.width && y >= 0 && y < mTiles.mSize.height; + gfx::IntPoint GetTileOffset(TileIntPoint aPosition) const { + gfx::IntSize scaledTileSize = GetScaledTileSize(); + return gfx::IntPoint(aPosition.x * scaledTileSize.width, + aPosition.y * scaledTileSize.height); } + const TilesPlacement& GetPlacement() const { return mTiles; } + const gfx::IntSize& GetTileSize() const { return mTileSize; } gfx::IntSize GetScaledTileSize() const { return RoundedToInt(gfx::Size(mTileSize) / mResolution); } unsigned int GetTileCount() const { return mRetainedTiles.Length(); } + Tile& GetTile(size_t i) { return mRetainedTiles[i]; } + const nsIntRegion& GetValidRegion() const { return mValidRegion; } const nsIntRegion& GetPaintedRegion() const { return mPaintedRegion; } void ClearPaintedRegion() { mPaintedRegion.SetEmpty(); } - void ResetPaintedAndValidState() { - mPaintedRegion.SetEmpty(); - mValidRegion.SetEmpty(); - mTiles.mSize.width = 0; - mTiles.mSize.height = 0; - for (size_t i = 0; i < mRetainedTiles.Length(); i++) { - if (!mRetainedTiles[i].IsPlaceholderTile()) { - AsDerived().ReleaseTile(mRetainedTiles[i]); - } - } - mRetainedTiles.Clear(); - } - - // Given a position i, this function returns the position inside the current tile. - int GetTileStart(int i, int aTileLength) const { - return (i >= 0) ? (i % aTileLength) - : ((aTileLength - (-i % aTileLength)) % - aTileLength); - } - - // Rounds the given coordinate down to the nearest tile boundary. - int RoundDownToTileEdge(int aX, int aTileLength) const { return aX - GetTileStart(aX, aTileLength); } - // Get and set draw scaling. mResolution affects the resolution at which the // contents of the buffer are drawn. mResolution has no effect on the // coordinate space of the valid region, but does affect the size of an @@ -228,22 +175,9 @@ public: float GetResolution() const { return mResolution; } bool IsLowPrecision() const { return mResolution < 1; } - typedef Tile* Iterator; - Iterator TilesBegin() { return mRetainedTiles.Elements(); } - Iterator TilesEnd() { return mRetainedTiles.Elements() + mRetainedTiles.Length(); } - void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml); protected: - // The implementor should call Update() to change - // the new valid region. This implementation will call - // validateTile on each tile that is dirty, which is left - // to the implementor. - void Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion); - - // Return a reference to this tile in GetTile when the requested tile offset - // does not exist. - Tile mPlaceHolderTile; nsIntRegion mValidRegion; nsIntRegion mPaintedRegion; @@ -260,411 +194,25 @@ protected: TilesPlacement mTiles; float mResolution; gfx::IntSize mTileSize; - -private: - const Derived& AsDerived() const { return *static_cast(this); } - Derived& AsDerived() { return *static_cast(this); } }; -class ClientTiledLayerBuffer; -class SurfaceDescriptorTiles; -class ISurfaceAllocator; - -// Shadow layers may implement this interface in order to be notified when a -// tiled layer buffer is updated. -class TiledLayerComposer -{ -public: - /** - * Update the current retained layer with the updated layer data. - * It is expected that the tiles described by aTiledDescriptor are all in the - * ReadLock state, so that the locks can be adopted when recreating a - * ClientTiledLayerBuffer locally. This lock will be retained until the buffer - * has completed uploading. - * - * Returns false if a deserialization error happened, in which case we will - * have to kill the child process. - */ - virtual bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, - const SurfaceDescriptorTiles& aTiledDescriptor) = 0; - - /** - * If some part of the buffer is being rendered at a lower precision, this - * returns that region. If it is not, an empty region will be returned. - */ - virtual const nsIntRegion& GetValidLowPrecisionRegion() const = 0; - - virtual const nsIntRegion& GetValidRegion() const = 0; -}; - -template bool -TiledLayerBuffer::HasTile(const gfx::IntPoint& aTileOrigin) const { - gfx::IntSize scaledTileSize = GetScaledTileSize(); - return HasTile(floor_div(aTileOrigin.x, scaledTileSize.width) - mTiles.mFirst.x, - floor_div(aTileOrigin.y, scaledTileSize.height) - mTiles.mFirst.y); -} - -template Tile& -TiledLayerBuffer::GetTile(const nsIntPoint& aTileOrigin) -{ - if (HasTile(aTileOrigin)) { - return mRetainedTiles[TileIndex(aTileOrigin)]; - } - return mPlaceHolderTile; -} - -template int -TiledLayerBuffer::TileIndex(const gfx::IntPoint& aTileOrigin) const -{ - // Find the tile x/y of the first tile and the target tile relative to the (0, 0) - // origin, the difference is the tile x/y relative to the start of the tile buffer. - gfx::IntSize scaledTileSize = GetScaledTileSize(); - return TileIndex(floor_div(aTileOrigin.x, scaledTileSize.width) - mTiles.mFirst.x, - floor_div(aTileOrigin.y, scaledTileSize.height) - mTiles.mFirst.y); -} - -template Tile& -TiledLayerBuffer::GetTile(int x, int y) -{ - if (HasTile(x, y)) { - return mRetainedTiles[TileIndex(x, y)]; - } - return mPlaceHolderTile; -} - template void TiledLayerBuffer::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml) { - gfx::IntRect visibleRect = GetValidRegion().GetBounds(); - gfx::IntSize scaledTileSize = GetScaledTileSize(); - for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { - int32_t tileStartX = GetTileStart(x, scaledTileSize.width); - int32_t w = scaledTileSize.width - tileStartX; + for (size_t i = 0; i < mRetainedTiles.Length(); ++i) { + const TileIntPoint tilePosition = mTiles.TilePosition(i); + gfx::IntPoint tileOffset = GetTileOffset(tilePosition); - for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { - int32_t tileStartY = GetTileStart(y, scaledTileSize.height); - nsIntPoint tileOrigin = nsIntPoint(RoundDownToTileEdge(x, scaledTileSize.width), - RoundDownToTileEdge(y, scaledTileSize.height)); - Tile& tileTexture = GetTile(tileOrigin); - int32_t h = scaledTileSize.height - tileStartY; - - aStream << "\n" << aPrefix << "Tile (x=" << - RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" << - RoundDownToTileEdge(y, scaledTileSize.height) << "): "; - if (!tileTexture.IsPlaceholderTile()) { - tileTexture.DumpTexture(aStream); - } else { - aStream << "empty tile"; - } - y += h; - } - x += w; - } -} - -template void -TiledLayerBuffer::Update(const nsIntRegion& newValidRegion, - const nsIntRegion& aPaintRegion) -{ - gfx::IntSize scaledTileSize = GetScaledTileSize(); - - nsTArray newRetainedTiles; - nsTArray& oldRetainedTiles = mRetainedTiles; - const gfx::IntRect oldBound = mValidRegion.GetBounds(); - const gfx::IntRect newBound = newValidRegion.GetBounds(); - const nsIntPoint oldBufferOrigin(RoundDownToTileEdge(oldBound.x, scaledTileSize.width), - RoundDownToTileEdge(oldBound.y, scaledTileSize.height)); - const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x, scaledTileSize.width), - RoundDownToTileEdge(newBound.y, scaledTileSize.height)); - - // This is the reason we break the style guide with newValidRegion instead - // of aNewValidRegion - so that the names match better and code easier to read - const nsIntRegion& oldValidRegion = mValidRegion; - const int oldRetainedHeight = mTiles.mSize.height; - -#ifdef GFX_TILEDLAYER_RETAINING_LOG - { // scope ss - std::stringstream ss; - ss << "TiledLayerBuffer " << this << " starting update" - << " on bounds "; - AppendToString(ss, newBound); - ss << " with mResolution=" << mResolution << "\n"; - for (size_t i = 0; i < mRetainedTiles.Length(); i++) { - ss << "mRetainedTiles[" << i << "] = "; - mRetainedTiles[i].Dump(ss); - ss << "\n"; - } - print_stderr(ss); - } -#endif - - // Pass 1: Recycle valid content from the old buffer - // Recycle tiles from the old buffer that contain valid regions. - // Insert placeholders tiles if we have no valid area for that tile - // which we will allocate in pass 2. - // TODO: Add a tile pool to reduce new allocation - int tileX = 0; - int tileY = 0; - int tilesMissing = 0; - // Iterate over the new drawing bounds in steps of tiles. - for (int32_t x = newBound.x; x < newBound.XMost(); tileX++) { - // Compute tileRect(x,y,width,height) in layer space coordinate - // giving us the rect of the tile that hits the newBounds. - int width = scaledTileSize.width - GetTileStart(x, scaledTileSize.width); - if (x + width > newBound.XMost()) { - width = newBound.x + newBound.width - x; - } - - tileY = 0; - for (int32_t y = newBound.y; y < newBound.YMost(); tileY++) { - int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height); - if (y + height > newBound.y + newBound.height) { - height = newBound.y + newBound.height - y; - } - - const gfx::IntRect tileRect(x,y,width,height); - if (oldValidRegion.Intersects(tileRect) && newValidRegion.Intersects(tileRect)) { - // This old tiles contains some valid area so move it to the new tile - // buffer. Replace the tile in the old buffer with a placeholder - // to leave the old buffer index unaffected. - int tileX = floor_div(x - oldBufferOrigin.x, scaledTileSize.width); - int tileY = floor_div(y - oldBufferOrigin.y, scaledTileSize.height); - int index = tileX * oldRetainedHeight + tileY; - - // The tile may have been removed, skip over it in this case. - if (oldRetainedTiles. - SafeElementAt(index, AsDerived().GetPlaceholderTile()).IsPlaceholderTile()) { - newRetainedTiles.AppendElement(AsDerived().GetPlaceholderTile()); - } else { - Tile tileWithPartialValidContent = oldRetainedTiles[index]; - newRetainedTiles.AppendElement(tileWithPartialValidContent); - oldRetainedTiles[index] = AsDerived().GetPlaceholderTile(); - } - - } else { - // This tile is either: - // 1) Outside the new valid region and will simply be an empty - // placeholder forever. - // 2) The old buffer didn't have any data for this tile. We postpone - // the allocation of this tile after we've reused any tile with - // valid content because then we know we can safely recycle - // with taking from a tile that has recyclable content. - newRetainedTiles.AppendElement(AsDerived().GetPlaceholderTile()); - - if (aPaintRegion.Intersects(tileRect)) { - tilesMissing++; - } - } - - y += height; - } - - x += width; - } - - // Keep track of the number of horizontal/vertical tiles - // in the buffer so that we can easily look up a tile. - mTiles.mSize.width = tileX; - mTiles.mSize.height = tileY; - -#ifdef GFX_TILEDLAYER_RETAINING_LOG - { // scope ss - std::stringstream ss; - ss << "TiledLayerBuffer " << this << " finished pass 1 of update;" - << " tilesMissing=" << tilesMissing << "\n"; - for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { - ss << "oldRetainedTiles[" << i << "] = "; - oldRetainedTiles[i].Dump(ss); - ss << "\n"; - } - print_stderr(ss); - } -#endif - - - // Pass 1.5: Release excess tiles in oldRetainedTiles - // Tiles in oldRetainedTiles that aren't in newRetainedTiles will be recycled - // before creating new ones, but there could still be excess unnecessary - // tiles. As tiles may not have a fixed memory cost (for example, due to - // double-buffering), we should release these excess tiles first. - int oldTileCount = 0; - for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { - Tile oldTile = oldRetainedTiles[i]; - if (oldTile.IsPlaceholderTile()) { - continue; - } - - if (oldTileCount >= tilesMissing) { - oldRetainedTiles[i] = AsDerived().GetPlaceholderTile(); - AsDerived().ReleaseTile(oldTile); + aStream << "\n" << aPrefix << "Tile (x=" << + tileOffset.x << ", y=" << tileOffset.y << "): "; + if (!mRetainedTiles[i].IsPlaceholderTile()) { + mRetainedTiles[i].DumpTexture(aStream); } else { - oldTileCount ++; + aStream << "empty tile"; } } - - if (!newValidRegion.Contains(aPaintRegion)) { - gfxCriticalError() << "Painting outside visible:" - << " paint " << aPaintRegion.ToString().get() - << " old valid " << oldValidRegion.ToString().get() - << " new valid " << newValidRegion.ToString().get(); - } -#ifdef DEBUG - nsIntRegion oldAndPainted(oldValidRegion); - oldAndPainted.Or(oldAndPainted, aPaintRegion); - if (!oldAndPainted.Contains(newValidRegion)) { - gfxCriticalError() << "Not fully painted:" - << " paint " << aPaintRegion.ToString().get() - << " old valid " << oldValidRegion.ToString().get() - << " old painted " << oldAndPainted.ToString().get() - << " new valid " << newValidRegion.ToString().get(); - } -#endif - - nsIntRegion regionToPaint(aPaintRegion); - -#ifdef GFX_TILEDLAYER_RETAINING_LOG - { // scope ss - std::stringstream ss; - ss << "TiledLayerBuffer " << this << " finished pass 1.5 of update\n"; - for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { - ss << "oldRetainedTiles[" << i << "] = "; - oldRetainedTiles[i].Dump(ss); - ss << "\n"; - } - for (size_t i = 0; i < newRetainedTiles.Length(); i++) { - ss << "newRetainedTiles[" << i << "] = "; - newRetainedTiles[i].Dump(ss); - ss << "\n"; - } - print_stderr(ss); - } -#endif - - // Pass 2: Validate - // We know at this point that any tile in the new buffer that had valid content - // from the previous buffer is placed correctly in the new buffer. - // We know that any tile in the old buffer that isn't a place holder is - // of no use and can be recycled. - // We also know that any place holder tile in the new buffer must be - // allocated. - tileX = 0; -#ifdef GFX_TILEDLAYER_PREF_WARNINGS - printf_stderr("Update %i, %i, %i, %i\n", newBound.x, newBound.y, newBound.width, newBound.height); -#endif - for (int x = newBound.x; x < newBound.x + newBound.width; tileX++) { - // Compute tileRect(x,y,width,height) in layer space coordinate - // giving us the rect of the tile that hits the newBounds. - int tileStartX = RoundDownToTileEdge(x, scaledTileSize.width); - int width = scaledTileSize.width - GetTileStart(x, scaledTileSize.width); - if (x + width > newBound.XMost()) - width = newBound.XMost() - x; - - tileY = 0; - for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) { - int tileStartY = RoundDownToTileEdge(y, scaledTileSize.height); - int height = scaledTileSize.height - GetTileStart(y, scaledTileSize.height); - if (y + height > newBound.YMost()) { - height = newBound.YMost() - y; - } - - const gfx::IntRect tileRect(x, y, width, height); - - nsIntRegion tileDrawRegion; - tileDrawRegion.And(tileRect, regionToPaint); - - if (tileDrawRegion.IsEmpty()) { - // We have a tile but it doesn't hit the draw region - // because we can reuse all of the content from the - // previous buffer. -#ifdef DEBUG - int currTileX = floor_div(x - newBufferOrigin.x, scaledTileSize.width); - int currTileY = floor_div(y - newBufferOrigin.y, scaledTileSize.height); - int index = TileIndex(currTileX, currTileY); - // If allocating a tile failed we can run into this assertion. - // Rendering is going to be glitchy but we don't want to crash. - NS_ASSERTION(!newValidRegion.Intersects(tileRect) || - !newRetainedTiles. - SafeElementAt(index, AsDerived().GetPlaceholderTile()).IsPlaceholderTile(), - "Unexpected placeholder tile"); - -#endif - y += height; - continue; - } - - int tileX = floor_div(x - newBufferOrigin.x, scaledTileSize.width); - int tileY = floor_div(y - newBufferOrigin.y, scaledTileSize.height); - int index = TileIndex(tileX, tileY); - MOZ_ASSERT(index >= 0 && - static_cast(index) < newRetainedTiles.Length(), - "index out of range"); - - Tile newTile = newRetainedTiles[index]; - - // Try to reuse a tile from the old retained tiles that had no partially - // valid content. - while (newTile.IsPlaceholderTile() && oldRetainedTiles.Length() > 0) { - AsDerived().SwapTiles(newTile, oldRetainedTiles[oldRetainedTiles.Length()-1]); - oldRetainedTiles.RemoveElementAt(oldRetainedTiles.Length()-1); - if (!newTile.IsPlaceholderTile()) { - oldTileCount--; - } - } - - // We've done our best effort to recycle a tile but it can be null - // in which case it's up to the derived class's ValidateTile() - // implementation to allocate a new tile before drawing - nsIntPoint tileOrigin(tileStartX, tileStartY); - newTile = AsDerived().ValidateTile(newTile, nsIntPoint(tileStartX, tileStartY), - tileDrawRegion); - NS_ASSERTION(!newTile.IsPlaceholderTile(), "Unexpected placeholder tile - failed to allocate?"); -#ifdef GFX_TILEDLAYER_PREF_WARNINGS - printf_stderr("Store Validate tile %i, %i -> %i\n", tileStartX, tileStartY, index); -#endif - newRetainedTiles[index] = newTile; - - y += height; - } - - x += width; - } - - AsDerived().PostValidate(aPaintRegion); - for (unsigned int i = 0; i < newRetainedTiles.Length(); ++i) { - AsDerived().UnlockTile(newRetainedTiles[i]); - } - -#ifdef GFX_TILEDLAYER_RETAINING_LOG - { // scope ss - std::stringstream ss; - ss << "TiledLayerBuffer " << this << " finished pass 2 of update;" - << " oldTileCount=" << oldTileCount << "\n"; - for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { - ss << "oldRetainedTiles[" << i << "] = "; - oldRetainedTiles[i].Dump(ss); - ss << "\n"; - } - for (size_t i = 0; i < newRetainedTiles.Length(); i++) { - ss << "newRetainedTiles[" << i << "] = "; - newRetainedTiles[i].Dump(ss); - ss << "\n"; - } - print_stderr(ss); - } -#endif - - // At this point, oldTileCount should be zero - MOZ_ASSERT(oldTileCount == 0, "Failed to release old tiles"); - - mRetainedTiles = newRetainedTiles; - mValidRegion = newValidRegion; - - mTiles.mFirst.x = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width); - mTiles.mFirst.y = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height); - - mPaintedRegion.Or(mPaintedRegion, aPaintRegion); } } // namespace layers diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 97f30fbe9b..05d93bf8ac 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -188,7 +188,7 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest, #ifdef MOZ_ENABLE_SKIA static SkMatrix -Matrix3DToSkia(const gfx3DMatrix& aMatrix) +Matrix3DToSkia(const Matrix4x4& aMatrix) { SkMatrix transform; transform.setAll(aMatrix._11, @@ -207,7 +207,7 @@ Matrix3DToSkia(const gfx3DMatrix& aMatrix) static void Transform(DataSourceSurface* aDest, DataSourceSurface* aSource, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, const Point& aDestOffset) { if (aTransform.IsSingular()) { @@ -233,8 +233,8 @@ Transform(DataSourceSurface* aDest, src.setInfo(srcInfo, aSource->Stride()); src.setPixels((uint32_t*)aSource->GetData()); - gfx3DMatrix transform = aTransform; - transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0)); + Matrix4x4 transform = aTransform; + transform.PostTranslate(Point3D(-aDestOffset.x, -aDestOffset.y, 0)); destCanvas.setMatrix(Matrix3DToSkia(transform)); SkPaint paint; @@ -246,7 +246,7 @@ Transform(DataSourceSurface* aDest, } #else static pixman_transform -Matrix3DToPixman(const gfx3DMatrix& aMatrix) +Matrix3DToPixman(const Matrix4x4& aMatrix) { pixman_f_transform transform; @@ -269,7 +269,7 @@ Matrix3DToPixman(const gfx3DMatrix& aMatrix) static void Transform(DataSourceSurface* aDest, DataSourceSurface* aSource, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, const Point& aDestOffset) { IntSize destSize = aDest->GetSize(); @@ -329,7 +329,8 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) { RefPtr buffer = mRenderTarget->mDrawTarget; @@ -342,7 +343,7 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, Matrix newTransform; Rect transformBounds; - gfx3DMatrix new3DTransform; + Matrix4x4 new3DTransform; IntPoint offset = mRenderTarget->GetOrigin(); if (aTransform.Is2D()) { @@ -357,8 +358,9 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, dest->SetTransform(Matrix::Translation(-aRect.x, -aRect.y)); // Get the bounds post-transform. - new3DTransform = To3DMatrix(aTransform); - gfxRect bounds = new3DTransform.TransformBounds(ThebesRect(aRect)); + new3DTransform = aTransform; + gfxRect bounds = ThebesRect(aRect); + bounds.TransformBounds(new3DTransform); bounds.IntersectRect(bounds, gfxRect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height)); transformBounds = ToRect(bounds); @@ -369,7 +371,7 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, // When we apply the 3D transformation, we do it against a temporary // surface, so undo the coordinate offset. - new3DTransform = gfx3DMatrix::Translation(aRect.x, aRect.y, 0) * new3DTransform; + new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * new3DTransform; } newTransform.PostTranslate(-offset.x, -offset.y); diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index b5910396cf..8a4f2a639b 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -84,7 +84,8 @@ public: const gfx::Rect& aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) override; + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) override; virtual void ClearRect(const gfx::Rect& aRect) override; diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index f6f4ca6ead..1b053e9497 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -16,7 +16,6 @@ #include "RenderTrace.h" // for RenderTraceLayers, etc #include "basic/BasicImplData.h" // for BasicImplData #include "basic/BasicLayers.h" // for BasicLayerManager, etc -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxASurface.h" // for gfxASurface, etc #include "gfxColor.h" // for gfxRGBA #include "gfxContext.h" // for gfxContext, etc @@ -613,7 +612,7 @@ BasicLayerManager::SetRoot(Layer* aLayer) #ifdef MOZ_ENABLE_SKIA static SkMatrix -BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix) +BasicLayerManager_Matrix3DToSkia(const Matrix4x4& aMatrix) { SkMatrix transform; transform.setAll(aMatrix._11, @@ -632,7 +631,7 @@ BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix) static void Transform(const gfxImageSurface* aDest, RefPtr aSrc, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, gfxPoint aDestOffset) { if (aTransform.IsSingular()) { @@ -658,8 +657,8 @@ Transform(const gfxImageSurface* aDest, src.setInfo(srcInfo, aSrc->Stride()); src.setPixels((uint32_t*)aSrc->GetData()); - gfx3DMatrix transform = aTransform; - transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0)); + Matrix4x4 transform = aTransform; + transform.PostTranslate(Point3D(-aDestOffset.x, -aDestOffset.y, 0)); destCanvas.setMatrix(BasicLayerManager_Matrix3DToSkia(transform)); SkPaint paint; @@ -671,7 +670,7 @@ Transform(const gfxImageSurface* aDest, } #else static pixman_transform -BasicLayerManager_Matrix3DToPixman(const gfx3DMatrix& aMatrix) +BasicLayerManager_Matrix3DToPixman(const Matrix4x4& aMatrix) { pixman_f_transform transform; @@ -694,7 +693,7 @@ BasicLayerManager_Matrix3DToPixman(const gfx3DMatrix& aMatrix) static void Transform(const gfxImageSurface* aDest, RefPtr aSrc, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, gfxPoint aDestOffset) { IntSize destSize = aDest->GetSize(); @@ -743,7 +742,7 @@ Transform(const gfxImageSurface* aDest, #endif /** - * Transform a surface using a gfx3DMatrix and blit to the destination if + * Transform a surface using a Matrix4x4 and blit to the destination if * it is efficient to do so. * * @param aSource Source surface. @@ -759,11 +758,12 @@ static already_AddRefed Transform3D(RefPtr aSource, gfxContext* aDest, const gfxRect& aBounds, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, gfxRect& aDestRect) { // Find the transformed rectangle of our layer. - gfxRect offsetRect = aTransform.TransformBounds(aBounds); + gfxRect offsetRect = aBounds; + offsetRect.TransformBounds(aTransform); // Intersect the transformed layer with the destination rectangle. // This is in device space since we have an identity transform set on aTarget. @@ -779,7 +779,7 @@ Transform3D(RefPtr aSource, gfxPoint offset = aDestRect.TopLeft(); // Include a translation to the correct origin. - gfx3DMatrix translation = gfx3DMatrix::Translation(aBounds.x, aBounds.y, 0); + Matrix4x4 translation = Matrix4x4::Translation(aBounds.x, aBounds.y, 0); // Transform the content and offset it such that the content begins at the origin. Transform(destImage, aSource->GetDataSurface(), translation * aTransform, offset); @@ -958,8 +958,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget, temp->Paint(); } #endif - gfx3DMatrix effectiveTransform; - effectiveTransform = gfx::To3DMatrix(aLayer->GetEffectiveTransform()); + Matrix4x4 effectiveTransform = aLayer->GetEffectiveTransform(); nsRefPtr result = Transform3D(untransformedDT->Snapshot(), aTarget, bounds, effectiveTransform, destRect); diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 1eef4f75d5..544b00f499 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1092,6 +1092,71 @@ ClientTiledLayerBuffer::UnlockTile(TileClient aTile) } } +void ClientTiledLayerBuffer::Update(const nsIntRegion& newValidRegion, + const nsIntRegion& aPaintRegion) +{ + const IntSize scaledTileSize = GetScaledTileSize(); + const gfx::IntRect newBounds = newValidRegion.GetBounds(); + + const TilesPlacement oldTiles = mTiles; + const TilesPlacement newTiles(floor_div(newBounds.x, scaledTileSize.width), + floor_div(newBounds.y, scaledTileSize.height), + floor_div(GetTileStart(newBounds.x, scaledTileSize.width) + + newBounds.width, scaledTileSize.width) + 1, + floor_div(GetTileStart(newBounds.y, scaledTileSize.height) + + newBounds.height, scaledTileSize.height) + 1); + + const size_t oldTileCount = mRetainedTiles.Length(); + const size_t newTileCount = newTiles.mSize.width * newTiles.mSize.height; + + nsTArray oldRetainedTiles; + mRetainedTiles.SwapElements(oldRetainedTiles); + mRetainedTiles.SetLength(newTileCount); + + for (size_t oldIndex = 0; oldIndex < oldTileCount; oldIndex++) { + const TileIntPoint tilePosition = oldTiles.TilePosition(oldIndex); + const size_t newIndex = newTiles.TileIndex(tilePosition); + // First, get the already existing tiles to the right place in the new array. + // Leave placeholders (default constructor) where there was no tile. + if (newTiles.HasTile(tilePosition)) { + mRetainedTiles[newIndex] = oldRetainedTiles[oldIndex]; + } else { + // release tiles that we are not going to reuse before allocating new ones + // to avoid allocating unnecessarily. + oldRetainedTiles[oldIndex].Release(); + } + } + + oldRetainedTiles.Clear(); + + for (size_t i = 0; i < newTileCount; ++i) { + const TileIntPoint tilePosition = newTiles.TilePosition(i); + + IntPoint tileOffset = GetTileOffset(tilePosition); + nsIntRegion tileDrawRegion = IntRect(tileOffset, scaledTileSize); + tileDrawRegion.AndWith(aPaintRegion); + + if (tileDrawRegion.IsEmpty()) { + continue; + } + + TileClient tile = mRetainedTiles[i]; + tile = ValidateTile(tile, GetTileOffset(tilePosition), + tileDrawRegion); + + mRetainedTiles[i] = tile; + } + + PostValidate(aPaintRegion); + for (size_t i = 0; i < mRetainedTiles.Length(); ++i) { + UnlockTile(mRetainedTiles[i]); + } + + mTiles = newTiles; + mValidRegion = newValidRegion; + mPaintedRegion.OrWith(aPaintRegion); +} + TileClient ClientTiledLayerBuffer::ValidateTile(TileClient aTile, const nsIntPoint& aTileOrigin, diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index de2a260de8..1fb2c3c72f 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -416,6 +416,8 @@ public: LayerManager::DrawPaintedLayerCallback aCallback, void* aCallbackData); + void Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion); + void ReadLock(); void Release(); @@ -450,6 +452,19 @@ public: mResolution = aResolution; } + void ResetPaintedAndValidState() { + mPaintedRegion.SetEmpty(); + mValidRegion.SetEmpty(); + mTiles.mSize.width = 0; + mTiles.mSize.height = 0; + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { + if (!mRetainedTiles[i].IsPlaceholderTile()) { + mRetainedTiles[i].Release(); + } + } + mRetainedTiles.Clear(); + } + protected: TileClient ValidateTile(TileClient aTile, const nsIntPoint& aTileRect, @@ -459,10 +474,6 @@ protected: void UnlockTile(TileClient aTile); - void ReleaseTile(TileClient aTile) { aTile.Release(); } - - void SwapTiles(TileClient& aTileA, TileClient& aTileB) { std::swap(aTileA, aTileB); } - TileClient GetPlaceholderTile() const { return TileClient(); } private: diff --git a/gfx/layers/composite/CanvasLayerComposite.cpp b/gfx/layers/composite/CanvasLayerComposite.cpp index efdbff56e2..009fa35132 100644 --- a/gfx/layers/composite/CanvasLayerComposite.cpp +++ b/gfx/layers/composite/CanvasLayerComposite.cpp @@ -5,7 +5,7 @@ #include "CanvasLayerComposite.h" #include "composite/CompositableHost.h" // for CompositableHost -#include "gfx2DGlue.h" // for ToFilter, ToMatrix4x4 +#include "gfx2DGlue.h" // for ToFilter #include "GraphicsFilter.h" // for GraphicsFilter #include "gfxUtils.h" // for gfxUtils, etc #include "mozilla/gfx/Matrix.h" // for Matrix4x4 diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index d1daf82b42..eaed00a16c 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -39,7 +39,7 @@ namespace layers { class Layer; class Compositor; class ThebesBufferData; -class TiledLayerComposer; +class TiledContentHost; class CompositableParentManager; class PCompositableParent; struct EffectChain; @@ -132,7 +132,7 @@ public: Layer* GetLayer() const { return mLayer; } void SetLayer(Layer* aLayer) { mLayer = aLayer; } - virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; } + virtual TiledContentHost* AsTiledContentHost() { return nullptr; } typedef uint32_t AttachFlags; static const AttachFlags NO_FLAGS = 0; diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index cbbe4b7a47..9f3c048db9 100755 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -8,7 +8,6 @@ #include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController #include "FrameMetrics.h" // for FrameMetrics #include "Units.h" // for LayerRect, LayerPixel, etc -#include "gfx2DGlue.h" // for ToMatrix4x4 #include "gfxPrefs.h" // for gfxPrefs #include "gfxUtils.h" // for gfxUtils, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 2f7600b286..0af885441f 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -301,7 +301,7 @@ ContentHostTexture::Dump(std::stringstream& aStream, static inline void AddWrappedRegion(const nsIntRegion& aInput, nsIntRegion& aOutput, - const nsIntSize& aSize, const nsIntPoint& aShift) + const IntSize& aSize, const nsIntPoint& aShift) { nsIntRegion tempRegion; tempRegion.And(IntRect(aShift, aSize), aInput); @@ -341,7 +341,7 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, // Shift to the rotation point destRegion.MoveBy(aData.rotation()); - nsIntSize bufferSize = aData.rect().Size(); + IntSize bufferSize = aData.rect().Size(); // Select only the pixels that are still within the buffer. nsIntRegion finalRegion; diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index d78abb9761..9ef34efa34 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -40,7 +40,6 @@ class Matrix4x4; namespace layers { class Compositor; class ThebesBufferData; -class TiledLayerComposer; struct EffectChain; struct TexturedEffect; @@ -54,10 +53,6 @@ struct TexturedEffect; class ContentHost : public CompositableHost { public: - // Subclasses should implement this method if they support being used as a - // tiling. - virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; } - virtual bool UpdateThebes(const ThebesBufferData& aData, const nsIntRegion& aUpdated, const nsIntRegion& aOldValidRegionBack, diff --git a/gfx/layers/composite/ImageLayerComposite.cpp b/gfx/layers/composite/ImageLayerComposite.cpp index 76e02103f9..40fcf2e840 100644 --- a/gfx/layers/composite/ImageLayerComposite.cpp +++ b/gfx/layers/composite/ImageLayerComposite.cpp @@ -6,7 +6,7 @@ #include "ImageLayerComposite.h" #include "CompositableHost.h" // for CompositableHost #include "Layers.h" // for WriteSnapshotToDumpFile, etc -#include "gfx2DGlue.h" // for ToFilter, ToMatrix4x4 +#include "gfx2DGlue.h" // for ToFilter #include "gfxRect.h" // for gfxRect #include "gfxUtils.h" // for gfxUtils, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 55ea1684bd..6fe9886d60 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -19,10 +19,9 @@ #include "LayerScope.h" // for LayerScope Tool #include "protobuf/LayerScopePacket.pb.h" // for protobuf (LayerScope) #include "PaintedLayerComposite.h" // for PaintedLayerComposite -#include "TiledLayerBuffer.h" // for TiledLayerComposer +#include "TiledContentHost.h" #include "Units.h" // for ScreenIntRect #include "UnitTransforms.h" // for ViewAs -#include "gfx2DGlue.h" // for ToMatrix4x4 #include "gfxPrefs.h" // for gfxPrefs #ifdef XP_MACOSX #include "gfxPlatformMac.h" @@ -1015,10 +1014,10 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer, SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen); // See if there's any incomplete low-precision rendering - TiledLayerComposer* composer = nullptr; + TiledContentHost* composer = nullptr; LayerComposite* shadow = aLayer->AsLayerComposite(); if (shadow) { - composer = shadow->GetTiledLayerComposer(); + composer = shadow->GetCompositableHost()->AsTiledContentHost(); if (composer) { incompleteRegion.Sub(incompleteRegion, composer->GetValidLowPrecisionRegion()); if (!incompleteRegion.IsEmpty()) { @@ -1337,7 +1336,8 @@ LayerManagerComposite::AsyncPanZoomEnabled() const nsIntRegion LayerComposite::GetFullyRenderedRegion() { - if (TiledLayerComposer* tiled = GetTiledLayerComposer()) { + if (TiledContentHost* tiled = GetCompositableHost() ? GetCompositableHost()->AsTiledContentHost() + : nullptr) { nsIntRegion shadowVisibleRegion = GetShadowVisibleRegion(); // Discard the region which hasn't been drawn yet when doing // progressive drawing. Note that if the shadow visible region diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 54f1f131e4..80988891e5 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -57,7 +57,6 @@ class ImageLayerComposite; class LayerComposite; class RefLayerComposite; class PaintedLayerComposite; -class TiledLayerComposer; class TextRenderer; class CompositingRenderTarget; struct FPSState; @@ -380,8 +379,6 @@ public: virtual void CleanupResources() = 0; - virtual TiledLayerComposer* GetTiledLayerComposer() { return nullptr; } - virtual void DestroyFrontBuffer() { } void AddBlendModeEffect(EffectChain& aEffectChain); diff --git a/gfx/layers/composite/PaintedLayerComposite.cpp b/gfx/layers/composite/PaintedLayerComposite.cpp index 6aae61f364..a096e71076 100644 --- a/gfx/layers/composite/PaintedLayerComposite.cpp +++ b/gfx/layers/composite/PaintedLayerComposite.cpp @@ -7,7 +7,6 @@ #include "CompositableHost.h" // for TiledLayerProperties, etc #include "FrameMetrics.h" // for FrameMetrics #include "Units.h" // for CSSRect, LayerPixel, etc -#include "gfx2DGlue.h" // for ToMatrix4x4 #include "gfxUtils.h" // for gfxUtils, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/gfx/Matrix.h" // for Matrix4x4 @@ -29,8 +28,6 @@ namespace mozilla { namespace layers { -class TiledLayerComposer; - PaintedLayerComposite::PaintedLayerComposite(LayerManagerComposite *aManager) : PaintedLayer(aManager, nullptr) , LayerComposite(aManager) @@ -91,16 +88,6 @@ PaintedLayerComposite::SetLayerManager(LayerManagerComposite* aManager) } } -TiledLayerComposer* -PaintedLayerComposite::GetTiledLayerComposer() -{ - if (!mBuffer) { - return nullptr; - } - MOZ_ASSERT(mBuffer->IsAttached()); - return mBuffer->AsTiledLayerComposer(); -} - LayerRenderState PaintedLayerComposite::GetRenderState() { diff --git a/gfx/layers/composite/PaintedLayerComposite.h b/gfx/layers/composite/PaintedLayerComposite.h index 01cd5bf471..c4107d6a9b 100644 --- a/gfx/layers/composite/PaintedLayerComposite.h +++ b/gfx/layers/composite/PaintedLayerComposite.h @@ -28,7 +28,6 @@ namespace layers { class CompositableHost; class ContentHost; -class TiledLayerComposer; class PaintedLayerComposite : public PaintedLayer, public LayerComposite @@ -52,8 +51,6 @@ public: virtual void SetLayerManager(LayerManagerComposite* aManager) override; - virtual TiledLayerComposer* GetTiledLayerComposer() override; - virtual void RenderLayer(const gfx::IntRect& aClipRect) override; virtual void CleanupResources() override; diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index bcc41ad511..1d395c0003 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -408,7 +408,6 @@ TiledContentHost::Composite(EffectChain& aEffectChain, void TiledContentHost::RenderTile(TileHost& aTile, - const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, @@ -416,22 +415,10 @@ TiledContentHost::RenderTile(TileHost& aTile, const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, const IntPoint& aTextureOffset, - const nsIntSize& aTextureBounds) + const IntSize& aTextureBounds, + const gfx::Rect& aVisibleRect) { - if (aTile.IsPlaceholderTile()) { - // This shouldn't ever happen, but let's fail semi-gracefully. No need - // to warn, the texture update would have already caught this. - return; - } - - if (aBackgroundColor) { - aEffectChain.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); - nsIntRegionRectIterator it(aScreenRegion); - for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { - Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); - mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, 1.0, aTransform); - } - } + MOZ_ASSERT(!aTile.IsPlaceholderTile()); AutoLockTextureHost autoLock(aTile.mTextureHost); AutoLockTextureHost autoLockOnWhite(aTile.mTextureHostOnWhite); @@ -471,7 +458,7 @@ TiledContentHost::RenderTile(TileHost& aTile, textureRect.y / aTextureBounds.height, textureRect.width / aTextureBounds.width, textureRect.height / aTextureBounds.height); - mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform); + mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform, aVisibleRect); } DiagnosticFlags flags = DiagnosticFlags::CONTENT | DiagnosticFlags::TILE; if (aTile.mTextureHostOnWhite) { @@ -499,9 +486,9 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, float resolution = aLayerBuffer.GetResolution(); gfx::Size layerScale(1, 1); - // We assume that the current frame resolution is the one used in our high - // precision layer buffer. Compensate for a changing frame resolution when - // rendering the low precision buffer. + // Make sure we don't render at low resolution where we have valid high + // resolution content, to avoid overdraw and artifacts with semi-transparent + // layers. if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) { const CSSToParentLayerScale2D& layerResolution = aLayerBuffer.GetFrameResolution(); const CSSToParentLayerScale2D& localResolution = mTiledBuffer.GetFrameResolution(); @@ -528,53 +515,57 @@ TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, DiagnosticFlags componentAlphaDiagnostic = DiagnosticFlags::NO_DIAGNOSTIC; - uint32_t rowCount = 0; - uint32_t tileX = 0; + nsIntRegion compositeRegion = aLayerBuffer.GetValidRegion(); + compositeRegion.AndWith(aVisibleRegion); + compositeRegion.SubOut(maskRegion); + IntRect visibleRect = aVisibleRegion.GetBounds(); - gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize(); - for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { - rowCount++; - int32_t tileStartX = aLayerBuffer.GetTileStart(x, scaledTileSize.width); - int32_t w = scaledTileSize.width - tileStartX; - if (x + w > visibleRect.x + visibleRect.width) { - w = visibleRect.x + visibleRect.width - x; - } - int tileY = 0; - for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { - int32_t tileStartY = aLayerBuffer.GetTileStart(y, scaledTileSize.height); - int32_t h = scaledTileSize.height - tileStartY; - if (y + h > visibleRect.y + visibleRect.height) { - h = visibleRect.y + visibleRect.height - y; - } - nsIntPoint tileOrigin = nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width), - aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height)); - TileHost& tileTexture = aLayerBuffer.GetTile(tileOrigin); - if (!tileTexture.IsPlaceholderTile()) { - nsIntRegion tileDrawRegion; - tileDrawRegion.And(IntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); - tileDrawRegion.And(tileDrawRegion, aVisibleRegion); - tileDrawRegion.Sub(tileDrawRegion, maskRegion); - - if (!tileDrawRegion.IsEmpty()) { - tileDrawRegion.ScaleRoundOut(resolution, resolution); - IntPoint tileOffset((x - tileStartX) * resolution, - (y - tileStartY) * resolution); - gfx::IntSize tileSize = aLayerBuffer.GetTileSize(); - RenderTile(tileTexture, aBackgroundColor, aEffectChain, aOpacity, aTransform, - aFilter, aClipRect, tileDrawRegion, tileOffset, - nsIntSize(tileSize.width, tileSize.height)); - if (tileTexture.mTextureHostOnWhite) { - componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA; - } - } - } - tileY++; - y += h; - } - tileX++; - x += w; + if (compositeRegion.IsEmpty()) { + return; } + + if (aBackgroundColor) { + nsIntRegion backgroundRegion = compositeRegion; + backgroundRegion.ScaleRoundOut(resolution, resolution); + EffectChain effect; + effect.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); + nsIntRegionRectIterator it(backgroundRegion); + for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { + Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); + mCompositor->DrawQuad(graphicsRect, aClipRect, effect, 1.0, aTransform); + } + } + + for (size_t i = 0; i < aLayerBuffer.GetTileCount(); ++i) { + TileHost& tile = aLayerBuffer.GetTile(i); + if (tile.IsPlaceholderTile()) { + continue; + } + + TileIntPoint tilePosition = aLayerBuffer.GetPlacement().TilePosition(i); + // A sanity check that catches a lot of mistakes. + MOZ_ASSERT(tilePosition.x == tile.x && tilePosition.y == tile.y); + + IntPoint tileOffset = aLayerBuffer.GetTileOffset(tilePosition); + nsIntRegion tileDrawRegion = IntRect(tileOffset, aLayerBuffer.GetScaledTileSize()); + tileDrawRegion.AndWith(compositeRegion); + + if (tileDrawRegion.IsEmpty()) { + continue; + } + + tileDrawRegion.ScaleRoundOut(resolution, resolution); + RenderTile(tile, aEffectChain, aOpacity, + aTransform, aFilter, aClipRect, tileDrawRegion, + tileOffset * resolution, aLayerBuffer.GetTileSize(), + gfx::Rect(visibleRect.x, visibleRect.y, + visibleRect.width, visibleRect.height)); + if (tile.mTextureHostOnWhite) { + componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA; + } + } + gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTENT | componentAlphaDiagnostic, diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index e547799566..beb155ecd4 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -167,8 +167,6 @@ public: static void RecycleCallback(TextureHost* textureHost, void* aClosure); protected: - void SwapTiles(TileHost& aTileA, TileHost& aTileB) { std::swap(aTileA, aTileB); } - CSSToParentLayerScale2D mFrameResolution; }; @@ -192,8 +190,7 @@ protected: * buffer after compositing a new one. Rendering takes us to RenderTile which * is similar to Composite for non-tiled ContentHosts. */ -class TiledContentHost : public ContentHost, - public TiledLayerComposer +class TiledContentHost : public ContentHost { public: explicit TiledContentHost(const TextureInfo& aTextureInfo); @@ -217,12 +214,12 @@ public: return false; } - const nsIntRegion& GetValidLowPrecisionRegion() const override + const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionTiledBuffer.GetValidRegion(); } - const nsIntRegion& GetValidRegion() const override + const nsIntRegion& GetValidRegion() const { return mTiledBuffer.GetValidRegion(); } @@ -235,8 +232,8 @@ public: mLowPrecisionTiledBuffer.SetCompositor(aCompositor); } - virtual bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, - const SurfaceDescriptorTiles& aTiledDescriptor) override; + bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, + const SurfaceDescriptorTiles& aTiledDescriptor); void Composite(EffectChain& aEffectChain, float aOpacity, @@ -247,7 +244,7 @@ public: virtual CompositableType GetType() override { return CompositableType::CONTENT_TILED; } - virtual TiledLayerComposer* AsTiledLayerComposer() override { return this; } + virtual TiledContentHost* AsTiledContentHost() override { return this; } virtual void Attach(Layer* aLayer, Compositor* aCompositor, @@ -275,7 +272,6 @@ private: // Renders a single given tile. void RenderTile(TileHost& aTile, - const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, @@ -283,7 +279,8 @@ private: const gfx::Rect& aClipRect, const nsIntRegion& aScreenRegion, const gfx::IntPoint& aTextureOffset, - const gfx::IntSize& aTextureBounds); + const gfx::IntSize& aTextureBounds, + const gfx::Rect& aVisibleRect); void EnsureTileStore() {} diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index bb4ceee851..d0117b1840 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -745,7 +745,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain& aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4& aTransform) + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) { if (mCurrentClip.IsEmpty()) { return; @@ -1022,7 +1023,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, return; } - nsIntSize oldSize = mSize; + IntSize oldSize = mSize; UpdateRenderTarget(); // Failed to create a render target or the view. @@ -1096,7 +1097,7 @@ CompositorD3D11::EndFrame() mContext->Flush(); - nsIntSize oldSize = mSize; + IntSize oldSize = mSize; EnsureSize(); UINT presentInterval = 0; diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index 4227512095..394560381a 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -94,7 +94,8 @@ public: const gfx::Rect &aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) override; + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) override; /* Helper for when the primary effect is VR_DISTORTION */ void DrawVRDistortion(const gfx::Rect &aRect, diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index c175fc61ad..7251fccad1 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -245,7 +245,8 @@ CompositorD3D9::DrawQuad(const gfx::Rect &aRect, const gfx::Rect &aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) { if (!mDeviceManager) { return; @@ -671,7 +672,7 @@ CompositorD3D9::EndFrame() if (mDeviceManager) { device()->EndScene(); - nsIntSize oldSize = mSize; + IntSize oldSize = mSize; EnsureSize(); if (oldSize == mSize) { if (mTarget) { diff --git a/gfx/layers/d3d9/CompositorD3D9.h b/gfx/layers/d3d9/CompositorD3D9.h index c6aba0e9c1..54bf776635 100644 --- a/gfx/layers/d3d9/CompositorD3D9.h +++ b/gfx/layers/d3d9/CompositorD3D9.h @@ -7,6 +7,7 @@ #define MOZILLA_GFX_COMPOSITORD3D9_H #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Point.h" #include "gfx2DGlue.h" #include "mozilla/layers/Compositor.h" #include "mozilla/layers/TextureD3D9.h" @@ -57,7 +58,8 @@ public: const gfx::Rect &aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) override; + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) override; virtual void BeginFrame(const nsIntRegion& aInvalidRegion, const gfx::Rect *aClipRectIn, @@ -167,7 +169,7 @@ private: RefPtr mDefaultRT; RefPtr mCurrentRT; - nsIntSize mSize; + gfx::IntSize mSize; uint32_t mDeviceResetCount; uint32_t mFailedResetAttemps; diff --git a/gfx/layers/ipc/CompositableTransactionParent.cpp b/gfx/layers/ipc/CompositableTransactionParent.cpp index 6b5a412933..574fff41d9 100644 --- a/gfx/layers/ipc/CompositableTransactionParent.cpp +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp @@ -11,7 +11,6 @@ #include "GLContext.h" // for GLContext #include "Layers.h" // for Layer #include "RenderTrace.h" // for RenderTraceInvalidateEnd, etc -#include "TiledLayerBuffer.h" // for TiledLayerComposer #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/RefPtr.h" // for RefPtr #include "mozilla/layers/CompositorTypes.h" @@ -23,6 +22,7 @@ #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG #include "mozilla/layers/TextureHost.h" // for TextureHost #include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL +#include "mozilla/layers/TiledContentHost.h" #include "mozilla/layers/PaintedLayerComposite.h" #include "mozilla/mozalloc.h" // for operator delete #include "mozilla/unused.h" @@ -112,13 +112,12 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); - CompositableHost* compositable = AsCompositable(op); + TiledContentHost* compositable = AsCompositable(op)->AsTiledContentHost(); - TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); - NS_ASSERTION(tileComposer, "compositable is not a tile composer"); + NS_ASSERTION(compositable, "The compositable is not tiled"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); - bool success = tileComposer->UseTiledLayerBuffer(this, tileDesc); + bool success = compositable->UseTiledLayerBuffer(this, tileDesc); if (!success) { return false; } diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index dd616323bb..626cc7d367 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -481,7 +481,7 @@ protected: bool mPaused; bool mUseExternalSurfaceSize; - nsIntSize mEGLSurfaceSize; + gfx::IntSize mEGLSurfaceSize; mozilla::Monitor mPauseCompositionMonitor; mozilla::Monitor mResumeCompositionMonitor; diff --git a/gfx/layers/ipc/SharedRGBImage.cpp b/gfx/layers/ipc/SharedRGBImage.cpp index a87c4d6dd2..5338fab290 100644 --- a/gfx/layers/ipc/SharedRGBImage.cpp +++ b/gfx/layers/ipc/SharedRGBImage.cpp @@ -28,7 +28,7 @@ namespace layers { already_AddRefed CreateSharedRGBImage(ImageContainer *aImageContainer, - nsIntSize aSize, + gfx::IntSize aSize, gfxImageFormat aImageFormat) { NS_ASSERTION(aImageFormat == gfxImageFormat::ARGB32 || diff --git a/gfx/layers/ipc/SharedRGBImage.h b/gfx/layers/ipc/SharedRGBImage.h index 70a4305b84..9bb0b03f25 100644 --- a/gfx/layers/ipc/SharedRGBImage.h +++ b/gfx/layers/ipc/SharedRGBImage.h @@ -23,7 +23,7 @@ class ImageClient; class TextureClient; already_AddRefed CreateSharedRGBImage(ImageContainer* aImageContainer, - nsIntSize aSize, + gfx::IntSize aSize, gfxImageFormat aImageFormat); /** diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 2171062fc9..20a7e6db34 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -128,6 +128,7 @@ EXPORTS.mozilla.layers += [ 'composite/LayerManagerComposite.h', 'composite/PaintedLayerComposite.h', 'composite/TextureHost.h', + 'composite/TiledContentHost.h', 'Compositor.h', 'CompositorTypes.h', 'D3D11ShareHandleImage.h', diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index eefcdefb3c..6a2af2f27e 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -41,7 +41,6 @@ #include "ScopedGLHelpers.h" #include "GLReadTexImageHelper.h" #include "GLBlitTextureImageHelper.h" -#include "TiledLayerBuffer.h" // for TiledLayerComposer #include "HeapCopyOfStackArray.h" #if MOZ_WIDGET_ANDROID @@ -87,7 +86,7 @@ CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth, , mUseExternalSurfaceSize(aUseExternalSurfaceSize) , mFrameInProgress(false) , mDestroyed(false) - , mHeight(0) + , mViewportSize(0, 0) , mCurrentProgram(nullptr) { MOZ_COUNT_CTOR(CompositorOGL); @@ -441,7 +440,7 @@ CompositorOGL::PrepareViewport(const gfx::IntSize& aSize) // Set the viewport correctly. mGLContext->fViewport(0, 0, aSize.width, aSize.height); - mHeight = aSize.height; + mViewportSize = aSize; // We flip the view matrix around so that everything is right-side up; we're // drawing directly into the window's back buffer, so this keeps things @@ -575,7 +574,7 @@ void CompositorOGL::ClearRect(const gfx::Rect& aRect) { // Map aRect to OGL coordinates, origin:bottom-left - GLint y = mHeight - (aRect.y + aRect.height); + GLint y = mViewportSize.height - (aRect.y + aRect.height); ScopedGLState scopedScissorTestState(mGLContext, LOCAL_GL_SCISSOR_TEST, true); ScopedScissorRect autoScissorRect(mGLContext, aRect.x, y, aRect.width, aRect.height); @@ -770,7 +769,8 @@ ShaderConfigOGL CompositorOGL::GetShaderConfigFor(Effect *aEffect, MaskType aMask, gfx::CompositionOp aOp, - bool aColorMatrix) const + bool aColorMatrix, + bool aDEAAEnabled) const { ShaderConfigOGL config; @@ -821,6 +821,7 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect, config.SetColorMatrix(aColorMatrix); config.SetMask2D(aMask == MaskType::Mask2d); config.SetMask3D(aMask == MaskType::Mask3d); + config.SetDEAA(aDEAAEnabled); return config; } @@ -902,12 +903,41 @@ static bool SetBlendMode(GLContext* aGL, gfx::CompositionOp aBlendMode, bool aIs return true; } +gfx::Point3D +CompositorOGL::GetLineCoefficients(const gfx::Point& aPoint1, + const gfx::Point& aPoint2) +{ + // Return standard coefficients for a line between aPoint1 and aPoint2 + // for standard line equation: + // + // Ax + By + C = 0 + // + // A = (p1.y – p2.y) + // B = (p2.x – p1.x) + // C = (p1.x * p2.y) – (p2.x * p1.y) + + gfx::Point3D coeffecients; + coeffecients.x = aPoint1.y - aPoint2.y; + coeffecients.y = aPoint2.x - aPoint1.x; + coeffecients.z = aPoint1.x * aPoint2.y - aPoint2.x * aPoint1.y; + + coeffecients *= 1.0f / sqrtf(coeffecients.x * coeffecients.x + + coeffecients.y * coeffecients.y); + + // Offset outwards by 0.5 pixel as the edge is considered to be 1 pixel + // wide and included within the interior of the polygon + coeffecients.z += 0.5f; + + return coeffecients; +} + void CompositorOGL::DrawQuad(const Rect& aRect, const Rect& aClipRect, const EffectChain &aEffectChain, Float aOpacity, - const gfx::Matrix4x4 &aTransform) + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) { PROFILER_LABEL("CompositorOGL", "DrawQuad", js::ProfileEntry::Category::GRAPHICS); @@ -1000,8 +1030,15 @@ CompositorOGL::DrawQuad(const Rect& aRect, blendMode = blendEffect->mBlendMode; } + // Only apply DEAA to quads that have been transformed such that aliasing + // could be visible + bool bEnableAA = gfxPrefs::LayersDEAAEnabled() && + !aTransform.Is2DIntegerTranslation(); + bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX]; - ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode, colorMatrix); + ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, + maskType, blendMode, colorMatrix, + bEnableAA); config.SetOpacity(aOpacity != 1.f); ShaderProgramOGL *program = GetShaderProgramFor(config); ActivateProgram(program); @@ -1028,6 +1065,74 @@ CompositorOGL::DrawQuad(const Rect& aRect, program->SetTexCoordMultiplier(source->GetSize().width, source->GetSize().height); } + // XXX kip - These calculations could be performed once per layer rather than + // for every tile. This might belong in Compositor.cpp once DEAA + // is implemented for DirectX. + if (bEnableAA) { + // Calculate the transformed vertices of aVisibleRect in screen space + // pixels, mirroring the calculations in the vertex shader + Matrix4x4 flatTransform = aTransform; + flatTransform.PostTranslate(-offset.x, -offset.y, 0.0f); + flatTransform *= mProjMatrix; + + Rect viewportClip = Rect(-1.0f, -1.0f, 2.0f, 2.0f); + size_t edgeCount = 0; + Point3D coefficients[4]; + + Point points[Matrix4x4::kTransformAndClipRectMaxVerts]; + size_t pointCount = flatTransform.TransformAndClipRect(aVisibleRect, viewportClip, points); + for (size_t i = 0; i < pointCount; i++) { + points[i] = Point((points[i].x * 0.5f + 0.5f) * mViewportSize.width, + (points[i].y * 0.5f + 0.5f) * mViewportSize.height); + } + if (pointCount > 2) { + // Use shoelace formula on a triangle in the clipped quad to determine if + // winding order is reversed. Iterate through the triangles until one is + // found with a non-zero area. + float winding = 0.0f; + size_t wp = 0; + while (winding == 0.0f && wp < pointCount) { + int wp1 = (wp + 1) % pointCount; + int wp2 = (wp + 2) % pointCount; + winding = (points[wp1].x - points[wp].x) * (points[wp1].y + points[wp].y) + + (points[wp2].x - points[wp1].x) * (points[wp2].y + points[wp1].y) + + (points[wp].x - points[wp2].x) * (points[wp].y + points[wp2].y); + wp++; + } + bool frontFacing = winding >= 0.0f; + + // Calculate the line coefficients used by the DEAA shader to determine the + // sub-pixel coverage of the edge pixels + for (size_t i=0; iSetLayerTransformInverse(transformInverted); + program->SetDEAAEdges(coefficients); + program->SetVisibleCenter(aVisibleRect.Center()); + program->SetViewportSize(mViewportSize); + } + bool didSetBlendMode = false; switch (aEffectChain.mPrimaryEffect->mType) { @@ -1126,9 +1231,7 @@ CompositorOGL::DrawQuad(const Rect& aRect, program->SetTextureUnit(0); if (maskType != MaskType::MaskNone) { - sourceMask->BindTexture(LOCAL_GL_TEXTURE1, gfx::Filter::LINEAR); - program->SetMaskTextureUnit(1); - program->SetMaskLayerTransform(maskQuadTransform); + BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform); } if (config.mFeatures & ENABLE_TEXTURE_RECT) { diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index d1e1bbbb9c..0d32798371 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -228,7 +228,8 @@ public: const gfx::Rect& aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, - const gfx::Matrix4x4 &aTransform) override; + const gfx::Matrix4x4& aTransform, + const gfx::Rect& aVisibleRect) override; virtual void EndFrame() override; virtual void SetDispAcquireFence(Layer* aLayer) override; @@ -334,7 +335,7 @@ private: gfx::Matrix4x4 mProjMatrix; /** The size of the surface we are rendering to */ - nsIntSize mSurfaceSize; + gfx::IntSize mSurfaceSize; ScreenPoint mRenderOffset; @@ -386,7 +387,8 @@ private: ShaderConfigOGL GetShaderConfigFor(Effect *aEffect, MaskType aMask = MaskType::MaskNone, gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER, - bool aColorMatrix = false) const; + bool aColorMatrix = false, + bool aDEAAEnabled = false) const; ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig); /** @@ -417,7 +419,8 @@ private: const gfx::Rect& aRect, const gfx::Rect& aTexCoordRect, TextureSource *aTexture); - + gfx::Point3D GetLineCoefficients(const gfx::Point& aPoint1, + const gfx::Point& aPoint2); void ActivateProgram(ShaderProgramOGL *aProg); void CleanupResources(); @@ -436,7 +439,7 @@ private: * y-axis pointing downwards, for good reason as Web pages are typically * scrolled downwards. So, some flipping has to take place; FlippedY does it. */ - GLint FlipY(GLint y) const { return mHeight - y; } + GLint FlipY(GLint y) const { return mViewportSize.height - y; } RefPtr mTexturePool; @@ -445,10 +448,10 @@ private: bool mDestroyed; /** - * Height of the OpenGL context's primary framebuffer in pixels. Used by - * FlipY for the y-flipping calculation. + * Size of the OpenGL context's primary framebuffer in pixels. Used by + * FlipY for the y-flipping calculation and by the DEAA shader. */ - GLint mHeight; + gfx::IntSize mViewportSize; FenceHandle mReleaseFenceHandle; ShaderProgramOGL *mCurrentProgram; diff --git a/gfx/layers/opengl/CompositorOGLVR.cpp b/gfx/layers/opengl/CompositorOGLVR.cpp index 9bed2fbeb2..1ae8faddc6 100644 --- a/gfx/layers/opengl/CompositorOGLVR.cpp +++ b/gfx/layers/opengl/CompositorOGLVR.cpp @@ -19,7 +19,6 @@ #include "Layers.h" // for WriteSnapshotToDumpFile #include "LayerScope.h" // for LayerScope #include "gfx2DGlue.h" // for ThebesFilter -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxMatrix.h" // for gfxMatrix #include "GraphicsFilter.h" // for GraphicsFilter #include "gfxPlatform.h" // for gfxPlatform diff --git a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp index a0ae692c0c..6a63d0703b 100644 --- a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp +++ b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp @@ -14,6 +14,7 @@ #include "gfx2DGlue.h" #include "gfxUtils.h" #include "CompositorOGL.h" +#include "mozilla/gfx/Point.h" using namespace mozilla::gl; @@ -110,8 +111,8 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const gfx::IntRec srcSubInDstRect.MoveBy(aDstRect.TopLeft()); // we transform these rectangles to be relative to the current src and dst tiles, respectively - nsIntSize srcSize = srcTextureRect.Size(); - nsIntSize dstSize = dstTextureRect.Size(); + gfx::IntSize srcSize = srcTextureRect.Size(); + gfx::IntSize dstSize = dstTextureRect.Size(); srcSubRect.MoveBy(-srcTextureRect.x, -srcTextureRect.y); srcSubInDstRect.MoveBy(-dstTextureRect.x, -dstTextureRect.y); @@ -123,10 +124,10 @@ GLBlitTextureImageHelper::BlitTextureImage(TextureImage *aSrc, const gfx::IntRec RectTriangles rects; - nsIntSize realTexSize = srcSize; + gfx::IntSize realTexSize = srcSize; if (!CanUploadNonPowerOfTwo(gl)) { - realTexSize = nsIntSize(gfx::NextPowerOfTwo(srcSize.width), - gfx::NextPowerOfTwo(srcSize.height)); + realTexSize = gfx::IntSize(gfx::NextPowerOfTwo(srcSize.width), + gfx::NextPowerOfTwo(srcSize.height)); } if (aSrc->GetWrapMode() == LOCAL_GL_REPEAT) { diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index 44b9df2468..c877230bd0 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -30,6 +30,7 @@ AddUniforms(ProgramProfileOGL& aProfile) // This needs to be kept in sync with the KnownUniformName enum static const char *sKnownUniformNames[] = { "uLayerTransform", + "uLayerTransformInverse", "uMaskTransform", "uLayerRects", "uMatrixProj", @@ -53,6 +54,9 @@ AddUniforms(ProgramProfileOGL& aProfile) "uBlurOffset", "uBlurAlpha", "uBlurGaussianKernel", + "uSSEdges", + "uViewportSize", + "uVisibleCenter", nullptr }; @@ -142,6 +146,12 @@ ShaderConfigOGL::SetPremultiply(bool aEnabled) SetFeature(ENABLE_PREMULTIPLY, aEnabled); } +void +ShaderConfigOGL::SetDEAA(bool aEnabled) +{ + SetFeature(ENABLE_DEAA, aEnabled); +} + /* static */ ProgramProfileOGL ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) { @@ -153,8 +163,13 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) vs << "uniform mat4 uMatrixProj;" << endl; vs << "uniform vec4 uLayerRects[4];" << endl; vs << "uniform mat4 uLayerTransform;" << endl; - vs << "uniform vec4 uRenderTargetOffset;" << endl; - + if (aConfig.mFeatures & ENABLE_DEAA) { + vs << "uniform mat4 uLayerTransformInverse;" << endl; + vs << "uniform vec3 uSSEdges[4];" << endl; + vs << "uniform vec2 uVisibleCenter;" << endl; + vs << "uniform vec2 uViewportSize;" << endl; + } + vs << "uniform vec2 uRenderTargetOffset;" << endl; vs << "attribute vec4 aCoord;" << endl; if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { @@ -174,27 +189,78 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) vs << " vec4 layerRect = uLayerRects[vertexID];" << endl; vs << " vec4 finalPosition = vec4(aCoord.xy * layerRect.zw + layerRect.xy, 0.0, 1.0);" << endl; vs << " finalPosition = uLayerTransform * finalPosition;" << endl; - vs << " finalPosition.xyz /= finalPosition.w;" << endl; - if (aConfig.mFeatures & ENABLE_MASK_3D) { - vs << " vMaskCoord.xy = (uMaskTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl; - // correct for perspective correct interpolation, see comment in D3D10 shader - vs << " vMaskCoord.z = 1.0;" << endl; - vs << " vMaskCoord *= finalPosition.w;" << endl; - } else if (aConfig.mFeatures & ENABLE_MASK_2D) { - vs << " vMaskCoord.xy = (uMaskTransform * finalPosition).xy;" << endl; - } + if (aConfig.mFeatures & ENABLE_DEAA) { + // XXX kip - The DEAA shader could be made simpler if we switch to + // using dynamic vertex buffers instead of sending everything + // in through uniforms. This would enable passing information + // about how to dilate each vertex explicitly and eliminate the + // need to extrapolate this with the sub-pixel coverage + // calculation in the vertex shader. - vs << " finalPosition = finalPosition - uRenderTargetOffset;" << endl; - vs << " finalPosition.xyz *= finalPosition.w;" << endl; - vs << " finalPosition = uMatrixProj * finalPosition;" << endl; + // Calculate the screen space position of this vertex, in screen pixels + vs << " vec4 ssPos = finalPosition;" << endl; + vs << " ssPos.xy -= uRenderTargetOffset * finalPosition.w;" << endl; + vs << " ssPos = uMatrixProj * ssPos;" << endl; + vs << " ssPos.xy = ((ssPos.xy/ssPos.w)*0.5+0.5)*uViewportSize;" << endl; - if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { + if (aConfig.mFeatures & ENABLE_MASK_2D || + aConfig.mFeatures & ENABLE_MASK_3D || + !(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { + vs << " vec4 coordAdjusted;" << endl; + vs << " coordAdjusted.xy = aCoord.xy;" << endl; + } + + // It is necessary to dilate edges away from uVisibleCenter to ensure that + // fragments with less than 50% sub-pixel coverage will be shaded. + // This offset is applied when the sub-pixel coverage of the vertex is + // less than 100%. Expanding by 0.5 pixels in screen space is sufficient + // to include these pixels. + vs << " if (dot(uSSEdges[0], vec3(ssPos.xy, 1.0)) < 1.5 ||" << endl; + vs << " dot(uSSEdges[1], vec3(ssPos.xy, 1.0)) < 1.5 ||" << endl; + vs << " dot(uSSEdges[2], vec3(ssPos.xy, 1.0)) < 1.5 ||" << endl; + vs << " dot(uSSEdges[3], vec3(ssPos.xy, 1.0)) < 1.5) {" << endl; + // If the shader reaches this branch, then this vertex is on the edge of + // the layer's visible rect and should be dilated away from the center of + // the visible rect. We don't want to hit this for inner facing + // edges between tiles, as the pixels may be covered twice without clipping + // against uSSEdges. If all edges were dilated, it would result in + // artifacts visible within semi-transparent layers with multiple tiles. + vs << " vec4 visibleCenter = uLayerTransform * vec4(uVisibleCenter, 0.0, 1.0);" << endl; + vs << " vec2 dilateDir = finalPosition.xy / finalPosition.w - visibleCenter.xy / visibleCenter.w;" << endl; + vs << " vec2 offset = sign(dilateDir) * 0.5;" << endl; + vs << " finalPosition.xy += offset * finalPosition.w;" << endl; + if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { + // We must adjust the texture coordinates to compensate for the dilation + vs << " coordAdjusted = uLayerTransformInverse * finalPosition;" << endl; + vs << " coordAdjusted /= coordAdjusted.w;" << endl; + vs << " coordAdjusted.xy -= layerRect.xy;" << endl; + vs << " coordAdjusted.xy /= layerRect.zw;" << endl; + } + vs << " }" << endl; + + if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { + vs << " vec4 textureRect = uTextureRects[vertexID];" << endl; + vs << " vec2 texCoord = coordAdjusted.xy * textureRect.zw + textureRect.xy;" << endl; + vs << " vTexCoord = (uTextureTransform * vec4(texCoord, 0.0, 1.0)).xy;" << endl; + } + + } else if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { vs << " vec4 textureRect = uTextureRects[vertexID];" << endl; vs << " vec2 texCoord = aCoord.xy * textureRect.zw + textureRect.xy;" << endl; vs << " vTexCoord = (uTextureTransform * vec4(texCoord, 0.0, 1.0)).xy;" << endl; } - + if (aConfig.mFeatures & ENABLE_MASK_2D || + aConfig.mFeatures & ENABLE_MASK_3D) { + vs << " vMaskCoord.xy = (uMaskTransform * (finalPosition / finalPosition.w)).xy;" << endl; + if (aConfig.mFeatures & ENABLE_MASK_3D) { + // correct for perspective correct interpolation, see comment in D3D10 shader + vs << " vMaskCoord.z = 1.0;" << endl; + vs << " vMaskCoord *= finalPosition.w;" << endl; + } + } + vs << " finalPosition.xy -= uRenderTargetOffset * finalPosition.w;" << endl; + vs << " finalPosition = uMatrixProj * finalPosition;" << endl; vs << " gl_Position = finalPosition;" << endl; vs << "}" << endl; @@ -261,6 +327,10 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) fs << "uniform sampler2D uMaskTexture;" << endl; } + if (aConfig.mFeatures & ENABLE_DEAA) { + fs << "uniform vec3 uSSEdges[4];" << endl; + } + if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { fs << "vec4 sample(vec2 coord) {" << endl; fs << " vec4 color;" << endl; @@ -353,6 +423,16 @@ For [0,1] instead of [0,255], and to 5 places: fs << " color.rgb *= color.a;" << endl; } } + if (aConfig.mFeatures & ENABLE_DEAA) { + // Calculate the sub-pixel coverage of the pixel and modulate its opacity + // by that amount to perform DEAA. + fs << " vec3 ssPos = vec3(gl_FragCoord.xy, 1.0);" << endl; + fs << " float deaaCoverage = clamp(dot(uSSEdges[0], ssPos), 0.0, 1.0);" << endl; + fs << " deaaCoverage *= clamp(dot(uSSEdges[1], ssPos), 0.0, 1.0);" << endl; + fs << " deaaCoverage *= clamp(dot(uSSEdges[2], ssPos), 0.0, 1.0);" << endl; + fs << " deaaCoverage *= clamp(dot(uSSEdges[3], ssPos), 0.0, 1.0);" << endl; + fs << " color *= deaaCoverage;" << endl; + } if (aConfig.mFeatures & ENABLE_MASK_3D) { fs << " vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;" << endl; fs << " COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;" << endl; diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index ffa4822e0f..170c9dea3e 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -40,7 +40,8 @@ enum ShaderFeatures { ENABLE_COLOR_MATRIX=0x200, ENABLE_MASK_2D=0x400, ENABLE_MASK_3D=0x800, - ENABLE_PREMULTIPLY=0x1000 + ENABLE_PREMULTIPLY=0x1000, + ENABLE_DEAA=0x2000 }; class KnownUniform { @@ -50,6 +51,7 @@ public: NotAKnownUniform = -1, LayerTransform = 0, + LayerTransformInverse, MaskTransform, LayerRects, MatrixProj, @@ -73,6 +75,9 @@ public: BlurOffset, BlurAlpha, BlurGaussianKernel, + SSEdges, + ViewportSize, + VisibleCenter, KnownUniformCount }; @@ -163,6 +168,30 @@ public: return false; } + bool UpdateArrayUniform(int cnt, const gfx::Point3D* points) { + if (mLocation == -1) return false; + if (cnt > 4) { + return false; + } + + float fp[12]; + float *d = fp; + for(int i=0; i < cnt; i++) { + // Note: Do not want to make assumptions about .x, .y, .z member packing. + // If gfx::Point3D is updated to make this guarantee, SIMD optimizations + // may be possible + *d++ = points[i].x; + *d++ = points[i].y; + *d++ = points[i].z; + } + + if (memcmp(mValue.f16v, fp, sizeof(float) * cnt * 3) != 0) { + memcpy(mValue.f16v, fp, sizeof(float) * cnt * 3); + return true; + } + return false; + } + KnownUniformName mName; const char *mNameString; int32_t mLocation; @@ -192,6 +221,7 @@ public: void SetMask2D(bool aEnabled); void SetMask3D(bool aEnabled); void SetPremultiply(bool aEnabled); + void SetDEAA(bool aEnabled); bool operator< (const ShaderConfigOGL& other) const { return mFeatures < other.mFeatures; @@ -303,10 +333,28 @@ public: SetMatrixUniform(KnownUniform::LayerTransform, aMatrix); } + void SetLayerTransformInverse(const gfx::Matrix4x4& aMatrix) { + SetMatrixUniform(KnownUniform::LayerTransformInverse, aMatrix); + } + void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) { SetMatrixUniform(KnownUniform::MaskTransform, aMatrix); } + void SetDEAAEdges(const gfx::Point3D* aEdges) { + SetArrayUniform(KnownUniform::SSEdges, 4, aEdges); + } + + void SetViewportSize(const gfx::IntSize& aSize) { + float vals[2] = { (float)aSize.width, (float)aSize.height }; + SetUniform(KnownUniform::ViewportSize, 2, vals); + } + + void SetVisibleCenter(const gfx::Point& aVisibleCenter) { + float vals[2] = { aVisibleCenter.x, aVisibleCenter.y }; + SetUniform(KnownUniform::VisibleCenter, 2, vals); + } + void SetLayerRects(const gfx::Rect* aRects) { float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].width, aRects[0].height, aRects[1].x, aRects[1].y, aRects[1].width, aRects[1].height, @@ -333,13 +381,13 @@ public: } void SetRenderOffset(const nsIntPoint& aOffset) { - float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f }; - SetUniform(KnownUniform::RenderTargetOffset, 4, vals); + float vals[4] = { float(aOffset.x), float(aOffset.y) }; + SetUniform(KnownUniform::RenderTargetOffset, 2, vals); } void SetRenderOffset(float aX, float aY) { - float vals[4] = { aX, aY, 0.0f, 0.0f }; - SetUniform(KnownUniform::RenderTargetOffset, 4, vals); + float vals[2] = { aX, aY }; + SetUniform(KnownUniform::RenderTargetOffset, 2, vals); } void SetLayerOpacity(float aOpacity) { @@ -497,6 +545,17 @@ protected: } } + void SetArrayUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const gfx::Point3D *aPointValues) + { + ASSERT_THIS_PROGRAM; + NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); + + KnownUniform& ku(mProfile.mUniforms[aKnownUniform]); + if (ku.UpdateArrayUniform(aLength, aPointValues)) { + mGL->fUniform3fv(ku.mLocation, aLength, ku.mValue.f16v); + } + } + void SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue) { ASSERT_THIS_PROGRAM; NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index d4b31e732a..34d200bab6 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -183,7 +183,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, } void -TextureImageTextureSourceOGL::EnsureBuffer(const nsIntSize& aSize, +TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize, gfxContentType aContentType) { if (!mTexImage || diff --git a/gfx/src/FilterSupport.cpp b/gfx/src/FilterSupport.cpp index cafd251c9c..1af69adfeb 100644 --- a/gfx/src/FilterSupport.cpp +++ b/gfx/src/FilterSupport.cpp @@ -1438,7 +1438,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a switch (aDescription.Type()) { case PrimitiveType::Empty: - return nsIntRect(); + return IntRect(); case PrimitiveType::Composite: { @@ -1475,7 +1475,7 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a case PrimitiveType::Flood: { if (atts.GetColor(eFloodColor).a == 0.0f) { - return nsIntRect(); + return IntRect(); } return aDescription.PrimitiveSubregion(); } @@ -1586,7 +1586,7 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription, } case PrimitiveType::Tile: - return nsIntRect(INT32_MIN/2, INT32_MIN/2, INT32_MAX, INT32_MAX); + return IntRect(INT32_MIN/2, INT32_MIN/2, INT32_MAX, INT32_MAX); case PrimitiveType::ConvolveMatrix: { diff --git a/gfx/src/nsRect.cpp b/gfx/src/nsRect.cpp index d1a3dd6391..b94d844e43 100644 --- a/gfx/src/nsRect.cpp +++ b/gfx/src/nsRect.cpp @@ -16,7 +16,7 @@ static_assert((int(NS_SIDE_TOP) == 0) && "The mozilla::css::Side sequence must match the nsMargin nscoord sequence"); nsRect -ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel) +ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel) { return nsRect(NSIntPixelsToAppUnits(aRect.x, aAppUnitsPerPixel), NSIntPixelsToAppUnits(aRect.y, aAppUnitsPerPixel), @@ -24,8 +24,8 @@ ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel) NSIntPixelsToAppUnits(aRect.height, aAppUnitsPerPixel)); } -const nsIntRect& GetMaxSizedIntRect() { - static const nsIntRect r(0, 0, INT32_MAX, INT32_MAX); +const mozilla::gfx::IntRect& GetMaxSizedIntRect() { + static const mozilla::gfx::IntRect r(0, 0, INT32_MAX, INT32_MAX); return r; } diff --git a/gfx/src/nsRect.h b/gfx/src/nsRect.h index f160a87da2..8d402c749c 100644 --- a/gfx/src/nsRect.h +++ b/gfx/src/nsRect.h @@ -149,27 +149,27 @@ struct NS_GFX nsRect : MOZ_WARN_UNUSED_RESULT inline nsRect ScaleToOtherAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToNearestPixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToNearestPixels(nscoord aAppUnitsPerPixel) const; // Note: this can turn an empty rectangle into a non-empty rectangle - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToOutsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; // Note: this can turn an empty rectangle into a non-empty rectangle - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ScaleToInsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; - MOZ_WARN_UNUSED_RESULT inline nsIntRect + MOZ_WARN_UNUSED_RESULT inline mozilla::gfx::IntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const; // This is here only to keep IPDL-generated code happy. DO NOT USE. @@ -220,11 +220,11 @@ nsRect::ScaleToOtherAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const } // scale the rect but round to preserve centers -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToNearestPixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntRoundUp(NSAppUnitsToDoublePixels(x, aAppUnitsPerPixel) * aXScale); rect.y = NSToIntRoundUp(NSAppUnitsToDoublePixels(y, aAppUnitsPerPixel) * aYScale); // Avoid negative widths and heights due to overflow @@ -236,11 +236,11 @@ nsRect::ScaleToNearestPixels(float aXScale, float aYScale, } // scale the rect but round to smallest containing rect -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToOutsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntFloor(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale); rect.y = NSToIntFloor(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale); // Avoid negative widths and heights due to overflow @@ -252,11 +252,11 @@ nsRect::ScaleToOutsidePixels(float aXScale, float aYScale, } // scale the rect but round to largest contained rect -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ScaleToInsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const { - nsIntRect rect; + mozilla::gfx::IntRect rect; rect.x = NSToIntCeil(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale); rect.y = NSToIntCeil(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale); // Avoid negative widths and heights due to overflow @@ -267,29 +267,29 @@ nsRect::ScaleToInsidePixels(float aXScale, float aYScale, return rect; } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToNearestPixels(nscoord aAppUnitsPerPixel) const { return ScaleToNearestPixels(1.0f, 1.0f, aAppUnitsPerPixel); } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToOutsidePixels(nscoord aAppUnitsPerPixel) const { return ScaleToOutsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); } -inline nsIntRect +inline mozilla::gfx::IntRect nsRect::ToInsidePixels(nscoord aAppUnitsPerPixel) const { return ScaleToInsidePixels(1.0f, 1.0f, aAppUnitsPerPixel); } -const nsIntRect& GetMaxSizedIntRect(); +const mozilla::gfx::IntRect& GetMaxSizedIntRect(); // app units are integer multiples of pixels, so no rounding needed nsRect -ToAppUnits(const nsIntRect& aRect, nscoord aAppUnitsPerPixel); +ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel); #ifdef DEBUG // Diagnostics diff --git a/gfx/src/nsRegion.cpp b/gfx/src/nsRegion.cpp index 85329fb9fe..cf8754b348 100644 --- a/gfx/src/nsRegion.cpp +++ b/gfx/src/nsRegion.cpp @@ -6,7 +6,6 @@ #include "nsRegion.h" #include "nsPrintfCString.h" #include "nsTArray.h" -#include "gfx3DMatrix.h" #include "gfxUtils.h" bool nsRegion::Contains(const nsRegion& aRgn) const @@ -606,26 +605,26 @@ nsRegion& nsRegion::ScaleInverseRoundOut (float aXScale, float aYScale) return *this; } -static nsIntRect -TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform) +static mozilla::gfx::IntRect +TransformRect(const mozilla::gfx::IntRect& aRect, const mozilla::gfx::Matrix4x4& aTransform) { if (aRect.IsEmpty()) { - return nsIntRect(); + return mozilla::gfx::IntRect(); } gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height); - rect = aTransform.TransformBounds(rect); + rect.TransformBounds(aTransform); rect.RoundOut(); - nsIntRect intRect; + mozilla::gfx::IntRect intRect; if (!gfxUtils::GfxRectToIntRect(rect, &intRect)) { - return nsIntRect(); + return mozilla::gfx::IntRect(); } return intRect; } -nsRegion& nsRegion::Transform (const gfx3DMatrix &aTransform) +nsRegion& nsRegion::Transform (const mozilla::gfx::Matrix4x4 &aTransform) { int n; pixman_box32_t *boxes = pixman_region32_rectangles(&mImpl, &n); @@ -699,7 +698,7 @@ nsIntRegion nsRegion::ToPixels (nscoord aAppUnitsPerPixel, bool aOutsidePixels) pixman_box32_t *boxes = pixman_region32_rectangles(®ion.mImpl, &n); for (int i=0; iScaleToNearestPixels(aScaleX, aScaleY, aAppUnitsPerPixel); result.Or(result, deviceRect); } @@ -747,7 +746,7 @@ nsIntRegion nsRegion::ScaleToOutsidePixels (float aScaleX, float aScaleY, nsRegionRectIterator rgnIter(*this); const nsRect* currentRect; while ((currentRect = rgnIter.Next())) { - nsIntRect deviceRect = + mozilla::gfx::IntRect deviceRect = currentRect->ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel); result.Or(result, deviceRect); } @@ -778,14 +777,14 @@ nsIntRegion nsRegion::ScaleToInsidePixels (float aScaleX, float aScaleY, nsIntRegion intRegion; if (n) { nsRect first = BoxToRect(boxes[0]); - nsIntRect firstDeviceRect = + mozilla::gfx::IntRect firstDeviceRect = first.ScaleToInsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel); for (int i=1; i +class NS_GFX nsIntRegion : public mozilla::gfx::BaseIntRegion { public: // Forward constructors. nsIntRegion() {} - MOZ_IMPLICIT nsIntRegion(const nsIntRect& aRect) : BaseIntRegion(aRect) {} + MOZ_IMPLICIT nsIntRegion(const mozilla::gfx::IntRect& aRect) : BaseIntRegion(aRect) {} nsIntRegion(const nsIntRegion& aRegion) : BaseIntRegion(aRegion) {} nsIntRegion(nsIntRegion&& aRegion) : BaseIntRegion(mozilla::Move(aRegion)) {} diff --git a/gfx/src/nsScriptableRegion.cpp b/gfx/src/nsScriptableRegion.cpp index a861e08e25..c0452b6d07 100644 --- a/gfx/src/nsScriptableRegion.cpp +++ b/gfx/src/nsScriptableRegion.cpp @@ -13,7 +13,7 @@ #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc #include "nsID.h" -#include "nsRect.h" // for nsIntRect +#include "nsRect.h" // for mozilla::gfx::IntRect #include "nscore.h" // for NS_IMETHODIMP class JSObject; @@ -38,7 +38,7 @@ NS_IMETHODIMP nsScriptableRegion::SetToRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::SetToRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion = nsIntRect(aX, aY, aWidth, aHeight); + mRegion = mozilla::gfx::IntRect(aX, aY, aWidth, aHeight); return NS_OK; } @@ -52,7 +52,7 @@ NS_IMETHODIMP nsScriptableRegion::IntersectRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::IntersectRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.And(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.And(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -66,7 +66,7 @@ NS_IMETHODIMP nsScriptableRegion::UnionRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::UnionRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.Or(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.Or(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -80,7 +80,7 @@ NS_IMETHODIMP nsScriptableRegion::SubtractRegion(nsIScriptableRegion *aRegion) NS_IMETHODIMP nsScriptableRegion::SubtractRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) { - mRegion.Sub(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); + mRegion.Sub(mRegion, mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -100,7 +100,7 @@ NS_IMETHODIMP nsScriptableRegion::IsEqualRegion(nsIScriptableRegion *aRegion, bo NS_IMETHODIMP nsScriptableRegion::GetBoundingBox(int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight) { - nsIntRect boundRect = mRegion.GetBounds(); + mozilla::gfx::IntRect boundRect = mRegion.GetBounds(); *aX = boundRect.x; *aY = boundRect.y; *aWidth = boundRect.width; @@ -116,7 +116,7 @@ NS_IMETHODIMP nsScriptableRegion::Offset(int32_t aXOffset, int32_t aYOffset) NS_IMETHODIMP nsScriptableRegion::ContainsRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool *containsRect) { - *containsRect = mRegion.Contains(nsIntRect(aX, aY, aWidth, aHeight)); + *containsRect = mRegion.Contains(mozilla::gfx::IntRect(aX, aY, aWidth, aHeight)); return NS_OK; } @@ -145,7 +145,7 @@ NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandlex, JSPROP_ENUMERATE) || diff --git a/gfx/tests/gtest/TestTiledLayerBuffer.cpp b/gfx/tests/gtest/TestTiledLayerBuffer.cpp index 9207ee8b79..ee9f03c13d 100644 --- a/gfx/tests/gtest/TestTiledLayerBuffer.cpp +++ b/gfx/tests/gtest/TestTiledLayerBuffer.cpp @@ -10,81 +10,50 @@ namespace mozilla { namespace layers { -struct TestTiledLayerTile { - int value; - explicit TestTiledLayerTile(int v = 0) { - value = v; - } - bool operator== (const TestTiledLayerTile& o) const { - return value == o.value; - } - bool operator!= (const TestTiledLayerTile& o) const { - return value != o.value; - } - - bool IsPlaceholderTile() const { - return value == -1; - } -}; - -class TestTiledLayerBuffer : public TiledLayerBuffer -{ - friend class TiledLayerBuffer; - -public: - TestTiledLayerTile GetPlaceholderTile() const { - return TestTiledLayerTile(-1); - } - - TestTiledLayerTile ValidateTile(TestTiledLayerTile aTile, const nsIntPoint& aTileOrigin, const nsIntRegion& aDirtyRect) { - return TestTiledLayerTile(); - } - - void ReleaseTile(TestTiledLayerTile aTile) - { - - } - - void SwapTiles(TestTiledLayerTile& aTileA, TestTiledLayerTile& aTileB) - { - TestTiledLayerTile oldTileA = aTileA; - aTileA = aTileB; - aTileB = oldTileA; - } - - void TestUpdate(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion) - { - Update(aNewValidRegion, aPaintRegion); - } - - void UnlockTile(TestTiledLayerTile aTile) {} - void PostValidate(const nsIntRegion& aPaintRegion) {} -}; - -TEST(TiledLayerBuffer, TileConstructor) { - gfxPlatform::GetPlatform()->ComputeTileSize(); - - TestTiledLayerBuffer buffer; -} - TEST(TiledLayerBuffer, TileStart) { gfxPlatform::GetPlatform()->ComputeTileSize(); - TestTiledLayerBuffer buffer; - - ASSERT_EQ(buffer.RoundDownToTileEdge(10, 256), 0); - ASSERT_EQ(buffer.RoundDownToTileEdge(-10, 256), -256); + ASSERT_EQ(RoundDownToTileEdge(10, 256), 0); + ASSERT_EQ(RoundDownToTileEdge(-10, 256), -256); } -TEST(TiledLayerBuffer, EmptyUpdate) { - gfxPlatform::GetPlatform()->ComputeTileSize(); +TEST(TiledLayerBuffer, TilesPlacement) { + for (int firstY = -10; firstY < 10; ++firstY) { + for (int firstX = -10; firstX < 10; ++firstX) { + for (int height = 1; height < 10; ++height) { + for (int width = 1; width < 10; ++width) { - TestTiledLayerBuffer buffer; + const TilesPlacement p1 = TilesPlacement(firstX, firstY, width, height); + // Check that HasTile returns false with some positions that we know + // not to be in the rectangle of the TilesPlacement. + ASSERT_FALSE(p1.HasTile(TileIntPoint(firstX - 1, 0))); + ASSERT_FALSE(p1.HasTile(TileIntPoint(0, firstY - 1))); + ASSERT_FALSE(p1.HasTile(TileIntPoint(firstX + width + 1, 0))); + ASSERT_FALSE(p1.HasTile(TileIntPoint(0, firstY + height + 1))); - nsIntRegion validRegion(gfx::IntRect(0, 0, 10, 10)); - buffer.TestUpdate(validRegion, validRegion); + // Verify that all positions within the rect that defines the + // TilesPlacement map to indices between 0 and width*height. + for (int y = firstY; y < (firstY+height); ++y) { + for (int x = firstX; x < (firstX+width); ++x) { + ASSERT_TRUE(p1.HasTile(TileIntPoint(x,y))); + ASSERT_TRUE(p1.TileIndex(TileIntPoint(x, y)) >= 0); + ASSERT_TRUE(p1.TileIndex(TileIntPoint(x, y)) < width * height); + } + } - ASSERT_EQ(buffer.GetValidRegion(), validRegion); + // Verify that indices map to positions that are within the rect that + // defines the TilesPlacement. + for (int i = 0; i < width * height; ++i) { + ASSERT_TRUE(p1.TilePosition(i).x >= firstX); + ASSERT_TRUE(p1.TilePosition(i).x < firstX + width); + ASSERT_TRUE(p1.TilePosition(i).y >= firstY); + ASSERT_TRUE(p1.TilePosition(i).y < firstY + height); + } + + } + } + } + } } } diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h index 9c64ff6f1b..7d8e68dfe6 100644 --- a/gfx/thebes/gfx2DGlue.h +++ b/gfx/thebes/gfx2DGlue.h @@ -9,7 +9,6 @@ #include "gfxPlatform.h" #include "gfxRect.h" #include "gfxMatrix.h" -#include "gfx3DMatrix.h" #include "gfxContext.h" #include "mozilla/gfx/Matrix.h" #include "mozilla/gfx/Rect.h" @@ -310,52 +309,6 @@ inline gfxContext::GraphicsOperator ThebesOp(CompositionOp aOp) } } -inline Matrix4x4 -ToMatrix4x4(const gfx3DMatrix& aIn) -{ - Matrix4x4 m; - m._11 = aIn._11; - m._12 = aIn._12; - m._13 = aIn._13; - m._14 = aIn._14; - m._21 = aIn._21; - m._22 = aIn._22; - m._23 = aIn._23; - m._24 = aIn._24; - m._31 = aIn._31; - m._32 = aIn._32; - m._33 = aIn._33; - m._34 = aIn._34; - m._41 = aIn._41; - m._42 = aIn._42; - m._43 = aIn._43; - m._44 = aIn._44; - return m; -} - -inline gfx3DMatrix -To3DMatrix(const Matrix4x4& aIn) -{ - gfx3DMatrix m; - m._11 = aIn._11; - m._12 = aIn._12; - m._13 = aIn._13; - m._14 = aIn._14; - m._21 = aIn._21; - m._22 = aIn._22; - m._23 = aIn._23; - m._24 = aIn._24; - m._31 = aIn._31; - m._32 = aIn._32; - m._33 = aIn._33; - m._34 = aIn._34; - m._41 = aIn._41; - m._42 = aIn._42; - m._43 = aIn._43; - m._44 = aIn._44; - return m; -} - } // namespace gfx } // namespace mozilla diff --git a/gfx/thebes/gfx3DMatrix.cpp b/gfx/thebes/gfx3DMatrix.cpp deleted file mode 100644 index 4277493e67..0000000000 --- a/gfx/thebes/gfx3DMatrix.cpp +++ /dev/null @@ -1,798 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * 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/. */ - -#include "gfxMatrix.h" -#include "gfx3DMatrix.h" -#include "gfx2DGlue.h" -#include "mozilla/gfx/Tools.h" -#include -#include - -using namespace std; -using namespace mozilla; -using namespace mozilla::gfx; - -/* Force small values to zero. We do this to avoid having sin(360deg) - * evaluate to a tiny but nonzero value. - */ -static double FlushToZero(double aVal) -{ - if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON) - return 0.0f; - else - return aVal; -} - -/* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is - * undefined or very large, SafeTangent returns a manageably large value - * of the correct sign. - */ -static double SafeTangent(double aTheta) -{ - const double kEpsilon = 0.0001; - - /* tan(theta) = sin(theta)/cos(theta); problems arise when - * cos(theta) is too close to zero. Limit cos(theta) to the - * range [-1, -epsilon] U [epsilon, 1]. - */ - double sinTheta = sin(aTheta); - double cosTheta = cos(aTheta); - - if (cosTheta >= 0 && cosTheta < kEpsilon) - cosTheta = kEpsilon; - else if (cosTheta < 0 && cosTheta >= -kEpsilon) - cosTheta = -kEpsilon; - - return FlushToZero(sinTheta / cosTheta); -} - -gfx3DMatrix::gfx3DMatrix(void) -{ - _11 = _22 = _33 = _44 = 1.0f; - _12 = _13 = _14 = 0.0f; - _21 = _23 = _24 = 0.0f; - _31 = _32 = _34 = 0.0f; - _41 = _42 = _43 = 0.0f; -} - -gfx3DMatrix -gfx3DMatrix::operator*(const gfx3DMatrix &aMatrix) const -{ - if (Is2D() && aMatrix.Is2D()) { - return Multiply2D(aMatrix); - } - - gfx3DMatrix matrix; - - matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _13 * aMatrix._31 + _14 * aMatrix._41; - matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21 + _23 * aMatrix._31 + _24 * aMatrix._41; - matrix._31 = _31 * aMatrix._11 + _32 * aMatrix._21 + _33 * aMatrix._31 + _34 * aMatrix._41; - matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + _43 * aMatrix._31 + _44 * aMatrix._41; - matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22 + _13 * aMatrix._32 + _14 * aMatrix._42; - matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22 + _23 * aMatrix._32 + _24 * aMatrix._42; - matrix._32 = _31 * aMatrix._12 + _32 * aMatrix._22 + _33 * aMatrix._32 + _34 * aMatrix._42; - matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + _43 * aMatrix._32 + _44 * aMatrix._42; - matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23 + _13 * aMatrix._33 + _14 * aMatrix._43; - matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23 + _23 * aMatrix._33 + _24 * aMatrix._43; - matrix._33 = _31 * aMatrix._13 + _32 * aMatrix._23 + _33 * aMatrix._33 + _34 * aMatrix._43; - matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23 + _43 * aMatrix._33 + _44 * aMatrix._43; - matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24 + _13 * aMatrix._34 + _14 * aMatrix._44; - matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24 + _23 * aMatrix._34 + _24 * aMatrix._44; - matrix._34 = _31 * aMatrix._14 + _32 * aMatrix._24 + _33 * aMatrix._34 + _34 * aMatrix._44; - matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24 + _43 * aMatrix._34 + _44 * aMatrix._44; - - return matrix; -} - -gfx3DMatrix& -gfx3DMatrix::operator*=(const gfx3DMatrix &aMatrix) -{ - return *this = *this * aMatrix; -} - -gfx3DMatrix -gfx3DMatrix::Multiply2D(const gfx3DMatrix &aMatrix) const -{ - gfx3DMatrix matrix; - - matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21; - matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21; - matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + aMatrix._41; - matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22; - matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22; - matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + aMatrix._42; - - return matrix; -} - -bool -gfx3DMatrix::operator==(const gfx3DMatrix& o) const -{ - // XXX would be nice to memcmp here, but that breaks IEEE 754 semantics - return _11 == o._11 && _12 == o._12 && _13 == o._13 && _14 == o._14 && - _21 == o._21 && _22 == o._22 && _23 == o._23 && _24 == o._24 && - _31 == o._31 && _32 == o._32 && _33 == o._33 && _34 == o._34 && - _41 == o._41 && _42 == o._42 && _43 == o._43 && _44 == o._44; -} - -bool -gfx3DMatrix::operator!=(const gfx3DMatrix& o) const -{ - return !((*this) == o); -} - -bool -gfx3DMatrix::FuzzyEqual(const gfx3DMatrix& o) const -{ - static const float error = 1e-4; - return gfx::FuzzyEqual(_11, o._11, error) && gfx::FuzzyEqual(_12, o._12, error) && - gfx::FuzzyEqual(_13, o._13, error) && gfx::FuzzyEqual(_14, o._14, error) && - gfx::FuzzyEqual(_21, o._21, error) && gfx::FuzzyEqual(_22, o._22, error) && - gfx::FuzzyEqual(_23, o._23, error) && gfx::FuzzyEqual(_24, o._24, error) && - gfx::FuzzyEqual(_31, o._31, error) && gfx::FuzzyEqual(_32, o._32, error) && - gfx::FuzzyEqual(_33, o._33, error) && gfx::FuzzyEqual(_34, o._34, error) && - gfx::FuzzyEqual(_41, o._41, error) && gfx::FuzzyEqual(_42, o._42, error) && - gfx::FuzzyEqual(_43, o._43, error) && gfx::FuzzyEqual(_44, o._44, error); -} - -gfx3DMatrix& -gfx3DMatrix::operator/=(const gfxFloat scalar) -{ - _11 /= scalar; - _12 /= scalar; - _13 /= scalar; - _14 /= scalar; - _21 /= scalar; - _22 /= scalar; - _23 /= scalar; - _24 /= scalar; - _31 /= scalar; - _32 /= scalar; - _33 /= scalar; - _34 /= scalar; - _41 /= scalar; - _42 /= scalar; - _43 /= scalar; - _44 /= scalar; - return *this; -} - -gfx3DMatrix -gfx3DMatrix::From2D(const gfxMatrix &aMatrix) -{ - gfx3DMatrix matrix; - matrix._11 = (float)aMatrix._11; - matrix._12 = (float)aMatrix._12; - matrix._21 = (float)aMatrix._21; - matrix._22 = (float)aMatrix._22; - matrix._41 = (float)aMatrix._31; - matrix._42 = (float)aMatrix._32; - return matrix; -} - -bool -gfx3DMatrix::IsIdentity() const -{ - return _11 == 1.0f && _12 == 0.0f && _13 == 0.0f && _14 == 0.0f && - _21 == 0.0f && _22 == 1.0f && _23 == 0.0f && _24 == 0.0f && - _31 == 0.0f && _32 == 0.0f && _33 == 1.0f && _34 == 0.0f && - _41 == 0.0f && _42 == 0.0f && _43 == 0.0f && _44 == 1.0f; -} - -void -gfx3DMatrix::Translate(const Point3D& aPoint) -{ - _41 += aPoint.x * _11 + aPoint.y * _21 + aPoint.z * _31; - _42 += aPoint.x * _12 + aPoint.y * _22 + aPoint.z * _32; - _43 += aPoint.x * _13 + aPoint.y * _23 + aPoint.z * _33; - _44 += aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34; -} - -void -gfx3DMatrix::TranslatePost(const Point3D& aPoint) -{ - _11 += _14 * aPoint.x; - _21 += _24 * aPoint.x; - _31 += _34 * aPoint.x; - _41 += _44 * aPoint.x; - _12 += _14 * aPoint.y; - _22 += _24 * aPoint.y; - _32 += _34 * aPoint.y; - _42 += _44 * aPoint.y; - _13 += _14 * aPoint.z; - _23 += _24 * aPoint.z; - _33 += _34 * aPoint.z; - _43 += _44 * aPoint.z; -} - -void -gfx3DMatrix::ScalePost(float aX, float aY, float aZ) -{ - _11 *= aX; - _21 *= aX; - _31 *= aX; - _41 *= aX; - - _12 *= aY; - _22 *= aY; - _32 *= aY; - _42 *= aY; - - _13 *= aZ; - _23 *= aZ; - _33 *= aZ; - _43 *= aZ; -} - -void -gfx3DMatrix::ChangeBasis(const Point3D& aOrigin) -{ - // Translate to the origin before applying this matrix. - Translate(-aOrigin); - - // Translate back into position after applying this matrix. - TranslatePost(aOrigin); -} - -void -gfx3DMatrix::Scale(float aX, float aY, float aZ) -{ - (*this)[0] *= aX; - (*this)[1] *= aY; - (*this)[2] *= aZ; -} - -void -gfx3DMatrix::Perspective(float aDepth) -{ - NS_ASSERTION(aDepth > 0.0f, "Perspective must be positive!"); - _31 += -1.0/aDepth * _41; - _32 += -1.0/aDepth * _42; - _33 += -1.0/aDepth * _43; - _34 += -1.0/aDepth * _44; -} - -void gfx3DMatrix::SkewXY(double aXSkew, double aYSkew) -{ - float tanX = SafeTangent(aXSkew); - float tanY = SafeTangent(aYSkew); - float temp; - - temp = _11; - _11 += tanY * _21; - _21 += tanX * temp; - - temp = _12; - _12 += tanY * _22; - _22 += tanX * temp; - - temp = _13; - _13 += tanY * _23; - _23 += tanX * temp; - - temp = _14; - _14 += tanY * _24; - _24 += tanX * temp; -} - -void -gfx3DMatrix::RotateX(double aTheta) -{ - double cosTheta = FlushToZero(cos(aTheta)); - double sinTheta = FlushToZero(sin(aTheta)); - - float temp; - - temp = _21; - _21 = cosTheta * _21 + sinTheta * _31; - _31 = -sinTheta * temp + cosTheta * _31; - - temp = _22; - _22 = cosTheta * _22 + sinTheta * _32; - _32 = -sinTheta * temp + cosTheta * _32; - - temp = _23; - _23 = cosTheta * _23 + sinTheta * _33; - _33 = -sinTheta * temp + cosTheta * _33; - - temp = _24; - _24 = cosTheta * _24 + sinTheta * _34; - _34 = -sinTheta * temp + cosTheta * _34; -} - -void -gfx3DMatrix::RotateY(double aTheta) -{ - double cosTheta = FlushToZero(cos(aTheta)); - double sinTheta = FlushToZero(sin(aTheta)); - - float temp; - - temp = _11; - _11 = cosTheta * _11 + -sinTheta * _31; - _31 = sinTheta * temp + cosTheta * _31; - - temp = _12; - _12 = cosTheta * _12 + -sinTheta * _32; - _32 = sinTheta * temp + cosTheta * _32; - - temp = _13; - _13 = cosTheta * _13 + -sinTheta * _33; - _33 = sinTheta * temp + cosTheta * _33; - - temp = _14; - _14 = cosTheta * _14 + -sinTheta * _34; - _34 = sinTheta * temp + cosTheta * _34; -} - -void -gfx3DMatrix::RotateZ(double aTheta) -{ - double cosTheta = FlushToZero(cos(aTheta)); - double sinTheta = FlushToZero(sin(aTheta)); - - float temp; - - temp = _11; - _11 = cosTheta * _11 + sinTheta * _21; - _21 = -sinTheta * temp + cosTheta * _21; - - temp = _12; - _12 = cosTheta * _12 + sinTheta * _22; - _22 = -sinTheta * temp + cosTheta * _22; - - temp = _13; - _13 = cosTheta * _13 + sinTheta * _23; - _23 = -sinTheta * temp + cosTheta * _23; - - temp = _14; - _14 = cosTheta * _14 + sinTheta * _24; - _24 = -sinTheta * temp + cosTheta * _24; -} - -void -gfx3DMatrix::PreMultiply(const gfx3DMatrix& aOther) -{ - *this = aOther * (*this); -} - -void -gfx3DMatrix::PreMultiply(const gfxMatrix& aOther) -{ - gfx3DMatrix temp; - temp._11 = aOther._11 * _11 + aOther._12 * _21; - temp._21 = aOther._21 * _11 + aOther._22 * _21; - temp._31 = _31; - temp._41 = aOther._31 * _11 + aOther._32 * _21 + _41; - temp._12 = aOther._11 * _12 + aOther._12 * _22; - temp._22 = aOther._21 * _12 + aOther._22 * _22; - temp._32 = _32; - temp._42 = aOther._31 * _12 + aOther._32 * _22 + _42; - temp._13 = aOther._11 * _13 + aOther._12 * _23; - temp._23 = aOther._21 * _13 + aOther._22 * _23; - temp._33 = _33; - temp._43 = aOther._31 * _13 + aOther._32 * _23 + _43; - temp._14 = aOther._11 * _14 + aOther._12 * _24; - temp._24 = aOther._21 * _14 + aOther._22 * _24; - temp._34 = _34; - temp._44 = aOther._31 * _14 + aOther._32 * _24 + _44; - - *this = temp; -} - -gfx3DMatrix -gfx3DMatrix::Translation(float aX, float aY, float aZ) -{ - gfx3DMatrix matrix; - - matrix._41 = aX; - matrix._42 = aY; - matrix._43 = aZ; - return matrix; -} - -gfx3DMatrix -gfx3DMatrix::Translation(const Point3D& aPoint) -{ - gfx3DMatrix matrix; - - matrix._41 = aPoint.x; - matrix._42 = aPoint.y; - matrix._43 = aPoint.z; - return matrix; -} - -gfx3DMatrix -gfx3DMatrix::ScalingMatrix(float aFactor) -{ - gfx3DMatrix matrix; - - matrix._11 = matrix._22 = matrix._33 = aFactor; - return matrix; -} - -gfx3DMatrix -gfx3DMatrix::ScalingMatrix(float aX, float aY, float aZ) -{ - gfx3DMatrix matrix; - - matrix._11 = aX; - matrix._22 = aY; - matrix._33 = aZ; - - return matrix; -} - -gfxFloat -gfx3DMatrix::Determinant() const -{ - return _14 * _23 * _32 * _41 - - _13 * _24 * _32 * _41 - - _14 * _22 * _33 * _41 - + _12 * _24 * _33 * _41 - + _13 * _22 * _34 * _41 - - _12 * _23 * _34 * _41 - - _14 * _23 * _31 * _42 - + _13 * _24 * _31 * _42 - + _14 * _21 * _33 * _42 - - _11 * _24 * _33 * _42 - - _13 * _21 * _34 * _42 - + _11 * _23 * _34 * _42 - + _14 * _22 * _31 * _43 - - _12 * _24 * _31 * _43 - - _14 * _21 * _32 * _43 - + _11 * _24 * _32 * _43 - + _12 * _21 * _34 * _43 - - _11 * _22 * _34 * _43 - - _13 * _22 * _31 * _44 - + _12 * _23 * _31 * _44 - + _13 * _21 * _32 * _44 - - _11 * _23 * _32 * _44 - - _12 * _21 * _33 * _44 - + _11 * _22 * _33 * _44; -} - -gfxFloat -gfx3DMatrix::Determinant3x3() const -{ - return _11 * (_22 * _33 - _23 * _32) + - _12 * (_23 * _31 - _33 * _21) + - _13 * (_21 * _32 - _22 * _31); -} - -gfx3DMatrix -gfx3DMatrix::Inverse3x3() const -{ - gfxFloat det = Determinant3x3(); - if (det == 0.0) { - return *this; - } - - gfxFloat detInv = 1/det; - gfx3DMatrix temp; - - temp._11 = (_22 * _33 - _23 * _32) * detInv; - temp._12 = (_13 * _32 - _12 * _33) * detInv; - temp._13 = (_12 * _23 - _13 * _22) * detInv; - temp._21 = (_23 * _31 - _33 * _21) * detInv; - temp._22 = (_11 * _33 - _13 * _31) * detInv; - temp._23 = (_13 * _21 - _11 * _23) * detInv; - temp._31 = (_21 * _32 - _22 * _31) * detInv; - temp._32 = (_31 * _12 - _11 * _32) * detInv; - temp._33 = (_11 * _22 - _12 * _21) * detInv; - return temp; -} - -bool -gfx3DMatrix::IsSingular() const -{ - return Determinant() == 0.0; -} - -gfx3DMatrix -gfx3DMatrix::Inverse() const -{ - if (_14 == 0 && _24 == 0 && _34 == 0 && _44 == 1) { - /** - * When the matrix contains no perspective, the inverse - * is the same as the 3x3 inverse of the rotation components - * multiplied by the inverse of the translation components. - * Doing these steps separately is faster and more numerically - * stable. - * - * Inverse of the translation matrix is just negating - * the values. - */ - gfx3DMatrix matrix3 = Inverse3x3(); - matrix3.Translate(Point3D(-_41, -_42, -_43)); - return matrix3; - } - - gfxFloat det = Determinant(); - if (det == 0.0) { - return *this; - } - - gfx3DMatrix temp; - - temp._11 = _23*_34*_42 - _24*_33*_42 + - _24*_32*_43 - _22*_34*_43 - - _23*_32*_44 + _22*_33*_44; - temp._12 = _14*_33*_42 - _13*_34*_42 - - _14*_32*_43 + _12*_34*_43 + - _13*_32*_44 - _12*_33*_44; - temp._13 = _13*_24*_42 - _14*_23*_42 + - _14*_22*_43 - _12*_24*_43 - - _13*_22*_44 + _12*_23*_44; - temp._14 = _14*_23*_32 - _13*_24*_32 - - _14*_22*_33 + _12*_24*_33 + - _13*_22*_34 - _12*_23*_34; - temp._21 = _24*_33*_41 - _23*_34*_41 - - _24*_31*_43 + _21*_34*_43 + - _23*_31*_44 - _21*_33*_44; - temp._22 = _13*_34*_41 - _14*_33*_41 + - _14*_31*_43 - _11*_34*_43 - - _13*_31*_44 + _11*_33*_44; - temp._23 = _14*_23*_41 - _13*_24*_41 - - _14*_21*_43 + _11*_24*_43 + - _13*_21*_44 - _11*_23*_44; - temp._24 = _13*_24*_31 - _14*_23*_31 + - _14*_21*_33 - _11*_24*_33 - - _13*_21*_34 + _11*_23*_34; - temp._31 = _22*_34*_41 - _24*_32*_41 + - _24*_31*_42 - _21*_34*_42 - - _22*_31*_44 + _21*_32*_44; - temp._32 = _14*_32*_41 - _12*_34*_41 - - _14*_31*_42 + _11*_34*_42 + - _12*_31*_44 - _11*_32*_44; - temp._33 = _12*_24*_41 - _14*_22*_41 + - _14*_21*_42 - _11*_24*_42 - - _12*_21*_44 + _11*_22*_44; - temp._34 = _14*_22*_31 - _12*_24*_31 - - _14*_21*_32 + _11*_24*_32 + - _12*_21*_34 - _11*_22*_34; - temp._41 = _23*_32*_41 - _22*_33*_41 - - _23*_31*_42 + _21*_33*_42 + - _22*_31*_43 - _21*_32*_43; - temp._42 = _12*_33*_41 - _13*_32*_41 + - _13*_31*_42 - _11*_33*_42 - - _12*_31*_43 + _11*_32*_43; - temp._43 = _13*_22*_41 - _12*_23*_41 - - _13*_21*_42 + _11*_23*_42 + - _12*_21*_43 - _11*_22*_43; - temp._44 = _12*_23*_31 - _13*_22*_31 + - _13*_21*_32 - _11*_23*_32 - - _12*_21*_33 + _11*_22*_33; - - temp /= det; - return temp; -} - -gfxPoint -gfx3DMatrix::Transform(const gfxPoint& point) const -{ - // Note: we don't use Transform3D here because passing point.x/y via - // a Point3D would lose precision and cause bugs, e.g. bug 1091709. - gfxFloat px = point.x; - gfxFloat py = point.y; - - gfxFloat x = px * _11 + py * _21 + _41; - gfxFloat y = px * _12 + py * _22 + _42; - gfxFloat w = px * _14 + py * _24 + _44; - - x /= w; - y /= w; - - return gfxPoint(x, y); -} - -Point3D -gfx3DMatrix::Transform3D(const Point3D& point) const -{ - gfxFloat x = point.x * _11 + point.y * _21 + point.z * _31 + _41; - gfxFloat y = point.x * _12 + point.y * _22 + point.z * _32 + _42; - gfxFloat z = point.x * _13 + point.y * _23 + point.z * _33 + _43; - gfxFloat w = point.x * _14 + point.y * _24 + point.z * _34 + _44; - - x /= w; - y /= w; - z /= w; - - return Point3D(x, y, z); -} - -Point4D -gfx3DMatrix::Transform4D(const Point4D& aPoint) const -{ - gfxFloat x = aPoint.x * _11 + aPoint.y * _21 + aPoint.z * _31 + aPoint.w * _41; - gfxFloat y = aPoint.x * _12 + aPoint.y * _22 + aPoint.z * _32 + aPoint.w * _42; - gfxFloat z = aPoint.x * _13 + aPoint.y * _23 + aPoint.z * _33 + aPoint.w * _43; - gfxFloat w = aPoint.x * _14 + aPoint.y * _24 + aPoint.z * _34 + aPoint.w * _44; - - return Point4D(x, y, z, w); -} - -gfxRect -gfx3DMatrix::TransformBounds(const gfxRect& rect) const -{ - gfxPoint points[4]; - - points[0] = Transform(rect.TopLeft()); - points[1] = Transform(gfxPoint(rect.X() + rect.Width(), rect.Y())); - points[2] = Transform(gfxPoint(rect.X(), rect.Y() + rect.Height())); - points[3] = Transform(gfxPoint(rect.X() + rect.Width(), - rect.Y() + rect.Height())); - - gfxFloat min_x, max_x; - gfxFloat min_y, max_y; - - min_x = max_x = points[0].x; - min_y = max_y = points[0].y; - - for (int i=1; i<4; i++) { - min_x = min(points[i].x, min_x); - max_x = max(points[i].x, max_x); - min_y = min(points[i].y, min_y); - max_y = max(points[i].y, max_y); - } - - return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y); -} - -gfxQuad -gfx3DMatrix::TransformRect(const gfxRect& aRect) const -{ - gfxPoint points[4]; - - points[0] = Transform(aRect.TopLeft()); - points[1] = Transform(gfxPoint(aRect.X() + aRect.Width(), aRect.Y())); - points[2] = Transform(gfxPoint(aRect.X() + aRect.Width(), - aRect.Y() + aRect.Height())); - points[3] = Transform(gfxPoint(aRect.X(), aRect.Y() + aRect.Height())); - - // Could this ever result in lines that intersect? I don't think so. - return gfxQuad(points[0], points[1], points[2], points[3]); -} - -bool -gfx3DMatrix::Is2D() const -{ - if (_13 != 0.0f || _14 != 0.0f || - _23 != 0.0f || _24 != 0.0f || - _31 != 0.0f || _32 != 0.0f || _33 != 1.0f || _34 != 0.0f || - _43 != 0.0f || _44 != 1.0f) { - return false; - } - return true; -} - -bool -gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const -{ - if (!Is2D()) { - return false; - } - if (aMatrix) { - aMatrix->_11 = _11; - aMatrix->_12 = _12; - aMatrix->_21 = _21; - aMatrix->_22 = _22; - aMatrix->_31 = _41; - aMatrix->_32 = _42; - } - return true; -} - -bool -gfx3DMatrix::CanDraw2D(gfxMatrix* aMatrix) const -{ - if (_14 != 0.0f || - _24 != 0.0f || - _44 != 1.0f) { - return false; - } - if (aMatrix) { - aMatrix->_11 = _11; - aMatrix->_12 = _12; - aMatrix->_21 = _21; - aMatrix->_22 = _22; - aMatrix->_31 = _41; - aMatrix->_32 = _42; - } - return true; -} - -gfx3DMatrix& -gfx3DMatrix::ProjectTo2D() -{ - _31 = 0.0f; - _32 = 0.0f; - _13 = 0.0f; - _23 = 0.0f; - _33 = 1.0f; - _43 = 0.0f; - _34 = 0.0f; - return *this; -} - -Point4D gfx3DMatrix::ProjectPoint(const gfxPoint& aPoint) const -{ - // Find a value for z that will transform to 0. - - // The transformed value of z is computed as: - // z' = aPoint.x * _13 + aPoint.y * _23 + z * _33 + _43; - - // Solving for z when z' = 0 gives us: - float z = -(aPoint.x * _13 + aPoint.y * _23 + _43) / _33; - - // Compute the transformed point - return Transform4D(Point4D(aPoint.x, aPoint.y, z, 1)); -} - -Point3D gfx3DMatrix::GetNormalVector() const -{ - // Define a plane in transformed space as the transformations - // of 3 points on the z=0 screen plane. - Point3D a = Transform3D(Point3D(0, 0, 0)); - Point3D b = Transform3D(Point3D(0, 1, 0)); - Point3D c = Transform3D(Point3D(1, 0, 0)); - - // Convert to two vectors on the surface of the plane. - Point3D ab = b - a; - Point3D ac = c - a; - - return ac.CrossProduct(ab); -} - -bool gfx3DMatrix::IsBackfaceVisible() const -{ - // Inverse()._33 < 0; - gfxFloat det = Determinant(); - float _33 = _12*_24*_41 - _14*_22*_41 + - _14*_21*_42 - _11*_24*_42 - - _12*_21*_44 + _11*_22*_44; - return (_33 * det) < 0; -} - -void gfx3DMatrix::NudgeToIntegers(void) -{ - NudgeToInteger(&_11); - NudgeToInteger(&_12); - NudgeToInteger(&_13); - NudgeToInteger(&_14); - NudgeToInteger(&_21); - NudgeToInteger(&_22); - NudgeToInteger(&_23); - NudgeToInteger(&_24); - NudgeToInteger(&_31); - NudgeToInteger(&_32); - NudgeToInteger(&_33); - NudgeToInteger(&_34); - NudgeToInteger(&_41); - NudgeToInteger(&_42); - NudgeToInteger(&_43); - NudgeToInteger(&_44); -} - -void gfx3DMatrix::NudgeToIntegersFixedEpsilon(void) -{ - NudgeToInteger(&_11); - NudgeToInteger(&_12); - NudgeToInteger(&_13); - NudgeToInteger(&_14); - NudgeToInteger(&_21); - NudgeToInteger(&_22); - NudgeToInteger(&_23); - NudgeToInteger(&_24); - NudgeToInteger(&_31); - NudgeToInteger(&_32); - NudgeToInteger(&_33); - NudgeToInteger(&_34); - static const float error = 1e-5; - NudgeToInteger(&_41, error); - NudgeToInteger(&_42, error); - NudgeToInteger(&_43, error); - NudgeToInteger(&_44, error); -} diff --git a/gfx/thebes/gfx3DMatrix.h b/gfx/thebes/gfx3DMatrix.h deleted file mode 100644 index 34c9685d0b..0000000000 --- a/gfx/thebes/gfx3DMatrix.h +++ /dev/null @@ -1,357 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * 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/. */ - -#ifndef GFX_3DMATRIX_H -#define GFX_3DMATRIX_H - -#include -#include "mozilla/gfx/Point.h" -#include - -class gfxMatrix; - -/** - * This class represents a 3D transformation. The matrix is laid - * out as follows: - * - * _11 _12 _13 _14 - * _21 _22 _23 _24 - * _31 _32 _33 _34 - * _41 _42 _43 _44 - * - * This matrix is treated as row-major. Assuming we consider our vectors row - * vectors, this matrix type will be identical in memory to the OpenGL and D3D - * matrices. OpenGL matrices are column-major, however OpenGL also treats - * vectors as column vectors, the double transposition makes everything work - * out nicely. - */ -class gfx3DMatrix -{ - typedef mozilla::gfx::Point3D Point3D; - typedef mozilla::gfx::Point4D Point4D; -public: - /** - * Create matrix. - */ - gfx3DMatrix(void); - - friend std::ostream& operator<<(std::ostream& stream, const gfx3DMatrix& m) { - if (m.IsIdentity()) { - return stream << "[ I ]"; - } - - if (m.Is2D()) { - return stream << "[" - << m._11 << " " << m._12 << "; " - << m._21 << " " << m._22 << "; " - << m._41 << " " << m._42 - << "]"; - } - - return stream << "[" - << m._11 << " " << m._12 << " " << m._13 << " " << m._14 << "; " - << m._21 << " " << m._22 << " " << m._23 << " " << m._24 << "; " - << m._31 << " " << m._32 << " " << m._33 << " " << m._34 << "; " - << m._41 << " " << m._42 << " " << m._43 << " " << m._44 - << "]"; - } - - /** - * Matrix multiplication. - */ - gfx3DMatrix operator*(const gfx3DMatrix &aMatrix) const; - gfx3DMatrix& operator*=(const gfx3DMatrix &aMatrix); - - Point4D& operator[](int aIndex) - { - MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index"); - return *reinterpret_cast((&_11)+4*aIndex); - } - const Point4D& operator[](int aIndex) const - { - MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index"); - return *reinterpret_cast((&_11)+4*aIndex); - } - - /** - * Return true if this matrix and |aMatrix| are the same matrix. - */ - bool operator==(const gfx3DMatrix& aMatrix) const; - bool operator!=(const gfx3DMatrix& aMatrix) const; - - bool FuzzyEqual(const gfx3DMatrix& aMatrix) const; - - /** - * Divide all values in the matrix by a scalar value - */ - gfx3DMatrix& operator/=(gfxFloat scalar); - - /** - * Create a 3D matrix from a gfxMatrix 2D affine transformation. - * - * \param aMatrix gfxMatrix 2D affine transformation. - */ - static gfx3DMatrix From2D(const gfxMatrix &aMatrix); - - /** - * Returns true if the matrix is isomorphic to a 2D affine transformation - * (i.e. as obtained by From2D). If it is, optionally returns the 2D - * matrix in aMatrix. - */ - bool Is2D(gfxMatrix* aMatrix) const; - bool Is2D() const; - - /** - * Returns true if the matrix can be reduced to a 2D affine transformation - * (i.e. as obtained by From2D). If it is, optionally returns the 2D - * matrix in aMatrix. This should only be used on matrices required for - * rendering, not for intermediate calculations. It is assumed that the 2D - * matrix will only be used for transforming objects on to the z=0 plane, - * therefore any z-component perspective is ignored. This means that if - * aMatrix is applied to objects with z != 0, the results may be incorrect. - * - * Since drawing is to a 2d plane, any 3d transform without perspective - * can be reduced by dropping the z row and column. - */ - bool CanDraw2D(gfxMatrix* aMatrix = nullptr) const; - - /** - * Converts the matrix to one that doesn't modify the z coordinate of points, - * but leaves the rest of the transformation unchanged. - */ - gfx3DMatrix& ProjectTo2D(); - - /** - * Returns true if the matrix is the identity matrix. The most important - * property we require is that gfx3DMatrix().IsIdentity() returns true. - */ - bool IsIdentity() const; - - /** - * Pre-multiplication transformation functions: - * - * These functions construct a temporary matrix containing - * a single transformation and pre-multiply it onto the current - * matrix. - */ - - /** - * Add a translation by aPoint to the matrix. - * - * This creates this temporary matrix: - * | 1 0 0 0 | - * | 0 1 0 0 | - * | 0 0 1 0 | - * | aPoint.x aPoint.y aPoint.z 1 | - */ - void Translate(const Point3D& aPoint); - - /** - * Skew the matrix. - * - * This creates this temporary matrix: - * | 1 tan(aYSkew) 0 0 | - * | tan(aXSkew) 1 0 0 | - * | 0 0 1 0 | - * | 0 0 0 1 | - */ - void SkewXY(double aXSkew, double aYSkew); - - /** - * Scale the matrix - * - * This creates this temporary matrix: - * | aX 0 0 0 | - * | 0 aY 0 0 | - * | 0 0 aZ 0 | - * | 0 0 0 1 | - */ - void Scale(float aX, float aY, float aZ); - - /** - * Return the currently set scaling factors. - */ - float GetXScale() const { return _11; } - float GetYScale() const { return _22; } - float GetZScale() const { return _33; } - - /** - * Rotate around the X axis.. - * - * This creates this temporary matrix: - * | 1 0 0 0 | - * | 0 cos(aTheta) sin(aTheta) 0 | - * | 0 -sin(aTheta) cos(aTheta) 0 | - * | 0 0 0 1 | - */ - void RotateX(double aTheta); - - /** - * Rotate around the Y axis.. - * - * This creates this temporary matrix: - * | cos(aTheta) 0 -sin(aTheta) 0 | - * | 0 1 0 0 | - * | sin(aTheta) 0 cos(aTheta) 0 | - * | 0 0 0 1 | - */ - void RotateY(double aTheta); - - /** - * Rotate around the Z axis.. - * - * This creates this temporary matrix: - * | cos(aTheta) sin(aTheta) 0 0 | - * | -sin(aTheta) cos(aTheta) 0 0 | - * | 0 0 1 0 | - * | 0 0 0 1 | - */ - void RotateZ(double aTheta); - - /** - * Apply perspective to the matrix. - * - * This creates this temporary matrix: - * | 1 0 0 0 | - * | 0 1 0 0 | - * | 0 0 1 -1/aDepth | - * | 0 0 0 1 | - */ - void Perspective(float aDepth); - - /** - * Pre multiply an existing matrix onto the current - * matrix - */ - void PreMultiply(const gfx3DMatrix& aOther); - void PreMultiply(const gfxMatrix& aOther); - - /** - * Post-multiplication transformation functions: - * - * These functions construct a temporary matrix containing - * a single transformation and post-multiply it onto the current - * matrix. - */ - - /** - * Add a translation by aPoint after the matrix. - * This is functionally equivalent to: - * matrix * gfx3DMatrix::Translation(aPoint) - */ - void TranslatePost(const Point3D& aPoint); - - void ScalePost(float aX, float aY, float aZ); - - /** - * Let T be the transformation matrix translating points in the coordinate - * space with origin aOrigin to the coordinate space used by this matrix. - * If this matrix is M, this function changes it to be (T-1)MT, the matrix - * that's equivalent to M but in the coordinate space that treats aOrigin - * as the origin. - * - * @param aOrigin The origin to translate to - * @return The modified matrix - */ - void ChangeBasis(const Point3D& aOrigin); - - /** - * Transforms a point according to this matrix. - */ - gfxPoint Transform(const gfxPoint& point) const; - - /** - * Transforms a rectangle according to this matrix - */ - gfxRect TransformBounds(const gfxRect& rect) const; - - - gfxQuad TransformRect(const gfxRect& aRect) const; - - /** - * Transforms a 3D vector according to this matrix. - */ - Point3D Transform3D(const Point3D& point) const; - Point4D Transform4D(const Point4D& aPoint) const; - - /** - * Given a point (x,y) find a value for z such that (x,y,z,1) transforms - * into (x',y',0,w') and returns the latter. - */ - Point4D ProjectPoint(const gfxPoint& aPoint) const; - - /** - * Inverts this matrix, if possible. Otherwise, the matrix is left - * unchanged. - */ - gfx3DMatrix Inverse() const; - - gfx3DMatrix& Invert() - { - *this = Inverse(); - return *this; - } - - /** - * Returns a unit vector that is perpendicular to the plane formed - * by transform the screen plane (z=0) by this matrix. - */ - Point3D GetNormalVector() const; - - /** - * Returns true if a plane transformed by this matrix will - * have it's back face visible. - */ - bool IsBackfaceVisible() const; - - /** - * Check if matrix is singular (no inverse exists). - */ - bool IsSingular() const; - - /** - * Create a translation matrix. - * - * \param aX Translation on X-axis. - * \param aY Translation on Y-axis. - * \param aZ Translation on Z-axis. - */ - static gfx3DMatrix Translation(float aX, float aY, float aZ); - static gfx3DMatrix Translation(const Point3D& aPoint); - - /** - * Create a scale matrix. Scales uniformly along all axes. - * - * \param aScale Scale factor - */ - static gfx3DMatrix ScalingMatrix(float aFactor); - - /** - * Create a scale matrix. - */ - static gfx3DMatrix ScalingMatrix(float aX, float aY, float aZ); - - gfxFloat Determinant() const; - - void NudgeToIntegers(void); - void NudgeToIntegersFixedEpsilon(); - -private: - - gfxFloat Determinant3x3() const; - gfx3DMatrix Inverse3x3() const; - - gfx3DMatrix Multiply2D(const gfx3DMatrix &aMatrix) const; - -public: - - /** Matrix elements */ - float _11, _12, _13, _14; - float _21, _22, _23, _24; - float _31, _32, _33, _34; - float _41, _42, _43, _44; -}; - -#endif /* GFX_3DMATRIX_H */ diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 8b6c45872c..60fc186403 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -293,6 +293,7 @@ private: DECL_GFX_PREF(Live, "layers.composer2d.enabled", Composer2DCompositionEnabled, bool, false); DECL_GFX_PREF(Once, "layers.d3d11.disable-warp", LayersD3D11DisableWARP, bool, false); DECL_GFX_PREF(Once, "layers.d3d11.force-warp", LayersD3D11ForceWARP, bool, false); + DECL_GFX_PREF(Live, "layers.deaa.enabled", LayersDEAAEnabled, bool, false); DECL_GFX_PREF(Live, "layers.draw-bigimage-borders", DrawBigImageBorders, bool, false); DECL_GFX_PREF(Live, "layers.draw-borders", DrawLayerBorders, bool, false); DECL_GFX_PREF(Live, "layers.draw-tile-borders", DrawTileBorders, bool, false); diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build index 4de3570423..c7593327cf 100644 --- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -8,7 +8,6 @@ EXPORTS += [ 'ContextStateTracker.h', 'DrawMode.h', 'gfx2DGlue.h', - 'gfx3DMatrix.h', 'gfxAlphaRecovery.h', 'gfxASurface.h', 'gfxBaseSharedMemorySurface.h', @@ -213,7 +212,6 @@ SOURCES += [ UNIFIED_SOURCES += [ 'CJKCompatSVS.cpp', - 'gfx3DMatrix.cpp', 'gfxAlphaRecovery.cpp', 'gfxBaseSharedMemorySurface.cpp', 'gfxBlur.cpp', diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 8bd5ebf9d2..cbe58195d6 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -1246,7 +1246,7 @@ nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame, aBpd->ResetData(); } -void +/* static */ nscoord nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, int32_t aNumFramesOnLine, WritingMode aLineWM, @@ -1256,16 +1256,17 @@ nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, // If this line consists of a line frame, reorder the line frame's children. if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) { aFirstFrameOnLine = aFirstFrameOnLine->GetFirstPrincipalChild(); - if (!aFirstFrameOnLine) - return; + if (!aFirstFrameOnLine) { + return 0; + } // All children of the line frame are on the first line. Setting aNumFramesOnLine // to -1 makes InitLogicalArrayFromLine look at all of them. aNumFramesOnLine = -1; } BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); - RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, - aContainerSize, aStart); + return RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, + aContainerSize, aStart); } nsIFrame* @@ -1420,6 +1421,41 @@ nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame, } } +/* static */ void +nsBidiPresUtils::RepositionRubyContentFrame( + nsIFrame* aFrame, WritingMode aFrameWM, const LogicalMargin& aBorderPadding) +{ + const nsFrameList& childList = aFrame->PrincipalChildList(); + if (childList.IsEmpty()) { + return; + } + + // Reorder the children. + // XXX It currently doesn't work properly because we do not + // resolve frames inside ruby content frames. + nscoord isize = ReorderFrames(childList.FirstChild(), + childList.GetLength(), + aFrameWM, aFrame->GetSize(), + aBorderPadding.IStart(aFrameWM)); + isize += aBorderPadding.IEnd(aFrameWM); + + if (aFrame->StyleText()->mRubyAlign == NS_STYLE_RUBY_ALIGN_START) { + return; + } + nscoord residualISize = aFrame->ISize(aFrameWM) - isize; + if (residualISize <= 0) { + return; + } + + // When ruby-align is not "start", if the content does not fill this + // frame, we need to center the children. + for (nsIFrame* child : childList) { + LogicalRect rect = child->GetLogicalRect(aFrameWM, 0); + rect.IStart(aFrameWM) += residualISize / 2; + child->SetRect(aFrameWM, rect, 0); + } +} + /* static */ nscoord nsBidiPresUtils::RepositionRubyFrame( nsIFrame* aFrame, @@ -1475,14 +1511,7 @@ nsBidiPresUtils::RepositionRubyFrame( } else { if (frameType == nsGkAtoms::rubyBaseFrame || frameType == nsGkAtoms::rubyTextFrame) { - // Reorder the children. - // XXX It currently doesn't work properly because we do not - // resolve frames inside ruby content frames. - const nsFrameList& childList = aFrame->PrincipalChildList(); - if (childList.NotEmpty()) { - ReorderFrames(childList.FirstChild(), childList.GetLength(), - frameWM, frameSize, aBorderPadding.IStart(frameWM)); - } + RepositionRubyContentFrame(aFrame, frameWM, aBorderPadding); } // Note that, ruby text container is not present in all conditions // above. It is intended, because the children of rtc are reordered @@ -1619,7 +1648,7 @@ nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame, } } -void +/* static */ nscoord nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, nsIFrame* aFirstChild, WritingMode aLineWM, @@ -1656,6 +1685,7 @@ nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, start, &continuationStates, aLineWM, false, aContainerSize); } + return start; } bool diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h index dfa2acc81c..67ceb16910 100644 --- a/layout/base/nsBidiPresUtils.h +++ b/layout/base/nsBidiPresUtils.h @@ -159,14 +159,16 @@ public: /** * Reorder this line using Bidi engine. * Update frame array, following the new visual sequence. + * + * @return total inline size * * @lina 05/02/2000 */ - static void ReorderFrames(nsIFrame* aFirstFrameOnLine, - int32_t aNumFramesOnLine, - mozilla::WritingMode aLineWM, - const nsSize& aContainerSize, - nscoord aStart); + static nscoord ReorderFrames(nsIFrame* aFirstFrameOnLine, + int32_t aNumFramesOnLine, + mozilla::WritingMode aLineWM, + const nsSize& aContainerSize, + nscoord aStart); /** * Format Unicode text, taking into account bidi capabilities @@ -415,6 +417,14 @@ private: nsIFrame* aCurrentFrame, BidiParagraphData* aBpd); + /** + * Position ruby content frames (ruby base/text frame). + * Called from RepositionRubyFrame. + */ + static void RepositionRubyContentFrame( + nsIFrame* aFrame, mozilla::WritingMode aFrameWM, + const mozilla::LogicalMargin& aBorderPadding); + /* * Position ruby frames. Called from RepositionFrame. */ @@ -493,14 +503,15 @@ private: * Adjust frame positions following their visual order * * @param aFirstChild the first kid + * @return total inline size * * @lina 04/11/2000 */ - static void RepositionInlineFrames(BidiLineData* aBld, - nsIFrame* aFirstChild, - mozilla::WritingMode aLineWM, - const nsSize& aContainerSize, - nscoord aStart); + static nscoord RepositionInlineFrames(BidiLineData* aBld, + nsIFrame* aFirstChild, + mozilla::WritingMode aLineWM, + const nsSize& aContainerSize, + nscoord aStart); /** * Helper method for Resolve() diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index b541ba8274..e5b910fc2c 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -545,7 +545,7 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer, // XXX Performance here isn't ideal for SVG. We'd prefer to avoid resolving // the dimensions of refBox. That said, we only get here if there are CSS // animations or transitions on this element, and that is likely to be a - // lot rarer that transforms on SVG (the frequency of which drives the need + // lot rarer than transforms on SVG (the frequency of which drives the need // for TransformReferenceBox). TransformReferenceBox refBox(aFrame); nsRect bounds(0, 0, refBox.Width(), refBox.Height()); @@ -4690,7 +4690,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, Init(aBuilder); } -/* Returns the delta specified by the -moz-transform-origin property. +/* Returns the delta specified by the -transform-origin property. * This is a positive delta, meaning that it indicates the direction to move * to get from (0, 0) of the frame to the transform origin. This function is * called off the main thread. @@ -4708,7 +4708,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, return Point3D(); } - /* For both of the coordinates, if the value of -moz-transform is a + /* For both of the coordinates, if the value of -transform is a * percentage, it's relative to the size of the frame. Otherwise, if it's * a distance, it's already computed for us! */ @@ -4732,7 +4732,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, { &TransformReferenceBox::X, &TransformReferenceBox::Y }; for (uint8_t index = 0; index < 2; ++index) { - /* If the -moz-transform-origin specifies a percentage, take the percentage + /* If the -transform-origin specifies a percentage, take the percentage * of the size of the box. */ const nsStyleCoord &coord = display->mTransformOrigin[index]; @@ -4812,7 +4812,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, { &TransformReferenceBox::Width, &TransformReferenceBox::Height }; for (uint8_t index = 0; index < 2; ++index) { - /* If the -moz-transform-origin specifies a percentage, take the percentage + /* If the -transform-origin specifies a percentage, take the percentage * of the size of the box. */ const nsStyleCoord &coord = display->mPerspectiveOrigin[index]; @@ -4865,7 +4865,7 @@ nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsI } } -/* Wraps up the -moz-transform matrix in a change-of-basis matrix pair that +/* Wraps up the -transform matrix in a change-of-basis matrix pair that * translates from local coordinate space to transform coordinate space, then * hands it back. */ @@ -4960,7 +4960,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp result = result * perspective; } - /* Account for the -moz-transform-origin property by translating the + /* Account for the -transform-origin property by translating the * coordinate space to the new origin. */ Point3D newOrigin = diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 7dbbde0451..c2f07892f6 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -141,7 +141,7 @@ typedef nsStyleTransformMatrix::TransformReferenceBox TransformReferenceBox; /* static */ bool nsLayoutUtils::sInvalidationDebuggingIsEnabled; /* static */ bool nsLayoutUtils::sCSSVariablesEnabled; /* static */ bool nsLayoutUtils::sInterruptibleReflowEnabled; -/* static */ bool nsLayoutUtils::sSVGTransformOriginEnabled; +/* static */ bool nsLayoutUtils::sSVGTransformBoxEnabled; static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID; @@ -7297,8 +7297,8 @@ nsLayoutUtils::Initialize() "layout.css.variables.enabled"); Preferences::AddBoolVarCache(&sInterruptibleReflowEnabled, "layout.interruptible-reflow.enabled"); - Preferences::AddBoolVarCache(&sSVGTransformOriginEnabled, - "svg.transform-origin.enabled"); + Preferences::AddBoolVarCache(&sSVGTransformBoxEnabled, + "svg.transform-box.enabled"); Preferences::RegisterCallback(GridEnabledPrefChangeCallback, GRID_ENABLED_PREF_NAME); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index ca7e27c9ec..09f3abe09f 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2344,8 +2344,8 @@ public: return sFontSizeInflationDisabledInMasterProcess; } - static bool SVGTransformOriginEnabled() { - return sSVGTransformOriginEnabled; + static bool SVGTransformBoxEnabled() { + return sSVGTransformBoxEnabled; } /** @@ -2715,7 +2715,7 @@ private: static bool sInvalidationDebuggingIsEnabled; static bool sCSSVariablesEnabled; static bool sInterruptibleReflowEnabled; - static bool sSVGTransformOriginEnabled; + static bool sSVGTransformBoxEnabled; /** * Helper function for LogTestDataForPaint(). diff --git a/layout/forms/crashtests/1140216.html b/layout/forms/crashtests/1140216.html new file mode 100644 index 0000000000..72612b8b3c --- /dev/null +++ b/layout/forms/crashtests/1140216.html @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/layout/forms/crashtests/997709-1.html b/layout/forms/crashtests/997709-1.html new file mode 100644 index 0000000000..31d048407d --- /dev/null +++ b/layout/forms/crashtests/997709-1.html @@ -0,0 +1,5 @@ + +
+
+ +
diff --git a/layout/forms/crashtests/crashtests.list b/layout/forms/crashtests/crashtests.list index 87cfa6df53..8241012edd 100644 --- a/layout/forms/crashtests/crashtests.list +++ b/layout/forms/crashtests/crashtests.list @@ -59,4 +59,6 @@ load 944198.html load 949891.xhtml load 959311.html load 960277-2.html +load 997709-1.html load 1102791.html +load 1140216.html diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index e48bfa45ad..c569f72e9a 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -220,11 +220,11 @@ nsComboboxControlFrame::nsComboboxControlFrame(nsStyleContext* aContext) , mButtonFrame(nullptr) , mDropdownFrame(nullptr) , mListControlFrame(nullptr) - , mDisplayWidth(0) + , mDisplayISize(0) , mRecentSelectedIndex(NS_SKIP_NOTIFY_INDEX) , mDisplayedIndex(-1) - , mLastDropDownAboveScreenY(nscoord_MIN) - , mLastDropDownBelowScreenY(nscoord_MIN) + , mLastDropDownBeforeScreenBCoord(nscoord_MIN) + , mLastDropDownAfterScreenBCoord(nscoord_MIN) , mDroppedDown(false) , mInRedisplayText(false) , mDelayedShowDropDown(false) @@ -413,7 +413,7 @@ void nsComboboxControlFrame::ReflowDropdown(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState) { - // All we want out of it later on, really, is the height of a row, so we + // All we want out of it later on, really, is the block size of a row, so we // don't even need to cache mDropdownFrame's ascent or anything. If we don't // need to reflow it, just bail out here. if (!aReflowState.ShouldReflowAllKids() && @@ -421,23 +421,24 @@ nsComboboxControlFrame::ReflowDropdown(nsPresContext* aPresContext, return; } - // XXXbz this will, for small-height dropdowns, have extra space on the right - // edge for the scrollbar we don't show... but that's the best we can do here - // for now. + // XXXbz this will, for small-block-size dropdowns, have extra space + // on the appropriate edge for the scrollbar we don't show... but + // that's the best we can do here for now. WritingMode wm = mDropdownFrame->GetWritingMode(); LogicalSize availSize = aReflowState.AvailableSize(wm); availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; nsHTMLReflowState kidReflowState(aPresContext, aReflowState, mDropdownFrame, availSize); - // If the dropdown's intrinsic width is narrower than our specified width, - // then expand it out. We want our border-box width to end up the same as - // the dropdown's so account for both sets of mComputedBorderPadding. - nscoord forcedWidth = aReflowState.ComputedWidth() + - aReflowState.ComputedPhysicalBorderPadding().LeftRight() - - kidReflowState.ComputedPhysicalBorderPadding().LeftRight(); - kidReflowState.SetComputedWidth(std::max(kidReflowState.ComputedWidth(), - forcedWidth)); + // If the dropdown's intrinsic inline size is narrower than our + // specified inline size, then expand it out. We want our border-box + // inline size to end up the same as the dropdown's so account for + // both sets of mComputedBorderPadding. + nscoord forcedISize = aReflowState.ComputedISize() + + aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm) - + kidReflowState.ComputedLogicalBorderPadding().IStartEnd(wm); + kidReflowState.SetComputedISize(std::max(kidReflowState.ComputedISize(), + forcedISize)); // ensure we start off hidden if (GetStateBits() & NS_FRAME_FIRST_REFLOW) { @@ -450,19 +451,26 @@ nsComboboxControlFrame::ReflowDropdown(nsPresContext* aPresContext, // Allow the child to move/size/change-visibility its view if it's currently // dropped down - int32_t flags = NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_VISIBILITY | NS_FRAME_NO_SIZE_VIEW; - if (mDroppedDown) { - flags = 0; - } - nsRect rect = mDropdownFrame->GetRect(); + int32_t flags = mDroppedDown ? 0 + : NS_FRAME_NO_MOVE_FRAME | + NS_FRAME_NO_VISIBILITY | + NS_FRAME_NO_SIZE_VIEW; + + //XXX Can this be different from the dropdown's writing mode? + // That would be odd! + // Note that we don't need to pass the true frame position or container width + // to ReflowChild or FinishReflowChild here; it will be positioned as needed + // by AbsolutelyPositionDropDown(). + WritingMode outerWM = GetWritingMode(); nsHTMLReflowMetrics desiredSize(aReflowState); nsReflowStatus ignoredStatus; ReflowChild(mDropdownFrame, aPresContext, desiredSize, - kidReflowState, rect.x, rect.y, flags, ignoredStatus); + kidReflowState, outerWM, LogicalPoint(outerWM), 0, + flags, ignoredStatus); // Set the child's width and height to its desired size - FinishReflowChild(mDropdownFrame, aPresContext, desiredSize, - &kidReflowState, rect.x, rect.y, flags); + FinishReflowChild(mDropdownFrame, aPresContext, desiredSize, &kidReflowState, + outerWM, LogicalPoint(outerWM), 0, flags); } nsPoint @@ -544,71 +552,81 @@ public: }; void -nsComboboxControlFrame::GetAvailableDropdownSpace(nscoord* aAbove, - nscoord* aBelow, - nsPoint* aTranslation) +nsComboboxControlFrame::GetAvailableDropdownSpace(WritingMode aWM, + nscoord* aBefore, + nscoord* aAfter, + LogicalPoint* aTranslation) { - // Note: At first glance, it appears that you could simply get the absolute - // bounding box for the dropdown list by first getting its view, then getting - // the view's nsIWidget, then asking the nsIWidget for its AbsoluteBounds. - // The problem with this approach, is that the dropdown lists y location can - // change based on whether the dropdown is placed below or above the display - // frame. The approach, taken here is to get the absolute position of the - // display frame and use its location to determine if the dropdown will go - // offscreen. + // Note: At first glance, it appears that you could simply get the + // absolute bounding box for the dropdown list by first getting its + // view, then getting the view's nsIWidget, then asking the nsIWidget + // for its AbsoluteBounds. + // The problem with this approach, is that the dropdown list's bcoord + // location can change based on whether the dropdown is placed after + // or before the display frame. The approach taken here is to get the + // absolute position of the display frame and use its location to + // determine if the dropdown will go offscreen. // Normal frame geometry (eg GetOffsetTo, mRect) doesn't include transforms. // In the special case that our transform is only a 2D translation we // introduce this hack so that the dropdown will show up in the right place. - *aTranslation = GetCSSTransformTranslation(); - *aAbove = 0; - *aBelow = 0; + *aTranslation = LogicalPoint(aWM, GetCSSTransformTranslation(), 0); + *aBefore = 0; + *aAfter = 0; nsRect screen = nsFormControlFrame::GetUsableScreenRect(PresContext()); - if (mLastDropDownBelowScreenY == nscoord_MIN) { - nsRect thisScreenRect = GetScreenRectInAppUnits(); - mLastDropDownBelowScreenY = thisScreenRect.YMost() + aTranslation->y; - mLastDropDownAboveScreenY = thisScreenRect.y + aTranslation->y; + nscoord containerWidth = screen.width; + LogicalRect logicalScreen(aWM, screen, containerWidth); + if (mLastDropDownAfterScreenBCoord == nscoord_MIN) { + LogicalRect thisScreenRect(aWM, GetScreenRectInAppUnits(), + containerWidth); + mLastDropDownAfterScreenBCoord = thisScreenRect.BEnd(aWM) + + aTranslation->B(aWM); + mLastDropDownBeforeScreenBCoord = thisScreenRect.BEnd(aWM) + + aTranslation->B(aWM); } - nscoord minY; + nscoord minBCoord; nsPresContext* pc = PresContext()->GetToplevelContentDocumentPresContext(); nsIFrame* root = pc ? pc->PresShell()->GetRootFrame() : nullptr; if (root) { - minY = root->GetScreenRectInAppUnits().y; - if (mLastDropDownBelowScreenY < minY) { - // Don't allow the drop-down to be placed above the content area. + minBCoord = LogicalRect(aWM, + root->GetScreenRectInAppUnits(), + containerWidth).BStart(aWM); + if (mLastDropDownAfterScreenBCoord < minBCoord) { + // Don't allow the drop-down to be placed before the content area. return; } } else { - minY = screen.y; + minBCoord = logicalScreen.BStart(aWM); } - nscoord below = screen.YMost() - mLastDropDownBelowScreenY; - nscoord above = mLastDropDownAboveScreenY - minY; + nscoord after = logicalScreen.BEnd(aWM) - mLastDropDownAfterScreenBCoord; + nscoord before = mLastDropDownBeforeScreenBCoord - minBCoord; - // If the difference between the space above and below is less - // than a row-height, then we favor the space below. - if (above >= below) { + // If the difference between the space before and after is less + // than a row-block-size, then we favor the space after. + if (before >= after) { nsListControlFrame* lcf = static_cast(mDropdownFrame); - nscoord rowHeight = lcf->GetHeightOfARow(); - if (above < below + rowHeight) { - above -= rowHeight; + nscoord rowBSize = lcf->GetBSizeOfARow(); + if (before < after + rowBSize) { + before -= rowBSize; } } - *aBelow = below; - *aAbove = above; + *aAfter = after; + *aBefore = before; } nsComboboxControlFrame::DropDownPositionState nsComboboxControlFrame::AbsolutelyPositionDropDown() { - nsPoint translation; - nscoord above, below; - mLastDropDownBelowScreenY = nscoord_MIN; - GetAvailableDropdownSpace(&above, &below, &translation); - if (above <= 0 && below <= 0) { + WritingMode wm = GetWritingMode(); + LogicalPoint translation(wm); + nscoord before, after; + mLastDropDownAfterScreenBCoord = nscoord_MIN; + GetAvailableDropdownSpace(wm, &before, &after, &translation); + if (before <= 0 && after <= 0) { if (IsDroppedDown()) { // Hide the view immediately to minimize flicker. nsView* view = mDropdownFrame->GetView(); @@ -618,17 +636,17 @@ nsComboboxControlFrame::AbsolutelyPositionDropDown() return eDropDownPositionSuppressed; } - nsSize dropdownSize = mDropdownFrame->GetSize(); - nscoord height = std::max(above, below); + LogicalSize dropdownSize = mDropdownFrame->GetLogicalSize(wm); + nscoord bSize = std::max(before, after); nsListControlFrame* lcf = static_cast(mDropdownFrame); - if (height < dropdownSize.height) { + if (bSize < dropdownSize.BSize(wm)) { if (lcf->GetNumDisplayRows() > 1) { // The drop-down doesn't fit and currently shows more than 1 row - // schedule a resize to show fewer rows. NS_DispatchToCurrentThread(new nsAsyncResize(this)); return eDropDownPositionPendingResize; } - } else if (height > (dropdownSize.height + lcf->GetHeightOfARow() * 1.5) && + } else if (bSize > (dropdownSize.BSize(wm) + lcf->GetBSizeOfARow() * 1.5) && lcf->GetDropdownCanGrow()) { // The drop-down fits but there is room for at least 1.5 more rows - // schedule a resize to show more rows if it has more rows to show. @@ -638,22 +656,20 @@ nsComboboxControlFrame::AbsolutelyPositionDropDown() return eDropDownPositionPendingResize; } - // Position the drop-down below if there is room, otherwise place it above + // Position the drop-down after if there is room, otherwise place it before // if there is room. If there is no room for it on either side then place - // it below (to avoid overlapping UI like the URL bar). - bool b = dropdownSize.height <= below || dropdownSize.height > above; - nsPoint dropdownPosition(0, b ? GetRect().height : -dropdownSize.height); - if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { - // Align the right edge of the drop-down with the right edge of the control. - dropdownPosition.x = GetRect().width - dropdownSize.width; - } + // it after (to avoid overlapping UI like the URL bar). + bool b = dropdownSize.BSize(wm)<= after || dropdownSize.BSize(wm) > before; + LogicalPoint dropdownPosition(wm, 0, b ? BSize(wm) : -dropdownSize.BSize(wm)); // Don't position the view unless the position changed since it might cause // a call to NotifyGeometryChange() and an infinite loop here. - const nsPoint currentPos = mDropdownFrame->GetPosition(); - const nsPoint newPos = dropdownPosition + translation; + nscoord containerWidth = GetRect().width; + const LogicalPoint currentPos = + mDropdownFrame->GetLogicalPosition(containerWidth); + const LogicalPoint newPos = dropdownPosition + translation; if (currentPos != newPos) { - mDropdownFrame->SetPosition(newPos); + mDropdownFrame->SetPosition(wm, newPos, containerWidth); nsContainerFrame::PositionFrameView(mDropdownFrame); } return eDropDownPositionFinal; @@ -711,63 +727,63 @@ nsComboboxControlFrame::GetIntrinsicISize(nsRenderingContext* aRenderingContext, presContext, aRenderingContext); } - nscoord displayWidth = 0; + nscoord displayISize = 0; if (MOZ_LIKELY(mDisplayFrame)) { - displayWidth = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, + displayISize = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, mDisplayFrame, aType); } if (mDropdownFrame) { - nscoord dropdownContentWidth; + nscoord dropdownContentISize; bool isUsingOverlayScrollbars = LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0; if (aType == nsLayoutUtils::MIN_ISIZE) { - dropdownContentWidth = mDropdownFrame->GetMinISize(aRenderingContext); + dropdownContentISize = mDropdownFrame->GetMinISize(aRenderingContext); if (isUsingOverlayScrollbars) { - dropdownContentWidth += scrollbarWidth; + dropdownContentISize += scrollbarWidth; } } else { NS_ASSERTION(aType == nsLayoutUtils::PREF_ISIZE, "Unexpected type"); - dropdownContentWidth = mDropdownFrame->GetPrefISize(aRenderingContext); + dropdownContentISize = mDropdownFrame->GetPrefISize(aRenderingContext); if (isUsingOverlayScrollbars) { - dropdownContentWidth += scrollbarWidth; + dropdownContentISize += scrollbarWidth; } } - dropdownContentWidth = NSCoordSaturatingSubtract(dropdownContentWidth, + dropdownContentISize = NSCoordSaturatingSubtract(dropdownContentISize, scrollbarWidth, nscoord_MAX); - displayWidth = std::max(dropdownContentWidth, displayWidth); + displayISize = std::max(dropdownContentISize, displayISize); } // add room for the dropmarker button if there is one if ((!IsThemed() || presContext->GetTheme()->ThemeNeedsComboboxDropmarker()) && StyleDisplay()->mAppearance != NS_THEME_NONE) { - displayWidth += scrollbarWidth; + displayISize += scrollbarWidth; } - return displayWidth; + return displayISize; } nscoord nsComboboxControlFrame::GetMinISize(nsRenderingContext *aRenderingContext) { - nscoord minWidth; - DISPLAY_MIN_WIDTH(this, minWidth); - minWidth = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::MIN_ISIZE); - return minWidth; + nscoord minISize; + DISPLAY_MIN_WIDTH(this, minISize); + minISize = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::MIN_ISIZE); + return minISize; } nscoord nsComboboxControlFrame::GetPrefISize(nsRenderingContext *aRenderingContext) { - nscoord prefWidth; - DISPLAY_PREF_WIDTH(this, prefWidth); - prefWidth = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::PREF_ISIZE); - return prefWidth; + nscoord prefISize; + DISPLAY_PREF_WIDTH(this, prefISize); + prefISize = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::PREF_ISIZE); + return prefISize; } void @@ -779,13 +795,13 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); // Constraints we try to satisfy: - // 1) Default width of button is the vertical scrollbar size - // 2) If the width of button is bigger than our width, set width of - // button to 0. - // 3) Default height of button is height of display area - // 4) Width of display area is whatever is left over from our width after - // allocating width for the button. - // 5) Height of display area is GetHeightOfARow() on the + // 1) Default inline size of button is the vertical scrollbar size + // 2) If the inline size of button is bigger than our inline size, set + // inline size of button to 0. + // 3) Default block size of button is block size of display area + // 4) Inline size of display area is whatever is left over from our + // inline size after allocating inline size for the button. + // 5) Block Size of display area is GetBSizeOfARow() on the // mListControlFrame. if (!mDisplayFrame || !mButtonFrame || !mDropdownFrame) { @@ -821,48 +837,46 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, unused << resize.forget(); } - // Get the width of the vertical scrollbar. That will be the width of the - // dropdown button. - nscoord buttonWidth; + // Get the width of the vertical scrollbar. That will be the inline + // size of the dropdown button. + nscoord buttonISize; const nsStyleDisplay *disp = StyleDisplay(); if ((IsThemed(disp) && !aPresContext->GetTheme()->ThemeNeedsComboboxDropmarker()) || StyleDisplay()->mAppearance == NS_THEME_NONE) { - buttonWidth = 0; + buttonISize = 0; } else { nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame); NS_ASSERTION(scrollable, "List must be a scrollable frame"); - buttonWidth = scrollable->GetNondisappearingScrollbarWidth( + buttonISize = scrollable->GetNondisappearingScrollbarWidth( PresContext(), aReflowState.rendContext); - if (buttonWidth > aReflowState.ComputedWidth()) { - buttonWidth = 0; + if (buttonISize > aReflowState.ComputedISize()) { + buttonISize = 0; } } - mDisplayWidth = aReflowState.ComputedWidth() - buttonWidth; + mDisplayISize = aReflowState.ComputedISize() - buttonISize; nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); // The button should occupy the same space as a scrollbar - nsRect buttonRect = mButtonFrame->GetRect(); + WritingMode wm = aReflowState.GetWritingMode(); + nscoord containerWidth = + aReflowState.ComputedSizeAsContainerIfConstrained().width; + LogicalRect buttonRect = mButtonFrame->GetLogicalRect(containerWidth); - if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { - buttonRect.x = aReflowState.ComputedPhysicalBorderPadding().left - - aReflowState.ComputedPhysicalPadding().left; - } - else { - buttonRect.x = aReflowState.ComputedPhysicalBorderPadding().LeftRight() + - mDisplayWidth - - (aReflowState.ComputedPhysicalBorderPadding().right - - aReflowState.ComputedPhysicalPadding().right); - } - buttonRect.width = buttonWidth; + buttonRect.IStart(wm) = + aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm) + + mDisplayISize - + (aReflowState.ComputedLogicalBorderPadding().IEnd(wm) - + aReflowState.ComputedLogicalPadding().IEnd(wm)); + buttonRect.ISize(wm) = buttonISize; - buttonRect.y = this->GetUsedBorder().top; - buttonRect.height = mDisplayFrame->GetRect().height + - this->GetUsedPadding().TopBottom(); + buttonRect.BStart(wm) = this->GetLogicalUsedBorder(wm).BStart(wm); + buttonRect.BSize(wm) = mDisplayFrame->BSize(wm) + + this->GetLogicalUsedPadding(wm).BStartEnd(wm); - mButtonFrame->SetRect(buttonRect); + mButtonFrame->SetRect(buttonRect, containerWidth); if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && !NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { @@ -1018,7 +1032,7 @@ nsComboboxControlFrame::ActuallyDisplayText(bool aNotify) { nsCOMPtr displayContent = mDisplayContent; if (mDisplayedOptionText.IsEmpty()) { - // Have to use a non-breaking space for line-height calculations + // Have to use a non-breaking space for line-block-size calculations // to be right static const char16_t space = 0xA0; displayContent->SetText(&space, 1, aNotify); @@ -1222,8 +1236,8 @@ public: mComboBox(aComboBox) {} - // Need this so that line layout knows that this block's width - // depends on the available width. + // Need this so that line layout knows that this block's inline size + // depends on the available inline size. virtual nsIAtom* GetType() const override; virtual bool IsFrameOfType(uint32_t aFlags) const override @@ -1260,20 +1274,21 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { nsHTMLReflowState state(aReflowState); - if (state.ComputedHeight() == NS_INTRINSICSIZE) { - // Note that the only way we can have a computed height here is if the - // combobox had a specified height. If it didn't, size based on what our - // rows look like, for lack of anything better. - state.SetComputedHeight(mComboBox->mListControlFrame->GetHeightOfARow()); + if (state.ComputedBSize() == NS_INTRINSICSIZE) { + // Note that the only way we can have a computed block size here is + // if the combobox had a specified block size. If it didn't, size + // based on what our rows look like, for lack of anything better. + state.SetComputedBSize(mComboBox->mListControlFrame->GetBSizeOfARow()); } - nscoord computedWidth = mComboBox->mDisplayWidth - - state.ComputedPhysicalBorderPadding().LeftRight(); - if (computedWidth < 0) { - computedWidth = 0; + WritingMode wm = aReflowState.GetWritingMode(); + nscoord computedISize = mComboBox->mDisplayISize - + state.ComputedLogicalBorderPadding().IStartEnd(wm); + if (computedISize < 0) { + computedISize = 0; } - state.SetComputedWidth(computedWidth); - - return nsBlockFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); + state.SetComputedISize(computedISize); + nsBlockFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); + aStatus = NS_FRAME_COMPLETE; // this type of frame can't be split } void @@ -1312,7 +1327,8 @@ nsComboboxControlFrame::CreateFrameFor(nsIContent* aContent) nsRefPtr styleContext; styleContext = styleSet-> ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozDisplayComboboxControlFrame, - mStyleContext); + mStyleContext, + nsStyleSet::eSkipParentDisplayBasedStyleFixup); nsRefPtr textStyleContext; textStyleContext = styleSet->ResolveStyleForNonElement(mStyleContext); diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index 0819d60491..6cc9503398 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -146,14 +146,15 @@ public: virtual void RollupFromList() override; /** - * Return the available space above and below this frame for + * Return the available space before and after this frame for * placing the drop-down list, and the current 2D translation. * Note that either or both can be less than or equal to zero, * if both are then the drop-down should be closed. */ - void GetAvailableDropdownSpace(nscoord* aAbove, - nscoord* aBelow, - nsPoint* aTranslation); + void GetAvailableDropdownSpace(mozilla::WritingMode aWM, + nscoord* aBefore, + nscoord* aAfter, + mozilla::LogicalPoint* aTranslation); virtual int32_t GetIndexOfDisplayArea() override; /** * @note This method might destroy |this|. @@ -271,9 +272,9 @@ protected: nsIFrame* mDropdownFrame; // dropdown list frame nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame - // The width of our display area. Used by that frame's reflow to - // size to the full width except the drop-marker. - nscoord mDisplayWidth; + // The inline size of our display area. Used by that frame's reflow + // to size to the full inline size except the drop-marker. + nscoord mDisplayISize; nsRevocableEventPtr mRedisplayTextEvent; @@ -285,13 +286,13 @@ protected: // then open or close the combo box. nsCOMPtr mButtonListener; - // The last y-positions used for estimating available space above and - // below for the dropdown list in GetAvailableDropdownSpace. These are + // The last y-positions used for estimating available space before and + // after for the dropdown list in GetAvailableDropdownSpace. These are // reset to nscoord_MIN in AbsolutelyPositionDropDown when placing the // dropdown at its actual position. The GetAvailableDropdownSpace call // from nsListControlFrame::ReflowAsDropdown use the last position. - nscoord mLastDropDownAboveScreenY; - nscoord mLastDropDownBelowScreenY; + nscoord mLastDropDownBeforeScreenBCoord; + nscoord mLastDropDownAfterScreenBCoord; // Current state of the dropdown list, true is dropped down. bool mDroppedDown; // See comment in HandleRedisplayTextEvent(). diff --git a/layout/forms/nsIListControlFrame.h b/layout/forms/nsIListControlFrame.h index cfdb4e8057..bb91483580 100644 --- a/layout/forms/nsIListControlFrame.h +++ b/layout/forms/nsIListControlFrame.h @@ -54,10 +54,10 @@ public: virtual void CaptureMouseEvents(bool aGrabMouseEvents) = 0; /** - * Returns the height of a single row in the list. This is the - * maximum of the heights of all the options/optgroups. + * Returns the block size of a single row in the list. This is the + * maximum of the block sizes of all the options/optgroups. */ - virtual nscoord GetHeightOfARow() = 0; + virtual nscoord GetBSizeOfARow() = 0; /** * Returns the number of options in the listbox diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 44c6fc7650..179c9bfab4 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -97,7 +97,7 @@ nsListControlFrame::nsListControlFrame(nsStyleContext* aContext) mHasPendingInterruptAtStartOfReflow(false), mDropdownCanGrow(false), mForceSelection(false), - mLastDropdownComputedHeight(NS_UNCONSTRAINEDSIZE) + mLastDropdownComputedBSize(NS_UNCONSTRAINEDSIZE) { mComboboxFrame = nullptr; mChangesSinceDragStart = false; @@ -206,8 +206,13 @@ void nsListControlFrame::PaintFocus(nsRenderingContext& aRC, nsPoint aPt) } else { float inflation = nsLayoutUtils::FontSizeInflationFor(this); fRect.x = fRect.y = 0; - fRect.width = GetScrollPortRect().width; - fRect.height = CalcFallbackRowHeight(inflation); + if (GetWritingMode().IsVertical()) { + fRect.width = GetScrollPortRect().width; + fRect.height = CalcFallbackRowBSize(inflation); + } else { + fRect.width = CalcFallbackRowBSize(inflation); + fRect.height = GetScrollPortRect().height; + } fRect.MoveBy(containerFrame->GetOffsetTo(this)); } fRect += aPt; @@ -257,22 +262,22 @@ nsListControlFrame::AccessibleType() #endif static nscoord -GetMaxOptionHeight(nsIFrame* aContainer) +GetMaxOptionBSize(nsIFrame* aContainer, WritingMode aWM) { nscoord result = 0; for (nsIFrame* option = aContainer->GetFirstPrincipalChild(); option; option = option->GetNextSibling()) { - nscoord optionHeight; + nscoord optionBSize; if (nsCOMPtr (do_QueryInterface(option->GetContent()))) { // an optgroup - optionHeight = GetMaxOptionHeight(option); + optionBSize = GetMaxOptionBSize(option, aWM); } else { // an option - optionHeight = option->GetSize().height; + optionBSize = option->BSize(aWM); } - if (result < optionHeight) - result = optionHeight; + if (result < optionBSize) + result = optionBSize; } return result; } @@ -282,22 +287,24 @@ GetMaxOptionHeight(nsIFrame* aContainer) //----------------------------------------------------------------- nscoord -nsListControlFrame::CalcHeightOfARow() +nsListControlFrame::CalcBSizeOfARow() { - // Calculate the height of a single row in the listbox or dropdown list by - // using the tallest thing in the subtree, since there may be option groups - // in addition to option elements, either of which may be visible or - // invisible, may use different fonts, etc. - int32_t heightOfARow = GetMaxOptionHeight(GetOptionsContainer()); + // Calculate the block size in our writing mode of a single row in the + // listbox or dropdown list by using the tallest thing in the subtree, + // since there may be option groups in addition to option elements, + // either of which may be visible or invisible, may use different + // fonts, etc. + int32_t blockSizeOfARow = GetMaxOptionBSize(GetOptionsContainer(), + GetWritingMode()); // Check to see if we have zero items (and optimize by checking - // heightOfARow first) - if (heightOfARow == 0 && GetNumberOfOptions() == 0) { + // blockSizeOfARow first) + if (blockSizeOfARow == 0 && GetNumberOfOptions() == 0) { float inflation = nsLayoutUtils::FontSizeInflationFor(this); - heightOfARow = CalcFallbackRowHeight(inflation); + blockSizeOfARow = CalcFallbackRowBSize(inflation); } - return heightOfARow; + return blockSizeOfARow; } nscoord @@ -306,13 +313,15 @@ nsListControlFrame::GetPrefISize(nsRenderingContext *aRenderingContext) nscoord result; DISPLAY_PREF_WIDTH(this, result); - // Always add scrollbar widths to the pref-width of the scrolled - // content. Combobox frames depend on this happening in the dropdown, - // and standalone listboxes are overflow:scroll so they need it too. + // Always add scrollbar inline sizes to the pref-inline-size of the + // scrolled content. Combobox frames depend on this happening in the + // dropdown, and standalone listboxes are overflow:scroll so they need + // it too. + WritingMode wm = GetWritingMode(); result = GetScrolledFrame()->GetPrefISize(aRenderingContext); - result = NSCoordSaturatingAdd(result, - GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight()); - + LogicalMargin scrollbarSize(wm, GetDesiredScrollbarSizes(PresContext(), + aRenderingContext)); + result = NSCoordSaturatingAdd(result, scrollbarSize.IStartEnd(wm)); return result; } @@ -322,11 +331,15 @@ nsListControlFrame::GetMinISize(nsRenderingContext *aRenderingContext) nscoord result; DISPLAY_MIN_WIDTH(this, result); - // Always add scrollbar widths to the min-width of the scrolled - // content. Combobox frames depend on this happening in the dropdown, - // and standalone listboxes are overflow:scroll so they need it too. + // Always add scrollbar inline sizes to the min-inline-size of the + // scrolled content. Combobox frames depend on this happening in the + // dropdown, and standalone listboxes are overflow:scroll so they need + // it too. + WritingMode wm = GetWritingMode(); result = GetScrolledFrame()->GetMinISize(aRenderingContext); - result += GetDesiredScrollbarSizes(PresContext(), aRenderingContext).LeftRight(); + LogicalMargin scrollbarSize(wm, GetDesiredScrollbarSizes(PresContext(), + aRenderingContext)); + result += scrollbarSize.IStartEnd(wm); return result; } @@ -337,8 +350,8 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - NS_PRECONDITION(aReflowState.ComputedWidth() != NS_UNCONSTRAINEDSIZE, - "Must have a computed width"); + NS_PRECONDITION(aReflowState.ComputedISize() != NS_UNCONSTRAINEDSIZE, + "Must have a computed inline size"); SchedulePaint(); @@ -366,65 +379,69 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); /* - * Due to the fact that our intrinsic height depends on the heights of our - * kids, we end up having to do two-pass reflow, in general -- the first pass - * to find the intrinsic height and a second pass to reflow the scrollframe - * at that height (which will size the scrollbars correctly, etc). + * Due to the fact that our intrinsic block size depends on the block + * sizes of our kids, we end up having to do two-pass reflow, in + * general -- the first pass to find the intrinsic block size and a + * second pass to reflow the scrollframe at that block size (which + * will size the scrollbars correctly, etc). * - * Naturaly, we want to avoid doing the second reflow as much as possible. - * We can skip it in the following cases (in all of which the first reflow is - * already happening at the right height): + * Naturally, we want to avoid doing the second reflow as much as + * possible. + * We can skip it in the following cases (in all of which the first + * reflow is already happening at the right block size): * - * - We're reflowing with a constrained computed height -- just use that - * height. - * - We're not dirty and have no dirty kids and shouldn't be reflowing all - * kids. In this case, our cached max height of a child is not going to - * change. - * - We do our first reflow using our cached max height of a child, then - * compute the new max height and it's the same as the old one. + * - We're reflowing with a constrained computed block size -- just + * use that block size. + * - We're not dirty and have no dirty kids and shouldn't be reflowing + * all kids. In this case, our cached max block size of a child is + * not going to change. + * - We do our first reflow using our cached max block size of a + * child, then compute the new max block size and it's the same as + * the old one. */ - bool autoHeight = (aReflowState.ComputedHeight() == NS_UNCONSTRAINEDSIZE); + bool autoBSize = (aReflowState.ComputedBSize() == NS_UNCONSTRAINEDSIZE); - mMightNeedSecondPass = autoHeight && + mMightNeedSecondPass = autoBSize && (NS_SUBTREE_DIRTY(this) || aReflowState.ShouldReflowAllKids()); nsHTMLReflowState state(aReflowState); int32_t length = GetNumberOfRows(); - nscoord oldHeightOfARow = HeightOfARow(); + nscoord oldBSizeOfARow = BSizeOfARow(); - if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW) && autoHeight) { - // When not doing an initial reflow, and when the height is auto, start off - // with our computed height set to what we'd expect our height to be. - nscoord computedHeight = CalcIntrinsicBSize(oldHeightOfARow, length); - computedHeight = state.ApplyMinMaxHeight(computedHeight); - state.SetComputedHeight(computedHeight); + if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW) && autoBSize) { + // When not doing an initial reflow, and when the block size is + // auto, start off with our computed block size set to what we'd + // expect our block size to be. + nscoord computedBSize = CalcIntrinsicBSize(oldBSizeOfARow, length); + computedBSize = state.ApplyMinMaxBSize(computedBSize); + state.SetComputedBSize(computedBSize); } nsHTMLScrollFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); if (!mMightNeedSecondPass) { - NS_ASSERTION(!autoHeight || HeightOfARow() == oldHeightOfARow, - "How did our height of a row change if nothing was dirty?"); - NS_ASSERTION(!autoHeight || + NS_ASSERTION(!autoBSize || BSizeOfARow() == oldBSizeOfARow, + "How did our BSize of a row change if nothing was dirty?"); + NS_ASSERTION(!autoBSize || !(GetStateBits() & NS_FRAME_FIRST_REFLOW), "How do we not need a second pass during initial reflow at " - "auto height?"); + "auto BSize?"); NS_ASSERTION(!IsScrollbarUpdateSuppressed(), "Shouldn't be suppressing if we don't need a second pass!"); - if (!autoHeight) { - // Update our mNumDisplayRows based on our new row height now that we - // know it. Note that if autoHeight and we landed in this code then we - // already set mNumDisplayRows in CalcIntrinsicBSize. Also note that we - // can't use HeightOfARow() here because that just uses a cached value - // that we didn't compute. - nscoord rowHeight = CalcHeightOfARow(); - if (rowHeight == 0) { + if (!autoBSize) { + // Update our mNumDisplayRows based on our new row block size now + // that we know it. Note that if autoBSize and we landed in this + // code then we already set mNumDisplayRows in CalcIntrinsicBSize. + // Also note that we can't use BSizeOfARow() here because that + // just uses a cached value that we didn't compute. + nscoord rowBSize = CalcBSizeOfARow(); + if (rowBSize == 0) { // Just pick something mNumDisplayRows = 1; } else { - mNumDisplayRows = std::max(1, state.ComputedHeight() / rowHeight); + mNumDisplayRows = std::max(1, state.ComputedBSize() / rowBSize); } } @@ -433,12 +450,12 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, mMightNeedSecondPass = false; - // Now see whether we need a second pass. If we do, our nsSelectsAreaFrame - // will have suppressed the scrollbar update. + // Now see whether we need a second pass. If we do, our + // nsSelectsAreaFrame will have suppressed the scrollbar update. if (!IsScrollbarUpdateSuppressed()) { // All done. No need to do more reflow. NS_ASSERTION(!IsScrollbarUpdateSuppressed(), - "Shouldn't be suppressing if the height of a row has not " + "Shouldn't be suppressing if the block size of a row has not " "changed!"); return; } @@ -446,17 +463,18 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, SetSuppressScrollbarUpdate(false); // Gotta reflow again. - // XXXbz We're just changing the height here; do we need to dirty ourselves - // or anything like that? We might need to, per the letter of the reflow - // protocol, but things seem to work fine without it... Is that just an - // implementation detail of nsHTMLScrollFrame that we're depending on? + // XXXbz We're just changing the block size here; do we need to dirty + // ourselves or anything like that? We might need to, per the letter + // of the reflow protocol, but things seem to work fine without it... + // Is that just an implementation detail of nsHTMLScrollFrame that + // we're depending on? nsHTMLScrollFrame::DidReflow(aPresContext, &state, nsDidReflowStatus::FINISHED); - // Now compute the height we want to have - nscoord computedHeight = CalcIntrinsicBSize(HeightOfARow(), length); - computedHeight = state.ApplyMinMaxHeight(computedHeight); - state.SetComputedHeight(computedHeight); + // Now compute the block size we want to have + nscoord computedBSize = CalcIntrinsicBSize(BSizeOfARow(), length); + computedBSize = state.ApplyMinMaxBSize(computedBSize); + state.SetComputedBSize(computedBSize); // XXXbz to make the ascent really correct, we should add our // mComputedPadding.top to it (and subtract it from descent). Need that @@ -470,36 +488,39 @@ nsListControlFrame::ReflowAsDropdown(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - NS_PRECONDITION(aReflowState.ComputedHeight() == NS_UNCONSTRAINEDSIZE, - "We should not have a computed height here!"); + NS_PRECONDITION(aReflowState.ComputedBSize() == NS_UNCONSTRAINEDSIZE, + "We should not have a computed block size here!"); mMightNeedSecondPass = NS_SUBTREE_DIRTY(this) || aReflowState.ShouldReflowAllKids(); + WritingMode wm = aReflowState.GetWritingMode(); #ifdef DEBUG - nscoord oldHeightOfARow = HeightOfARow(); - nscoord oldVisibleHeight = (GetStateBits() & NS_FRAME_FIRST_REFLOW) ? - NS_UNCONSTRAINEDSIZE : GetScrolledFrame()->GetSize().height; + nscoord oldBSizeOfARow = BSizeOfARow(); + nscoord oldVisibleBSize = (GetStateBits() & NS_FRAME_FIRST_REFLOW) ? + NS_UNCONSTRAINEDSIZE : GetScrolledFrame()->BSize(wm); #endif nsHTMLReflowState state(aReflowState); if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { - // When not doing an initial reflow, and when the height is auto, start off - // with our computed height set to what we'd expect our height to be. - // Note: At this point, mLastDropdownComputedHeight can be - // NS_UNCONSTRAINEDSIZE in cases when last time we didn't have to constrain - // the height. That's fine; just do the same thing as last time. - state.SetComputedHeight(mLastDropdownComputedHeight); + // When not doing an initial reflow, and when the block size is + // auto, start off with our computed block size set to what we'd + // expect our block size to be. + // Note: At this point, mLastDropdownComputedBSize can be + // NS_UNCONSTRAINEDSIZE in cases when last time we didn't have to + // constrain the block size. That's fine; just do the same thing as + // last time. + state.SetComputedBSize(mLastDropdownComputedBSize); } nsHTMLScrollFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); if (!mMightNeedSecondPass) { - NS_ASSERTION(oldVisibleHeight == GetScrolledFrame()->GetSize().height, - "How did our kid's height change if nothing was dirty?"); - NS_ASSERTION(HeightOfARow() == oldHeightOfARow, - "How did our height of a row change if nothing was dirty?"); + NS_ASSERTION(oldVisibleBSize == GetScrolledFrame()->BSize(wm), + "How did our kid's BSize change if nothing was dirty?"); + NS_ASSERTION(BSizeOfARow() == oldBSizeOfARow, + "How did our BSize of a row change if nothing was dirty?"); NS_ASSERTION(!IsScrollbarUpdateSuppressed(), "Shouldn't be suppressing if we don't need a second pass!"); NS_ASSERTION(!(GetStateBits() & NS_FRAME_FIRST_REFLOW), @@ -520,61 +541,64 @@ nsListControlFrame::ReflowAsDropdown(nsPresContext* aPresContext, SetSuppressScrollbarUpdate(false); - nscoord visibleHeight = GetScrolledFrame()->GetSize().height; - nscoord heightOfARow = HeightOfARow(); + nscoord visibleBSize = GetScrolledFrame()->BSize(wm); + nscoord blockSizeOfARow = BSizeOfARow(); // Gotta reflow again. - // XXXbz We're just changing the height here; do we need to dirty ourselves - // or anything like that? We might need to, per the letter of the reflow - // protocol, but things seem to work fine without it... Is that just an - // implementation detail of nsHTMLScrollFrame that we're depending on? + // XXXbz We're just changing the block size here; do we need to dirty + // ourselves or anything like that? We might need to, per the letter + // of the reflow protocol, but things seem to work fine without it... + // Is that just an implementation detail of nsHTMLScrollFrame that + // we're depending on? nsHTMLScrollFrame::DidReflow(aPresContext, &state, nsDidReflowStatus::FINISHED); - // Now compute the height we want to have. + // Now compute the block size we want to have. // Note: no need to apply min/max constraints, since we have no such // rules applied to the combobox dropdown. mDropdownCanGrow = false; - if (visibleHeight <= 0 || heightOfARow <= 0) { - // Looks like we have no options. Just size us to a single row height. - state.SetComputedHeight(heightOfARow); + if (visibleBSize <= 0 || blockSizeOfARow <= 0) { + // Looks like we have no options. Just size us to a single row + // block size. + state.SetComputedBSize(blockSizeOfARow); mNumDisplayRows = 1; } else { - nsComboboxControlFrame* combobox = static_cast(mComboboxFrame); - nsPoint translation; - nscoord above, below; - combobox->GetAvailableDropdownSpace(&above, &below, &translation); - if (above <= 0 && below <= 0) { - state.SetComputedHeight(heightOfARow); + nsComboboxControlFrame* combobox = + static_cast(mComboboxFrame); + LogicalPoint translation(wm); + nscoord before, after; + combobox->GetAvailableDropdownSpace(wm, &before, &after, &translation); + if (before <= 0 && after <= 0) { + state.SetComputedBSize(blockSizeOfARow); mNumDisplayRows = 1; mDropdownCanGrow = GetNumberOfRows() > 1; } else { - nscoord bp = aReflowState.ComputedPhysicalBorderPadding().TopBottom(); - nscoord availableHeight = std::max(above, below) - bp; - nscoord newHeight; + nscoord bp = aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm); + nscoord availableBSize = std::max(before, after) - bp; + nscoord newBSize; uint32_t rows; - if (visibleHeight <= availableHeight) { - // The dropdown fits in the available height. + if (visibleBSize <= availableBSize) { + // The dropdown fits in the available block size. rows = GetNumberOfRows(); mNumDisplayRows = clamped(rows, 1, kMaxDropDownRows); if (mNumDisplayRows == rows) { - newHeight = visibleHeight; // use the exact height + newBSize = visibleBSize; // use the exact block size } else { - newHeight = mNumDisplayRows * heightOfARow; // approximate + newBSize = mNumDisplayRows * blockSizeOfARow; // approximate } } else { - rows = availableHeight / heightOfARow; + rows = availableBSize / blockSizeOfARow; mNumDisplayRows = clamped(rows, 1, kMaxDropDownRows); - newHeight = mNumDisplayRows * heightOfARow; // approximate + newBSize = mNumDisplayRows * blockSizeOfARow; // approximate } - state.SetComputedHeight(newHeight); - mDropdownCanGrow = visibleHeight - newHeight >= heightOfARow && + state.SetComputedBSize(newBSize); + mDropdownCanGrow = visibleBSize - newBSize >= blockSizeOfARow && mNumDisplayRows != kMaxDropDownRows; } } - mLastDropdownComputedHeight = state.ComputedHeight(); + mLastDropdownComputedBSize = state.ComputedBSize(); nsHTMLScrollFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); } @@ -584,13 +608,17 @@ nsListControlFrame::GetScrollbarStyles() const { // We can't express this in the style system yet; when we can, this can go away // and GetScrollbarStyles can be devirtualized - int32_t verticalStyle = IsInDropDownMode() ? NS_STYLE_OVERFLOW_AUTO - : NS_STYLE_OVERFLOW_SCROLL; - return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, verticalStyle); + int32_t style = IsInDropDownMode() ? NS_STYLE_OVERFLOW_AUTO + : NS_STYLE_OVERFLOW_SCROLL; + if (GetWritingMode().IsVertical()) { + return ScrollbarStyles(style, NS_STYLE_OVERFLOW_HIDDEN); + } else { + return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, style); + } } bool -nsListControlFrame::ShouldPropagateComputedHeightToScrolledContent() const +nsListControlFrame::ShouldPropagateComputedBSizeToScrolledContent() const { return !IsInDropDownMode(); } @@ -1480,9 +1508,9 @@ nsListControlFrame::GetFrameName(nsAString& aResult) const #endif nscoord -nsListControlFrame::GetHeightOfARow() +nsListControlFrame::GetBSizeOfARow() { - return HeightOfARow(); + return BSizeOfARow(); } nsresult @@ -1515,23 +1543,23 @@ nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent) } nscoord -nsListControlFrame::CalcFallbackRowHeight(float aFontSizeInflation) +nsListControlFrame::CalcFallbackRowBSize(float aFontSizeInflation) { - nscoord rowHeight = 0; + nscoord rowBSize = 0; nsRefPtr fontMet; nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet), aFontSizeInflation); if (fontMet) { - rowHeight = fontMet->MaxHeight(); + rowBSize = fontMet->MaxHeight(); } - return rowHeight; + return rowBSize; } nscoord -nsListControlFrame::CalcIntrinsicBSize(nscoord aHeightOfARow, - int32_t aNumberOfOptions) +nsListControlFrame::CalcIntrinsicBSize(nscoord aBSizeOfARow, + int32_t aNumberOfOptions) { NS_PRECONDITION(!IsInDropDownMode(), "Shouldn't be in dropdown mode when we call this"); @@ -1548,7 +1576,7 @@ nsListControlFrame::CalcIntrinsicBSize(nscoord aHeightOfARow, mNumDisplayRows = 4; } - return mNumDisplayRows * aHeightOfARow; + return mNumDisplayRows * aBSizeOfARow; } //---------------------------------------------------------------------- diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index 53133c9e10..4482be340c 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -109,7 +109,7 @@ public: virtual void SetFocus(bool aOn = true, bool aRepaint = false) override; virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override; - virtual bool ShouldPropagateComputedHeightToScrolledContent() const override; + virtual bool ShouldPropagateComputedBSizeToScrolledContent() const override; // for accessibility purposes #ifdef ACCESSIBILITY @@ -129,7 +129,7 @@ public: virtual void GetOptionText(uint32_t aIndex, nsAString& aStr) override; virtual void CaptureMouseEvents(bool aGrabMouseEvents) override; - virtual nscoord GetHeightOfARow() override; + virtual nscoord GetBSizeOfARow() override; virtual uint32_t GetNumberOfOptions() override; virtual void AboutToDropDown() override; @@ -203,10 +203,11 @@ public: void InvalidateFocus(); /** - * Function to calculate the height a row, for use with the "size" attribute. + * Function to calculate the block size of a row, for use with the + * "size" attribute. * Can't be const because GetNumberOfOptions() isn't const. */ - nscoord CalcHeightOfARow(); + nscoord CalcBSizeOfARow(); /** * Function to ask whether we're currently in what might be the @@ -327,12 +328,13 @@ protected: bool CheckIfAllFramesHere(); bool IsLeftButton(nsIDOMEvent* aMouseEvent); - // guess at a row height based on our own style. - nscoord CalcFallbackRowHeight(float aFontSizeInflation); + // guess at a row block size based on our own style. + nscoord CalcFallbackRowBSize(float aFontSizeInflation); - // CalcIntrinsicBSize computes our intrinsic height (taking the "size" - // attribute into account). This should only be called in non-dropdown mode. - nscoord CalcIntrinsicBSize(nscoord aHeightOfARow, int32_t aNumberOfOptions); + // CalcIntrinsicBSize computes our intrinsic block size (taking the + // "size" attribute into account). This should only be called in + // non-dropdown mode. + nscoord CalcIntrinsicBSize(nscoord aBSizeOfARow, int32_t aNumberOfOptions); // Dropped down stuff void SetComboboxItem(int32_t aIndex); @@ -378,8 +380,8 @@ public: } protected: - nscoord HeightOfARow() { - return GetOptionsContainer()->HeightOfARow(); + nscoord BSizeOfARow() { + return GetOptionsContainer()->BSizeOfARow(); } /** @@ -425,10 +427,11 @@ protected: // True if the selection can be set to nothing or disabled options. bool mForceSelection:1; - // The last computed height we reflowed at if we're a combobox dropdown. + // The last computed block size we reflowed at if we're a combobox + // dropdown. // XXXbz should we be using a subclass here? Or just not worry // about the extra member on listboxes? - nscoord mLastDropdownComputedHeight; + nscoord mLastDropdownComputedBSize; // At the time of our last dropdown, the backstop color to draw in case we // are translucent. diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 4efccad788..9b74d31a25 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -808,17 +808,17 @@ nsNumberControlFrame::GetPseudoElement(nsCSSPseudoElements::Type aType) } if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinBox) { - MOZ_ASSERT(mSpinBox); + // Might be null. return mSpinBox; } if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinUp) { - MOZ_ASSERT(mSpinUp); + // Might be null. return mSpinUp; } if (aType == nsCSSPseudoElements::ePseudo_mozNumberSpinDown) { - MOZ_ASSERT(mSpinDown); + // Might be null. return mSpinDown; } diff --git a/layout/forms/nsSelectsAreaFrame.cpp b/layout/forms/nsSelectsAreaFrame.cpp index b067751998..c1bd774c43 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -6,6 +6,9 @@ #include "nsIContent.h" #include "nsListControlFrame.h" #include "nsDisplayList.h" +#include "WritingModes.h" + +using namespace mozilla; nsContainerFrame* NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsStyleContext* aContext, nsFrameState aFlags) @@ -164,35 +167,38 @@ nsSelectsAreaFrame::Reflow(nsPresContext* aPresContext, NS_ASSERTION(list, "Must have an nsListControlFrame! Frame constructor is " "broken"); - + bool isInDropdownMode = list->IsInDropDownMode(); - + // See similar logic in nsListControlFrame::Reflow and // nsListControlFrame::ReflowAsDropdown. We need to match it here. - nscoord oldHeight; + WritingMode wm = aReflowState.GetWritingMode(); + nscoord oldBSize; if (isInDropdownMode) { - // Store the height now in case it changes during + // Store the block size now in case it changes during // nsBlockFrame::Reflow for some odd reason. if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { - oldHeight = GetSize().height; + oldBSize = BSize(wm); } else { - oldHeight = NS_UNCONSTRAINEDSIZE; + oldBSize = NS_UNCONSTRAINEDSIZE; } } - + nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); - // Check whether we need to suppress scrollbar updates. We want to do that if - // we're in a possible first pass and our height of a row has changed. + // Check whether we need to suppress scrollbar updates. We want to do + // that if we're in a possible first pass and our block size of a row + // has changed. if (list->MightNeedSecondPass()) { - nscoord newHeightOfARow = list->CalcHeightOfARow(); - // We'll need a second pass if our height of a row changed. For - // comboboxes, we'll also need it if our height changed. If we're going - // to do a second pass, suppress scrollbar updates for this pass. - if (newHeightOfARow != mHeightOfARow || - (isInDropdownMode && (oldHeight != aDesiredSize.Height() || - oldHeight != GetSize().height))) { - mHeightOfARow = newHeightOfARow; + nscoord newBSizeOfARow = list->CalcBSizeOfARow(); + // We'll need a second pass if our block size of a row changed. For + // comboboxes, we'll also need it if our block size changed. If + // we're going to do a second pass, suppress scrollbar updates for + // this pass. + if (newBSizeOfARow != mBSizeOfARow || + (isInDropdownMode && (oldBSize != aDesiredSize.BSize(wm) || + oldBSize != BSize(wm)))) { + mBSizeOfARow = newBSizeOfARow; list->SetSuppressScrollbarUpdate(true); } } diff --git a/layout/forms/nsSelectsAreaFrame.h b/layout/forms/nsSelectsAreaFrame.h index c00b63e5b4..7212c2dbc7 100644 --- a/layout/forms/nsSelectsAreaFrame.h +++ b/layout/forms/nsSelectsAreaFrame.h @@ -30,19 +30,20 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) override; - nscoord HeightOfARow() const { return mHeightOfARow; } + nscoord BSizeOfARow() const { return mBSizeOfARow; } protected: explicit nsSelectsAreaFrame(nsStyleContext* aContext) : nsBlockFrame(aContext), - mHeightOfARow(0) + mBSizeOfARow(0) {} - // We cache the height of a single row so that changes to the "size" - // attribute, padding, etc. can all be handled with only one reflow. We'll - // have to reflow twice if someone changes our font size or something like - // that, so that the heights of our options will change. - nscoord mHeightOfARow; + // We cache the block size of a single row so that changes to the + // "size" attribute, padding, etc. can all be handled with only one + // reflow. We'll have to reflow twice if someone changes our font + // size or something like that, so that the block size of our options + // will change. + nscoord mBSizeOfARow; }; #endif /* nsSelectsAreaFrame_h___ */ diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index 246326a2f0..98064442be 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -239,69 +239,70 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f, } const nsStylePadding* padding = f->StylePadding(); const nsStyleMargin* margin = f->StyleMargin(); - if (aCBWidthChanged) { - // See if f's width might have changed. - // If border-left, border-right, padding-left, padding-right, - // width, min-width, and max-width are all lengths, 'none', or enumerated, - // then our frame width does not depend on the parent width. - // Note that borders never depend on the parent width + WritingMode wm = f->GetWritingMode(); + if (wm.IsVertical() ? aCBHeightChanged : aCBWidthChanged) { + // See if f's inline-size might have changed. + // If margin-inline-start/end, padding-inline-start/end, + // inline-size, min/max-inline-size are all lengths, 'none', or enumerated, + // then our frame isize does not depend on the parent isize. + // Note that borders never depend on the parent isize. // XXX All of the enumerated values except -moz-available are ok too. - if (pos->WidthDependsOnContainer() || - pos->MinWidthDependsOnContainer() || - pos->MaxWidthDependsOnContainer() || - !IsFixedPaddingSize(padding->mPadding.GetLeft()) || - !IsFixedPaddingSize(padding->mPadding.GetRight())) { + if (pos->ISizeDependsOnContainer(wm) || + pos->MinISizeDependsOnContainer(wm) || + pos->MaxISizeDependsOnContainer(wm) || + !IsFixedPaddingSize(padding->mPadding.GetIStart(wm)) || + !IsFixedPaddingSize(padding->mPadding.GetIEnd(wm))) { return true; } // See if f's position might have changed. If we're RTL then the // rules are slightly different. We'll assume percentage or auto // margins will always induce a dependency on the size - if (!IsFixedMarginSize(margin->mMargin.GetLeft()) || - !IsFixedMarginSize(margin->mMargin.GetRight())) { + if (!IsFixedMarginSize(margin->mMargin.GetIStart(wm)) || + !IsFixedMarginSize(margin->mMargin.GetIEnd(wm))) { return true; } - if (f->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { - // Note that even if 'left' is a length, our position can - // still depend on the containing block width, because if - // 'right' is also a length we will discard 'left' and be - // positioned relative to the containing block right edge. - // 'left' length and 'right' auto is the only combination + if (!wm.IsBidiLTR()) { + // Note that even if 'istart' is a length, our position can + // still depend on the containing block isze, because if + // 'iend' is also a length we will discard 'istart' and be + // positioned relative to the containing block iend edge. + // 'istart' length and 'iend' auto is the only combination // we can be sure of. - if (!IsFixedOffset(pos->mOffset.GetLeft()) || - pos->mOffset.GetRightUnit() != eStyleUnit_Auto) { + if (!IsFixedOffset(pos->mOffset.GetIStart(wm)) || + pos->mOffset.GetIEndUnit(wm) != eStyleUnit_Auto) { return true; } } else { - if (!IsFixedOffset(pos->mOffset.GetLeft())) { + if (!IsFixedOffset(pos->mOffset.GetIStart(wm))) { return true; } } } - if (aCBHeightChanged) { - // See if f's height might have changed. - // If border-top, border-bottom, padding-top, padding-bottom, - // min-height, and max-height are all lengths or 'none', - // and height is a length or height and bottom are auto and top is not auto, - // then our frame height does not depend on the parent height. - // Note that borders never depend on the parent height - if ((pos->HeightDependsOnContainer() && - !(pos->mHeight.GetUnit() == eStyleUnit_Auto && - pos->mOffset.GetBottomUnit() == eStyleUnit_Auto && - pos->mOffset.GetTopUnit() != eStyleUnit_Auto)) || - pos->MinHeightDependsOnContainer() || - pos->MaxHeightDependsOnContainer() || - !IsFixedPaddingSize(padding->mPadding.GetTop()) || - !IsFixedPaddingSize(padding->mPadding.GetBottom())) { + if (wm.IsVertical() ? aCBWidthChanged : aCBHeightChanged) { + // See if f's block-size might have changed. + // If margin-block-start/end, padding-block-start/end, + // min-block-size, and max-block-size are all lengths or 'none', + // and bsize is a length or bsize and bend are auto and bstart is not auto, + // then our frame bsize does not depend on the parent bsize. + // Note that borders never depend on the parent bsize. + if ((pos->BSizeDependsOnContainer(wm) && + !(pos->BSize(wm).GetUnit() == eStyleUnit_Auto && + pos->mOffset.GetBEndUnit(wm) == eStyleUnit_Auto && + pos->mOffset.GetBStartUnit(wm) != eStyleUnit_Auto)) || + pos->MinBSizeDependsOnContainer(wm) || + pos->MaxBSizeDependsOnContainer(wm) || + !IsFixedPaddingSize(padding->mPadding.GetBStart(wm)) || + !IsFixedPaddingSize(padding->mPadding.GetBEnd(wm))) { return true; } // See if f's position might have changed. - if (!IsFixedMarginSize(margin->mMargin.GetTop()) || - !IsFixedMarginSize(margin->mMargin.GetBottom())) { + if (!IsFixedMarginSize(margin->mMargin.GetBStart(wm)) || + !IsFixedMarginSize(margin->mMargin.GetBEnd(wm))) { return true; } - if (!IsFixedOffset(pos->mOffset.GetTop())) { + if (!IsFixedOffset(pos->mOffset.GetBStart(wm))) { return true; } } @@ -353,7 +354,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, const nsRect& aContainingBlock, - bool aConstrainHeight, + bool aConstrainBSize, nsIFrame* aKidFrame, nsReflowStatus& aStatus, nsOverflowAreas* aOverflowAreas) @@ -391,84 +392,105 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat aReflowState.ComputedSizeWithPadding(wm).ISize(wm); } - nsHTMLReflowMetrics kidDesiredSize(aReflowState); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, LogicalSize(wm, availISize, NS_UNCONSTRAINEDSIZE), &logicalCBSize); // Get the border values - const nsMargin& border = aReflowState.mStyleBorder->GetComputedBorder(); - - bool constrainHeight = (aReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) - && aConstrainHeight + WritingMode outerWM = aReflowState.GetWritingMode(); + const LogicalMargin border(outerWM, + aReflowState.mStyleBorder->GetComputedBorder()); + const LogicalMargin margin = + kidReflowState.ComputedLogicalMargin().ConvertTo(outerWM, wm); + bool constrainBSize = (aReflowState.AvailableBSize() != NS_UNCONSTRAINEDSIZE) + && aConstrainBSize // Don't split if told not to (e.g. for fixed frames) && (aDelegatingFrame->GetType() != nsGkAtoms::inlineFrame) //XXX we don't handle splitting frames for inline absolute containing blocks yet - && (aKidFrame->GetRect().y <= aReflowState.AvailableHeight()); + && (aKidFrame->GetLogicalRect(aContainingBlock.width).BStart(wm) <= + aReflowState.AvailableBSize()); // Don't split things below the fold. (Ideally we shouldn't *have* // anything totally below the fold, but we can't position frames // across next-in-flow breaks yet. - if (constrainHeight) { - kidReflowState.AvailableHeight() = aReflowState.AvailableHeight() - border.top - - kidReflowState.ComputedPhysicalMargin().top; - if (NS_AUTOOFFSET != kidReflowState.ComputedPhysicalOffsets().top) - kidReflowState.AvailableHeight() -= kidReflowState.ComputedPhysicalOffsets().top; + if (constrainBSize) { + kidReflowState.AvailableBSize() = + aReflowState.AvailableBSize() - border.ConvertTo(wm, outerWM).BStart(wm) - + kidReflowState.ComputedLogicalMargin().BStart(wm); + if (NS_AUTOOFFSET != kidReflowState.ComputedLogicalOffsets().BStart(wm)) { + kidReflowState.AvailableBSize() -= + kidReflowState.ComputedLogicalOffsets().BStart(wm); + } } // Do the reflow + nsHTMLReflowMetrics kidDesiredSize(kidReflowState); aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); - // If we're solving for 'left' or 'top', then compute it now that we know the - // width/height - if ((NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().left) || - (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().top)) { + const LogicalSize kidSize = kidDesiredSize.Size(wm).ConvertTo(outerWM, wm); - if (logicalCBSize.Width(wm) == -1) { + LogicalMargin offsets = + kidReflowState.ComputedLogicalOffsets().ConvertTo(outerWM, wm); + + // If we're solving for start in either inline or block direction, + // then compute it now that we know the dimensions. + if ((NS_AUTOOFFSET == offsets.IStart(outerWM)) || + (NS_AUTOOFFSET == offsets.BStart(outerWM))) { + if (-1 == logicalCBSize.ISize(wm)) { // Get the containing block width/height logicalCBSize = kidReflowState.ComputeContainingBlockRectangle(aPresContext, &aReflowState); } - if (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().left) { - NS_ASSERTION(NS_AUTOOFFSET != kidReflowState.ComputedPhysicalOffsets().right, - "Can't solve for both left and right"); - kidReflowState.ComputedPhysicalOffsets().left = logicalCBSize.Width(wm) - - kidReflowState.ComputedPhysicalOffsets().right - - kidReflowState.ComputedPhysicalMargin().right - - kidDesiredSize.Width() - - kidReflowState.ComputedPhysicalMargin().left; + if (NS_AUTOOFFSET == offsets.IStart(outerWM)) { + NS_ASSERTION(NS_AUTOOFFSET != offsets.IEnd(outerWM), + "Can't solve for both start and end"); + offsets.IStart(outerWM) = + logicalCBSize.ConvertTo(outerWM, wm).ISize(outerWM) - + offsets.IEnd(outerWM) - margin.IStartEnd(outerWM) - + kidSize.ISize(outerWM); } - if (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().top) { - kidReflowState.ComputedPhysicalOffsets().top = logicalCBSize.Height(wm) - - kidReflowState.ComputedPhysicalOffsets().bottom - - kidReflowState.ComputedPhysicalMargin().bottom - - kidDesiredSize.Height() - - kidReflowState.ComputedPhysicalMargin().top; + if (NS_AUTOOFFSET == offsets.BStart(outerWM)) { + offsets.BStart(outerWM) = + logicalCBSize.ConvertTo(outerWM, wm).BSize(outerWM) - + offsets.BEnd(outerWM) - margin.BStartEnd(outerWM) - + kidSize.BSize(outerWM); } + kidReflowState.SetComputedLogicalOffsets(offsets.ConvertTo(wm, outerWM)); } // Position the child relative to our padding edge - nsRect rect(border.left + kidReflowState.ComputedPhysicalOffsets().left + kidReflowState.ComputedPhysicalMargin().left, - border.top + kidReflowState.ComputedPhysicalOffsets().top + kidReflowState.ComputedPhysicalMargin().top, - kidDesiredSize.Width(), kidDesiredSize.Height()); + LogicalRect rect(outerWM, + border.IStart(outerWM) + offsets.IStart(outerWM) + + margin.IStart(outerWM), + border.BStart(outerWM) + offsets.BStart(outerWM) + + margin.BStart(outerWM), + kidSize.ISize(outerWM), kidSize.BSize(outerWM)); + nsRect r = + rect.GetPhysicalRect(outerWM, logicalCBSize.Width(wm) + + border.LeftRight(outerWM)); + // XXX hack to correct for lack of bidi support in vertical mode + if (outerWM.IsVertical() && !outerWM.IsBidiLTR()) { + r.y = logicalCBSize.Height(wm) + border.TopBottom(outerWM) - r.YMost(); + } // Offset the frame rect by the given origin of the absolute containing block. // If the frame is auto-positioned on both sides of an axis, it will be // positioned based on its containing block and we don't need to offset. if (aContainingBlock.TopLeft() != nsPoint(0, 0)) { - if (!(kidReflowState.mStylePosition->mOffset.GetLeftUnit() == eStyleUnit_Auto && - kidReflowState.mStylePosition->mOffset.GetRightUnit() == eStyleUnit_Auto)) { - rect.x += aContainingBlock.x; + const nsStyleSides& offsets = kidReflowState.mStylePosition->mOffset; + if (!(offsets.GetLeftUnit() == eStyleUnit_Auto && + offsets.GetRightUnit() == eStyleUnit_Auto)) { + r.x += aContainingBlock.x; } - if (!(kidReflowState.mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Auto && - kidReflowState.mStylePosition->mOffset.GetBottomUnit() == eStyleUnit_Auto)) { - rect.y += aContainingBlock.y; + if (!(offsets.GetTopUnit() == eStyleUnit_Auto && + offsets.GetBottomUnit() == eStyleUnit_Auto)) { + r.y += aContainingBlock.y; } } - aKidFrame->SetRect(rect); + aKidFrame->SetRect(r); nsView* view = aKidFrame->GetView(); if (view) { @@ -480,7 +502,8 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat nsContainerFrame::PositionChildViews(aKidFrame); } - aKidFrame->DidReflow(aPresContext, &kidReflowState, nsDidReflowStatus::FINISHED); + aKidFrame->DidReflow(aPresContext, &kidReflowState, + nsDidReflowStatus::FINISHED); #ifdef DEBUG if (nsBlockFrame::gNoisyReflow) { @@ -492,11 +515,11 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat printf("%s ", NS_LossyConvertUTF16toASCII(name).get()); } printf("%p rect=%d,%d,%d,%d\n", static_cast(aKidFrame), - rect.x, rect.y, rect.width, rect.height); + r.x, r.y, r.width, r.height); } #endif if (aOverflowAreas) { - aOverflowAreas->UnionWith(kidDesiredSize.mOverflowAreas + rect.TopLeft()); + aOverflowAreas->UnionWith(kidDesiredSize.mOverflowAreas + r.TopLeft()); } } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index b3e6992c02..f874d6f86b 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4508,9 +4508,9 @@ nsFrame::FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, - bool aConstrainHeight) + bool aConstrainBSize) { - ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, aConstrainHeight); + ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, aConstrainBSize); FinishAndStoreOverflow(&aDesiredSize); } @@ -4520,7 +4520,7 @@ nsFrame::ReflowAbsoluteFrames(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, - bool aConstrainHeight) + bool aConstrainBSize) { if (HasAbsolutelyPositionedChildren()) { nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock(); @@ -4542,7 +4542,7 @@ nsFrame::ReflowAbsoluteFrames(nsPresContext* aPresContext, nsRect containingBlock(0, 0, containingBlockWidth, containingBlockHeight); absoluteContainer->Reflow(container, aPresContext, aReflowState, aStatus, containingBlock, - aConstrainHeight, true, true, // XXX could be optimized + aConstrainBSize, true, true, // XXX could be optimized &aDesiredSize.mOverflowAreas); } } @@ -5704,6 +5704,31 @@ nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix, uint32_t aFlags) con aTo += nsPrintfCString(" IBSplitPrevSibling=%p", IBprevsibling); } aTo += nsPrintfCString(" {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height); + + mozilla::WritingMode wm = GetWritingMode(); + if (wm.IsVertical() || !wm.IsBidiLTR()) { + aTo += nsPrintfCString(" wm=%s-%s: logical size={%d,%d}", + wm.IsVertical() ? wm.IsVerticalLR() ? "vlr" : "vrl" + : "htb", + wm.IsBidiLTR() ? "ltr" : "rtl", + ISize(), BSize()); + } + + nsIFrame* parent = GetParent(); + if (parent) { + WritingMode pWM = parent->GetWritingMode(); + if (pWM.IsVertical() || !pWM.IsBidiLTR()) { + nscoord cw = parent->mRect.width; + LogicalRect lr(pWM, mRect, cw); + aTo += nsPrintfCString(" parent wm=%s-%s,width=%d,logicalRect={%d,%d,%d,%d}", + pWM.IsVertical() ? pWM.IsVerticalLR() + ? "vlr" : "vrl" + : "htb", + wm.IsBidiLTR() ? "ltr" : "rtl", + cw, lr.IStart(pWM), lr.BStart(pWM), + lr.ISize(pWM), lr.BSize(pWM)); + } + } nsIFrame* f = const_cast(this); if (f->HasOverflowAreas()) { nsRect vo = f->GetVisualOverflowRect(); diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 53812c1248..eac0e378bb 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -339,12 +339,12 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, - bool aConstrainHeight = true); + bool aConstrainBSize = true); void FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, - bool aConstrainHeight = true); + bool aConstrainBSize = true); /* * If this frame is dirty, marks all absolutely-positioned children of this diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index e424087b36..5a506859eb 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -440,7 +440,7 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState, nscoord computedBSize = aState->mReflowState.ComputedBSize(); nscoord computedMinBSize = aState->mReflowState.ComputedMinBSize(); nscoord computedMaxBSize = aState->mReflowState.ComputedMaxBSize(); - if (!ShouldPropagateComputedHeightToScrolledContent()) { + if (!ShouldPropagateComputedBSizeToScrolledContent()) { computedBSize = NS_UNCONSTRAINEDSIZE; computedMinBSize = 0; computedMaxBSize = NS_UNCONSTRAINEDSIZE; diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 7f5fff8338..59356d2433 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -939,11 +939,11 @@ protected: bool InInitialReflow() const; /** - * Override this to return false if computed height/min-height/max-height + * Override this to return false if computed bsize/min-bsize/max-bsize * should NOT be propagated to child content. * nsListControlFrame uses this. */ - virtual bool ShouldPropagateComputedHeightToScrolledContent() const { return true; } + virtual bool ShouldPropagateComputedBSizeToScrolledContent() const { return true; } private: friend class mozilla::ScrollFrameHelper; diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 30adc6d9d4..198ffed182 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -1012,7 +1012,7 @@ nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame, state = nullptr; } - WritingMode wm = GetWritingMode(); + WritingMode wm = aFrame->GetWritingMode(); if (state) { WritingMode stateWM = state->GetWritingMode(); aCBIStartEdge = @@ -1026,31 +1026,31 @@ nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame, "aFrame shouldn't be in reflow; we'll lie if it is"); LogicalMargin borderPadding = aFrame->GetLogicalUsedBorderAndPadding(wm); aCBIStartEdge = borderPadding.IStart(wm); - aCBISize = aFrame->GetLogicalSize(wm).ISize(wm) - - borderPadding.IStartEnd(wm); + aCBISize = aFrame->ISize(wm) - borderPadding.IStartEnd(wm); } return aFrame; } // When determining the hypothetical box that would have been if the element -// had been in the flow we may not be able to exactly determine both the left -// and right edges. For example, if the element is a non-replaced inline-level -// element we would have to reflow it in order to determine it desired width. -// In that case depending on the progression direction either the left or -// right edge would be marked as not being exact +// had been in the flow we may not be able to exactly determine both the IStart +// and IEnd edges. For example, if the element is a non-replaced inline-level +// element we would have to reflow it in order to determine its desired ISize. +// In that case depending on the progression direction either the IStart or +// IEnd edge would be marked as not being exact. struct nsHypotheticalBox { - // offsets from left edge of containing block (which is a padding edge) - nscoord mLeft, mRight; - // offset from top edge of containing block (which is a padding edge) - nscoord mTop; + // offsets from inline-start edge of containing block (which is a padding edge) + nscoord mIStart, mIEnd; + // offset from block-start edge of containing block (which is a padding edge) + nscoord mBStart; + WritingMode mWritingMode; #ifdef DEBUG - bool mLeftIsExact, mRightIsExact; + bool mIStartIsExact, mIEndIsExact; #endif nsHypotheticalBox() { #ifdef DEBUG - mLeftIsExact = mRightIsExact = false; + mIStartIsExact = mIEndIsExact = false; #endif } }; @@ -1174,15 +1174,11 @@ static bool AreAllEarlierInFlowFramesEmpty(nsIFrame* aFrame, // Calculate the hypothetical box that the element would have if it were in // the flow. The values returned are relative to the padding edge of the -// absolute containing block -// aContainingBlock is the placeholder's containing block (XXX rename it?) +// absolute containing block, in the actual containing block's writing mode. // cbrs->frame is the actual containing block void nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, nsIFrame* aPlaceholderFrame, - nsIFrame* aContainingBlock, - nscoord aBlockIStartContentEdge, - nscoord aBlockContentISize, const nsHTMLReflowState* cbrs, nsHypotheticalBox& aHypotheticalBox, nsIAtom* aFrameType) @@ -1190,11 +1186,20 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, NS_ASSERTION(mStyleDisplay->mOriginalDisplay != NS_STYLE_DISPLAY_NONE, "mOriginalDisplay has not been properly initialized"); + // Find the nearest containing block frame to the placeholder frame, + // and its inline-start edge and width. + nscoord blockIStartContentEdge, blockContentISize; + nsIFrame* containingBlock = + GetHypotheticalBoxContainer(aPlaceholderFrame, blockIStartContentEdge, + blockContentISize); + // If it's a replaced element and it has a 'auto' value for //'inline size', see if we can get the intrinsic size. This will allow // us to exactly determine both the inline edges - WritingMode cbWM = cbrs->GetWritingMode(); - nsStyleCoord styleISize = mStylePosition->ISize(cbWM); + WritingMode wm = containingBlock->GetWritingMode(); + aHypotheticalBox.mWritingMode = wm; + + nsStyleCoord styleISize = mStylePosition->ISize(wm); bool isAutoISize = styleISize.GetUnit() == eStyleUnit_Auto; nsSize intrinsicSize; bool knowIntrinsicSize = false; @@ -1221,28 +1226,28 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, // been in the flow. Note that we ignore any 'auto' and 'inherit' // values nscoord insideBoxSizing, outsideBoxSizing; - CalculateInlineBorderPaddingMargin(aBlockContentISize, + CalculateInlineBorderPaddingMargin(blockContentISize, &insideBoxSizing, &outsideBoxSizing); if (NS_FRAME_IS_REPLACED(mFrameType) && isAutoISize) { // It's a replaced element with an 'auto' inline size so the box // inline size is its intrinsic size plus any border/padding/margin if (knowIntrinsicSize) { - boxISize = LogicalSize(cbWM, intrinsicSize).ISize(cbWM) + + boxISize = LogicalSize(wm, intrinsicSize).ISize(wm) + outsideBoxSizing + insideBoxSizing; knowBoxISize = true; } } else if (isAutoISize) { // The box inline size is the containing block inline size - boxISize = aBlockContentISize; + boxISize = blockContentISize; knowBoxISize = true; } else { // We need to compute it. It's important we do this, because if it's // percentage based this computed value may be different from the computed // value calculated using the absolute containing block width - boxISize = ComputeISizeValue(aBlockContentISize, + boxISize = ComputeISizeValue(blockContentISize, insideBoxSizing, outsideBoxSizing, styleISize) + insideBoxSizing + outsideBoxSizing; @@ -1250,29 +1255,38 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, } } - // Get the 'direction' of the block - const nsStyleVisibility* blockVis = aContainingBlock->StyleVisibility(); - // Get the placeholder x-offset and y-offset in the coordinate // space of its containing block // XXXbz the placeholder is not fully reflowed yet if our containing block is // relatively positioned... - nsPoint placeholderOffset = aPlaceholderFrame->GetOffsetTo(aContainingBlock); + WritingMode cbwm = cbrs->GetWritingMode(); + nscoord containerWidth = containingBlock->GetStateBits() & NS_FRAME_IN_REFLOW + ? cbrs->ComputedSizeAsContainerIfConstrained().width + : containingBlock->GetSize().width; + LogicalPoint placeholderOffset(wm, aPlaceholderFrame->GetOffsetTo(containingBlock), + containerWidth); - // First, determine the hypothetical box's mTop. We want to check the - // content insertion frame of aContainingBlock for block-ness, but make + // XXX hack to correct for lack of LogicalPoint bidi support in vertical mode + if (wm.IsVertical() && !wm.IsBidiLTR()) { + placeholderOffset.I(wm) = cbrs->ComputedHeight() + + cbrs->ComputedLogicalBorderPadding().TopBottom(cbwm) - + placeholderOffset.I(wm); + } + + // First, determine the hypothetical box's mBStart. We want to check the + // content insertion frame of containingBlock for block-ness, but make // sure to compute all coordinates in the coordinate system of - // aContainingBlock. + // containingBlock. nsBlockFrame* blockFrame = - nsLayoutUtils::GetAsBlock(aContainingBlock->GetContentInsertionFrame()); + nsLayoutUtils::GetAsBlock(containingBlock->GetContentInsertionFrame()); if (blockFrame) { - nscoord blockYOffset = blockFrame->GetOffsetTo(aContainingBlock).y; + LogicalPoint blockOffset(wm, blockFrame->GetOffsetTo(containingBlock), 0); bool isValid; nsBlockInFlowLineIterator iter(blockFrame, aPlaceholderFrame, &isValid); if (!isValid) { // Give up. We're probably dealing with somebody using // position:absolute inside native-anonymous content anyway. - aHypotheticalBox.mTop = placeholderOffset.y; + aHypotheticalBox.mBStart = placeholderOffset.B(wm); } else { NS_ASSERTION(iter.GetContainer() == blockFrame, "Found placeholder in wrong block!"); @@ -1280,10 +1294,13 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, // How we determine the hypothetical box depends on whether the element // would have been inline-level or block-level + LogicalRect lineBounds = + lineBox->GetBounds().ConvertTo(wm, lineBox->mWritingMode, + lineBox->mContainerWidth); if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { - // Use the top of the inline box which the placeholder lives in - // as the hypothetical box's top. - aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset; + // Use the block-start of the inline box which the placeholder lives in + // as the hypothetical box's block-start. + aHypotheticalBox.mBStart = lineBounds.BStart(wm) + blockOffset.B(wm); } else { // The element would have been block-level which means it would // be below the line containing the placeholder frame, unless @@ -1308,81 +1325,51 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, // The top of the hypothetical box is the top of the line // containing the placeholder, since there is nothing in the // line before our placeholder except empty frames. - aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset; + aHypotheticalBox.mBStart = lineBounds.BStart(wm) + blockOffset.B(wm); } else { // The top of the hypothetical box is just below the line // containing the placeholder. - aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().YMost() + blockYOffset; + aHypotheticalBox.mBStart = lineBounds.BEnd(wm) + blockOffset.B(wm); } } else { - // Just use the placeholder's y-offset wrt the containing block - aHypotheticalBox.mTop = placeholderOffset.y; + // Just use the placeholder's block-offset wrt the containing block + aHypotheticalBox.mBStart = placeholderOffset.B(wm); } } } } else { // The containing block is not a block, so it's probably something // like a XUL box, etc. - // Just use the placeholder's y-offset - aHypotheticalBox.mTop = placeholderOffset.y; + // Just use the placeholder's block-offset + aHypotheticalBox.mBStart = placeholderOffset.B(wm); } - // Second, determine the hypothetical box's mLeft & mRight - // To determine the left and right offsets we need to look at the block's 'direction' - if (NS_STYLE_DIRECTION_LTR == blockVis->mDirection) { - // How we determine the hypothetical box depends on whether the element - // would have been inline-level or block-level - if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { - // The placeholder represents the left edge of the hypothetical box - aHypotheticalBox.mLeft = placeholderOffset.x; - } else { - aHypotheticalBox.mLeft = aBlockIStartContentEdge; - } -#ifdef DEBUG - aHypotheticalBox.mLeftIsExact = true; -#endif - - if (knowBoxISize) { - aHypotheticalBox.mRight = aHypotheticalBox.mLeft + boxISize; -#ifdef DEBUG - aHypotheticalBox.mRightIsExact = true; -#endif - } else { - // We can't compute the right edge because we don't know the desired - // width. So instead use the right content edge of the block parent, - // but remember it's not exact - aHypotheticalBox.mRight = aBlockIStartContentEdge + aBlockContentISize; -#ifdef DEBUG - aHypotheticalBox.mRightIsExact = false; -#endif - } - + // Second, determine the hypothetical box's mIStart & mIEnd. + // How we determine the hypothetical box depends on whether the element + // would have been inline-level or block-level + if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { + // The placeholder represents the left edge of the hypothetical box + aHypotheticalBox.mIStart = placeholderOffset.I(wm); } else { - // The placeholder represents the right edge of the hypothetical box - if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { - aHypotheticalBox.mRight = placeholderOffset.x; - } else { - aHypotheticalBox.mRight = aBlockIStartContentEdge + aBlockContentISize; - } + aHypotheticalBox.mIStart = blockIStartContentEdge; + } #ifdef DEBUG - aHypotheticalBox.mRightIsExact = true; + aHypotheticalBox.mIStartIsExact = true; #endif - if (knowBoxISize) { - aHypotheticalBox.mLeft = aHypotheticalBox.mRight - boxISize; + if (knowBoxISize) { + aHypotheticalBox.mIEnd = aHypotheticalBox.mIStart + boxISize; #ifdef DEBUG - aHypotheticalBox.mLeftIsExact = true; + aHypotheticalBox.mIEndIsExact = true; #endif - } else { - // We can't compute the left edge because we don't know the desired - // width. So instead use the left content edge of the block parent, - // but remember it's not exact - aHypotheticalBox.mLeft = aBlockIStartContentEdge; + } else { + // We can't compute the inline-end edge because we don't know the desired + // inline-size. So instead use the end content edge of the block parent, + // but remember it's not exact + aHypotheticalBox.mIEnd = blockIStartContentEdge + blockContentISize; #ifdef DEBUG - aHypotheticalBox.mLeftIsExact = false; + aHypotheticalBox.mIEndIsExact = false; #endif - } - } // The current coordinate space is that of the nearest block to the placeholder. @@ -1395,44 +1382,49 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, // Exclude cases inside -moz-transform where fixed is like absolute. nsLayoutUtils::IsReallyFixedPos(frame)) { // In this case, cbrs->frame will likely be an ancestor of - // aContainingBlock, so can just walk our way up the frame tree. + // containingBlock, so can just walk our way up the frame tree. // Make sure to not add positions of frames whose parent is a // scrollFrame, since we're doing fixed positioning, which assumes // everything is scrolled to (0,0). cbOffset.MoveTo(0, 0); do { - cbOffset += aContainingBlock->GetPositionIgnoringScrolling(); - nsContainerFrame* parent = aContainingBlock->GetParent(); + cbOffset += containingBlock->GetPositionIgnoringScrolling(); + nsContainerFrame* parent = containingBlock->GetParent(); if (!parent) { // Oops, our absolute containing block isn't an ancestor of the // placeholder's containing block. This can happen if the placeholder // is pushed to a different page in a printing context. 'cbOffset' is - // currently relative to the root frame (aContainingBlock) - so just + // currently relative to the root frame (containingBlock) - so just // subtract the offset to the absolute containing block to make it // relative to that. - cbOffset -= aContainingBlock->GetOffsetTo(cbrs->frame); + cbOffset -= containingBlock->GetOffsetTo(cbrs->frame); break; } - aContainingBlock = parent; - } while (aContainingBlock != cbrs->frame); + containingBlock = parent; + } while (containingBlock != cbrs->frame); } else { // XXXldb We need to either ignore scrolling for the absolute // positioning case too (and take the incompatibility) or figure out // how to make these positioned elements actually *move* when we // scroll, and thus avoid the resulting incremental reflow bugs. - cbOffset = aContainingBlock->GetOffsetTo(cbrs->frame); + cbOffset = containingBlock->GetOffsetTo(cbrs->frame); } - aHypotheticalBox.mLeft += cbOffset.x; - aHypotheticalBox.mTop += cbOffset.y; - aHypotheticalBox.mRight += cbOffset.x; - + nscoord cbrsWidth = cbrs->ComputedWidth() + + cbrs->ComputedLogicalBorderPadding().LeftRight(cbwm); + LogicalPoint logCBOffs(wm, cbOffset, cbrsWidth - containerWidth); + aHypotheticalBox.mIStart += logCBOffs.I(wm); + aHypotheticalBox.mIEnd += logCBOffs.I(wm); + aHypotheticalBox.mBStart += logCBOffs.B(wm); + // The specified offsets are relative to the absolute containing block's // padding edge and our current values are relative to the border edge, so // translate. - nsMargin border = cbrs->ComputedPhysicalBorderPadding() - cbrs->ComputedPhysicalPadding(); - aHypotheticalBox.mLeft -= border.left; - aHypotheticalBox.mRight -= border.left; - aHypotheticalBox.mTop -= border.top; + LogicalMargin border = + cbrs->ComputedLogicalBorderPadding() - cbrs->ComputedLogicalPadding(); + border = border.ConvertTo(wm, cbrs->GetWritingMode()); + aHypotheticalBox.mIStart -= border.IStart(wm); + aHypotheticalBox.mIEnd -= border.IStart(wm); + aHypotheticalBox.mBStart -= border.BStart(wm); } void @@ -1442,8 +1434,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, nsIAtom* aFrameType) { WritingMode wm = GetWritingMode(); - NS_PRECONDITION(aCBSize.BSize(wm) != NS_AUTOHEIGHT, - "containing block height must be constrained"); + WritingMode cbwm = cbrs->GetWritingMode(); + NS_PRECONDITION(aCBSize.BSize(cbwm) != NS_AUTOHEIGHT, + "containing block bsize must be constrained"); NS_ASSERTION(aFrameType != nsGkAtoms::tableFrame, "InitAbsoluteConstraints should not be called on table frames"); @@ -1464,189 +1457,218 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, (eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) || ((eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) && (eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()))) { - // Find the nearest containing block frame to the placeholder frame, - // and return its left edge and width. - nscoord cbIStartEdge, cbISize; - nsIFrame* cbFrame = GetHypotheticalBoxContainer(placeholderFrame, - cbIStartEdge, - cbISize); - - CalculateHypotheticalBox(aPresContext, placeholderFrame, cbFrame, - cbIStartEdge, cbISize, cbrs, hypotheticalBox, - aFrameType); + CalculateHypotheticalBox(aPresContext, placeholderFrame, cbrs, + hypotheticalBox, aFrameType); } // Initialize the 'left' and 'right' computed offsets // XXX Handle new 'static-position' value... - bool leftIsAuto = false, rightIsAuto = false; - if (eStyleUnit_Auto == mStylePosition->mOffset.GetLeftUnit()) { - ComputedPhysicalOffsets().left = 0; - leftIsAuto = true; + + bool iStartIsAuto = false, iEndIsAuto = false; + bool bStartIsAuto = false, bEndIsAuto = false; + + // Size of the containing block in its writing mode + LogicalSize cbSize = aCBSize; + + LogicalMargin offsets = ComputedLogicalOffsets().ConvertTo(cbwm, wm); + + if (eStyleUnit_Auto == mStylePosition->mOffset.GetIStartUnit(cbwm)) { + offsets.IStart(cbwm) = 0; + iStartIsAuto = true; } else { - ComputedPhysicalOffsets().left = nsLayoutUtils:: - ComputeCBDependentValue(aCBSize.ISize(wm), - mStylePosition->mOffset.GetLeft()); + offsets.IStart(cbwm) = nsLayoutUtils:: + ComputeCBDependentValue(cbSize.ISize(cbwm), + mStylePosition->mOffset.GetIStart(cbwm)); } - if (eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit()) { - ComputedPhysicalOffsets().right = 0; - rightIsAuto = true; + if (eStyleUnit_Auto == mStylePosition->mOffset.GetIEndUnit(cbwm)) { + offsets.IEnd(cbwm) = 0; + iEndIsAuto = true; } else { - ComputedPhysicalOffsets().right = nsLayoutUtils:: - ComputeCBDependentValue(aCBSize.ISize(wm), - mStylePosition->mOffset.GetRight()); + offsets.IEnd(cbwm) = nsLayoutUtils:: + ComputeCBDependentValue(cbSize.ISize(cbwm), + mStylePosition->mOffset.GetIEnd(cbwm)); } - // Use the horizontal component of the hypothetical box in the cases - // where it's needed. - if (leftIsAuto && rightIsAuto) { - // Use the direction of the original ("static-position") containing block - // to dictate whether 'left' or 'right' is treated like 'static-position'. - if (NS_STYLE_DIRECTION_LTR == placeholderFrame->GetContainingBlock() - ->StyleVisibility()->mDirection) { - NS_ASSERTION(hypotheticalBox.mLeftIsExact, "should always have " - "exact value on containing block's start side"); - ComputedPhysicalOffsets().left = hypotheticalBox.mLeft; - leftIsAuto = false; + if (iStartIsAuto && iEndIsAuto) { + NS_ASSERTION(hypotheticalBox.mIStartIsExact, "should always have " + "exact value on containing block's start side"); + if (cbwm.IsBidiLTR() != hypotheticalBox.mWritingMode.IsBidiLTR()) { + offsets.IEnd(cbwm) = hypotheticalBox.mIStart; + iEndIsAuto = false; } else { - NS_ASSERTION(hypotheticalBox.mRightIsExact, "should always have " - "exact value on containing block's start side"); - ComputedPhysicalOffsets().right = aCBSize.ISize(wm) - - hypotheticalBox.mRight; - rightIsAuto = false; + offsets.IStart(cbwm) = hypotheticalBox.mIStart; + iStartIsAuto = false; } } - // Initialize the 'top' and 'bottom' computed offsets - bool topIsAuto = false, bottomIsAuto = false; - if (eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) { - ComputedPhysicalOffsets().top = 0; - topIsAuto = true; + if (eStyleUnit_Auto == mStylePosition->mOffset.GetBStartUnit(cbwm)) { + offsets.BStart(cbwm) = 0; + bStartIsAuto = true; } else { - ComputedPhysicalOffsets().top = nsLayoutUtils:: - ComputeBSizeDependentValue(aCBSize.BSize(wm), - mStylePosition->mOffset.GetTop()); + offsets.BStart(cbwm) = nsLayoutUtils:: + ComputeBSizeDependentValue(cbSize.BSize(cbwm), + mStylePosition->mOffset.GetBStart(cbwm)); } - if (eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()) { - ComputedPhysicalOffsets().bottom = 0; - bottomIsAuto = true; + if (eStyleUnit_Auto == mStylePosition->mOffset.GetBEndUnit(cbwm)) { + offsets.BEnd(cbwm) = 0; + bEndIsAuto = true; } else { - ComputedPhysicalOffsets().bottom = nsLayoutUtils:: - ComputeBSizeDependentValue(aCBSize.BSize(wm), - mStylePosition->mOffset.GetBottom()); + offsets.BEnd(cbwm) = nsLayoutUtils:: + ComputeBSizeDependentValue(cbSize.BSize(cbwm), + mStylePosition->mOffset.GetBEnd(cbwm)); } - if (topIsAuto && bottomIsAuto) { + if (bStartIsAuto && bEndIsAuto) { // Treat 'top' like 'static-position' - ComputedPhysicalOffsets().top = hypotheticalBox.mTop; - topIsAuto = false; + NS_ASSERTION(hypotheticalBox.mWritingMode.GetBlockDir() == cbwm.GetBlockDir(), + "block direction mismatch"); + offsets.BStart(cbwm) = hypotheticalBox.mBStart; + bStartIsAuto = false; } - bool widthIsAuto = eStyleUnit_Auto == mStylePosition->mWidth.GetUnit(); - bool heightIsAuto = eStyleUnit_Auto == mStylePosition->mHeight.GetUnit(); + SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm)); + + bool iSizeIsAuto = eStyleUnit_Auto == mStylePosition->ISize(cbwm).GetUnit(); + bool bSizeIsAuto = eStyleUnit_Auto == mStylePosition->BSize(cbwm).GetUnit(); typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags; ComputeSizeFlags computeSizeFlags = ComputeSizeFlags::eDefault; - if (leftIsAuto || rightIsAuto) { - computeSizeFlags = - ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); + if (wm.IsOrthogonalTo(cbwm)) { + if (bStartIsAuto || bEndIsAuto) { + computeSizeFlags = + ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); + } + } else { + if (iStartIsAuto || iEndIsAuto) { + computeSizeFlags = + ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); + } } + LogicalSize computedSize(wm); { AutoMaybeDisableFontInflation an(frame); - LogicalSize size = - frame->ComputeSize(rendContext, wm, aCBSize, - aCBSize.ISize(wm), // XXX or AvailableISize()? + computedSize = + frame->ComputeSize(rendContext, wm, cbSize.ConvertTo(wm, cbwm), + cbSize.ConvertTo(wm, cbwm).ISize(wm), // XXX or AvailableISize()? ComputedLogicalMargin().Size(wm) + ComputedLogicalOffsets().Size(wm), ComputedLogicalBorderPadding().Size(wm) - ComputedLogicalPadding().Size(wm), ComputedLogicalPadding().Size(wm), computeSizeFlags); - ComputedISize() = size.ISize(wm); - ComputedBSize() = size.BSize(wm); + ComputedISize() = computedSize.ISize(wm); + ComputedBSize() = computedSize.BSize(wm); + NS_ASSERTION(ComputedISize() >= 0, "Bogus inline-size"); + NS_ASSERTION(ComputedBSize() == NS_UNCONSTRAINEDSIZE || + ComputedBSize() >= 0, "Bogus block-size"); } - NS_ASSERTION(ComputedISize() >= 0, "Bogus inline-size"); - NS_ASSERTION(ComputedBSize() == NS_UNCONSTRAINEDSIZE || - ComputedBSize() >= 0, "Bogus block-size"); + computedSize = computedSize.ConvertTo(cbwm, wm); // XXX Now that we have ComputeSize, can we condense many of the // branches off of widthIsAuto? - if (leftIsAuto) { + LogicalMargin margin = ComputedLogicalMargin().ConvertTo(cbwm, wm); + const LogicalMargin borderPadding = + ComputedLogicalBorderPadding().ConvertTo(cbwm, wm); + + if (iStartIsAuto) { // We know 'right' is not 'auto' anymore thanks to the hypothetical // box code above. // Solve for 'left'. - if (widthIsAuto) { + if (iSizeIsAuto) { // XXXldb This, and the corresponding code in // nsAbsoluteContainingBlock.cpp, could probably go away now that // we always compute widths. - ComputedPhysicalOffsets().left = NS_AUTOOFFSET; + offsets.IStart(cbwm) = NS_AUTOOFFSET; } else { - ComputedPhysicalOffsets().left = aCBSize.Width(wm) - ComputedPhysicalMargin().left - - ComputedPhysicalBorderPadding().left - ComputedWidth() - ComputedPhysicalBorderPadding().right - - ComputedPhysicalMargin().right - ComputedPhysicalOffsets().right; - + offsets.IStart(cbwm) = + cbSize.ISize(cbwm) - offsets.IEnd(cbwm) - + computedSize.ISize(cbwm) - margin.IStartEnd(cbwm) - + borderPadding.IStartEnd(cbwm); } - } else if (rightIsAuto) { + } else if (iEndIsAuto) { // We know 'left' is not 'auto' anymore thanks to the hypothetical // box code above. // Solve for 'right'. - if (widthIsAuto) { + if (iSizeIsAuto) { // XXXldb This, and the corresponding code in // nsAbsoluteContainingBlock.cpp, could probably go away now that // we always compute widths. - ComputedPhysicalOffsets().right = NS_AUTOOFFSET; + offsets.IEnd(cbwm) = NS_AUTOOFFSET; } else { - ComputedPhysicalOffsets().right = aCBSize.Width(wm) - ComputedPhysicalOffsets().left - - ComputedPhysicalMargin().left - ComputedPhysicalBorderPadding().left - ComputedWidth() - - ComputedPhysicalBorderPadding().right - ComputedPhysicalMargin().right; + offsets.IEnd(cbwm) = + cbSize.ISize(cbwm) - offsets.IStart(cbwm) - + computedSize.ISize(cbwm) - margin.IStartEnd(cbwm) - + borderPadding.IStartEnd(cbwm); } } else { - // Neither 'left' nor 'right' is 'auto'. However, the width might + // Neither 'inline-start' nor 'inline-end' is 'auto'. + + if (wm.IsOrthogonalTo(cbwm)) { + // For orthogonal blocks, we need to handle the case where the block had + // unconstrained block-size, which mapped to unconstrained inline-size + // in the containing block's writing mode. + nscoord autoISize = cbSize.ISize(cbwm) - margin.IStartEnd(cbwm) - + borderPadding.IStartEnd(cbwm) - offsets.IStartEnd(cbwm); + if (autoISize < 0) { + autoISize = 0; + } + + if (computedSize.ISize(cbwm) == NS_UNCONSTRAINEDSIZE) { + // For non-replaced elements with block-size auto, the block-size + // fills the remaining space. + computedSize.ISize(cbwm) = autoISize; + + // XXX Do these need box-sizing adjustments? + LogicalSize maxSize = ComputedMaxSize(cbwm); + LogicalSize minSize = ComputedMinSize(cbwm); + if (computedSize.ISize(cbwm) > maxSize.ISize(cbwm)) { + computedSize.ISize(cbwm) = maxSize.ISize(cbwm); + } + if (computedSize.ISize(cbwm) < minSize.ISize(cbwm)) { + computedSize.ISize(cbwm) = minSize.ISize(cbwm); + } + } + } + + // However, the inline-size might // still not fill all the available space (even though we didn't // shrink-wrap) in case: - // * width was specified + // * inline-size was specified // * we're dealing with a replaced element - // * width was constrained by min-width or max-width. + // * width was constrained by min- or max-inline-size. - nscoord availMarginSpace = aCBSize.Width(wm) - - ComputedPhysicalOffsets().LeftRight() - - ComputedPhysicalMargin().LeftRight() - - ComputedPhysicalBorderPadding().LeftRight() - - ComputedWidth(); - bool marginLeftIsAuto = - eStyleUnit_Auto == mStyleMargin->mMargin.GetLeftUnit(); - bool marginRightIsAuto = - eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit(); + nscoord availMarginSpace = + aCBSize.ISize(cbwm) - offsets.IStartEnd(cbwm) - margin.IStartEnd(cbwm) - + borderPadding.IStartEnd(cbwm) - computedSize.ISize(cbwm); + bool marginIStartIsAuto = + eStyleUnit_Auto == mStyleMargin->mMargin.GetIStartUnit(cbwm); + bool marginIEndIsAuto = + eStyleUnit_Auto == mStyleMargin->mMargin.GetIEndUnit(cbwm); - if (marginLeftIsAuto) { - if (marginRightIsAuto) { + if (marginIStartIsAuto) { + if (marginIEndIsAuto) { if (availMarginSpace < 0) { // Note that this case is different from the neither-'auto' // case below, where the spec says to ignore 'left'/'right'. - if (cbrs && - NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { - // Ignore the specified value for 'margin-left'. - ComputedPhysicalMargin().left = availMarginSpace; - } else { - // Ignore the specified value for 'margin-right'. - ComputedPhysicalMargin().right = availMarginSpace; - } + // Ignore the specified value for 'margin-right'. + margin.IEnd(cbwm) = availMarginSpace; } else { // Both 'margin-left' and 'margin-right' are 'auto', so they get // equal values - ComputedPhysicalMargin().left = availMarginSpace / 2; - ComputedPhysicalMargin().right = availMarginSpace - ComputedPhysicalMargin().left; + margin.IStart(cbwm) = availMarginSpace / 2; + margin.IEnd(cbwm) = availMarginSpace - margin.IStart(cbwm); } } else { // Just 'margin-left' is 'auto' - ComputedPhysicalMargin().left = availMarginSpace; + margin.IStart(cbwm) = availMarginSpace; } } else { - if (marginRightIsAuto) { + if (marginIEndIsAuto) { // Just 'margin-right' is 'auto' - ComputedPhysicalMargin().right = availMarginSpace; + margin.IEnd(cbwm) = availMarginSpace; } else { // We're over-constrained so use the direction of the containing // block to dictate which value to ignore. (And note that the @@ -1655,95 +1677,96 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, // Note that this case is different from the both-'auto' case // above, where the spec says to ignore // 'margin-left'/'margin-right'. - if (cbrs && - NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { - // Ignore the specified value for 'left'. - ComputedPhysicalOffsets().left += availMarginSpace; - } else { - // Ignore the specified value for 'right'. - ComputedPhysicalOffsets().right += availMarginSpace; - } + // Ignore the specified value for 'right'. + offsets.IEnd(cbwm) += availMarginSpace; } } } - if (topIsAuto) { - // solve for 'top' - if (heightIsAuto) { - ComputedPhysicalOffsets().top = NS_AUTOOFFSET; + if (bStartIsAuto) { + // solve for block-start + if (bSizeIsAuto) { + offsets.BStart(cbwm) = NS_AUTOOFFSET; } else { - ComputedPhysicalOffsets().top = aCBSize.Height(wm) - ComputedPhysicalMargin().top - - ComputedPhysicalBorderPadding().top - ComputedHeight() - ComputedPhysicalBorderPadding().bottom - - ComputedPhysicalMargin().bottom - ComputedPhysicalOffsets().bottom; + offsets.BStart(cbwm) = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) - + borderPadding.BStartEnd(cbwm) - computedSize.BSize(cbwm) - + offsets.BEnd(cbwm); } - } else if (bottomIsAuto) { - // solve for 'bottom' - if (heightIsAuto) { - ComputedPhysicalOffsets().bottom = NS_AUTOOFFSET; + } else if (bEndIsAuto) { + // solve for block-end + if (bSizeIsAuto) { + offsets.BEnd(cbwm) = NS_AUTOOFFSET; } else { - ComputedPhysicalOffsets().bottom = aCBSize.Height(wm) - ComputedPhysicalOffsets().top - - ComputedPhysicalMargin().top - ComputedPhysicalBorderPadding().top - ComputedHeight() - - ComputedPhysicalBorderPadding().bottom - ComputedPhysicalMargin().bottom; + offsets.BEnd(cbwm) = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) - + borderPadding.BStartEnd(cbwm) - computedSize.BSize(cbwm) - + offsets.BStart(cbwm); } } else { - // Neither 'top' nor 'bottom' is 'auto'. - nscoord autoHeight = aCBSize.Height(wm) - - ComputedPhysicalOffsets().TopBottom() - - ComputedPhysicalMargin().TopBottom() - - ComputedPhysicalBorderPadding().TopBottom(); - if (autoHeight < 0) { - autoHeight = 0; + // Neither block-start nor -end is 'auto'. + nscoord autoBSize = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) - + borderPadding.BStartEnd(cbwm) - offsets.BStartEnd(cbwm); + if (autoBSize < 0) { + autoBSize = 0; } - if (ComputedHeight() == NS_UNCONSTRAINEDSIZE) { - // For non-replaced elements with 'height' auto, the 'height' + if (computedSize.BSize(cbwm) == NS_UNCONSTRAINEDSIZE) { + // For non-replaced elements with block-size auto, the block-size // fills the remaining space. - ComputedHeight() = autoHeight; + computedSize.BSize(cbwm) = autoBSize; // XXX Do these need box-sizing adjustments? - if (ComputedHeight() > ComputedMaxHeight()) - ComputedHeight() = ComputedMaxHeight(); - if (ComputedHeight() < ComputedMinHeight()) - ComputedHeight() = ComputedMinHeight(); + LogicalSize maxSize = ComputedMaxSize(cbwm); + LogicalSize minSize = ComputedMinSize(cbwm); + if (computedSize.BSize(cbwm) > maxSize.BSize(cbwm)) { + computedSize.BSize(cbwm) = maxSize.BSize(cbwm); + } + if (computedSize.BSize(cbwm) < minSize.BSize(cbwm)) { + computedSize.BSize(cbwm) = minSize.BSize(cbwm); + } } - // The height might still not fill all the available space in case: - // * height was specified + // The block-size might still not fill all the available space in case: + // * bsize was specified // * we're dealing with a replaced element - // * height was constrained by min-height or max-height. - nscoord availMarginSpace = autoHeight - ComputedHeight(); - bool marginTopIsAuto = - eStyleUnit_Auto == mStyleMargin->mMargin.GetTopUnit(); - bool marginBottomIsAuto = - eStyleUnit_Auto == mStyleMargin->mMargin.GetBottomUnit(); + // * bsize was constrained by min- or max-bsize. + nscoord availMarginSpace = autoBSize - computedSize.BSize(cbwm); + bool marginBStartIsAuto = + eStyleUnit_Auto == mStyleMargin->mMargin.GetBStartUnit(cbwm); + bool marginBEndIsAuto = + eStyleUnit_Auto == mStyleMargin->mMargin.GetBEndUnit(cbwm); - if (marginTopIsAuto) { - if (marginBottomIsAuto) { + if (marginBStartIsAuto) { + if (marginBEndIsAuto) { if (availMarginSpace < 0) { // FIXME: Note that the spec doesn't actually say we should do this! - ComputedPhysicalMargin().bottom = availMarginSpace; + margin.BEnd(cbwm) = availMarginSpace; } else { - // Both 'margin-top' and 'margin-bottom' are 'auto', so they get + // Both margin-block-start and -end are 'auto', so they get // equal values - ComputedPhysicalMargin().top = availMarginSpace / 2; - ComputedPhysicalMargin().bottom = availMarginSpace - ComputedPhysicalMargin().top; + margin.BStart(cbwm) = availMarginSpace / 2; + margin.BEnd(cbwm) = availMarginSpace - margin.BStart(cbwm); } } else { - // Just 'margin-top' is 'auto' - ComputedPhysicalMargin().top = availMarginSpace; + // Just margin-block-start is 'auto' + margin.BStart(cbwm) = availMarginSpace; } } else { - if (marginBottomIsAuto) { - // Just 'margin-bottom' is 'auto' - ComputedPhysicalMargin().bottom = availMarginSpace; + if (marginBEndIsAuto) { + // Just margin-block-end is 'auto' + margin.BEnd(cbwm) = availMarginSpace; } else { // We're over-constrained so ignore the specified value for - // 'bottom'. (And note that the spec says to ignore 'bottom' + // block-end. (And note that the spec says to ignore 'bottom' // rather than 'margin-bottom'.) - ComputedPhysicalOffsets().bottom += availMarginSpace; + offsets.BEnd(cbwm) += availMarginSpace; } } } + ComputedBSize() = computedSize.ConvertTo(wm, cbwm).BSize(wm); + ComputedISize() = computedSize.ConvertTo(wm, cbwm).ISize(wm); + + SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm)); + SetComputedLogicalMargin(margin.ConvertTo(wm, cbwm)); } // This will not be converted to abstract coordinates because it's only @@ -1774,7 +1797,8 @@ GetBlockMarginBorderPadding(const nsHTMLReflowState* aReflowState) * until it finds the canvas frame, or it encounters a frame that is not a block, * area, or scroll frame. This handles compatibility with IE (see bug 85016 and bug 219693) * - * When we encounter scrolledContent block frames, we skip over them, since they are guaranteed to not be useful for computing the containing block. + * When we encounter scrolledContent block frames, we skip over them, + * since they are guaranteed to not be useful for computing the containing block. * * See also IsQuirkContainingBlockHeight. */ @@ -1848,13 +1872,15 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState) if (firstAncestorRS) { nsIContent* frameContent = firstAncestorRS->frame->GetContent(); if (frameContent) { - NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::html), "First ancestor is not HTML"); + NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::html), + "First ancestor is not HTML"); } } if (secondAncestorRS) { nsIContent* frameContent = secondAncestorRS->frame->GetContent(); if (frameContent) { - NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::body), "Second ancestor is not BODY"); + NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::body), + "Second ancestor is not BODY"); } } #endif @@ -2023,15 +2049,19 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext, ComputedPhysicalMargin().SizeTo(0, 0, 0, 0); ComputedPhysicalOffsets().SizeTo(0, 0, 0, 0); - ComputedWidth() = AvailableWidth() - ComputedPhysicalBorderPadding().LeftRight(); - if (ComputedWidth() < 0) - ComputedWidth() = 0; - if (AvailableHeight() != NS_UNCONSTRAINEDSIZE) { - ComputedHeight() = AvailableHeight() - ComputedPhysicalBorderPadding().TopBottom(); - if (ComputedHeight() < 0) - ComputedHeight() = 0; + ComputedISize() = + AvailableISize() - ComputedLogicalBorderPadding().IStartEnd(wm); + if (ComputedISize() < 0) { + ComputedISize() = 0; + } + if (AvailableBSize() != NS_UNCONSTRAINEDSIZE) { + ComputedBSize() = + AvailableBSize() - ComputedLogicalBorderPadding().BStartEnd(wm); + if (ComputedBSize() < 0) { + ComputedBSize() = 0; + } } else { - ComputedHeight() = NS_UNCONSTRAINEDSIZE; + ComputedBSize() = NS_UNCONSTRAINEDSIZE; } ComputedMinWidth() = ComputedMinHeight() = 0; @@ -2205,7 +2235,7 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext, } else if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) { // XXX not sure if this belongs here or somewhere else - cwk - InitAbsoluteConstraints(aPresContext, cbrs, cbSize, aFrameType); + InitAbsoluteConstraints(aPresContext, cbrs, cbSize.ConvertTo(cbrs->GetWritingMode(), wm), aFrameType); } else { AutoMaybeDisableFontInflation an(frame); diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 2f03258e42..35d964cff6 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -441,9 +441,23 @@ struct nsHTMLReflowState : public nsCSSOffsetState { const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; } nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; } - LogicalMargin ComputedLogicalOffsets() const + const LogicalMargin ComputedLogicalOffsets() const { return LogicalMargin(mWritingMode, mComputedOffsets); } + void SetComputedLogicalOffsets(const LogicalMargin& aOffsets) + { mComputedOffsets = aOffsets.GetPhysicalMargin(mWritingMode); } + + // Return the state's computed size including border-padding, with + // unconstrained dimensions replaced by zero. + nsSize ComputedSizeAsContainerIfConstrained() const { + const nscoord wd = ComputedWidth(); + const nscoord ht = ComputedHeight(); + return nsSize(wd == NS_UNCONSTRAINEDSIZE + ? 0 : wd + ComputedPhysicalBorderPadding().LeftRight(), + ht == NS_UNCONSTRAINEDSIZE + ? 0 : ht + ComputedPhysicalBorderPadding().TopBottom()); + } + private: // the available width in which to reflow the frame. The space // represents the amount of room for the frame's margin, border, @@ -899,9 +913,6 @@ protected: void CalculateHypotheticalBox(nsPresContext* aPresContext, nsIFrame* aPlaceholderFrame, - nsIFrame* aContainingBlock, - nscoord aBlockIStartContentEdge, - nscoord aBlockContentISize, const nsHTMLReflowState* cbrs, nsHypotheticalBox& aHypotheticalBox, nsIAtom* aFrameType); diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp index 47746563f1..7e01ea2ffa 100644 --- a/layout/generic/nsLineBox.cpp +++ b/layout/generic/nsLineBox.cpp @@ -246,11 +246,17 @@ nsLineBox::List(FILE* out, const char* aPrefix, uint32_t aFlags) const str += nsPrintfCString("bm=%d ", GetCarriedOutBEndMargin().get()); } nsRect bounds = GetPhysicalBounds(); - str += nsPrintfCString("{%d,%d,%d,%d} {%d,%d,%d,%d;cw=%d} ", - bounds.x, bounds.y, bounds.width, bounds.height, - mBounds.IStart(mWritingMode), mBounds.BStart(mWritingMode), - mBounds.ISize(mWritingMode), mBounds.BSize(mWritingMode), - mContainerWidth); + str += nsPrintfCString("{%d,%d,%d,%d} ", + bounds.x, bounds.y, bounds.width, bounds.height); + if (mWritingMode.IsVertical() || !mWritingMode.IsBidiLTR()) { + str += nsPrintfCString("{%s-%s: %d,%d,%d,%d; cw=%d} ", + mWritingMode.IsVertical() + ? mWritingMode.IsVerticalLR() ? "vlr" : "vrl" + : "htb", + mWritingMode.IsBidiLTR() ? "ltr" : "rtl", + IStart(), BStart(), ISize(), BSize(), + mContainerWidth); + } if (mData && (!mData->mOverflowAreas.VisualOverflow().IsEqualEdges(bounds) || !mData->mOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds))) { diff --git a/layout/reftests/css-ruby/bug1181890-notref.html b/layout/reftests/css-ruby/bug1181890-notref.html new file mode 100644 index 0000000000..0e97415a88 --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890-notref.html @@ -0,0 +1,9 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

diff --git a/layout/reftests/css-ruby/bug1181890-ref.html b/layout/reftests/css-ruby/bug1181890-ref.html new file mode 100644 index 0000000000..41a46d13e3 --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890-ref.html @@ -0,0 +1,9 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

diff --git a/layout/reftests/css-ruby/bug1181890.html b/layout/reftests/css-ruby/bug1181890.html new file mode 100644 index 0000000000..3369a7482d --- /dev/null +++ b/layout/reftests/css-ruby/bug1181890.html @@ -0,0 +1,10 @@ + +

+ Aaaaaaaaaaaaa + BBBBBb +

+

+ Aaaaaaaaaaaaa + BBBBBb +

+‎ diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index 2ad3aa3185..18091598f9 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -50,3 +50,5 @@ pref(layout.css.vertical-text.enabled,true) fails == ruby-position-vertical-rl.h == ruby-span-1.html ruby-span-1-ref.html == ruby-whitespace-1.html ruby-whitespace-1-ref.html == ruby-whitespace-2.html ruby-whitespace-2-ref.html +== bug1181890.html bug1181890-ref.html +!= bug1181890.html bug1181890-notref.html diff --git a/layout/reftests/forms/select/997709-2-ref.html b/layout/reftests/forms/select/997709-2-ref.html new file mode 100644 index 0000000000..349abe0b77 --- /dev/null +++ b/layout/reftests/forms/select/997709-2-ref.html @@ -0,0 +1,4 @@ + + + + diff --git a/layout/reftests/forms/select/997709-2.html b/layout/reftests/forms/select/997709-2.html new file mode 100644 index 0000000000..46be454185 --- /dev/null +++ b/layout/reftests/forms/select/997709-2.html @@ -0,0 +1,4 @@ + + + + diff --git a/layout/reftests/forms/select/reftest.list b/layout/reftests/forms/select/reftest.list index 1f4897ffd3..9c35b13371 100644 --- a/layout/reftests/forms/select/reftest.list +++ b/layout/reftests/forms/select/reftest.list @@ -5,3 +5,4 @@ skip-if(B2G||Mulet) == multiple.html multiple-ref.html # Initial mulet triage: p == option-children.html option-children-ref.html fuzzy(1,4) == padding-button-placement.html padding-button-placement-ref.html HTTP(../..) == vertical-centering.html vertical-centering-ref.html +== 997709-2.html 997709-2-ref.html diff --git a/layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html b/layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html new file mode 100644 index 0000000000..bce2509b84 --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + +
x x
x x xx
x x x
x x
xx xx
+ + + diff --git a/layout/reftests/table-bordercollapse/border-collapse-rtl.html b/layout/reftests/table-bordercollapse/border-collapse-rtl.html new file mode 100644 index 0000000000..f97ef30d45 --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-collapse-rtl.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + +
x x
xxxx
x xx
x x
x x xx
+ + + diff --git a/layout/reftests/table-bordercollapse/reftest.list b/layout/reftests/table-bordercollapse/reftest.list index 2c029e31dd..0a4fba0a48 100644 --- a/layout/reftests/table-bordercollapse/reftest.list +++ b/layout/reftests/table-bordercollapse/reftest.list @@ -95,3 +95,4 @@ == bordercolor-4.html bordercolor-4-ref.html == empty-toprow.html empty-toprow-ref.html == double_borders.html double_borders_ref.html +fails == border-collapse-rtl.html border-collapse-rtl-ref.html # see bug 1157569 diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index a39652f76b..784cdd9ed0 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -39,7 +39,7 @@ fuzzy-if(winWidget&&!layersGPUAccelerated,1,251) == backface-visibility-2.html b == backface-visibility-3.html backface-visibility-3-ref.html != perspective-origin-1a.html rotatex-perspective-1a.html random-if(Android&&AndroidVersion==17) == perspective-origin-1b.html perspective-origin-1a.html -random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # bug 732568 +fuzzy(3,99) random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # subpixel AA, bug 732568 fuzzy-if(winWidget&&!layersGPUAccelerated,1,61) == perspective-origin-3a.html perspective-origin-3-ref.html == perspective-origin-4a.html perspective-origin-4-ref.html != sorting-1a.html sorting-1-ref.html @@ -57,9 +57,9 @@ pref(layout.css.will-change.enabled,true) != willchange-containing-block.html?wi fuzzy-if(winWidget&&!layersGPUAccelerated,1,606) == scroll-perspective-1.html scroll-perspective-1-ref.html # Bugs fails-if(!layersGPUAccelerated) == 1035611-1.html 1035611-1-ref.html # Bug 1072898 for !layersGPUAccelerated failures -== animate-cube-radians.html animate-cube-radians-ref.html -fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated,16,6) fuzzy-if(Mulet,16,9) == animate-cube-radians-zoom.html animate-cube-radians-zoom-ref.html +fuzzy(3,99) == animate-cube-radians.html animate-cube-radians-ref.html # subpixel AA +fuzzy(3,99) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated,16,6) fuzzy-if(Mulet,16,9) == animate-cube-radians-zoom.html animate-cube-radians-zoom-ref.html != animate-cube-radians-ref.html animate-cube-radians-zoom-ref.html -== animate-cube-degrees.html animate-cube-degrees-ref.html +fuzzy(3,99) == animate-cube-degrees.html animate-cube-degrees-ref.html # subpixel AA == animate-cube-degrees-zoom.html animate-cube-degrees-zoom-ref.html != animate-cube-degrees-ref.html animate-cube-degrees-zoom-ref.html diff --git a/layout/reftests/transform/reftest.list b/layout/reftests/transform/reftest.list index 682bac53f1..2769cd5a75 100644 --- a/layout/reftests/transform/reftest.list +++ b/layout/reftests/transform/reftest.list @@ -45,12 +45,12 @@ random == rotate-1f.html rotate-1-ref.html # to look the same. == rotate-2a.html rotate-2-ref.html == rotate-2b.html rotate-2-ref.html -# -moz-transform-origin: We should NOT get the same images when using different -# -moz-transform-origins. +# -transform-origin: We should NOT get the same images when using different +# -transform-origins. != origin-1a.html origin-1-ref.html != origin-1b.html origin-1-ref.html -# -moz-transform-origin: We should get the same images when using equivalent -# -moz-transform-origins. +# -transform-origin: We should get the same images when using equivalent +# -transform-origins. == origin-2a.html origin-2-ref.html == origin-2b.html origin-2-ref.html == origin-2c.html origin-2-ref.html @@ -124,14 +124,14 @@ skip-if(B2G||Mulet) == stresstest-1.html stresstest-1-ref.html # bug 773482 # In == table-2b.html table-2-ref.html # Bug 722463 == inline-1a.html inline-1-ref.html -pref(svg.transform-origin.enabled,true) == transform-box-svg-1a.svg transform-box-svg-1-ref.svg -pref(svg.transform-origin.enabled,true) == transform-box-svg-1b.svg transform-box-svg-1-ref.svg -pref(svg.transform-origin.enabled,true) == transform-box-svg-2a.svg transform-box-svg-2-ref.svg -pref(svg.transform-origin.enabled,true) == transform-box-svg-2b.svg transform-box-svg-2-ref.svg -pref(svg.transform-origin.enabled,true) == transform-origin-svg-1a.svg transform-origin-svg-1-ref.svg -pref(svg.transform-origin.enabled,true) == transform-origin-svg-1b.svg transform-origin-svg-1-ref.svg -pref(svg.transform-origin.enabled,true) == transform-origin-svg-2a.svg transform-origin-svg-2-ref.svg -pref(svg.transform-origin.enabled,true) == transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg +pref(svg.transform-box.enabled,true) == transform-box-svg-1a.svg transform-box-svg-1-ref.svg +pref(svg.transform-box.enabled,true) == transform-box-svg-1b.svg transform-box-svg-1-ref.svg +pref(svg.transform-box.enabled,true) == transform-box-svg-2a.svg transform-box-svg-2-ref.svg +pref(svg.transform-box.enabled,true) == transform-box-svg-2b.svg transform-box-svg-2-ref.svg +== transform-origin-svg-1a.svg transform-origin-svg-1-ref.svg +== transform-origin-svg-1b.svg transform-origin-svg-1-ref.svg +== transform-origin-svg-2a.svg transform-origin-svg-2-ref.svg +== transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg # Bug 1122526 == animate-layer-scale-inherit-1.html animate-layer-scale-inherit-1-ref.html == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html diff --git a/layout/reftests/writing-mode/abspos/reftest.list b/layout/reftests/writing-mode/abspos/reftest.list index 54921fd07e..826c8ccb1a 100644 --- a/layout/reftests/writing-mode/abspos/reftest.list +++ b/layout/reftests/writing-mode/abspos/reftest.list @@ -3,99 +3,99 @@ # (See bug 1079151 for the origin of these testcases by Gérard Talbot.) default-preferences pref(layout.css.vertical-text.enabled,true) -fails == s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-005.xht s71-abs-pos-non-replaced-vlr-005-ref.xht -fails == s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007-ref.xht -fails == s71-abs-pos-non-replaced-vlr-009.xht s71-abs-pos-non-replaced-vlr-009-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-009.xht s71-abs-pos-non-replaced-vlr-009-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-011.xht s71-abs-pos-non-replaced-vlr-011-ref.xht -fails == s71-abs-pos-non-replaced-vlr-013.xht s71-abs-pos-non-replaced-vlr-013-ref.xht -fails == s71-abs-pos-non-replaced-vlr-015.xht s71-abs-pos-non-replaced-vlr-015-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-013.xht s71-abs-pos-non-replaced-vlr-013-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-015.xht s71-abs-pos-non-replaced-vlr-015-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-017.xht s71-abs-pos-non-replaced-vlr-017-ref.xht -fails == s71-abs-pos-non-replaced-vlr-019.xht s71-abs-pos-non-replaced-vlr-019-ref.xht -fails == s71-abs-pos-non-replaced-vlr-021.xht s71-abs-pos-non-replaced-vlr-021-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-019.xht s71-abs-pos-non-replaced-vlr-019-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-021.xht s71-abs-pos-non-replaced-vlr-021-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-023.xht s71-abs-pos-non-replaced-vlr-023-ref.xht -fails == s71-abs-pos-non-replaced-vlr-025.xht s71-abs-pos-non-replaced-vlr-025-ref.xht -fails == s71-abs-pos-non-replaced-vlr-027.xht s71-abs-pos-non-replaced-vlr-027-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-025.xht s71-abs-pos-non-replaced-vlr-025-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-027.xht s71-abs-pos-non-replaced-vlr-027-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-029.xht s71-abs-pos-non-replaced-vlr-029-ref.xht -fails == s71-abs-pos-non-replaced-vlr-031.xht s71-abs-pos-non-replaced-vlr-031-ref.xht -fails == s71-abs-pos-non-replaced-vlr-033.xht s71-abs-pos-non-replaced-vlr-033-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-031.xht s71-abs-pos-non-replaced-vlr-031-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-033.xht s71-abs-pos-non-replaced-vlr-033-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-035.xht s71-abs-pos-non-replaced-vlr-035-ref.xht -fails == s71-abs-pos-non-replaced-vlr-037.xht s71-abs-pos-non-replaced-vlr-037-ref.xht -fails == s71-abs-pos-non-replaced-vlr-039.xht s71-abs-pos-non-replaced-vlr-039-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-037.xht s71-abs-pos-non-replaced-vlr-037-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-039.xht s71-abs-pos-non-replaced-vlr-039-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-041.xht s71-abs-pos-non-replaced-vlr-041-ref.xht -fails == s71-abs-pos-non-replaced-vlr-043.xht s71-abs-pos-non-replaced-vlr-043-ref.xht -fails == s71-abs-pos-non-replaced-vlr-045.xht s71-abs-pos-non-replaced-vlr-045-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-043.xht s71-abs-pos-non-replaced-vlr-043-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-045.xht s71-abs-pos-non-replaced-vlr-045-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-047.xht s71-abs-pos-non-replaced-vlr-047-ref.xht -fails == s71-abs-pos-non-replaced-vlr-049.xht s71-abs-pos-non-replaced-vlr-049-ref.xht -fails == s71-abs-pos-non-replaced-vlr-051.xht s71-abs-pos-non-replaced-vlr-051-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-049.xht s71-abs-pos-non-replaced-vlr-049-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-051.xht s71-abs-pos-non-replaced-vlr-051-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-053.xht s71-abs-pos-non-replaced-vlr-053-ref.xht -fails == s71-abs-pos-non-replaced-vlr-055.xht s71-abs-pos-non-replaced-vlr-055-ref.xht -fails == s71-abs-pos-non-replaced-vlr-057.xht s71-abs-pos-non-replaced-vlr-057-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-055.xht s71-abs-pos-non-replaced-vlr-055-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-057.xht s71-abs-pos-non-replaced-vlr-057-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-059.xht s71-abs-pos-non-replaced-vlr-059-ref.xht -fails == s71-abs-pos-non-replaced-vlr-061.xht s71-abs-pos-non-replaced-vlr-061-ref.xht -fails == s71-abs-pos-non-replaced-vlr-063.xht s71-abs-pos-non-replaced-vlr-063-ref.xht -fails == s71-abs-pos-non-replaced-vlr-065.xht s71-abs-pos-non-replaced-vlr-065-ref.xht -fails == s71-abs-pos-non-replaced-vlr-067.xht s71-abs-pos-non-replaced-vlr-067-ref.xht -fails == s71-abs-pos-non-replaced-vlr-069.xht s71-abs-pos-non-replaced-vlr-069-ref.xht -fails == s71-abs-pos-non-replaced-vlr-071.xht s71-abs-pos-non-replaced-vlr-071-ref.xht -fails == s71-abs-pos-non-replaced-vlr-073.xht s71-abs-pos-non-replaced-vlr-073-ref.xht -fails == s71-abs-pos-non-replaced-vlr-075.xht s71-abs-pos-non-replaced-vlr-075-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-061.xht s71-abs-pos-non-replaced-vlr-061-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-063.xht s71-abs-pos-non-replaced-vlr-063-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-065.xht s71-abs-pos-non-replaced-vlr-065-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-067.xht s71-abs-pos-non-replaced-vlr-067-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-069.xht s71-abs-pos-non-replaced-vlr-069-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-071.xht s71-abs-pos-non-replaced-vlr-071-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vlr-073.xht s71-abs-pos-non-replaced-vlr-073-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-075.xht s71-abs-pos-non-replaced-vlr-075-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-077.xht s71-abs-pos-non-replaced-vlr-077-ref.xht -fails == s71-abs-pos-non-replaced-vlr-079.xht s71-abs-pos-non-replaced-vlr-079-ref.xht -fails == s71-abs-pos-non-replaced-vlr-081.xht s71-abs-pos-non-replaced-vlr-081-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-079.xht s71-abs-pos-non-replaced-vlr-079-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-081.xht s71-abs-pos-non-replaced-vlr-081-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-083.xht s71-abs-pos-non-replaced-vlr-083-ref.xht -fails == s71-abs-pos-non-replaced-vlr-085.xht s71-abs-pos-non-replaced-vlr-085-ref.xht -fails == s71-abs-pos-non-replaced-vlr-087.xht s71-abs-pos-non-replaced-vlr-087-ref.xht -fails == s71-abs-pos-non-replaced-vlr-089.xht s71-abs-pos-non-replaced-vlr-089-ref.xht -fails == s71-abs-pos-non-replaced-vlr-091.xht s71-abs-pos-non-replaced-vlr-091-ref.xht -fails == s71-abs-pos-non-replaced-vlr-093.xht s71-abs-pos-non-replaced-vlr-093-ref.xht -fails == s71-abs-pos-non-replaced-vlr-095.xht s71-abs-pos-non-replaced-vlr-095-ref.xht -fails == s71-abs-pos-non-replaced-vlr-097.xht s71-abs-pos-non-replaced-vlr-097-ref.xht -fails == s71-abs-pos-non-replaced-vrl-002.xht s71-abs-pos-non-replaced-vrl-002-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-085.xht s71-abs-pos-non-replaced-vlr-085-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-087.xht s71-abs-pos-non-replaced-vlr-087-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-089.xht s71-abs-pos-non-replaced-vlr-089-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-091.xht s71-abs-pos-non-replaced-vlr-091-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-093.xht s71-abs-pos-non-replaced-vlr-093-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-095.xht s71-abs-pos-non-replaced-vlr-095-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vlr-097.xht s71-abs-pos-non-replaced-vlr-097-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-002.xht s71-abs-pos-non-replaced-vrl-002-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-004.xht s71-abs-pos-non-replaced-vrl-004-ref.xht -fails == s71-abs-pos-non-replaced-vrl-006.xht s71-abs-pos-non-replaced-vrl-006-ref.xht -fails == s71-abs-pos-non-replaced-vrl-008.xht s71-abs-pos-non-replaced-vrl-008-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-006.xht s71-abs-pos-non-replaced-vrl-006-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-008.xht s71-abs-pos-non-replaced-vrl-008-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-010.xht s71-abs-pos-non-replaced-vrl-010-ref.xht -fails == s71-abs-pos-non-replaced-vrl-012.xht s71-abs-pos-non-replaced-vrl-012-ref.xht -fails == s71-abs-pos-non-replaced-vrl-014.xht s71-abs-pos-non-replaced-vrl-014-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-012.xht s71-abs-pos-non-replaced-vrl-012-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-014.xht s71-abs-pos-non-replaced-vrl-014-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-016.xht s71-abs-pos-non-replaced-vrl-016-ref.xht -fails == s71-abs-pos-non-replaced-vrl-018.xht s71-abs-pos-non-replaced-vrl-018-ref.xht -fails == s71-abs-pos-non-replaced-vrl-020.xht s71-abs-pos-non-replaced-vrl-020-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-018.xht s71-abs-pos-non-replaced-vrl-018-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-020.xht s71-abs-pos-non-replaced-vrl-020-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-022.xht s71-abs-pos-non-replaced-vrl-022-ref.xht -fails == s71-abs-pos-non-replaced-vrl-024.xht s71-abs-pos-non-replaced-vrl-024-ref.xht -fails == s71-abs-pos-non-replaced-vrl-026.xht s71-abs-pos-non-replaced-vrl-026-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-024.xht s71-abs-pos-non-replaced-vrl-024-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-026.xht s71-abs-pos-non-replaced-vrl-026-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-028.xht s71-abs-pos-non-replaced-vrl-028-ref.xht -fails == s71-abs-pos-non-replaced-vrl-030.xht s71-abs-pos-non-replaced-vrl-030-ref.xht -fails == s71-abs-pos-non-replaced-vrl-032.xht s71-abs-pos-non-replaced-vrl-032-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-030.xht s71-abs-pos-non-replaced-vrl-030-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-032.xht s71-abs-pos-non-replaced-vrl-032-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-034.xht s71-abs-pos-non-replaced-vrl-034-ref.xht -fails == s71-abs-pos-non-replaced-vrl-036.xht s71-abs-pos-non-replaced-vrl-036-ref.xht -fails == s71-abs-pos-non-replaced-vrl-038.xht s71-abs-pos-non-replaced-vrl-038-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-036.xht s71-abs-pos-non-replaced-vrl-036-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-038.xht s71-abs-pos-non-replaced-vrl-038-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-040.xht s71-abs-pos-non-replaced-vrl-040-ref.xht -fails == s71-abs-pos-non-replaced-vrl-042.xht s71-abs-pos-non-replaced-vrl-042-ref.xht -fails == s71-abs-pos-non-replaced-vrl-044.xht s71-abs-pos-non-replaced-vrl-044-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-042.xht s71-abs-pos-non-replaced-vrl-042-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-044.xht s71-abs-pos-non-replaced-vrl-044-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-046.xht s71-abs-pos-non-replaced-vrl-046-ref.xht -fails == s71-abs-pos-non-replaced-vrl-048.xht s71-abs-pos-non-replaced-vrl-048-ref.xht -fails == s71-abs-pos-non-replaced-vrl-050.xht s71-abs-pos-non-replaced-vrl-050-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-048.xht s71-abs-pos-non-replaced-vrl-048-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-050.xht s71-abs-pos-non-replaced-vrl-050-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-052.xht s71-abs-pos-non-replaced-vrl-052-ref.xht -fails == s71-abs-pos-non-replaced-vrl-054.xht s71-abs-pos-non-replaced-vrl-054-ref.xht -fails == s71-abs-pos-non-replaced-vrl-056.xht s71-abs-pos-non-replaced-vrl-056-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-054.xht s71-abs-pos-non-replaced-vrl-054-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-056.xht s71-abs-pos-non-replaced-vrl-056-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-058.xht s71-abs-pos-non-replaced-vrl-058-ref.xht -fails == s71-abs-pos-non-replaced-vrl-060.xht s71-abs-pos-non-replaced-vrl-060-ref.xht -fails == s71-abs-pos-non-replaced-vrl-062.xht s71-abs-pos-non-replaced-vrl-062-ref.xht -fails == s71-abs-pos-non-replaced-vrl-064.xht s71-abs-pos-non-replaced-vrl-064-ref.xht -fails == s71-abs-pos-non-replaced-vrl-066.xht s71-abs-pos-non-replaced-vrl-066-ref.xht -fails == s71-abs-pos-non-replaced-vrl-068.xht s71-abs-pos-non-replaced-vrl-068-ref.xht -fails == s71-abs-pos-non-replaced-vrl-070.xht s71-abs-pos-non-replaced-vrl-070-ref.xht -fails == s71-abs-pos-non-replaced-vrl-072.xht s71-abs-pos-non-replaced-vrl-072-ref.xht -fails == s71-abs-pos-non-replaced-vrl-074.xht s71-abs-pos-non-replaced-vrl-074-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-060.xht s71-abs-pos-non-replaced-vrl-060-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-062.xht s71-abs-pos-non-replaced-vrl-062-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-064.xht s71-abs-pos-non-replaced-vrl-064-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-066.xht s71-abs-pos-non-replaced-vrl-066-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-068.xht s71-abs-pos-non-replaced-vrl-068-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-070.xht s71-abs-pos-non-replaced-vrl-070-ref.xht +fuzzy-if(cocoaWidget,118,242) fuzzy-if(winWidget,116,240) == s71-abs-pos-non-replaced-vrl-072.xht s71-abs-pos-non-replaced-vrl-072-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-074.xht s71-abs-pos-non-replaced-vrl-074-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-076.xht s71-abs-pos-non-replaced-vrl-076-ref.xht -fails == s71-abs-pos-non-replaced-vrl-078.xht s71-abs-pos-non-replaced-vrl-078-ref.xht -fails == s71-abs-pos-non-replaced-vrl-080.xht s71-abs-pos-non-replaced-vrl-080-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-078.xht s71-abs-pos-non-replaced-vrl-078-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-080.xht s71-abs-pos-non-replaced-vrl-080-ref.xht fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-082.xht s71-abs-pos-non-replaced-vrl-082-ref.xht -fails == s71-abs-pos-non-replaced-vrl-084.xht s71-abs-pos-non-replaced-vrl-084-ref.xht -fails == s71-abs-pos-non-replaced-vrl-086.xht s71-abs-pos-non-replaced-vrl-086-ref.xht -fails == s71-abs-pos-non-replaced-vrl-088.xht s71-abs-pos-non-replaced-vrl-088-ref.xht -fails == s71-abs-pos-non-replaced-vrl-090.xht s71-abs-pos-non-replaced-vrl-090-ref.xht -fails == s71-abs-pos-non-replaced-vrl-092.xht s71-abs-pos-non-replaced-vrl-092-ref.xht -fails == s71-abs-pos-non-replaced-vrl-094.xht s71-abs-pos-non-replaced-vrl-094-ref.xht -fails == s71-abs-pos-non-replaced-vrl-096.xht s71-abs-pos-non-replaced-vrl-096-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-084.xht s71-abs-pos-non-replaced-vrl-084-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-086.xht s71-abs-pos-non-replaced-vrl-086-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-088.xht s71-abs-pos-non-replaced-vrl-088-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-090.xht s71-abs-pos-non-replaced-vrl-090-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-092.xht s71-abs-pos-non-replaced-vrl-092-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-094.xht s71-abs-pos-non-replaced-vrl-094-ref.xht +fuzzy-if(cocoaWidget,15,5) fuzzy-if(d2d,102,164) == s71-abs-pos-non-replaced-vrl-096.xht s71-abs-pos-non-replaced-vrl-096-ref.xht diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-003.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-003.xht index e9943203f6..8d310eeb01 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-003.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-003.xht @@ -12,7 +12,7 @@ - + @@ -44,38 +44,38 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -83,27 +83,27 @@ So: gives us: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 240px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-005.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-005.xht index 78aa6e4e82..492f8b8635 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-005.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-005.xht @@ -12,7 +12,7 @@ - + @@ -45,9 +45,7 @@ /* " If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" -" 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " @@ -55,21 +53,21 @@ If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' va So: - 0px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== @@ -77,13 +75,13 @@ So: gives us: - 0px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -91,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 240px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-007.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-007.xht index d99fe09eed..ab32348545 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-007.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-007.xht @@ -12,7 +12,7 @@ - + @@ -49,38 +49,38 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -88,27 +88,27 @@ So: gives us: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 240px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-009.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-009.xht index a6cb849c2b..0787fb621c 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-009.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-009.xht @@ -12,7 +12,7 @@ - + @@ -44,40 +44,40 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" - -" -3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + +1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block @@ -85,25 +85,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -And so computed top value must be 240px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-011.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-011.xht index 0e3145b915..7a5bf63c47 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-011.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-011.xht @@ -12,7 +12,7 @@ - + @@ -45,9 +45,7 @@ /* " If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" -" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " @@ -57,21 +55,21 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right: auto + 160px : right: auto: set to static position ===================== 320px : width of containing block @@ -79,11 +77,11 @@ gives us: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -91,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right: auto + 160px : right: auto: set to static position ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-013.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-013.xht index 3e685b254c..7d098c9175 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-013.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-013.xht @@ -12,7 +12,7 @@ - + @@ -48,40 +48,40 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" - -" -3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + +1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block @@ -89,25 +89,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -And so computed top value must be 240px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-015.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-015.xht index a6d0143ad0..d69a507aa7 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-015.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-015.xht @@ -12,7 +12,7 @@ - + @@ -44,37 +44,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -84,25 +83,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed bottom value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-017.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-017.xht index fe7ca0b701..b2408a91f8 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-017.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-017.xht @@ -55,11 +55,11 @@ So: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + @@ -77,9 +77,9 @@ gives us: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -93,7 +93,7 @@ gives us: ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-019.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-019.xht index a9c8425241..49a8929d83 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-019.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-019.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'height' are 'auto and 'bottom' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'height' are 'auto' and 'bottom' is not 'auto' @@ -12,7 +12,7 @@ - + @@ -34,7 +34,6 @@ height: 320px; position: relative; width: 320px; - } div#containing-block > span @@ -49,36 +48,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -88,25 +87,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-021.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-021.xht index f9921e63fb..1a0d096d23 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-021.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-021.xht @@ -12,7 +12,7 @@ - + @@ -44,36 +44,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -83,25 +83,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-023.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-023.xht index 41d7213738..b3e430fb05 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-023.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-023.xht @@ -34,7 +34,7 @@ color: green; left: auto; position: absolute; - right: auto; + right: 2em; width: auto; -ah-writing-mode: vertical-lr; -webkit-writing-mode: vertical-lr; @@ -44,8 +44,6 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. - 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " @@ -55,19 +53,19 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 160px : right ===================== @@ -77,11 +75,11 @@ gives us: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -89,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 160px : right ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-025.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-025.xht index 4b8cf20631..9b12885665 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-025.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-025.xht @@ -12,7 +12,7 @@ - + @@ -48,36 +48,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -87,25 +87,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-027.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-027.xht index c3d79ae997..df3640a6f6 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-027.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-027.xht @@ -4,15 +4,15 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom are 'auto' and 'height' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom' are 'auto' and 'height' is not 'auto' - + - + @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 160px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,35 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -gives us: - - 160px : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - (solve): bottom: auto - ===================== - 320px : height of containing block - -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-029.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-029.xht index 2a5b5e56a3..63ab36c275 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-029.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-029.xht @@ -51,13 +51,13 @@ So: - 160px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,21 +65,21 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block gives us: - 160px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -87,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 80px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-031.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-031.xht index 7acfb2d4b6..209aec7462 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-031.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-031.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom are 'auto' and 'height' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom' are 'auto' and 'height' is not 'auto' @@ -12,7 +12,7 @@ - + @@ -48,23 +48,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 160px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -76,35 +78,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -gives us: - - 160px : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - (solve): bottom: auto - ===================== - 320px : height of containing block - -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-033.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-033.xht index f1520328f3..5e4be1bf07 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-033.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-033.xht @@ -12,7 +12,7 @@ - + @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,35 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 160px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -gives us: - - (solve) : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - 160px : bottom: auto - ===================== - 320px : height of containing block - -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-035.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-035.xht index f72648cd98..5ae49beb38 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-035.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-035.xht @@ -53,11 +53,11 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,35 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 160px : right: auto ===================== 320px : width of containing block -gives us: - - (solve) : left: auto - + - 0px : margin-left: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : width - + - 0px : padding-right - + - 0px : border-right-width - + - 0px : margin-right: auto - + - 160px : right: auto - ===================== - 320px : width of containing block - -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-037.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-037.xht index 6c1d1a205b..da548931e0 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-037.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-037.xht @@ -12,7 +12,7 @@ - + @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,35 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 160px : bottom + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -gives us: - - (solve) : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - 160px : bottom - ===================== - 320px : height of containing block - -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-039.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-039.xht index 25840ce04d..15570b21a0 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-039.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-039.xht @@ -12,7 +12,7 @@ - + @@ -43,38 +43,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -82,25 +83,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-041.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-041.xht index 460ef7a98b..fcc17fe5da 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-041.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-041.xht @@ -54,21 +54,21 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block @@ -76,7 +76,7 @@ gives us: 80px : left + - 0px : margin-left: auto + 0px : margin-left + 0px : border-top-width + @@ -88,13 +88,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-043.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-043.xht index 0b54fb590d..11c90eaa37 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-043.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-043.xht @@ -12,7 +12,7 @@ - + @@ -47,38 +47,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -86,25 +87,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-045.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-045.xht index 0b202e6114..090e26a869 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-045.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-045.xht @@ -12,7 +12,7 @@ - + @@ -43,38 +43,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -82,25 +83,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-047.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-047.xht index a5426ca7b4..9cafed71da 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-047.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-047.xht @@ -43,7 +43,6 @@ } /* - " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " @@ -54,21 +53,21 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block @@ -76,11 +75,11 @@ gives us: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -88,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-049.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-049.xht index 62cecbb3d5..044c563c25 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-049.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-049.xht @@ -12,7 +12,7 @@ - + @@ -47,36 +47,37 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 80px: top + 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -84,27 +85,27 @@ So: gives us: - 80px: top + 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-051.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-051.xht index 275a3f051e..a038a9003f 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-051.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-051.xht @@ -12,7 +12,7 @@ - + @@ -43,42 +43,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-053.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-053.xht index afa02759f5..973798a09e 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-053.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-053.xht @@ -53,25 +53,25 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - 80px : width: auto + 80px : width + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed left value must be 160px; +And so computed left value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-055.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-055.xht index 952292465c..d0da9d3c27 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-055.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-055.xht @@ -12,7 +12,7 @@ - + @@ -47,41 +47,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-057.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-057.xht index cf7af79afd..e951bafb02 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-057.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-057.xht @@ -43,41 +43,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-059.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-059.xht index 574c1d8f70..d2ea5fc064 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-059.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-059.xht @@ -53,11 +53,11 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed left value must be 160px; +And so computed left value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-061.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-061.xht index ddc3cb11f8..45c8e0dc65 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-061.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-061.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,15 +77,16 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ + ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-063.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-063.xht index bafb7d106a..600a845234 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-063.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-063.xht @@ -12,7 +12,7 @@ - + @@ -34,32 +34,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -88,7 +90,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-065.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-065.xht index 5fd5d050c6..ecfd274cb5 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-065.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-065.xht @@ -30,8 +30,8 @@ div#containing-block > span { - background-color: red; - color: green; + background-color: green; + height: 1em; left: 2em; position: absolute; right: 1em; @@ -53,11 +53,11 @@ So: 160px : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + (solve) : width: auto + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right: auto ===================== 320px : width of containing block -And so computed width value must be 80px; +And so computed width value must be 80px . */ ]]> @@ -82,7 +82,7 @@ And so computed width value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-067.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-067.xht index 60ffa8047b..f84cb9075a 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-067.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-067.xht @@ -38,32 +38,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -92,7 +94,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-069.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-069.xht index 116d3759bb..150f7dbf63 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-069.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-069.xht @@ -34,32 +34,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -88,7 +90,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-071.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-071.xht index 842c03d946..b92e70f1ef 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-071.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-071.xht @@ -30,8 +30,8 @@ div#containing-block > span { - background-color: red; - color: green; + background-color: green; + height: 1em; left: 2em; position: absolute; right: 1em; @@ -53,11 +53,11 @@ So: 160px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + (solve) : width: auto + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed width value must be 80px; +And so computed width value must be 80px . */ ]]> @@ -82,7 +82,7 @@ And so computed width value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-073.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-073.xht index 00162c62b5..844d3dfde1 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-073.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-073.xht @@ -12,7 +12,7 @@ - + @@ -38,32 +38,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -92,7 +94,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-075.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-075.xht index e31044360c..34afe69305 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-075.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-075.xht @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-077.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-077.xht index aa36898144..7680949aec 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-077.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-077.xht @@ -53,11 +53,11 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-079.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-079.xht index ce862e1fe8..689863c43f 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-079.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-079.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-081.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-081.xht index cc3ee0476a..4605260c72 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-081.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-081.xht @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-083.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-083.xht index 0bca6edbcc..f98e853202 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-083.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-083.xht @@ -53,11 +53,11 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-085.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-085.xht index 0872461b9d..774e54dbc5 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-085.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-085.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-087.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-087.xht index 99b6572b5a..c12bda239d 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-087.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-087.xht @@ -46,20 +46,22 @@ /* " -If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 160px : top + 160px : top + 0px : margin-top + @@ -67,7 +69,7 @@ So: + 0px : padding-top + - 80px : height + 80px : height + 0px : padding-bottom + @@ -81,7 +83,7 @@ So: gives us: - 160px : top + 160px : top + 0px : margin-top + @@ -89,7 +91,7 @@ gives us: + 0px : padding-top + - 80px : height + 80px : height + 0px : padding-bottom + @@ -101,7 +103,7 @@ gives us: ===================== 320px : height of containing block -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-089.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-089.xht index f72441b996..c5367dbbec 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-089.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-089.xht @@ -91,11 +91,11 @@ gives us: + 0px : margin-right + - (solve) : right: auto + (solve) : right ===================== 320px : width of containing block -And so computed right value must be 80px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-091.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-091.xht index ee22d9b057..0217c3d488 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-091.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-091.xht @@ -50,16 +50,18 @@ /* " -If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -105,7 +107,7 @@ gives us: ===================== 320px : height of containing block -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-093.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-093.xht index c5b8d0c5e6..97d9ea47e4 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-093.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-093.xht @@ -45,17 +45,19 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -101,7 +103,7 @@ gives us: ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-095.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-095.xht index fcc8308df6..d8f913f9dd 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-095.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-095.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'left', 'width' and 'right' are not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'left', 'width' and 'right' are not 'auto' (overconstrained) @@ -57,9 +57,9 @@ So: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -79,9 +79,9 @@ gives us: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -89,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 160px : right ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-097.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-097.xht index 1f0a2292f3..1c6055fbb5 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-097.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vlr-097.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'top', 'height' and 'bottom' are not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'top', 'height' and 'bottom' are not 'auto' (overconstrained) @@ -49,17 +49,19 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -105,7 +107,7 @@ gives us: ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-002.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-002.xht index 297b4c7098..b8f23b4110 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-002.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-002.xht @@ -12,7 +12,7 @@ - + @@ -44,38 +44,38 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -83,27 +83,27 @@ So: gives us: - 0px : top: auto + 160px : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 240px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-004.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-004.xht index 05d6e2369a..a261ae81a1 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-004.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-004.xht @@ -9,11 +9,10 @@ - - + @@ -46,9 +45,7 @@ /* " If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" -" 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " @@ -56,21 +53,21 @@ If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' va So: - 0px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== @@ -78,13 +75,13 @@ So: gives us: - 0px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -92,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 240px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-006.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-006.xht index 74f9462d0e..80e097a700 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-006.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-006.xht @@ -12,7 +12,7 @@ - + @@ -48,38 +48,38 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -87,27 +87,27 @@ So: gives us: - 0px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 240px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-008.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-008.xht index bf0cba59a6..b24e2703b3 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-008.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-008.xht @@ -12,7 +12,7 @@ - + @@ -44,40 +44,40 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" - -" -3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + +1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block @@ -85,25 +85,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -And so computed top value must be 240px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-010.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-010.xht index 53a667d6e0..e9afe99c09 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-010.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-010.xht @@ -12,7 +12,7 @@ - + @@ -45,9 +45,7 @@ /* " If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" -" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " @@ -57,21 +55,21 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right: auto + 160px : right: auto: set to static position ===================== 320px : width of containing block @@ -79,11 +77,11 @@ gives us: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -91,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right: auto + 160px : right: auto: set to static position ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-012.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-012.xht index 09b15a8ccb..0deb425654 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-012.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-012.xht @@ -9,10 +9,10 @@ - + - + @@ -48,40 +48,40 @@ /* " -If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. -" - -" -3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. + +1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block @@ -89,25 +89,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 0px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -And so computed top value must be 240px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-014.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-014.xht index 86cc97a90d..b8ae0f1c77 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-014.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-014.xht @@ -12,7 +12,7 @@ - + @@ -44,37 +44,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -84,25 +83,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-016.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-016.xht index 2e0c184439..fa57900a56 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-016.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-016.xht @@ -55,11 +55,11 @@ So: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + @@ -77,9 +77,9 @@ gives us: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -93,7 +93,7 @@ gives us: ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-018.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-018.xht index 96407d95cd..da299956d2 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-018.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-018.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'height' are 'auto and 'bottom' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'height' are 'auto' and 'bottom' is not 'auto' @@ -12,7 +12,7 @@ - + @@ -48,36 +48,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -87,25 +87,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-020.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-020.xht index ac4cb14d81..a49d254455 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-020.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-020.xht @@ -12,7 +12,7 @@ - + @@ -44,36 +44,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -83,25 +83,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-022.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-022.xht index 0f742e7d74..29fbe27c52 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-022.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-022.xht @@ -44,8 +44,6 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. - 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " @@ -55,21 +53,21 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right + 160px : right ===================== 320px : width of containing block @@ -77,11 +75,11 @@ gives us: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -89,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right + 160px : right ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-024.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-024.xht index d6d6828589..d55f12573e 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-024.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-024.xht @@ -12,7 +12,7 @@ - + @@ -48,36 +48,36 @@ /* " -set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== @@ -87,25 +87,25 @@ gives us: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 160px : bottom ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-026.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-026.xht index 0ba56f48bd..df66a1e66a 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-026.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-026.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom are 'auto' and 'height' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom' are 'auto' and 'height' is not 'auto' @@ -12,7 +12,7 @@ - + @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 160px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,35 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -gives us: - - 160px : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - (solve) : bottom: auto - ===================== - 320px : height of containing block - -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-028.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-028.xht index 96567ca5bf..0a2cea204e 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-028.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-028.xht @@ -51,13 +51,13 @@ So: - 160px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,21 +65,21 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block gives us: - 160px : left: auto + 160px : left: auto: set to static position + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -87,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 80px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-030.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-030.xht index f89585eb4d..df20ebeee9 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-030.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-030.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom are 'auto' and 'height' is not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: ltr' and 'top' and 'bottom' are 'auto' and 'height' is not 'auto' @@ -12,7 +12,7 @@ - + @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 160px : top: auto + 160px : top: auto: set to static position + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,35 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -gives us: - - 160px : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - (solve): bottom: auto - ===================== - 320px : height of containing block - -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-032.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-032.xht index 6847a29b43..c721a93bed 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-032.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-032.xht @@ -9,10 +9,10 @@ - + - + @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,35 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 160px : bottom: auto + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -gives us: - - (solve) : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - 160px : bottom: auto - ===================== - 320px : height of containing block - -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-034.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-034.xht index 7c57819813..f0fb045397 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-034.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-034.xht @@ -53,11 +53,11 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,35 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 160px : right: auto + 160px : right: auto: set to static position ===================== 320px : width of containing block -gives us: - - (solve) : left: auto - + - 0px : margin-left: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : width - + - 0px : padding-right - + - 0px : border-right-width - + - 0px : margin-right: auto - + - 160px : right: auto - ===================== - 320px : width of containing block - -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-036.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-036.xht index b1626955ab..c4569c5819 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-036.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-036.xht @@ -12,7 +12,7 @@ - + @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,35 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - 160px : bottom + 160px : bottom: auto: set to static position ===================== 320px : height of containing block -gives us: - - (solve) : top: auto - + - 0px : margin-top: auto - + - 0px : border-top-width - + - 0px : padding-top - + - 80px : height - + - 0px : padding-bottom - + - 0px : border-bottom-width - + - 0px : margin-bottom: auto - + - 160px : bottom - ===================== - 320px : height of containing block - -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-038.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-038.xht index f45c6200ac..62e9059a64 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-038.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-038.xht @@ -12,7 +12,7 @@ - + @@ -43,38 +43,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -82,25 +83,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-040.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-040.xht index fee04dd2b8..13ffffc5bf 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-040.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-040.xht @@ -43,7 +43,6 @@ } /* - " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " @@ -54,21 +53,21 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block @@ -76,7 +75,7 @@ gives us: 80px : left + - 0px : margin-left: auto + 0px : margin-left + 0px : border-top-width + @@ -88,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-042.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-042.xht index 567adf3321..a20a1c8b6c 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-042.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-042.xht @@ -12,7 +12,7 @@ - + @@ -47,38 +47,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -86,25 +87,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-044.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-044.xht index 2eb2e576bf..9dc62d8942 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-044.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-044.xht @@ -12,7 +12,7 @@ - + @@ -43,38 +43,39 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block @@ -82,25 +83,25 @@ gives us: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + - (solve): bottom: auto + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-046.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-046.xht index efb42c82ac..27d388d8e4 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-046.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-046.xht @@ -43,7 +43,6 @@ } /* - " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " @@ -54,21 +53,21 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - (shrink-to-fit) : width: auto + (shrink-to-fit) : width: auto + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block @@ -76,11 +75,11 @@ gives us: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : (shrink-to-fit) : width: auto + @@ -88,13 +87,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - (solve): right: auto + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-048.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-048.xht index f23a6b0749..3bf09d48e5 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-048.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-048.xht @@ -12,7 +12,7 @@ - + @@ -47,36 +47,37 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: - 80px: top + 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - (shrink-to-fit) : height: auto + (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== @@ -84,29 +85,30 @@ So: gives us: - 80px: top + 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : (shrink-to-fit) : height: auto + 80px : (based on the content) : height: auto + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ + ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-050.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-050.xht index 733cddb1ea..44a10f668d 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-050.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-050.xht @@ -43,42 +43,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-052.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-052.xht index 7cd717ff3a..2ef2c95cf1 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-052.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-052.xht @@ -53,25 +53,25 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + - 80px : width: auto + 80px : width + 0px : padding-right + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed left value must be 160px; +And so computed left value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-054.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-054.xht index 7d34d371f3..e2baabfd34 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-054.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-054.xht @@ -12,7 +12,7 @@ - + @@ -47,41 +47,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-056.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-056.xht index 11924dea6c..00d2d7223f 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-056.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-056.xht @@ -43,41 +43,43 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + 0px : padding-top + - 80px : height: auto + 80px : height + 0px : padding-bottom + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-058.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-058.xht index e17fe78bac..81392b524b 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-058.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-058.xht @@ -53,11 +53,11 @@ So: (solve) : left: auto + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed left value must be 160px; +And so computed left value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-060.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-060.xht index f0329c2ac7..ff2f8bc7ea 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-060.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-060.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: (solve) : top: auto + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,15 +77,16 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed top value must be 160px; +And so computed top value must be 160px . */ + ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-062.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-062.xht index dd678065e6..2fbfbfa533 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-062.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-062.xht @@ -12,7 +12,7 @@ - + @@ -34,32 +34,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -88,7 +90,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-064.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-064.xht index 4c8c125dc1..6b747031bd 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-064.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-064.xht @@ -12,7 +12,7 @@ - + @@ -30,8 +30,8 @@ div#containing-block > span { - background-color: red; - color: green; + background-color: green; + height: 1em; left: 2em; position: absolute; right: 1em; @@ -51,13 +51,13 @@ So: - 160px : left: auto + 160px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + (solve) : width: auto + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + - 80px : right: auto + 80px : right ===================== 320px : width of containing block -And so computed width value must be 80px; +And so computed width value must be 80px . */ ]]> @@ -82,7 +82,7 @@ And so computed width value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-066.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-066.xht index f7e0f60722..1c5a37cebe 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-066.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-066.xht @@ -38,32 +38,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -92,7 +94,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-068.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-068.xht index 7c8d4445d8..071ce34d75 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-068.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-068.xht @@ -34,32 +34,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -88,7 +90,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-070.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-070.xht index aeabf6fdfd..469b3c4f89 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-070.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-070.xht @@ -30,8 +30,8 @@ div#containing-block > span { - background-color: red; - color: green; + background-color: green; + height: 1em; left: 2em; position: absolute; right: 1em; @@ -53,11 +53,11 @@ So: 160px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + (solve) : width: auto + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 80px : right ===================== 320px : width of containing block -And so computed width value must be 80px; +And so computed width value must be 80px . */ ]]> @@ -82,7 +82,7 @@ And so computed width value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-072.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-072.xht index 4487233770..1092601e47 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-072.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-072.xht @@ -12,7 +12,7 @@ - + @@ -38,32 +38,34 @@ div#containing-block > span { - background-color: red; + background-color: green; bottom: 1em; - color: green; height: auto; position: absolute; top: 2em; + width: 1em; } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 160px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + 80px : bottom ===================== 320px : height of containing block -And so computed height value must be 80px; +And so computed height value must be 80px . */ ]]> @@ -92,7 +94,7 @@ And so computed height value must be 80px;

Image download support must be enabled

-
1 2 34X
+
1 2 34
\ No newline at end of file diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-074.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-074.xht index c74527faff..5e9d9588d7 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-074.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-074.xht @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-076.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-076.xht index e2f05a25ee..b64c33c910 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-076.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-076.xht @@ -53,11 +53,11 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-078.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-078.xht index 20c742d1f2..824f438dcf 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-078.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-078.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-080.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-080.xht index 1449cb8367..ed644247c4 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-080.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-080.xht @@ -43,23 +43,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -71,13 +73,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-082.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-082.xht index 8101222985..22e8ddfe68 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-082.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-082.xht @@ -53,11 +53,11 @@ So: 80px : left + - 0px : margin-left: auto + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -65,13 +65,13 @@ So: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + (solve) : right: auto ===================== 320px : width of containing block -And so computed right value must be 160px; +And so computed right value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-084.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-084.xht index 163a594ff6..9a4129279b 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-084.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-084.xht @@ -47,23 +47,25 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: 80px : top + - 0px : margin-top: auto + 0px : margin-top + 0px : border-top-width + @@ -75,13 +77,13 @@ So: + 0px : border-bottom-width + - 0px : margin-bottom: auto + 0px : margin-bottom + (solve) : bottom: auto ===================== 320px : height of containing block -And so computed bottom value must be 160px; +And so computed bottom value must be 160px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-086.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-086.xht index 2f485caca9..6b45920bd0 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-086.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-086.xht @@ -46,16 +46,18 @@ /* " -If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -101,7 +103,7 @@ gives us: ===================== 320px : height of containing block -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-088.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-088.xht index 6d26c4d661..2c959917dc 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-088.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-088.xht @@ -57,9 +57,9 @@ So: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -79,9 +79,9 @@ gives us: + 0px : margin-left + - 0px : border-top-width + 0px : border-left-width + - 0px : padding-top + 0px : padding-left + 80px : width + @@ -91,11 +91,11 @@ gives us: + 0px : margin-right + - (solve) : right: auto + (solve) : right ===================== 320px : width of containing block -And so computed right value must be 80px; +And so computed right value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-090.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-090.xht index 858fca40a7..e3671d95c8 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-090.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-090.xht @@ -50,16 +50,18 @@ /* " -If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. -" - -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. " 7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + +" +If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. +" + +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -105,7 +107,7 @@ gives us: ===================== 320px : height of containing block -And so computed bottom value must be 80px; +And so computed bottom value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-092.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-092.xht index f4516a7bf8..ff547dc1c8 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-092.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-092.xht @@ -45,17 +45,19 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -101,7 +103,7 @@ gives us: ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-094.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-094.xht index 1ef102f113..581b2962d2 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-094.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-094.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'left', 'width' and 'right' are not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'left', 'width' and 'right' are not 'auto' (overconstrained) @@ -89,13 +89,13 @@ gives us: + 0px : border-right-width + - 0px : margin-right: auto + 0px : margin-right + 160px : right ===================== 320px : width of containing block -And so computed left value must be 80px; +And so computed left value must be 80px . */ ]]> diff --git a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-096.xht b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-096.xht index ede2cd4933..9d426e20d4 100644 --- a/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-096.xht +++ b/layout/reftests/writing-mode/abspos/s71-abs-pos-non-replaced-vrl-096.xht @@ -4,7 +4,7 @@ - CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'top', 'height' and 'bottom' are not 'auto' + CSS Writing Modes Test: absolutely positioned non-replaced element - 'direction: rtl' and 'top', 'height' and 'bottom' are not 'auto' (overconstrained) @@ -49,17 +49,19 @@ } /* +" +Layout calculation rules (such as those in CSS2.1, Section 10.3) that apply to the horizontal dimension in horizontal writing modes instead apply to the vertical dimension in vertical writing modes. +" +7.1 Principles of Layout in Vertical Writing Modes +http://www.w3.org/TR/css-writing-modes-3/#vertical-layout + +So here, *-top and *-bottom properties are input into the §10.3.7 algorithms where *-top properties refer to *-left properties in the layout rules and where *-bottom properties refer to *-right properties in the layout rules. + " If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value. If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value. " -'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block - -" -Layout rules that refer to the *-left and *-right box properties (border, margin, padding) use *-top and *-bottom instead, and vice versa. Which side of the box the property applies to doesn't change: only which values are inputs to which layout calculations changes. -" -7.1 Principles of Layout in Vertical Writing Modes -http://www.w3.org/TR/css-writing-modes-3/#logical-direction-layout +'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block So: @@ -105,7 +107,7 @@ gives us: ===================== 320px : height of containing block -And so computed top value must be 80px; +And so computed top value must be 80px . */ ]]> diff --git a/layout/style/forms.css b/layout/style/forms.css index a9567395bb..4b4ee6e39f 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -207,7 +207,6 @@ textarea:-moz-read-write { } select { - writing-mode: horizontal-tb !important; /* XXX remove when bug 1112954 is fixed */ margin: 0; border-color: ThreeDFace; background-color: -moz-Combobox; diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 0b3f201cb1..fe611f6bb2 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -3345,7 +3345,7 @@ CSS_PROP_DISPLAY( transform_box, TransformBox, CSS_PROPERTY_PARSE_VALUE, - "svg.transform-origin.enabled", + "svg.transform-box.enabled", VARIANT_HK, kTransformBoxKTable, CSS_PROP_NO_OFFSET, diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 747c2925ba..14eb7f8fa0 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -1831,7 +1831,8 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, already_AddRefed nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, - nsStyleContext* aParentContext) + nsStyleContext* aParentContext, + uint32_t aFlags) { NS_ENSURE_FALSE(mInShutdown, nullptr); @@ -1869,7 +1870,7 @@ nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, return GetContext(aParentContext, ruleWalker.CurrentNode(), nullptr, aPseudoTag, nsCSSPseudoElements::ePseudo_AnonBox, - nullptr, eNoFlags); + nullptr, aFlags); } #ifdef MOZ_XUL diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 713dc218ee..ed0161cbd8 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -192,10 +192,30 @@ class nsStyleSet TreeMatchContext& aTreeMatchContext, mozilla::dom::Element* aPseudoElement = nullptr); + /** + * Bit-flags that can be passed to ResolveAnonymousBoxStyle and GetContext + * in their parameter 'aFlags'. + */ + enum { + eNoFlags = 0, + eIsLink = 1 << 0, + eIsVisitedLink = 1 << 1, + eDoAnimation = 1 << 2, + + // Indicates that we should skip the flex/grid item specific chunk of + // ApplyStyleFixups(). This is useful if our parent has "display: flex" + // or "display: grid" but we can tell we're not going to honor that (e.g. if + // it's the outer frame of a button widget, and we're the inline frame for + // the button's label). + eSkipParentDisplayBasedStyleFixup = 1 << 3 + }; + // Get a style context for an anonymous box. aPseudoTag is the - // pseudo-tag to use and must be non-null. + // pseudo-tag to use and must be non-null. aFlags will be forwarded + // to a GetContext call internally. already_AddRefed - ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext); + ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext, + uint32_t aFlags = eNoFlags); #ifdef MOZ_XUL // Get a style context for a XUL tree pseudo. aPseudoTag is the @@ -442,23 +462,6 @@ class nsStyleSet nsCSSPseudoElements::Type aPseudoType, nsRestyleHint aReplacements); - /** - * Bit-flags that can be passed to GetContext() in its parameter 'aFlags'. - */ - enum { - eNoFlags = 0, - eIsLink = 1 << 0, - eIsVisitedLink = 1 << 1, - eDoAnimation = 1 << 2, - - // Indicates that we should skip the flex/grid item specific chunk of - // ApplyStyleFixups(). This is useful if our parent has "display: flex" - // or "display: grid" but we can tell we're not going to honor that (e.g. if - // it's the outer frame of a button widget, and we're the inline frame for - // the button's label). - eSkipParentDisplayBasedStyleFixup = 1 << 3 - }; - already_AddRefed GetContext(nsStyleContext* aParentContext, nsRuleNode* aRuleNode, diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp index e8abbe7df2..75e8c58e1f 100644 --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -52,11 +52,12 @@ TransformReferenceBox::EnsureDimensionsAreCached() mIsCached = true; if (mFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) { - if (!nsLayoutUtils::SVGTransformOriginEnabled()) { + if (!nsLayoutUtils::SVGTransformBoxEnabled()) { mX = -mFrame->GetPosition().x; mY = -mFrame->GetPosition().y; - mWidth = 0; - mHeight = 0; + Size contextSize = nsSVGUtils::GetContextSize(mFrame); + mWidth = nsPresContext::CSSPixelsToAppUnits(contextSize.width); + mHeight = nsPresContext::CSSPixelsToAppUnits(contextSize.height); } else if (mFrame->StyleDisplay()->mTransformBox == NS_STYLE_TRANSFORM_BOX_FILL_BOX) { @@ -82,7 +83,7 @@ TransformReferenceBox::EnsureDimensionsAreCached() NS_STYLE_TRANSFORM_BOX_BORDER_BOX, "Unexpected value for 'transform-box'"); // Percentages in transforms resolve against the width/height of the - // nearest viewport (or it's viewBox if one is applied), and the + // nearest viewport (or its viewBox if one is applied), and the // transform is relative to {0,0} in current user space. mX = -mFrame->GetPosition().x; mY = -mFrame->GetPosition().y; diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index de5e9a5ce3..245e4c3bb8 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -5341,7 +5341,7 @@ if (SpecialPowers.getBoolPref("svg.paint-order.enabled")) { }; } -if (SpecialPowers.getBoolPref("svg.transform-origin.enabled")) { +if (SpecialPowers.getBoolPref("svg.transform-box.enabled")) { gCSSProperties["transform-box"] = { domProp: "transformBox", inherited: false, diff --git a/layout/style/test/test_computed_style_prefs.html b/layout/style/test/test_computed_style_prefs.html index 98699b5389..68d05405df 100644 --- a/layout/style/test/test_computed_style_prefs.html +++ b/layout/style/test/test_computed_style_prefs.html @@ -75,7 +75,7 @@ var gProps = { "layout.css.isolation.enabled": [ "isolation"], "layout.css.masking.enabled": ["mask-type"], "layout.css.touch_action.enabled": ["touch-action"], - "svg.transform-origin.enabled": ["transform-box"] + "svg.transform-box.enabled": ["transform-box"] }; var gCS = getComputedStyle(document.body, ""); diff --git a/layout/tables/celldata.h b/layout/tables/celldata.h index 255a472a02..c369eaf8aa 100644 --- a/layout/tables/celldata.h +++ b/layout/tables/celldata.h @@ -8,6 +8,7 @@ #include "nsISupports.h" #include "nsCoord.h" #include "mozilla/gfx/Types.h" +#include "mozilla/WritingModes.h" #include class nsTableCellFrame; @@ -179,7 +180,7 @@ static inline nscoord BC_BORDER_END_HALF_COORD(int32_t p2t, BCPixelSize px) { return BC_BORDER_END_HALF(px) * p2t; } -// BCData stores the top and left border info and the corner connecting the two. +// BCData stores the bstart and istart border info and the corner connecting the two. class BCData { public: @@ -187,49 +188,49 @@ public: ~BCData(); - nscoord GetLeftEdge(BCBorderOwner& aOwner, - bool& aStart) const; + nscoord GetIStartEdge(BCBorderOwner& aOwner, + bool& aStart) const; - void SetLeftEdge(BCBorderOwner aOwner, - nscoord aSize, - bool aStart); + void SetIStartEdge(BCBorderOwner aOwner, + nscoord aSize, + bool aStart); - nscoord GetTopEdge(BCBorderOwner& aOwner, - bool& aStart) const; + nscoord GetBStartEdge(BCBorderOwner& aOwner, + bool& aStart) const; - void SetTopEdge(BCBorderOwner aOwner, - nscoord aSize, - bool aStart); + void SetBStartEdge(BCBorderOwner aOwner, + nscoord aSize, + bool aStart); - BCPixelSize GetCorner(mozilla::Side& aCornerOwner, - bool& aBevel) const; + BCPixelSize GetCorner(mozilla::LogicalSide& aCornerOwner, + bool& aBevel) const; - void SetCorner(BCPixelSize aSubSize, - mozilla::Side aOwner, - bool aBevel); + void SetCorner(BCPixelSize aSubSize, + mozilla::LogicalSide aOwner, + bool aBevel); - bool IsLeftStart() const; + bool IsIStartStart() const; - void SetLeftStart(bool aValue); + void SetIStartStart(bool aValue); - bool IsTopStart() const; + bool IsBStartStart() const; - void SetTopStart(bool aValue); + void SetBStartStart(bool aValue); protected: - BCPixelSize mLeftSize; // size in pixels of left border - BCPixelSize mTopSize; // size in pixels of top border + BCPixelSize mIStartSize; // size in pixels of iStart border + BCPixelSize mBStartSize; // size in pixels of bStart border BCPixelSize mCornerSubSize; // size of the largest border not in the // dominant plane (for example, if corner is - // owned by the segment to its top or bottom, + // owned by the segment to its bStart or bEnd, // then the size is the max of the border - // sizes of the segments to its left or right. - unsigned mLeftOwner: 4; // owner of left border - unsigned mTopOwner: 4; // owner of top border - unsigned mLeftStart: 1; // set if this is the start of a vertical border segment - unsigned mTopStart: 1; // set if this is the start of a horizontal border segment - unsigned mCornerSide: 2; // mozilla::Side of the owner of the upper left corner relative to the corner + // sizes of the segments to its iStart or iEnd. + unsigned mIStartOwner: 4; // owner of iStart border + unsigned mBStartOwner: 4; // owner of bStart border + unsigned mIStartStart: 1; // set if this is the start of a block-dir border segment + unsigned mBStartStart: 1; // set if this is the start of an inline-dir border segment + unsigned mCornerSide: 2; // LogicalSide of the owner of the bStart-iStart corner relative to the corner unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted). }; @@ -402,10 +403,10 @@ inline void CellData::SetOverlap(bool aOverlap) inline BCData::BCData() { - mLeftOwner = mTopOwner = eCellOwner; - mLeftStart = mTopStart = 1; - mLeftSize = mCornerSubSize = mTopSize = 0; - mCornerSide = NS_SIDE_TOP; + mIStartOwner = mBStartOwner = eCellOwner; + mIStartStart = mBStartStart = 1; + mIStartSize = mCornerSubSize = mBStartSize = 0; + mCornerSide = mozilla::eLogicalSideBStart; mCornerBevel = false; } @@ -413,77 +414,77 @@ inline BCData::~BCData() { } -inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner, - bool& aStart) const +inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner, + bool& aStart) const { - aOwner = (BCBorderOwner)mLeftOwner; - aStart = (bool)mLeftStart; + aOwner = (BCBorderOwner)mIStartOwner; + aStart = (bool)mIStartStart; - return (nscoord)mLeftSize; + return (nscoord)mIStartSize; } -inline void BCData::SetLeftEdge(BCBorderOwner aOwner, - nscoord aSize, - bool aStart) +inline void BCData::SetIStartEdge(BCBorderOwner aOwner, + nscoord aSize, + bool aStart) { - mLeftOwner = aOwner; - mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; - mLeftStart = aStart; + mIStartOwner = aOwner; + mIStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; + mIStartStart = aStart; } -inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner, - bool& aStart) const +inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner, + bool& aStart) const { - aOwner = (BCBorderOwner)mTopOwner; - aStart = (bool)mTopStart; + aOwner = (BCBorderOwner)mBStartOwner; + aStart = (bool)mBStartStart; - return (nscoord)mTopSize; + return (nscoord)mBStartSize; } -inline void BCData::SetTopEdge(BCBorderOwner aOwner, - nscoord aSize, - bool aStart) +inline void BCData::SetBStartEdge(BCBorderOwner aOwner, + nscoord aSize, + bool aStart) { - mTopOwner = aOwner; - mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; - mTopStart = aStart; + mBStartOwner = aOwner; + mBStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; + mBStartStart = aStart; } -inline BCPixelSize BCData::GetCorner(mozilla::Side& aOwnerSide, - bool& aBevel) const +inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide, + bool& aBevel) const { - aOwnerSide = mozilla::Side(mCornerSide); + aOwnerSide = mozilla::LogicalSide(mCornerSide); aBevel = (bool)mCornerBevel; return mCornerSubSize; } -inline void BCData::SetCorner(BCPixelSize aSubSize, - mozilla::Side aOwnerSide, - bool aBevel) +inline void BCData::SetCorner(BCPixelSize aSubSize, + mozilla::LogicalSide aOwnerSide, + bool aBevel) { mCornerSubSize = aSubSize; mCornerSide = aOwnerSide; mCornerBevel = aBevel; } -inline bool BCData::IsLeftStart() const +inline bool BCData::IsIStartStart() const { - return (bool)mLeftStart; + return (bool)mIStartStart; } -inline void BCData::SetLeftStart(bool aValue) +inline void BCData::SetIStartStart(bool aValue) { - mLeftStart = aValue; + mIStartStart = aValue; } -inline bool BCData::IsTopStart() const +inline bool BCData::IsBStartStart() const { - return (bool)mTopStart; + return (bool)mBStartStart; } -inline void BCData::SetTopStart(bool aValue) +inline void BCData::SetBStartStart(bool aValue) { - mTopStart = aValue; + mBStartStart = aValue; } #endif diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp index 5482a2d689..7bcebeaa99 100644 --- a/layout/tables/nsCellMap.cpp +++ b/layout/tables/nsCellMap.cpp @@ -93,48 +93,48 @@ nsTableCellMap::~nsTableCellMap() } if (mBCInfo) { - DeleteRightBottomBorders(); + DeleteIEndBEndBorders(); delete mBCInfo; } } -// Get the bcData holding the border segments of the right edge of the table +// Get the bcData holding the border segments of the iEnd edge of the table BCData* -nsTableCellMap::GetRightMostBorder(int32_t aRowIndex) +nsTableCellMap::GetIEndMostBorder(int32_t aRowIndex) { if (!mBCInfo) ABORT1(nullptr); - int32_t numRows = mBCInfo->mRightBorders.Length(); + int32_t numRows = mBCInfo->mIEndBorders.Length(); if (aRowIndex < numRows) { - return &mBCInfo->mRightBorders.ElementAt(aRowIndex); + return &mBCInfo->mIEndBorders.ElementAt(aRowIndex); } - mBCInfo->mRightBorders.SetLength(aRowIndex+1); - return &mBCInfo->mRightBorders.ElementAt(aRowIndex); + mBCInfo->mIEndBorders.SetLength(aRowIndex+1); + return &mBCInfo->mIEndBorders.ElementAt(aRowIndex); } -// Get the bcData holding the border segments of the bottom edge of the table +// Get the bcData holding the border segments of the bEnd edge of the table BCData* -nsTableCellMap::GetBottomMostBorder(int32_t aColIndex) +nsTableCellMap::GetBEndMostBorder(int32_t aColIndex) { if (!mBCInfo) ABORT1(nullptr); - int32_t numCols = mBCInfo->mBottomBorders.Length(); + int32_t numCols = mBCInfo->mBEndBorders.Length(); if (aColIndex < numCols) { - return &mBCInfo->mBottomBorders.ElementAt(aColIndex); + return &mBCInfo->mBEndBorders.ElementAt(aColIndex); } - mBCInfo->mBottomBorders.SetLength(aColIndex+1); - return &mBCInfo->mBottomBorders.ElementAt(aColIndex); + mBCInfo->mBEndBorders.SetLength(aColIndex+1); + return &mBCInfo->mBEndBorders.ElementAt(aColIndex); } -// delete the borders corresponding to the right and bottom edges of the table +// delete the borders corresponding to the iEnd and bEnd edges of the table void -nsTableCellMap::DeleteRightBottomBorders() +nsTableCellMap::DeleteIEndBEndBorders() { if (mBCInfo) { - mBCInfo->mBottomBorders.Clear(); - mBCInfo->mRightBorders.Clear(); + mBCInfo->mBEndBorders.Clear(); + mBCInfo->mIEndBorders.Clear(); } } @@ -426,7 +426,7 @@ nsTableCellMap::AddColsAtEnd(uint32_t aNumCols) NS_WARNING("Could not AppendElement"); } if (mBCInfo) { - if (!mBCInfo->mBottomBorders.AppendElements(aNumCols)) { + if (!mBCInfo->mBEndBorders.AppendElements(aNumCols)) { NS_WARNING("Could not AppendElement"); } } @@ -445,9 +445,9 @@ nsTableCellMap::RemoveColsAtEnd() mCols.RemoveElementAt(colX); if (mBCInfo) { - int32_t count = mBCInfo->mBottomBorders.Length(); + int32_t count = mBCInfo->mBEndBorders.Length(); if (colX < count) { - mBCInfo->mBottomBorders.RemoveElementAt(colX); + mBCInfo->mBEndBorders.RemoveElementAt(colX); } } } @@ -460,7 +460,7 @@ nsTableCellMap::ClearCols() { mCols.Clear(); if (mBCInfo) - mBCInfo->mBottomBorders.Clear(); + mBCInfo->mBEndBorders.Clear(); } void nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent, @@ -484,16 +484,16 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent, Dump("after InsertRows"); #endif if (mBCInfo) { - int32_t count = mBCInfo->mRightBorders.Length(); + int32_t count = mBCInfo->mIEndBorders.Length(); if (aFirstRowIndex < count) { for (int32_t rowX = aFirstRowIndex; rowX < aFirstRowIndex + numNewRows; rowX++) { - mBCInfo->mRightBorders.InsertElementAt(rowX); + mBCInfo->mIEndBorders.InsertElementAt(rowX); } } else { - GetRightMostBorder(aFirstRowIndex); // this will create missing entries + GetIEndMostBorder(aFirstRowIndex); // this will create missing entries for (int32_t rowX = aFirstRowIndex + 1; rowX < aFirstRowIndex + numNewRows; rowX++) { - mBCInfo->mRightBorders.AppendElement(); + mBCInfo->mIEndBorders.AppendElement(); } } } @@ -524,8 +524,8 @@ nsTableCellMap::RemoveRows(int32_t aFirstRowIndex, rgStartRowIndex, aDamageArea); if (mBCInfo) { for (int32_t rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) { - if (uint32_t(rowX) < mBCInfo->mRightBorders.Length()) { - mBCInfo->mRightBorders.RemoveElementAt(rowX); + if (uint32_t(rowX) < mBCInfo->mIEndBorders.Length()) { + mBCInfo->mIEndBorders.RemoveElementAt(rowX); } } } @@ -726,25 +726,25 @@ nsTableCellMap::Dump(char* aString) const cellMap = cellMap->GetNextSibling(); } if (nullptr != mBCInfo) { - printf("***** bottom borders *****\n"); + printf("***** block-end borders *****\n"); nscoord size; BCBorderOwner owner; - mozilla::Side side; + LogicalSide side; bool segStart; bool bevel; int32_t colIndex; - int32_t numCols = mBCInfo->mBottomBorders.Length(); + int32_t numCols = mBCInfo->mBEndBorders.Length(); for (int32_t i = 0; i <= 2; i++) { printf("\n "); for (colIndex = 0; colIndex < numCols; colIndex++) { - BCData& cd = mBCInfo->mBottomBorders.ElementAt(colIndex); + BCData& cd = mBCInfo->mBEndBorders.ElementAt(colIndex); if (0 == i) { - size = cd.GetTopEdge(owner, segStart); + size = cd.GetBStartEdge(owner, segStart); printf("t=%d%X%d ", int32_t(size), owner, segStart); } else if (1 == i) { - size = cd.GetLeftEdge(owner, segStart); + size = cd.GetIStartEdge(owner, segStart); printf("l=%d%X%d ", int32_t(size), owner, segStart); } else { @@ -752,13 +752,13 @@ nsTableCellMap::Dump(char* aString) const printf("c=%d%X%d ", int32_t(size), side, bevel); } } - BCData& cd = mBCInfo->mLowerRightCorner; + BCData& cd = mBCInfo->mBEndIEndCorner; if (0 == i) { - size = cd.GetTopEdge(owner, segStart); + size = cd.GetBStartEdge(owner, segStart); printf("t=%d%X%d ", int32_t(size), owner, segStart); } else if (1 == i) { - size = cd.GetLeftEdge(owner, segStart); + size = cd.GetIStartEdge(owner, segStart); printf("l=%d%X%d ", int32_t(size), owner, segStart); } else { @@ -912,28 +912,28 @@ void nsTableCellMap::ExpandZeroColSpans() } void -nsTableCellMap::ResetTopStart(uint8_t aSide, - nsCellMap& aCellMap, - uint32_t aRowIndex, - uint32_t aColIndex, - bool aIsLowerRight) +nsTableCellMap::ResetBStartStart(LogicalSide aSide, + nsCellMap& aCellMap, + uint32_t aRowIndex, + uint32_t aColIndex, + bool aIsBEndIEnd) { - if (!mBCInfo || aIsLowerRight) ABORT0(); + if (!mBCInfo || aIsBEndIEnd) ABORT0(); BCCellData* cellData; BCData* bcData = nullptr; switch(aSide) { - case NS_SIDE_BOTTOM: + case eLogicalSideBEnd: aRowIndex++; // FALLTHROUGH - case NS_SIDE_TOP: + case eLogicalSideBStart: cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex, aColIndex); if (cellData) { bcData = &cellData->mData; } else { - NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error"); + NS_ASSERTION(aSide == eLogicalSideBEnd, "program error"); // try the next row group nsCellMap* cellMap = aCellMap.GetNextSibling(); if (cellMap) { @@ -942,36 +942,36 @@ nsTableCellMap::ResetTopStart(uint8_t aSide, bcData = &cellData->mData; } else { - bcData = GetBottomMostBorder(aColIndex); + bcData = GetBEndMostBorder(aColIndex); } } } break; - case NS_SIDE_RIGHT: + case eLogicalSideIEnd: aColIndex++; // FALLTHROUGH - case NS_SIDE_LEFT: + case eLogicalSideIStart: cellData = (BCCellData*)aCellMap.GetDataAt(aRowIndex, aColIndex); if (cellData) { bcData = &cellData->mData; } else { - NS_ASSERTION(aSide == NS_SIDE_RIGHT, "program error"); - bcData = GetRightMostBorder(aRowIndex); + NS_ASSERTION(aSide == eLogicalSideIEnd, "program error"); + bcData = GetIEndMostBorder(aRowIndex); } break; } if (bcData) { - bcData->SetTopStart(false); + bcData->SetBStartStart(false); } } -// store the aSide border segment at coord = (aRowIndex, aColIndex). For top/left, store -// the info at coord. For bottom/left store it at the adjacent location so that it is -// top/left at that location. If the new location is at the right or bottom edge of the -// table, then store it one of the special arrays (right most borders, bottom most borders). +// store the aSide border segment at coord = (aRowIndex, aColIndex). For bStart/iStart, store +// the info at coord. For bEnd/iStart store it at the adjacent location so that it is +// bStart/iStart at that location. If the new location is at the iEnd or bEnd edge of the +// table, then store it one of the special arrays (iEnd-most borders, bEnd-most borders). void -nsTableCellMap::SetBCBorderEdge(mozilla::Side aSide, +nsTableCellMap::SetBCBorderEdge(LogicalSide aSide, nsCellMap& aCellMap, uint32_t aCellMapStart, uint32_t aRowIndex, @@ -991,10 +991,10 @@ nsTableCellMap::SetBCBorderEdge(mozilla::Side aSide, bool changed; switch(aSide) { - case NS_SIDE_BOTTOM: + case eLogicalSideBEnd: rgYPos++; yPos++; - case NS_SIDE_TOP: + case eLogicalSideBStart: lastIndex = xPos + aLength - 1; for (xIndex = xPos; xIndex <= lastIndex; xIndex++) { changed = aChanged && (xIndex == xPos); @@ -1009,7 +1009,7 @@ nsTableCellMap::SetBCBorderEdge(mozilla::Side aSide, if (!cellData) ABORT0(); } else { - NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error"); + NS_ASSERTION(aSide == eLogicalSideBEnd, "program error"); // try the next non empty row group nsCellMap* cellMap = aCellMap.GetNextSibling(); while (cellMap && (0 == cellMap->GetRowCount())) { @@ -1025,7 +1025,7 @@ nsTableCellMap::SetBCBorderEdge(mozilla::Side aSide, } } else { // must be at the end of the table - bcData = GetBottomMostBorder(xIndex); + bcData = GetBEndMostBorder(xIndex); } } } @@ -1033,53 +1033,53 @@ nsTableCellMap::SetBCBorderEdge(mozilla::Side aSide, bcData = &cellData->mData; } if (bcData) { - bcData->SetTopEdge(aOwner, aSize, changed); + bcData->SetBStartEdge(aOwner, aSize, changed); } - else NS_ERROR("Cellmap: Top edge not found"); + else NS_ERROR("Cellmap: BStart edge not found"); } break; - case NS_SIDE_RIGHT: + case eLogicalSideIEnd: xPos++; - case NS_SIDE_LEFT: - // since top, bottom borders were set, there should already be a cellData entry + case eLogicalSideIStart: + // since bStart, bEnd borders were set, there should already be a cellData entry lastIndex = rgYPos + aLength - 1; for (yIndex = rgYPos; yIndex <= lastIndex; yIndex++) { changed = aChanged && (yIndex == rgYPos); cellData = (BCCellData*)aCellMap.GetDataAt(yIndex, xPos); if (cellData) { - cellData->mData.SetLeftEdge(aOwner, aSize, changed); + cellData->mData.SetIStartEdge(aOwner, aSize, changed); } else { - NS_ASSERTION(aSide == NS_SIDE_RIGHT, "program error"); - BCData* bcData = GetRightMostBorder(yIndex + aCellMapStart); + NS_ASSERTION(aSide == eLogicalSideIEnd, "program error"); + BCData* bcData = GetIEndMostBorder(yIndex + aCellMapStart); if (bcData) { - bcData->SetLeftEdge(aOwner, aSize, changed); + bcData->SetIStartEdge(aOwner, aSize, changed); } - else NS_ERROR("Cellmap: Left edge not found"); + else NS_ERROR("Cellmap: IStart edge not found"); } } break; } } -// store corner info (aOwner, aSubSize, aBevel). For aCorner = eTopLeft, store the info at -// (aRowIndex, aColIndex). For eTopRight, store it in the entry to the right where -// it would be top left. For eBottomRight, store it in the entry to the bottom. etc. +// store corner info (aOwner, aSubSize, aBevel). For aCorner = eBStartIStart, store the info at +// (aRowIndex, aColIndex). For eBStartIEnd, store it in the entry to the iEnd-wards where +// it would be BStartIStart. For eBEndIEnd, store it in the entry to the bEnd-wards. etc. void nsTableCellMap::SetBCBorderCorner(Corner aCorner, nsCellMap& aCellMap, uint32_t aCellMapStart, uint32_t aRowIndex, uint32_t aColIndex, - mozilla::Side aOwner, + LogicalSide aOwner, nscoord aSubSize, bool aBevel, - bool aIsBottomRight) + bool aIsBEndIEnd) { if (!mBCInfo) ABORT0(); - if (aIsBottomRight) { - mBCInfo->mLowerRightCorner.SetCorner(aSubSize, aOwner, aBevel); + if (aIsBEndIEnd) { + mBCInfo->mBEndIEndCorner.SetCorner(aSubSize, aOwner, aBevel); return; } @@ -1087,15 +1087,15 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner, int32_t yPos = aRowIndex; int32_t rgYPos = aRowIndex - aCellMapStart; - if (eTopRight == aCorner) { + if (eBStartIEnd == aCorner) { xPos++; } - else if (eBottomRight == aCorner) { + else if (eBEndIEnd == aCorner) { xPos++; rgYPos++; yPos++; } - else if (eBottomLeft == aCorner) { + else if (eBEndIStart == aCorner) { rgYPos++; yPos++; } @@ -1104,9 +1104,9 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner, BCData* bcData = nullptr; if (GetColCount() <= xPos) { NS_ASSERTION(xPos == GetColCount(), "program error"); - // at the right edge of the table as we checked the corner before - NS_ASSERTION(!aIsBottomRight, "should be handled before"); - bcData = GetRightMostBorder(yPos); + // at the iEnd edge of the table as we checked the corner before + NS_ASSERTION(!aIsBEndIEnd, "should be handled before"); + bcData = GetIEndMostBorder(yPos); } else { cellData = (BCCellData*)aCellMap.GetDataAt(rgYPos, xPos); @@ -1131,8 +1131,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner, false, 0, damageArea); } } - else { // must be at the bottom of the table - bcData = GetBottomMostBorder(xPos); + else { // must be at the bEnd of the table + bcData = GetBEndMostBorder(xPos); } } } @@ -2585,7 +2585,7 @@ void nsCellMap::Dump(bool aIsBorderCollapse) const if (aIsBorderCollapse) { nscoord size; BCBorderOwner owner; - mozilla::Side side; + LogicalSide side; bool segStart; bool bevel; for (int32_t i = 0; i <= 2; i++) { @@ -2594,11 +2594,11 @@ void nsCellMap::Dump(bool aIsBorderCollapse) const BCCellData* cd = (BCCellData *)row[colIndex]; if (cd) { if (0 == i) { - size = cd->mData.GetTopEdge(owner, segStart); + size = cd->mData.GetBStartEdge(owner, segStart); printf("t=%d%d%d ", int32_t(size), owner, segStart); } else if (1 == i) { - size = cd->mData.GetLeftEdge(owner, segStart); + size = cd->mData.GetIStartEdge(owner, segStart); printf("l=%d%d%d ", int32_t(size), owner, segStart); } else { diff --git a/layout/tables/nsCellMap.h b/layout/tables/nsCellMap.h index 40c9118c1c..e424098e17 100644 --- a/layout/tables/nsCellMap.h +++ b/layout/tables/nsCellMap.h @@ -38,17 +38,17 @@ struct nsColInfo enum Corner { - eTopLeft = 0, - eTopRight = 1, - eBottomRight = 2, - eBottomLeft = 3 + eBStartIStart = 0, + eBStartIEnd = 1, + eBEndIEnd = 2, + eBEndIStart = 3 }; struct BCInfo { - nsTArray mRightBorders; - nsTArray mBottomBorders; - BCData mLowerRightCorner; + nsTArray mIEndBorders; + nsTArray mBEndBorders; + BCData mBEndIEndCorner; }; class nsTableCellMap @@ -200,13 +200,13 @@ protected: public: void ExpandZeroColSpans(); - void ResetTopStart(uint8_t aSide, - nsCellMap& aCellMap, - uint32_t aYPos, - uint32_t aXPos, - bool aIsLowerRight = false); + void ResetBStartStart(mozilla::LogicalSide aSide, + nsCellMap& aCellMap, + uint32_t aYPos, + uint32_t aXPos, + bool aIsBEndIEnd = false); - void SetBCBorderEdge(mozilla::Side aEdge, + void SetBCBorderEdge(mozilla::LogicalSide aEdge, nsCellMap& aCellMap, uint32_t aCellMapStart, uint32_t aYPos, @@ -221,7 +221,7 @@ public: uint32_t aCellMapStart, uint32_t aYPos, uint32_t aXPos, - mozilla::Side aOwner, + mozilla::LogicalSide aOwner, nscoord aSubSize, bool aBevel, bool aIsBottomRight = false); @@ -232,8 +232,8 @@ public: #endif protected: - BCData* GetRightMostBorder(int32_t aRowIndex); - BCData* GetBottomMostBorder(int32_t aColIndex); + BCData* GetIEndMostBorder(int32_t aRowIndex); + BCData* GetBEndMostBorder(int32_t aColIndex); friend class nsCellMap; friend class BCMapCellIterator; @@ -246,7 +246,7 @@ protected: */ void InsertGroupCellMap(nsCellMap* aPrevMap, nsCellMap& aNewMap); - void DeleteRightBottomBorders(); + void DeleteIEndBEndBorders(); nsTableFrame& mTableFrame; nsAutoTArray mCols; diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index f4061c6b6a..e24e51d758 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -944,14 +944,9 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext, kidReflowState.SetBResize(true); } - nscoord containerWidth; - if (aReflowState.ComputedWidth() == NS_UNCONSTRAINEDSIZE) { - containerWidth = 0; // avoid passing unconstrained container width to - // ReflowChild; but position will not be valid - } else { - containerWidth = aReflowState.ComputedWidth() + - aReflowState.ComputedPhysicalBorderPadding().LeftRight(); - } + nscoord containerWidth = + aReflowState.ComputedSizeAsContainerIfConstrained().width; + LogicalPoint kidOrigin(wm, borderPadding.IStart(wm), borderPadding.BStart(wm)); nsRect origRect = firstKid->GetRect(); diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index 5646cb21de..6060cf167a 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -95,13 +95,14 @@ public: /** * Gets inner border widths before collapsing with cell borders - * Caller must get left border from previous column or from table - * GetContinuousBCBorderWidth will not overwrite aBorder.left + * Caller must get istart border from previous column or from table + * GetContinuousBCBorderWidth will not overwrite aBorder.IStart * see nsTablePainter about continuous borders * - * @return outer right border width (left inner for next column) + * @return outer iend border width (istart inner for next column) */ - nscoord GetContinuousBCBorderWidth(nsMargin& aBorder); + nscoord GetContinuousBCBorderWidth(mozilla::WritingMode aWM, + mozilla::LogicalMargin& aBorder); /** * Set full border widths before collapsing with cell borders * @param aForSide - side to set; only valid for bstart, iend, and bend @@ -325,18 +326,16 @@ inline void nsTableColFrame::SetColIndex (int32_t aColIndex) } inline nscoord -nsTableColFrame::GetContinuousBCBorderWidth(nsMargin& aBorder) +nsTableColFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM, + mozilla::LogicalMargin& aBorder) { int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); - mozilla::WritingMode wm = GetWritingMode(); - mozilla::LogicalMargin border(wm, aBorder); - border.BStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, - mBStartContBorderWidth); - border.IEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, - mIEndContBorderWidth); - border.BEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, - mBEndContBorderWidth); - aBorder = border.GetPhysicalMargin(wm); + aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, + mBStartContBorderWidth); + aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, + mIEndContBorderWidth); + aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, + mBEndContBorderWidth); return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mIEndContBorderWidth); } diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index bc761c63bb..f5f1827cac 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -416,31 +416,32 @@ int32_t nsTableColGroupFrame::GetSpan() return StyleTable()->mSpan; } -void nsTableColGroupFrame::SetContinuousBCBorderWidth(uint8_t aForSide, +void nsTableColGroupFrame::SetContinuousBCBorderWidth(LogicalSide aForSide, BCPixelSize aPixelValue) { switch (aForSide) { - case NS_SIDE_TOP: - mTopContBorderWidth = aPixelValue; + case eLogicalSideBStart: + mBStartContBorderWidth = aPixelValue; return; - case NS_SIDE_BOTTOM: - mBottomContBorderWidth = aPixelValue; + case eLogicalSideBEnd: + mBEndContBorderWidth = aPixelValue; return; default: NS_ERROR("invalid side arg"); } } -void nsTableColGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder) +void nsTableColGroupFrame::GetContinuousBCBorderWidth(WritingMode aWM, + LogicalMargin& aBorder) { int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); nsTableColFrame* col = GetTableFrame()-> GetColFrame(mStartColIndex + mColCount - 1); - col->GetContinuousBCBorderWidth(aBorder); - aBorder.top = BC_BORDER_END_HALF_COORD(aPixelsToTwips, - mTopContBorderWidth); - aBorder.bottom = BC_BORDER_START_HALF_COORD(aPixelsToTwips, - mBottomContBorderWidth); + col->GetContinuousBCBorderWidth(aWM, aBorder); + aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips, + mBStartContBorderWidth); + aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips, + mBEndContBorderWidth); } /* ----- global methods ----- */ diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index e387ee9370..37df997a05 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -186,16 +186,17 @@ public: /** * Gets inner border widths before collapsing with cell borders - * Caller must get left border from previous column - * GetContinuousBCBorderWidth will not overwrite aBorder.left + * Caller must get istart border from previous column + * GetContinuousBCBorderWidth will not overwrite aBorder.IStart * see nsTablePainter about continuous borders */ - void GetContinuousBCBorderWidth(nsMargin& aBorder); + void GetContinuousBCBorderWidth(mozilla::WritingMode aWM, + mozilla::LogicalMargin& aBorder); /** * Set full border widths before collapsing with cell borders - * @param aForSide - side to set; only accepts top and bottom + * @param aForSide - side to set; only accepts bstart and bend */ - void SetContinuousBCBorderWidth(uint8_t aForSide, + void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide, BCPixelSize aPixelValue); virtual bool IsFrameOfType(uint32_t aFlags) const override @@ -221,8 +222,8 @@ protected: int32_t mStartColIndex; // border width in pixels - BCPixelSize mTopContBorderWidth; - BCPixelSize mBottomContBorderWidth; + BCPixelSize mBStartContBorderWidth; + BCPixelSize mBEndContBorderWidth; }; inline nsTableColGroupFrame::nsTableColGroupFrame(nsStyleContext *aContext) diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 55b32519d8..0a6189e059 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -109,16 +109,16 @@ struct nsTableReflowState { struct BCPropertyData { - BCPropertyData() : mTopBorderWidth(0), mRightBorderWidth(0), - mBottomBorderWidth(0), mLeftBorderWidth(0), - mLeftCellBorderWidth(0), mRightCellBorderWidth(0) {} + BCPropertyData() : mBStartBorderWidth(0), mIEndBorderWidth(0), + mBEndBorderWidth(0), mIStartBorderWidth(0), + mIStartCellBorderWidth(0), mIEndCellBorderWidth(0) {} TableArea mDamageArea; - BCPixelSize mTopBorderWidth; - BCPixelSize mRightBorderWidth; - BCPixelSize mBottomBorderWidth; - BCPixelSize mLeftBorderWidth; - BCPixelSize mLeftCellBorderWidth; - BCPixelSize mRightCellBorderWidth; + BCPixelSize mBStartBorderWidth; + BCPixelSize mIEndBorderWidth; + BCPixelSize mBEndBorderWidth; + BCPixelSize mIStartBorderWidth; + BCPixelSize mIStartCellBorderWidth; + BCPixelSize mIEndCellBorderWidth; }; nsStyleContext* @@ -497,8 +497,8 @@ nsTableFrame::AdjustRowIndices(int32_t aRowIndex, RowGroupArray rowGroups; OrderRowGroups(rowGroups); - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - rowGroups[rgX]->AdjustRowIndices(aRowIndex, aAdjustment); + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + rowGroups[rgIdx]->AdjustRowIndices(aRowIndex, aAdjustment); } } @@ -519,8 +519,8 @@ nsTableFrame::ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude) excludeRowGroupsEnumerator.Next(); } - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; if (!excludeRowGroups.GetEntry(rgFrame)) { const nsFrameList& rowFrames = rgFrame->PrincipalChildList(); for (nsFrameList::Enumerator rows(rowFrames); !rows.AtEnd(); rows.Next()) { @@ -917,9 +917,9 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame, } // assign the correct row indices to the new rows. If they were adjusted above // it may not have been done correctly because each row is constructed with index 0 - for (int32_t rowY = 0; rowY < numNewRows; rowY++) { - nsTableRowFrame* rowFrame = aRowFrames.ElementAt(rowY); - rowFrame->SetRowIndex(aRowIndex + rowY); + for (int32_t rowB = 0; rowB < numNewRows; rowB++) { + nsTableRowFrame* rowFrame = aRowFrames.ElementAt(rowB); + rowFrame->SetRowIndex(aRowIndex + rowB); } if (IsBorderCollapse()) { AddBCDamageArea(damageArea); @@ -1488,8 +1488,8 @@ nsTableFrame::ProcessRowInserted(nscoord aNewBSize) nsTableFrame::RowGroupArray rowGroups; OrderRowGroups(rowGroups); // find the row group containing the inserted row - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; NS_ASSERTION(rgFrame, "Must have rgFrame here"); nsIFrame* childFrame = rgFrame->GetFirstPrincipalChild(); // find the row that was inserted first @@ -2647,40 +2647,39 @@ DivideBCBorderSize(BCPixelSize aPixelSize, LogicalMargin nsTableFrame::GetOuterBCBorder(const WritingMode aWM) const { - if (NeedToCalcBCBorders()) + if (NeedToCalcBCBorders()) { const_cast(this)->CalcBCBorders(); + } - nsMargin border(0, 0, 0, 0); int32_t d2a = PresContext()->AppUnitsPerDevPixel(); BCPropertyData* propData = GetBCProperty(); if (propData) { - return LogicalMargin( - aWM, - BC_BORDER_START_HALF_COORD(d2a, propData->mTopBorderWidth), - BC_BORDER_END_HALF_COORD(d2a, propData->mRightBorderWidth), - BC_BORDER_END_HALF_COORD(d2a, propData->mBottomBorderWidth), - BC_BORDER_START_HALF_COORD(d2a, propData->mLeftBorderWidth)); + return LogicalMargin(aWM, + BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mIEndBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), + BC_BORDER_START_HALF_COORD(d2a, propData->mIStartBorderWidth)); } - return LogicalMargin(GetWritingMode()); + return LogicalMargin(aWM); } LogicalMargin nsTableFrame::GetIncludedOuterBCBorder(const WritingMode aWM) const { - if (NeedToCalcBCBorders()) + if (NeedToCalcBCBorders()) { const_cast(this)->CalcBCBorders(); + } int32_t d2a = PresContext()->AppUnitsPerDevPixel(); BCPropertyData* propData = GetBCProperty(); if (propData) { - return LogicalMargin( - aWM, - BC_BORDER_START_HALF_COORD(d2a, propData->mTopBorderWidth), - BC_BORDER_END_HALF_COORD(d2a, propData->mRightCellBorderWidth), - BC_BORDER_END_HALF_COORD(d2a, propData->mBottomBorderWidth), - BC_BORDER_START_HALF_COORD(d2a, propData->mLeftCellBorderWidth)); + return LogicalMargin(aWM, + BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mIEndCellBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), + BC_BORDER_START_HALF_COORD(d2a, propData->mIStartCellBorderWidth)); } - return LogicalMargin(GetWritingMode()); + return LogicalMargin(aWM); } LogicalMargin @@ -2734,7 +2733,7 @@ nsTableFrame::InitChildReflowState(nsHTMLReflowState& aReflowState) !aReflowState.parentReflowState->mFlags.mSpecialBSizeReflow, "should not resize columns on special bsize reflow"); if (mBits.mResizedColumns) { - aReflowState.SetHResize(true); + aReflowState.SetIResize(true); } } @@ -2972,19 +2971,11 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, nsIFrame* prevKidFrame = nullptr; WritingMode wm = aReflowState.reflowState.GetWritingMode(); - nscoord containerWidth = aReflowState.reflowState.ComputedWidth(); - if (containerWidth == NS_UNCONSTRAINEDSIZE) { - NS_WARN_IF_FALSE(wm.IsVertical(), - "shouldn't have unconstrained width in horizontal mode"); - // We won't know the containerWidth until we've reflowed our contents, - // so use zero for now; in vertical-rl mode, this will mean the children - // are misplaced in the block-direction, and will need to be moved - // rightwards by the true containerWidth once we know it. - containerWidth = 0; - } else { - containerWidth += - aReflowState.reflowState.ComputedPhysicalBorderPadding().LeftRight(); - } + NS_WARN_IF_FALSE(wm.IsVertical() || NS_UNCONSTRAINEDSIZE != + aReflowState.reflowState.ComputedWidth(), + "shouldn't have unconstrained width in horizontal mode"); + nscoord containerWidth = + aReflowState.reflowState.ComputedSizeAsContainerIfConstrained().width; nsPresContext* presContext = PresContext(); // XXXldb Should we be checking constrained height instead? @@ -3325,10 +3316,10 @@ nsTableFrame::CalcDesiredBSize(const nsHTMLReflowState& aReflowState, nscoord desiredBSize = borderPadding.BStartEnd(wm); if (rowCount > 0 && colCount > 0) { desiredBSize += GetRowSpacing(-1); - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - desiredBSize += rowGroups[rgX]->BSize(wm) + - GetRowSpacing(rowGroups[rgX]->GetRowCount() + - rowGroups[rgX]->GetStartRowIndex()); + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + desiredBSize += rowGroups[rgIdx]->BSize(wm) + + GetRowSpacing(rowGroups[rgIdx]->GetRowCount() + + rowGroups[rgIdx]->GetStartRowIndex()); } } @@ -3361,8 +3352,8 @@ void ResizeCells(nsTableFrame& aTableFrame) tableDesiredSize.SetSize(wm, aTableFrame.GetLogicalSize(wm)); tableDesiredSize.SetOverflowAreasToDesiredBounds(); - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; nsHTMLReflowMetrics groupDesiredSize(wm); groupDesiredSize.SetSize(wm, rgFrame->GetLogicalSize(wm)); @@ -3388,12 +3379,8 @@ nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState, WritingMode wm = aReflowState.GetWritingMode(); LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState); - nscoord containerWidth = aReflowState.ComputedWidth(); - if (containerWidth == NS_UNCONSTRAINEDSIZE) { - containerWidth = 0; - } else { - containerWidth += aReflowState.ComputedPhysicalBorderPadding().LeftRight(); - } + nscoord containerWidth = + aReflowState.ComputedSizeAsContainerIfConstrained().width; RowGroupArray rowGroups; OrderRowGroups(rowGroups); @@ -3405,9 +3392,9 @@ nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState, nscoord pctBasis = aReflowState.ComputedBSize() - GetRowSpacing(-1, GetRowCount()); nscoord bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0); nscoord bEndRG = bOriginRG; - uint32_t rgX; - for (rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + uint32_t rgIdx; + for (rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; nscoord amountUsedByRG = 0; nscoord bOriginRow = 0; LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), containerWidth); @@ -3491,8 +3478,8 @@ nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState, // unconstrained bsize nsTableRowGroupFrame* firstUnStyledRG = nullptr; nsTableRowFrame* firstUnStyledRow = nullptr; - for (rgX = 0; rgX < rowGroups.Length() && !firstUnStyledRG; rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (rgIdx = 0; rgIdx < rowGroups.Length() && !firstUnStyledRG; rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; if (!rgFrame->HasStyleBSize()) { nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { @@ -3520,8 +3507,8 @@ nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState, divisor = GetRowCount(); } else { - for (rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; if (!firstUnStyledRG || !rgFrame->HasStyleBSize()) { nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { @@ -3550,8 +3537,8 @@ nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState, nscoord bSizeToDistribute = aAmount - amountUsed; bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(-1); bEndRG = bOriginRG; - for (rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; nscoord amountUsedByRG = 0; nscoord bOriginRow = 0; LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), containerWidth); @@ -4107,16 +4094,16 @@ nsTableFrame::SetFullBCDamageArea() } -/* BCCellBorder represents a border segment which can be either a horizontal - * or a vertical segment. For each segment we need to know the color, width, +/* BCCellBorder represents a border segment which can be either an inline-dir + * or a block-dir segment. For each segment we need to know the color, width, * style, who owns it and how long it is in cellmap coordinates. * Ownership of these segments is important to calculate which corners should * be bevelled. This structure has dual use, its used first to compute the - * dominant border for horizontal and vertical segments and to store the + * dominant border for inline-dir and block-dir segments and to store the * preliminary computed border results in the BCCellBorders structure. - * This temporary storage is not symmetric with respect to horizontal and - * vertical border segments, its always column oriented. For each column in - * the cellmap there is a temporary stored vertical and horizontal segment. + * This temporary storage is not symmetric with respect to inline-dir and + * block-dir border segments, its always column oriented. For each column in + * the cellmap there is a temporary stored block-dir and inline-dir segment. * XXX_Bernd this asymmetry is the root of those rowspan bc border errors */ struct BCCellBorder @@ -4132,9 +4119,9 @@ struct BCCellBorder // segment we store the owner and later when // painting we know the owner and can retrieve the // style info from the corresponding frame - int32_t rowIndex; // rowIndex of temporary stored horizontal border + int32_t rowIndex; // rowIndex of temporary stored inline-dir border // segments relative to the table - int32_t rowSpan; // row span of temporary stored horizontal border + int32_t rowSpan; // row span of temporary stored inline-dir border // segments }; @@ -4189,8 +4176,8 @@ struct BCMapCellInfo // functions to set the border widths on the table related frames, where the // knowledge about the current position in the table is used. void SetTableBStartBorderWidth(BCPixelSize aWidth); - void SetTableIStartBorderWidth(int32_t aRowY, BCPixelSize aWidth); - void SetTableIEndBorderWidth(int32_t aRowY, BCPixelSize aWidth); + void SetTableIStartBorderWidth(int32_t aRowB, BCPixelSize aWidth); + void SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth); void SetTableBEndBorderWidth(BCPixelSize aWidth); void SetIStartBorderWidths(BCPixelSize aWidth); void SetIEndBorderWidths(BCPixelSize aWidth); @@ -4210,10 +4197,10 @@ struct BCMapCellInfo BCCellBorder GetBStartInternalBorder(); BCCellBorder GetBEndInternalBorder(); - // functions to set the interal position information + // functions to set the internal position information void SetColumn(int32_t aColX); // Increment the row as we loop over the rows of a rowspan - void IncrementRow(bool aResetToTopRowOfCell = false); + void IncrementRow(bool aResetToBStartRowOfCell = false); // Helper functions to get extent of the cell int32_t GetCellEndRowIndex() const; @@ -4229,12 +4216,12 @@ struct BCMapCellInfo // a cell can only belong to one rowgroup nsTableRowGroupFrame* mRowGroup; - // a cell with a rowspan has a top and a bottom row, and rows in between + // a cell with a rowspan has a bstart and a bend row, and rows in between nsTableRowFrame* mStartRow; nsTableRowFrame* mEndRow; nsTableRowFrame* mCurrentRowFrame; - // a cell with a colspan has a left and right column and columns in between + // a cell with a colspan has an istart and iend column and columns in between // they can belong to different colgroups nsTableColGroupFrame* mColGroup; nsTableColGroupFrame* mCurrentColGroupFrame; @@ -4253,7 +4240,7 @@ struct BCMapCellInfo int32_t mColSpan; // flags to describe the position of the cell with respect to the row- and - // colgroups, for instance mRgAtStart documents that the top cell border hits + // colgroups, for instance mRgAtStart documents that the bStart cell border hits // a rowgroup border bool mRgAtStart; bool mRgAtEnd; @@ -4312,19 +4299,19 @@ public: void Next(BCMapCellInfo& aMapCellInfo); - void PeekRight(BCMapCellInfo& aRefInfo, - uint32_t aRowIndex, - BCMapCellInfo& aAjaInfo); + void PeekIEnd(BCMapCellInfo& aRefInfo, + uint32_t aRowIndex, + BCMapCellInfo& aAjaInfo); - void PeekBottom(BCMapCellInfo& aRefInfo, - uint32_t aColIndex, - BCMapCellInfo& aAjaInfo); + void PeekBEnd(BCMapCellInfo& aRefInfo, + uint32_t aColIndex, + BCMapCellInfo& aAjaInfo); bool IsNewRow() { return mIsNewRow; } nsTableRowFrame* GetPrevRow() const { return mPrevRow; } nsTableRowFrame* GetCurrentRow() const { return mRow; } - nsTableRowGroupFrame* GetCurrentRowGroup() const { return mRowGroup;} + nsTableRowGroupFrame* GetCurrentRowGroup() const { return mRowGroup; } int32_t mRowGroupStart; int32_t mRowGroupEnd; @@ -4347,13 +4334,14 @@ private: int32_t mRowIndex; uint32_t mNumTableCols; int32_t mColIndex; - nsPoint mAreaStart; - nsPoint mAreaEnd; + nsPoint mAreaStart; // These are not really points in the usual + nsPoint mAreaEnd; // sense; they're column/row coordinates + // in the cell map. }; BCMapCellIterator::BCMapCellIterator(nsTableFrame* aTableFrame, const TableArea& aDamageArea) -:mTableFrame(aTableFrame) + : mTableFrame(aTableFrame) { mTableCellMap = aTableFrame->GetCellMap(); @@ -4509,7 +4497,7 @@ BCMapCellIterator::SetNewRow(nsTableRowFrame* aRow) bool BCMapCellIterator::SetNewRowGroup(bool aFindFirstDamagedRow) { - mAtEnd = true; + mAtEnd = true; int32_t numRowGroups = mRowGroups.Length(); mCellMap = nullptr; for (mRowGroupIndex++; mRowGroupIndex < numRowGroups; mRowGroupIndex++) { @@ -4556,8 +4544,8 @@ BCMapCellIterator::First(BCMapCellInfo& aMapInfo) if ((mAreaStart.y >= mRowGroupStart) && (mAreaStart.y <= mRowGroupEnd)) { BCCellData* cellData = static_cast(mCellMap->GetDataAt(mAreaStart.y - - mRowGroupStart, - mAreaStart.x)); + mRowGroupStart, + mAreaStart.x)); if (cellData && (cellData->IsOrig() || cellData->IsDead())) { aMapInfo.SetInfo(mRow, mAreaStart.x, cellData, this); return; @@ -4588,8 +4576,8 @@ BCMapCellIterator::Next(BCMapCellInfo& aMapInfo) TableArea damageArea; cellData = static_cast(mCellMap->AppendCell(*mTableCellMap, nullptr, - rgRowIndex, false, 0, - damageArea)); + rgRowIndex, false, 0, + damageArea)); if (!cellData) ABORT0(); } if (cellData && (cellData->IsOrig() || cellData->IsDead())) { @@ -4608,9 +4596,9 @@ BCMapCellIterator::Next(BCMapCellInfo& aMapInfo) } void -BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo, - uint32_t aRowIndex, - BCMapCellInfo& aAjaInfo) +BCMapCellIterator::PeekIEnd(BCMapCellInfo& aRefInfo, + uint32_t aRowIndex, + BCMapCellInfo& aAjaInfo) { aAjaInfo.ResetCellInfo(); int32_t colIndex = aRefInfo.mColIndex + aRefInfo.mColSpan; @@ -4623,8 +4611,8 @@ BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo, TableArea damageArea; cellData = static_cast(mCellMap->AppendCell(*mTableCellMap, nullptr, - rgRowIndex, false, 0, - damageArea)); + rgRowIndex, false, 0, + damageArea)); if (!cellData) ABORT0(); } nsTableRowFrame* row = nullptr; @@ -4642,9 +4630,9 @@ BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo, } void -BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo, - uint32_t aColIndex, - BCMapCellInfo& aAjaInfo) +BCMapCellIterator::PeekBEnd(BCMapCellInfo& aRefInfo, + uint32_t aColIndex, + BCMapCellInfo& aAjaInfo) { aAjaInfo.ResetCellInfo(); int32_t rowIndex = aRefInfo.mRowIndex + aRefInfo.mRowSpan; @@ -4681,8 +4669,8 @@ BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo, TableArea damageArea; cellData = static_cast(cellMap->AppendCell(*mTableCellMap, nullptr, - rgRowIndex, false, 0, - damageArea)); + rgRowIndex, false, 0, + damageArea)); if (!cellData) ABORT0(); } if (cellData->IsColSpan()) { @@ -4717,7 +4705,6 @@ static uint8_t styleToPriority[13] = { 0, // NS_STYLE_BORDER_STYLE_NONE * @param aSide - the side of the frame * @param aStyle - the border style * @param aColor - the border color - * @param aWidth - the border width in px. * @param aWidth - the border width in px */ static void @@ -4827,13 +4814,13 @@ nsTableFrame::BCRecalcNeeded(nsStyleContext* aOldStyleContext, // Compare two border segments, this comparison depends whether the two -// segments meet at a corner and whether the second segment is horizontal. +// segments meet at a corner and whether the second segment is inline-dir. // The return value is whichever of aBorder1 or aBorder2 dominates. static const BCCellBorder& CompareBorders(bool aIsCorner, // Pass true for corner calculations const BCCellBorder& aBorder1, const BCCellBorder& aBorder2, - bool aSecondIsHorizontal, + bool aSecondIsInlineDir, bool* aFirstDominates = nullptr) { bool firstDominates = true; @@ -4853,7 +4840,7 @@ CompareBorders(bool aIsCorner, // Pass true for corner calculatio } else if (styleToPriority[aBorder1.style] == styleToPriority[aBorder2.style]) { if (aBorder1.owner == aBorder2.owner) { - firstDominates = !aSecondIsHorizontal; + firstDominates = !aSecondIsInlineDir; } else if (aBorder1.owner < aBorder2.owner) { firstDominates = false; @@ -4871,11 +4858,11 @@ CompareBorders(bool aIsCorner, // Pass true for corner calculatio /** calc the dominant border by considering the table, row/col group, row/col, * cell. - * Depending on whether the side is vertical or horizontal and whether + * Depending on whether the side is block-dir or inline-dir and whether * adjacent frames are taken into account the ownership of a single border * segment is defined. The return value is the dominating border - * The cellmap stores only top and left borders for each cellmap position. - * If the cell border is owned by the cell that is left of the border + * The cellmap stores only bstart and istart borders for each cellmap position. + * If the cell border is owned by the cell that is istart-wards of the border * it will be an adjacent owner aka eAjaCellOwner. See celldata.h for the other * scenarios with a adjacent owner. * @param xxxFrame - the frame for style information, might be zero if @@ -4885,8 +4872,8 @@ CompareBorders(bool aIsCorner, // Pass true for corner calculatio * @param aAja - the border comparison takes place from the point of * a frame that is adjacent to the cellmap entry, for * when a cell owns its lower border it will be the - * adjacent owner as in the cellmap only top and left - * borders are stored. + * adjacent owner as in the cellmap only bstart and + * istart borders are stored. */ static BCCellBorder CompareBorders(const nsIFrame* aTableFrame, @@ -4916,7 +4903,7 @@ CompareBorders(const nsIFrame* aTableFrame, GetColorAndStyle(aColGroupFrame, aTableWM, aSide, &tempBorder.style, &tempBorder.color, &tempBorder.width); tempBorder.owner = aAja && !inlineAxis ? eAjaColGroupOwner : eColGroupOwner; - // pass here and below false for aSecondIsHorizontal as it is only used for corner calculations. + // pass here and below false for aSecondIsInlineDir as it is only used for corner calculations. border = CompareBorders(!CELL_CORNER, border, tempBorder, false); if (NS_STYLE_BORDER_STYLE_HIDDEN == border.style) { return border; @@ -4963,38 +4950,29 @@ CompareBorders(const nsIFrame* aTableFrame, } static bool -Perpendicular(mozilla::css::Side aSide1, - mozilla::css::Side aSide2) +Perpendicular(mozilla::LogicalSide aSide1, + mozilla::LogicalSide aSide2) { - switch (aSide1) { - case NS_SIDE_TOP: - return (NS_SIDE_BOTTOM != aSide2); - case NS_SIDE_RIGHT: - return (NS_SIDE_LEFT != aSide2); - case NS_SIDE_BOTTOM: - return (NS_SIDE_TOP != aSide2); - default: // NS_SIDE_LEFT - return (NS_SIDE_RIGHT != aSide2); - } + return IsInline(aSide1) != IsInline(aSide2); } // XXX allocate this as number-of-cols+1 instead of number-of-cols+1 * number-of-rows+1 struct BCCornerInfo { BCCornerInfo() { ownerColor = 0; ownerWidth = subWidth = ownerElem = subSide = - subElem = hasDashDot = numSegs = bevel = 0; ownerSide = NS_SIDE_TOP; + subElem = hasDashDot = numSegs = bevel = 0; ownerSide = eLogicalSideBStart; ownerStyle = 0xFF; subStyle = NS_STYLE_BORDER_STYLE_SOLID; } - void Set(mozilla::css::Side aSide, + void Set(mozilla::LogicalSide aSide, BCCellBorder border); - void Update(mozilla::css::Side aSide, + void Update(mozilla::LogicalSide aSide, BCCellBorder border); nscolor ownerColor; // color of borderOwner uint16_t ownerWidth; // pixel width of borderOwner uint16_t subWidth; // pixel width of the largest border intersecting the border perpendicular // to ownerSide - uint32_t ownerSide:2; // mozilla::css::Side (e.g NS_SIDE_TOP, NS_SIDE_RIGHT, etc) of the border + uint32_t ownerSide:2; // LogicalSide (e.g eLogicalSideBStart, etc) of the border // owning the corner relative to the corner uint32_t ownerElem:3; // elem type (e.g. eTable, eGroup, etc) owning the corner uint32_t ownerStyle:8; // border style of ownerElem @@ -5008,7 +4986,7 @@ struct BCCornerInfo }; void -BCCornerInfo::Set(mozilla::css::Side aSide, +BCCornerInfo::Set(mozilla::LogicalSide aSide, BCCellBorder aBorder) { ownerElem = aBorder.owner; @@ -5026,13 +5004,13 @@ BCCornerInfo::Set(mozilla::css::Side aSide, bevel = 0; subWidth = 0; // the following will get set later - subSide = ((aSide == NS_SIDE_LEFT) || (aSide == NS_SIDE_RIGHT)) ? NS_SIDE_TOP : NS_SIDE_LEFT; + subSide = IsInline(aSide) ? eLogicalSideBStart : eLogicalSideIStart; subElem = eTableOwner; subStyle = NS_STYLE_BORDER_STYLE_SOLID; } void -BCCornerInfo::Update(mozilla::css::Side aSide, +BCCornerInfo::Update(mozilla::LogicalSide aSide, BCCellBorder aBorder) { bool existingWins = false; @@ -5040,23 +5018,23 @@ BCCornerInfo::Update(mozilla::css::Side aSide, Set(aSide, aBorder); } else { - bool horizontal = (NS_SIDE_LEFT == aSide) || (NS_SIDE_RIGHT == aSide); // relative to the corner + bool isInline = IsInline(aSide); // relative to the corner BCCellBorder oldBorder, tempBorder; oldBorder.owner = (BCBorderOwner) ownerElem; oldBorder.style = ownerStyle; oldBorder.width = ownerWidth; oldBorder.color = ownerColor; - mozilla::css::Side oldSide = mozilla::css::Side(ownerSide); + LogicalSide oldSide = LogicalSide(ownerSide); - tempBorder = CompareBorders(CELL_CORNER, oldBorder, aBorder, horizontal, &existingWins); + tempBorder = CompareBorders(CELL_CORNER, oldBorder, aBorder, isInline, &existingWins); ownerElem = tempBorder.owner; ownerStyle = tempBorder.style; ownerWidth = tempBorder.width; ownerColor = tempBorder.color; if (existingWins) { // existing corner is dominant - if (::Perpendicular(mozilla::css::Side(ownerSide), aSide)) { + if (::Perpendicular(LogicalSide(ownerSide), aSide)) { // see if the new sub info replaces the old BCCellBorder subBorder; subBorder.owner = (BCBorderOwner) subElem; @@ -5065,7 +5043,7 @@ BCCornerInfo::Update(mozilla::css::Side aSide, subBorder.color = 0; // we are not interested in subBorder color bool firstWins; - tempBorder = CompareBorders(CELL_CORNER, subBorder, aBorder, horizontal, &firstWins); + tempBorder = CompareBorders(CELL_CORNER, subBorder, aBorder, isInline, &firstWins); subElem = tempBorder.owner; subStyle = tempBorder.style; @@ -5077,7 +5055,7 @@ BCCornerInfo::Update(mozilla::css::Side aSide, } else { // input args are dominant ownerSide = aSide; - if (::Perpendicular(oldSide, mozilla::css::Side(ownerSide))) { + if (::Perpendicular(oldSide, LogicalSide(ownerSide))) { subElem = oldBorder.owner; subStyle = oldBorder.style; subWidth = oldBorder.width; @@ -5166,17 +5144,17 @@ SetBorder(const BCCellBorder& aNewBorder, return changed; } -// this function will set the horizontal border. It will return true if the -// existing segment will not be continued. Having a vertical owner of a corner +// this function will set the inline-dir border. It will return true if the +// existing segment will not be continued. Having a block-dir owner of a corner // should also start a new segment. static bool -SetHorBorder(const BCCellBorder& aNewBorder, - const BCCornerInfo& aCorner, - BCCellBorder& aBorder) +SetInlineDirBorder(const BCCellBorder& aNewBorder, + const BCCornerInfo& aCorner, + BCCellBorder& aBorder) { bool startSeg = ::SetBorder(aNewBorder, aBorder); if (!startSeg) { - startSeg = ((NS_SIDE_LEFT != aCorner.ownerSide) && (NS_SIDE_RIGHT != aCorner.ownerSide)); + startSeg = !IsInline(LogicalSide(aCorner.ownerSide)); } return startSeg; } @@ -5223,8 +5201,8 @@ nsTableFrame::ExpandBCDamageArea(TableArea& aArea) const // Scope outside loop to be used as hint. nsCellMap* cellMap = nullptr; - for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; + for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { + nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; int32_t rgStartY = rgFrame->GetStartRowIndex(); int32_t rgEndY = rgStartY + rgFrame->GetRowCount() - 1; if (dEndY < rgStartY) @@ -5315,7 +5293,7 @@ nsTableFrame::ExpandBCDamageArea(TableArea& aArea) const #define ADJACENT true -#define HORIZONTAL true +#define INLINE_DIR true void BCMapCellInfo::SetTableBStartIStartContBCBorder() @@ -5342,7 +5320,7 @@ BCMapCellInfo::SetTableBStartIStartContBCBorder() currentBorder = CompareBorders(mTableFrame, mColGroup, mStartCol, nullptr, nullptr, nullptr, mTableWM, eLogicalSideIStart, !ADJACENT); - mTableFrame->SetContinuousLeftBCBorderWidth(currentBorder.width); + mTableFrame->SetContinuousIStartBCBorderWidth(currentBorder.width); } } @@ -5384,8 +5362,8 @@ BCMapCellInfo::SetColumnBStartIEndContBCBorder() mCurrentColFrame, mRowGroup, mStartRow, nullptr, mTableWM, eLogicalSideBStart, !ADJACENT); - ((nsTableColFrame*) mCurrentColFrame)-> - SetContinuousBCBorderWidth(eLogicalSideBStart, currentBorder.width); + mCurrentColFrame->SetContinuousBCBorderWidth(eLogicalSideBStart, + currentBorder.width); if (mNumTableCols == GetCellEndColIndex() + 1) { currentBorder = CompareBorders(mTableFrame, mCurrentColGroupFrame, mCurrentColFrame, nullptr, nullptr, nullptr, @@ -5420,7 +5398,7 @@ BCMapCellInfo::SetColGroupBEndContBCBorder() currentBorder = CompareBorders(mTableFrame, mColGroup, nullptr, mRowGroup, mEndRow, nullptr, mTableWM, eLogicalSideBEnd, ADJACENT); - mColGroup->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, currentBorder.width); + mColGroup->SetContinuousBCBorderWidth(eLogicalSideBEnd, currentBorder.width); } } @@ -5450,7 +5428,7 @@ BCMapCellInfo::SetInnerRowGroupBEndContBCBorder(const nsIFrame* aNextRowGroup, aNextRow, nullptr, mTableWM, eLogicalSideBStart, !ADJACENT); currentBorder = CompareBorders(false, currentBorder, adjacentBorder, - HORIZONTAL); + INLINE_DIR); if (aNextRow) { aNextRow->SetContinuousBCBorderWidth(eLogicalSideBStart, currentBorder.width); @@ -5489,39 +5467,30 @@ BCMapCellInfo::SetRowIEndContBCBorder() void BCMapCellInfo::SetTableBStartBorderWidth(BCPixelSize aWidth) { - mTableBCData->mTopBorderWidth = std::max(mTableBCData->mTopBorderWidth, aWidth); + mTableBCData->mBStartBorderWidth = std::max(mTableBCData->mBStartBorderWidth, + aWidth); } void -BCMapCellInfo::SetTableIStartBorderWidth(int32_t aRowY, BCPixelSize aWidth) +BCMapCellInfo::SetTableIStartBorderWidth(int32_t aRowB, BCPixelSize aWidth) { - // update the left/right first cell border - if (aRowY == 0) { - if (mTableWM.IsBidiLTR()) { - mTableBCData->mLeftCellBorderWidth = aWidth; - } - else { - mTableBCData->mRightCellBorderWidth = aWidth; - } + // update the iStart first cell border + if (aRowB == 0) { + mTableBCData->mIStartCellBorderWidth = aWidth; } - mTableBCData->mLeftBorderWidth = std::max(mTableBCData->mLeftBorderWidth, - aWidth); + mTableBCData->mIStartBorderWidth = std::max(mTableBCData->mIStartBorderWidth, + aWidth); } void -BCMapCellInfo::SetTableIEndBorderWidth(int32_t aRowY, BCPixelSize aWidth) +BCMapCellInfo::SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth) { - // update the left/right first cell border - if (aRowY == 0) { - if (mTableWM.IsBidiLTR()) { - mTableBCData->mRightCellBorderWidth = aWidth; - } - else { - mTableBCData->mLeftCellBorderWidth = aWidth; - } + // update the iEnd first cell border + if (aRowB == 0) { + mTableBCData->mIEndCellBorderWidth = aWidth; } - mTableBCData->mRightBorderWidth = std::max(mTableBCData->mRightBorderWidth, - aWidth); + mTableBCData->mIEndBorderWidth = std::max(mTableBCData->mIEndBorderWidth, + aWidth); } void @@ -5583,7 +5552,7 @@ BCMapCellInfo::SetIStartBorderWidths(BCPixelSize aWidth) void BCMapCellInfo::SetTableBEndBorderWidth(BCPixelSize aWidth) { - mTableBCData->mBottomBorderWidth = std::max(mTableBCData->mBottomBorderWidth, + mTableBCData->mBEndBorderWidth = std::max(mTableBCData->mBEndBorderWidth, aWidth); } @@ -5602,10 +5571,10 @@ BCMapCellInfo::SetColumn(int32_t aColX) } void -BCMapCellInfo::IncrementRow(bool aResetToTopRowOfCell) +BCMapCellInfo::IncrementRow(bool aResetToBStartRowOfCell) { mCurrentRowFrame = - aResetToTopRowOfCell ? mStartRow : mCurrentRowFrame->GetNextRow(); + aResetToBStartRowOfCell ? mStartRow : mCurrentRowFrame->GetNextRow(); } BCCellBorder @@ -5669,7 +5638,9 @@ BCMapCellInfo::GetBStartInternalBorder() mTableWM, eLogicalSideBStart, !ADJACENT); } -/* Here is the order for storing border edges in the cell map as a cell is processed. There are +/* XXX This comment is still written in physical (horizontal-tb) terms. + + Here is the order for storing border edges in the cell map as a cell is processed. There are n=colspan top and bottom border edges per cell and n=rowspan left and right border edges per cell. 1) On the top edge of the table, store the top edge. Never store the top edge otherwise, since @@ -5736,81 +5707,81 @@ nsTableFrame::CalcBCBorders() // segments that are on the table border edges need // to be initialized only once bool tableBorderReset[4]; - for (uint32_t sideX = NS_SIDE_TOP; sideX <= NS_SIDE_LEFT; sideX++) { + for (uint32_t sideX = eLogicalSideBStart; sideX <= eLogicalSideIStart; sideX++) { tableBorderReset[sideX] = false; } - // vertical borders indexed in x-direction (cols) - BCCellBorders lastVerBorders(damageArea.ColCount() + 1, - damageArea.StartCol()); - if (!lastVerBorders.borders) ABORT0(); - BCCellBorder lastTopBorder, lastBottomBorder; - // horizontal borders indexed in x-direction (cols) - BCCellBorders lastBottomBorders(damageArea.ColCount() + 1, - damageArea.StartCol()); - if (!lastBottomBorders.borders) ABORT0(); + // block-dir borders indexed in inline-direction (cols) + BCCellBorders lastBlockDirBorders(damageArea.ColCount() + 1, + damageArea.StartCol()); + if (!lastBlockDirBorders.borders) ABORT0(); + BCCellBorder lastBStartBorder, lastBEndBorder; + // inline-dir borders indexed in inline-direction (cols) + BCCellBorders lastBEndBorders(damageArea.ColCount() + 1, + damageArea.StartCol()); + if (!lastBEndBorders.borders) ABORT0(); bool startSeg; bool gotRowBorder = false; BCMapCellInfo info(this), ajaInfo(this); BCCellBorder currentBorder, adjacentBorder; - BCCorners topCorners(damageArea.ColCount() + 1, damageArea.StartCol()); - if (!topCorners.corners) ABORT0(); - BCCorners bottomCorners(damageArea.ColCount() + 1, damageArea.StartCol()); - if (!bottomCorners.corners) ABORT0(); + BCCorners bStartCorners(damageArea.ColCount() + 1, damageArea.StartCol()); + if (!bStartCorners.corners) ABORT0(); + BCCorners bEndCorners(damageArea.ColCount() + 1, damageArea.StartCol()); + if (!bEndCorners.corners) ABORT0(); BCMapCellIterator iter(this, damageArea); for (iter.First(info); !iter.mAtEnd; iter.Next(info)) { - // see if lastTopBorder, lastBottomBorder need to be reset + // see if lastBStartBorder, lastBEndBorder need to be reset if (iter.IsNewRow()) { gotRowBorder = false; - lastTopBorder.Reset(info.mRowIndex, info.mRowSpan); - lastBottomBorder.Reset(info.GetCellEndRowIndex() + 1, info.mRowSpan); + lastBStartBorder.Reset(info.mRowIndex, info.mRowSpan); + lastBEndBorder.Reset(info.GetCellEndRowIndex() + 1, info.mRowSpan); } else if (info.mColIndex > damageArea.StartCol()) { - lastBottomBorder = lastBottomBorders[info.mColIndex - 1]; + lastBEndBorder = lastBEndBorders[info.mColIndex - 1]; if (info.mRowIndex > - (lastBottomBorder.rowIndex - lastBottomBorder.rowSpan)) { - // the top border's left edge butts against the middle of a rowspan - lastTopBorder.Reset(info.mRowIndex, info.mRowSpan); + (lastBEndBorder.rowIndex - lastBEndBorder.rowSpan)) { + // the bStart border's iStart edge butts against the middle of a rowspan + lastBStartBorder.Reset(info.mRowIndex, info.mRowSpan); } - if (lastBottomBorder.rowIndex > (info.GetCellEndRowIndex() + 1)) { - // the bottom border's left edge butts against the middle of a rowspan - lastBottomBorder.Reset(info.GetCellEndRowIndex() + 1, info.mRowSpan); + if (lastBEndBorder.rowIndex > (info.GetCellEndRowIndex() + 1)) { + // the bEnd border's iStart edge butts against the middle of a rowspan + lastBEndBorder.Reset(info.GetCellEndRowIndex() + 1, info.mRowSpan); } } - // find the dominant border considering the cell's top border and the table, - // row group, row if the border is at the top of the table, otherwise it was + // find the dominant border considering the cell's bStart border and the table, + // row group, row if the border is at the bStart of the table, otherwise it was // processed in a previous row if (0 == info.mRowIndex) { - if (!tableBorderReset[NS_SIDE_TOP]) { - propData->mTopBorderWidth = 0; - tableBorderReset[NS_SIDE_TOP] = true; + if (!tableBorderReset[eLogicalSideBStart]) { + propData->mBStartBorderWidth = 0; + tableBorderReset[eLogicalSideBStart] = true; } for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { info.SetColumn(colIdx); currentBorder = info.GetBStartEdgeBorder(); - // update/store the top left & top right corners of the seg - BCCornerInfo& tlCorner = topCorners[colIdx]; // top left + // update/store the bStart-iStart & bStart-iEnd corners of the seg + BCCornerInfo& tlCorner = bStartCorners[colIdx]; // bStart-iStart if (0 == colIdx) { - // we are on right hand side of the corner - tlCorner.Set(NS_SIDE_RIGHT, currentBorder); + // we are on the iEnd side of the corner + tlCorner.Set(eLogicalSideIEnd, currentBorder); } else { - tlCorner.Update(NS_SIDE_RIGHT, currentBorder); - tableCellMap->SetBCBorderCorner(eTopLeft, *iter.mCellMap, 0, 0, colIdx, - mozilla::css::Side(tlCorner.ownerSide), + tlCorner.Update(eLogicalSideIEnd, currentBorder); + tableCellMap->SetBCBorderCorner(eBStartIStart, *iter.mCellMap, 0, 0, colIdx, + LogicalSide(tlCorner.ownerSide), tlCorner.subWidth, tlCorner.bevel); } - topCorners[colIdx + 1].Set(NS_SIDE_LEFT, currentBorder); // top right - // update lastTopBorder and see if a new segment starts - startSeg = SetHorBorder(currentBorder, tlCorner, lastTopBorder); + bStartCorners[colIdx + 1].Set(eLogicalSideIStart, currentBorder); // bStart-iEnd + // update lastBStartBorder and see if a new segment starts + startSeg = SetInlineDirBorder(currentBorder, tlCorner, lastBStartBorder); // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(NS_SIDE_TOP, *iter.mCellMap, 0, 0, colIdx, + tableCellMap->SetBCBorderEdge(eLogicalSideBStart, *iter.mCellMap, 0, 0, colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); @@ -5821,99 +5792,99 @@ nsTableFrame::CalcBCBorders() info.SetTableBStartIStartContBCBorder(); } else { - // see if the top border needs to be the start of a segment due to a - // vertical border owning the corner + // see if the bStart border needs to be the start of a segment due to a + // block-dir border owning the corner if (info.mColIndex > 0) { BCData& data = info.mCellData->mData; - if (!data.IsTopStart()) { - mozilla::css::Side cornerSide; + if (!data.IsBStartStart()) { + LogicalSide cornerSide; bool bevel; data.GetCorner(cornerSide, bevel); - if ((NS_SIDE_TOP == cornerSide) || (NS_SIDE_BOTTOM == cornerSide)) { - data.SetTopStart(true); + if (IsBlock(cornerSide)) { + data.SetBStartStart(true); } } } } - // find the dominant border considering the cell's left border and the - // table, col group, col if the border is at the left of the table, + // find the dominant border considering the cell's iStart border and the + // table, col group, col if the border is at the iStart of the table, // otherwise it was processed in a previous col if (0 == info.mColIndex) { - if (!tableBorderReset[NS_SIDE_LEFT]) { - propData->mLeftBorderWidth = 0; - tableBorderReset[NS_SIDE_LEFT] = true; + if (!tableBorderReset[eLogicalSideIStart]) { + propData->mIStartBorderWidth = 0; + tableBorderReset[eLogicalSideIStart] = true; } info.mCurrentRowFrame = nullptr; - for (int32_t rowY = info.mRowIndex; rowY <= info.GetCellEndRowIndex(); - rowY++) { - info.IncrementRow(rowY == info.mRowIndex); + for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); + rowB++) { + info.IncrementRow(rowB == info.mRowIndex); currentBorder = info.GetIStartEdgeBorder(); - BCCornerInfo& tlCorner = (0 == rowY) ? topCorners[0] : bottomCorners[0]; - tlCorner.Update(NS_SIDE_BOTTOM, currentBorder); - tableCellMap->SetBCBorderCorner(eTopLeft, *iter.mCellMap, - iter.mRowGroupStart, rowY, 0, - mozilla::css::Side(tlCorner.ownerSide), + BCCornerInfo& tlCorner = (0 == rowB) ? bStartCorners[0] : bEndCorners[0]; + tlCorner.Update(eLogicalSideBEnd, currentBorder); + tableCellMap->SetBCBorderCorner(eBStartIStart, *iter.mCellMap, + iter.mRowGroupStart, rowB, 0, + LogicalSide(tlCorner.ownerSide), tlCorner.subWidth, tlCorner.bevel); - bottomCorners[0].Set(NS_SIDE_TOP, currentBorder); // bottom left + bEndCorners[0].Set(eLogicalSideBStart, currentBorder); // bEnd-iStart - // update lastVerBordersBorder and see if a new segment starts - startSeg = SetBorder(currentBorder, lastVerBorders[0]); + // update lastBlockDirBorders and see if a new segment starts + startSeg = SetBorder(currentBorder, lastBlockDirBorders[0]); // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(NS_SIDE_LEFT, *iter.mCellMap, - iter.mRowGroupStart, rowY, info.mColIndex, + tableCellMap->SetBCBorderEdge(eLogicalSideIStart, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.mColIndex, 1, currentBorder.owner, currentBorder.width, startSeg); - info.SetTableIStartBorderWidth(rowY , currentBorder.width); + info.SetTableIStartBorderWidth(rowB , currentBorder.width); info.SetIStartBorderWidths(currentBorder.width); info.SetRowIStartContBCBorder(); } info.SetRowGroupIStartContBCBorder(); } - // find the dominant border considering the cell's right border, adjacent + // find the dominant border considering the cell's iEnd border, adjacent // cells and the table, row group, row if (info.mNumTableCols == info.GetCellEndColIndex() + 1) { - // touches right edge of table - if (!tableBorderReset[NS_SIDE_RIGHT]) { - propData->mRightBorderWidth = 0; - tableBorderReset[NS_SIDE_RIGHT] = true; + // touches iEnd edge of table + if (!tableBorderReset[eLogicalSideIEnd]) { + propData->mIEndBorderWidth = 0; + tableBorderReset[eLogicalSideIEnd] = true; } info.mCurrentRowFrame = nullptr; - for (int32_t rowY = info.mRowIndex; rowY <= info.GetCellEndRowIndex(); - rowY++) { - info.IncrementRow(rowY == info.mRowIndex); + for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); + rowB++) { + info.IncrementRow(rowB == info.mRowIndex); currentBorder = info.GetIEndEdgeBorder(); - // update/store the top right & bottom right corners - BCCornerInfo& trCorner = (0 == rowY) ? - topCorners[info.GetCellEndColIndex() + 1] : - bottomCorners[info.GetCellEndColIndex() + 1]; - trCorner.Update(NS_SIDE_BOTTOM, currentBorder); // top right - tableCellMap->SetBCBorderCorner(eTopRight, *iter.mCellMap, - iter.mRowGroupStart, rowY, + // update/store the bStart-iEnd & bEnd-iEnd corners + BCCornerInfo& trCorner = (0 == rowB) ? + bStartCorners[info.GetCellEndColIndex() + 1] : + bEndCorners[info.GetCellEndColIndex() + 1]; + trCorner.Update(eLogicalSideBEnd, currentBorder); // bStart-iEnd + tableCellMap->SetBCBorderCorner(eBStartIEnd, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), - mozilla::css::Side(trCorner.ownerSide), + LogicalSide(trCorner.ownerSide), trCorner.subWidth, trCorner.bevel); - BCCornerInfo& brCorner = bottomCorners[info.GetCellEndColIndex() + 1]; - brCorner.Set(NS_SIDE_TOP, currentBorder); // bottom right - tableCellMap->SetBCBorderCorner(eBottomRight, *iter.mCellMap, - iter.mRowGroupStart, rowY, + BCCornerInfo& brCorner = bEndCorners[info.GetCellEndColIndex() + 1]; + brCorner.Set(eLogicalSideBStart, currentBorder); // bEnd-iEnd + tableCellMap->SetBCBorderCorner(eBEndIEnd, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), - mozilla::css::Side(brCorner.ownerSide), + LogicalSide(brCorner.ownerSide), brCorner.subWidth, brCorner.bevel); - // update lastVerBorders and see if a new segment starts + // update lastBlockDirBorders and see if a new segment starts startSeg = SetBorder(currentBorder, - lastVerBorders[info.GetCellEndColIndex() + 1]); + lastBlockDirBorders[info.GetCellEndColIndex() + 1]); // store the border segment in the cell map and update cellBorders - tableCellMap->SetBCBorderEdge(NS_SIDE_RIGHT, *iter.mCellMap, - iter.mRowGroupStart, rowY, + tableCellMap->SetBCBorderEdge(eLogicalSideIEnd, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), 1, currentBorder.owner, currentBorder.width, startSeg); - info.SetTableIEndBorderWidth(rowY, currentBorder.width); + info.SetTableIEndBorderWidth(rowB, currentBorder.width); info.SetIEndBorderWidths(currentBorder.width); info.SetRowIEndContBCBorder(); } @@ -5922,133 +5893,133 @@ nsTableFrame::CalcBCBorders() else { int32_t segLength = 0; BCMapCellInfo priorAjaInfo(this); - for (int32_t rowY = info.mRowIndex; rowY <= info.GetCellEndRowIndex(); - rowY += segLength) { - iter.PeekRight(info, rowY, ajaInfo); + for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); + rowB += segLength) { + iter.PeekIEnd(info, rowB, ajaInfo); currentBorder = info.GetIEndInternalBorder(); adjacentBorder = ajaInfo.GetIStartInternalBorder(); currentBorder = CompareBorders(!CELL_CORNER, currentBorder, - adjacentBorder, !HORIZONTAL); + adjacentBorder, !INLINE_DIR); - segLength = std::max(1, ajaInfo.mRowIndex + ajaInfo.mRowSpan - rowY); - segLength = std::min(segLength, info.mRowIndex + info.mRowSpan - rowY); + segLength = std::max(1, ajaInfo.mRowIndex + ajaInfo.mRowSpan - rowB); + segLength = std::min(segLength, info.mRowIndex + info.mRowSpan - rowB); - // update lastVerBorders and see if a new segment starts + // update lastBlockDirBorders and see if a new segment starts startSeg = SetBorder(currentBorder, - lastVerBorders[info.GetCellEndColIndex() + 1]); + lastBlockDirBorders[info.GetCellEndColIndex() + 1]); // store the border segment in the cell map and update cellBorders if (info.GetCellEndColIndex() < damageArea.EndCol() && - rowY >= damageArea.StartRow() && rowY < damageArea.EndRow()) { - tableCellMap->SetBCBorderEdge(NS_SIDE_RIGHT, *iter.mCellMap, - iter.mRowGroupStart, rowY, + rowB >= damageArea.StartRow() && rowB < damageArea.EndRow()) { + tableCellMap->SetBCBorderEdge(eLogicalSideIEnd, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), segLength, currentBorder.owner, currentBorder.width, startSeg); info.SetIEndBorderWidths(currentBorder.width); ajaInfo.SetIStartBorderWidths(currentBorder.width); } - // update the top right corner - bool hitsSpanOnRight = (rowY > ajaInfo.mRowIndex) && - (rowY < ajaInfo.mRowIndex + ajaInfo.mRowSpan); - BCCornerInfo* trCorner = ((0 == rowY) || hitsSpanOnRight) ? - &topCorners[info.GetCellEndColIndex() + 1] : - &bottomCorners[info.GetCellEndColIndex() + 1]; - trCorner->Update(NS_SIDE_BOTTOM, currentBorder); + // update the bStart-iEnd corner + bool hitsSpanOnIEnd = (rowB > ajaInfo.mRowIndex) && + (rowB < ajaInfo.mRowIndex + ajaInfo.mRowSpan); + BCCornerInfo* trCorner = ((0 == rowB) || hitsSpanOnIEnd) ? + &bStartCorners[info.GetCellEndColIndex() + 1] : + &bEndCorners[info.GetCellEndColIndex() + 1]; + trCorner->Update(eLogicalSideBEnd, currentBorder); // if this is not the first time through, - // consider the segment to the right - if (rowY != info.mRowIndex) { + // consider the segment to the iEnd side + if (rowB != info.mRowIndex) { currentBorder = priorAjaInfo.GetBEndInternalBorder(); adjacentBorder = ajaInfo.GetBStartInternalBorder(); currentBorder = CompareBorders(!CELL_CORNER, currentBorder, - adjacentBorder, HORIZONTAL); - trCorner->Update(NS_SIDE_RIGHT, currentBorder); + adjacentBorder, INLINE_DIR); + trCorner->Update(eLogicalSideIEnd, currentBorder); } - // store the top right corner in the cell map + // store the bStart-iEnd corner in the cell map if (info.GetCellEndColIndex() < damageArea.EndCol() && - rowY >= damageArea.StartRow()) { - if (0 != rowY) { - tableCellMap->SetBCBorderCorner(eTopRight, *iter.mCellMap, - iter.mRowGroupStart, rowY, + rowB >= damageArea.StartRow()) { + if (0 != rowB) { + tableCellMap->SetBCBorderCorner(eBStartIEnd, *iter.mCellMap, + iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), - mozilla::css::Side(trCorner->ownerSide), + LogicalSide(trCorner->ownerSide), trCorner->subWidth, trCorner->bevel); } // store any corners this cell spans together with the aja cell - for (int32_t rX = rowY + 1; rX < rowY + segLength; rX++) { - tableCellMap->SetBCBorderCorner(eBottomRight, *iter.mCellMap, + for (int32_t rX = rowB + 1; rX < rowB + segLength; rX++) { + tableCellMap->SetBCBorderCorner(eBEndIEnd, *iter.mCellMap, iter.mRowGroupStart, rX, info.GetCellEndColIndex(), - mozilla::css::Side(trCorner->ownerSide), + LogicalSide(trCorner->ownerSide), trCorner->subWidth, false); } } - // update bottom right corner, topCorners, bottomCorners - hitsSpanOnRight = (rowY + segLength < + // update bEnd-iEnd corner, bStartCorners, bEndCorners + hitsSpanOnIEnd = (rowB + segLength < ajaInfo.mRowIndex + ajaInfo.mRowSpan); - BCCornerInfo& brCorner = (hitsSpanOnRight) ? - topCorners[info.GetCellEndColIndex() + 1] : - bottomCorners[info.GetCellEndColIndex() + 1]; - brCorner.Set(NS_SIDE_TOP, currentBorder); + BCCornerInfo& brCorner = (hitsSpanOnIEnd) ? + bStartCorners[info.GetCellEndColIndex() + 1] : + bEndCorners[info.GetCellEndColIndex() + 1]; + brCorner.Set(eLogicalSideBStart, currentBorder); priorAjaInfo = ajaInfo; } } for (int32_t colIdx = info.mColIndex + 1; colIdx <= info.GetCellEndColIndex(); colIdx++) { - lastVerBorders[colIdx].Reset(0,1); + lastBlockDirBorders[colIdx].Reset(0,1); } - // find the dominant border considering the cell's bottom border, adjacent + // find the dominant border considering the cell's bEnd border, adjacent // cells and the table, row group, row if (info.mNumTableRows == info.GetCellEndRowIndex() + 1) { - // touches bottom edge of table - if (!tableBorderReset[NS_SIDE_BOTTOM]) { - propData->mBottomBorderWidth = 0; - tableBorderReset[NS_SIDE_BOTTOM] = true; + // touches bEnd edge of table + if (!tableBorderReset[eLogicalSideBEnd]) { + propData->mBEndBorderWidth = 0; + tableBorderReset[eLogicalSideBEnd] = true; } for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { info.SetColumn(colIdx); currentBorder = info.GetBEndEdgeBorder(); - // update/store the bottom left & bottom right corners - BCCornerInfo& blCorner = bottomCorners[colIdx]; // bottom left - blCorner.Update(NS_SIDE_RIGHT, currentBorder); - tableCellMap->SetBCBorderCorner(eBottomLeft, *iter.mCellMap, + // update/store the bEnd-iStart & bEnd-IEnd corners + BCCornerInfo& blCorner = bEndCorners[colIdx]; // bEnd-iStart + blCorner.Update(eLogicalSideIEnd, currentBorder); + tableCellMap->SetBCBorderCorner(eBEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, - mozilla::css::Side(blCorner.ownerSide), + LogicalSide(blCorner.ownerSide), blCorner.subWidth, blCorner.bevel); - BCCornerInfo& brCorner = bottomCorners[colIdx + 1]; // bottom right - brCorner.Update(NS_SIDE_LEFT, currentBorder); - if (info.mNumTableCols == colIdx + 1) { // lower right corner of the table - tableCellMap->SetBCBorderCorner(eBottomRight, *iter.mCellMap, + BCCornerInfo& brCorner = bEndCorners[colIdx + 1]; // bEnd-iEnd + brCorner.Update(eLogicalSideIStart, currentBorder); + if (info.mNumTableCols == colIdx + 1) { // bEnd-IEnd corner of the table + tableCellMap->SetBCBorderCorner(eBEndIEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, - mozilla::css::Side(brCorner.ownerSide), + LogicalSide(brCorner.ownerSide), brCorner.subWidth, brCorner.bevel, true); } - // update lastBottomBorder and see if a new segment starts - startSeg = SetHorBorder(currentBorder, blCorner, lastBottomBorder); + // update lastBEndBorder and see if a new segment starts + startSeg = SetInlineDirBorder(currentBorder, blCorner, lastBEndBorder); if (!startSeg) { // make sure that we did not compare apples to oranges i.e. the - // current border should be a continuation of the lastBottomBorder, - // as it is a bottom border + // current border should be a continuation of the lastBEndBorder, + // as it is a bEnd border // add 1 to the info.GetCellEndRowIndex() - startSeg = (lastBottomBorder.rowIndex != + startSeg = (lastBEndBorder.rowIndex != (info.GetCellEndRowIndex() + 1)); } // store the border segment in the cell map and update cellBorders - tableCellMap->SetBCBorderEdge(NS_SIDE_BOTTOM, *iter.mCellMap, + tableCellMap->SetBCBorderEdge(eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); - // update lastBottomBorders - lastBottomBorder.rowIndex = info.GetCellEndRowIndex() + 1; - lastBottomBorder.rowSpan = info.mRowSpan; - lastBottomBorders[colIdx] = lastBottomBorder; + // update lastBEndBorders + lastBEndBorder.rowIndex = info.GetCellEndRowIndex() + 1; + lastBEndBorder.rowSpan = info.mRowSpan; + lastBEndBorders[colIdx] = lastBEndBorder; info.SetBEndBorderWidths(currentBorder.width); info.SetTableBEndBorderWidth(currentBorder.width); @@ -6061,77 +6032,77 @@ nsTableFrame::CalcBCBorders() int32_t segLength = 0; for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx += segLength) { - iter.PeekBottom(info, colIdx, ajaInfo); + iter.PeekBEnd(info, colIdx, ajaInfo); currentBorder = info.GetBEndInternalBorder(); adjacentBorder = ajaInfo.GetBStartInternalBorder(); currentBorder = CompareBorders(!CELL_CORNER, currentBorder, - adjacentBorder, HORIZONTAL); + adjacentBorder, INLINE_DIR); segLength = std::max(1, ajaInfo.mColIndex + ajaInfo.mColSpan - colIdx); segLength = std::min(segLength, info.mColIndex + info.mColSpan - colIdx); - // update, store the bottom left corner - BCCornerInfo& blCorner = bottomCorners[colIdx]; // bottom left + // update, store the bEnd-iStart corner + BCCornerInfo& blCorner = bEndCorners[colIdx]; // bEnd-iStart bool hitsSpanBelow = (colIdx > ajaInfo.mColIndex) && (colIdx < ajaInfo.mColIndex + ajaInfo.mColSpan); bool update = true; if (colIdx == info.mColIndex && colIdx > damageArea.StartCol()) { - int32_t prevRowIndex = lastBottomBorders[colIdx - 1].rowIndex; + int32_t prevRowIndex = lastBEndBorders[colIdx - 1].rowIndex; if (prevRowIndex > info.GetCellEndRowIndex() + 1) { - // hits a rowspan on the right + // hits a rowspan on the iEnd side update = false; - // the corner was taken care of during the cell on the left + // the corner was taken care of during the cell on the iStart side } else if (prevRowIndex < info.GetCellEndRowIndex() + 1) { - // spans below the cell to the left - topCorners[colIdx] = blCorner; - blCorner.Set(NS_SIDE_RIGHT, currentBorder); + // spans below the cell to the iStart side + bStartCorners[colIdx] = blCorner; + blCorner.Set(eLogicalSideIEnd, currentBorder); update = false; } } if (update) { - blCorner.Update(NS_SIDE_RIGHT, currentBorder); + blCorner.Update(eLogicalSideIEnd, currentBorder); } if (info.GetCellEndRowIndex() < damageArea.EndRow() && colIdx >= damageArea.StartCol()) { if (hitsSpanBelow) { - tableCellMap->SetBCBorderCorner(eBottomLeft, *iter.mCellMap, + tableCellMap->SetBCBorderCorner(eBEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, - mozilla::css::Side(blCorner.ownerSide), + LogicalSide(blCorner.ownerSide), blCorner.subWidth, blCorner.bevel); } // store any corners this cell spans together with the aja cell for (int32_t c = colIdx + 1; c < colIdx + segLength; c++) { - BCCornerInfo& corner = bottomCorners[c]; - corner.Set(NS_SIDE_RIGHT, currentBorder); - tableCellMap->SetBCBorderCorner(eBottomLeft, *iter.mCellMap, + BCCornerInfo& corner = bEndCorners[c]; + corner.Set(eLogicalSideIEnd, currentBorder); + tableCellMap->SetBCBorderCorner(eBEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), c, - mozilla::css::Side(corner.ownerSide), + LogicalSide(corner.ownerSide), corner.subWidth, false); } } - // update lastBottomBorders and see if a new segment starts - startSeg = SetHorBorder(currentBorder, blCorner, lastBottomBorder); + // update lastBEndBorders and see if a new segment starts + startSeg = SetInlineDirBorder(currentBorder, blCorner, lastBEndBorder); if (!startSeg) { // make sure that we did not compare apples to oranges i.e. the - // current border should be a continuation of the lastBottomBorder, - // as it is a bottom border + // current border should be a continuation of the lastBEndBorder, + // as it is a bEnd border // add 1 to the info.GetCellEndRowIndex() - startSeg = (lastBottomBorder.rowIndex != + startSeg = (lastBEndBorder.rowIndex != info.GetCellEndRowIndex() + 1); } - lastBottomBorder.rowIndex = info.GetCellEndRowIndex() + 1; - lastBottomBorder.rowSpan = info.mRowSpan; + lastBEndBorder.rowIndex = info.GetCellEndRowIndex() + 1; + lastBEndBorder.rowSpan = info.mRowSpan; for (int32_t c = colIdx; c < colIdx + segLength; c++) { - lastBottomBorders[c] = lastBottomBorder; + lastBEndBorders[c] = lastBEndBorder; } // store the border segment the cell map and update cellBorders if (info.GetCellEndRowIndex() < damageArea.EndRow() && colIdx >= damageArea.StartCol() && colIdx < damageArea.EndCol()) { - tableCellMap->SetBCBorderEdge(NS_SIDE_BOTTOM, *iter.mCellMap, + tableCellMap->SetBCBorderEdge(eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, segLength, currentBorder.owner, @@ -6139,16 +6110,16 @@ nsTableFrame::CalcBCBorders() info.SetBEndBorderWidths(currentBorder.width); ajaInfo.SetBStartBorderWidths(currentBorder.width); } - // update bottom right corner - BCCornerInfo& brCorner = bottomCorners[colIdx + segLength]; - brCorner.Update(NS_SIDE_LEFT, currentBorder); + // update bEnd-iEnd corner + BCCornerInfo& brCorner = bEndCorners[colIdx + segLength]; + brCorner.Update(eLogicalSideIStart, currentBorder); } if (!gotRowBorder && 1 == info.mRowSpan && (ajaInfo.mStartRow || info.mRgAtEnd)) { //get continuous row/row group border - //we need to check the row group's bottom border if this is + //we need to check the row group's bEnd border if this is //the last row in the row group, but only a cell with rowspan=1 - //will know whether *this* row is at the bottom + //will know whether *this* row is at the bEnd const nsIFrame* nextRowGroup = ajaInfo.mRgAtStart ? ajaInfo.mRowGroup : nullptr; info.SetInnerRowGroupBEndContBCBorder(nextRowGroup, ajaInfo.mStartRow); @@ -6156,26 +6127,25 @@ nsTableFrame::CalcBCBorders() } } - // see if the cell to the right had a rowspan and its lower left border - // needs be joined with this one's bottom - // if there is a cell to the right and the cell to right was a rowspan + // see if the cell to the iEnd side had a rowspan and its bEnd-iStart border + // needs be joined with this one's bEnd + // if there is a cell to the iEnd and the cell to iEnd side was a rowspan if ((info.mNumTableCols != info.GetCellEndColIndex() + 1) && - (lastBottomBorders[info.GetCellEndColIndex() + 1].rowSpan > 1)) { - BCCornerInfo& corner = bottomCorners[info.GetCellEndColIndex() + 1]; - if ((NS_SIDE_TOP != corner.ownerSide) && - (NS_SIDE_BOTTOM != corner.ownerSide)) { - // not a vertical owner - BCCellBorder& thisBorder = lastBottomBorder; - BCCellBorder& nextBorder = lastBottomBorders[info.mColIndex + 1]; + (lastBEndBorders[info.GetCellEndColIndex() + 1].rowSpan > 1)) { + BCCornerInfo& corner = bEndCorners[info.GetCellEndColIndex() + 1]; + if (!IsBlock(LogicalSide(corner.ownerSide))) { + // not a block-dir owner + BCCellBorder& thisBorder = lastBEndBorder; + BCCellBorder& nextBorder = lastBEndBorders[info.mColIndex + 1]; if ((thisBorder.color == nextBorder.color) && (thisBorder.width == nextBorder.width) && (thisBorder.style == nextBorder.style)) { // set the flag on the next border indicating it is not the start of a // new segment if (iter.mCellMap) { - tableCellMap->ResetTopStart(NS_SIDE_BOTTOM, *iter.mCellMap, - info.GetCellEndRowIndex(), - info.GetCellEndColIndex() + 1); + tableCellMap->ResetBStartStart(eLogicalSideBEnd, *iter.mCellMap, + info.GetCellEndRowIndex(), + info.GetCellEndColIndex() + 1); } } } @@ -6191,24 +6161,24 @@ nsTableFrame::CalcBCBorders() class BCPaintBorderIterator; -struct BCVerticalSeg +struct BCBlockDirSeg { - BCVerticalSeg(); + BCBlockDirSeg(); void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, - BCPixelSize aVerSegWidth, - BCPixelSize aHorSegHeight); + BCPixelSize aBlockSegISize, + BCPixelSize aInlineSegBSize); void Initialize(BCPaintBorderIterator& aIter); - void GetBottomCorner(BCPaintBorderIterator& aIter, - BCPixelSize aHorSegHeight); + void GetBEndCorner(BCPaintBorderIterator& aIter, + BCPixelSize aInlineSegBSize); void Paint(BCPaintBorderIterator& aIter, nsRenderingContext& aRenderingContext, - BCPixelSize aHorSegHeight); - void AdvanceOffsetY(); + BCPixelSize aInlineSegBSize); + void AdvanceOffsetB(); void IncludeCurrentBorder(BCPaintBorderIterator& aIter); @@ -6216,10 +6186,10 @@ struct BCVerticalSeg nsTableColFrame* mCol; int32_t mColWidth; }; - nscoord mOffsetX; // x-offset with respect to the table edge - nscoord mOffsetY; // y-offset with respect to the table edge - nscoord mLength; // vertical length including corners - BCPixelSize mWidth; // width in pixels + nscoord mOffsetI; // i-offset with respect to the table edge + nscoord mOffsetB; // b-offset with respect to the table edge + nscoord mLength; // block-dir length including corners + BCPixelSize mWidth; // thickness in pixels nsTableCellFrame* mAjaCell; // previous sibling to the first cell // where the segment starts, it can be @@ -6233,43 +6203,43 @@ struct BCVerticalSeg uint8_t mOwner; // owner of the border, defines the // style - mozilla::css::Side mTopBevelSide; // direction to bevel at the top - nscoord mTopBevelOffset; // how much to bevel at the top - BCPixelSize mBottomHorSegHeight; // height of the crossing - //horizontal border - nscoord mBottomOffset; // how much longer is the segment due - // to the horizontal border, by this + LogicalSide mBStartBevelSide; // direction to bevel at the bStart + nscoord mBStartBevelOffset; // how much to bevel at the bStart + BCPixelSize mBEndInlineSegBSize; // bSize of the crossing + // inline-dir border + nscoord mBEndOffset; // how much longer is the segment due + // to the inline-dir border, by this // amount the next segment needs to be // shifted. - bool mIsBottomBevel; // should we bevel at the bottom + bool mIsBEndBevel; // should we bevel at the bEnd }; -struct BCHorizontalSeg +struct BCInlineDirSeg { - BCHorizontalSeg(); + BCInlineDirSeg(); void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, - BCPixelSize aBottomVerSegWidth, - BCPixelSize aHorSegHeight); - void GetRightCorner(BCPaintBorderIterator& aIter, - BCPixelSize aLeftSegWidth); - void AdvanceOffsetX(int32_t aIncrement); + BCPixelSize aBEndBlockSegISize, + BCPixelSize aInlineSegBSize); + void GetIEndCorner(BCPaintBorderIterator& aIter, + BCPixelSize aIStartSegISize); + void AdvanceOffsetI(); void IncludeCurrentBorder(BCPaintBorderIterator& aIter); void Paint(BCPaintBorderIterator& aIter, - nsRenderingContext& aRenderingContext); + nsRenderingContext& aRenderingContext); - nscoord mOffsetX; // x-offset with respect to the table edge - nscoord mOffsetY; // y-offset with respect to the table edge - nscoord mLength; // horizontal length including corners - BCPixelSize mWidth; // border width in pixels - nscoord mLeftBevelOffset; // how much to bevel at the left - mozilla::css::Side mLeftBevelSide; // direction to bevel at the left - bool mIsRightBevel; // should we bevel at the right end - nscoord mRightBevelOffset; // how much to bevel at the right - mozilla::css::Side mRightBevelSide; // direction to bevel at the right + nscoord mOffsetI; // i-offset with respect to the table edge + nscoord mOffsetB; // b-offset with respect to the table edge + nscoord mLength; // inline-dir length including corners + BCPixelSize mWidth; // border thickness in pixels + nscoord mIStartBevelOffset; // how much to bevel at the iStart + LogicalSide mIStartBevelSide; // direction to bevel at the iStart + bool mIsIEndBevel; // should we bevel at the iEnd end + nscoord mIEndBevelOffset; // how much to bevel at the iEnd + LogicalSide mIEndBevelSide; // direction to bevel at the iEnd nscoord mEndOffset; // how much longer is the segment due - // to the vertical border, by this + // to the block-dir border, by this // amount the next segment needs to be // shifted. uint8_t mOwner; // owner of the border, defines the @@ -6280,39 +6250,38 @@ struct BCHorizontalSeg // the owner of a segment }; -// Iterates over borders (left border, corner, top border) in the cell map within a damage area -// from left to right, top to bottom. All members are in terms of the 1st in flow frames, except +// Iterates over borders (iStart border, corner, bStart border) in the cell map within a damage area +// from iStart to iEnd, bStart to bEnd. All members are in terms of the 1st in flow frames, except // where suffixed by InFlow. class BCPaintBorderIterator { public: explicit BCPaintBorderIterator(nsTableFrame* aTable); - ~BCPaintBorderIterator() { if (mVerInfo) { - delete [] mVerInfo; + ~BCPaintBorderIterator() { if (mBlockDirInfo) { + delete [] mBlockDirInfo; }} void Reset(); /** * Determine the damage area in terms of rows and columns and finalize - * mInitialOffsetX and mInitialOffsetY. + * mInitialOffsetI and mInitialOffsetB. * @param aDirtyRect - dirty rect in table coordinates * @return - true if we need to paint something given dirty rect */ bool SetDamageArea(const nsRect& aDamageRect); void First(); void Next(); - void AccumulateOrPaintHorizontalSegment(nsRenderingContext& aRenderingContext); - void AccumulateOrPaintVerticalSegment(nsRenderingContext& aRenderingContext); + void AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRenderingContext); + void AccumulateOrPaintBlockDirSegment(nsRenderingContext& aRenderingContext); void ResetVerInfo(); void StoreColumnWidth(int32_t aIndex); - bool VerticalSegmentOwnsCorner(); + bool BlockDirSegmentOwnsCorner(); nsTableFrame* mTable; nsTableFrame* mTableFirstInFlow; nsTableCellMap* mTableCellMap; nsCellMap* mCellMap; WritingMode mTableWM; - int32_t mColInc; // +1 for ltr -1 for rtl const nsStyleBackground* mTableBgColor; nsTableFrame::RowGroupArray mRowGroups; @@ -6322,9 +6291,9 @@ public: bool mIsRepeatedFooter; nsTableRowGroupFrame* mStartRg; // first row group in the damagearea int32_t mRgIndex; // current row group index in the - // mRowgroups array + // mRowgroups array int32_t mFifRgFirstRowIndex; // start row index of the first in - // flow of the row group + // flow of the row group int32_t mRgFirstRowIndex; // row index of the first row in the // row group int32_t mRgLastRowIndex; // row index of the last row in the row @@ -6342,7 +6311,7 @@ public: // we're not bool mIsNewRow; bool mAtEnd; // the iterator cycled over all - // borders + // borders nsTableRowFrame* mPrevRow; nsTableRowFrame* mRow; nsTableRowFrame* mStartRow; //first row in a inside the damagearea @@ -6355,49 +6324,50 @@ public: BCCellData* mCellData; BCData* mBCData; - bool IsTableTopMost() {return (mRowIndex == 0) && !mTable->GetPrevInFlow();} - bool IsTableRightMost() {return (mColIndex >= mNumTableCols);} - bool IsTableBottomMost() {return (mRowIndex >= mNumTableRows) && !mTable->GetNextInFlow();} - bool IsTableLeftMost() {return (mColIndex == 0);} - bool IsDamageAreaTopMost() const + bool IsTableBStartMost() {return (mRowIndex == 0) && !mTable->GetPrevInFlow();} + bool IsTableIEndMost() {return (mColIndex >= mNumTableCols);} + bool IsTableBEndMost() {return (mRowIndex >= mNumTableRows) && !mTable->GetNextInFlow();} + bool IsTableIStartMost() {return (mColIndex == 0);} + bool IsDamageAreaBStartMost() const { return mRowIndex == mDamageArea.StartRow(); } - bool IsDamageAreaRightMost() const + bool IsDamageAreaIEndMost() const { return mColIndex >= mDamageArea.EndCol(); } - bool IsDamageAreaBottomMost() const + bool IsDamageAreaBEndMost() const { return mRowIndex >= mDamageArea.EndRow(); } - bool IsDamageAreaLeftMost() const + bool IsDamageAreaIStartMost() const { return mColIndex == mDamageArea.StartCol(); } int32_t GetRelativeColIndex() const { return mColIndex - mDamageArea.StartCol(); } TableArea mDamageArea; // damageArea in cellmap coordinates - bool IsAfterRepeatedHeader() { return !mIsRepeatedHeader && (mRowIndex == (mRepeatedHeaderRowIndex + 1));} + bool IsAfterRepeatedHeader() + { return !mIsRepeatedHeader && (mRowIndex == (mRepeatedHeaderRowIndex + 1)); } bool StartRepeatedFooter() const { return mIsRepeatedFooter && mRowIndex == mRgFirstRowIndex && mRowIndex != mDamageArea.StartRow(); } - nscoord mInitialOffsetX; // offsetX of the first border with + nscoord mInitialOffsetI; // offsetI of the first border with // respect to the table - nscoord mInitialOffsetY; // offsetY of the first border with + nscoord mInitialOffsetB; // offsetB of the first border with // respect to the table - nscoord mNextOffsetY; // offsetY of the next segment - BCVerticalSeg* mVerInfo; // this array is used differently when - // horizontal and vertical borders are drawn - // When horizontal border are drawn we cache + nscoord mNextOffsetB; // offsetB of the next segment + BCBlockDirSeg* mBlockDirInfo; // this array is used differently when + // inline-dir and block-dir borders are drawn + // When inline-dir border are drawn we cache // the column widths and the width of the - // vertical borders that arrive from top - // When we draw vertical borders we store - // lengths and width for vertical borders + // block-dir borders that arrive from bStart + // When we draw block-dir borders we store + // lengths and width for block-dir borders // before they are drawn while we move over // the columns in the damage area // It has one more elements than columns are - //in the table. - BCHorizontalSeg mHorSeg; // the horizontal segment while we + // in the table. + BCInlineDirSeg mInlineSeg; // the inline-dir segment while we // move over the colums - BCPixelSize mPrevHorSegHeight; // the height of the previous - // horizontal border + BCPixelSize mPrevInlineSegBSize; // the bSize of the previous + // inline-dir border private: @@ -6415,10 +6385,10 @@ BCPaintBorderIterator::BCPaintBorderIterator(nsTableFrame* aTable) , mTableCellMap(aTable->GetCellMap()) , mTableWM(aTable->StyleContext()) { - mVerInfo = nullptr; + mBlockDirInfo = nullptr; LogicalMargin childAreaOffset = mTable->GetChildAreaOffset(mTableWM, nullptr); // y position of first row in damage area - mInitialOffsetY = + mInitialOffsetB = mTable->GetPrevInFlow() ? 0 : childAreaOffset.BStart(mTableWM); mNumTableRows = mTable->GetRowCount(); mNumTableCols = mTable->GetColCount(); @@ -6428,8 +6398,6 @@ BCPaintBorderIterator::BCPaintBorderIterator(nsTableFrame* aTable) // initialize to a non existing index mRepeatedHeaderRowIndex = -99; - mColInc = mTableWM.IsBidiLTR() ? 1 : -1; - nsIFrame* bgFrame = nsCSSRendering::FindNonTransparentBackgroundFrame(aTable); mTableBgColor = bgFrame->StyleBackground(); @@ -6438,26 +6406,27 @@ BCPaintBorderIterator::BCPaintBorderIterator(nsTableFrame* aTable) bool BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) { - + nscoord containerWidth = mTable->GetRect().width; + LogicalRect dirtyRect(mTableWM, aDirtyRect, containerWidth); uint32_t startRowIndex, endRowIndex, startColIndex, endColIndex; startRowIndex = endRowIndex = startColIndex = endColIndex = 0; bool done = false; bool haveIntersect = false; // find startRowIndex, endRowIndex - nscoord rowY = mInitialOffsetY; + nscoord rowB = mInitialOffsetB; nsPresContext* presContext = mTable->PresContext(); - for (uint32_t rgX = 0; rgX < mRowGroups.Length() && !done; rgX++) { - nsTableRowGroupFrame* rgFrame = mRowGroups[rgX]; + for (uint32_t rgIdx = 0; rgIdx < mRowGroups.Length() && !done; rgIdx++) { + nsTableRowGroupFrame* rgFrame = mRowGroups[rgIdx]; for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) { // get the row rect relative to the table rather than the row group - nsSize rowSize = rowFrame->GetSize(); + nscoord rowBSize = rowFrame->BSize(mTableWM); if (haveIntersect) { // conservatively estimate the half border widths outside the row nscoord borderHalf = mTable->GetPrevInFlow() ? 0 : presContext->DevPixelsToAppUnits( rowFrame->GetBStartBCBorderWidth() + 1); - if (aDirtyRect.YMost() >= rowY - borderHalf) { + if (dirtyRect.BEnd(mTableWM) >= rowB - borderHalf) { nsTableRowFrame* fifRow = static_cast(rowFrame->FirstInFlow()); endRowIndex = fifRow->GetRowIndex(); @@ -6469,7 +6438,7 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) nscoord borderHalf = mTable->GetNextInFlow() ? 0 : presContext->DevPixelsToAppUnits( rowFrame->GetBEndBCBorderWidth() + 1); - if (rowY + rowSize.height + borderHalf >= aDirtyRect.y) { + if (rowB + rowBSize + borderHalf >= dirtyRect.BStart(mTableWM)) { mStartRg = rgFrame; mStartRow = rowFrame; nsTableRowFrame* fifRow = @@ -6478,13 +6447,13 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) haveIntersect = true; } else { - mInitialOffsetY += rowSize.height; + mInitialOffsetB += rowBSize; } } - rowY += rowSize.height; + rowB += rowBSize; } } - mNextOffsetY = mInitialOffsetY; + mNextOffsetB = mInitialOffsetB; // XXX comment refers to the obsolete NS_FRAME_OUTSIDE_CHILDREN flag // XXX but I don't understand it, so not changing it for now @@ -6497,61 +6466,40 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) haveIntersect = false; if (0 == mNumTableCols) return false; - int32_t leftCol, rightCol; // columns are in the range [leftCol, rightCol) LogicalMargin childAreaOffset = mTable->GetChildAreaOffset(mTableWM, nullptr); - if (mTableWM.IsBidiLTR()) { - // x position of first col in damage area - mInitialOffsetX = childAreaOffset.IStart(mTableWM); - leftCol = 0; - rightCol = mNumTableCols; - } else { - // x position of first col in damage area - mInitialOffsetX = - mTable->GetRect().width - childAreaOffset.IStart(mTableWM); - leftCol = mNumTableCols-1; - rightCol = -1; - } + + // inline position of first col in damage area + mInitialOffsetI = childAreaOffset.IStart(mTableWM); + nscoord x = 0; - int32_t colX; - for (colX = leftCol; colX != rightCol; colX += mColInc) { - nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(colX); + int32_t colIdx; + for (colIdx = 0; colIdx != mNumTableCols; colIdx++) { + nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(colIdx); if (!colFrame) ABORT1(false); // get the col rect relative to the table rather than the col group - nsSize size = colFrame->GetSize(); + nscoord colISize = colFrame->ISize(mTableWM); if (haveIntersect) { - // conservatively estimate the left half border width outside the col - nscoord istartBorderHalf = mTable->PresContext()->DevPixelsToAppUnits(colFrame->GetIStartBorderWidth() + 1); - if (aDirtyRect.XMost() >= x - istartBorderHalf) { - endColIndex = colX; + // conservatively estimate the iStart half border width outside the col + nscoord iStartBorderHalf = mTable->PresContext()->DevPixelsToAppUnits(colFrame->GetIStartBorderWidth() + 1); + if (dirtyRect.IEnd(mTableWM) >= x - iStartBorderHalf) { + endColIndex = colIdx; } else break; } else { - // conservatively estimate the right half border width outside the col - nscoord iendBorderHalf = + // conservatively estimate the iEnd half border width outside the col + nscoord iEndBorderHalf = mTable->PresContext()->DevPixelsToAppUnits(colFrame->GetIEndBorderWidth() + 1); - if ((x + size.width + iendBorderHalf) >= aDirtyRect.x) { - startColIndex = endColIndex = colX; + if (x + colISize + iEndBorderHalf >= dirtyRect.IStart(mTableWM)) { + startColIndex = endColIndex = colIdx; haveIntersect = true; } else { - mInitialOffsetX += mColInc * size.width; + mInitialOffsetI += colISize; } } - x += size.width; - } - if (!mTableWM.IsBidiLTR()) { - uint32_t temp; - mInitialOffsetX = - mTable->GetRect().width - childAreaOffset.IStart(mTableWM); - temp = startColIndex; startColIndex = endColIndex; endColIndex = temp; - for (uint32_t column = 0; column < startColIndex; column++) { - nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(column); - if (!colFrame) ABORT1(false); - nsSize size = colFrame->GetSize(); - mInitialOffsetX += mColInc * size.width; - } + x += colISize; } if (!haveIntersect) return false; @@ -6560,8 +6508,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) 1 + endRowIndex - startRowIndex); Reset(); - mVerInfo = new BCVerticalSeg[mDamageArea.ColCount() + 1]; - if (!mVerInfo) + mBlockDirInfo = new BCBlockDirSeg[mDamageArea.ColCount() + 1]; + if (!mBlockDirInfo) return false; return true; } @@ -6598,17 +6546,17 @@ BCPaintBorderIterator::SetNewData(int32_t aY, mColIndex = aX; mRowIndex = aY; mPrevCellData = mCellData; - if (IsTableRightMost() && IsTableBottomMost()) { + if (IsTableIEndMost() && IsTableBEndMost()) { mCell = nullptr; - mBCData = &mTableCellMap->mBCInfo->mLowerRightCorner; + mBCData = &mTableCellMap->mBCInfo->mBEndIEndCorner; } - else if (IsTableRightMost()) { + else if (IsTableIEndMost()) { mCellData = nullptr; - mBCData = &mTableCellMap->mBCInfo->mRightBorders.ElementAt(aY); + mBCData = &mTableCellMap->mBCInfo->mIEndBorders.ElementAt(aY); } - else if (IsTableBottomMost()) { + else if (IsTableBEndMost()) { mCellData = nullptr; - mBCData = &mTableCellMap->mBCInfo->mBottomBorders.ElementAt(aX); + mBCData = &mTableCellMap->mBCInfo->mBEndBorders.ElementAt(aX); } else { if (uint32_t(mRowIndex - mFifRgFirstRowIndex) < mCellMap->mRows.Length()) { @@ -6651,7 +6599,7 @@ BCPaintBorderIterator::SetNewRow(nsTableRowFrame* aRow) mIsNewRow = true; mRowIndex = mRow->GetRowIndex(); mColIndex = mDamageArea.StartCol(); - mPrevHorSegHeight = 0; + mPrevInlineSegBSize = 0; if (mIsRepeatedHeader) { mRepeatedHeaderRowIndex = mRowIndex; } @@ -6772,6 +6720,7 @@ BCPaintBorderIterator::Next() // XXX if CalcVerCornerOffset and CalcHorCornerOffset remain similar, combine // them +// XXX Update terminology from physical to logical /** Compute the vertical offset of a vertical border segment * @param aCornerOwnerSide - which side owns the corner * @param aCornerSubWidth - how wide is the nonwinning side of the corner @@ -6781,7 +6730,7 @@ BCPaintBorderIterator::Next() * @return - offset in twips */ static nscoord -CalcVerCornerOffset(mozilla::css::Side aCornerOwnerSide, +CalcVerCornerOffset(LogicalSide aCornerOwnerSide, BCPixelSize aCornerSubWidth, BCPixelSize aHorWidth, bool aIsStartOfSeg, @@ -6791,14 +6740,13 @@ CalcVerCornerOffset(mozilla::css::Side aCornerOwnerSide, nscoord offset = 0; // XXX These should be replaced with appropriate side-specific macros (which?) BCPixelSize smallHalf, largeHalf; - if ((NS_SIDE_TOP == aCornerOwnerSide) || - (NS_SIDE_BOTTOM == aCornerOwnerSide)) { + if (IsBlock(aCornerOwnerSide)) { DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf); if (aIsBevel) { offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { - offset = (NS_SIDE_TOP == aCornerOwnerSide) ? smallHalf : -largeHalf; + offset = (eLogicalSideBStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { @@ -6819,43 +6767,30 @@ CalcVerCornerOffset(mozilla::css::Side aCornerOwnerSide, * @param aVerWidth - how wide is the vertical edge of the corner * @param aIsStartOfSeg - does this corner start a new segment * @param aIsBevel - is this corner beveled - * @param aTableIsLTR - direction, the computation depends on ltr or rtl * @return - offset in twips */ static nscoord -CalcHorCornerOffset(mozilla::css::Side aCornerOwnerSide, +CalcHorCornerOffset(LogicalSide aCornerOwnerSide, BCPixelSize aCornerSubWidth, BCPixelSize aVerWidth, bool aIsStartOfSeg, bool aIsBevel, - bool aTableIsLTR, nsPresContext* aPresContext) { nscoord offset = 0; // XXX These should be replaced with appropriate side-specific macros (which?) BCPixelSize smallHalf, largeHalf; - if ((NS_SIDE_LEFT == aCornerOwnerSide) || - (NS_SIDE_RIGHT == aCornerOwnerSide)) { - if (aTableIsLTR) { - DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf); - } - else { - DivideBCBorderSize(aCornerSubWidth, largeHalf, smallHalf); - } + if (IsInline(aCornerOwnerSide)) { + DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf); if (aIsBevel) { offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { - offset = (NS_SIDE_LEFT == aCornerOwnerSide) ? smallHalf : -largeHalf; + offset = (eLogicalSideIStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { - if (aTableIsLTR) { - DivideBCBorderSize(aVerWidth, smallHalf, largeHalf); - } - else { - DivideBCBorderSize(aVerWidth, largeHalf, smallHalf); - } + DivideBCBorderSize(aVerWidth, smallHalf, largeHalf); if (aIsBevel) { offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } @@ -6866,121 +6801,120 @@ CalcHorCornerOffset(mozilla::css::Side aCornerOwnerSide, return aPresContext->DevPixelsToAppUnits(offset); } -BCVerticalSeg::BCVerticalSeg() +BCBlockDirSeg::BCBlockDirSeg() { mCol = nullptr; mFirstCell = mLastCell = mAjaCell = nullptr; - mOffsetX = mOffsetY = mLength = mWidth = mTopBevelOffset = 0; - mTopBevelSide = NS_SIDE_TOP; + mOffsetI = mOffsetB = mLength = mWidth = mBStartBevelOffset = 0; + mBStartBevelSide = eLogicalSideBStart; mOwner = eCellOwner; } /** - * Start a new vertical segment + * Start a new block-direction segment * @param aIter - iterator containing the structural information * @param aBorderOwner - determines the border style - * @param aVerSegWidth - the width of segment in pixel - * @param aHorSegHeight - the width of the horizontal segment joining the corner + * @param aBlockSegISize - the width of segment in pixel + * @param aInlineSegBSize - the width of the inline-dir segment joining the corner * at the start */ void -BCVerticalSeg::Start(BCPaintBorderIterator& aIter, +BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, - BCPixelSize aVerSegWidth, - BCPixelSize aHorSegHeight) + BCPixelSize aBlockSegISize, + BCPixelSize aInlineSegBSize) { - mozilla::css::Side ownerSide = NS_SIDE_TOP; + LogicalSide ownerSide = eLogicalSideBStart; bool bevel = false; - nscoord cornerSubWidth = (aIter.mBCData) ? aIter.mBCData->GetCorner(ownerSide, bevel) : 0; - bool topBevel = (aVerSegWidth > 0) ? bevel : false; - BCPixelSize maxHorSegHeight = std::max(aIter.mPrevHorSegHeight, aHorSegHeight); + bool bStartBevel = (aBlockSegISize > 0) ? bevel : false; + BCPixelSize maxInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); nscoord offset = CalcVerCornerOffset(ownerSide, cornerSubWidth, - maxHorSegHeight, true, - topBevel, aIter.mTable->PresContext()); + maxInlineSegBSize, true, + bStartBevel, aIter.mTable->PresContext()); - mTopBevelOffset = topBevel ? - aIter.mTable->PresContext()->DevPixelsToAppUnits(maxHorSegHeight): 0; + mBStartBevelOffset = bStartBevel ? + aIter.mTable->PresContext()->DevPixelsToAppUnits(maxInlineSegBSize): 0; // XXX this assumes that only corners where 2 segments join can be beveled - mTopBevelSide = (aHorSegHeight > 0) ? NS_SIDE_RIGHT : NS_SIDE_LEFT; - mOffsetY += offset; + mBStartBevelSide = (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; + mOffsetB += offset; mLength = -offset; - mWidth = aVerSegWidth; + mWidth = aBlockSegISize; mOwner = aBorderOwner; mFirstCell = aIter.mCell; mFirstRowGroup = aIter.mRg; mFirstRow = aIter.mRow; if (aIter.GetRelativeColIndex() > 0) { - mAjaCell = aIter.mVerInfo[aIter.GetRelativeColIndex() - 1].mLastCell; + mAjaCell = aIter.mBlockDirInfo[aIter.GetRelativeColIndex() - 1].mLastCell; } } /** - * Initialize the vertical segments with information that will persist for any - * vertical segment in this column + * Initialize the block-dir segments with information that will persist for any + * block-dir segment in this column * @param aIter - iterator containing the structural information */ void -BCVerticalSeg::Initialize(BCPaintBorderIterator& aIter) +BCBlockDirSeg::Initialize(BCPaintBorderIterator& aIter) { int32_t relColIndex = aIter.GetRelativeColIndex(); - mCol = aIter.IsTableRightMost() ? aIter.mVerInfo[relColIndex - 1].mCol : + mCol = aIter.IsTableIEndMost() ? aIter.mBlockDirInfo[relColIndex - 1].mCol : aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex); if (!mCol) ABORT0(); if (0 == relColIndex) { - mOffsetX = aIter.mInitialOffsetX; + mOffsetI = aIter.mInitialOffsetI; } - // set colX for the next column - if (!aIter.IsDamageAreaRightMost()) { - aIter.mVerInfo[relColIndex + 1].mOffsetX = mOffsetX + - aIter.mColInc * mCol->GetSize().width; + // set mOffsetI for the next column + if (!aIter.IsDamageAreaIEndMost()) { + aIter.mBlockDirInfo[relColIndex + 1].mOffsetI = + mOffsetI + mCol->ISize(aIter.mTableWM); } - mOffsetY = aIter.mInitialOffsetY; + mOffsetB = aIter.mInitialOffsetB; mLastCell = aIter.mCell; } /** - * Compute the offsets for the bottom corner of a vertical segment - * @param aIter - iterator containing the structural information - * @param aHorSegHeight - the width of the horizontal segment joining the corner - * at the start + * Compute the offsets for the bEnd corner of a block-dir segment + * @param aIter - iterator containing the structural information + * @param aInlineSegBSize - the width of the inline-dir segment joining the corner + * at the start */ void -BCVerticalSeg::GetBottomCorner(BCPaintBorderIterator& aIter, - BCPixelSize aHorSegHeight) +BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, + BCPixelSize aInlineSegBSize) { - mozilla::css::Side ownerSide = NS_SIDE_TOP; + LogicalSide ownerSide = eLogicalSideBStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { cornerSubWidth = aIter.mBCData->GetCorner(ownerSide, bevel); } - mIsBottomBevel = (mWidth > 0) ? bevel : false; - mBottomHorSegHeight = std::max(aIter.mPrevHorSegHeight, aHorSegHeight); - mBottomOffset = CalcVerCornerOffset(ownerSide, cornerSubWidth, - mBottomHorSegHeight, false, - mIsBottomBevel, aIter.mTable->PresContext()); - mLength += mBottomOffset; + mIsBEndBevel = (mWidth > 0) ? bevel : false; + mBEndInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); + mBEndOffset = CalcVerCornerOffset(ownerSide, cornerSubWidth, + mBEndInlineSegBSize, false, + mIsBEndBevel, aIter.mTable->PresContext()); + mLength += mBEndOffset; } /** - * Paint the vertical segment - * @param aIter - iterator containing the structural information + * Paint the block-dir segment + * @param aIter - iterator containing the structural information * @param aRenderingContext - the rendering context - * @param aHorSegHeight - the width of the horizontal segment joining the corner - * at the start + * @param aInlineSegBSize - the width of the inline-dir segment joining the corner + * at the start */ void -BCVerticalSeg::Paint(BCPaintBorderIterator& aIter, +BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, nsRenderingContext& aRenderingContext, - BCPixelSize aHorSegHeight) + BCPixelSize aInlineSegBSize) { // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaRightMost() ? eLogicalSideIEnd : eLogicalSideIStart; + aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart; int32_t relColIndex = aIter.GetRelativeColIndex(); nsTableColFrame* col = mCol; if (!col) ABORT0(); nsTableCellFrame* cell = mFirstCell; // ??? @@ -6998,8 +6932,8 @@ BCVerticalSeg::Paint(BCPaintBorderIterator& aIter, break; case eAjaColGroupOwner: side = eLogicalSideIEnd; - if (!aIter.IsTableRightMost() && (relColIndex > 0)) { - col = aIter.mVerInfo[relColIndex - 1].mCol; + if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { + col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } // and fall through case eColGroupOwner: if (col) { @@ -7008,8 +6942,8 @@ BCVerticalSeg::Paint(BCPaintBorderIterator& aIter, break; case eAjaColOwner: side = eLogicalSideIEnd; - if (!aIter.IsTableRightMost() && (relColIndex > 0)) { - col = aIter.mVerInfo[relColIndex - 1].mCol; + if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { + col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } // and fall through case eColOwner: owner = col; @@ -7018,14 +6952,14 @@ BCVerticalSeg::Paint(BCPaintBorderIterator& aIter, NS_ERROR("a neighboring rowgroup can never own a vertical border"); // and fall through case eRowGroupOwner: - NS_ASSERTION(aIter.IsTableLeftMost() || aIter.IsTableRightMost(), + NS_ASSERTION(aIter.IsTableIStartMost() || aIter.IsTableIEndMost(), "row group can own border only at table edge"); owner = mFirstRowGroup; break; case eAjaRowOwner: NS_ERROR("program error"); // and fall through case eRowOwner: - NS_ASSERTION(aIter.IsTableLeftMost() || aIter.IsTableRightMost(), + NS_ASSERTION(aIter.IsTableIStartMost() || aIter.IsTableIEndMost(), "row can own border only at table edge"); owner = mFirstRow; break; @@ -7041,64 +6975,64 @@ BCVerticalSeg::Paint(BCPaintBorderIterator& aIter, } BCPixelSize smallHalf, largeHalf; DivideBCBorderSize(mWidth, smallHalf, largeHalf); - nsRect segRect(mOffsetX - aIter.mTable->PresContext()->DevPixelsToAppUnits(largeHalf), - mOffsetY, - aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth), mLength); - nscoord bottomBevelOffset = (mIsBottomBevel) ? - aIter.mTable->PresContext()->DevPixelsToAppUnits(mBottomHorSegHeight) : 0; - mozilla::css::Side bottomBevelSide = - (aHorSegHeight > 0) ^ !aIter.mTableWM.IsBidiLTR() ? - NS_SIDE_RIGHT : NS_SIDE_LEFT; - mozilla::css::Side topBevelSide = - (mTopBevelSide == NS_SIDE_RIGHT) ^ !aIter.mTableWM.IsBidiLTR() ? - NS_SIDE_RIGHT : NS_SIDE_LEFT; + LogicalRect segRect(aIter.mTableWM, + mOffsetI - aIter.mTable->PresContext()->DevPixelsToAppUnits(largeHalf), + mOffsetB, aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth), mLength); + nscoord bEndBevelOffset = (mIsBEndBevel) ? + aIter.mTable->PresContext()->DevPixelsToAppUnits(mBEndInlineSegBSize) : 0; + LogicalSide bEndBevelSide = + (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; nsCSSRendering::DrawTableBorderSegment(aRenderingContext, style, color, - aIter.mTableBgColor, segRect, + aIter.mTableBgColor, + segRect.GetPhysicalRect(aIter.mTableWM, + aIter.mTable->GetSize().width), appUnitsPerDevPixel, aIter.mTable->PresContext()->AppUnitsPerDevPixel(), - topBevelSide, mTopBevelOffset, - bottomBevelSide, bottomBevelOffset); + aIter.mTableWM.PhysicalSide(mBStartBevelSide), + mBStartBevelOffset, + aIter.mTableWM.PhysicalSide(bEndBevelSide), + bEndBevelOffset); } /** * Advance the start point of a segment */ void -BCVerticalSeg::AdvanceOffsetY() +BCBlockDirSeg::AdvanceOffsetB() { - mOffsetY += mLength - mBottomOffset; + mOffsetB += mLength - mBEndOffset; } /** * Accumulate the current segment */ void -BCVerticalSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) +BCBlockDirSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) { mLastCell = aIter.mCell; - mLength += aIter.mRow->GetRect().height; + mLength += aIter.mRow->BSize(aIter.mTableWM); } -BCHorizontalSeg::BCHorizontalSeg() +BCInlineDirSeg::BCInlineDirSeg() { - mOffsetX = mOffsetY = mLength = mWidth = mLeftBevelOffset = 0; - mLeftBevelSide = NS_SIDE_TOP; + mOffsetI = mOffsetB = mLength = mWidth = mIStartBevelOffset = 0; + mIStartBevelSide = eLogicalSideBStart; mFirstCell = mAjaCell = nullptr; } -/** Initialize a horizontal border segment for painting +/** Initialize an inline-dir border segment for painting * @param aIter - iterator storing the current and adjacent frames * @param aBorderOwner - which frame owns the border - * @param aBottomVerSegWidth - vertical segment width coming from up - * @param aHorSegHeight - the height of the segment + * @param aBEndBlockSegISize - block-dir segment width coming from up + * @param aInlineSegBSize - the thickness of the segment + */ void -BCHorizontalSeg::Start(BCPaintBorderIterator& aIter, - BCBorderOwner aBorderOwner, - BCPixelSize aBottomVerSegWidth, - BCPixelSize aHorSegHeight) +BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, + BCBorderOwner aBorderOwner, + BCPixelSize aBEndBlockSegISize, + BCPixelSize aInlineSegBSize) { - mozilla::css::Side cornerOwnerSide = NS_SIDE_TOP; + LogicalSide cornerOwnerSide = eLogicalSideBStart; bool bevel = false; mOwner = aBorderOwner; @@ -7106,69 +7040,65 @@ BCHorizontalSeg::Start(BCPaintBorderIterator& aIter, aIter.mBCData->GetCorner(cornerOwnerSide, bevel) : 0; - bool leftBevel = (aHorSegHeight > 0) ? bevel : false; + bool iStartBevel = (aInlineSegBSize > 0) ? bevel : false; int32_t relColIndex = aIter.GetRelativeColIndex(); - nscoord maxVerSegWidth = std::max(aIter.mVerInfo[relColIndex].mWidth, - aBottomVerSegWidth); + nscoord maxBlockSegISize = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, + aBEndBlockSegISize); nscoord offset = CalcHorCornerOffset(cornerOwnerSide, cornerSubWidth, - maxVerSegWidth, true, leftBevel, - aIter.mTableWM.IsBidiLTR(), aIter.mTable->PresContext()); - mLeftBevelOffset = (leftBevel && (aHorSegHeight > 0)) ? maxVerSegWidth : 0; + maxBlockSegISize, true, iStartBevel, + aIter.mTable->PresContext()); + mIStartBevelOffset = (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; // XXX this assumes that only corners where 2 segments join can be beveled - mLeftBevelSide = (aBottomVerSegWidth > 0) ? NS_SIDE_BOTTOM : NS_SIDE_TOP; - if (aIter.mTableWM.IsBidiLTR()) { - mOffsetX += offset; - } - else { - mOffsetX -= offset; - } + mIStartBevelSide = (aBEndBlockSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; + mOffsetI += offset; mLength = -offset; - mWidth = aHorSegHeight; + mWidth = aInlineSegBSize; mFirstCell = aIter.mCell; - mAjaCell = (aIter.IsDamageAreaTopMost()) ? nullptr : - aIter.mVerInfo[relColIndex].mLastCell; + mAjaCell = (aIter.IsDamageAreaBStartMost()) ? nullptr : + aIter.mBlockDirInfo[relColIndex].mLastCell; } /** - * Compute the offsets for the right corner of a horizontal segment + * Compute the offsets for the iEnd corner of an inline-dir segment * @param aIter - iterator containing the structural information - * @param aLeftSegWidth - the width of the vertical segment joining the corner + * @param aIStartSegISize - the iSize of the block-dir segment joining the corner * at the start */ void -BCHorizontalSeg::GetRightCorner(BCPaintBorderIterator& aIter, - BCPixelSize aLeftSegWidth) +BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, + BCPixelSize aIStartSegISize) { - mozilla::css::Side ownerSide = NS_SIDE_TOP; + LogicalSide ownerSide = eLogicalSideBStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { cornerSubWidth = aIter.mBCData->GetCorner(ownerSide, bevel); } - mIsRightBevel = (mWidth > 0) ? bevel : 0; + mIsIEndBevel = (mWidth > 0) ? bevel : 0; int32_t relColIndex = aIter.GetRelativeColIndex(); - nscoord verWidth = std::max(aIter.mVerInfo[relColIndex].mWidth, aLeftSegWidth); + nscoord verWidth = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, + aIStartSegISize); mEndOffset = CalcHorCornerOffset(ownerSide, cornerSubWidth, verWidth, false, - mIsRightBevel, aIter.mTableWM.IsBidiLTR(), aIter.mTable->PresContext()); + mIsIEndBevel, aIter.mTable->PresContext()); mLength += mEndOffset; - mRightBevelOffset = (mIsRightBevel) ? + mIEndBevelOffset = (mIsIEndBevel) ? aIter.mTable->PresContext()->DevPixelsToAppUnits(verWidth) : 0; - mRightBevelSide = (aLeftSegWidth > 0) ? NS_SIDE_BOTTOM : NS_SIDE_TOP; + mIEndBevelSide = (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; } /** - * Paint the horizontal segment - * @param aIter - iterator containing the structural information + * Paint the inline-dir segment + * @param aIter - iterator containing the structural information * @param aRenderingContext - the rendering context */ void -BCHorizontalSeg::Paint(BCPaintBorderIterator& aIter, - nsRenderingContext& aRenderingContext) +BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, + nsRenderingContext& aRenderingContext) { // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaBottomMost() ? eLogicalSideBEnd : eLogicalSideBStart; + aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart; nsIFrame* rg = aIter.mRg; if (!rg) ABORT0(); nsIFrame* row = aIter.mRow; if (!row) ABORT0(); nsIFrame* cell = mFirstCell; @@ -7182,41 +7112,40 @@ BCHorizontalSeg::Paint(BCPaintBorderIterator& aIter, uint8_t style = NS_STYLE_BORDER_STYLE_SOLID; nscolor color = 0xFFFFFFFF; - switch (mOwner) { case eTableOwner: owner = aIter.mTable; break; case eAjaColGroupOwner: - NS_ERROR("neighboring colgroups can never own a horizontal border"); + NS_ERROR("neighboring colgroups can never own an inline-dir border"); // and fall through case eColGroupOwner: - NS_ASSERTION(aIter.IsTableTopMost() || aIter.IsTableBottomMost(), + NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(), "col group can own border only at the table edge"); col = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1); if (!col) ABORT0(); owner = col->GetParent(); break; case eAjaColOwner: - NS_ERROR("neighboring column can never own a horizontal border"); + NS_ERROR("neighboring column can never own an inline-dir border"); // and fall through case eColOwner: - NS_ASSERTION(aIter.IsTableTopMost() || aIter.IsTableBottomMost(), + NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(), "col can own border only at the table edge"); owner = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1); break; case eAjaRowGroupOwner: side = eLogicalSideBEnd; - rg = (aIter.IsTableBottomMost()) ? aIter.mRg : aIter.mPrevRg; + rg = (aIter.IsTableBEndMost()) ? aIter.mRg : aIter.mPrevRg; // and fall through case eRowGroupOwner: owner = rg; break; case eAjaRowOwner: side = eLogicalSideBEnd; - row = (aIter.IsTableBottomMost()) ? aIter.mRow : aIter.mPrevRow; + row = (aIter.IsTableBEndMost()) ? aIter.mRow : aIter.mPrevRow; // and fall through - case eRowOwner: + case eRowOwner: owner = row; break; case eAjaCellOwner: @@ -7234,28 +7163,32 @@ BCHorizontalSeg::Paint(BCPaintBorderIterator& aIter, } BCPixelSize smallHalf, largeHalf; DivideBCBorderSize(mWidth, smallHalf, largeHalf); - nsRect segRect(mOffsetX, - mOffsetY - aIter.mTable->PresContext()->DevPixelsToAppUnits(largeHalf), - mLength, - aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth)); + LogicalRect segRect(aIter.mTableWM, mOffsetI, + mOffsetB - nsPresContext::CSSPixelsToAppUnits(largeHalf), + mLength, + aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth)); if (aIter.mTableWM.IsBidiLTR()) { nsCSSRendering::DrawTableBorderSegment(aRenderingContext, style, color, - aIter.mTableBgColor, segRect, + aIter.mTableBgColor, + segRect.GetPhysicalRect(aIter.mTableWM, + aIter.mTable->GetSize().width), appUnitsPerDevPixel, aIter.mTable->PresContext()->AppUnitsPerDevPixel(), - mLeftBevelSide, - aIter.mTable->PresContext()->DevPixelsToAppUnits(mLeftBevelOffset), - mRightBevelSide, mRightBevelOffset); - } - else { - segRect.x -= segRect.width; + aIter.mTableWM.PhysicalSide(mIStartBevelSide), + aIter.mTable->PresContext()->DevPixelsToAppUnits(mIStartBevelOffset), + aIter.mTableWM.PhysicalSide(mIEndBevelSide), + mIEndBevelOffset); + } else { nsCSSRendering::DrawTableBorderSegment(aRenderingContext, style, color, - aIter.mTableBgColor, segRect, + aIter.mTableBgColor, + segRect.GetPhysicalRect(aIter.mTableWM, + aIter.mTable->GetSize().width), appUnitsPerDevPixel, aIter.mTable->PresContext()->AppUnitsPerDevPixel(), - mRightBevelSide, mRightBevelOffset, - mLeftBevelSide, - aIter.mTable->PresContext()->DevPixelsToAppUnits(mLeftBevelOffset)); + aIter.mTableWM.PhysicalSide(mIEndBevelSide), + mIEndBevelOffset, + aIter.mTableWM.PhysicalSide(mIStartBevelSide), + aIter.mTable->PresContext()->DevPixelsToAppUnits(mIStartBevelOffset)); } } @@ -7263,62 +7196,62 @@ BCHorizontalSeg::Paint(BCPaintBorderIterator& aIter, * Advance the start point of a segment */ void -BCHorizontalSeg::AdvanceOffsetX(int32_t aIncrement) +BCInlineDirSeg::AdvanceOffsetI() { - mOffsetX += aIncrement * (mLength - mEndOffset); + mOffsetI += (mLength - mEndOffset); } /** * Accumulate the current segment */ void -BCHorizontalSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) +BCInlineDirSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) { - mLength += aIter.mVerInfo[aIter.GetRelativeColIndex()].mColWidth; + mLength += aIter.mBlockDirInfo[aIter.GetRelativeColIndex()].mColWidth; } /** - * store the column width information while painting horizontal segment + * store the column width information while painting inline-dir segment */ void BCPaintBorderIterator::StoreColumnWidth(int32_t aIndex) { - if (IsTableRightMost()) { - mVerInfo[aIndex].mColWidth = mVerInfo[aIndex - 1].mColWidth; + if (IsTableIEndMost()) { + mBlockDirInfo[aIndex].mColWidth = mBlockDirInfo[aIndex - 1].mColWidth; } else { nsTableColFrame* col = mTableFirstInFlow->GetColFrame(mColIndex); if (!col) ABORT0(); - mVerInfo[aIndex].mColWidth = col->GetSize().width; + mBlockDirInfo[aIndex].mColWidth = col->ISize(mTableWM); } } /** - * Determine if a vertical segment owns the corder + * Determine if a block-dir segment owns the corner */ bool -BCPaintBorderIterator::VerticalSegmentOwnsCorner() +BCPaintBorderIterator::BlockDirSegmentOwnsCorner() { - mozilla::css::Side cornerOwnerSide = NS_SIDE_TOP; + LogicalSide cornerOwnerSide = eLogicalSideBStart; bool bevel = false; if (mBCData) { mBCData->GetCorner(cornerOwnerSide, bevel); } // unitialized ownerside, bevel - return (NS_SIDE_TOP == cornerOwnerSide) || - (NS_SIDE_BOTTOM == cornerOwnerSide); + return (eLogicalSideBStart == cornerOwnerSide) || + (eLogicalSideBEnd == cornerOwnerSide); } /** - * Paint if necessary a horizontal segment, otherwise accumulate it + * Paint if necessary an inline-dir segment, otherwise accumulate it * @param aRenderingContext - the rendering context */ void -BCPaintBorderIterator::AccumulateOrPaintHorizontalSegment(nsRenderingContext& aRenderingContext) +BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(nsRenderingContext& aRenderingContext) { int32_t relColIndex = GetRelativeColIndex(); // store the current col width if it hasn't been already - if (mVerInfo[relColIndex].mColWidth < 0) { + if (mBlockDirInfo[relColIndex].mColWidth < 0) { StoreColumnWidth(relColIndex); } @@ -7327,88 +7260,88 @@ BCPaintBorderIterator::AccumulateOrPaintHorizontalSegment(nsRenderingContext& aR bool isSegStart = true; bool ignoreSegStart; - nscoord leftSegWidth = - mBCData ? mBCData->GetLeftEdge(ignoreBorderOwner, ignoreSegStart) : 0; - nscoord topSegHeight = - mBCData ? mBCData->GetTopEdge(borderOwner, isSegStart) : 0; + nscoord iStartSegISize = + mBCData ? mBCData->GetIStartEdge(ignoreBorderOwner, ignoreSegStart) : 0; + nscoord bStartSegBSize = + mBCData ? mBCData->GetBStartEdge(borderOwner, isSegStart) : 0; - if (mIsNewRow || (IsDamageAreaLeftMost() && IsDamageAreaBottomMost())) { + if (mIsNewRow || (IsDamageAreaIStartMost() && IsDamageAreaBEndMost())) { // reset for every new row and on the bottom of the last row - mHorSeg.mOffsetY = mNextOffsetY; - mNextOffsetY = mNextOffsetY + mRow->GetSize().height; - mHorSeg.mOffsetX = mInitialOffsetX; - mHorSeg.Start(*this, borderOwner, leftSegWidth, topSegHeight); + mInlineSeg.mOffsetB = mNextOffsetB; + mNextOffsetB = mNextOffsetB + mRow->BSize(mTableWM); + mInlineSeg.mOffsetI = mInitialOffsetI; + mInlineSeg.Start(*this, borderOwner, iStartSegISize, bStartSegBSize); } - if (!IsDamageAreaLeftMost() && (isSegStart || IsDamageAreaRightMost() || - VerticalSegmentOwnsCorner())) { - // paint the previous seg or the current one if IsDamageAreaRightMost() - if (mHorSeg.mLength > 0) { - mHorSeg.GetRightCorner(*this, leftSegWidth); - if (mHorSeg.mWidth > 0) { - mHorSeg.Paint(*this, aRenderingContext); + if (!IsDamageAreaIStartMost() && (isSegStart || IsDamageAreaIEndMost() || + BlockDirSegmentOwnsCorner())) { + // paint the previous seg or the current one if IsDamageAreaIEndMost() + if (mInlineSeg.mLength > 0) { + mInlineSeg.GetIEndCorner(*this, iStartSegISize); + if (mInlineSeg.mWidth > 0) { + mInlineSeg.Paint(*this, aRenderingContext); } - mHorSeg.AdvanceOffsetX(mColInc); + mInlineSeg.AdvanceOffsetI(); } - mHorSeg.Start(*this, borderOwner, leftSegWidth, topSegHeight); + mInlineSeg.Start(*this, borderOwner, iStartSegISize, bStartSegBSize); } - mHorSeg.IncludeCurrentBorder(*this); - mVerInfo[relColIndex].mWidth = leftSegWidth; - mVerInfo[relColIndex].mLastCell = mCell; + mInlineSeg.IncludeCurrentBorder(*this); + mBlockDirInfo[relColIndex].mWidth = iStartSegISize; + mBlockDirInfo[relColIndex].mLastCell = mCell; } /** - * Paint if necessary a vertical segment, otherwise it + * Paint if necessary a block-dir segment, otherwise accumulate it * @param aRenderingContext - the rendering context */ void -BCPaintBorderIterator::AccumulateOrPaintVerticalSegment(nsRenderingContext& aRenderingContext) +BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(nsRenderingContext& aRenderingContext) { BCBorderOwner borderOwner = eCellOwner; BCBorderOwner ignoreBorderOwner; bool isSegStart = true; bool ignoreSegStart; - nscoord verSegWidth = - mBCData ? mBCData->GetLeftEdge(borderOwner, isSegStart) : 0; - nscoord horSegHeight = - mBCData ? mBCData->GetTopEdge(ignoreBorderOwner, ignoreSegStart) : 0; + nscoord blockSegISize = + mBCData ? mBCData->GetIStartEdge(borderOwner, isSegStart) : 0; + nscoord inlineSegBSize = + mBCData ? mBCData->GetBStartEdge(ignoreBorderOwner, ignoreSegStart) : 0; int32_t relColIndex = GetRelativeColIndex(); - BCVerticalSeg& verSeg = mVerInfo[relColIndex]; - if (!verSeg.mCol) { // on the first damaged row and the first segment in the - // col - verSeg.Initialize(*this); - verSeg.Start(*this, borderOwner, verSegWidth, horSegHeight); + BCBlockDirSeg& blockDirSeg = mBlockDirInfo[relColIndex]; + if (!blockDirSeg.mCol) { // on the first damaged row and the first segment in the + // col + blockDirSeg.Initialize(*this); + blockDirSeg.Start(*this, borderOwner, blockSegISize, inlineSegBSize); } - if (!IsDamageAreaTopMost() && (isSegStart || IsDamageAreaBottomMost() || - IsAfterRepeatedHeader() || - StartRepeatedFooter())) { - // paint the previous seg or the current one if IsDamageAreaBottomMost() - if (verSeg.mLength > 0) { - verSeg.GetBottomCorner(*this, horSegHeight); - if (verSeg.mWidth > 0) { - verSeg.Paint(*this, aRenderingContext, horSegHeight); + if (!IsDamageAreaBStartMost() && (isSegStart || IsDamageAreaBEndMost() || + IsAfterRepeatedHeader() || + StartRepeatedFooter())) { + // paint the previous seg or the current one if IsDamageAreaBEndMost() + if (blockDirSeg.mLength > 0) { + blockDirSeg.GetBEndCorner(*this, inlineSegBSize); + if (blockDirSeg.mWidth > 0) { + blockDirSeg.Paint(*this, aRenderingContext, inlineSegBSize); } - verSeg.AdvanceOffsetY(); + blockDirSeg.AdvanceOffsetB(); } - verSeg.Start(*this, borderOwner, verSegWidth, horSegHeight); + blockDirSeg.Start(*this, borderOwner, blockSegISize, inlineSegBSize); } - verSeg.IncludeCurrentBorder(*this); - mPrevHorSegHeight = horSegHeight; + blockDirSeg.IncludeCurrentBorder(*this); + mPrevInlineSegBSize = inlineSegBSize; } /** - * Reset the vertical information cache + * Reset the block-dir information cache */ void BCPaintBorderIterator::ResetVerInfo() { - if (mVerInfo) { - memset(mVerInfo, 0, mDamageArea.ColCount() * sizeof(BCVerticalSeg)); + if (mBlockDirInfo) { + memset(mBlockDirInfo, 0, mDamageArea.ColCount() * sizeof(BCBlockDirSeg)); // XXX reinitialize properly for (auto xIndex : MakeRange(mDamageArea.ColCount())) { - mVerInfo[xIndex].mColWidth = -1; + mBlockDirInfo[xIndex].mColWidth = -1; } } } @@ -7429,6 +7362,7 @@ nsTableFrame::PaintBCBorders(nsRenderingContext& aRenderingContext, if (!iter.SetDamageArea(aDirtyRect)) return; + // XXX comment still has physical terminology // First, paint all of the vertical borders from top to bottom and left to // right as they become complete. They are painted first, since they are less // efficient to paint than horizontal segments. They were stored with as few @@ -7437,17 +7371,17 @@ nsTableFrame::PaintBCBorders(nsRenderingContext& aRenderingContext, // we look up if the current border would start a new segment, if so we paint // the previously stored vertical segment and start a new segment. After // this we the now active segment with the current border. These - // segments are stored in mVerInfo to be used on the next row + // segments are stored in mBlockDirInfo to be used on the next row for (iter.First(); !iter.mAtEnd; iter.Next()) { - iter.AccumulateOrPaintVerticalSegment(aRenderingContext); + iter.AccumulateOrPaintBlockDirSegment(aRenderingContext); } - // Next, paint all of the horizontal border segments from top to bottom reuse - // the mVerInfo array to keep track of col widths and vertical segments for + // Next, paint all of the inline-dir border segments from bStart to bEnd reuse + // the mBlockDirInfo array to keep track of col widths and block-dir segments for // corner calculations iter.Reset(); for (iter.First(); !iter.mAtEnd; iter.Next()) { - iter.AccumulateOrPaintHorizontalSegment(aRenderingContext); + iter.AccumulateOrPaintInlineDirSegment(aRenderingContext); } } diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index cbca9e8b53..ee5d1ac302 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -300,11 +300,11 @@ public: nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const; /** Get width of table + colgroup + col collapse: elements that - * continue along the length of the whole left side. + * continue along the length of the whole iStart side. * see nsTablePainter about continuous borders */ - nscoord GetContinuousLeftBCBorderWidth() const; - void SetContinuousLeftBCBorderWidth(nscoord aValue); + nscoord GetContinuousIStartBCBorderWidth() const; + void SetContinuousIStartBCBorderWidth(nscoord aValue); friend class nsDelayedCalcBCBorders; @@ -873,7 +873,7 @@ protected: uint32_t mRowInserted:1; uint32_t mNeedToCalcBCBorders:1; uint32_t mGeometryDirty:1; - uint32_t mLeftContBCBorder:8; + uint32_t mIStartContBCBorder:8; uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed uint32_t mHasZeroColSpans:1; uint32_t mNeedColSpanExpansion:1; @@ -995,15 +995,15 @@ inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue) } inline nscoord -nsTableFrame::GetContinuousLeftBCBorderWidth() const +nsTableFrame::GetContinuousIStartBCBorderWidth() const { int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); - return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder); + return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mBits.mIStartContBCBorder); } -inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue) +inline void nsTableFrame::SetContinuousIStartBCBorderWidth(nscoord aValue) { - mBits.mLeftContBCBorder = (unsigned) aValue; + mBits.mIStartContBCBorder = (unsigned) aValue; } #define ABORT0() \ diff --git a/layout/tables/nsTablePainter.cpp b/layout/tables/nsTablePainter.cpp index 88cd427a18..7b89ff3fc4 100644 --- a/layout/tables/nsTablePainter.cpp +++ b/layout/tables/nsTablePainter.cpp @@ -213,26 +213,26 @@ TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame, if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) { //only handle non-degenerate tables; we need a more robust BC model //to make degenerate tables' borders reasonable to deal with - nsMargin border, tempBorder; + LogicalMargin border(wm); + LogicalMargin tempBorder(wm); nsTableColFrame* colFrame = aTableFrame->GetColFrame(mNumCols - 1); if (colFrame) { - colFrame->GetContinuousBCBorderWidth(tempBorder); + colFrame->GetContinuousBCBorderWidth(wm, tempBorder); } - border.right = tempBorder.right; + border.IEnd(wm) = tempBorder.IEnd(wm); - LogicalMargin logBorder(wm); - aLastRowGroup->GetContinuousBCBorderWidth(wm, logBorder); - border.bottom = logBorder.Bottom(wm); + aLastRowGroup->GetContinuousBCBorderWidth(wm, tempBorder); + border.BEnd(wm) = tempBorder.BEnd(wm); nsTableRowFrame* rowFrame = aFirstRowGroup->GetFirstRow(); if (rowFrame) { - rowFrame->GetContinuousBCBorderWidth(wm, logBorder); - border.top = logBorder.Top(wm); + rowFrame->GetContinuousBCBorderWidth(wm, tempBorder); + border.BStart(wm) = tempBorder.BStart(wm); } - border.left = aTableFrame->GetContinuousLeftBCBorderWidth(); + border.IStart(wm) = aTableFrame->GetContinuousIStartBCBorderWidth(); - tableData.SetBCBorder(border); + tableData.SetBCBorder(border.GetPhysicalMargin(wm)); } } @@ -279,6 +279,7 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame, nsTableFrame::RowGroupArray rowGroups; aTableFrame->OrderRowGroups(rowGroups); + WritingMode wm = aTableFrame->GetWritingMode(); DrawResult result = DrawResult::SUCCESS; @@ -317,19 +318,19 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame, // mColGroups is destroyed as part of TablePainter destruction. mColGroups.SetCapacity(colGroupFrames.Length()); - nsMargin border; - /* BC left borders aren't stored on cols, but the previous column's - right border is the next one's left border.*/ - //Start with table's left border. - nscoord lastLeftBorder = aTableFrame->GetContinuousLeftBCBorderWidth(); + LogicalMargin border(wm); + /* BC iStart borders aren't stored on cols, but the previous column's + iEnd border is the next one's iStart border.*/ + //Start with table's iStart border. + nscoord lastIStartBorder = aTableFrame->GetContinuousIStartBCBorderWidth(); for (nsTableColGroupFrame* cgFrame : colGroupFrames) { /*Create data struct for column group*/ TableBackgroundData& cgData = *mColGroups.AppendElement(TableBackgroundData(cgFrame)); if (mIsBorderCollapse && cgData.ShouldSetBCBorder()) { - border.left = lastLeftBorder; - cgFrame->GetContinuousBCBorderWidth(border); - cgData.SetBCBorder(border); + border.IStart(wm) = lastIStartBorder; + cgFrame->GetContinuousBCBorderWidth(wm, border); + cgData.SetBCBorder(border.GetPhysicalMargin(wm)); } /*Loop over columns in this colgroup*/ @@ -341,10 +342,10 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame, //Bring column mRect into table's coord system colData.mCol.mRect.MoveBy(cgData.mRect.x, cgData.mRect.y); if (mIsBorderCollapse) { - border.left = lastLeftBorder; - lastLeftBorder = col->GetContinuousBCBorderWidth(border); + border.IStart(wm) = lastIStartBorder; + lastIStartBorder = col->GetContinuousBCBorderWidth(wm, border); if (colData.mCol.ShouldSetBCBorder()) { - colData.mCol.SetBCBorder(border); + colData.mCol.SetBCBorder(border.GetPhysicalMargin(wm)); } } } @@ -494,14 +495,14 @@ TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame, if (mIsBorderCollapse && aRowBGData.ShouldSetBCBorder()) { LogicalMargin border(wm); nsTableRowFrame* nextRow = aFrame->GetNextRow(); - if (nextRow) { //outer top below us is inner bottom for us + if (nextRow) { //outer bStart after us is inner bEnd for us border.BEnd(wm) = nextRow->GetOuterBStartContBCBorderWidth(); } - else { //acquire rg's bottom border + else { //acquire rg's bEnd border nsTableRowGroupFrame* rowGroup = static_cast(aFrame->GetParent()); rowGroup->GetContinuousBCBorderWidth(wm, border); } - //get the rest of the borders; will overwrite all but bottom + //get the rest of the borders; will overwrite all but bEnd aFrame->GetContinuousBCBorderWidth(wm, border); aRowBGData.SetBCBorder(border.GetPhysicalMargin(wm)); diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index bda622ef1a..ccc372ce3e 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -817,12 +817,8 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, // Reflow each of our existing cell frames WritingMode wm = aReflowState.GetWritingMode(); - nscoord containerWidth = aReflowState.ComputedWidth(); - if (containerWidth == NS_UNCONSTRAINEDSIZE) { - containerWidth = 0; // cell positions will not yet be correct - } else { - containerWidth += aReflowState.ComputedPhysicalBorderPadding().LeftRight(); - } + nscoord containerWidth = + aReflowState.ComputedSizeAsContainerIfConstrained().width; for (nsIFrame* kidFrame : mFrames) { nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 1a0d88c567..c0d44882f2 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -346,14 +346,8 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, // get the necessary containerWidth for placing our kids bool needToCalcRowBSizes = reflowAllKids || wm.IsVerticalRL(); - nscoord containerWidth = aReflowState.reflowState.ComputedWidth(); - if (containerWidth == NS_UNCONSTRAINEDSIZE) { - containerWidth = 0; // we can't position frames correctly in RTL yet, - // so they will need to be adjusted later - } else { - containerWidth += - aReflowState.reflowState.ComputedPhysicalBorderPadding().LeftRight(); - } + nscoord containerWidth = + aReflowState.reflowState.ComputedSizeAsContainerIfConstrained().width; nsIFrame *prevKidFrame = nullptr; for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; diff --git a/layout/xul/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp index e212cac5a4..3225b3e46f 100644 --- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -129,16 +129,18 @@ nsLeafBoxFrame::GetMinISize(nsRenderingContext *aRenderingContext) nscoord result; DISPLAY_MIN_WIDTH(this, result); nsBoxLayoutState state(PresContext(), aRenderingContext); - nsSize minSize = GetMinSize(state); - // GetMinSize returns border-box width, and we want to return content - // width. Since Reflow uses the reflow state's border and padding, we + WritingMode wm = GetWritingMode(); + LogicalSize minSize(wm, GetMinSize(state)); + + // GetMinSize returns border-box size, and we want to return content + // inline-size. Since Reflow uses the reflow state's border and padding, we // actually just want to subtract what GetMinSize added, which is the // result of GetBorderAndPadding. nsMargin bp; GetBorderAndPadding(bp); - result = minSize.width - bp.LeftRight(); + result = minSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm); return result; } @@ -149,16 +151,18 @@ nsLeafBoxFrame::GetPrefISize(nsRenderingContext *aRenderingContext) nscoord result; DISPLAY_PREF_WIDTH(this, result); nsBoxLayoutState state(PresContext(), aRenderingContext); - nsSize prefSize = GetPrefSize(state); - // GetPrefSize returns border-box width, and we want to return content - // width. Since Reflow uses the reflow state's border and padding, we + WritingMode wm = GetWritingMode(); + LogicalSize prefSize(wm, GetPrefSize(state)); + + // GetPrefSize returns border-box size, and we want to return content + // inline-size. Since Reflow uses the reflow state's border and padding, we // actually just want to subtract what GetPrefSize added, which is the // result of GetBorderAndPadding. nsMargin bp; GetBorderAndPadding(bp); - result = prefSize.width - bp.LeftRight(); + result = prefSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm); return result; } diff --git a/layout/xul/nsTextBoxFrame.cpp b/layout/xul/nsTextBoxFrame.cpp index e3c52bdc9f..e24561e2b2 100644 --- a/layout/xul/nsTextBoxFrame.cpp +++ b/layout/xul/nsTextBoxFrame.cpp @@ -406,7 +406,8 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, // A mask of all possible decorations. uint8_t decorMask = NS_STYLE_TEXT_DECORATION_LINE_LINES_MASK; - bool vertical = GetWritingMode().IsVertical(); + WritingMode wm = GetWritingMode(); + bool vertical = wm.IsVertical(); nsIFrame* f = this; do { // find decoration colors @@ -461,8 +462,18 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, nscoord size; nscoord ascent = fontMet->MaxAscent(); - nscoord baseline = - presContext->RoundAppUnitsToNearestDevPixels(aTextRect.y + ascent); + nsPoint baselinePt; + if (wm.IsVertical()) { + baselinePt.x = + presContext->RoundAppUnitsToNearestDevPixels(aTextRect.x + + (wm.IsVerticalRL() ? aTextRect.width - ascent : ascent)); + baselinePt.y = aTextRect.y; + } else { + baselinePt.x = aTextRect.x; + baselinePt.y = + presContext->RoundAppUnitsToNearestDevPixels(aTextRect.y + ascent); + } + nsRefPtr ctx = aRenderingContext.ThebesContext(); gfxPoint pt(presContext->AppUnitsToGfxUnits(aTextRect.x), presContext->AppUnitsToGfxUnits(aTextRect.y)); @@ -471,6 +482,9 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, Float xInFrame = Float(PresContext()->AppUnitsToGfxUnits(mTextDrawRect.x)); gfxRect dirtyRect(presContext->AppUnitsToGfxUnits(aDirtyRect)); + // XXX todo: vertical-mode support for decorations not tested yet, + // probably won't be positioned correctly + // Underlines are drawn before overlines, and both before the text // itself, per http://www.w3.org/TR/CSS21/zindex.html point 7.2.1.4.1.1. // (We don't apply this rule to the access-key underline because we only @@ -523,7 +537,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level, presContext, aRenderingContext, refContext, *fontMet, - aTextRect.x, baseline, + baselinePt.x, baselinePt.y, &posResolve, 1); mAccessKeyInfo->mBeforeWidth = posResolve.visualLeftTwips; @@ -534,7 +548,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), level, presContext, aRenderingContext, refContext, *fontMet, - aTextRect.x, baseline); + baselinePt.x, baselinePt.y); } } if (NS_FAILED(rv)) { @@ -554,7 +568,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext, } fontMet->DrawString(mCroppedTitle.get(), mCroppedTitle.Length(), - aTextRect.x, baseline, &aRenderingContext, + baselinePt.x, baselinePt.y, &aRenderingContext, &refContext); } @@ -949,11 +963,16 @@ nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState) mCroppedTitle.Length(), aBoxLayoutState.GetRenderingContext()); - textRect.x -= metrics.leftBearing; - textRect.width = metrics.width; + WritingMode wm = GetWritingMode(); + LogicalRect tr(wm, textRect, GetSize().width); + + tr.IStart(wm) -= metrics.leftBearing; + tr.ISize(wm) = metrics.width; // In DrawText() we always draw with the baseline at MaxAscent() (relative to mTextDrawRect), - textRect.y += fontMet->MaxAscent() - metrics.ascent; - textRect.height = metrics.ascent + metrics.descent; + tr.BStart(wm) += fontMet->MaxAscent() - metrics.ascent; + tr.BSize(wm) = metrics.ascent + metrics.descent; + + textRect = tr.GetPhysicalRect(wm, GetSize().width); // Our scrollable overflow is our bounds; our visual overflow may // extend beyond that. @@ -1019,6 +1038,9 @@ nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState) if (rendContext) { GetTextSize(presContext, *rendContext, mTitle, size, mAscent); + if (GetWritingMode().IsVertical()) { + Swap(size.width, size.height); + } mTextSize = size; mNeedsRecalc = false; } @@ -1028,16 +1050,21 @@ nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState) void nsTextBoxFrame::CalcDrawRect(nsRenderingContext &aRenderingContext) { - nsRect textRect(nsPoint(0, 0), GetSize()); + WritingMode wm = GetWritingMode(); + + LogicalRect textRect(wm, LogicalPoint(wm, 0, 0), GetLogicalSize(wm)); nsMargin borderPadding; GetBorderAndPadding(borderPadding); - textRect.Deflate(borderPadding); + textRect.Deflate(wm, LogicalMargin(wm, borderPadding)); // determine (cropped) title and underline position nsPresContext* presContext = PresContext(); - // determine (cropped) title which fits in aRect.width and its width + // determine (cropped) title which fits in aRect, and its width + // (where "width" is the text measure along its baseline, i.e. actually + // a physical height in vertical writing modes) nscoord titleWidth = - CalculateTitleForWidth(presContext, aRenderingContext, textRect.width); + CalculateTitleForWidth(presContext, aRenderingContext, + textRect.ISize(wm)); #ifdef ACCESSIBILITY // Make sure to update the accessible tree in case when cropped title is @@ -1053,24 +1080,22 @@ nsTextBoxFrame::CalcDrawRect(nsRenderingContext &aRenderingContext) UpdateAccessIndex(); // make the rect as small as our (cropped) text. - nscoord outerWidth = textRect.width; - textRect.width = titleWidth; + nscoord outerISize = textRect.ISize(wm); + textRect.ISize(wm) = titleWidth; // Align our text within the overall rect by checking our text-align property. - const nsStyleVisibility* vis = StyleVisibility(); const nsStyleText* textStyle = StyleText(); - - if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_CENTER) - textRect.x += (outerWidth - textRect.width)/2; - else if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_RIGHT || - (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_DEFAULT && - vis->mDirection == NS_STYLE_DIRECTION_RTL) || - (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_END && - vis->mDirection == NS_STYLE_DIRECTION_LTR)) { - textRect.x += (outerWidth - textRect.width); + if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_CENTER) { + textRect.IStart(wm) += (outerISize - textRect.ISize(wm)) / 2; + } else if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_END || + (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_LEFT && + !wm.IsBidiLTR()) || + (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_RIGHT && + wm.IsBidiLTR())) { + textRect.IStart(wm) += (outerISize - textRect.ISize(wm)); } - mTextDrawRect = textRect; + mTextDrawRect = textRect.GetPhysicalRect(wm, GetSize().width); } /** @@ -1103,8 +1128,13 @@ nsTextBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState) DISPLAY_MIN_SIZE(this, size); // if there is cropping our min width becomes our border and padding - if (mCropType != CropNone) - size.width = 0; + if (mCropType != CropNone) { + if (GetWritingMode().IsVertical()) { + size.height = 0; + } else { + size.width = 0; + } + } AddBorderAndPadding(size); bool widthSet, heightSet; @@ -1122,7 +1152,9 @@ nsTextBoxFrame::GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) nsMargin m(0,0,0,0); GetBorderAndPadding(m); - ascent += m.top; + + WritingMode wm = GetWritingMode(); + ascent += LogicalMargin(wm, m).BStart(wm); return ascent; } diff --git a/modules/libmar/verify/MacVerifyCrypto.cpp b/modules/libmar/verify/MacVerifyCrypto.cpp index ce2846d501..8d6833e1f9 100644 --- a/modules/libmar/verify/MacVerifyCrypto.cpp +++ b/modules/libmar/verify/MacVerifyCrypto.cpp @@ -212,9 +212,10 @@ CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, void* aBuf, CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData, + unsigned int aDataSize, CryptoX_PublicKey* aPublicKey) { - if (!aCertData || !aPublicKey) { + if (!aCertData || aDataSize == 0 || !aPublicKey) { return CryptoX_Error; } *aPublicKey = NULL; @@ -261,121 +262,30 @@ CryptoMac_LoadPublicKey(const unsigned char* aCertData, } sCspHandle = cspHandle; } - - FILE* certFile = NULL; - long certFileSize = 0; - uint8* certBuffer = NULL; - - certFile = fopen((char*)aCertData, "rb"); - if (!certFile) { - return CryptoX_Error; - } - if (fseek(certFile, 0, SEEK_END)) { - fclose(certFile); - return CryptoX_Error; - } - certFileSize = ftell(certFile); - if (certFileSize < 0) { - fclose(certFile); - return CryptoX_Error; - } - certBuffer = (uint8*)malloc(certFileSize); - if (fseek(certFile, 0, SEEK_SET)) { - free(certBuffer); - fclose(certFile); - return CryptoX_Error; - } - uint readResult = fread(certBuffer, sizeof(uint8), certFileSize, certFile); - if (readResult != certFileSize) { - free(certBuffer); - fclose(certFile); - return CryptoX_Error; - } - fclose(certFile); - - CFDataRef certData = CFDataCreate(kCFAllocatorDefault, - certBuffer, - certFileSize); - free(certBuffer); - if (!certData) { - return CryptoX_Error; - } - - SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, - certData); - CFRelease(certData); - if (!cert) { - return CryptoX_Error; - } - - SecKeyRef publicKey; - OSStatus status = SecCertificateCopyPublicKey(cert, (SecKeyRef*)&publicKey); - CFRelease(cert); - if (status) { - return CryptoX_Error; - } - - *aPublicKey = (void*)publicKey; - return CryptoX_Success; } - CFURLRef url = - CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, - aCertData, - strlen((char*)aCertData), - false); - if (!url) { - return CryptoX_Error; - } - - CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); - if (!stream) { - CFRelease(url); - return CryptoX_Error; - } - - SecTransformRef readTransform = - SecTransformCreateReadTransformWithReadStreamPtr(stream); - if (!readTransform) { - CFRelease(url); - CFRelease(stream); - return CryptoX_Error; - } - - CFErrorRef error; - CFDataRef tempCertData = (CFDataRef)SecTransformExecutePtr(readTransform, - &error); - if (!tempCertData || error) { - CFRelease(url); - CFRelease(stream); - CFRelease(readTransform); + CFDataRef certData = CFDataCreate(kCFAllocatorDefault, + aCertData, + aDataSize); + if (!certData) { return CryptoX_Error; } SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, - tempCertData); + certData); + CFRelease(certData); if (!cert) { - CFRelease(url); - CFRelease(stream); - CFRelease(readTransform); - CFRelease(tempCertData); return CryptoX_Error; } - CryptoX_Result result = CryptoX_Error; OSStatus status = SecCertificateCopyPublicKey(cert, (SecKeyRef*)aPublicKey); - if (status == 0) { - result = CryptoX_Success; + CFRelease(cert); + if (status != 0) { + return CryptoX_Error; } - CFRelease(url); - CFRelease(stream); - CFRelease(readTransform); - CFRelease(tempCertData); - CFRelease(cert); - - return result; + return CryptoX_Success; } CryptoX_Result diff --git a/modules/libmar/verify/cryptox.h b/modules/libmar/verify/cryptox.h index 2dd93efd6e..d5f61eaa1b 100644 --- a/modules/libmar/verify/cryptox.h +++ b/modules/libmar/verify/cryptox.h @@ -73,6 +73,7 @@ CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle* aInputData); CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle* aInputData, void* aBuf, unsigned int aLen); CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char* aCertData, + unsigned int aDataSize, CryptoX_PublicKey* aPublicKey); CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData, CryptoX_PublicKey* aPublicKey, @@ -92,7 +93,7 @@ void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey); CryptoMac_VerifyUpdate(aInputData, aBuf, aLen) #define CryptoX_LoadPublicKey(aProviderHandle, aCertData, aDataSize, \ aPublicKey, aCertName, aCert) \ - CryptoMac_LoadPublicKey(aCertData, aPublicKey) + CryptoMac_LoadPublicKey(aCertData, aDataSize, aPublicKey) #define CryptoX_VerifySignature(aInputData, aPublicKey, aSignature, \ aSignatureLen) \ CryptoMac_VerifySignature(aInputData, aPublicKey, aSignature, aSignatureLen) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 0cf44a7ebc..b814dbf809 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2798,9 +2798,9 @@ pref("svg.marker-improvements.enabled", true); pref("svg.new-getBBox.enabled", false); #ifdef RELEASE_BUILD -pref("svg.transform-origin.enabled", false); +pref("svg.transform-box.enabled", false); #else -pref("svg.transform-origin.enabled", true); +pref("svg.transform-box.enabled", true); #endif // RELEASE_BUILD // Default font types and sizes by locale @@ -4382,6 +4382,9 @@ pref("layers.acceleration.force-enabled", false); pref("layers.acceleration.draw-fps", false); +// Enable DEAA antialiasing for transformed layers in the compositor +pref("layers.deaa.enabled", false); + pref("layers.dump", false); #ifdef MOZ_DUMP_PAINTING // If we're dumping layers, also dump the texture data diff --git a/toolkit/mozapps/update/updater/archivereader.cpp b/toolkit/mozapps/update/updater/archivereader.cpp index 5192f71f0a..cb8f7736b3 100644 --- a/toolkit/mozapps/update/updater/archivereader.cpp +++ b/toolkit/mozapps/update/updater/archivereader.cpp @@ -15,13 +15,11 @@ #include "updatehelper.h" #endif -#ifdef XP_WIN // These are generated at compile time based on the DER file for the channel // being used #include "primaryCert.h" #include "secondaryCert.h" #include "xpcshellCert.h" -#endif #define UPDATER_NO_STRING_GLUE_STL #include "nsVersionComparator.cpp" @@ -38,9 +36,6 @@ static int outbuf_size = 262144; static char *inbuf = nullptr; static char *outbuf = nullptr; -#ifdef XP_WIN -#include "resource.h" - /** * Performs a verification on the opened MAR file with the passed in * certificate name ID and type ID. @@ -53,16 +48,19 @@ template int VerifyLoadedCert(MarFile *archive, const uint8_t (&certData)[SIZE]) { + (void)archive; + (void)certData; + +#ifdef MOZ_VERIFY_MAR_SIGNATURE const uint32_t size = SIZE; - const uint8_t * const data = &certData[0]; - if (mar_verify_signaturesW(archive, &data, &size, 1)) { + const uint8_t* const data = &certData[0]; + if (mar_verify_signatures(archive, &data, &size, 1)) { return CERT_VERIFY_ERROR; } +#endif return OK; } -#endif - /** * Performs a verification on the opened MAR file. Both the primary and backup @@ -79,22 +77,21 @@ ArchiveReader::VerifySignature() return ARCHIVE_NOT_OPEN; } -#ifdef XP_WIN // If the fallback key exists we're running an XPCShell test and we should // use the XPCShell specific cert for the signed MAR. - int rv; + int rv = OK; +#ifdef XP_WIN if (DoesFallbackKeyExist()) { rv = VerifyLoadedCert(mArchive, xpcshellCertData); - } else { + } else +#endif + { rv = VerifyLoadedCert(mArchive, primaryCertData); if (rv != OK) { rv = VerifyLoadedCert(mArchive, secondaryCertData); } } return rv; -#else - return OK; -#endif } /** diff --git a/toolkit/mozapps/update/updater/moz.build b/toolkit/mozapps/update/updater/moz.build index 12b00ea57b..664f1182fb 100644 --- a/toolkit/mozapps/update/updater/moz.build +++ b/toolkit/mozapps/update/updater/moz.build @@ -13,6 +13,12 @@ SOURCES += [ ] have_progressui = 0 + +if CONFIG['MOZ_VERIFY_MAR_SIGNATURE']: + USE_LIBS += [ + 'verifymar', + ] + if CONFIG['OS_ARCH'] == 'WINNT': have_progressui = 1 SOURCES += [ @@ -32,7 +38,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': ] USE_LIBS += [ 'updatecommon-standalone', - 'verifymar', ] OS_LIBS += [ 'comctl32', @@ -42,15 +47,18 @@ if CONFIG['OS_ARCH'] == 'WINNT': 'crypt32', 'advapi32', ] -else: +elif CONFIG['OS_ARCH'] == 'Linux': USE_LIBS += [ 'updatecommon', '/modules/libmar/sign/signmar', - '/modules/libmar/sign/verifymar', '/security/nss/lib/nss/nss3', '/security/nss/lib/util/nssutil3', ] OS_LIBS += CONFIG['NSPR_LIBS'] +else: + USE_LIBS += [ + 'updatecommon', + ] USE_LIBS += [ 'mar', diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 526a65f632..155896d83e 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -120,6 +120,11 @@ static bool sUseHardLinks = true; # define MAYBE_USE_HARD_LINKS 0 #endif +#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX) +#include "nss.h" +#include "prerror.h" +#endif + #ifdef XP_WIN #include "registrycertificates.h" BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra); @@ -2427,6 +2432,20 @@ int NS_main(int argc, NS_tchar **argv) _exit(1); } #endif + +#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX) + // On Windows and Mac we rely on native APIs to do verifications so we don't + // need to initialize NSS at all there. + // Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS + // databases. + if (NSS_NoDB_Init(NULL) != SECSuccess) { + PRErrorCode error = PR_GetError(); + fprintf(stderr, "Could not initialize NSS: %s (%d)", + PR_ErrorToName(error), (int) error); + _exit(1); + } +#endif + InitProgressUI(&argc, &argv); // To process an update the updater command line must at a minimum have the