diff --git a/mozilla/layout/base/nsCSSColorUtils.cpp b/mozilla/layout/base/nsCSSColorUtils.cpp index 8d210bcfead..cf31ebe05cc 100644 --- a/mozilla/layout/base/nsCSSColorUtils.cpp +++ b/mozilla/layout/base/nsCSSColorUtils.cpp @@ -41,9 +41,9 @@ // Weird color computing code stolen from winfe which was stolen // from the xfe which was written originally by Eric Bina. So there. -#define RED_LUMINOSITY 30 -#define GREEN_LUMINOSITY 59 -#define BLUE_LUMINOSITY 11 +#define RED_LUMINOSITY 299 +#define GREEN_LUMINOSITY 587 +#define BLUE_LUMINOSITY 114 #define INTENSITY_FACTOR 25 #define LIGHT_FACTOR 0 #define LUMINOSITY_FACTOR 75 @@ -179,15 +179,19 @@ int NS_GetBrightness(PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue) PRUint8 intensity = (aRed + aGreen + aBlue) / 3; - PRUint8 luminosity = - ((RED_LUMINOSITY * aRed) / 100) + - ((GREEN_LUMINOSITY * aGreen) / 100) + - ((BLUE_LUMINOSITY * aBlue) / 100); + PRUint8 luminosity = NS_GetLuminosity(NS_RGB(aRed, aGreen, aBlue)) / 1000; return ((intensity * INTENSITY_FACTOR) + (luminosity * LUMINOSITY_FACTOR)) / 100; } +PRUint32 NS_GetLuminosity(nscolor aColor) +{ + return (NS_GET_R(aColor) * RED_LUMINOSITY + + NS_GET_G(aColor) * GREEN_LUMINOSITY + + NS_GET_B(aColor) * BLUE_LUMINOSITY); +} + // Function to convert RGB color space into the HSV colorspace // Hue is the primary color defined from 0 to 359 degrees // Saturation is defined from 0 to 255. The higher the number.. the deeper the color diff --git a/mozilla/layout/base/nsCSSColorUtils.h b/mozilla/layout/base/nsCSSColorUtils.h index ba749b420d5..644b2e0aaa1 100644 --- a/mozilla/layout/base/nsCSSColorUtils.h +++ b/mozilla/layout/base/nsCSSColorUtils.h @@ -41,6 +41,13 @@ #include "nsColor.h" +// "Sufficient contrast" is determined by +// "Techniques For Accessibility Evalution And Repair Tools". +// See http://www.w3.org/TR/AERT#color-contrast +#define NS_SUFFICIENT_LUMINOSITY_DIFFERENCE 125000 +#define NS_LUMINOSITY_DIFFERENCE(a, b) \ + PR_ABS(NS_GetLuminosity(a) - NS_GetLuminosity(b)) + // Weird color computing code stolen from winfe which was stolen // from the xfe which was written originally by Eric Bina. So there. // To determin colors based on the background brightness @@ -48,12 +55,16 @@ void NS_Get3DColors(nscolor aResult[2], nscolor aBackgroundColor); // To determine colors based on the background brightness and border color void NS_GetSpecial3DColors(nscolor aResult[2], - nscolor aBackgroundColor, - nscolor aBorderColor); + nscolor aBackgroundColor, + nscolor aBorderColor); // Determins brightness for a specific color int NS_GetBrightness(PRUint8 aRed, PRUint8 aGreen, PRUint8 aBlue); +// Get Luminosity of a specific color. That is same as Y of YIQ color space. +// The range of return value is 0 to 255000. +PRUint32 NS_GetLuminosity(nscolor aColor); + // function to convert from RGB color space to HSV color space void NS_RGB2HSV(nscolor aColor,PRUint16 &aHue,PRUint16 &aSat,PRUint16 &aValue); // function to convert from HSV color space to RGB color space diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 3f6168acd8d..52b526273f2 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -28,6 +28,7 @@ * Roland Mainz * Daniel Glazman * Neil Deakin + * Masayuki Nakano * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -71,6 +72,7 @@ #include "nsILineBreaker.h" #include "nsIWordBreaker.h" #include "nsCompatibility.h" +#include "nsCSSColorUtils.h" #include "nsITextContent.h" #include "nsTextFragment.h" @@ -963,9 +965,22 @@ public: char * CurrentTextCStrPtr(); PRUint32 CurrentLength(); nsTextFrame::TextPaintStyle & CurrentStyle(); - nscolor CurrentForeGroundColor(); - PRBool CurrentBackGroundColor(nscolor &aColor, PRBool *aIsTransparent); PRBool IsBeforeOrAfter(); + + /** + * Get foreground color, background color, whether the background is transparent, + * and whether the current range is the normal selection. + * + * @param aForeColor [out] returns the foreground color of the current range. + * @param aBackColor [out] returns the background color of the current range. + * Note that this value is undefined if aBackIsTransparent + * is true or if @return is false. + * @param aBackIsTransparent [out] returns whether the background is transparent. + * If true, the background is transparent. + * Otherwise, it isn't so. + * @return whether the current range is a normal selection. + */ + PRBool GetSelectionColors(nscolor *aForeColor, nscolor *aBackColor, PRBool *aBackIsTransparent); private: union { PRUnichar *mUniStr; @@ -1202,54 +1217,69 @@ DrawSelectionIterator::CurrentStyle() return mOldStyle; } -nscolor -DrawSelectionIterator::CurrentForeGroundColor() -{ - nscolor foreColor; - PRBool colorSet = PR_FALSE; - - if (!mTypes) - { - if (mCurrentIdx == (PRUint32)mDetails->mStart) - { - foreColor = mOldStyle.mSelectionTextColor; - colorSet = PR_TRUE; - } - } - else if (mTypes[mCurrentIdx] & nsISelectionController::SELECTION_NORMAL)//Find color based on mTypes[mCurrentIdx]; - { - foreColor = mOldStyle.mSelectionTextColor; - colorSet = PR_TRUE; - } - - if (colorSet && (foreColor != NS_DONT_CHANGE_COLOR)) { - if (mSelectionPseudoStyle) - return mSelectionPseudoFGcolor; - else - return foreColor; - } - return mOldStyle.mColor->mColor; -} - PRBool -DrawSelectionIterator::CurrentBackGroundColor(nscolor &aColor, PRBool *aIsTransparent) -{ - //Find color based on mTypes[mCurrentIdx]; - *aIsTransparent = PR_FALSE; - if (mTypes? (mTypes[mCurrentIdx] & nsISelectionController::SELECTION_NORMAL): (mCurrentIdx == (PRUint32)mDetails->mStart)) { - aColor = mOldStyle.mSelectionBGColor; - if (mSelectionPseudoStyle) { - aColor = mSelectionPseudoBGcolor; - *aIsTransparent = mSelectionPseudoBGIsTransparent; - } - if (mSelectionStatus==nsISelectionController::SELECTION_ATTENTION) - aColor = mAttentionColor; - else if (mSelectionStatus != nsISelectionController::SELECTION_ON) - aColor = mDisabledColor; +DrawSelectionIterator::GetSelectionColors(nscolor *aForeColor, + nscolor *aBackColor, + PRBool *aBackIsTransparent) +{ + *aBackIsTransparent = PR_FALSE; + PRBool isSelection = + (mTypes && (mTypes[mCurrentIdx] & nsISelectionController::SELECTION_NORMAL)) || + (!mTypes && mCurrentIdx == (PRUint32)mDetails->mStart); + if (!isSelection) { + *aForeColor = mOldStyle.mColor->mColor; + return PR_FALSE; + } + + PRBool dontChangeTextColor = mOldStyle.mSelectionTextColor == NS_DONT_CHANGE_COLOR; + + // If the selection text color is NS_DONT_CHANGE_COLOR, + // we don't accept the ::selection pseudo element. + if (!dontChangeTextColor && + mSelectionPseudoStyle && + mSelectionStatus == nsISelectionController::SELECTION_ON) { + *aForeColor = mSelectionPseudoFGcolor; + *aBackColor = mSelectionPseudoBGcolor; + *aBackIsTransparent = mSelectionPseudoBGIsTransparent; return PR_TRUE; } - return PR_FALSE; + if (dontChangeTextColor) + *aForeColor = mOldStyle.mColor->mColor; + else + *aForeColor = mOldStyle.mSelectionTextColor; + + if (mSelectionStatus == nsISelectionController::SELECTION_ATTENTION) + *aBackColor = mAttentionColor; + else if (mSelectionStatus != nsISelectionController::SELECTION_ON) + *aBackColor = mDisabledColor; + else + *aBackColor = mOldStyle.mSelectionBGColor; + + // We don't support selection color exchanging when selection text color is + // NS_DONT_CHANGE_COLOR. Because the text color should not be background color. + if (dontChangeTextColor) { + *aForeColor = EnsureDifferentColors(*aForeColor, *aBackColor); + return PR_TRUE; + } + + // Note: We assume that the combination of the background color and text color + // of selection is sufficient contrast. Because if it isn't, user cannot read + // the selection text. + + // If the combination of the selection text color and the original text color + // are sufficient contrast, probably these background colors are not alike. + // Therefore, we should not exchange selection colors. + if (NS_LUMINOSITY_DIFFERENCE(*aForeColor, mOldStyle.mColor->mColor) >= + NS_SUFFICIENT_LUMINOSITY_DIFFERENCE) + return PR_TRUE; + + // Otherwise, if those colors are similar, those background colors may be similar. + // Therefore, we should exchange the colors. + nscolor tmpColor = *aForeColor; + *aForeColor = *aBackColor; + *aBackColor = tmpColor; + return PR_TRUE; } PRBool @@ -2499,10 +2529,11 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, PRUnichar *currenttext = iter.CurrentTextUnicharPtr(); PRUint32 currentlength= iter.CurrentLength(); //TextStyle ¤tStyle = iter.CurrentStyle(); - nscolor currentFGColor = iter.CurrentForeGroundColor(); - nscolor currentBKColor; + nscolor currentFGColor, currentBKColor; PRBool isCurrentBKColorTransparent; - + PRBool isSelection = iter.GetSelectionColors(¤tFGColor, + ¤tBKColor, + &isCurrentBKColorTransparent); #ifdef IBMBIDI if (currentlength > 0 && NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING @@ -2514,13 +2545,12 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { #endif - if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated) + if (isSelection && !isPaginated) {//DRAW RECT HERE!!! if (!isCurrentBKColorTransparent) { aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); } - currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor); } } else @@ -3168,21 +3198,22 @@ nsTextFrame::PaintTextSlowly(nsPresContext* aPresContext, PRUnichar *currenttext = iter.CurrentTextUnicharPtr(); PRUint32 currentlength= iter.CurrentLength(); //TextStyle ¤tStyle = iter.CurrentStyle(); - nscolor currentFGColor = iter.CurrentForeGroundColor(); - nscolor currentBKColor; + nscolor currentFGColor, currentBKColor; PRBool isCurrentBKColorTransparent; + PRBool isSelection = iter.GetSelectionColors(¤tFGColor, + ¤tBKColor, + &isCurrentBKColorTransparent); PRBool isEndOfFrame = iter.IsLast(); GetTextDimensions(aRenderingContext, aTextStyle, currenttext, (PRInt32)currentlength, isEndOfFrame, &newDimensions); if (newDimensions.width) { - if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent)) + if (isSelection) {//DRAW RECT HERE!!! if (!isCurrentBKColorTransparent) { aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newDimensions.width, mRect.height); } - currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor); } } @@ -3397,19 +3428,19 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, char *currenttext = iter.CurrentTextCStrPtr(); PRUint32 currentlength= iter.CurrentLength(); //TextStyle ¤tStyle = iter.CurrentStyle(); - nscolor currentFGColor = iter.CurrentForeGroundColor(); - nscolor currentBKColor; + nscolor currentFGColor, currentBKColor; PRBool isCurrentBKColorTransparent; - + PRBool isSelection = iter.GetSelectionColors(¤tFGColor, + ¤tBKColor, + &isCurrentBKColorTransparent); if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { - if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated) + if (isSelection && !isPaginated) {//DRAW RECT HERE!!! if (!isCurrentBKColorTransparent) { aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); } - currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor); } } else