From b89baff607307d102a69cec0ed8b12c1cc33156b Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 8 Aug 2012 21:37:11 +1000 Subject: [PATCH] Bug 655877 - Part 19: Add function to convert text decorations to a path. r=roc --- layout/base/nsCSSRendering.cpp | 47 ++++++++++++++++++++++++++++++++++ layout/base/nsCSSRendering.h | 20 +++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 1a5890461085..5738811517c1 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -3554,6 +3554,53 @@ nsCSSRendering::PaintDecorationLine(nsIFrame* aFrame, } } +void +nsCSSRendering::DecorationLineToPath(nsIFrame* aFrame, + gfxContext* aGfxContext, + const gfxRect& aDirtyRect, + const nscolor aColor, + const gfxPoint& aPt, + const gfxFloat aXInFrame, + const gfxSize& aLineSize, + const gfxFloat aAscent, + const gfxFloat aOffset, + const PRUint8 aDecoration, + const PRUint8 aStyle, + const gfxFloat aDescentLimit) +{ + NS_ASSERTION(aStyle != NS_STYLE_TEXT_DECORATION_STYLE_NONE, "aStyle is none"); + + aGfxContext->NewPath(); + + gfxRect rect = + GetTextDecorationRectInternal(aPt, aLineSize, aAscent, aOffset, + aDecoration, aStyle, aDescentLimit); + if (rect.IsEmpty() || !rect.Intersects(aDirtyRect)) { + return; + } + + if (aDecoration != NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE && + aDecoration != NS_STYLE_TEXT_DECORATION_LINE_OVERLINE && + aDecoration != NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH) { + NS_ERROR("Invalid decoration value!"); + return; + } + + if (aStyle != NS_STYLE_TEXT_DECORATION_STYLE_SOLID) { + // For the moment, we support only solid text decorations. + return; + } + + gfxFloat lineHeight = NS_MAX(NS_round(aLineSize.height), 1.0); + + // The y position should be set to the middle of the line. + rect.y += lineHeight / 2; + + aGfxContext->Rectangle + (gfxRect(gfxPoint(rect.TopLeft() - gfxPoint(0.0, lineHeight / 2)), + gfxSize(rect.Width(), lineHeight))); +} + nsRect nsCSSRendering::GetTextDecorationRect(nsPresContext* aPresContext, const gfxSize& aLineSize, diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index 9fe38fd03177..8366e9f163f4 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -434,6 +434,26 @@ struct nsCSSRendering { const PRUint8 aStyle, const gfxFloat aDescentLimit = -1.0); + /** + * Adds a path corresponding to the outline of the decoration line to + * the specified context. Arguments have the same meaning as for + * PaintDecorationLine. Currently this only works for solid + * decorations; for other decoration styles, an empty path is added + * to the context. + */ + static void DecorationLineToPath(nsIFrame* aFrame, + gfxContext* aGfxContext, + const gfxRect& aDirtyRect, + const nscolor aColor, + const gfxPoint& aPt, + const gfxFloat aXInFrame, + const gfxSize& aLineSize, + const gfxFloat aAscent, + const gfxFloat aOffset, + const PRUint8 aDecoration, + const PRUint8 aStyle, + const gfxFloat aDescentLimit = -1.0); + /** * Function for getting the decoration line rect for the text. * NOTE: aLineSize, aAscent and aOffset are non-rounded device pixels,