зеркало из https://github.com/mozilla/gecko-dev.git
Implement text-align-last. Bug 536557, r=dbaron
This commit is contained in:
Родитель
6285970ced
Коммит
ad89de3591
|
@ -620,6 +620,9 @@ interface nsIDOMCSS2Properties : nsISupports
|
|||
attribute DOMString outlineOffset;
|
||||
// raises(DOMException) on setting
|
||||
|
||||
attribute DOMString MozTextAlignLast;
|
||||
// raises(DOMException) on setting
|
||||
|
||||
/* Mozilla extensions */
|
||||
attribute DOMString overflowX;
|
||||
// raises(DOMException) on setting
|
||||
|
|
|
@ -625,12 +625,13 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
|||
#define NS_STYLE_TEXT_ALIGN_JUSTIFY 4
|
||||
#define NS_STYLE_TEXT_ALIGN_CHAR 5 //align based on a certain character, for table cell
|
||||
#define NS_STYLE_TEXT_ALIGN_END 6
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_CENTER 7
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_RIGHT 8
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_LEFT 9
|
||||
#define NS_STYLE_TEXT_ALIGN_AUTO 7
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_CENTER 8
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_RIGHT 9
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_LEFT 10
|
||||
// NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT is only used in data structs; it
|
||||
// is never present in stylesheets or computed data.
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT 10
|
||||
#define NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT 11
|
||||
// Note: make sure that the largest NS_STYLE_TEXT_ALIGN_* value is smaller than
|
||||
// the smallest NS_STYLE_VERTICAL_ALIGN_* value below!
|
||||
|
||||
|
@ -682,15 +683,15 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
|||
// Note: these values pickup after the text-align values because there
|
||||
// are a few html cases where an object can have both types of
|
||||
// alignment applied with a single attribute
|
||||
#define NS_STYLE_VERTICAL_ALIGN_BASELINE 11
|
||||
#define NS_STYLE_VERTICAL_ALIGN_SUB 12
|
||||
#define NS_STYLE_VERTICAL_ALIGN_SUPER 13
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TOP 14
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TEXT_TOP 15
|
||||
#define NS_STYLE_VERTICAL_ALIGN_MIDDLE 16
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM 17
|
||||
#define NS_STYLE_VERTICAL_ALIGN_BOTTOM 18
|
||||
#define NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE 19
|
||||
#define NS_STYLE_VERTICAL_ALIGN_BASELINE 12
|
||||
#define NS_STYLE_VERTICAL_ALIGN_SUB 13
|
||||
#define NS_STYLE_VERTICAL_ALIGN_SUPER 14
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TOP 15
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TEXT_TOP 16
|
||||
#define NS_STYLE_VERTICAL_ALIGN_MIDDLE 17
|
||||
#define NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM 18
|
||||
#define NS_STYLE_VERTICAL_ALIGN_BOTTOM 19
|
||||
#define NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE 20
|
||||
|
||||
// See nsStyleVisibility
|
||||
#define NS_STYLE_VISIBILITY_HIDDEN 0
|
||||
|
|
|
@ -4107,16 +4107,15 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
|
|||
}
|
||||
|
||||
bool
|
||||
nsBlockFrame::ShouldJustifyLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine)
|
||||
nsBlockFrame::IsLastLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine)
|
||||
{
|
||||
while (++aLine != end_lines()) {
|
||||
// There is another line
|
||||
if (0 != aLine->GetChildCount()) {
|
||||
// If the next line is a block line then we must not justify
|
||||
// this line because it means that this line is the last in a
|
||||
// If the next line is a block line then this line is the last in a
|
||||
// group of inline lines.
|
||||
return !aLine->IsBlock();
|
||||
return aLine->IsBlock();
|
||||
}
|
||||
// The next line is empty, try the next one
|
||||
}
|
||||
|
@ -4131,13 +4130,13 @@ nsBlockFrame::ShouldJustifyLine(nsBlockReflowState& aState,
|
|||
++line)
|
||||
{
|
||||
if (0 != line->GetChildCount())
|
||||
return !line->IsBlock();
|
||||
return line->IsBlock();
|
||||
}
|
||||
nextInFlow = (nsBlockFrame*) nextInFlow->GetNextInFlow();
|
||||
}
|
||||
|
||||
// This is the last line - so don't allow justification
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -4222,10 +4221,19 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
// inline frames "shrink-wrap" around their children (therefore
|
||||
// there is no extra horizontal space).
|
||||
const nsStyleText* styleText = GetStyleText();
|
||||
bool allowJustify = NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign &&
|
||||
!aLineLayout.GetLineEndsInBR() &&
|
||||
ShouldJustifyLine(aState, aLine);
|
||||
aLineLayout.HorizontalAlignFrames(aLine->mBounds, allowJustify);
|
||||
|
||||
/**
|
||||
* text-align-last defaults to the same value as text-align when
|
||||
* text-align-last is set to auto (unless when text-align is set to justify),
|
||||
* so in that case we don't need to set isLastLine.
|
||||
*
|
||||
* In other words, isLastLine really means isLastLineAndWeCare.
|
||||
*/
|
||||
bool isLastLine = ((NS_STYLE_TEXT_ALIGN_AUTO != styleText->mTextAlignLast ||
|
||||
NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign) &&
|
||||
(aLineLayout.GetLineEndsInBR() ||
|
||||
IsLastLine(aState, aLine)));
|
||||
aLineLayout.HorizontalAlignFrames(aLine->mBounds, isLastLine);
|
||||
// XXX: not only bidi: right alignment can be broken after
|
||||
// RelativePositionFrames!!!
|
||||
// XXXldb Is something here considering relatively positioned frames at
|
||||
|
|
|
@ -530,8 +530,8 @@ protected:
|
|||
const nsLineList* aLineList = nsnull);
|
||||
|
||||
// XXX where to go
|
||||
bool ShouldJustifyLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine);
|
||||
bool IsLastLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine);
|
||||
|
||||
void DeleteLine(nsBlockReflowState& aState,
|
||||
nsLineList::iterator aLine,
|
||||
|
|
|
@ -113,7 +113,6 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext,
|
|||
|
||||
// Stash away some style data that we need
|
||||
mStyleText = aOuterReflowState->frame->GetStyleText();
|
||||
mTextAlign = mStyleText->mTextAlign;
|
||||
mLineNumber = 0;
|
||||
mFlags = 0; // default all flags to false except those that follow here...
|
||||
mTotalPlacedFrames = 0;
|
||||
|
@ -2493,8 +2492,12 @@ nsLineLayout::ApplyFrameJustification(PerSpanData* aPSD, FrameJustificationState
|
|||
|
||||
void
|
||||
nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
|
||||
bool aAllowJustify)
|
||||
bool aIsLastLine)
|
||||
{
|
||||
/**
|
||||
* NOTE: aIsLastLine ain't necessarily so: it is correctly set by caller
|
||||
* only in cases where the last line needs special handling.
|
||||
*/
|
||||
PerSpanData* psd = mRootSpan;
|
||||
NS_WARN_IF_FALSE(psd->mRightEdge != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width; this should only result from "
|
||||
|
@ -2510,29 +2513,44 @@ nsLineLayout::HorizontalAlignFrames(nsRect& aLineBounds,
|
|||
nscoord dx = 0;
|
||||
|
||||
if (remainingWidth > 0) {
|
||||
switch (mTextAlign) {
|
||||
case NS_STYLE_TEXT_ALIGN_JUSTIFY:
|
||||
// If this is not the last line then go ahead and justify the
|
||||
// frames in the line.
|
||||
if (aAllowJustify) {
|
||||
PRInt32 numSpaces;
|
||||
PRInt32 numLetters;
|
||||
|
||||
ComputeJustificationWeights(psd, &numSpaces, &numLetters);
|
||||
PRUint8 textAlign = mStyleText->mTextAlign;
|
||||
|
||||
if (numSpaces > 0) {
|
||||
FrameJustificationState state =
|
||||
{ numSpaces, numLetters, remainingWidth, 0, 0, 0, 0, 0 };
|
||||
|
||||
// Apply the justification, and make sure to update our linebox
|
||||
// width to account for it.
|
||||
aLineBounds.width += ApplyFrameJustification(psd, &state);
|
||||
remainingWidth = availWidth - aLineBounds.width;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* 'text-align-last: auto' is equivalent to the value of the 'text-align'
|
||||
* property except when 'text-align' is set to 'justify', in which case it
|
||||
* is 'justify' when 'text-justify' is 'distribute' and 'start' otherwise.
|
||||
*
|
||||
* XXX: the code below will have to change when we implement text-justify
|
||||
*/
|
||||
if (aIsLastLine) {
|
||||
if (mStyleText->mTextAlignLast == NS_STYLE_TEXT_ALIGN_AUTO) {
|
||||
if (textAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY) {
|
||||
textAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
|
||||
}
|
||||
// Fall through to the default case if we were told not to
|
||||
// justify anything or could not justify to fill the space.
|
||||
} else {
|
||||
textAlign = mStyleText->mTextAlignLast;
|
||||
}
|
||||
}
|
||||
|
||||
switch (textAlign) {
|
||||
case NS_STYLE_TEXT_ALIGN_JUSTIFY:
|
||||
PRInt32 numSpaces;
|
||||
PRInt32 numLetters;
|
||||
|
||||
ComputeJustificationWeights(psd, &numSpaces, &numLetters);
|
||||
|
||||
if (numSpaces > 0) {
|
||||
FrameJustificationState state =
|
||||
{ numSpaces, numLetters, remainingWidth, 0, 0, 0, 0, 0 };
|
||||
|
||||
// Apply the justification, and make sure to update our linebox
|
||||
// width to account for it.
|
||||
aLineBounds.width += ApplyFrameJustification(psd, &state);
|
||||
remainingWidth = availWidth - aLineBounds.width;
|
||||
break;
|
||||
}
|
||||
// Fall through to the default case if we could not justify to fill
|
||||
// the space.
|
||||
|
||||
case NS_STYLE_TEXT_ALIGN_DEFAULT:
|
||||
if (NS_STYLE_DIRECTION_LTR == psd->mDirection) {
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
|
||||
bool TrimTrailingWhiteSpace();
|
||||
|
||||
void HorizontalAlignFrames(nsRect& aLineBounds, bool aAllowJustify);
|
||||
void HorizontalAlignFrames(nsRect& aLineBounds, bool aIsLastLine);
|
||||
|
||||
/**
|
||||
* Handle all the relative positioning in the line, compute the
|
||||
|
@ -568,8 +568,6 @@ protected:
|
|||
|
||||
PRUint32 mFlags;
|
||||
|
||||
PRUint8 mTextAlign;
|
||||
|
||||
nsresult NewPerFrameData(PerFrameData** aResult);
|
||||
|
||||
nsresult NewPerSpanData(PerSpanData** aResult);
|
||||
|
|
|
@ -1765,7 +1765,8 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
|||
PRUint32 nextBreakIndex = 0;
|
||||
nsTextFrame* nextBreakBeforeFrame = GetNextBreakBeforeFrame(&nextBreakIndex);
|
||||
bool enabledJustification = mLineContainer &&
|
||||
mLineContainer->GetStyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY;
|
||||
(mLineContainer->GetStyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY ||
|
||||
mLineContainer->GetStyleText()->mTextAlignLast == NS_STYLE_TEXT_ALIGN_JUSTIFY);
|
||||
|
||||
PRUint32 i;
|
||||
const nsStyleText* textStyle = nsnull;
|
||||
|
@ -7674,7 +7675,8 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
|
||||
// Compute space and letter counts for justification, if required
|
||||
if (!textStyle->WhiteSpaceIsSignificant() &&
|
||||
lineContainer->GetStyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY) {
|
||||
(lineContainer->GetStyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY ||
|
||||
lineContainer->GetStyleText()->mTextAlignLast == NS_STYLE_TEXT_ALIGN_JUSTIFY)) {
|
||||
AddStateBits(TEXT_JUSTIFICATION_ENABLED); // This will include a space for trailing whitespace, if any is present.
|
||||
// This is corrected for in nsLineLayout::TrimWhiteSpaceIn.
|
||||
PRInt32 numJustifiableCharacters =
|
||||
|
|
|
@ -2208,6 +2208,15 @@ CSS_PROP_TEXT(
|
|||
kTextAlignKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_TEXT(
|
||||
-moz-text-align-last,
|
||||
text_align_last,
|
||||
CSS_PROP_DOMPROP_PREFIXED(TextAlignLast),
|
||||
CSS_PROPERTY_PARSE_VALUE,
|
||||
VARIANT_HK,
|
||||
kTextAlignLastKTable,
|
||||
offsetof(nsStyleText, mTextAlignLast),
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_SHORTHAND(
|
||||
text-decoration,
|
||||
text_decoration,
|
||||
|
|
|
@ -1200,6 +1200,17 @@ const PRInt32 nsCSSProps::kTextAlignKTable[] = {
|
|||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const PRInt32 nsCSSProps::kTextAlignLastKTable[] = {
|
||||
eCSSKeyword_auto, NS_STYLE_TEXT_ALIGN_AUTO,
|
||||
eCSSKeyword_left, NS_STYLE_TEXT_ALIGN_LEFT,
|
||||
eCSSKeyword_right, NS_STYLE_TEXT_ALIGN_RIGHT,
|
||||
eCSSKeyword_center, NS_STYLE_TEXT_ALIGN_CENTER,
|
||||
eCSSKeyword_justify, NS_STYLE_TEXT_ALIGN_JUSTIFY,
|
||||
eCSSKeyword_start, NS_STYLE_TEXT_ALIGN_DEFAULT,
|
||||
eCSSKeyword_end, NS_STYLE_TEXT_ALIGN_END,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const PRInt32 nsCSSProps::kTextBlinkKTable[] = {
|
||||
eCSSKeyword_none, NS_STYLE_TEXT_BLINK_NONE,
|
||||
eCSSKeyword_blink, NS_STYLE_TEXT_BLINK_BLINK,
|
||||
|
|
|
@ -408,6 +408,7 @@ public:
|
|||
static const PRInt32 kStackSizingKTable[];
|
||||
static const PRInt32 kTableLayoutKTable[];
|
||||
static const PRInt32 kTextAlignKTable[];
|
||||
static const PRInt32 kTextAlignLastKTable[];
|
||||
static const PRInt32 kTextBlinkKTable[];
|
||||
static const PRInt32 kTextDecorationLineKTable[];
|
||||
static const PRInt32 kTextDecorationStyleKTable[];
|
||||
|
|
|
@ -2401,6 +2401,16 @@ nsComputedDOMStyle::DoGetTextAlign()
|
|||
return val;
|
||||
}
|
||||
|
||||
nsIDOMCSSValue*
|
||||
nsComputedDOMStyle::DoGetTextAlignLast()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(GetStyleText()->mTextAlignLast,
|
||||
nsCSSProps::kTextAlignLastKTable));
|
||||
return val;
|
||||
}
|
||||
|
||||
nsIDOMCSSValue*
|
||||
nsComputedDOMStyle::DoGetMozTextBlink()
|
||||
{
|
||||
|
@ -4575,6 +4585,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength)
|
|||
//// COMPUTED_STYLE_MAP_ENTRY(size, Size),
|
||||
COMPUTED_STYLE_MAP_ENTRY(table_layout, TableLayout),
|
||||
COMPUTED_STYLE_MAP_ENTRY(text_align, TextAlign),
|
||||
COMPUTED_STYLE_MAP_ENTRY(text_align_last, TextAlignLast),
|
||||
COMPUTED_STYLE_MAP_ENTRY(text_decoration, TextDecoration),
|
||||
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(text_indent, TextIndent),
|
||||
COMPUTED_STYLE_MAP_ENTRY(text_overflow, TextOverflow),
|
||||
|
|
|
@ -313,6 +313,7 @@ private:
|
|||
/* Text Properties */
|
||||
nsIDOMCSSValue* DoGetLineHeight();
|
||||
nsIDOMCSSValue* DoGetTextAlign();
|
||||
nsIDOMCSSValue* DoGetTextAlignLast();
|
||||
nsIDOMCSSValue* DoGetMozTextBlink();
|
||||
nsIDOMCSSValue* DoGetTextDecoration();
|
||||
nsIDOMCSSValue* DoGetMozTextDecorationColor();
|
||||
|
|
|
@ -3365,6 +3365,11 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
|
|||
NS_STYLE_TEXT_ALIGN_DEFAULT,
|
||||
0, 0, 0, 0);
|
||||
|
||||
// text-align-last: enum, inherit, initial
|
||||
SetDiscrete(*aRuleData->ValueForTextAlignLast(), text->mTextAlignLast,
|
||||
canStoreInRuleTree, SETDSC_ENUMERATED, parentText->mTextAlignLast,
|
||||
NS_STYLE_TEXT_ALIGN_AUTO, 0, 0, 0, 0);
|
||||
|
||||
// text-indent: length, percent, calc, inherit, initial
|
||||
SetCoord(*aRuleData->ValueForTextIndent(), text->mTextIndent, parentText->mTextIndent,
|
||||
SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC,
|
||||
|
|
|
@ -2814,6 +2814,7 @@ nsStyleText::nsStyleText(void)
|
|||
{
|
||||
MOZ_COUNT_CTOR(nsStyleText);
|
||||
mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
|
||||
mTextAlignLast = NS_STYLE_TEXT_ALIGN_AUTO;
|
||||
mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
|
||||
mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
|
||||
mWordWrap = NS_STYLE_WORDWRAP_NORMAL;
|
||||
|
@ -2831,6 +2832,7 @@ nsStyleText::nsStyleText(void)
|
|||
|
||||
nsStyleText::nsStyleText(const nsStyleText& aSource)
|
||||
: mTextAlign(aSource.mTextAlign),
|
||||
mTextAlignLast(aSource.mTextAlignLast),
|
||||
mTextTransform(aSource.mTextTransform),
|
||||
mWhiteSpace(aSource.mWhiteSpace),
|
||||
mWordWrap(aSource.mWordWrap),
|
||||
|
@ -2859,6 +2861,7 @@ nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const
|
|||
}
|
||||
|
||||
if ((mTextAlign != aOther.mTextAlign) ||
|
||||
(mTextAlignLast != aOther.mTextAlignLast) ||
|
||||
(mTextTransform != aOther.mTextTransform) ||
|
||||
(mWhiteSpace != aOther.mWhiteSpace) ||
|
||||
(mWordWrap != aOther.mWordWrap) ||
|
||||
|
|
|
@ -1277,6 +1277,7 @@ struct nsStyleText {
|
|||
static bool ForceCompare() { return false; }
|
||||
|
||||
PRUint8 mTextAlign; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mTextAlignLast; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mTextTransform; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mWhiteSpace; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mWordWrap; // [inherited] see nsStyleConsts.h
|
||||
|
|
|
@ -2646,6 +2646,14 @@ var gCSSProperties = {
|
|||
other_values: [ "center", "justify", "end" ],
|
||||
invalid_values: []
|
||||
},
|
||||
"-moz-text-align-last": {
|
||||
domProp: "MozTextAlignLast",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "auto" ],
|
||||
other_values: [ "center", "justify", "start", "end", "left", "right" ],
|
||||
invalid_values: []
|
||||
},
|
||||
"-moz-text-blink": {
|
||||
domProp: "MozTextBlink",
|
||||
inherited: false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче