mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
bug 721750 - support text-shadow property on ::-moz-selection. r=dbaron
This commit is contained in:
parent
882831b9b9
commit
22fe279335
@ -116,6 +116,7 @@ public:
|
||||
#define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
|
||||
#define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
|
||||
#define NS_AUTHOR_SPECIFIED_PADDING (1 << 2)
|
||||
#define NS_AUTHOR_SPECIFIED_TEXT_SHADOW (1 << 3)
|
||||
|
||||
class nsRootPresContext;
|
||||
|
||||
|
@ -304,6 +304,10 @@ public:
|
||||
float* aRelativeSize,
|
||||
PRUint8* aStyle);
|
||||
|
||||
// if this returns false, no text-shadow was specified for the selection
|
||||
// and the *aShadow parameter was not modified.
|
||||
bool GetSelectionShadow(nsCSSShadowArray** aShadow);
|
||||
|
||||
nsPresContext* PresContext() const { return mPresContext; }
|
||||
|
||||
enum {
|
||||
@ -337,13 +341,15 @@ protected:
|
||||
nsTextFrame* mFrame;
|
||||
nsPresContext* mPresContext;
|
||||
bool mInitCommonColors;
|
||||
bool mInitSelectionColors;
|
||||
bool mInitSelectionColorsAndShadow;
|
||||
|
||||
// Selection data
|
||||
|
||||
PRInt16 mSelectionStatus; // see nsIDocument.h SetDisplaySelection()
|
||||
nscolor mSelectionTextColor;
|
||||
nscolor mSelectionBGColor;
|
||||
nsRefPtr<nsCSSShadowArray> mSelectionShadow;
|
||||
bool mHasSelectionShadow;
|
||||
|
||||
// Common data
|
||||
|
||||
@ -365,7 +371,7 @@ protected:
|
||||
|
||||
// Color initializations
|
||||
void InitCommonColors();
|
||||
bool InitSelectionColors();
|
||||
bool InitSelectionColorsAndShadow();
|
||||
|
||||
nsSelectionStyle* GetSelectionStyle(PRInt32 aIndex);
|
||||
void InitSelectionStyle(PRInt32 aIndex);
|
||||
@ -3390,7 +3396,8 @@ nsTextPaintStyle::nsTextPaintStyle(nsTextFrame* aFrame)
|
||||
: mFrame(aFrame),
|
||||
mPresContext(aFrame->PresContext()),
|
||||
mInitCommonColors(false),
|
||||
mInitSelectionColors(false)
|
||||
mInitSelectionColorsAndShadow(false),
|
||||
mHasSelectionShadow(false)
|
||||
{
|
||||
for (PRUint32 i = 0; i < ArrayLength(mSelectionStyle); i++)
|
||||
mSelectionStyle[i].mInit = false;
|
||||
@ -3434,7 +3441,7 @@ nsTextPaintStyle::GetSelectionColors(nscolor* aForeColor,
|
||||
NS_ASSERTION(aForeColor, "aForeColor is null");
|
||||
NS_ASSERTION(aBackColor, "aBackColor is null");
|
||||
|
||||
if (!InitSelectionColors())
|
||||
if (!InitSelectionColorsAndShadow())
|
||||
return false;
|
||||
|
||||
*aForeColor = mSelectionTextColor;
|
||||
@ -3566,9 +3573,9 @@ FindElementAncestorForMozSelection(nsIContent* aContent)
|
||||
}
|
||||
|
||||
bool
|
||||
nsTextPaintStyle::InitSelectionColors()
|
||||
nsTextPaintStyle::InitSelectionColorsAndShadow()
|
||||
{
|
||||
if (mInitSelectionColors)
|
||||
if (mInitSelectionColorsAndShadow)
|
||||
return true;
|
||||
|
||||
PRInt16 selectionFlags;
|
||||
@ -3581,7 +3588,7 @@ nsTextPaintStyle::InitSelectionColors()
|
||||
return false;
|
||||
}
|
||||
|
||||
mInitSelectionColors = true;
|
||||
mInitSelectionColorsAndShadow = true;
|
||||
|
||||
nsIFrame* nonGeneratedAncestor = nsLayoutUtils::GetNonGeneratedAncestor(mFrame);
|
||||
Element* selectionElement =
|
||||
@ -3599,6 +3606,13 @@ nsTextPaintStyle::InitSelectionColors()
|
||||
mSelectionBGColor =
|
||||
sc->GetVisitedDependentColor(eCSSProperty_background_color);
|
||||
mSelectionTextColor = sc->GetVisitedDependentColor(eCSSProperty_color);
|
||||
mHasSelectionShadow =
|
||||
nsRuleNode::HasAuthorSpecifiedRules(sc,
|
||||
NS_AUTHOR_SPECIFIED_TEXT_SHADOW,
|
||||
true);
|
||||
if (mHasSelectionShadow) {
|
||||
mSelectionShadow = sc->GetStyleText()->mTextShadow;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -3759,6 +3773,21 @@ nsTextPaintStyle::GetSelectionUnderline(nsPresContext* aPresContext,
|
||||
size > 0.0f;
|
||||
}
|
||||
|
||||
bool
|
||||
nsTextPaintStyle::GetSelectionShadow(nsCSSShadowArray** aShadow)
|
||||
{
|
||||
if (!InitSelectionColorsAndShadow()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mHasSelectionShadow) {
|
||||
*aShadow = mSelectionShadow;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline nscolor Get40PercentColor(nscolor aForeColor, nscolor aBackColor)
|
||||
{
|
||||
nscolor foreColor = NS_RGBA(NS_GET_R(aForeColor),
|
||||
@ -4934,6 +4963,24 @@ static bool GetSelectionTextColors(SelectionType aType,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets *aShadow to the appropriate shadow, if any, for the given
|
||||
* type of selection. Returns true if *aShadow was set.
|
||||
* If text-shadow was not specified, *aShadow is left untouched
|
||||
* (NOT reset to null), and the function returns false.
|
||||
*/
|
||||
static bool GetSelectionTextShadow(SelectionType aType,
|
||||
nsTextPaintStyle& aTextPaintStyle,
|
||||
nsCSSShadowArray** aShadow)
|
||||
{
|
||||
switch (aType) {
|
||||
case nsISelectionController::SELECTION_NORMAL:
|
||||
return aTextPaintStyle.GetSelectionShadow(aShadow);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class lets us iterate over chunks of text in a uniform selection state,
|
||||
* observing cluster boundaries, in content order, maintaining the current
|
||||
@ -5217,8 +5264,13 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
||||
&foreground, &background);
|
||||
gfxPoint textBaselinePt(aFramePt.x + xOffset, aTextBaselinePt.y);
|
||||
|
||||
// Determine what shadow, if any, to draw - either from textStyle
|
||||
// or from the ::-moz-selection pseudo-class if specified there
|
||||
nsCSSShadowArray *shadow = textStyle->mTextShadow;
|
||||
GetSelectionTextShadow(type, aTextPaintStyle, &shadow);
|
||||
|
||||
// Draw shadows, if any
|
||||
if (textStyle->mTextShadow) {
|
||||
if (shadow) {
|
||||
gfxTextRun::Metrics shadowMetrics =
|
||||
mTextRun->MeasureText(offset, length, gfxFont::LOOSE_INK_EXTENTS,
|
||||
nullptr, &aProvider);
|
||||
@ -5226,9 +5278,9 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
||||
AddHyphenToMetrics(this, mTextRun, &shadowMetrics,
|
||||
gfxFont::LOOSE_INK_EXTENTS, aCtx);
|
||||
}
|
||||
for (PRUint32 i = textStyle->mTextShadow->Length(); i > 0; --i) {
|
||||
for (PRUint32 i = shadow->Length(); i > 0; --i) {
|
||||
PaintOneShadow(offset, length,
|
||||
textStyle->mTextShadow->ShadowAt(i - 1), &aProvider,
|
||||
shadow->ShadowAt(i - 1), &aProvider,
|
||||
dirtyRect, aFramePt, textBaselinePt, aCtx,
|
||||
foreground, aClipEdges,
|
||||
xOffset - (mTextRun->IsRightToLeft() ?
|
||||
|
@ -7671,8 +7671,12 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_PADDING)
|
||||
inheritBits |= NS_STYLE_INHERIT_BIT(Padding);
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_TEXT_SHADOW)
|
||||
inheritBits |= NS_STYLE_INHERIT_BIT(Text);
|
||||
|
||||
// properties in the SIDS, whether or not we care about them
|
||||
size_t nprops = 0, backgroundOffset, borderOffset, paddingOffset;
|
||||
size_t nprops = 0,
|
||||
backgroundOffset, borderOffset, paddingOffset, textShadowOffset;
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND) {
|
||||
backgroundOffset = nprops;
|
||||
@ -7689,6 +7693,11 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
nprops += nsCSSProps::PropertyCountInStruct(eStyleStruct_Padding);
|
||||
}
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_TEXT_SHADOW) {
|
||||
textShadowOffset = nprops;
|
||||
nprops += nsCSSProps::PropertyCountInStruct(eStyleStruct_Text);
|
||||
}
|
||||
|
||||
void* dataStorage = alloca(nprops * sizeof(nsCSSValue));
|
||||
AutoCSSValueArray dataArray(dataStorage, nprops);
|
||||
|
||||
@ -7708,6 +7717,10 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
ruleData.mValueOffsets[eStyleStruct_Padding] = paddingOffset;
|
||||
}
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_TEXT_SHADOW) {
|
||||
ruleData.mValueOffsets[eStyleStruct_Text] = textShadowOffset;
|
||||
}
|
||||
|
||||
static const nsCSSProperty backgroundValues[] = {
|
||||
eCSSProperty_background_color,
|
||||
eCSSProperty_background_image,
|
||||
@ -7747,16 +7760,22 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
eCSSProperty_padding_end_value,
|
||||
};
|
||||
|
||||
static const nsCSSProperty textShadowValues[] = {
|
||||
eCSSProperty_text_shadow
|
||||
};
|
||||
|
||||
// Number of properties we care about
|
||||
size_t nValues = 0;
|
||||
|
||||
nsCSSValue* values[NS_ARRAY_LENGTH(backgroundValues) +
|
||||
NS_ARRAY_LENGTH(borderValues) +
|
||||
NS_ARRAY_LENGTH(paddingValues)];
|
||||
NS_ARRAY_LENGTH(paddingValues) +
|
||||
NS_ARRAY_LENGTH(textShadowValues)];
|
||||
|
||||
nsCSSProperty properties[NS_ARRAY_LENGTH(backgroundValues) +
|
||||
NS_ARRAY_LENGTH(borderValues) +
|
||||
NS_ARRAY_LENGTH(paddingValues)];
|
||||
NS_ARRAY_LENGTH(paddingValues) +
|
||||
NS_ARRAY_LENGTH(textShadowValues)];
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND) {
|
||||
for (PRUint32 i = 0, i_end = ArrayLength(backgroundValues);
|
||||
@ -7782,6 +7801,14 @@ nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_TEXT_SHADOW) {
|
||||
for (PRUint32 i = 0, i_end = ArrayLength(textShadowValues);
|
||||
i < i_end; ++i) {
|
||||
properties[nValues] = textShadowValues[i];
|
||||
values[nValues++] = ruleData.ValueFor(textShadowValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nsStyleContext* styleContext = aStyleContext;
|
||||
|
||||
// We need to be careful not to count styles covered up by user-important or
|
||||
|
Loading…
x
Reference in New Issue
Block a user