зеркало из https://github.com/mozilla/pjs.git
Bug 365336 text-decoration width should be rounded to the device pixels r+sr=roc
This commit is contained in:
Родитель
8f9c022bd3
Коммит
33b8312a5c
|
@ -4355,3 +4355,128 @@ nsCSSRendering::DrawTableBorderSegment(nsIRenderingContext& aContext,
|
||||||
|
|
||||||
// End table border-collapsing section
|
// End table border-collapsing section
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext,
|
||||||
|
const nscolor aColor,
|
||||||
|
const gfxPoint& aPt,
|
||||||
|
const gfxSize& aLineSize,
|
||||||
|
const gfxFloat aAscent,
|
||||||
|
const gfxFloat aOffset,
|
||||||
|
const gfxFloat aPreferredHeight,
|
||||||
|
const PRUint8 aDecoration,
|
||||||
|
const PRUint8 aStyle,
|
||||||
|
const PRBool aIsRTL)
|
||||||
|
{
|
||||||
|
if (aLineSize.width <= 0 || aLineSize.height <= 0 ||
|
||||||
|
aStyle == NS_STYLE_BORDER_STYLE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PRBool contextIsSaved = PR_FALSE;
|
||||||
|
gfxFloat totalHeight = aLineSize.height;
|
||||||
|
switch (aStyle) {
|
||||||
|
case NS_STYLE_BORDER_STYLE_SOLID:
|
||||||
|
break;
|
||||||
|
case NS_STYLE_BORDER_STYLE_DASHED: {
|
||||||
|
aGfxContext->Save();
|
||||||
|
contextIsSaved = PR_TRUE;
|
||||||
|
gfxFloat dashWidth = aLineSize.height * DOT_LENGTH * DASH_LENGTH;
|
||||||
|
gfxFloat dash[2] = { dashWidth, dashWidth };
|
||||||
|
aGfxContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
|
||||||
|
aGfxContext->SetDash(dash, 2, 0.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NS_STYLE_BORDER_STYLE_DOTTED: {
|
||||||
|
aGfxContext->Save();
|
||||||
|
contextIsSaved = PR_TRUE;
|
||||||
|
gfxFloat dashWidth = aLineSize.height * DOT_LENGTH;
|
||||||
|
gfxFloat dash[2];
|
||||||
|
if (aLineSize.height > 2.0) {
|
||||||
|
dash[0] = 0.0;
|
||||||
|
dash[1] = dashWidth * 2.0;
|
||||||
|
aGfxContext->SetLineCap(gfxContext::LINE_CAP_ROUND);
|
||||||
|
} else {
|
||||||
|
dash[0] = dashWidth;
|
||||||
|
dash[1] = dashWidth;
|
||||||
|
}
|
||||||
|
aGfxContext->SetDash(dash, 2, 0.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NS_STYLE_BORDER_STYLE_DOUBLE:
|
||||||
|
totalHeight *= 3.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_ERROR("Invalid style value!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxFloat offset = aOffset;
|
||||||
|
switch (aDecoration) {
|
||||||
|
case NS_STYLE_TEXT_DECORATION_UNDERLINE:
|
||||||
|
break;
|
||||||
|
case NS_STYLE_TEXT_DECORATION_OVERLINE:
|
||||||
|
// The offset includes the preferred size, we should remove it
|
||||||
|
offset += aPreferredHeight;
|
||||||
|
// the bottom of the decoration line should be aligned to the top of the
|
||||||
|
// text.
|
||||||
|
offset -= totalHeight;
|
||||||
|
break;
|
||||||
|
case NS_STYLE_TEXT_DECORATION_LINE_THROUGH: {
|
||||||
|
// The offset includes the preferred size, we should remove it
|
||||||
|
offset += aPreferredHeight;
|
||||||
|
// the middle of the decoration line should be aligned to the middle of
|
||||||
|
// the original strike out offset.
|
||||||
|
offset -= PR_MAX(aPreferredHeight, (totalHeight / 2.0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NS_ERROR("Invalid decoration value!");
|
||||||
|
if (contextIsSaved)
|
||||||
|
aGfxContext->Restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// round to device pixels for suppressing the AA.
|
||||||
|
gfxFloat x = NS_round(aPt.x);
|
||||||
|
gfxFloat y = NS_round(aPt.y + aAscent - offset);
|
||||||
|
gfxFloat width = NS_round(aLineSize.width);
|
||||||
|
gfxFloat height = NS_round(aLineSize.height);
|
||||||
|
// The y position should be set to the middle of the line.
|
||||||
|
y += height / 2;
|
||||||
|
|
||||||
|
aGfxContext->SetColor(gfxRGBA(aColor));
|
||||||
|
aGfxContext->SetLineWidth(height);
|
||||||
|
switch (aStyle) {
|
||||||
|
case NS_STYLE_BORDER_STYLE_SOLID:
|
||||||
|
aGfxContext->NewPath();
|
||||||
|
aGfxContext->MoveTo(gfxPoint(x, y));
|
||||||
|
aGfxContext->LineTo(gfxPoint(x + width, y));
|
||||||
|
aGfxContext->Stroke();
|
||||||
|
break;
|
||||||
|
case NS_STYLE_BORDER_STYLE_DOUBLE:
|
||||||
|
aGfxContext->NewPath();
|
||||||
|
aGfxContext->MoveTo(gfxPoint(x, y));
|
||||||
|
aGfxContext->LineTo(gfxPoint(x + width, y));
|
||||||
|
aGfxContext->MoveTo(gfxPoint(x, y + height * 2.0));
|
||||||
|
aGfxContext->LineTo(gfxPoint(x + width, y + height * 2.0));
|
||||||
|
aGfxContext->Stroke();
|
||||||
|
break;
|
||||||
|
case NS_STYLE_BORDER_STYLE_DOTTED:
|
||||||
|
case NS_STYLE_BORDER_STYLE_DASHED:
|
||||||
|
aGfxContext->NewPath();
|
||||||
|
if (aIsRTL) {
|
||||||
|
aGfxContext->MoveTo(gfxPoint(x + width, y));
|
||||||
|
aGfxContext->LineTo(gfxPoint(x, y));
|
||||||
|
} else {
|
||||||
|
aGfxContext->MoveTo(gfxPoint(x, y));
|
||||||
|
aGfxContext->LineTo(gfxPoint(x + width, y));
|
||||||
|
}
|
||||||
|
aGfxContext->Stroke();
|
||||||
|
aGfxContext->Restore();
|
||||||
|
contextIsSaved = PR_FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_ERROR("Invalid style value!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NS_ASSERTION(!contextIsSaved, "The gfxContext has been saved, but not restored!");
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define nsCSSRendering_h___
|
#define nsCSSRendering_h___
|
||||||
|
|
||||||
#include "nsIRenderingContext.h"
|
#include "nsIRenderingContext.h"
|
||||||
|
#include "gfxContext.h"
|
||||||
struct nsPoint;
|
struct nsPoint;
|
||||||
class nsStyleContext;
|
class nsStyleContext;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
|
@ -198,6 +199,45 @@ public:
|
||||||
*/
|
*/
|
||||||
static nscolor TransformColor(nscolor aMapColor,PRBool aNoBackGround);
|
static nscolor TransformColor(nscolor aMapColor,PRBool aNoBackGround);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for painting the decoration lines for the text.
|
||||||
|
* NOTE: aPt, aLineSize, aAscent, aOffset and aReferredHeight are non-rounded
|
||||||
|
* device pixels, not app units.
|
||||||
|
* input:
|
||||||
|
* @param aGfxContext
|
||||||
|
* @param aColor the color of the decoration line
|
||||||
|
* @param aPt the top/left edge of the text
|
||||||
|
* @param aLineSize the width and the height of the decoration
|
||||||
|
* line
|
||||||
|
* @param aAscent the ascent of the text
|
||||||
|
* @param aOffset the offset of the decoration line from
|
||||||
|
* the baseline of the text (if the value is
|
||||||
|
* positive, the line is lifted up)
|
||||||
|
* @param aPreferredHeight the preferred size of the decoration line by
|
||||||
|
* the font of the text
|
||||||
|
* @param aDecoration which line will be painted. The value can be
|
||||||
|
* NS_STYLE_TEXT_DECORATION_UNDERLINE or
|
||||||
|
* NS_STYLE_TEXT_DECORATION_OVERLINE or
|
||||||
|
* NS_STYLE_TEXT_DECORATION_LINE_THROUGH.
|
||||||
|
* @param aStyle the style of the decoration line. The value
|
||||||
|
* can be NS_STYLE_BORDER_STYLE_SOLID or
|
||||||
|
* NS_STYLE_BORDER_STYLE_DOTTED or
|
||||||
|
* NS_STYLE_BORDER_STYLE_DASHED or
|
||||||
|
* NS_STYLE_BORDER_STYLE_DOUBLE or
|
||||||
|
* NS_STYLE_BORDER_STYLE_NONE.
|
||||||
|
* @param aIsRTL when the text is RTL, it is true.
|
||||||
|
*/
|
||||||
|
static void PaintDecorationLine(gfxContext* aGfxContext,
|
||||||
|
const nscolor aColor,
|
||||||
|
const gfxPoint& aPt,
|
||||||
|
const gfxSize& aLineSize,
|
||||||
|
const gfxFloat aAscent,
|
||||||
|
const gfxFloat aOffset,
|
||||||
|
const gfxFloat aPreferredSize,
|
||||||
|
const PRUint8 aDecoration,
|
||||||
|
const PRUint8 aStyle,
|
||||||
|
const PRBool aIsRTL);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void PaintBackgroundColor(nsPresContext* aPresContext,
|
static void PaintBackgroundColor(nsPresContext* aPresContext,
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "nsContentErrors.h"
|
#include "nsContentErrors.h"
|
||||||
#include "nsCSSAnonBoxes.h"
|
#include "nsCSSAnonBoxes.h"
|
||||||
|
#include "nsCSSRendering.h"
|
||||||
|
|
||||||
#ifdef IBMBIDI
|
#ifdef IBMBIDI
|
||||||
#include "nsBidiPresUtils.h"
|
#include "nsBidiPresUtils.h"
|
||||||
|
@ -5663,9 +5664,9 @@ nsBlockFrame::PaintTextDecorationLine(nsIRenderingContext& aRenderingContext,
|
||||||
nscolor aColor,
|
nscolor aColor,
|
||||||
nscoord aOffset,
|
nscoord aOffset,
|
||||||
nscoord aAscent,
|
nscoord aAscent,
|
||||||
nscoord aSize)
|
nscoord aSize,
|
||||||
|
const PRUint8 aDecoration)
|
||||||
{
|
{
|
||||||
aRenderingContext.SetColor(aColor);
|
|
||||||
NS_ASSERTION(!aLine->IsBlock(), "Why did we ask for decorations on a block?");
|
NS_ASSERTION(!aLine->IsBlock(), "Why did we ask for decorations on a block?");
|
||||||
|
|
||||||
nscoord start = aLine->mBounds.x;
|
nscoord start = aLine->mBounds.x;
|
||||||
|
@ -5698,9 +5699,18 @@ nsBlockFrame::PaintTextDecorationLine(nsIRenderingContext& aRenderingContext,
|
||||||
|
|
||||||
// Only paint if we have a positive width
|
// Only paint if we have a positive width
|
||||||
if (width > 0) {
|
if (width > 0) {
|
||||||
aRenderingContext.FillRect(start + aPt.x,
|
const nsStyleVisibility* visibility = GetStyleVisibility();
|
||||||
aLine->mBounds.y + aLine->GetAscent() - aOffset + aPt.y,
|
PRBool isRTL = visibility->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||||
width, aSize);
|
nsRefPtr<gfxContext> ctx = (gfxContext*)
|
||||||
|
aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||||
|
gfxFloat a2p = 1.0 / PresContext()->AppUnitsPerDevPixel();
|
||||||
|
gfxPoint pt((start + aPt.x) * a2p, (aLine->mBounds.y + aPt.y) * a2p);
|
||||||
|
gfxSize size(width * a2p, aSize * a2p);
|
||||||
|
nsCSSRendering::PaintDecorationLine(ctx, aColor, pt, size,
|
||||||
|
aLine->GetAscent() * a2p, aOffset * a2p,
|
||||||
|
aSize * a2p, aDecoration,
|
||||||
|
NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
isRTL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,8 @@ protected:
|
||||||
nscolor aColor,
|
nscolor aColor,
|
||||||
nscoord aOffset,
|
nscoord aOffset,
|
||||||
nscoord aAscent,
|
nscoord aAscent,
|
||||||
nscoord aSize);
|
nscoord aSize,
|
||||||
|
const PRUint8 aDecoration);
|
||||||
|
|
||||||
void TryAllLines(nsLineList::iterator* aIterator,
|
void TryAllLines(nsLineList::iterator* aIterator,
|
||||||
nsLineList::iterator* aEndIterator,
|
nsLineList::iterator* aEndIterator,
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
#include "nsBlockFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
#include "nsLineBox.h"
|
#include "nsLineBox.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
|
#include "nsCSSRendering.h"
|
||||||
|
|
||||||
class nsDisplayTextDecoration : public nsDisplayItem {
|
class nsDisplayTextDecoration : public nsDisplayItem {
|
||||||
public:
|
public:
|
||||||
|
@ -117,13 +118,16 @@ nsDisplayTextDecoration::Paint(nsDisplayListBuilder* aBuilder,
|
||||||
if (mDecoration != NS_STYLE_TEXT_DECORATION_LINE_THROUGH) {
|
if (mDecoration != NS_STYLE_TEXT_DECORATION_LINE_THROUGH) {
|
||||||
fm->GetUnderline(offset, size);
|
fm->GetUnderline(offset, size);
|
||||||
if (mDecoration == NS_STYLE_TEXT_DECORATION_UNDERLINE) {
|
if (mDecoration == NS_STYLE_TEXT_DECORATION_UNDERLINE) {
|
||||||
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor, offset, ascent, size);
|
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor,
|
||||||
|
offset, ascent, size, mDecoration);
|
||||||
} else if (mDecoration == NS_STYLE_TEXT_DECORATION_OVERLINE) {
|
} else if (mDecoration == NS_STYLE_TEXT_DECORATION_OVERLINE) {
|
||||||
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor, ascent, ascent, size);
|
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor,
|
||||||
|
ascent, ascent, size, mDecoration);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fm->GetStrikeout(offset, size);
|
fm->GetStrikeout(offset, size);
|
||||||
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor, offset, ascent, size);
|
f->PaintTextDecorationLine(*aCtx, pt, mLine, mColor,
|
||||||
|
offset, ascent, size, mDecoration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +207,8 @@ nsHTMLContainerFrame::PaintTextDecorationLine(
|
||||||
nscolor aColor,
|
nscolor aColor,
|
||||||
nscoord aOffset,
|
nscoord aOffset,
|
||||||
nscoord aAscent,
|
nscoord aAscent,
|
||||||
nscoord aSize)
|
nscoord aSize,
|
||||||
|
const PRUint8 aDecoration)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!aLine, "Should not have passed a linebox to a non-block frame");
|
NS_ASSERTION(!aLine, "Should not have passed a linebox to a non-block frame");
|
||||||
nsMargin bp = GetUsedBorderAndPadding();
|
nsMargin bp = GetUsedBorderAndPadding();
|
||||||
|
@ -213,10 +218,17 @@ nsHTMLContainerFrame::PaintTextDecorationLine(
|
||||||
bp.side(side) = 0;
|
bp.side(side) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aRenderingContext.SetColor(aColor);
|
const nsStyleVisibility* visibility = GetStyleVisibility();
|
||||||
|
PRBool isRTL = visibility->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||||
nscoord innerWidth = mRect.width - bp.left - bp.right;
|
nscoord innerWidth = mRect.width - bp.left - bp.right;
|
||||||
aRenderingContext.FillRect(bp.left + aPt.x,
|
nsRefPtr<gfxContext> ctx = (gfxContext*)
|
||||||
bp.top + aAscent - aOffset + aPt.y, innerWidth, aSize);
|
aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||||
|
gfxFloat a2p = 1.0 / PresContext()->AppUnitsPerDevPixel();
|
||||||
|
gfxPoint pt((bp.left + aPt.x) * a2p, (bp.top + aPt.y) * a2p);
|
||||||
|
gfxSize size(innerWidth * a2p, aSize * a2p);
|
||||||
|
nsCSSRendering::PaintDecorationLine(ctx, aColor, pt, size, aAscent * a2p,
|
||||||
|
aOffset * a2p, aSize * a2p, aDecoration,
|
||||||
|
NS_STYLE_BORDER_STYLE_SOLID, isRTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -170,6 +170,10 @@ protected:
|
||||||
* i.e. negative offsets draws *below*
|
* i.e. negative offsets draws *below*
|
||||||
* the baseline.
|
* the baseline.
|
||||||
* @param aSize the thickness of the line
|
* @param aSize the thickness of the line
|
||||||
|
* @param aDecoration which line will be painted
|
||||||
|
* i.e., NS_STYLE_TEXT_DECORATION_UNDERLINE or
|
||||||
|
* NS_STYLE_TEXT_DECORATION_OVERLINE or
|
||||||
|
* NS_STYLE_TEXT_DECORATION_LINE_THROUGH.
|
||||||
*/
|
*/
|
||||||
virtual void PaintTextDecorationLine(nsIRenderingContext& aRenderingContext,
|
virtual void PaintTextDecorationLine(nsIRenderingContext& aRenderingContext,
|
||||||
nsPoint aPt,
|
nsPoint aPt,
|
||||||
|
@ -177,8 +181,9 @@ protected:
|
||||||
nscolor aColor,
|
nscolor aColor,
|
||||||
nscoord aOffset,
|
nscoord aOffset,
|
||||||
nscoord aAscent,
|
nscoord aAscent,
|
||||||
nscoord aSize);
|
nscoord aSize,
|
||||||
|
const PRUint8 aDecoration);
|
||||||
|
|
||||||
friend class nsDisplayTextDecoration;
|
friend class nsDisplayTextDecoration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3691,7 +3691,7 @@ FillClippedRect(gfxContext* aCtx, nsPresContext* aPresContext,
|
||||||
{
|
{
|
||||||
gfxRect r = aRect.Intersect(aDirtyRect);
|
gfxRect r = aRect.Intersect(aDirtyRect);
|
||||||
// For now, we need to put this in pixel coordinates
|
// For now, we need to put this in pixel coordinates
|
||||||
float t2p = 1.0/aPresContext->AppUnitsPerDevPixel();
|
float t2p = 1.0f / aPresContext->AppUnitsPerDevPixel();
|
||||||
aCtx->NewPath();
|
aCtx->NewPath();
|
||||||
// pixel-snap
|
// pixel-snap
|
||||||
aCtx->Rectangle(gfxRect(r.X()*t2p, r.Y()*t2p, r.Width()*t2p, r.Height()*t2p), PR_TRUE);
|
aCtx->Rectangle(gfxRect(r.X()*t2p, r.Y()*t2p, r.Width()*t2p, r.Height()*t2p), PR_TRUE);
|
||||||
|
@ -3765,24 +3765,35 @@ nsTextFrame::PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gfxFont::Metrics fontMetrics = GetFontMetrics(aProvider.GetFontGroup());
|
gfxFont::Metrics fontMetrics = GetFontMetrics(aProvider.GetFontGroup());
|
||||||
gfxFloat pix2app = mTextRun->GetAppUnitsPerDevUnit();
|
gfxFloat a2p = 1.0 / aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
|
// XXX aFramePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||||
|
gfxPoint pt(aFramePt.x * a2p, aFramePt.y * a2p);
|
||||||
|
gfxSize size(GetRect().width * a2p, 0);
|
||||||
|
gfxFloat ascent = mAscent * a2p;
|
||||||
|
|
||||||
if (decorations & NS_FONT_DECORATION_OVERLINE) {
|
if (decorations & NS_FONT_DECORATION_OVERLINE) {
|
||||||
FillClippedRect(aCtx, aTextPaintStyle.PresContext(), overColor, aDirtyRect,
|
size.height = fontMetrics.underlineSize;
|
||||||
gfxRect(aFramePt.x, aFramePt.y,
|
nsCSSRendering::PaintDecorationLine(
|
||||||
GetRect().width, NS_round(fontMetrics.underlineSize)*pix2app));
|
aCtx, overColor, pt, size, ascent, ascent, size.height,
|
||||||
|
NS_STYLE_TEXT_DECORATION_OVERLINE, NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
mTextRun->IsRightToLeft());
|
||||||
}
|
}
|
||||||
if (decorations & NS_FONT_DECORATION_UNDERLINE) {
|
if (decorations & NS_FONT_DECORATION_UNDERLINE) {
|
||||||
FillClippedRect(aCtx, aTextPaintStyle.PresContext(), underColor, aDirtyRect,
|
size.height = fontMetrics.underlineSize;
|
||||||
gfxRect(aFramePt.x,
|
gfxFloat offset = fontMetrics.underlineOffset;
|
||||||
GetSnappedBaselineY(aCtx, aFramePt.y) - NS_round(fontMetrics.underlineOffset)*pix2app,
|
nsCSSRendering::PaintDecorationLine(
|
||||||
GetRect().width, NS_round(fontMetrics.underlineSize)*pix2app));
|
aCtx, underColor, pt, size, ascent, offset, size.height,
|
||||||
|
NS_STYLE_TEXT_DECORATION_UNDERLINE, NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
mTextRun->IsRightToLeft());
|
||||||
}
|
}
|
||||||
if (decorations & NS_FONT_DECORATION_LINE_THROUGH) {
|
if (decorations & NS_FONT_DECORATION_LINE_THROUGH) {
|
||||||
FillClippedRect(aCtx, aTextPaintStyle.PresContext(), strikeColor, aDirtyRect,
|
size.height = fontMetrics.strikeoutSize;
|
||||||
gfxRect(aFramePt.x,
|
gfxFloat offset = fontMetrics.strikeoutOffset;
|
||||||
GetSnappedBaselineY(aCtx, aFramePt.y) - NS_round(fontMetrics.strikeoutOffset)*pix2app,
|
nsCSSRendering::PaintDecorationLine(
|
||||||
GetRect().width, NS_round(fontMetrics.strikeoutSize)*pix2app));
|
aCtx, strikeColor, pt, size, ascent, offset, size.height,
|
||||||
|
NS_STYLE_TEXT_DECORATION_UNDERLINE, NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
mTextRun->IsRightToLeft());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3795,21 +3806,20 @@ static const SelectionType SelectionTypesWithDecorations =
|
||||||
nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
|
nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
|
||||||
|
|
||||||
static void DrawIMEUnderline(gfxContext* aContext, PRInt32 aIndex,
|
static void DrawIMEUnderline(gfxContext* aContext, PRInt32 aIndex,
|
||||||
nsTextPaintStyle& aTextPaintStyle, const gfxPoint& aBaselinePt, gfxFloat aWidth,
|
nsTextPaintStyle& aTextPaintStyle, const gfxPoint& aPt, gfxFloat aWidth,
|
||||||
const gfxRect& aDirtyRect, const gfxFont::Metrics& aFontMetrics)
|
gfxFloat aAscent, gfxFloat aSize, gfxFloat aOffset, PRBool aIsRTL)
|
||||||
{
|
{
|
||||||
float p2t = aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
|
||||||
nscolor color;
|
nscolor color;
|
||||||
float relativeSize;
|
float relativeSize;
|
||||||
if (!aTextPaintStyle.GetIMEUnderline(aIndex, &color, &relativeSize))
|
if (!aTextPaintStyle.GetIMEUnderline(aIndex, &color, &relativeSize))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gfxFloat y = aBaselinePt.y - aFontMetrics.underlineOffset*p2t;
|
gfxFloat actualSize = relativeSize * aSize;
|
||||||
gfxFloat size = aFontMetrics.underlineSize*p2t;
|
gfxFloat width = PR_MAX(0, aWidth - 2.0 * aSize);
|
||||||
FillClippedRect(aContext, aTextPaintStyle.PresContext(),
|
gfxPoint pt(aPt.x + 1.0, aPt.y);
|
||||||
color, aDirtyRect,
|
nsCSSRendering::PaintDecorationLine(
|
||||||
gfxRect(aBaselinePt.x + size, y,
|
aContext, color, pt, gfxSize(width, actualSize), aAscent, aOffset, aSize,
|
||||||
PR_MAX(0, aWidth - 2*size), relativeSize*size));
|
NS_STYLE_TEXT_DECORATION_UNDERLINE, NS_STYLE_BORDER_STYLE_SOLID, aIsRTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3817,40 +3827,41 @@ static void DrawIMEUnderline(gfxContext* aContext, PRInt32 aIndex,
|
||||||
* drawing text decoration for selections.
|
* drawing text decoration for selections.
|
||||||
*/
|
*/
|
||||||
static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
|
static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
|
||||||
nsTextPaintStyle& aTextPaintStyle, const gfxPoint& aBaselinePt, gfxFloat aWidth,
|
nsTextPaintStyle& aTextPaintStyle, const gfxPoint& aPt, gfxFloat aWidth,
|
||||||
const gfxRect& aDirtyRect, const gfxFont::Metrics& aFontMetrics)
|
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics, PRBool aIsRTL)
|
||||||
{
|
{
|
||||||
float p2t = aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
gfxSize size(aWidth, aFontMetrics.underlineSize);
|
||||||
float t2p = 1/p2t;
|
gfxFloat offset = aFontMetrics.underlineOffset;
|
||||||
|
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
case nsISelectionController::SELECTION_SPELLCHECK: {
|
case nsISelectionController::SELECTION_SPELLCHECK: {
|
||||||
gfxFloat y = aBaselinePt.y*t2p - aFontMetrics.underlineOffset;
|
nsCSSRendering::PaintDecorationLine(
|
||||||
aContext->SetDash(gfxContext::gfxLineDotted);
|
aContext, NS_RGB(255,0,0),
|
||||||
aContext->SetColor(gfxRGBA(1.0, 0.0, 0.0));
|
aPt, size, aAscent, aFontMetrics.underlineOffset, size.height,
|
||||||
aContext->SetLineWidth(1.0);
|
NS_STYLE_TEXT_DECORATION_UNDERLINE, NS_STYLE_BORDER_STYLE_DOTTED,
|
||||||
aContext->NewPath();
|
aIsRTL);
|
||||||
aContext->Line(gfxPoint(aBaselinePt.x*t2p, y),
|
|
||||||
gfxPoint((aBaselinePt.x + aWidth)*t2p, y));
|
|
||||||
aContext->Stroke();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsISelectionController::SELECTION_IME_RAWINPUT:
|
case nsISelectionController::SELECTION_IME_RAWINPUT:
|
||||||
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexRawInput, aTextPaintStyle,
|
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexRawInput,
|
||||||
aBaselinePt, aWidth, aDirtyRect, aFontMetrics);
|
aTextPaintStyle, aPt, aWidth, aAscent, size.height,
|
||||||
|
aFontMetrics.underlineOffset, aIsRTL);
|
||||||
break;
|
break;
|
||||||
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
||||||
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexSelRawText, aTextPaintStyle,
|
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexSelRawText,
|
||||||
aBaselinePt, aWidth, aDirtyRect, aFontMetrics);
|
aTextPaintStyle, aPt, aWidth, aAscent, size.height,
|
||||||
|
aFontMetrics.underlineOffset, aIsRTL);
|
||||||
break;
|
break;
|
||||||
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
||||||
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexConvText, aTextPaintStyle,
|
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexConvText,
|
||||||
aBaselinePt, aWidth, aDirtyRect, aFontMetrics);
|
aTextPaintStyle, aPt, aWidth, aAscent, size.height,
|
||||||
|
aFontMetrics.underlineOffset, aIsRTL);
|
||||||
break;
|
break;
|
||||||
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
|
||||||
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexSelConvText, aTextPaintStyle,
|
DrawIMEUnderline(aContext, nsTextPaintStyle::eIndexSelConvText,
|
||||||
aBaselinePt, aWidth, aDirtyRect, aFontMetrics);
|
aTextPaintStyle, aPt, aWidth, aAscent, size.height,
|
||||||
|
aFontMetrics.underlineOffset, aIsRTL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -4137,10 +4148,14 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
||||||
gfxFloat advance = hyphenWidth +
|
gfxFloat advance = hyphenWidth +
|
||||||
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
||||||
if (type == aSelectionType) {
|
if (type == aSelectionType) {
|
||||||
gfxFloat x = aTextBaselinePt.x + xOffset - (mTextRun->IsRightToLeft() ? advance : 0);
|
gfxFloat a2p = 1.0 / aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
||||||
|
// XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||||
|
gfxPoint pt((aTextBaselinePt.x + xOffset) * a2p,
|
||||||
|
(aTextBaselinePt.y - mAscent) * a2p);
|
||||||
|
gfxFloat width = PR_ABS(advance) * a2p;
|
||||||
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
|
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
|
||||||
gfxPoint(x, aTextBaselinePt.y), advance,
|
pt, width, mAscent * a2p, decorationMetrics,
|
||||||
aDirtyRect, decorationMetrics);
|
mTextRun->IsRightToLeft());
|
||||||
}
|
}
|
||||||
iterator.UpdateWithAdvance(advance);
|
iterator.UpdateWithAdvance(advance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ REQUIRES = xpcom \
|
||||||
dom \
|
dom \
|
||||||
content \
|
content \
|
||||||
gfx \
|
gfx \
|
||||||
|
thebes \
|
||||||
widget \
|
widget \
|
||||||
view \
|
view \
|
||||||
webshell \
|
webshell \
|
||||||
|
|
|
@ -51,6 +51,7 @@ REQUIRES = xpcom \
|
||||||
dom \
|
dom \
|
||||||
content \
|
content \
|
||||||
gfx \
|
gfx \
|
||||||
|
thebes \
|
||||||
widget \
|
widget \
|
||||||
locale \
|
locale \
|
||||||
view \
|
view \
|
||||||
|
|
|
@ -49,6 +49,7 @@ REQUIRES = xpcom \
|
||||||
string \
|
string \
|
||||||
content \
|
content \
|
||||||
gfx \
|
gfx \
|
||||||
|
thebes \
|
||||||
widget \
|
widget \
|
||||||
locale \
|
locale \
|
||||||
view \
|
view \
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
|
#include "nsCSSRendering.h"
|
||||||
|
|
||||||
#ifdef IBMBIDI
|
#ifdef IBMBIDI
|
||||||
#include "nsBidiUtils.h"
|
#include "nsBidiUtils.h"
|
||||||
|
@ -401,22 +402,48 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
||||||
presContext->DeviceContext()->GetMetricsFor(fontStyle->mFont,
|
presContext->DeviceContext()->GetMetricsFor(fontStyle->mFont,
|
||||||
*getter_AddRefs(fontMet));
|
*getter_AddRefs(fontMet));
|
||||||
fontMet->GetMaxAscent(baseline);
|
fontMet->GetMaxAscent(baseline);
|
||||||
|
PRBool isRTL = vis->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||||
|
|
||||||
|
nsRefPtr<gfxContext> ctx = (gfxContext*)
|
||||||
|
aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||||
|
gfxFloat a2p = 1.0 / presContext->AppUnitsPerDevPixel();
|
||||||
|
gfxPoint pt(textRect.x * a2p, textRect.y * a2p);
|
||||||
|
gfxFloat width = textRect.width * a2p;
|
||||||
|
gfxFloat baselinePixel = baseline * a2p;
|
||||||
if (decorations & (NS_FONT_DECORATION_OVERLINE | NS_FONT_DECORATION_UNDERLINE)) {
|
if (decorations & (NS_FONT_DECORATION_OVERLINE | NS_FONT_DECORATION_UNDERLINE)) {
|
||||||
fontMet->GetUnderline(offset, size);
|
fontMet->GetUnderline(offset, size);
|
||||||
|
gfxFloat offsetPixel = offset * a2p;
|
||||||
|
gfxFloat sizePixel = size * a2p;
|
||||||
if (decorations & NS_FONT_DECORATION_OVERLINE) {
|
if (decorations & NS_FONT_DECORATION_OVERLINE) {
|
||||||
aRenderingContext.SetColor(overColor);
|
nsCSSRendering::PaintDecorationLine(ctx, overColor,
|
||||||
aRenderingContext.FillRect(textRect.x, textRect.y, textRect.width, size);
|
pt, gfxSize(width, sizePixel),
|
||||||
|
baselinePixel, baselinePixel,
|
||||||
|
sizePixel,
|
||||||
|
NS_STYLE_TEXT_DECORATION_OVERLINE,
|
||||||
|
NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
isRTL);
|
||||||
}
|
}
|
||||||
if (decorations & NS_FONT_DECORATION_UNDERLINE) {
|
if (decorations & NS_FONT_DECORATION_UNDERLINE) {
|
||||||
aRenderingContext.SetColor(underColor);
|
nsCSSRendering::PaintDecorationLine(ctx, underColor,
|
||||||
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size);
|
pt, gfxSize(width, sizePixel),
|
||||||
|
baselinePixel, offsetPixel,
|
||||||
|
sizePixel,
|
||||||
|
NS_STYLE_TEXT_DECORATION_UNDERLINE,
|
||||||
|
NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
isRTL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (decorations & NS_FONT_DECORATION_LINE_THROUGH) {
|
if (decorations & NS_FONT_DECORATION_LINE_THROUGH) {
|
||||||
fontMet->GetStrikeout(offset, size);
|
fontMet->GetStrikeout(offset, size);
|
||||||
aRenderingContext.SetColor(strikeColor);
|
gfxFloat offsetPixel = offset * a2p;
|
||||||
aRenderingContext.FillRect(textRect.x, textRect.y + baseline - offset, textRect.width, size);
|
gfxFloat sizePixel = size * a2p;
|
||||||
|
nsCSSRendering::PaintDecorationLine(ctx, underColor,
|
||||||
|
pt, gfxSize(width, sizePixel),
|
||||||
|
baselinePixel, offsetPixel,
|
||||||
|
sizePixel,
|
||||||
|
NS_STYLE_TEXT_DECORATION_LINE_THROUGH,
|
||||||
|
NS_STYLE_BORDER_STYLE_SOLID,
|
||||||
|
isRTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
aRenderingContext.SetFont(fontStyle->mFont, nsnull);
|
aRenderingContext.SetFont(fontStyle->mFont, nsnull);
|
||||||
|
|
|
@ -51,6 +51,7 @@ REQUIRES = xpcom \
|
||||||
content \
|
content \
|
||||||
xul \
|
xul \
|
||||||
gfx \
|
gfx \
|
||||||
|
thebes \
|
||||||
widget \
|
widget \
|
||||||
locale \
|
locale \
|
||||||
view \
|
view \
|
||||||
|
|
Загрузка…
Ссылка в новой задаче