Bug 655877 - Part 11: Ignore vertical-align and map dominant-baseline to vertical-align in SVG text frames. r=roc

This commit is contained in:
Cameron McCormack 2012-08-02 21:38:48 +10:00
parent e3b6613c2b
commit dba2e1b104
4 changed files with 67 additions and 13 deletions

View File

@ -7410,6 +7410,52 @@ nsIFrame::HasTerminalNewline() const
return false;
}
static PRUint8
ConvertSVGDominantBaselineToVerticalAlign(PRUint8 aDominantBaseline)
{
switch (aDominantBaseline) {
case NS_STYLE_DOMINANT_BASELINE_HANGING:
case NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE:
return NS_STYLE_VERTICAL_ALIGN_TEXT_TOP;
case NS_STYLE_DOMINANT_BASELINE_TEXT_AFTER_EDGE:
case NS_STYLE_DOMINANT_BASELINE_IDEOGRAPHIC:
return NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM;
case NS_STYLE_DOMINANT_BASELINE_CENTRAL:
case NS_STYLE_DOMINANT_BASELINE_MIDDLE:
return NS_STYLE_VERTICAL_ALIGN_MIDDLE;
case NS_STYLE_DOMINANT_BASELINE_AUTO:
case NS_STYLE_DOMINANT_BASELINE_ALPHABETIC:
return NS_STYLE_VERTICAL_ALIGN_BASELINE;
default:
NS_NOTREACHED("unexpected aDominantBaseline value");
return NS_STYLE_VERTICAL_ALIGN_BASELINE;
}
}
PRUint8
nsIFrame::VerticalAlignEnum() const
{
if (mState & NS_FRAME_IS_SVG_TEXT) {
PRUint8 dominantBaseline;
for (const nsIFrame* frame = this; frame; frame = frame->GetParent()) {
dominantBaseline = frame->GetStyleSVGReset()->mDominantBaseline;
if (dominantBaseline != NS_STYLE_DOMINANT_BASELINE_AUTO ||
frame->GetType() == nsGkAtoms::svgTextFrame) {
break;
}
}
return ConvertSVGDominantBaselineToVerticalAlign(dominantBaseline);
}
const nsStyleCoord& verticalAlign =
GetStyleContext()->GetStyleTextReset()->mVerticalAlign;
if (verticalAlign.GetUnit() == eStyleUnit_Enumerated) {
return verticalAlign.GetIntValue();
}
return eInvalidVerticalAlign;
}
/* static */
void nsFrame::FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
nsIFrame::Cursor& aCursor)

View File

@ -2838,6 +2838,16 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
};
bool IsVisibleConsideringAncestors(PRUint32 aFlags = 0) const;
/**
* Returns the vertical-align value to be used for layout, if it is one
* of the enumerated values. If this is an SVG text frame, it returns a value
* that corresponds to the value of dominant-baseline. If the
* vertical-align property has length or percentage value, this returns
* eInvalidVerticalAlign.
*/
PRUint8 VerticalAlignEnum() const;
enum { eInvalidVerticalAlign = 0xFF };
bool IsSVGText() const { return mState & NS_FRAME_IS_SVG_TEXT; }
protected:

View File

@ -1452,11 +1452,7 @@ nsLineLayout::VerticalAlignLine()
if (rootPFD.mFrame->GetStyleContext()->HasTextDecorationLines()) {
for (const PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) {
const nsIFrame *const f = pfd->mFrame;
const nsStyleCoord& vAlign =
f->GetStyleContext()->GetStyleTextReset()->mVerticalAlign;
if (vAlign.GetUnit() != eStyleUnit_Enumerated ||
vAlign.GetIntValue() != NS_STYLE_VERTICAL_ALIGN_BASELINE) {
if (f->VerticalAlignEnum() != NS_STYLE_VERTICAL_ALIGN_BASELINE) {
const nscoord offset = baselineY - pfd->mBounds.y;
f->Properties().Set(nsIFrame::LineBaselineOffset(),
NS_INT32_TO_PTR(offset));
@ -1776,18 +1772,24 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd)
// Get vertical-align property
const nsStyleCoord& verticalAlign =
frame->GetStyleTextReset()->mVerticalAlign;
PRUint8 verticalAlignEnum = frame->VerticalAlignEnum();
#ifdef NOISY_VERTICAL_ALIGN
printf(" [frame]");
nsFrame::ListTag(stdout, frame);
printf(": verticalAlignUnit=%d (enum == %d)\n",
printf(": verticalAlignUnit=%d (enum == %d",
verticalAlign.GetUnit(),
((eStyleUnit_Enumerated == verticalAlign.GetUnit())
? verticalAlign.GetIntValue()
: -1));
if (verticalAlignEnum != nsIFrame::eInvalidVerticalAlign) {
printf(", after SVG dominant-baseline conversion == %d",
verticalAlignEnum);
}
printf(")\n");
#endif
if (verticalAlign.GetUnit() == eStyleUnit_Enumerated) {
switch (verticalAlign.GetIntValue()) {
if (verticalAlignEnum != nsIFrame::eInvalidVerticalAlign) {
switch (verticalAlignEnum) {
default:
case NS_STYLE_VERTICAL_ALIGN_BASELINE:
{

View File

@ -4566,11 +4566,7 @@ nsTextFrame::GetTextDecorations(nsPresContext* aPresContext,
// that should be set (see nsLineLayout::VerticalAlignLine).
if (firstBlock) {
// At this point, fChild can't be null since TextFrames can't be blocks
const nsStyleCoord& vAlign =
fChild->GetStyleContext()->GetStyleTextReset()->mVerticalAlign;
if (vAlign.GetUnit() != eStyleUnit_Enumerated ||
vAlign.GetIntValue() != NS_STYLE_VERTICAL_ALIGN_BASELINE)
{
if (fChild->VerticalAlignEnum() != NS_STYLE_VERTICAL_ALIGN_BASELINE) {
// Since offset is the offset in the child's coordinate space, we have
// to undo the accumulation to bring the transform out of the block's
// coordinate space