Backed out 4 changesets (bug 1253840) for causing multiple failures in nsLineLayout.cpp. CLOSED TREE

Backed out changeset 1a47c4ddf44c (bug 1253840)
Backed out changeset 816a9266d111 (bug 1253840)
Backed out changeset 7ce24f83240a (bug 1253840)
Backed out changeset cf6eff426d61 (bug 1253840)
This commit is contained in:
Stanca Serban 2023-05-20 00:49:29 +03:00
Родитель 80bb4b4f78
Коммит 403e698e38
19 изменённых файлов: 56 добавлений и 383 удалений

Просмотреть файл

@ -928,7 +928,7 @@ uint32_t gfxTextRun::BreakAndMeasureText(
gfxFloat aWidth, const PropertyProvider& aProvider,
SuppressBreak aSuppressBreak, gfxFont::BoundingBoxType aBoundingBoxType,
DrawTarget* aRefDrawTarget, bool aCanWordWrap, bool aCanWhitespaceWrap,
TrimmableWS* aOutTrimmableWhitespace, Metrics& aOutMetrics,
gfxFloat* aOutTrimmableWhitespace, Metrics& aOutMetrics,
bool& aOutUsedHyphenation, uint32_t& aOutLastBreak,
gfxBreakPriority& aBreakPriority) {
aMaxLength = std::min(aMaxLength, GetLength() - aStart);
@ -1174,8 +1174,7 @@ uint32_t gfxTextRun::BreakAndMeasureText(
aRefDrawTarget, &aProvider);
if (aOutTrimmableWhitespace) {
aOutTrimmableWhitespace->mAdvance = trimmableAdvance;
aOutTrimmableWhitespace->mCount = trimmableChars;
*aOutTrimmableWhitespace = trimmableAdvance;
}
if (charsFit == aMaxLength) {

Просмотреть файл

@ -384,13 +384,6 @@ class gfxTextRun : public gfxShapedText {
nsTArray<HyphenType>& aHyphenBuffer,
HyphenationState* aWordState);
// Struct used by BreakAndMeasureText to return the amount of trimmable
// trailing whitespace included in the run.
struct TrimmableWS {
mozilla::gfx::Float mAdvance = 0;
uint32_t mCount = 0;
};
/**
* Finds the longest substring that will fit into the given width.
* Uses GetHyphenationBreaks and GetSpacing from aProvider.
@ -462,7 +455,7 @@ class gfxTextRun : public gfxShapedText {
SuppressBreak aSuppressBreak, gfxFont::BoundingBoxType aBoundingBoxType,
DrawTarget* aRefDrawTarget, bool aCanWordWrap, bool aCanWhitespaceWrap,
// Output parameters:
TrimmableWS* aOutTrimmableWhitespace, // may be null
gfxFloat* aOutTrimmableWhitespace, // may be null
Metrics& aOutMetrics, bool& aOutUsedHyphenation, uint32_t& aOutLastBreak,
// In/out:
gfxBreakPriority& aBreakPriority);

Просмотреть файл

@ -3046,8 +3046,7 @@ void nsLineLayout::ExpandInlineRubyBoxes(PerSpanData* aSpan) {
}
}
nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan,
bool aLineIsRTL) const {
nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL) {
const PerFrameData* pfd = aSpan->mLastFrame;
nscoord result = 0;
while (pfd) {
@ -3080,36 +3079,6 @@ nscoord nsLineLayout::GetHangFrom(const PerSpanData* aSpan,
return result;
}
gfxTextRun::TrimmableWS nsLineLayout::GetTrimFrom(const PerSpanData* aSpan,
bool aLineIsRTL) const {
const PerFrameData* pfd = aSpan->mLastFrame;
while (pfd) {
if (const PerSpanData* childSpan = pfd->mSpan) {
return GetTrimFrom(childSpan, aLineIsRTL);
}
if (pfd->mIsTextFrame) {
auto* lastText = static_cast<nsTextFrame*>(pfd->mFrame);
auto result = lastText->GetTrimmableWS();
if (result.mAdvance) {
lastText->EnsureTextRun(nsTextFrame::eInflated);
auto* textRun = lastText->GetTextRun(nsTextFrame::eInflated);
if (textRun && textRun->IsRightToLeft() != aLineIsRTL) {
result.mAdvance = -result.mAdvance;
}
}
return result;
}
if (!pfd->mSkipWhenTrimmingWhitespace) {
// If we hit a frame on the end that's not text and not a placeholder or
// <br>, then there is no trailing whitespace to trim. Stop the search.
return gfxTextRun::TrimmableWS{};
}
// Scan back for a preceding frame whose whitespace we can trim.
pfd = pfd->mPrev;
}
return gfxTextRun::TrimmableWS{};
}
// Align inline frames within the line according to the CSS text-align
// property.
void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
@ -3137,16 +3106,9 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
// Check if there's trailing whitespace we need to "hang" at line-wrap.
nscoord hang = 0;
uint32_t trimCount = 0;
if (aLine->IsLineWrapped()) {
if (textAlign == StyleTextAlign::Justify) {
auto trim = GetTrimFrom(mRootSpan, lineWM.IsBidiRTL());
hang = NSToCoordRound(trim.mAdvance);
trimCount = trim.mCount;
} else {
hang = GetHangFrom(mRootSpan, lineWM.IsBidiRTL());
}
}
bool isSVG = LineContainerFrame()->IsInSVGTextSubtree();
bool doTextAlign = remainingISize > 0 || hang != 0;
@ -3182,11 +3144,9 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
switch (textAlign) {
case StyleTextAlign::Justify: {
int32_t opportunities =
psd->mFrame->mJustificationInfo.mInnerOpportunities -
(hang ? trimCount : 0);
psd->mFrame->mJustificationInfo.mInnerOpportunities;
if (opportunities > 0) {
int32_t gaps = opportunities * 2 + additionalGaps;
remainingISize += std::abs(hang);
JustificationApplicationState applyState(gaps, remainingISize);
// Apply the justification, and make sure to update our linebox
@ -3194,15 +3154,6 @@ void nsLineLayout::TextAlignLine(nsLineBox* aLine, bool aIsLastLine) {
aLine->ExpandBy(ApplyFrameJustification(psd, applyState),
ContainerSizeForSpan(psd));
// If the trimmable trailing whitespace that we want to hang had
// reverse-inline directionality, adjust line position to account for
// it being at the inline-start side.
// On top of the original "hang" amount, justification will have
// modified its width, so we include that adjustment here.
if (hang < 0) {
dx = hang - trimCount * remainingISize / opportunities;
}
MOZ_ASSERT(applyState.mGaps.mHandled == applyState.mGaps.mCount,
"Unprocessed justification gaps");
NS_ASSERTION(

Просмотреть файл

@ -10,7 +10,6 @@
#define nsLineLayout_h___
#include "gfxTypes.h"
#include "gfxTextRun.h"
#include "JustificationUtils.h"
#include "mozilla/ArenaAllocator.h"
#include "mozilla/WritingModes.h"
@ -527,9 +526,7 @@ class nsLineLayout {
// Get the advance of any trailing hangable whitespace. If the whitespace
// has directionality opposite to the line, the result is negated.
nscoord GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL) const;
gfxTextRun::TrimmableWS GetTrimFrom(const PerSpanData* aSpan,
bool aLineIsRTL) const;
nscoord GetHangFrom(const PerSpanData* aSpan, bool aLineIsRTL);
gfxBreakPriority mLastOptionalBreakPriority;
int32_t mLastOptionalBreakFrameOffset;

Просмотреть файл

@ -198,8 +198,6 @@ NS_DECLARE_FRAME_PROPERTY_RELEASABLE(UninflatedTextRunProperty, gfxTextRun)
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(FontSizeInflationProperty, float)
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(HangableWhitespaceProperty, nscoord)
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(TrimmableWhitespaceProperty,
gfxTextRun::TrimmableWS)
struct nsTextFrame::PaintTextSelectionParams : nsTextFrame::PaintTextParams {
Point textBaselinePt;
@ -2231,7 +2229,8 @@ already_AddRefed<gfxTextRun> BuildTextRunsScanner::BuildTextRunForFrames(
flags |= GetSpacingFlags(f);
nsTextFrameUtils::CompressionMode compression =
GetCSSWhitespaceToCompressionMode(f, textStyle);
if ((enabledJustification || f->ShouldSuppressLineBreak()) && !isSVG) {
if ((enabledJustification || f->ShouldSuppressLineBreak()) &&
!textStyle->WhiteSpaceIsSignificant() && !isSVG) {
flags |= gfx::ShapedTextFlags::TEXT_ENABLE_SPACING;
}
fontStyle = f->StyleFont();
@ -3890,7 +3889,7 @@ nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
if (!mNextContinuation) {
return nullptr;
}
if (mPropertyFlags & PropertyFlags::Continuations) {
if (mHasContinuationsProperty) {
return GetProperty(ContinuationsProperty());
}
size_t count = 0;
@ -3908,7 +3907,7 @@ nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
continuations = nullptr;
}
AddProperty(ContinuationsProperty(), continuations);
mPropertyFlags |= PropertyFlags::Continuations;
mHasContinuationsProperty = true;
return continuations;
}
@ -8157,53 +8156,20 @@ void nsTextFrame::SetFontSizeInflation(float aInflation) {
void nsTextFrame::SetHangableISize(nscoord aISize) {
MOZ_ASSERT(aISize >= 0, "unexpected negative hangable advance");
if (aISize <= 0) {
ClearHangableISize();
if (mHasHangableWS) {
RemoveProperty(HangableWhitespaceProperty());
}
mHasHangableWS = false;
return;
}
SetProperty(HangableWhitespaceProperty(), aISize);
mPropertyFlags |= PropertyFlags::HangableWS;
mHasHangableWS = true;
}
nscoord nsTextFrame::GetHangableISize() const {
MOZ_ASSERT(!!(mPropertyFlags & PropertyFlags::HangableWS) ==
HasProperty(HangableWhitespaceProperty()),
MOZ_ASSERT(mHasHangableWS == HasProperty(HangableWhitespaceProperty()),
"flag/property mismatch!");
return (mPropertyFlags & PropertyFlags::HangableWS)
? GetProperty(HangableWhitespaceProperty())
: 0;
}
void nsTextFrame::ClearHangableISize() {
if (mPropertyFlags & PropertyFlags::HangableWS) {
RemoveProperty(HangableWhitespaceProperty());
mPropertyFlags &= ~PropertyFlags::HangableWS;
}
}
void nsTextFrame::SetTrimmableWS(gfxTextRun::TrimmableWS aTrimmableWS) {
MOZ_ASSERT(aTrimmableWS.mAdvance >= 0, "negative trimmable size");
if (aTrimmableWS.mAdvance <= 0) {
ClearTrimmableWS();
return;
}
SetProperty(TrimmableWhitespaceProperty(), aTrimmableWS);
mPropertyFlags |= PropertyFlags::TrimmableWS;
}
gfxTextRun::TrimmableWS nsTextFrame::GetTrimmableWS() const {
MOZ_ASSERT(!!(mPropertyFlags & PropertyFlags::TrimmableWS) ==
HasProperty(TrimmableWhitespaceProperty()),
"flag/property mismatch!");
return (mPropertyFlags & PropertyFlags::TrimmableWS)
? GetProperty(TrimmableWhitespaceProperty())
: gfxTextRun::TrimmableWS{};
}
void nsTextFrame::ClearTrimmableWS() {
if (mPropertyFlags & PropertyFlags::TrimmableWS) {
RemoveProperty(TrimmableWhitespaceProperty());
mPropertyFlags &= ~PropertyFlags::TrimmableWS;
}
return mHasHangableWS ? GetProperty(HangableWhitespaceProperty()) : 0;
}
/* virtual */
@ -9202,7 +9168,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
gfxTextRun::Metrics textMetrics;
uint32_t transformedLastBreak = 0;
bool usedHyphenation = false;
gfxTextRun::TrimmableWS trimmableWS;
gfxFloat trimmableWidth = 0;
gfxFloat availWidth = aAvailableWidth;
if (Style()->IsTextCombined()) {
// If text-combine-upright is 'all', we would compress whatever long
@ -9227,7 +9193,8 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
availWidth, provider, suppressBreak, boundingBoxType, aDrawTarget,
textStyle->WordCanWrap(this), isBreakSpaces,
// The following are output parameters:
canTrimTrailingWhitespace || whitespaceCanHang ? &trimmableWS : nullptr,
canTrimTrailingWhitespace || whitespaceCanHang ? &trimmableWidth
: nullptr,
textMetrics, usedHyphenation, transformedLastBreak,
// In/out
breakPriority);
@ -9288,7 +9255,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
}
bool brokeText = forceBreak >= 0 || transformedCharsFit < transformedLength;
if (trimmableWS.mAdvance > 0.0) {
if (trimmableWidth > 0.0) {
if (canTrimTrailingWhitespace) {
// Optimization: if we we can be sure this frame will be at end of line,
// then trim the whitespace now.
@ -9296,41 +9263,32 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// We're definitely going to break so our trailing whitespace should
// definitely be trimmed. Record that we've already done it.
AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE);
textMetrics.mAdvanceWidth -= trimmableWS.mAdvance;
trimmableWS.mAdvance = 0.0;
textMetrics.mAdvanceWidth -= trimmableWidth;
trimmableWidth = 0.0;
}
ClearHangableISize();
ClearTrimmableWS();
SetHangableISize(0);
} else if (whitespaceCanHang) {
// Figure out how much whitespace will hang if at end-of-line.
gfxFloat hang =
std::min(std::max(0.0, textMetrics.mAdvanceWidth - availWidth),
gfxFloat(trimmableWS.mAdvance));
SetHangableISize(NSToCoordRound(trimmableWS.mAdvance - hang));
// nsLineLayout only needs the TrimmableWS property if justifying, so
// check whether this is relevant.
if (textStyle->mTextAlign == StyleTextAlign::Justify ||
textStyle->mTextAlignLast == StyleTextAlignLast::Justify) {
SetTrimmableWS(trimmableWS);
}
trimmableWidth);
SetHangableISize(NSToCoordRound(trimmableWidth - hang));
textMetrics.mAdvanceWidth -= hang;
trimmableWS.mAdvance = 0.0;
trimmableWidth = 0.0;
} else {
MOZ_ASSERT_UNREACHABLE("How did trimmableWS get set?!");
ClearHangableISize();
ClearTrimmableWS();
trimmableWS.mAdvance = 0.0;
MOZ_ASSERT_UNREACHABLE("How did trimmableWidth get set?!");
SetHangableISize(0);
trimmableWidth = 0.0;
}
} else {
// Remove any stale frame properties.
ClearHangableISize();
ClearTrimmableWS();
// Remove any stale frame property.
SetHangableISize(0);
}
if (!brokeText && lastBreak >= 0) {
// Since everything fit and no break was forced,
// record the last break opportunity
NS_ASSERTION(textMetrics.mAdvanceWidth - trimmableWS.mAdvance <= availWidth,
NS_ASSERTION(textMetrics.mAdvanceWidth - trimmableWidth <= availWidth,
"If the text doesn't fit, and we have a break opportunity, "
"why didn't MeasureText use it?");
MOZ_ASSERT(lastBreak >= offset, "Strange break position");
@ -9458,7 +9416,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// at most one space so there's no way for trimmable width from a previous
// frame to accumulate with trimmable width from this frame.)
if (transformedCharsFit > 0) {
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWS.mAdvance));
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWidth));
AddStateBits(TEXT_HAS_NONCOLLAPSED_CHARACTERS);
}
bool breakAfter = forceBreakAfter;
@ -9486,7 +9444,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// trailing whitespace. So we need to subtract trimmableWidth here
// because if we did break at this point, that much width would be
// trimmed.
if (textMetrics.mAdvanceWidth - trimmableWS.mAdvance > availWidth) {
if (textMetrics.mAdvanceWidth - trimmableWidth > availWidth) {
breakAfter = true;
} else {
aLineLayout.NotifyOptionalBreakPosition(this, length, true,
@ -9541,7 +9499,8 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
}
// Compute space and letter counts for justification, if required
if ((lineContainer->StyleText()->mTextAlign == StyleTextAlign::Justify ||
if (!textStyle->WhiteSpaceIsSignificant() &&
(lineContainer->StyleText()->mTextAlign == StyleTextAlign::Justify ||
lineContainer->StyleText()->mTextAlignLast ==
StyleTextAlignLast::Justify ||
shouldSuppressLineBreak) &&

Просмотреть файл

@ -773,11 +773,6 @@ class nsTextFrame : public nsIFrame {
void SetHangableISize(nscoord aISize);
nscoord GetHangableISize() const;
void ClearHangableISize();
void SetTrimmableWS(gfxTextRun::TrimmableWS aTrimmableWS);
gfxTextRun::TrimmableWS GetTrimmableWS() const;
void ClearTrimmableWS();
protected:
virtual ~nsTextFrame();
@ -813,20 +808,13 @@ class nsTextFrame : public nsIFrame {
};
mutable SelectionState mIsSelected;
// Flags used to track whether certain properties are present.
// (Public to keep MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS happy.)
public:
enum class PropertyFlags : uint8_t {
// Whether a cached continuations array is present.
Continuations = 1 << 0,
// Whether a HangableWhitespace property is present.
HangableWS = 1 << 1,
// Whether a TrimmableWhitespace property is present.
TrimmableWS = 2 << 1,
};
bool mHasContinuationsProperty = false;
protected:
PropertyFlags mPropertyFlags = PropertyFlags(0);
// Whether a HangableWhitespace property is present. This could have been a
// frame state bit, but they are currently full. Because we have a uint8_t
// and a bool just above, there's a hole here that we can use.
bool mHasHangableWS = false;
/**
* Return true if the frame is part of a Selection.
@ -1012,7 +1000,13 @@ class nsTextFrame : public nsIFrame {
// Clear any cached continuations array; this should be called whenever the
// chain is modified.
inline void ClearCachedContinuations();
void ClearCachedContinuations() {
MOZ_ASSERT(NS_IsMainThread());
if (mHasContinuationsProperty) {
RemoveProperty(ContinuationsProperty());
mHasContinuationsProperty = false;
}
}
/**
* UpdateIteratorFromOffset() updates the iterator from a given offset.
@ -1028,14 +1022,5 @@ class nsTextFrame : public nsIFrame {
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrame::TrimmedOffsetFlags)
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrame::PropertyFlags)
inline void nsTextFrame::ClearCachedContinuations() {
MOZ_ASSERT(NS_IsMainThread());
if (mPropertyFlags & PropertyFlags::Continuations) {
RemoveProperty(ContinuationsProperty());
mPropertyFlags &= ~PropertyFlags::Continuations;
}
}
#endif

Просмотреть файл

@ -5,7 +5,7 @@
<p>I am the very model of a modern major-general.</p>
<p style="width:100ch;">I am the very model of a modern major-general.</p>
<p style="width:100ch;">I &nbsp;am the<br>very model of a modern major-general.</p>
<p>I&nbsp;&nbsp;am the<br>very model of a modern major-general.</p>
<p style="text-align:left;">I&nbsp;&nbsp;&#x200b;am&nbsp;&#x200b;the<br>very&nbsp;&#x200b;model&nbsp;&#x200b;of&nbsp;&#x200b;a&nbsp;&#x200b;modern&nbsp;&#x200b;major-general.</p>
<p>I am the<br>very model of a modern major-general.</p>
</body>
</html>

Просмотреть файл

@ -1,4 +0,0 @@
[text-align-white-space-003.xht]
# CSS Text 3 allows justification to be applied, so this test is obsolete.
expected:
FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[pre-wrap-014.html]
expected: FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[textarea-pre-wrap-014.html]
expected: FAIL

Просмотреть файл

@ -1,3 +0,0 @@
[white-space-pre-wrap-justify-003.html]
fuzzy:
if os == "win": maxDifference=0-92;totalPixels=0-89

Просмотреть файл

@ -1,22 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text reference</title>
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=ref>one two three four five six seven eight nine ten</div>
<div class=ref>one two three four five six seven eight nine ten</div>

Просмотреть файл

@ -1,22 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text reference</title>
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=ref>one two&nbsp; three &nbsp; four five six seven eight nine &nbsp; ten</div>
<div class=ref>one two&nbsp; three &nbsp; four five six seven eight nine &nbsp; ten</div>

Просмотреть файл

@ -1,22 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text reference</title>
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=ref>one two&nbsp; three<br>&nbsp; &nbsp;four&nbsp; five&nbsp; six seven &nbsp; eight &nbsp; nine ten</div>
<div class=ref>one two&nbsp; three<br>&nbsp; &nbsp;four&nbsp; five&nbsp; six seven &nbsp; eight &nbsp; nine ten</div>

Просмотреть файл

@ -1,23 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text reference</title>
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.ref {
white-space: normal;
text-align: justify;
text-align-last: right;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=ref>,one, two, three<br>four, five, six, !seven, eight, nine</div>
<div class=ref>,one, two, three<br>four, five, six, !seven, eight, nine</div>

Просмотреть файл

@ -1,29 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: justification with white-space:pre-wrap</title>
<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-align-property">
<link rel="match" href="reference/white-space-pre-wrap-justify-001-ref.html">
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.test {
white-space: pre-wrap;
text-align: justify;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=test>one two three four five six seven eight nine ten</div>
<div class=ref>one two three four five six seven eight nine ten</div>

Просмотреть файл

@ -1,29 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: justification with white-space:pre-wrap</title>
<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-align-property">
<link rel="match" href="reference/white-space-pre-wrap-justify-002-ref.html">
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.test {
white-space: pre-wrap;
text-align: justify;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=test>one two three four five six seven eight nine ten</div>
<div class=ref>one two&nbsp; three &nbsp; four five six seven eight nine &nbsp; ten</div>

Просмотреть файл

@ -1,30 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: justification with white-space:pre-wrap</title>
<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-align-property">
<link rel="match" href="reference/white-space-pre-wrap-justify-003-ref.html">
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.test {
white-space: pre-wrap;
text-align: justify;
}
.ref {
white-space: normal;
text-align: justify;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div class=test>one two three
four five six seven eight nine ten</div>
<div class=ref>one two&nbsp; three<br>&nbsp; &nbsp;four&nbsp; five&nbsp; six seven &nbsp; eight &nbsp; nine ten</div>

Просмотреть файл

@ -1,31 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<title>CSS Text test: justification with white-space:pre-wrap</title>
<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-align-property">
<link rel="match" href="reference/white-space-pre-wrap-justify-004-ref.html">
<style>
div {
border: 1px solid gray;
font: 22px monospace;
width: 22ch;
margin: 1em;
}
.test {
white-space: pre-wrap;
text-align: justify;
}
.ref {
white-space: normal;
text-align: justify;
text-align-last: right;
}
</style>
<p>Test passes if the two blocks are rendered identically</p>
<div dir=rtl class=test>one, two, three,
four, five, six, seven, eight, nine!</div>
<div class=ref>,one, two, three<br>four, five, six, !seven, eight, nine</div>