Bug 1117210 - Snap text baselines to device pixels in vertical writing modes. r=smontagu

This commit is contained in:
Jonathan Kew 2015-02-11 08:44:34 +00:00
parent cfddf46217
commit 1e4c538120
4 changed files with 36 additions and 7 deletions

View File

@ -5099,6 +5099,19 @@ nsLayoutUtils::GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
return aContext->DeviceToUser(putativeRect.TopLeft()).y * appUnitsPerDevUnit;
}
gfxFloat
nsLayoutUtils::GetSnappedBaselineX(nsIFrame* aFrame, gfxContext* aContext,
nscoord aX, nscoord aAscent)
{
gfxFloat appUnitsPerDevUnit = aFrame->PresContext()->AppUnitsPerDevPixel();
gfxFloat baseline = gfxFloat(aX) + aAscent;
gfxRect putativeRect(baseline / appUnitsPerDevUnit, 0, 1, 1);
if (!aContext->UserToDevicePixelSnapped(putativeRect, true)) {
return baseline;
}
return aContext->DeviceToUser(putativeRect.TopLeft()).x * appUnitsPerDevUnit;
}
// Hard limit substring lengths to 8000 characters ... this lets us statically
// size the cluster buffer array in FindSafeLength
#define MAX_GFX_TEXT_BUF_SIZE 8000

View File

@ -1476,6 +1476,10 @@ public:
// Get a baseline y position in app units that is snapped to device pixels.
static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
nscoord aY, nscoord aAscent);
// Ditto for an x position (for vertical text). Note that for vertical-rl
// writing mode, the ascent value should be negated by the caller.
static gfxFloat GetSnappedBaselineX(nsIFrame* aFrame, gfxContext* aContext,
nscoord aX, nscoord aAscent);
static nscoord AppUnitWidthOfString(char16_t aC,
nsFontMetrics& aFontMetrics,

View File

@ -420,13 +420,19 @@ nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt,
nscoord ascent = wm.IsLineInverted()
? fm->MaxDescent() : fm->MaxAscent();
aPt.MoveBy(padding.left, padding.top);
gfxContext *ctx = aRenderingContext.ThebesContext();
if (wm.IsVertical()) {
// XXX what about baseline snapping?
aPt.x += (wm.IsVerticalLR() ? ascent
: mRect.width - ascent);
if (wm.IsVerticalLR()) {
aPt.x = NSToCoordRound(nsLayoutUtils::GetSnappedBaselineX(
this, ctx, aPt.x, ascent));
} else {
aPt.x = NSToCoordRound(nsLayoutUtils::GetSnappedBaselineX(
this, ctx, aPt.x + mRect.width,
-ascent));
}
} else {
aPt.y = NSToCoordRound(nsLayoutUtils::GetSnappedBaselineY(
this, aRenderingContext.ThebesContext(), aPt.y, ascent));
this, ctx, aPt.y, ascent));
}
nsPresContext* presContext = PresContext();
if (!presContext->BidiEnabled() && HasRTLChars(text)) {

View File

@ -6128,9 +6128,15 @@ nsTextFrame::PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt,
gfxPoint framePt(aPt.x, aPt.y);
gfxPoint textBaselinePt;
if (verticalRun) {
textBaselinePt = // XXX sideways-left will need different handling here
gfxPoint(aPt.x + (wm.IsVerticalLR() ? mAscent : frameWidth - mAscent),
rtl ? aPt.y + GetSize().height : aPt.y);
if (wm.IsVerticalLR()) {
textBaselinePt.x =
nsLayoutUtils::GetSnappedBaselineX(this, ctx, aPt.x, mAscent);
} else {
textBaselinePt.x =
nsLayoutUtils::GetSnappedBaselineX(this, ctx, aPt.x + frameWidth,
-mAscent);
}
textBaselinePt.y = rtl ? aPt.y + GetSize().height : aPt.y;
} else {
textBaselinePt = gfxPoint(rtl ? gfxFloat(aPt.x + frameWidth) : framePt.x,
nsLayoutUtils::GetSnappedBaselineY(this, ctx, aPt.y, mAscent));