From 12ece32c941dcfe0bbf213578f2e5b5c59d04fe6 Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Thu, 10 Sep 1998 23:43:12 +0000 Subject: [PATCH] Revised various vertical alignment cases to use font introspection data instead of hard coding in values; corrected middle computation. git-svn-id: svn://10.0.0.236/trunk@9787 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/html/style/src/nsCSSLayout.cpp | 61 ++++++++++++------- mozilla/layout/html/style/src/nsCSSLayout.cpp | 61 ++++++++++++------- 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/mozilla/content/html/style/src/nsCSSLayout.cpp b/mozilla/content/html/style/src/nsCSSLayout.cpp index d7598032889..d103285c0dd 100644 --- a/mozilla/content/html/style/src/nsCSSLayout.cpp +++ b/mozilla/content/html/style/src/nsCSSLayout.cpp @@ -56,8 +56,9 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, nscoord maxY = aY0; PRIntn pass2Kids = 0; PRIntn kidCount = aChildCount; + nscoord* ascents = aAscents; while (--kidCount >= 0) { - nscoord kidAscent = *aAscents++; + nscoord kidAscent = *ascents++; const nsStyleText* textStyle; kid->GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)textStyle); @@ -70,10 +71,17 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, nscoord kidYTop = 0; PRBool isPass2Kid = PR_FALSE; - nscoord fontHeight, fontAscent, fontDescent; + nscoord fontParam; switch (verticalAlignUnit) { case eStyleUnit_Coord: - kidYTop = aMaxAscent + textStyle->mVerticalAlign.GetCoordValue(); + // According to the spec, a positive value "raises" the box by + // the given distance while a negative value "lowers" the box + // by the given distance. Since Y coordinates increase towards + // the bottom of the screen we reverse the sign. All of the + // raising and lowering is done relative to the baseline, so + // we start our adjustments there. + kidYTop = aMaxAscent - kidAscent; // get baseline first + kidYTop -= textStyle->mVerticalAlign.GetCoordValue(); break; case eStyleUnit_Percent: @@ -95,17 +103,15 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; case NS_STYLE_VERTICAL_ALIGN_SUB: - // Move baseline by 1/2 the ascent of the child. - // NOTE: CSSx doesn't seem to specify what subscripting does - // so we are using ebina's logic - kidYTop = aMaxAscent + (kidAscent/2) - kidAscent; + // Align the child's baseline on the superscript baseline + fm->GetSubscriptOffset(fontParam); + kidYTop = aMaxAscent + fontParam - kidAscent; break; case NS_STYLE_VERTICAL_ALIGN_SUPER: - // Move baseline by 1/2 the ascent of the child - // NOTE: CSSx doesn't seem to specify what superscripting does - // so we are using ebina's logic - kidYTop = aMaxAscent - (kidAscent/2) - kidAscent; + // Align the child's baseline on the subscript baseline + fm->GetSuperscriptOffset(fontParam); + kidYTop = aMaxAscent - fontParam - kidAscent; break; case NS_STYLE_VERTICAL_ALIGN_BOTTOM: @@ -114,22 +120,20 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; case NS_STYLE_VERTICAL_ALIGN_MIDDLE: - // XXX spec says use the 'x' height but our font api - // doesn't give us that information. - fm->GetHeight(fontHeight); - kidYTop = aMaxAscent - (fontHeight / 2) - kidRect.height/2; + // Align the midpoint of the box with 1/2 the parent's x-height + fm->GetXHeight(fontParam); + kidYTop = aMaxAscent - (fontParam / 2) - (kidRect.height/2); break; case NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM: - fm->GetMaxDescent(fontDescent); - kidYTop = aMaxAscent + fontDescent - kidRect.height; + fm->GetMaxDescent(fontParam); + kidYTop = aMaxAscent + fontParam - kidRect.height; break; case NS_STYLE_VERTICAL_ALIGN_TEXT_TOP: - fm->GetMaxAscent(fontAscent); - kidYTop = aMaxAscent - fontAscent; + fm->GetMaxAscent(fontParam); + kidYTop = aMaxAscent - fontParam; break; - } break; @@ -139,6 +143,11 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; } + /* XXX or grow the box - which is it? */ + if (kidYTop < 0) { + kidYTop = 0; + } + // Place kid and update min and max Y values if (!isPass2Kid) { nscoord y = aY0 + kidYTop; @@ -162,14 +171,24 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, // Position all of the bottom aligned children kidCount = aChildCount; kid = aFirstChild; + ascents = aAscents; while (--kidCount >= 0) { + nscoord kidAscent = *ascents++; + // Get kid's vertical align style data const nsStyleText* textStyle; kid->GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)textStyle); nsStyleUnit verticalAlignUnit = textStyle->mVerticalAlign.GetUnit(); if (eStyleUnit_Percent == verticalAlignUnit) { - nscoord kidYTop = aMaxAscent + + // According to the spec, a positive value "raises" the box by + // the given distance while a negative value "lowers" the box + // by the given distance. Since Y coordinates increase towards + // the bottom of the screen we reverse the sign. All of the + // raising and lowering is done relative to the baseline, so + // we start our adjustments there. + nscoord kidYTop = aMaxAscent - kidAscent; // get baseline first + kidYTop -= nscoord(textStyle->mVerticalAlign.GetPercentValue() * lineHeight); kid->GetRect(kidRect); kid->MoveTo(kidRect.x, aY0 + kidYTop); diff --git a/mozilla/layout/html/style/src/nsCSSLayout.cpp b/mozilla/layout/html/style/src/nsCSSLayout.cpp index d7598032889..d103285c0dd 100644 --- a/mozilla/layout/html/style/src/nsCSSLayout.cpp +++ b/mozilla/layout/html/style/src/nsCSSLayout.cpp @@ -56,8 +56,9 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, nscoord maxY = aY0; PRIntn pass2Kids = 0; PRIntn kidCount = aChildCount; + nscoord* ascents = aAscents; while (--kidCount >= 0) { - nscoord kidAscent = *aAscents++; + nscoord kidAscent = *ascents++; const nsStyleText* textStyle; kid->GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)textStyle); @@ -70,10 +71,17 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, nscoord kidYTop = 0; PRBool isPass2Kid = PR_FALSE; - nscoord fontHeight, fontAscent, fontDescent; + nscoord fontParam; switch (verticalAlignUnit) { case eStyleUnit_Coord: - kidYTop = aMaxAscent + textStyle->mVerticalAlign.GetCoordValue(); + // According to the spec, a positive value "raises" the box by + // the given distance while a negative value "lowers" the box + // by the given distance. Since Y coordinates increase towards + // the bottom of the screen we reverse the sign. All of the + // raising and lowering is done relative to the baseline, so + // we start our adjustments there. + kidYTop = aMaxAscent - kidAscent; // get baseline first + kidYTop -= textStyle->mVerticalAlign.GetCoordValue(); break; case eStyleUnit_Percent: @@ -95,17 +103,15 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; case NS_STYLE_VERTICAL_ALIGN_SUB: - // Move baseline by 1/2 the ascent of the child. - // NOTE: CSSx doesn't seem to specify what subscripting does - // so we are using ebina's logic - kidYTop = aMaxAscent + (kidAscent/2) - kidAscent; + // Align the child's baseline on the superscript baseline + fm->GetSubscriptOffset(fontParam); + kidYTop = aMaxAscent + fontParam - kidAscent; break; case NS_STYLE_VERTICAL_ALIGN_SUPER: - // Move baseline by 1/2 the ascent of the child - // NOTE: CSSx doesn't seem to specify what superscripting does - // so we are using ebina's logic - kidYTop = aMaxAscent - (kidAscent/2) - kidAscent; + // Align the child's baseline on the subscript baseline + fm->GetSuperscriptOffset(fontParam); + kidYTop = aMaxAscent - fontParam - kidAscent; break; case NS_STYLE_VERTICAL_ALIGN_BOTTOM: @@ -114,22 +120,20 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; case NS_STYLE_VERTICAL_ALIGN_MIDDLE: - // XXX spec says use the 'x' height but our font api - // doesn't give us that information. - fm->GetHeight(fontHeight); - kidYTop = aMaxAscent - (fontHeight / 2) - kidRect.height/2; + // Align the midpoint of the box with 1/2 the parent's x-height + fm->GetXHeight(fontParam); + kidYTop = aMaxAscent - (fontParam / 2) - (kidRect.height/2); break; case NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM: - fm->GetMaxDescent(fontDescent); - kidYTop = aMaxAscent + fontDescent - kidRect.height; + fm->GetMaxDescent(fontParam); + kidYTop = aMaxAscent + fontParam - kidRect.height; break; case NS_STYLE_VERTICAL_ALIGN_TEXT_TOP: - fm->GetMaxAscent(fontAscent); - kidYTop = aMaxAscent - fontAscent; + fm->GetMaxAscent(fontParam); + kidYTop = aMaxAscent - fontParam; break; - } break; @@ -139,6 +143,11 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, break; } + /* XXX or grow the box - which is it? */ + if (kidYTop < 0) { + kidYTop = 0; + } + // Place kid and update min and max Y values if (!isPass2Kid) { nscoord y = aY0 + kidYTop; @@ -162,14 +171,24 @@ nsCSSLayout::VerticallyAlignChildren(nsIPresContext* aCX, // Position all of the bottom aligned children kidCount = aChildCount; kid = aFirstChild; + ascents = aAscents; while (--kidCount >= 0) { + nscoord kidAscent = *ascents++; + // Get kid's vertical align style data const nsStyleText* textStyle; kid->GetStyleData(eStyleStruct_Text, (const nsStyleStruct*&)textStyle); nsStyleUnit verticalAlignUnit = textStyle->mVerticalAlign.GetUnit(); if (eStyleUnit_Percent == verticalAlignUnit) { - nscoord kidYTop = aMaxAscent + + // According to the spec, a positive value "raises" the box by + // the given distance while a negative value "lowers" the box + // by the given distance. Since Y coordinates increase towards + // the bottom of the screen we reverse the sign. All of the + // raising and lowering is done relative to the baseline, so + // we start our adjustments there. + nscoord kidYTop = aMaxAscent - kidAscent; // get baseline first + kidYTop -= nscoord(textStyle->mVerticalAlign.GetPercentValue() * lineHeight); kid->GetRect(kidRect); kid->MoveTo(kidRect.x, aY0 + kidYTop);