mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 482138 [TSF] nsTextFrame has to draw composition string by TIP specified style r+sr=roc
This commit is contained in:
parent
257a5fc973
commit
cfff67f8c9
@ -47,15 +47,17 @@ interface nsIContent;
|
|||||||
class nsFrameSelection;
|
class nsFrameSelection;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsIPresShell;
|
class nsIPresShell;
|
||||||
|
struct nsTextRangeStyle;
|
||||||
struct nsPoint;
|
struct nsPoint;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
[ptr] native nsFrameSelection(nsFrameSelection);
|
[ptr] native nsFrameSelection(nsFrameSelection);
|
||||||
[ptr] native nsIFrame(nsIFrame);
|
[ptr] native nsIFrame(nsIFrame);
|
||||||
[ptr] native nsIPresShell(nsIPresShell);
|
[ptr] native nsIPresShell(nsIPresShell);
|
||||||
|
[ref] native constTextRangeStyleRef(const nsTextRangeStyle);
|
||||||
[ref] native nsPointRef(nsPoint);
|
[ref] native nsPointRef(nsPoint);
|
||||||
|
|
||||||
[scriptable, uuid(b416c692-eeb8-4186-addd-c444e81b68e5)]
|
[scriptable, uuid(98552206-ad7a-4d2d-8ce3-b6fa2389298b)]
|
||||||
interface nsISelectionPrivate : nsISupports
|
interface nsISelectionPrivate : nsISupports
|
||||||
{
|
{
|
||||||
const short ENDOFPRECEDINGLINE=0;
|
const short ENDOFPRECEDINGLINE=0;
|
||||||
@ -118,5 +120,13 @@ interface nsISelectionPrivate : nsISupports
|
|||||||
[noscript] nsFrameSelection getFrameSelection();
|
[noscript] nsFrameSelection getFrameSelection();
|
||||||
|
|
||||||
[noscript] void setAncestorLimiter(in nsIContent aContent);
|
[noscript] void setAncestorLimiter(in nsIContent aContent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the painting style for the range. The range must be a range in
|
||||||
|
* the selection. The textRangeStyle will be used by text frame
|
||||||
|
* when it is painting the selection.
|
||||||
|
*/
|
||||||
|
[noscript] void setTextRangeStyle(in nsIDOMRange range,
|
||||||
|
in constTextRangeStyleRef textRangeStyle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,10 +41,12 @@
|
|||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsGUIEvent.h"
|
||||||
|
|
||||||
|
// {B13C4BD8-CB9F-4763-A020-E99ABC9C2803}
|
||||||
#define NS_IPRIVATETEXTRANGE_IID \
|
#define NS_IPRIVATETEXTRANGE_IID \
|
||||||
{0xb471ab41, 0x2a79, 0x11d3, \
|
{ 0xb13c4bd8, 0xcb9f, 0x4763, \
|
||||||
{ 0x9e, 0xa4, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } }
|
{ 0xa0, 0x20, 0xe9, 0x9a, 0xbc, 0x9c, 0x28, 0x3 } }
|
||||||
|
|
||||||
class nsIPrivateTextRange : public nsISupports {
|
class nsIPrivateTextRange : public nsISupports {
|
||||||
public:
|
public:
|
||||||
@ -68,6 +70,8 @@ public:
|
|||||||
|
|
||||||
NS_IMETHOD GetRangeType(PRUint16* aRangeType)=0;
|
NS_IMETHOD GetRangeType(PRUint16* aRangeType)=0;
|
||||||
NS_IMETHOD SetRangeType(PRUint16 aRangeType)=0;
|
NS_IMETHOD SetRangeType(PRUint16 aRangeType)=0;
|
||||||
|
|
||||||
|
NS_IMETHOD GetRangeStyle(nsTextRangeStyle* aTextRangeStyle)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRange, NS_IPRIVATETEXTRANGE_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRange, NS_IPRIVATETEXTRANGE_IID)
|
||||||
|
@ -73,9 +73,7 @@ nsDOMTextEvent::nsDOMTextEvent(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
for(i = 0; i < te->rangeCount; i++) {
|
for(i = 0; i < te->rangeCount; i++) {
|
||||||
nsRefPtr<nsPrivateTextRange> tempPrivateTextRange = new
|
nsRefPtr<nsPrivateTextRange> tempPrivateTextRange = new
|
||||||
nsPrivateTextRange(te->rangeArray[i].mStartOffset,
|
nsPrivateTextRange(te->rangeArray[i]);
|
||||||
te->rangeArray[i].mEndOffset,
|
|
||||||
te->rangeArray[i].mRangeType);
|
|
||||||
|
|
||||||
if (tempPrivateTextRange) {
|
if (tempPrivateTextRange) {
|
||||||
mTextRange->AppendTextRange(tempPrivateTextRange);
|
mTextRange->AppendTextRange(tempPrivateTextRange);
|
||||||
|
@ -38,10 +38,11 @@
|
|||||||
#include "nsPrivateTextRange.h"
|
#include "nsPrivateTextRange.h"
|
||||||
|
|
||||||
|
|
||||||
nsPrivateTextRange::nsPrivateTextRange(PRUint16 aRangeStart, PRUint16 aRangeEnd, PRUint16 aRangeType)
|
nsPrivateTextRange::nsPrivateTextRange(const nsTextRange &aTextRange)
|
||||||
: mRangeStart(aRangeStart),
|
: mRangeStart(PRUint16(aTextRange.mStartOffset)),
|
||||||
mRangeEnd(aRangeEnd),
|
mRangeEnd(PRUint16(aTextRange.mEndOffset)),
|
||||||
mRangeType(aRangeType)
|
mRangeType(PRUint16(aTextRange.mRangeType)),
|
||||||
|
mRangeStyle(aTextRange.mRangeStyle)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +88,13 @@ NS_METHOD nsPrivateTextRange::SetRangeType(PRUint16 aRangeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_METHOD nsPrivateTextRange::GetRangeStyle(nsTextRangeStyle* aTextRangeStyle)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aTextRangeStyle);
|
||||||
|
*aTextRangeStyle = mRangeStyle;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsPrivateTextRangeList, nsIPrivateTextRangeList)
|
NS_IMPL_ISUPPORTS1(nsPrivateTextRangeList, nsIPrivateTextRangeList)
|
||||||
|
|
||||||
void nsPrivateTextRangeList::AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange)
|
void nsPrivateTextRangeList::AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange)
|
||||||
|
@ -47,7 +47,7 @@ class nsPrivateTextRange : public nsIPrivateTextRange
|
|||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
public:
|
public:
|
||||||
|
|
||||||
nsPrivateTextRange(PRUint16 aRangeStart, PRUint16 aRangeEnd, PRUint16 aRangeType);
|
nsPrivateTextRange(const nsTextRange &aTextRange);
|
||||||
virtual ~nsPrivateTextRange(void);
|
virtual ~nsPrivateTextRange(void);
|
||||||
|
|
||||||
NS_IMETHOD GetRangeStart(PRUint16* aRangeStart);
|
NS_IMETHOD GetRangeStart(PRUint16* aRangeStart);
|
||||||
@ -59,11 +59,14 @@ public:
|
|||||||
NS_IMETHOD GetRangeType(PRUint16* aRangeType);
|
NS_IMETHOD GetRangeType(PRUint16* aRangeType);
|
||||||
NS_IMETHOD SetRangeType(PRUint16 aRangeType);
|
NS_IMETHOD SetRangeType(PRUint16 aRangeType);
|
||||||
|
|
||||||
|
NS_IMETHOD GetRangeStyle(nsTextRangeStyle* aRangeStyle);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
PRUint16 mRangeStart;
|
PRUint16 mRangeStart;
|
||||||
PRUint16 mRangeEnd;
|
PRUint16 mRangeEnd;
|
||||||
PRUint16 mRangeType;
|
PRUint16 mRangeType;
|
||||||
|
nsTextRangeStyle mRangeStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsPrivateTextRangeList: public nsIPrivateTextRangeList
|
class nsPrivateTextRangeList: public nsIPrivateTextRangeList
|
||||||
|
@ -337,21 +337,38 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
|
|||||||
if(NS_FAILED(result))
|
if(NS_FAILED(result))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
newRange->SetStart(mElement,mOffset+selectionStart);
|
result = newRange->SetStart(mElement,mOffset+selectionStart);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetStart");
|
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetStart");
|
||||||
if(NS_FAILED(result))
|
if(NS_FAILED(result))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
newRange->SetEnd(mElement,mOffset+selectionEnd);
|
result = newRange->SetEnd(mElement,mOffset+selectionEnd);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetEnd");
|
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetEnd");
|
||||||
if(NS_FAILED(result))
|
if(NS_FAILED(result))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
imeSel->AddRange(newRange);
|
result = imeSel->AddRange(newRange);
|
||||||
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot AddRange");
|
NS_ASSERTION(NS_SUCCEEDED(result), "Cannot AddRange");
|
||||||
if(NS_FAILED(result))
|
if(NS_FAILED(result))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
nsCOMPtr<nsISelectionPrivate> imeSelPriv(
|
||||||
|
do_QueryInterface(imeSel));
|
||||||
|
if (imeSelPriv) {
|
||||||
|
nsTextRangeStyle textRangeStyle;
|
||||||
|
result = textRange->GetRangeStyle(&textRangeStyle);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(result),
|
||||||
|
"nsIPrivateTextRange::GetRangeStyle failed");
|
||||||
|
if (NS_FAILED(result))
|
||||||
|
break;
|
||||||
|
result = imeSelPriv->SetTextRangeStyle(newRange, textRangeStyle);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(result),
|
||||||
|
"nsISelectionPrivate::SetTextRangeStyle failed");
|
||||||
|
if (NS_FAILED(result))
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
NS_WARNING("IME selection doesn't have nsISelectionPrivate");
|
||||||
|
}
|
||||||
} // if GetRangeEnd
|
} // if GetRangeEnd
|
||||||
} // for textRangeListLength
|
} // for textRangeListLength
|
||||||
if(! setCaret) {
|
if(! setCaret) {
|
||||||
|
@ -49,10 +49,10 @@
|
|||||||
#include "nsIRange.h"
|
#include "nsIRange.h"
|
||||||
|
|
||||||
// IID for the nsFrameSelection interface
|
// IID for the nsFrameSelection interface
|
||||||
// d78edc5a-28d0-48f0-8abb-1597b1591556
|
// 0ea74459-e3f9-48b0-8aa4-5dfef53bf1f7
|
||||||
#define NS_FRAME_SELECTION_IID \
|
#define NS_FRAME_SELECTION_IID \
|
||||||
{ 0xd78edc5a, 0x28d0, 0x48f0, \
|
{ 0xea74459, 0xe3f9, 0x48b0, \
|
||||||
{ 0x8a, 0xbb, 0x15, 0x97, 0xb1, 0x59, 0x15, 0x56 } }
|
{ 0x8a, 0xa4, 0x5d, 0xfe, 0xf5, 0x3b, 0xf1, 0xf7 } }
|
||||||
|
|
||||||
#ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel
|
#ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel
|
||||||
#define BIDI_LEVEL_UNDEFINED 0x80
|
#define BIDI_LEVEL_UNDEFINED 0x80
|
||||||
@ -75,6 +75,7 @@ struct SelectionDetails
|
|||||||
PRInt32 mStart;
|
PRInt32 mStart;
|
||||||
PRInt32 mEnd;
|
PRInt32 mEnd;
|
||||||
SelectionType mType;
|
SelectionType mType;
|
||||||
|
nsTextRangeStyle mTextRangeStyle;
|
||||||
SelectionDetails *mNext;
|
SelectionDetails *mNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ struct RangeData
|
|||||||
|
|
||||||
nsCOMPtr<nsIRange> mRange;
|
nsCOMPtr<nsIRange> mRange;
|
||||||
PRInt32 mEndIndex; // index into mRangeEndings of this item
|
PRInt32 mEndIndex; // index into mRangeEndings of this item
|
||||||
|
nsTextRangeStyle mTextRangeStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
static RangeData sEmptyData(nsnull, 0);
|
static RangeData sEmptyData(nsnull, 0);
|
||||||
@ -357,6 +358,7 @@ private:
|
|||||||
nsINode* aEndNode, PRInt32 aEndOffset,
|
nsINode* aEndNode, PRInt32 aEndOffset,
|
||||||
PRBool aAllowAdjacent,
|
PRBool aAllowAdjacent,
|
||||||
nsCOMArray<nsIRange>* aRanges);
|
nsCOMArray<nsIRange>* aRanges);
|
||||||
|
RangeData* FindRangeData(nsIDOMRange* aRange);
|
||||||
|
|
||||||
nsTArray<RangeData> mRanges;
|
nsTArray<RangeData> mRanges;
|
||||||
nsTArray<PRInt32> mRangeEndings; // references info mRanges
|
nsTArray<PRInt32> mRangeEndings; // references info mRanges
|
||||||
@ -4542,6 +4544,10 @@ nsTypedSelection::LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset,
|
|||||||
details->mStart = start;
|
details->mStart = start;
|
||||||
details->mEnd = end;
|
details->mEnd = end;
|
||||||
details->mType = aType;
|
details->mType = aType;
|
||||||
|
RangeData *rd = FindRangeData(range);
|
||||||
|
if (rd) {
|
||||||
|
details->mTextRangeStyle = rd->mTextRangeStyle;
|
||||||
|
}
|
||||||
*aReturnDetails = details;
|
*aReturnDetails = details;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -4647,6 +4653,29 @@ nsTypedSelection::SetAncestorLimiter(nsIContent *aContent)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RangeData*
|
||||||
|
nsTypedSelection::FindRangeData(nsIDOMRange* aRange)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(aRange, nsnull);
|
||||||
|
for (PRUint32 i = 0; i < mRanges.Length(); i++) {
|
||||||
|
if (mRanges[i].mRange == aRange)
|
||||||
|
return &mRanges[i];
|
||||||
|
}
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTypedSelection::SetTextRangeStyle(nsIDOMRange *aRange,
|
||||||
|
const nsTextRangeStyle &aTextRangeStyle)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRange);
|
||||||
|
RangeData *rd = FindRangeData(aRange);
|
||||||
|
if (rd) {
|
||||||
|
rd->mTextRangeStyle = aTextRangeStyle;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsTypedSelection::StartAutoScrollTimer(nsPresContext *aPresContext,
|
nsTypedSelection::StartAutoScrollTimer(nsPresContext *aPresContext,
|
||||||
nsIView *aView,
|
nsIView *aView,
|
||||||
|
@ -4090,23 +4090,58 @@ static const SelectionType SelectionTypesWithDecorations =
|
|||||||
nsISelectionController::SELECTION_IME_CONVERTEDTEXT |
|
nsISelectionController::SELECTION_IME_CONVERTEDTEXT |
|
||||||
nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
|
nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
|
||||||
|
|
||||||
|
static PRUint8
|
||||||
|
GetTextDecorationStyle(const nsTextRangeStyle &aRangeStyle)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aRangeStyle.IsLineStyleDefined(),
|
||||||
|
"aRangeStyle.mLineStyle have to be defined");
|
||||||
|
switch (aRangeStyle.mLineStyle) {
|
||||||
|
case nsTextRangeStyle::LINESTYLE_NONE:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_NONE;
|
||||||
|
case nsTextRangeStyle::LINESTYLE_SOLID:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_SOLID;
|
||||||
|
case nsTextRangeStyle::LINESTYLE_DOTTED:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_DOTTED;
|
||||||
|
case nsTextRangeStyle::LINESTYLE_DASHED:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_DASHED;
|
||||||
|
case nsTextRangeStyle::LINESTYLE_DOUBLE:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_DOUBLE;
|
||||||
|
case nsTextRangeStyle::LINESTYLE_WAVY:
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_WAVY;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Requested underline style is not valid");
|
||||||
|
return nsCSSRendering::DECORATION_STYLE_SOLID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This, plus SelectionTypesWithDecorations, encapsulates all knowledge about
|
* This, plus SelectionTypesWithDecorations, encapsulates all knowledge about
|
||||||
* 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& aPt, gfxFloat aWidth,
|
nsTextPaintStyle& aTextPaintStyle,
|
||||||
|
const nsTextRangeStyle &aRangeStyle,
|
||||||
|
const gfxPoint& aPt, gfxFloat aWidth,
|
||||||
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics)
|
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics)
|
||||||
{
|
{
|
||||||
gfxPoint pt(aPt);
|
gfxPoint pt(aPt);
|
||||||
gfxSize size(aWidth, aFontMetrics.underlineSize);
|
gfxSize size(aWidth, aFontMetrics.underlineSize);
|
||||||
gfxFloat descentLimit = aFontMetrics.maxDescent;
|
gfxFloat descentLimit = aFontMetrics.maxDescent;
|
||||||
|
|
||||||
|
float relativeSize;
|
||||||
|
PRUint8 style;
|
||||||
|
nscolor color;
|
||||||
|
PRInt32 index =
|
||||||
|
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType);
|
||||||
|
PRBool weDefineSelectionUnderline =
|
||||||
|
aTextPaintStyle.GetSelectionUnderlineForPaint(index, &color,
|
||||||
|
&relativeSize, &style);
|
||||||
|
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
case nsISelectionController::SELECTION_IME_RAWINPUT:
|
case nsISelectionController::SELECTION_IME_RAWINPUT:
|
||||||
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
||||||
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
||||||
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: {
|
||||||
// IME decoration lines should not be drawn on the both ends, i.e., we
|
// IME decoration lines should not be drawn on the both ends, i.e., we
|
||||||
// need to cut both edges of the decoration lines. Because same style
|
// need to cut both edges of the decoration lines. Because same style
|
||||||
// IME selections can adjoin, but the users need to be able to know
|
// IME selections can adjoin, but the users need to be able to know
|
||||||
@ -4122,27 +4157,47 @@ static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
|
|||||||
// gap gap gap
|
// gap gap gap
|
||||||
pt.x += 1.0;
|
pt.x += 1.0;
|
||||||
size.width -= 2.0;
|
size.width -= 2.0;
|
||||||
case nsISelectionController::SELECTION_SPELLCHECK: {
|
if (aRangeStyle.IsDefined()) {
|
||||||
float relativeSize;
|
// If IME defines the style, that should override our definition.
|
||||||
PRUint8 style;
|
if (aRangeStyle.IsLineStyleDefined()) {
|
||||||
nscolor color;
|
if (aRangeStyle.mLineStyle == nsTextRangeStyle::LINESTYLE_NONE) {
|
||||||
PRInt32 index =
|
return;
|
||||||
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType);
|
}
|
||||||
if (aTextPaintStyle.GetSelectionUnderlineForPaint(index, &color,
|
style = GetTextDecorationStyle(aRangeStyle);
|
||||||
&relativeSize,
|
relativeSize = aRangeStyle.mIsBoldLine ? 2.0f : 1.0f;
|
||||||
&style)) {
|
} else if (!weDefineSelectionUnderline) {
|
||||||
|
// There is no underline style definition.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (aRangeStyle.IsUnderlineColorDefined()) {
|
||||||
|
color = aRangeStyle.mUnderlineColor;
|
||||||
|
} else if (aRangeStyle.IsForegroundColorDefined()) {
|
||||||
|
color = aRangeStyle.mForegroundColor;
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(!aRangeStyle.IsBackgroundColorDefined(),
|
||||||
|
"Only the background color is defined");
|
||||||
|
color = aTextPaintStyle.GetTextColor();
|
||||||
|
}
|
||||||
|
} else if (!weDefineSelectionUnderline) {
|
||||||
|
// IME doesn't specify the selection style and we don't define selection
|
||||||
|
// underline.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case nsISelectionController::SELECTION_SPELLCHECK:
|
||||||
|
if (!weDefineSelectionUnderline)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Requested selection decorations when there aren't any");
|
||||||
|
return;
|
||||||
|
}
|
||||||
size.height *= relativeSize;
|
size.height *= relativeSize;
|
||||||
nsCSSRendering::PaintDecorationLine(
|
nsCSSRendering::PaintDecorationLine(
|
||||||
aContext, color, pt, size, aAscent, aFontMetrics.underlineOffset,
|
aContext, color, pt, size, aAscent, aFontMetrics.underlineOffset,
|
||||||
NS_STYLE_TEXT_DECORATION_UNDERLINE, style, descentLimit);
|
NS_STYLE_TEXT_DECORATION_UNDERLINE, style, descentLimit);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
NS_WARNING("Requested selection decorations when there aren't any");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function encapsulates all knowledge of how selections affect foreground
|
* This function encapsulates all knowledge of how selections affect foreground
|
||||||
@ -4152,7 +4207,9 @@ static void DrawSelectionDecorations(gfxContext* aContext, SelectionType aType,
|
|||||||
* @param aBackground the background color to use, or RGBA(0,0,0,0) if no
|
* @param aBackground the background color to use, or RGBA(0,0,0,0) if no
|
||||||
* background should be painted
|
* background should be painted
|
||||||
*/
|
*/
|
||||||
static PRBool GetSelectionTextColors(SelectionType aType, nsTextPaintStyle& aTextPaintStyle,
|
static PRBool GetSelectionTextColors(SelectionType aType,
|
||||||
|
nsTextPaintStyle& aTextPaintStyle,
|
||||||
|
const nsTextRangeStyle &aRangeStyle,
|
||||||
nscolor* aForeground, nscolor* aBackground)
|
nscolor* aForeground, nscolor* aBackground)
|
||||||
{
|
{
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
@ -4165,11 +4222,25 @@ static PRBool GetSelectionTextColors(SelectionType aType, nsTextPaintStyle& aTex
|
|||||||
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
|
||||||
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
|
||||||
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
|
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
|
||||||
|
if (aRangeStyle.IsDefined()) {
|
||||||
|
*aForeground = aTextPaintStyle.GetTextColor();
|
||||||
|
*aBackground = NS_RGBA(0,0,0,0);
|
||||||
|
if (!aRangeStyle.IsForegroundColorDefined() &&
|
||||||
|
!aRangeStyle.IsBackgroundColorDefined()) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (aRangeStyle.IsForegroundColorDefined()) {
|
||||||
|
*aForeground = aRangeStyle.mForegroundColor;
|
||||||
|
}
|
||||||
|
if (aRangeStyle.IsBackgroundColorDefined()) {
|
||||||
|
*aBackground = aRangeStyle.mBackgroundColor;
|
||||||
|
}
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
aTextPaintStyle.GetIMESelectionColors(
|
aTextPaintStyle.GetIMESelectionColors(
|
||||||
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType),
|
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aType),
|
||||||
aForeground, aBackground);
|
aForeground, aBackground);
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*aForeground = aTextPaintStyle.GetTextColor();
|
*aForeground = aTextPaintStyle.GetTextColor();
|
||||||
*aBackground = NS_RGBA(0,0,0,0);
|
*aBackground = NS_RGBA(0,0,0,0);
|
||||||
@ -4187,12 +4258,12 @@ static PRBool GetSelectionTextColors(SelectionType aType, nsTextPaintStyle& aTex
|
|||||||
class SelectionIterator {
|
class SelectionIterator {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* aStart and aLength are in the original string. aSelectionBuffer is
|
* aStart and aLength are in the original string. aSelectionDetails is
|
||||||
* according to the original string.
|
* according to the original string.
|
||||||
*/
|
*/
|
||||||
SelectionIterator(SelectionType* aSelectionBuffer, PRInt32 aStart,
|
SelectionIterator(SelectionDetails** aSelectionDetails,
|
||||||
PRInt32 aLength, PropertyProvider& aProvider,
|
PRInt32 aStart, PRInt32 aLength,
|
||||||
gfxTextRun* aTextRun);
|
PropertyProvider& aProvider, gfxTextRun* aTextRun);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next segment of uniformly selected (or not) text.
|
* Returns the next segment of uniformly selected (or not) text.
|
||||||
@ -4204,16 +4275,18 @@ public:
|
|||||||
* @param aHyphenWidth if a hyphen is to be rendered after the text, the
|
* @param aHyphenWidth if a hyphen is to be rendered after the text, the
|
||||||
* width of the hyphen, otherwise zero
|
* width of the hyphen, otherwise zero
|
||||||
* @param aType the selection type for this segment
|
* @param aType the selection type for this segment
|
||||||
|
* @param aStyle the selection style for this segment
|
||||||
* @return false if there are no more segments
|
* @return false if there are no more segments
|
||||||
*/
|
*/
|
||||||
PRBool GetNextSegment(gfxFloat* aXOffset, PRUint32* aOffset, PRUint32* aLength,
|
PRBool GetNextSegment(gfxFloat* aXOffset, PRUint32* aOffset, PRUint32* aLength,
|
||||||
gfxFloat* aHyphenWidth, SelectionType* aType);
|
gfxFloat* aHyphenWidth, SelectionType* aType,
|
||||||
|
nsTextRangeStyle* aStyle);
|
||||||
void UpdateWithAdvance(gfxFloat aAdvance) {
|
void UpdateWithAdvance(gfxFloat aAdvance) {
|
||||||
mXOffset += aAdvance*mTextRun->GetDirection();
|
mXOffset += aAdvance*mTextRun->GetDirection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SelectionType* mSelectionBuffer;
|
SelectionDetails** mSelectionDetails;
|
||||||
PropertyProvider& mProvider;
|
PropertyProvider& mProvider;
|
||||||
gfxTextRun* mTextRun;
|
gfxTextRun* mTextRun;
|
||||||
gfxSkipCharsIterator mIterator;
|
gfxSkipCharsIterator mIterator;
|
||||||
@ -4222,10 +4295,10 @@ private:
|
|||||||
gfxFloat mXOffset;
|
gfxFloat mXOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectionIterator::SelectionIterator(SelectionType* aSelectionBuffer,
|
SelectionIterator::SelectionIterator(SelectionDetails** aSelectionDetails,
|
||||||
PRInt32 aStart, PRInt32 aLength, PropertyProvider& aProvider,
|
PRInt32 aStart, PRInt32 aLength, PropertyProvider& aProvider,
|
||||||
gfxTextRun* aTextRun)
|
gfxTextRun* aTextRun)
|
||||||
: mSelectionBuffer(aSelectionBuffer), mProvider(aProvider),
|
: mSelectionDetails(aSelectionDetails), mProvider(aProvider),
|
||||||
mTextRun(aTextRun), mIterator(aProvider.GetStart()),
|
mTextRun(aTextRun), mIterator(aProvider.GetStart()),
|
||||||
mOriginalStart(aStart), mOriginalEnd(aStart + aLength),
|
mOriginalStart(aStart), mOriginalEnd(aStart + aLength),
|
||||||
mXOffset(mTextRun->IsRightToLeft() ? aProvider.GetFrame()->GetSize().width : 0)
|
mXOffset(mTextRun->IsRightToLeft() ? aProvider.GetFrame()->GetSize().width : 0)
|
||||||
@ -4234,7 +4307,8 @@ SelectionIterator::SelectionIterator(SelectionType* aSelectionBuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PRBool SelectionIterator::GetNextSegment(gfxFloat* aXOffset,
|
PRBool SelectionIterator::GetNextSegment(gfxFloat* aXOffset,
|
||||||
PRUint32* aOffset, PRUint32* aLength, gfxFloat* aHyphenWidth, SelectionType* aType)
|
PRUint32* aOffset, PRUint32* aLength, gfxFloat* aHyphenWidth,
|
||||||
|
SelectionType* aType, nsTextRangeStyle* aStyle)
|
||||||
{
|
{
|
||||||
if (mIterator.GetOriginalOffset() >= mOriginalEnd)
|
if (mIterator.GetOriginalOffset() >= mOriginalEnd)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
@ -4243,9 +4317,15 @@ PRBool SelectionIterator::GetNextSegment(gfxFloat* aXOffset,
|
|||||||
PRUint32 runOffset = mIterator.GetSkippedOffset();
|
PRUint32 runOffset = mIterator.GetSkippedOffset();
|
||||||
|
|
||||||
PRInt32 index = mIterator.GetOriginalOffset() - mOriginalStart;
|
PRInt32 index = mIterator.GetOriginalOffset() - mOriginalStart;
|
||||||
SelectionType type = mSelectionBuffer[index];
|
SelectionDetails* sdptr = mSelectionDetails[index];
|
||||||
|
SelectionType type =
|
||||||
|
sdptr ? sdptr->mType : nsISelectionController::SELECTION_NONE;
|
||||||
|
nsTextRangeStyle style;
|
||||||
|
if (sdptr) {
|
||||||
|
style = sdptr->mTextRangeStyle;
|
||||||
|
}
|
||||||
for (++index; mOriginalStart + index < mOriginalEnd; ++index) {
|
for (++index; mOriginalStart + index < mOriginalEnd; ++index) {
|
||||||
if (mSelectionBuffer[index] != type)
|
if (sdptr != mSelectionDetails[index])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mIterator.SetOriginalOffset(index + mOriginalStart);
|
mIterator.SetOriginalOffset(index + mOriginalStart);
|
||||||
@ -4267,6 +4347,7 @@ PRBool SelectionIterator::GetNextSegment(gfxFloat* aXOffset,
|
|||||||
*aHyphenWidth = mProvider.GetHyphenWidth();
|
*aHyphenWidth = mProvider.GetHyphenWidth();
|
||||||
}
|
}
|
||||||
*aType = type;
|
*aType = type;
|
||||||
|
*aStyle = style;
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4362,14 +4443,15 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
|||||||
PRInt32 contentLength = aProvider.GetOriginalLength();
|
PRInt32 contentLength = aProvider.GetOriginalLength();
|
||||||
|
|
||||||
// Figure out which selections control the colors to use for each character.
|
// Figure out which selections control the colors to use for each character.
|
||||||
nsAutoTArray<SelectionType,BIG_TEXT_NODE_SIZE> prevailingSelectionsBuffer;
|
nsAutoTArray<SelectionDetails*,BIG_TEXT_NODE_SIZE> prevailingSelectionsBuffer;
|
||||||
if (!prevailingSelectionsBuffer.AppendElements(contentLength))
|
if (!prevailingSelectionsBuffer.AppendElements(contentLength))
|
||||||
return;
|
return;
|
||||||
SelectionType* prevailingSelections = prevailingSelectionsBuffer.Elements();
|
SelectionDetails** prevailingSelections = prevailingSelectionsBuffer.Elements();
|
||||||
|
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
SelectionType allTypes = 0;
|
SelectionType allTypes = 0;
|
||||||
for (i = 0; i < contentLength; ++i) {
|
for (i = 0; i < contentLength; ++i) {
|
||||||
prevailingSelections[i] = nsISelectionController::SELECTION_NONE;
|
prevailingSelections[i] = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionDetails *sdptr = aDetails;
|
SelectionDetails *sdptr = aDetails;
|
||||||
@ -4382,16 +4464,16 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
|||||||
allTypes |= type;
|
allTypes |= type;
|
||||||
// Ignore selections that don't set colors
|
// Ignore selections that don't set colors
|
||||||
nscolor foreground, background;
|
nscolor foreground, background;
|
||||||
if (GetSelectionTextColors(type, aTextPaintStyle, &foreground, &background)) {
|
if (GetSelectionTextColors(type, aTextPaintStyle, sdptr->mTextRangeStyle,
|
||||||
|
&foreground, &background)) {
|
||||||
if (NS_GET_A(background) > 0) {
|
if (NS_GET_A(background) > 0) {
|
||||||
anyBackgrounds = PR_TRUE;
|
anyBackgrounds = PR_TRUE;
|
||||||
}
|
}
|
||||||
for (i = start; i < end; ++i) {
|
for (i = start; i < end; ++i) {
|
||||||
PRInt16 currentPrevailingSelection = prevailingSelections[i];
|
|
||||||
// Favour normal selection over IME selections
|
// Favour normal selection over IME selections
|
||||||
if (currentPrevailingSelection == nsISelectionController::SELECTION_NONE ||
|
if (!prevailingSelections[i] ||
|
||||||
type < currentPrevailingSelection) {
|
type < prevailingSelections[i]->mType) {
|
||||||
prevailingSelections[i] = type;
|
prevailingSelections[i] = sdptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4403,13 +4485,16 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
|||||||
gfxFloat xOffset, hyphenWidth;
|
gfxFloat xOffset, hyphenWidth;
|
||||||
PRUint32 offset, length; // in transformed string
|
PRUint32 offset, length; // in transformed string
|
||||||
SelectionType type;
|
SelectionType type;
|
||||||
|
nsTextRangeStyle rangeStyle;
|
||||||
// Draw background colors
|
// Draw background colors
|
||||||
if (anyBackgrounds) {
|
if (anyBackgrounds) {
|
||||||
SelectionIterator iterator(prevailingSelections, contentOffset, contentLength,
|
SelectionIterator iterator(prevailingSelections, contentOffset, contentLength,
|
||||||
aProvider, mTextRun);
|
aProvider, mTextRun);
|
||||||
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth, &type)) {
|
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth,
|
||||||
|
&type, &rangeStyle)) {
|
||||||
nscolor foreground, background;
|
nscolor foreground, background;
|
||||||
GetSelectionTextColors(type, aTextPaintStyle, &foreground, &background);
|
GetSelectionTextColors(type, aTextPaintStyle, rangeStyle,
|
||||||
|
&foreground, &background);
|
||||||
// Draw background color
|
// Draw background color
|
||||||
gfxFloat advance = hyphenWidth +
|
gfxFloat advance = hyphenWidth +
|
||||||
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
||||||
@ -4426,9 +4511,11 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx,
|
|||||||
// Draw text
|
// Draw text
|
||||||
SelectionIterator iterator(prevailingSelections, contentOffset, contentLength,
|
SelectionIterator iterator(prevailingSelections, contentOffset, contentLength,
|
||||||
aProvider, mTextRun);
|
aProvider, mTextRun);
|
||||||
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth, &type)) {
|
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth,
|
||||||
|
&type, &rangeStyle)) {
|
||||||
nscolor foreground, background;
|
nscolor foreground, background;
|
||||||
GetSelectionTextColors(type, aTextPaintStyle, &foreground, &background);
|
GetSelectionTextColors(type, aTextPaintStyle, rangeStyle,
|
||||||
|
&foreground, &background);
|
||||||
// Draw text segment
|
// Draw text segment
|
||||||
aCtx->SetColor(gfxRGBA(foreground));
|
aCtx->SetColor(gfxRGBA(foreground));
|
||||||
gfxFloat advance;
|
gfxFloat advance;
|
||||||
@ -4453,15 +4540,14 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
|||||||
PRInt32 contentOffset = aProvider.GetStart().GetOriginalOffset();
|
PRInt32 contentOffset = aProvider.GetStart().GetOriginalOffset();
|
||||||
PRInt32 contentLength = aProvider.GetOriginalLength();
|
PRInt32 contentLength = aProvider.GetOriginalLength();
|
||||||
|
|
||||||
// Figure out which characters will be decorated for this selection. Here
|
// Figure out which characters will be decorated for this selection.
|
||||||
// we just fill the buffer with either SELECTION_NONE or aSelectionType.
|
nsAutoTArray<SelectionDetails*, BIG_TEXT_NODE_SIZE> selectedCharsBuffer;
|
||||||
nsAutoTArray<SelectionType,BIG_TEXT_NODE_SIZE> selectedCharsBuffer;
|
|
||||||
if (!selectedCharsBuffer.AppendElements(contentLength))
|
if (!selectedCharsBuffer.AppendElements(contentLength))
|
||||||
return;
|
return;
|
||||||
SelectionType* selectedChars = selectedCharsBuffer.Elements();
|
SelectionDetails** selectedChars = selectedCharsBuffer.Elements();
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
for (i = 0; i < contentLength; ++i) {
|
for (i = 0; i < contentLength; ++i) {
|
||||||
selectedChars[i] = nsISelectionController::SELECTION_NONE;
|
selectedChars[i] = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionDetails *sdptr = aDetails;
|
SelectionDetails *sdptr = aDetails;
|
||||||
@ -4470,7 +4556,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
|||||||
PRInt32 start = PR_MAX(0, sdptr->mStart - contentOffset);
|
PRInt32 start = PR_MAX(0, sdptr->mStart - contentOffset);
|
||||||
PRInt32 end = PR_MIN(contentLength, sdptr->mEnd - contentOffset);
|
PRInt32 end = PR_MIN(contentLength, sdptr->mEnd - contentOffset);
|
||||||
for (i = start; i < end; ++i) {
|
for (i = start; i < end; ++i) {
|
||||||
selectedChars[i] = aSelectionType;
|
selectedChars[i] = sdptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdptr = sdptr->mNext;
|
sdptr = sdptr->mNext;
|
||||||
@ -4491,7 +4577,9 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
|||||||
// XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
|
// XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||||
gfxPoint pt(0.0, (aTextBaselinePt.y - mAscent) / app);
|
gfxPoint pt(0.0, (aTextBaselinePt.y - mAscent) / app);
|
||||||
SelectionType type;
|
SelectionType type;
|
||||||
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth, &type)) {
|
nsTextRangeStyle selectedStyle;
|
||||||
|
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth,
|
||||||
|
&type, &selectedStyle)) {
|
||||||
gfxFloat advance = hyphenWidth +
|
gfxFloat advance = hyphenWidth +
|
||||||
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
||||||
if (type == aSelectionType) {
|
if (type == aSelectionType) {
|
||||||
@ -4499,6 +4587,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
|||||||
(mTextRun->IsRightToLeft() ? advance : 0)) / app;
|
(mTextRun->IsRightToLeft() ? advance : 0)) / app;
|
||||||
gfxFloat width = PR_ABS(advance) / app;
|
gfxFloat width = PR_ABS(advance) / app;
|
||||||
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
|
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
|
||||||
|
selectedStyle,
|
||||||
pt, width, mAscent / app, decorationMetrics);
|
pt, width, mAscent / app, decorationMetrics);
|
||||||
}
|
}
|
||||||
iterator.UpdateWithAdvance(advance);
|
iterator.UpdateWithAdvance(advance);
|
||||||
@ -4799,10 +4888,27 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
|
|||||||
float relativeSize;
|
float relativeSize;
|
||||||
PRInt32 index =
|
PRInt32 index =
|
||||||
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(sd->mType);
|
nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(sd->mType);
|
||||||
|
if (sd->mType == nsISelectionController::SELECTION_SPELLCHECK) {
|
||||||
if (!nsTextPaintStyle::GetSelectionUnderline(aPresContext, index, nsnull,
|
if (!nsTextPaintStyle::GetSelectionUnderline(aPresContext, index, nsnull,
|
||||||
&relativeSize, &style)) {
|
&relativeSize, &style)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// IME selections
|
||||||
|
nsTextRangeStyle& rangeStyle = sd->mTextRangeStyle;
|
||||||
|
if (rangeStyle.IsDefined()) {
|
||||||
|
if (!rangeStyle.IsLineStyleDefined() ||
|
||||||
|
rangeStyle.mLineStyle == nsTextRangeStyle::LINESTYLE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
style = GetTextDecorationStyle(rangeStyle);
|
||||||
|
relativeSize = rangeStyle.mIsBoldLine ? 2.0f : 1.0f;
|
||||||
|
} else if (!nsTextPaintStyle::GetSelectionUnderline(aPresContext, index,
|
||||||
|
nsnull, &relativeSize,
|
||||||
|
&style)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
nsRect decorationArea;
|
nsRect decorationArea;
|
||||||
gfxSize size(aPresContext->AppUnitsToGfxUnits(aRect.width),
|
gfxSize size(aPresContext->AppUnitsToGfxUnits(aRect.width),
|
||||||
metrics.underlineSize);
|
metrics.underlineSize);
|
||||||
|
@ -843,6 +843,96 @@ public:
|
|||||||
/**
|
/**
|
||||||
* IME Related Events
|
* IME Related Events
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct nsTextRangeStyle
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
LINESTYLE_NONE = 0,
|
||||||
|
LINESTYLE_SOLID = 1,
|
||||||
|
LINESTYLE_DOTTED = 2,
|
||||||
|
LINESTYLE_DASHED = 3,
|
||||||
|
LINESTYLE_DOUBLE = 4,
|
||||||
|
LINESTYLE_WAVY = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEFINED_NONE = 0x00,
|
||||||
|
DEFINED_LINESTYLE = 0x01,
|
||||||
|
DEFINED_FOREGROUND_COLOR = 0x02,
|
||||||
|
DEFINED_BACKGROUND_COLOR = 0x04,
|
||||||
|
DEFINED_UNDERLINE_COLOR = 0x08
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize all members, because nsTextRange instances may be compared by
|
||||||
|
// memcomp.
|
||||||
|
nsTextRangeStyle() :
|
||||||
|
mDefinedStyles(DEFINED_NONE), mLineStyle(LINESTYLE_NONE),
|
||||||
|
mIsBoldLine(PR_FALSE), mForegroundColor(NS_RGBA(0, 0, 0, 0)),
|
||||||
|
mBackgroundColor(NS_RGBA(0, 0, 0, 0)), mUnderlineColor(NS_RGBA(0, 0, 0, 0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsDefined() const { return mDefinedStyles != DEFINED_NONE; }
|
||||||
|
|
||||||
|
PRBool IsLineStyleDefined() const
|
||||||
|
{
|
||||||
|
return (mDefinedStyles & DEFINED_LINESTYLE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsForegroundColorDefined() const
|
||||||
|
{
|
||||||
|
return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsBackgroundColorDefined() const
|
||||||
|
{
|
||||||
|
return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsUnderlineColorDefined() const
|
||||||
|
{
|
||||||
|
return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool Equals(const nsTextRangeStyle& aOther)
|
||||||
|
{
|
||||||
|
if (mDefinedStyles != aOther.mDefinedStyles)
|
||||||
|
return PR_FALSE;
|
||||||
|
if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle ||
|
||||||
|
!mIsBoldLine != !aOther.mIsBoldLine))
|
||||||
|
return PR_FALSE;
|
||||||
|
if (IsForegroundColorDefined() &&
|
||||||
|
(mForegroundColor != aOther.mForegroundColor))
|
||||||
|
return PR_FALSE;
|
||||||
|
if (IsBackgroundColorDefined() &&
|
||||||
|
(mBackgroundColor != aOther.mBackgroundColor))
|
||||||
|
return PR_FALSE;
|
||||||
|
if (IsUnderlineColorDefined() &&
|
||||||
|
(mUnderlineColor != aOther.mUnderlineColor))
|
||||||
|
return PR_FALSE;
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool operator !=(const nsTextRangeStyle &aOther)
|
||||||
|
{
|
||||||
|
return !Equals(aOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool operator ==(const nsTextRangeStyle &aOther)
|
||||||
|
{
|
||||||
|
return Equals(aOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint8 mDefinedStyles;
|
||||||
|
PRUint8 mLineStyle; // DEFINED_LINESTYLE
|
||||||
|
|
||||||
|
PRPackedBool mIsBoldLine; // DEFINED_LINESTYLE
|
||||||
|
|
||||||
|
nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR
|
||||||
|
nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR
|
||||||
|
nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR
|
||||||
|
};
|
||||||
|
|
||||||
struct nsTextRange
|
struct nsTextRange
|
||||||
{
|
{
|
||||||
nsTextRange()
|
nsTextRange()
|
||||||
@ -853,6 +943,8 @@ struct nsTextRange
|
|||||||
PRUint32 mStartOffset;
|
PRUint32 mStartOffset;
|
||||||
PRUint32 mEndOffset;
|
PRUint32 mEndOffset;
|
||||||
PRUint32 mRangeType;
|
PRUint32 mRangeType;
|
||||||
|
|
||||||
|
nsTextRangeStyle mRangeStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef nsTextRange* nsTextRangeArray;
|
typedef nsTextRange* nsTextRangeArray;
|
||||||
|
@ -621,6 +621,50 @@ nsTextStore::UpdateCompositionExtent(ITfRange* aRangeNew)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
GetColor(const TF_DA_COLOR &aTSFColor, nscolor &aResult)
|
||||||
|
{
|
||||||
|
switch (aTSFColor.type) {
|
||||||
|
case TF_CT_SYSCOLOR: {
|
||||||
|
DWORD sysColor = ::GetSysColor(aTSFColor.nIndex);
|
||||||
|
aResult = NS_RGB(GetRValue(sysColor), GetGValue(sysColor),
|
||||||
|
GetBValue(sysColor));
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
case TF_CT_COLORREF:
|
||||||
|
aResult = NS_RGB(GetRValue(aTSFColor.cr), GetGValue(aTSFColor.cr),
|
||||||
|
GetBValue(aTSFColor.cr));
|
||||||
|
return PR_TRUE;
|
||||||
|
case TF_CT_NONE:
|
||||||
|
default:
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
GetLineStyle(TF_DA_LINESTYLE aTSFLineStyle, PRUint8 &aTextRangeLineStyle)
|
||||||
|
{
|
||||||
|
switch (aTSFLineStyle) {
|
||||||
|
case TF_LS_NONE:
|
||||||
|
aTextRangeLineStyle = nsTextRangeStyle::LINESTYLE_NONE;
|
||||||
|
return PR_TRUE;
|
||||||
|
case TF_LS_SOLID:
|
||||||
|
aTextRangeLineStyle = nsTextRangeStyle::LINESTYLE_SOLID;
|
||||||
|
return PR_TRUE;
|
||||||
|
case TF_LS_DOT:
|
||||||
|
aTextRangeLineStyle = nsTextRangeStyle::LINESTYLE_DOTTED;
|
||||||
|
return PR_TRUE;
|
||||||
|
case TF_LS_DASH:
|
||||||
|
aTextRangeLineStyle = nsTextRangeStyle::LINESTYLE_DASHED;
|
||||||
|
return PR_TRUE;
|
||||||
|
case TF_LS_SQUIGGLE:
|
||||||
|
aTextRangeLineStyle = nsTextRangeStyle::LINESTYLE_WAVY;
|
||||||
|
return PR_TRUE;
|
||||||
|
default:
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
nsTextStore::SendTextEventForCompositionString()
|
nsTextStore::SendTextEventForCompositionString()
|
||||||
{
|
{
|
||||||
@ -677,6 +721,7 @@ nsTextStore::SendTextEventForCompositionString()
|
|||||||
if (FAILED(GetRangeExtent(range, &start, &length)))
|
if (FAILED(GetRangeExtent(range, &start, &length)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
nsTextRange newRange;
|
||||||
newRange.mStartOffset = PRUint32(start - mCompositionStart);
|
newRange.mStartOffset = PRUint32(start - mCompositionStart);
|
||||||
// The end of the last range in the array is
|
// The end of the last range in the array is
|
||||||
// always kept at the end of composition
|
// always kept at the end of composition
|
||||||
@ -684,8 +729,28 @@ nsTextStore::SendTextEventForCompositionString()
|
|||||||
|
|
||||||
TF_DISPLAYATTRIBUTE attr;
|
TF_DISPLAYATTRIBUTE attr;
|
||||||
hr = GetDisplayAttribute(attrPropetry, range, &attr);
|
hr = GetDisplayAttribute(attrPropetry, range, &attr);
|
||||||
newRange.mRangeType =
|
if (FAILED(hr)) {
|
||||||
SUCCEEDED(hr) ? GetGeckoSelectionValue(attr) : NS_TEXTRANGE_RAWINPUT;
|
newRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
|
||||||
|
} else {
|
||||||
|
newRange.mRangeType = GetGeckoSelectionValue(attr);
|
||||||
|
if (GetColor(attr.crText, newRange.mRangeStyle.mForegroundColor)) {
|
||||||
|
newRange.mRangeStyle.mDefinedStyles |=
|
||||||
|
nsTextRangeStyle::DEFINED_FOREGROUND_COLOR;
|
||||||
|
}
|
||||||
|
if (GetColor(attr.crBk, newRange.mRangeStyle.mBackgroundColor)) {
|
||||||
|
newRange.mRangeStyle.mDefinedStyles |=
|
||||||
|
nsTextRangeStyle::DEFINED_BACKGROUND_COLOR;
|
||||||
|
}
|
||||||
|
if (GetColor(attr.crLine, newRange.mRangeStyle.mUnderlineColor)) {
|
||||||
|
newRange.mRangeStyle.mDefinedStyles |=
|
||||||
|
nsTextRangeStyle::DEFINED_UNDERLINE_COLOR;
|
||||||
|
}
|
||||||
|
if (GetLineStyle(attr.lsStyle, newRange.mRangeStyle.mLineStyle)) {
|
||||||
|
newRange.mRangeStyle.mDefinedStyles |=
|
||||||
|
nsTextRangeStyle::DEFINED_LINESTYLE;
|
||||||
|
newRange.mRangeStyle.mIsBoldLine = attr.fBoldLine != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsTextRange& lastRange = textRanges[textRanges.Length() - 1];
|
nsTextRange& lastRange = textRanges[textRanges.Length() - 1];
|
||||||
if (lastRange.mStartOffset == newRange.mStartOffset) {
|
if (lastRange.mStartOffset == newRange.mStartOffset) {
|
||||||
|
Loading…
Reference in New Issue
Block a user