Bug 486778 Spell checker's wavy line is sometimes drawn through misspelled words r+sr=roc

This commit is contained in:
Masayuki Nakano 2009-07-01 01:52:16 +09:00
Родитель 23f8f1476f
Коммит a9ad59ba64
3 изменённых файлов: 29 добавлений и 25 удалений

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

@ -2758,10 +2758,9 @@ nsCSSRendering::GetTextDecorationRectInternal(const gfxPoint& aPt,
lineHeight = PR_MAX(lineHeight, 1.0);
gfxFloat ascent = NS_round(aAscent);
gfxFloat descentLimit = NS_round(aDescentLimit);
gfxFloat descentLimit = NS_floor(aDescentLimit);
gfxFloat suggestedMaxRectHeight = PR_MAX(PR_MIN(ascent, descentLimit), 1.0);
gfxFloat underlineOffsetAdjust = 0.0;
r.size.height = lineHeight;
if (aStyle == DECORATION_STYLE_DOUBLE) {
/**
@ -2805,12 +2804,6 @@ nsCSSRendering::GetTextDecorationRectInternal(const gfxPoint& aPt,
*/
r.size.height = lineHeight > 2.0 ? lineHeight * 4.0 : lineHeight * 3.0;
if (canLiftUnderline) {
// Wavy line's top edge can overlap to the baseline, because even if the
// wavy line overlaps the baseline of the text, that shouldn't cause
// unreadability.
descentLimit += lineHeight;
// Recompute suggestedMaxRectHeight with new descentLimit value.
suggestedMaxRectHeight = PR_MAX(PR_MIN(ascent, descentLimit), 1.0);
if (r.Height() > suggestedMaxRectHeight) {
// Don't shrink the line height even if there is not enough space,
// because the thickness has some meaning. E.g., the 1px wavy line and
@ -2819,18 +2812,13 @@ nsCSSRendering::GetTextDecorationRectInternal(const gfxPoint& aPt,
r.size.height = PR_MAX(suggestedMaxRectHeight, lineHeight * 2.0);
}
}
// If this is underline, the middle of the rect should be aligned to the
// specified underline offset. So, wavy line's top edge can overlap to
// baseline. Because even if the wavy line overlaps the baseline of the
// text, that shouldn't cause unreadability.
underlineOffsetAdjust = r.Height() / 2.0;
}
gfxFloat baseline = NS_floor(aPt.y + aAscent + 0.5);
gfxFloat offset = 0.0;
switch (aDecoration) {
case NS_STYLE_TEXT_DECORATION_UNDERLINE:
offset = aOffset + underlineOffsetAdjust;
offset = aOffset;
if (canLiftUnderline) {
if (descentLimit < -offset + r.Height()) {
// If we can ignore the offset and the decoration line is overflowing,
@ -2838,7 +2826,7 @@ nsCSSRendering::GetTextDecorationRectInternal(const gfxPoint& aPt,
// possible. Otherwise, we should lift up the top edge of the rect as
// far as possible.
gfxFloat offsetBottomAligned = -descentLimit + r.Height();
gfxFloat offsetTopAligned = underlineOffsetAdjust;
gfxFloat offsetTopAligned = 0.0;
offset = PR_MIN(offsetBottomAligned, offsetTopAligned);
}
}

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

@ -164,10 +164,9 @@ function getTextDecorationRect(aPt, aLineSize, aAscent, aOffset, aStyle,
lineHeight = Math.max(lineHeight, 1.0);
var ascent = round(aAscent);
var descentLimit = round(aDescentLimit);
var descentLimit = Math.floor(aDescentLimit);
var suggestedMaxRectHeight = Math.max(Math.min(ascent, descentLimit), 1.0);
var underlineOffsetAdjust = 0.0;
r.height = lineHeight;
if (aStyle == kDecorationStyleDouble) {
var gap = round(lineHeight / 2.0);
@ -181,23 +180,20 @@ function getTextDecorationRect(aPt, aLineSize, aAscent, aOffset, aStyle,
} else if (aStyle == kDecorationStyleWavy) {
r.height = lineHeight > 2.0 ? lineHeight * 4.0 : lineHeight * 3.0;
if (liftupUnderline) {
descentLimit += lineHeight;
suggestedMaxRectHeight = Math.max(Math.min(ascent, descentLimit), 1.0);
if (r.height > suggestedMaxRectHeight) {
r.height = Math.max(suggestedMaxRectHeight, lineHeight * 2.0);
}
}
underlineOffsetAdjust = r.height / 2.0;
}
var baseline = Math.floor(aPt.y + aAscent + 0.5);
var offset = 0.0;
offset = aOffset + underlineOffsetAdjust;
offset = aOffset;
if (liftupUnderline) {
if (descentLimit < -offset + r.height) {
var offsetBottomAligned = -descentLimit + r.height;
var offsetTopAligned = underlineOffsetAdjust;
var offsetTopAligned = 0.0;
offset = Math.min(offsetBottomAligned, offsetTopAligned);
}
}

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

@ -4091,6 +4091,22 @@ nsTextFrame::PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
}
}
static gfxFloat
ComputeDescentLimitForSelectionUnderline(nsPresContext* aPresContext,
nsTextFrame* aFrame,
const gfxFont::Metrics& aFontMetrics)
{
gfxFloat app = aPresContext->AppUnitsPerDevPixel();
nscoord lineHeightApp =
nsHTMLReflowState::CalcLineHeight(aFrame->GetStyleContext(), NS_AUTOHEIGHT);
gfxFloat lineHeight = gfxFloat(lineHeightApp) / app;
if (lineHeight <= aFontMetrics.maxHeight) {
return aFontMetrics.maxDescent;
}
return aFontMetrics.maxDescent + (lineHeight - aFontMetrics.maxHeight) / 2;
}
// Make sure this stays in sync with DrawSelectionDecorations below
static const SelectionType SelectionTypesWithDecorations =
nsISelectionController::SELECTION_SPELLCHECK |
@ -4128,6 +4144,7 @@ GetTextDecorationStyle(const nsTextRangeStyle &aRangeStyle)
* drawing text decoration for selections.
*/
static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
nsTextFrame* aFrame,
nsTextPaintStyle& aTextPaintStyle,
const nsTextRangeStyle &aRangeStyle,
const gfxPoint& aPt, gfxFloat aWidth,
@ -4135,7 +4152,9 @@ static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
{
gfxPoint pt(aPt);
gfxSize size(aWidth, aFontMetrics.underlineSize);
gfxFloat descentLimit = aFontMetrics.maxDescent;
gfxFloat descentLimit =
ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
aFrame, aFontMetrics);
float relativeSize;
PRUint8 style;
@ -4595,7 +4614,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
pt.x = (aFramePt.x + xOffset -
(mTextRun->IsRightToLeft() ? advance : 0)) / app;
gfxFloat width = PR_ABS(advance) / app;
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
DrawSelectionDecorations(aCtx, aSelectionType, this, aTextPaintStyle,
selectedStyle,
pt, width, mAscent / app, decorationMetrics);
}
@ -4900,7 +4919,8 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
const gfxFont::Metrics& metrics = firstFont->GetMetrics();
gfxFloat underlineOffset = fontGroup->GetUnderlineOffset();
gfxFloat ascent = aPresContext->AppUnitsToGfxUnits(mAscent);
gfxFloat descentLimit = metrics.maxDescent;
gfxFloat descentLimit =
ComputeDescentLimitForSelectionUnderline(aPresContext, this, metrics);
SelectionDetails *details = GetSelectionDetails();
for (SelectionDetails *sd = details; sd; sd = sd->mNext) {