Bug 537230 part.1 Paint connection of complex style decoration lines smoothly r=roc

This commit is contained in:
Masayuki Nakano 2012-07-04 14:59:50 +09:00
Родитель 7b2b8a1c8a
Коммит 34bdb7d777
9 изменённых файлов: 549 добавлений и 24 удалений

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

@ -3249,11 +3249,56 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
// End table border-collapsing section // End table border-collapsing section
gfxRect
nsCSSRendering::ExpandPaintingRectForDecorationLine(nsIFrame* aFrame,
const PRUint8 aStyle,
const gfxRect& aClippedRect,
const gfxFloat aXInFrame,
const gfxFloat aCycleLength)
{
switch (aStyle) {
case NS_STYLE_TEXT_DECORATION_STYLE_DOTTED:
case NS_STYLE_TEXT_DECORATION_STYLE_DASHED:
case NS_STYLE_TEXT_DECORATION_STYLE_WAVY:
break;
default:
NS_ERROR("Invalid style was specified");
return aClippedRect;
}
nsBlockFrame* block = nsnull;
// Note that when we paint the decoration lines in relative positioned
// box, we should paint them like all of the boxes are positioned as static.
nscoord relativeX = 0;
for (nsIFrame* f = aFrame; f; f = f->GetParent()) {
block = do_QueryFrame(f);
if (block) {
break;
}
relativeX += f->GetRelativeOffset(f->GetStyleDisplay()).x;
}
NS_ENSURE_TRUE(block, aClippedRect);
nscoord frameXInBlockAppUnits = aFrame->GetOffsetTo(block).x - relativeX;
nsPresContext *pc = aFrame->PresContext();
gfxFloat frameXInBlock = pc->AppUnitsToGfxUnits(frameXInBlockAppUnits);
PRInt32 rectXInBlock = PRInt32(NS_round(frameXInBlock + aXInFrame));
PRInt32 extraLeft =
rectXInBlock - (rectXInBlock / PRInt32(aCycleLength) * aCycleLength);
gfxRect rect(aClippedRect);
rect.x -= extraLeft;
rect.width += extraLeft;
return rect;
}
void void
nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext, nsCSSRendering::PaintDecorationLine(nsIFrame* aFrame,
gfxContext* aGfxContext,
const gfxRect& aDirtyRect, const gfxRect& aDirtyRect,
const nscolor aColor, const nscolor aColor,
const gfxPoint& aPt, const gfxPoint& aPt,
const gfxFloat aXInFrame,
const gfxSize& aLineSize, const gfxSize& aLineSize,
const gfxFloat aAscent, const gfxFloat aAscent,
const gfxFloat aOffset, const gfxFloat aOffset,
@ -3297,6 +3342,8 @@ nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext,
gfxFloat dash[2] = { dashWidth, dashWidth }; gfxFloat dash[2] = { dashWidth, dashWidth };
aGfxContext->SetLineCap(gfxContext::LINE_CAP_BUTT); aGfxContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
aGfxContext->SetDash(dash, 2, 0.0); aGfxContext->SetDash(dash, 2, 0.0);
rect = ExpandPaintingRectForDecorationLine(aFrame, aStyle, rect,
aXInFrame, dashWidth * 2);
// We should continue to draw the last dash even if it is not in the rect. // We should continue to draw the last dash even if it is not in the rect.
rect.width += dashWidth; rect.width += dashWidth;
break; break;
@ -3316,6 +3363,8 @@ nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext,
dash[1] = dashWidth; dash[1] = dashWidth;
} }
aGfxContext->SetDash(dash, 2, 0.0); aGfxContext->SetDash(dash, 2, 0.0);
rect = ExpandPaintingRectForDecorationLine(aFrame, aStyle, rect,
aXInFrame, dashWidth * 2);
// We should continue to draw the last dot even if it is not in the rect. // We should continue to draw the last dot even if it is not in the rect.
rect.width += dashWidth; rect.width += dashWidth;
break; break;
@ -3413,10 +3462,13 @@ nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext,
gfxFloat adv = rect.Height() - lineHeight; gfxFloat adv = rect.Height() - lineHeight;
gfxFloat flatLengthAtVertex = NS_MAX((lineHeight - 1.0) * 2.0, 1.0); gfxFloat flatLengthAtVertex = NS_MAX((lineHeight - 1.0) * 2.0, 1.0);
// Align the start of wavy lines to the nearest ancestor block.
gfxFloat cycleLength = 2 * (adv + flatLengthAtVertex);
rect = ExpandPaintingRectForDecorationLine(aFrame, aStyle, rect,
aXInFrame, cycleLength);
// figure out if we can trim whole cycles from the left and right edges // figure out if we can trim whole cycles from the left and right edges
// of the line, to try and avoid creating an unnecessarily long and // of the line, to try and avoid creating an unnecessarily long and
// complex path // complex path
gfxFloat cycleLength = 2 * (adv + flatLengthAtVertex);
PRInt32 skipCycles = floor((aDirtyRect.x - rect.x) / cycleLength); PRInt32 skipCycles = floor((aDirtyRect.x - rect.x) / cycleLength);
if (skipCycles > 0) { if (skipCycles > 0) {
rect.x += skipCycles * cycleLength; rect.x += skipCycles * cycleLength;

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

@ -387,10 +387,16 @@ struct nsCSSRendering {
* NOTE: aPt, aLineSize, aAscent and aOffset are non-rounded device pixels, * NOTE: aPt, aLineSize, aAscent and aOffset are non-rounded device pixels,
* not app units. * not app units.
* input: * input:
* @param aFrame the frame which needs the decoration line
* @param aGfxContext * @param aGfxContext
* @param aDirtyRect no need to paint outside this rect * @param aDirtyRect no need to paint outside this rect
* @param aColor the color of the decoration line * @param aColor the color of the decoration line
* @param aPt the top/left edge of the text * @param aPt the top/left edge of the text
* @param aXInFrame the distance between aPt.x and left edge of
* aFrame. If the decoration line is for shadow,
* set the distance between the left edge of
* the aFrame and the position of the text as
* positioned without offset of the shadow.
* @param aLineSize the width and the height of the decoration * @param aLineSize the width and the height of the decoration
* line * line
* @param aAscent the ascent of the text * @param aAscent the ascent of the text
@ -415,10 +421,12 @@ struct nsCSSRendering {
* if it's possible. Therefore, this value is * if it's possible. Therefore, this value is
* used for strikeout line and overline too. * used for strikeout line and overline too.
*/ */
static void PaintDecorationLine(gfxContext* aGfxContext, static void PaintDecorationLine(nsIFrame* aFrame,
gfxContext* aGfxContext,
const gfxRect& aDirtyRect, const gfxRect& aDirtyRect,
const nscolor aColor, const nscolor aColor,
const gfxPoint& aPt, const gfxPoint& aPt,
const gfxFloat aXInFrame,
const gfxSize& aLineSize, const gfxSize& aLineSize,
const gfxFloat aAscent, const gfxFloat aAscent,
const gfxFloat aOffset, const gfxFloat aOffset,
@ -475,6 +483,32 @@ protected:
const PRUint8 aDecoration, const PRUint8 aDecoration,
const PRUint8 aStyle, const PRUint8 aStyle,
const gfxFloat aDscentLimit); const gfxFloat aDscentLimit);
/**
* Returns inflated rect for painting a decoration line.
* Complex style decoration lines should be painted from leftmost of nearest
* ancestor block box because that makes better look of connection of lines
* for different nodes. ExpandPaintingRectForDecorationLine() returns
* a rect for actual painting rect for the clipped rect.
*
* input:
* @param aFrame the frame which needs the decoration line.
* @param aStyle the style of the complex decoration line
* NS_STYLE_TEXT_DECORATION_STYLE_DOTTED or
* NS_STYLE_TEXT_DECORATION_STYLE_DASHED or
* NS_STYLE_TEXT_DECORATION_STYLE_WAVY.
* @param aClippedRect the clipped rect for the decoration line.
* in other words, visible area of the line.
* @param aXInFrame the distance between left edge of aFrame and
* aClippedRect.pos.x.
* @param aCycleLength the width of one cycle of the line style.
*/
static gfxRect ExpandPaintingRectForDecorationLine(
nsIFrame* aFrame,
const PRUint8 aStyle,
const gfxRect &aClippedRect,
const gfxFloat aXInFrame,
const gfxFloat aCycleLength);
}; };
/* /*

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

@ -4772,7 +4772,7 @@ static void DrawSelectionDecorations(gfxContext* aContext,
nsTextFrame* aFrame, nsTextFrame* aFrame,
nsTextPaintStyle& aTextPaintStyle, nsTextPaintStyle& aTextPaintStyle,
const nsTextRangeStyle &aRangeStyle, const nsTextRangeStyle &aRangeStyle,
const gfxPoint& aPt, gfxFloat aWidth, const gfxPoint& aPt, gfxFloat aXInFrame, gfxFloat aWidth,
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics) gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics)
{ {
gfxPoint pt(aPt); gfxPoint pt(aPt);
@ -4849,8 +4849,8 @@ static void DrawSelectionDecorations(gfxContext* aContext,
return; return;
} }
size.height *= relativeSize; size.height *= relativeSize;
nsCSSRendering::PaintDecorationLine( nsCSSRendering::PaintDecorationLine(aFrame, aContext, aDirtyRect, color, pt,
aContext, aDirtyRect, color, pt, size, aAscent, aFontMetrics.underlineOffset, pt.x - aPt.x + aXInFrame, size, aAscent, aFontMetrics.underlineOffset,
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, style, descentLimit); NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, style, descentLimit);
} }
@ -5289,9 +5289,10 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
pt.x = (aFramePt.x + xOffset - pt.x = (aFramePt.x + xOffset -
(mTextRun->IsRightToLeft() ? advance : 0)) / app; (mTextRun->IsRightToLeft() ? advance : 0)) / app;
gfxFloat width = NS_ABS(advance) / app; gfxFloat width = NS_ABS(advance) / app;
DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, this, aTextPaintStyle, gfxFloat xInFrame = pt.x - (aFramePt.x / app);
selectedStyle, DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, this,
pt, width, mAscent / app, decorationMetrics); aTextPaintStyle, selectedStyle, pt, xInFrame,
width, mAscent / app, decorationMetrics);
} }
iterator.UpdateWithAdvance(advance); iterator.UpdateWithAdvance(advance);
} }
@ -5642,9 +5643,9 @@ nsTextFrame::DrawTextRunAndDecorations(
decPt.y = (frameTop - dec.mBaselineOffset) / app; decPt.y = (frameTop - dec.mBaselineOffset) / app;
const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor; const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor;
nsCSSRendering::PaintDecorationLine(aCtx, dirtyRect, lineColor, decPt, decSize, ascent, nsCSSRendering::PaintDecorationLine(this, aCtx, dirtyRect, lineColor,
metrics.underlineOffset, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, decPt, 0.0, decSize, ascent, metrics.underlineOffset,
dec.mStyle); NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, dec.mStyle);
} }
// Overlines // Overlines
for (PRUint32 i = aDecorations.mOverlines.Length(); i-- > 0; ) { for (PRUint32 i = aDecorations.mOverlines.Length(); i-- > 0; ) {
@ -5659,8 +5660,9 @@ nsTextFrame::DrawTextRunAndDecorations(
decPt.y = (frameTop - dec.mBaselineOffset) / app; decPt.y = (frameTop - dec.mBaselineOffset) / app;
const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor; const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor;
nsCSSRendering::PaintDecorationLine(aCtx, dirtyRect, lineColor, decPt, decSize, ascent, nsCSSRendering::PaintDecorationLine(this, aCtx, dirtyRect, lineColor,
metrics.maxAscent, NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle); decPt, 0.0, decSize, ascent, metrics.maxAscent,
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle);
} }
// CSS 2.1 mandates that text be painted after over/underlines, and *then* // CSS 2.1 mandates that text be painted after over/underlines, and *then*
@ -5681,9 +5683,9 @@ nsTextFrame::DrawTextRunAndDecorations(
decPt.y = (frameTop - dec.mBaselineOffset) / app; decPt.y = (frameTop - dec.mBaselineOffset) / app;
const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor; const nscolor lineColor = aDecorationOverrideColor ? *aDecorationOverrideColor : dec.mColor;
nsCSSRendering::PaintDecorationLine(aCtx, dirtyRect, lineColor, decPt, decSize, ascent, nsCSSRendering::PaintDecorationLine(this, aCtx, dirtyRect, lineColor,
metrics.strikeoutOffset, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, decPt, 0.0, decSize, ascent, metrics.strikeoutOffset,
dec.mStyle); NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, dec.mStyle);
} }
} }

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

@ -0,0 +1,102 @@
<style type="text/css">
p {
margin-left: 11px;
padding-left: 11px;
}
p.dotted span {
-moz-text-decoration-style: dotted;
}
p.dashed span {
-moz-text-decoration-style: dashed;
}
p.wavy span {
-moz-text-decoration-style: wavy;
}
span {
text-decoration: underline line-through overline;
}
p.relative {
margin-left: 24px;
}
p.shadow span {
position: relative;
left: 1em;
top: 0.5em;
}
</style>
<div style="font-size: 16px;">
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
</div>
<div style="font-size: 32px;">
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
</div>

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

@ -0,0 +1,114 @@
<style type="text/css">
p {
margin-left: 11px;
padding-left: 11px;
}
p.dotted span {
-moz-text-decoration-style: dotted;
}
p.dashed span {
-moz-text-decoration-style: dashed;
}
p.wavy span {
-moz-text-decoration-style: wavy;
}
span {
text-decoration: underline line-through overline;
}
p.relative span {
position: relative;
left: 13px;
}
p.relative2 > span {
position: relative;
left: 13px;
text-decoration: none;
}
p.relative2 span span {
position: relative;
left: -13px;
}
p.shadow {
color: transparent;
text-shadow: 1em 0.5em black;
}
</style>
<div style="font-size: 16px;">
<p class="dotted">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dashed relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="wavy relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dotted shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
</div>
<div style="font-size: 32px;">
<p class="dotted">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dashed relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="wavy relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dotted shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
</div>

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

@ -0,0 +1,103 @@
<!DOCTYPE html>
<style type="text/css">
p {
margin-left: 11px;
padding-left: 11px;
}
p.dotted span {
-moz-text-decoration-style: dotted;
}
p.dashed span {
-moz-text-decoration-style: dashed;
}
p.wavy span {
-moz-text-decoration-style: wavy;
}
span {
text-decoration: underline line-through overline;
}
p.relative {
margin-left: 24px;
}
p.shadow span {
position: relative;
left: 1em;
top: 0.5em;
}
</style>
<div style="font-size: 16px;">
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
</div>
<div style="font-size: 32px;">
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dotted shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</p>
</div>

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

@ -0,0 +1,115 @@
<!DOCTYPE html>
<style type="text/css">
p {
margin-left: 11px;
padding-left: 11px;
}
p.dotted span {
-moz-text-decoration-style: dotted;
}
p.dashed span {
-moz-text-decoration-style: dashed;
}
p.wavy span {
-moz-text-decoration-style: wavy;
}
span {
text-decoration: underline line-through overline;
}
p.relative span {
position: relative;
left: 13px;
}
p.relative2 > span {
position: relative;
left: 13px;
text-decoration: none;
}
p.relative2 span span {
position: relative;
left: -13px;
}
p.shadow {
color: transparent;
text-shadow: 1em 0.5em black;
}
</style>
<div style="font-size: 16px;">
<p class="dotted">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dashed relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="wavy relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dotted shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
</div>
<div style="font-size: 32px;">
<p class="dotted">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy relative">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dotted relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dashed relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="wavy relative2">
<span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span></span>
</p>
<p class="dotted shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="dashed shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
<p class="wavy shadow">
<span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span><span>&nbsp;</span>
</p>
</div>

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

@ -1,3 +1,5 @@
== complex-decoration-style-quirks.html complex-decoration-style-quirks-ref.html
== complex-decoration-style-standards.html complex-decoration-style-standards-ref.html
== decoration-color-quirks.html decoration-color-quirks-ref.html == decoration-color-quirks.html decoration-color-quirks-ref.html
== decoration-color-standards.html decoration-color-standards-ref.html == decoration-color-standards.html decoration-color-standards-ref.html
== decoration-style-quirks.html decoration-style-quirks-ref.html == decoration-style-quirks.html decoration-style-quirks-ref.html

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

@ -460,6 +460,7 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
presContext->AppUnitsToGfxUnits(aTextRect.y)); presContext->AppUnitsToGfxUnits(aTextRect.y));
gfxFloat width = presContext->AppUnitsToGfxUnits(aTextRect.width); gfxFloat width = presContext->AppUnitsToGfxUnits(aTextRect.width);
gfxFloat ascentPixel = presContext->AppUnitsToGfxUnits(ascent); gfxFloat ascentPixel = presContext->AppUnitsToGfxUnits(ascent);
gfxFloat xInFrame = PresContext()->AppUnitsToGfxUnits(mTextDrawRect.x);
gfxRect dirtyRect(presContext->AppUnitsToGfxUnits(aDirtyRect)); gfxRect dirtyRect(presContext->AppUnitsToGfxUnits(aDirtyRect));
// Underlines are drawn before overlines, and both before the text // Underlines are drawn before overlines, and both before the text
@ -474,15 +475,15 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size); gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size);
if ((decorations & NS_FONT_DECORATION_UNDERLINE) && if ((decorations & NS_FONT_DECORATION_UNDERLINE) &&
underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) { underStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, underColor, nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, underColor,
pt, gfxSize(width, sizePixel), pt, xInFrame, gfxSize(width, sizePixel),
ascentPixel, offsetPixel, ascentPixel, offsetPixel,
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, underStyle); NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, underStyle);
} }
if ((decorations & NS_FONT_DECORATION_OVERLINE) && if ((decorations & NS_FONT_DECORATION_OVERLINE) &&
overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) { overStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE) {
nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, overColor, nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, overColor,
pt, gfxSize(width, sizePixel), pt, xInFrame, gfxSize(width, sizePixel),
ascentPixel, ascentPixel, ascentPixel, ascentPixel,
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, overStyle); NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, overStyle);
} }
@ -563,9 +564,9 @@ nsTextBoxFrame::DrawText(nsRenderingContext& aRenderingContext,
fontMet->GetStrikeout(offset, size); fontMet->GetStrikeout(offset, size);
gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset); gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset);
gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size); gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size);
nsCSSRendering::PaintDecorationLine(ctx, dirtyRect, strikeColor, nsCSSRendering::PaintDecorationLine(this, ctx, dirtyRect, strikeColor,
pt, gfxSize(width, sizePixel), ascentPixel, offsetPixel, pt, xInFrame, gfxSize(width, sizePixel), ascentPixel,
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, offsetPixel, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
strikeStyle); strikeStyle);
} }
} }