modified for new fontmetrics/renderingcontext.

This commit is contained in:
michaelp%netscape.com 1998-10-02 01:12:39 +00:00
Родитель db12868a7e
Коммит 9b82a28284
39 изменённых файлов: 1487 добавлений и 265 удалений

Просмотреть файл

@ -30,6 +30,7 @@ class nsIStyleSet;
class nsIViewManager;
class nsIReflowCommand;
class nsIDeviceContext;
class nsIRenderingContext;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -94,6 +95,12 @@ public:
virtual void ProcessReflowCommands() = 0;
/**
* Given a frame, cough up a rendering context suitable for use with
* the frame.
*/
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext *&aContext) = 0;
// XXX events
// XXX selection

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsIViewObserver.h"
#include "nsContainerFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIDeviceContext.h"
static PRBool gsNoisyRefs = PR_FALSE;
#undef NOISY
@ -207,8 +208,7 @@ public:
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand);
virtual void ProcessReflowCommands();
//nsIViewObserver
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext *&aContext);
//nsIViewObserver interface
@ -496,13 +496,17 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
mRootFrame->VerifyTree();
}
#endif
nsRect bounds;
nsRect bounds;
mPresContext->GetVisibleArea(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, eReflowReason_Initial, maxSize);
nsIHTMLReflow* htmlReflow;
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsIHTMLReflow* htmlReflow;
nsIRenderingContext* rcx = nsnull;
CreateRenderingContext(mRootFrame, rcx);
nsReflowState reflowState(mRootFrame, eReflowReason_Initial, maxSize, rcx);
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
@ -513,6 +517,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
}
#endif
}
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::InitialReflow"));
}
@ -542,13 +547,17 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
mRootFrame->VerifyTree();
}
#endif
nsRect bounds;
nsRect bounds;
mPresContext->GetVisibleArea(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, eReflowReason_Resize, maxSize);
nsIHTMLReflow* htmlReflow;
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsIHTMLReflow* htmlReflow;
nsIRenderingContext* rcx = nsnull;
CreateRenderingContext(mRootFrame, rcx);
nsReflowState reflowState(mRootFrame, eReflowReason_Resize, maxSize, rcx);
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
@ -559,6 +568,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
}
#endif
}
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
// XXX if debugging then we should assert that the cache is empty
@ -631,7 +641,10 @@ void
PresShell::ProcessReflowCommands()
{
if (0 != mReflowCommands.Count()) {
nsHTMLReflowMetrics desiredSize(nsnull);
nsHTMLReflowMetrics desiredSize(nsnull);
nsIRenderingContext* rcx;
CreateRenderingContext(mRootFrame, rcx);
while (0 != mReflowCommands.Count()) {
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(0);
@ -647,7 +660,7 @@ PresShell::ProcessReflowCommands()
("PresShell::ProcessReflowCommands: begin reflow command type=%d",
type));
#endif
rc->Dispatch(*mPresContext, desiredSize, maxSize);
rc->Dispatch(*mPresContext, desiredSize, maxSize, *rcx);
NS_RELEASE(rc);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("PresShell::ProcessReflowCommands: end reflow command"));
@ -663,9 +676,53 @@ PresShell::ProcessReflowCommands()
VerifyIncrementalReflow();
}
#endif
NS_IF_RELEASE(rcx);
}
}
NS_IMETHODIMP PresShell :: CreateRenderingContext(nsIFrame *aFrame,
nsIRenderingContext *&aContext)
{
nsIWidget *widget = nsnull;
nsIView *view = nsnull;
nsPoint pt;
nsresult rv;
aFrame->GetView(view);
if (nsnull == view)
aFrame->GetOffsetFromView(pt, view);
while (nsnull != view)
{
view->GetWidget(widget);
if (nsnull != widget)
{
NS_RELEASE(widget);
break;
}
view->GetParent(view);
}
if (nsnull != view)
{
nsIDeviceContext *dx;
dx = mPresContext->GetDeviceContext();
rv = dx->CreateRenderingContext(view, aContext);
NS_RELEASE(dx);
}
else
{
rv = NS_ERROR_FAILURE;
aContext = nsnull;
}
return rv;
}
#ifdef NS_DEBUG
static char*
ContentTag(nsIContent* aContent, PRIntn aSlot)

Просмотреть файл

@ -214,10 +214,12 @@ public:
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus) = 0;
virtual PRInt32 GetPosition(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset) = 0;
NS_IMETHOD GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset) = 0;
/**

Просмотреть файл

@ -21,6 +21,7 @@
#include "nslayout.h"
#include "nsISupports.h"
#include "nsSize.h"
#include "nsIRenderingContext.h"
class nsIFrame;
class nsIPresContext;
@ -88,21 +89,24 @@ struct nsReflowState {
nsReflowReason reason; // the reason for the reflow
nsIReflowCommand* reflowCommand; // only used for incremental changes
nsSize maxSize; // the max available space in which to reflow
nsIRenderingContext* rendContext; // rendering context to use for measurement
// Note: there is no copy constructor so that the compiler can
// generate an optimal one.
// Constructs an initial reflow state (no parent reflow state) for a
// non-incremental reflow command
nsReflowState(nsIFrame* aFrame,
nsReflowReason aReason,
const nsSize& aMaxSize);
nsReflowState(nsIFrame* aFrame,
nsReflowReason aReason,
const nsSize& aMaxSize,
nsIRenderingContext* aContext);
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize);
nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize,
nsIRenderingContext* aContext);
// Construct a reflow state for the given frame, parent reflow state, and
// max size. Uses the reflow reason and reflow command from the parent's
@ -252,29 +256,35 @@ private:
// Constructs an initial reflow state (no parent reflow state) for a
// non-incremental reflow command
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsReflowReason aReason,
const nsSize& aMaxSize)
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsReflowReason aReason,
const nsSize& aMaxSize,
nsIRenderingContext* aContext)
{
NS_PRECONDITION(aReason != eReflowReason_Incremental, "unexpected reflow reason");
NS_PRECONDITION(!(aContext == nsnull), "no rendering context");
reason = aReason;
reflowCommand = nsnull;
maxSize = aMaxSize;
parentReflowState = nsnull;
frame = aFrame;
rendContext = aContext;
}
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize)
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize,
nsIRenderingContext* aContext)
{
NS_PRECONDITION(!(aContext == nsnull), "no rendering context");
reason = eReflowReason_Incremental;
reflowCommand = &aReflowCommand;
maxSize = aMaxSize;
parentReflowState = nsnull;
frame = aFrame;
rendContext = aContext;
}
// Construct a reflow state for the given frame, parent reflow state, and
@ -289,6 +299,7 @@ inline nsReflowState::nsReflowState(nsIFrame* aFrame,
maxSize = aMaxSize;
parentReflowState = &aParentReflowState;
frame = aFrame;
rendContext = aParentReflowState.rendContext;
}
// Constructs a reflow state that overrides the reflow reason of the parent
@ -303,6 +314,7 @@ inline nsReflowState::nsReflowState(nsIFrame* aFrame,
maxSize = aMaxSize;
parentReflowState = &aParentReflowState;
frame = aFrame;
rendContext = aParentReflowState.rendContext;
}
#endif /* nsIFrameReflow_h___ */

Просмотреть файл

@ -30,6 +30,7 @@ class nsIStyleSet;
class nsIViewManager;
class nsIReflowCommand;
class nsIDeviceContext;
class nsIRenderingContext;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -94,6 +95,12 @@ public:
virtual void ProcessReflowCommands() = 0;
/**
* Given a frame, cough up a rendering context suitable for use with
* the frame.
*/
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext *&aContext) = 0;
// XXX events
// XXX selection

Просмотреть файл

@ -22,6 +22,7 @@
class nsIFrame;
class nsIPresContext;
class nsIRenderingContext;
struct nsHTMLReflowMetrics;
struct nsSize;
@ -93,7 +94,8 @@ public:
*/
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsSize& aMaxSize) = 0;
const nsSize& aMaxSize,
nsIRenderingContext& aRendContext) = 0;
/**
* Get the next frame in the command processing path. Note that this removes

Просмотреть файл

@ -580,7 +580,8 @@ GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2)
nscoord
nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize)
const nsString& aString, nsSize& aSize,
nsIRenderingContext *aRendContext)
{
nsFont font(aPresContext.GetDefaultFixedFont());
aFrame->GetFont(&aPresContext, font);
@ -589,14 +590,15 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
nsIFontMetrics* fontMet;
deviceContext->GetMetricsFor(font, fontMet);
fontMet->GetWidth(aString, aSize.width);
aRendContext->SetFont(fontMet);
aRendContext->GetWidth(aString, aSize.width);
fontMet->GetHeight(aSize.height);
char char1, char2;
GetRepChars(aPresContext, char1, char2);
nscoord char1Width, char2Width;
fontMet->GetWidth(char1, char1Width);
fontMet->GetWidth(char2, char2Width);
aRendContext->GetWidth(char1, char1Width);
aRendContext->GetWidth(char2, char2Width);
NS_RELEASE(fontMet);
NS_RELEASE(deviceContext);
@ -606,7 +608,8 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
nscoord
nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize)
PRInt32 aNumChars, nsSize& aSize,
nsIRenderingContext *aRendContext)
{
nsAutoString val;
char char1, char2;
@ -618,14 +621,15 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
for (i = 1; i < aNumChars; i+=2) {
val += char2;
}
return GetTextSize(aPresContext, aFrame, val, aSize);
return GetTextSize(aPresContext, aFrame, val, aSize, aRendContext);
}
PRInt32
nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowHeight)
PRBool& aHeightExplicit, nscoord& aRowHeight,
nsIRenderingContext *aRendContext)
{
nscoord charWidth = 0;
PRInt32 numRows = ATTR_NOTSET;
@ -669,7 +673,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else {
col = (col <= 0) ? 1 : col;
charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds, aRendContext);
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
if (aSpec.mColSizeAttrInPixels) {
@ -683,17 +687,17 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) { // use width of initial value
charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds, aRendContext);
}
else if (aSpec.mColDefaultValue) { // use default value
charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds, aRendContext);
}
else if (aSpec.mColDefaultSizeInPixels) { // use default width in pixels
charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds, aRendContext);
aBounds.width = aSpec.mColDefaultSize;
}
else { // use default width in num characters
charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds, aRendContext);
}
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
@ -709,7 +713,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
PRInt32 rowAttrInt = ((rowAttr.GetUnit() == eHTMLUnit_Pixel) ? rowAttr.GetPixelValue() : rowAttr.GetIntValue());
adjSize = (rowAttrInt > 0) ? rowAttrInt : 1;
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aBounds.height = textSize.height * adjSize;
aRowHeight = textSize.height;
numRows = adjSize;
@ -724,7 +728,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else { // use default height in num lines
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aBounds.height = textSize.height * aSpec.mRowDefaultSize;
aRowHeight = textSize.height;
}
@ -734,7 +738,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
if ((0 == charWidth) || (0 == textSize.width)) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aRowHeight = textSize.height;
}

Просмотреть файл

@ -92,7 +92,8 @@ public:
static nscoord CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowSize);
PRBool& aHeightExplicit, nscoord& aRowSize,
nsIRenderingContext *aRendContext);
/**
* Respond to a gui event
@ -179,9 +180,11 @@ public:
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize);
const nsString& aString, nsSize& aSize,
nsIRenderingContext *aRendContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize);
PRInt32 aNumChars, nsSize& aSize,
nsIRenderingContext *aRendContext);
void GetWidgetSize(nsSize& aSize) const { aSize.width = mWidgetSize.width;
aSize.height = mWidgetSize.height; }

Просмотреть файл

@ -197,12 +197,14 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, textSpec, size,
widthExplicit, heightExplicit, ignore);
widthExplicit, heightExplicit, ignore,
aReflowState.rendContext);
} else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20,
PR_FALSE, nsHTMLAtoms::rows, 1);
CalculateSize(aPresContext, this, styleSize, areaSpec, size,
widthExplicit, heightExplicit, ignore);
widthExplicit, heightExplicit, ignore,
aReflowState.rendContext);
}
if (NS_FORM_TEXTAREA == type) {

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -642,15 +642,17 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
return NS_OK;
}
nsFrame * currentFrame = this;
nsIPresShell * shell = aPresContext.GetShell();
nsMouseEvent * mouseEvent = (nsMouseEvent *)aEvent;
nsFrame * currentFrame = this;
nsIPresShell * shell = aPresContext.GetShell();
nsMouseEvent * mouseEvent = (nsMouseEvent *)aEvent;
nsIRenderingContext * acx;
gDoc = shell->GetDocument();
nsISelection * selection;
gDoc->GetSelection(selection);
shell->CreateRenderingContext(this, acx);
mSelectionRange = selection->GetRange();
@ -660,7 +662,7 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
mDidDrag = PR_FALSE;
mCurrentFrame = currentFrame;
mStartPos = GetPosition(aPresContext, aEvent, currentFrame, actualOffset);
GetPosition(aPresContext, acx, aEvent, currentFrame, actualOffset, mStartPos);
// Click count is 1
nsIContent * newContent;
@ -803,6 +805,8 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
if (SELECTION_DEBUG) printf("HandleEvent::mSelectionRange %s\n", mSelectionRange->ToString());
NS_IF_RELEASE(acx);
// Force Update
ForceDrawFrame(this);
@ -830,6 +834,12 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
mDidDrag = PR_TRUE;
nsIPresShell *ps = aPresContext.GetShell();
nsIRenderingContext *acx;
ps->CreateRenderingContext(this, acx);
NS_RELEASE(ps);
//if (aFrame != nsnull) {
//printf("nsFrame::HandleDrag\n");
@ -850,20 +860,20 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (currentContent == newContent) {
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, same content.\n");
AdjustPointsInSameContent(aPresContext, aEvent);
AdjustPointsInSameContent(aPresContext, acx, aEvent);
addRangeToSelectionTrackers(currentContent, currentContent, kInsertInAddList);
} else if (gDoc->IsBefore(newContent, currentContent)) {
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is Before.\n");
resetContentTrackers();
NewContentIsBefore(aPresContext, aEvent, newContent, currentContent, this);
NewContentIsBefore(aPresContext, acx, aEvent, newContent, currentContent, this);
} else { // Content is AFTER
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is After.\n");
resetContentTrackers();
NewContentIsAfter(aPresContext, aEvent, newContent, currentContent, this);
NewContentIsAfter(aPresContext, acx, aEvent, newContent, currentContent, this);
}
mCurrentFrame = this;
@ -882,7 +892,7 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (selStartContent == selEndContent) {
if (SELECTION_DEBUG) printf("Start & End Frame are the same: \n");
AdjustPointsInSameContent(aPresContext, aEvent);
AdjustPointsInSameContent(aPresContext, acx, aEvent);
} else {
if (SELECTION_DEBUG) printf("Start & End Frame are different: \n");
@ -892,7 +902,7 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
PRInt32 newPos = -1;
PRUint32 actualOffset = 0;
newPos = GetPosition(aPresContext, aEvent, this, actualOffset);
GetPosition(aPresContext, acx, aEvent, this, actualOffset, newPos);
if (newContent == selStartContent) {
if (SELECTION_DEBUG) printf("New Content equals Start Content\n");
@ -921,6 +931,8 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
NS_IF_RELEASE(startContent);
NS_IF_RELEASE(endContent);
NS_IF_RELEASE(acx);
// Force Update
ForceDrawFrame(this);
//RefreshContentFrames(aPresContext, startContent, endContent);
@ -943,10 +955,13 @@ NS_METHOD nsFrame::HandleRelease(nsIPresContext& aPresContext,
//--------------------------------------------------------------------------
//-- GetPosition
//--------------------------------------------------------------------------
PRInt32 nsFrame::GetPosition(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset) {
NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
//PRInt32 offset;
//PRInt32 width;
@ -955,19 +970,24 @@ PRInt32 nsFrame::GetPosition(nsIPresContext& aPresContext,
//return offset;
aAcutalContentOffset = 0;
return -1;
aOffset = -1;
return NS_OK;
}
/********************************************************
* Adjusts the Starting and Ending TextPoint for a Range
*********************************************************/
void nsFrame::AdjustPointsInNewContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame) {
PRUint32 actualOffset = 0;
// Get new Cursor Poition in the new content
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
if (mStartSelectionPoint->IsAnchor()) {
if (newPos == mStartSelectionPoint->GetOffset()) {
@ -1012,11 +1032,13 @@ void nsFrame::AdjustPointsInNewContent(nsIPresContext& aPresContext,
* Adjusts the Starting and Ending TextPoint for a Range
*********************************************************/
void nsFrame::AdjustPointsInSameContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent) {
PRUint32 actualOffset = 0;
// Get new Cursor Poition in the same content
PRInt32 newPos = GetPosition(aPresContext, aEvent, mCurrentFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, mCurrentFrame, actualOffset, newPos);
//newPos += actualOffset;
if (SELECTION_DEBUG) printf("AdjustTextPointsInSameContent newPos: %d\n", newPos);
@ -1469,6 +1491,7 @@ NS_METHOD nsFrame::VerifyTree() const
* the content that the cursor is currently in
*********************************************************/
void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
@ -1509,11 +1532,12 @@ void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
// Returns the new End Point, if Start and End are on the
// same content then End Point's Cursor is set to Start's
mEndSelectionPoint->SetContent(selStartContent);
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
AdjustPointsInNewContent(aPresContext, aRendContext, aEvent, aNewFrame);
} else {
PRUint32 actualOffset = 0;
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
mSelectionRange->SetEndPoint(mEndSelectionPoint);
}
@ -1525,7 +1549,9 @@ void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
if (SELECTION_DEBUG) printf("Case #2 - (Before) New Content is NOT in selected Range. Moving Start Backward.\n");
PRUint32 actualOffset = 0;
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Create new TextPoint and move Start Point backward
mStartSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE); // position is set correctly in adjustTextPoints
@ -1601,6 +1627,7 @@ void RefreshContentFrames(nsIPresContext& aPresContext,
* the content that the cursor is currently in
*********************************************************/
void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
@ -1638,14 +1665,15 @@ void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
PRUint32 actualOffset = 0;
// [TODO] Always get nearest Text content
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Check to see if the new Content is the same as the End Point's
if (aNewContent == selEndContent) {
if (SELECTION_DEBUG) printf("New Content matches End Point\n");
mStartSelectionPoint->SetContent(aNewContent);
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
AdjustPointsInNewContent(aPresContext, aRendContext, aEvent, aNewFrame);
} else {
if (SELECTION_DEBUG) printf("New Content does NOT matches End Point\n");
@ -1660,7 +1688,8 @@ void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
// Case #2 - Adding Content (at End)
PRUint32 actualOffset = 0;
// The new content is not in the selection
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Check to see if we need to create a new SelectionPoint and add it
// or do we simply move the existing start or end point

Просмотреть файл

@ -202,10 +202,12 @@ public:
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
virtual PRInt32 GetPosition(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset);
NS_IMETHOD GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset);
//--------------------------------------------------
// Additional methods
@ -229,22 +231,26 @@ public:
protected:
virtual void NewContentIsBefore(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
nsIFrame * aNewFrame);
virtual void NewContentIsAfter(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
nsIFrame * aNewFrame);
virtual void AdjustPointsInNewContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame);
virtual void AdjustPointsInSameContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent);
PRBool DisplaySelection(nsIPresContext& aPresContext, PRBool isOkToTurnOn = PR_FALSE);

Просмотреть файл

@ -1396,7 +1396,12 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext& aPresContext, nsGUIEvent* aEvent)
nsHTMLReflowMetrics metrics(nsnull);
nsSize size;
GetSize(size);
nsReflowState state(this, eReflowReason_Initial, size);
nsIPresShell *shell;
nsIRenderingContext *acx;
shell = aPresContext.GetShell();
shell->CreateRenderingContext(this, acx);
NS_RELEASE(shell);
nsReflowState state(this, eReflowReason_Initial, size, acx);
state.reason = eReflowReason_Incremental;
nsReflowStatus status;
nsDidReflowStatus didStatus;
@ -1404,6 +1409,7 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext& aPresContext, nsGUIEvent* aEvent)
nsFramesetDrag drag(mDragger->mVertical, mDragger->mPrevNeighbor, change, this);
Reflow(aPresContext, &drag, metrics, state, status);
DidReflow(aPresContext, didStatus);
NS_IF_RELEASE(acx);
}
mLastDragPoint.x = aEvent->point.x;

Просмотреть файл

@ -136,7 +136,8 @@ void nsHTMLReflowCommand::BuildPath()
NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
const nsSize& aMaxSize,
nsIRenderingContext& aRendContext)
{
// Build the path from the target frame (index 0) to the root frame
BuildPath();
@ -155,7 +156,7 @@ NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
if (nsnull != root) {
mPath.RemoveElementAt(mPath.Count() - 1);
nsReflowState reflowState(root, *this, aMaxSize);
nsReflowState reflowState(root, *this, aMaxSize, &aRendContext);
nsIHTMLReflow* htmlReflow;
nsReflowStatus status;

Просмотреть файл

@ -52,7 +52,8 @@ public:
// nsIReflowCommand
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsSize& aMaxSize);
const nsSize& aMaxSize,
nsIRenderingContext& aRendContext);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD SetTarget(nsIFrame* aTargetFrame);

Просмотреть файл

@ -214,10 +214,12 @@ public:
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus) = 0;
virtual PRInt32 GetPosition(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset) = 0;
NS_IMETHOD GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset) = 0;
/**

Просмотреть файл

@ -98,11 +98,11 @@ protected:
PRBool IsServerImageMap();
PRIntn GetSuppress();
nscoord MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit);
nscoord MeasureString(const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit,
nsIRenderingContext& aContext);
void DisplayAltText(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
@ -459,17 +459,18 @@ ImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
// Computes the width of the specified string. aMaxWidth specifies the maximum
// width available. Once this limit is reached no more characters are measured.
// The number of characters that fit within the maximum width are returned in
// aMaxFit
// aMaxFit. NOTE: it is assumed that the fontmetrics have already been selected
// into the rendering context before this is called (for performance). MMP
nscoord
ImageFrame::MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit)
ImageFrame::MeasureString(const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit,
nsIRenderingContext& aContext)
{
nscoord totalWidth = 0;
nscoord spaceWidth;
aFontMetrics->GetWidth(' ', spaceWidth);
aContext.GetWidth(' ', spaceWidth);
aMaxFit = 0;
while (aLength > 0) {
@ -486,7 +487,7 @@ ImageFrame::MeasureString(nsIFontMetrics* aFontMetrics,
// Measure this chunk of text, and see if it fits
nscoord width;
aFontMetrics->GetWidth(aString, len, width);
aContext.GetWidth(aString, len, width);
PRBool fits = (totalWidth + width) <= aMaxWidth;
// If it fits on the line, or it's the first word we've processed then
@ -554,7 +555,7 @@ ImageFrame::DisplayAltText(nsIPresContext& aPresContext,
while ((strLen > 0) && ((y + maxDescent) < aRect.YMost())) {
// Determine how much of the text to display on this line
PRUint32 maxFit; // number of characters that fit
nscoord width = MeasureString(fm, str, strLen, aRect.width, maxFit);
nscoord width = MeasureString(str, strLen, aRect.width, maxFit, aRenderingContext);
// Display the text
aRenderingContext.DrawString(str, maxFit, aRect.x, y, 0);

Просмотреть файл

@ -78,7 +78,7 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
#define XP_IS_SPACE(_ch) \
(((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
// XXX need more of this in nsIFontMetrics.GetWidth
// XXX need more of this in nsIRenderingContext.GetWidth
#define CH_NBSP 160
// XXX use a PreTextFrame for pre-formatted text?
@ -141,10 +141,12 @@ public:
NS_IMETHOD ListTag(FILE* out) const;
virtual PRInt32 GetPosition(nsIPresContext& aCX,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset);
NS_IMETHOD GetPosition(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset);
// nsIInlineReflow
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout,
@ -1009,7 +1011,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
if (si.mEmptySelection) {
aRenderingContext.DrawString(text, textLength, dx, dy, mRect.width);
PaintTextDecorations(aRenderingContext, aDecorations, dx, dy, mRect.width);
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
@ -1019,7 +1021,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
if (0 != si.mStartOffset) {
// Render first (unselected) section
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.DrawString(text, si.mStartOffset,
x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1028,7 +1030,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
PRInt32 secondLen = si.mEndOffset - si.mStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
fm->GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
aRenderingContext.GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aSelectionBGColor);
@ -1044,7 +1046,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
PRInt32 thirdLen = textLength - si.mEndOffset;
// Render third (unselected) section
fm->GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.DrawString(text + si.mEndOffset,
thirdLen, x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1104,7 +1106,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
if (si.mEmptySelection) {
aRenderingContext.DrawString(text, textLength, dx, dy, mRect.width);
PaintTextDecorations(aRenderingContext, aDecorations, dx, dy, mRect.width);
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
@ -1114,7 +1116,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
if (0 != si.mStartOffset) {
// Render first (unselected) section
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.DrawString(text, si.mStartOffset,
x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1123,7 +1125,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
PRInt32 secondLen = si.mEndOffset - si.mStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
fm->GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
aRenderingContext.GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aSelectionBGColor);
@ -1139,7 +1141,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
PRInt32 thirdLen = textLength - si.mEndOffset;
// Render third (unselected) section
fm->GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.DrawString(text + si.mEndOffset,
thirdLen, x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1182,7 +1184,7 @@ TextFrame::FindTextRuns(nsLineLayout& aLineLayout,
// aTextWidth returns the (in twips) the length of the text that falls before the cursor
// aIndex contains the index of the text where the cursor falls
static PRBool
BinarySearchForPosition(nsIFontMetrics* aFM,
BinarySearchForPosition(nsIRenderingContext* acx,
PRUnichar* aText,
PRInt32 aBaseWidth,
PRInt32 aBaseInx,
@ -1200,7 +1202,7 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
PRInt32 inx = aStartInx + (range / 2);
PRInt32 textWidth;
aFM->GetWidth(aText, inx, textWidth);
acx->GetWidth(aText, inx, textWidth);
PRInt32 fullWidth = aBaseWidth + textWidth;
if (fullWidth == aCursorPos) {
@ -1208,13 +1210,13 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
return PR_TRUE;
} else if (aCursorPos < fullWidth) {
aTextWidth = aBaseWidth;
if (BinarySearchForPosition(aFM, aText, aBaseWidth, aBaseInx, aStartInx, inx, aCursorPos, aIndex, aTextWidth)) {
if (BinarySearchForPosition(acx, aText, aBaseWidth, aBaseInx, aStartInx, inx, aCursorPos, aIndex, aTextWidth)) {
return PR_TRUE;
}
} else {
aTextWidth = fullWidth;
PRInt32 end = aEndInx - inx;
if (BinarySearchForPosition(aFM, aText+inx, fullWidth, aBaseInx+inx, 0, end, aCursorPos, aIndex, aTextWidth)) {
if (BinarySearchForPosition(acx, aText+inx, fullWidth, aBaseInx+inx, 0, end, aCursorPos, aIndex, aTextWidth)) {
return PR_TRUE;
}
}
@ -1227,11 +1229,13 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
// un-compressed text, selection is based on the un-compressed text, the visual
// display of selection is based on the compressed text.
//---------------------------------------------------------------------------
PRInt32
NS_IMETHODIMP
TextFrame::GetPosition(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame* aNewFrame,
PRUint32& aAcutalContentOffset)
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
const PRInt16 kNumIndices = 512;
@ -1259,10 +1263,12 @@ TextFrame::GetPosition(nsIPresContext& aCX,
PRInt32 index;
PRInt32 textWidth;
PRBool found = BinarySearchForPosition(fm, text, 0, 0, 0, PRInt32(textLength), PRInt32(aEvent->point.x), index, textWidth);
aRendContext->SetFont(fm);
PRBool found = BinarySearchForPosition(aRendContext, text, 0, 0, 0, PRInt32(textLength), PRInt32(aEvent->point.x), index, textWidth);
if (found) {
PRInt32 charWidth;
fm->GetWidth(text[index], charWidth);
aRendContext->GetWidth(text[index], charWidth);
charWidth /= 2;
if (PRInt32(aEvent->point.x) > textWidth+charWidth) {
@ -1290,7 +1296,9 @@ TextFrame::GetPosition(nsIPresContext& aCX,
}
aAcutalContentOffset = ((TextFrame *)aNewFrame)->mContentOffset;
return offset;
aOffset = offset;
return NS_OK;
}
NS_IMETHODIMP
@ -1363,7 +1371,8 @@ TextFrame::ReflowNormal(nsLineLayout& aLineLayout,
nsIFontMetrics* fm = aLineLayout.mPresContext.GetMetricsFor(aFont.mFont);
PRInt32 spaceWidth;
fm->GetWidth(' ', spaceWidth);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(' ', spaceWidth);
PRBool wrapping = PR_TRUE;
if (NS_STYLE_WHITESPACE_NORMAL != aTextStyle.mWhiteSpace) {
wrapping = PR_FALSE;
@ -1435,7 +1444,7 @@ TextFrame::ReflowNormal(nsLineLayout& aLineLayout,
}
break;
}
fm->GetWidth(wordStart, PRUint32(cp - wordStart), width);
aReflowState.rendContext->GetWidth(wordStart, PRUint32(cp - wordStart), width);
skipWhitespace = PR_FALSE;
isWhitespace = PR_FALSE;
}
@ -1543,7 +1552,8 @@ TextFrame::ReflowPre(nsLineLayout& aLineLayout,
PRUint16 col = aLineLayout.GetColumn();
mColumn = col;
nscoord spaceWidth;
fm->GetWidth(' ', spaceWidth);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(' ', spaceWidth);
// XXX change this to measure a line at a time
while (cp < end) {
@ -1569,11 +1579,11 @@ TextFrame::ReflowPre(nsLineLayout& aLineLayout,
}
if (ch < 256) {
nscoord charWidth;
fm->GetWidth(ch, charWidth);
aReflowState.rendContext->GetWidth(ch, charWidth);
width += charWidth;
} else {
nscoord charWidth;
fm->GetWidth(ch, charWidth);
aReflowState.rendContext->GetWidth(ch, charWidth);
width += charWidth;
hasMultibyte = PR_TRUE;
}

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -562,8 +562,8 @@ BulletFrame::Paint(nsIPresContext& aCX,
case NS_STYLE_LIST_STYLE_UPPER_ALPHA:
fm = aCX.GetMetricsFor(myFont->mFont);
GetListItemText(aCX, *myList, text);
aRenderingContext.SetFont(myFont->mFont);
fm->GetWidth(text, width);
aRenderingContext.SetFont(fm);
aRenderingContext.GetWidth(text, width);
aRenderingContext.DrawString(text, mPadding.left, mPadding.top, width);
NS_RELEASE(fm);
break;
@ -819,8 +819,9 @@ BulletFrame::GetDesiredSize(nsIPresContext* aCX,
// between the list item and the content that follows.
mPadding.right = aMetrics.height / 2; // From old layout engine
}
fm->GetWidth(text, aMetrics.width);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(text, aMetrics.width);
aMetrics.width += mPadding.right;
fm->GetMaxAscent(aMetrics.ascent);
fm->GetMaxDescent(aMetrics.descent);

Просмотреть файл

@ -642,15 +642,17 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
return NS_OK;
}
nsFrame * currentFrame = this;
nsIPresShell * shell = aPresContext.GetShell();
nsMouseEvent * mouseEvent = (nsMouseEvent *)aEvent;
nsFrame * currentFrame = this;
nsIPresShell * shell = aPresContext.GetShell();
nsMouseEvent * mouseEvent = (nsMouseEvent *)aEvent;
nsIRenderingContext * acx;
gDoc = shell->GetDocument();
nsISelection * selection;
gDoc->GetSelection(selection);
shell->CreateRenderingContext(this, acx);
mSelectionRange = selection->GetRange();
@ -660,7 +662,7 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
mDidDrag = PR_FALSE;
mCurrentFrame = currentFrame;
mStartPos = GetPosition(aPresContext, aEvent, currentFrame, actualOffset);
GetPosition(aPresContext, acx, aEvent, currentFrame, actualOffset, mStartPos);
// Click count is 1
nsIContent * newContent;
@ -803,6 +805,8 @@ NS_METHOD nsFrame::HandlePress(nsIPresContext& aPresContext,
if (SELECTION_DEBUG) printf("HandleEvent::mSelectionRange %s\n", mSelectionRange->ToString());
NS_IF_RELEASE(acx);
// Force Update
ForceDrawFrame(this);
@ -830,6 +834,12 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
mDidDrag = PR_TRUE;
nsIPresShell *ps = aPresContext.GetShell();
nsIRenderingContext *acx;
ps->CreateRenderingContext(this, acx);
NS_RELEASE(ps);
//if (aFrame != nsnull) {
//printf("nsFrame::HandleDrag\n");
@ -850,20 +860,20 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (currentContent == newContent) {
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, same content.\n");
AdjustPointsInSameContent(aPresContext, aEvent);
AdjustPointsInSameContent(aPresContext, acx, aEvent);
addRangeToSelectionTrackers(currentContent, currentContent, kInsertInAddList);
} else if (gDoc->IsBefore(newContent, currentContent)) {
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is Before.\n");
resetContentTrackers();
NewContentIsBefore(aPresContext, aEvent, newContent, currentContent, this);
NewContentIsBefore(aPresContext, acx, aEvent, newContent, currentContent, this);
} else { // Content is AFTER
if (SELECTION_DEBUG) printf("HandleDrag::New Frame, is After.\n");
resetContentTrackers();
NewContentIsAfter(aPresContext, aEvent, newContent, currentContent, this);
NewContentIsAfter(aPresContext, acx, aEvent, newContent, currentContent, this);
}
mCurrentFrame = this;
@ -882,7 +892,7 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (selStartContent == selEndContent) {
if (SELECTION_DEBUG) printf("Start & End Frame are the same: \n");
AdjustPointsInSameContent(aPresContext, aEvent);
AdjustPointsInSameContent(aPresContext, acx, aEvent);
} else {
if (SELECTION_DEBUG) printf("Start & End Frame are different: \n");
@ -892,7 +902,7 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
PRInt32 newPos = -1;
PRUint32 actualOffset = 0;
newPos = GetPosition(aPresContext, aEvent, this, actualOffset);
GetPosition(aPresContext, acx, aEvent, this, actualOffset, newPos);
if (newContent == selStartContent) {
if (SELECTION_DEBUG) printf("New Content equals Start Content\n");
@ -921,6 +931,8 @@ NS_METHOD nsFrame::HandleDrag(nsIPresContext& aPresContext,
NS_IF_RELEASE(startContent);
NS_IF_RELEASE(endContent);
NS_IF_RELEASE(acx);
// Force Update
ForceDrawFrame(this);
//RefreshContentFrames(aPresContext, startContent, endContent);
@ -943,10 +955,13 @@ NS_METHOD nsFrame::HandleRelease(nsIPresContext& aPresContext,
//--------------------------------------------------------------------------
//-- GetPosition
//--------------------------------------------------------------------------
PRInt32 nsFrame::GetPosition(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset) {
NS_IMETHODIMP nsFrame::GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
//PRInt32 offset;
//PRInt32 width;
@ -955,19 +970,24 @@ PRInt32 nsFrame::GetPosition(nsIPresContext& aPresContext,
//return offset;
aAcutalContentOffset = 0;
return -1;
aOffset = -1;
return NS_OK;
}
/********************************************************
* Adjusts the Starting and Ending TextPoint for a Range
*********************************************************/
void nsFrame::AdjustPointsInNewContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame) {
PRUint32 actualOffset = 0;
// Get new Cursor Poition in the new content
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
if (mStartSelectionPoint->IsAnchor()) {
if (newPos == mStartSelectionPoint->GetOffset()) {
@ -1012,11 +1032,13 @@ void nsFrame::AdjustPointsInNewContent(nsIPresContext& aPresContext,
* Adjusts the Starting and Ending TextPoint for a Range
*********************************************************/
void nsFrame::AdjustPointsInSameContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent) {
PRUint32 actualOffset = 0;
// Get new Cursor Poition in the same content
PRInt32 newPos = GetPosition(aPresContext, aEvent, mCurrentFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, mCurrentFrame, actualOffset, newPos);
//newPos += actualOffset;
if (SELECTION_DEBUG) printf("AdjustTextPointsInSameContent newPos: %d\n", newPos);
@ -1469,6 +1491,7 @@ NS_METHOD nsFrame::VerifyTree() const
* the content that the cursor is currently in
*********************************************************/
void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
@ -1509,11 +1532,12 @@ void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
// Returns the new End Point, if Start and End are on the
// same content then End Point's Cursor is set to Start's
mEndSelectionPoint->SetContent(selStartContent);
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
AdjustPointsInNewContent(aPresContext, aRendContext, aEvent, aNewFrame);
} else {
PRUint32 actualOffset = 0;
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
mEndSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE);
mSelectionRange->SetEndPoint(mEndSelectionPoint);
}
@ -1525,7 +1549,9 @@ void nsFrame::NewContentIsBefore(nsIPresContext& aPresContext,
if (SELECTION_DEBUG) printf("Case #2 - (Before) New Content is NOT in selected Range. Moving Start Backward.\n");
PRUint32 actualOffset = 0;
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Create new TextPoint and move Start Point backward
mStartSelectionPoint->SetPoint(aNewContent, newPos, PR_FALSE); // position is set correctly in adjustTextPoints
@ -1601,6 +1627,7 @@ void RefreshContentFrames(nsIPresContext& aPresContext,
* the content that the cursor is currently in
*********************************************************/
void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
@ -1638,14 +1665,15 @@ void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
PRUint32 actualOffset = 0;
// [TODO] Always get nearest Text content
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Check to see if the new Content is the same as the End Point's
if (aNewContent == selEndContent) {
if (SELECTION_DEBUG) printf("New Content matches End Point\n");
mStartSelectionPoint->SetContent(aNewContent);
AdjustPointsInNewContent(aPresContext, aEvent, aNewFrame);
AdjustPointsInNewContent(aPresContext, aRendContext, aEvent, aNewFrame);
} else {
if (SELECTION_DEBUG) printf("New Content does NOT matches End Point\n");
@ -1660,7 +1688,8 @@ void nsFrame::NewContentIsAfter(nsIPresContext& aPresContext,
// Case #2 - Adding Content (at End)
PRUint32 actualOffset = 0;
// The new content is not in the selection
PRInt32 newPos = GetPosition(aPresContext, aEvent, aNewFrame, actualOffset);
PRInt32 newPos;
GetPosition(aPresContext, aRendContext, aEvent, aNewFrame, actualOffset, newPos);
// Check to see if we need to create a new SelectionPoint and add it
// or do we simply move the existing start or end point

Просмотреть файл

@ -202,10 +202,12 @@ public:
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
virtual PRInt32 GetPosition(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset);
NS_IMETHOD GetPosition(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset);
//--------------------------------------------------
// Additional methods
@ -229,22 +231,26 @@ public:
protected:
virtual void NewContentIsBefore(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
nsIFrame * aNewFrame);
virtual void NewContentIsAfter(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIContent * aNewContent,
nsIContent * aCurrentContent,
nsIFrame * aNewFrame);
virtual void AdjustPointsInNewContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent,
nsIFrame * aNewFrame);
virtual void AdjustPointsInSameContent(nsIPresContext& aPresContext,
nsIRenderingContext * aRendContext,
nsGUIEvent * aEvent);
PRBool DisplaySelection(nsIPresContext& aPresContext, PRBool isOkToTurnOn = PR_FALSE);

Просмотреть файл

@ -0,0 +1,935 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsHTMLParts.h"
#include "nsHTMLImage.h"
#include "nsHTMLTagContent.h"
#include "nsString.h"
#include "nsLeafFrame.h"
#include "nsIPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIFrameImageLoader.h"
#include "nsIPresShell.h"
#include "nsHTMLIIDs.h"
#include "nsIImage.h"
#include "nsIWidget.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLAttributes.h"
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIImageMap.h"
#include "nsILinkHandler.h"
#include "nsIURL.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsCSSLayout.h"
#include "nsHTMLBase.h"
#include "prprf.h"
#include "nsISizeOfHandler.h"
#include "nsIFontMetrics.h"
#include "nsCSSRendering.h"
#include "nsIDOMHTMLImageElement.h"
#define BROKEN_IMAGE_URL "resource:/res/html/broken-image.gif"
#define XP_IS_SPACE(_ch) \
(((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
// XXX image frame layout can be 100% decoupled from the content
// object; all it needs are attributes to work properly
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
#if 0
#define nsHTMLImageSuper nsHTMLTagContent
class nsHTMLImage : public nsHTMLImageSuper, public nsIDOMHTMLImageElement {
public:
nsHTMLImage(nsIAtom* aTag);
NS_DECL_ISUPPORTS
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
NS_IMETHOD CreateFrame(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aResult);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD MapAttributesInto(nsIStyleContext* aContext,
nsIPresContext* aPresContext);
NS_IMETHOD AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const;
NS_FORWARD_IDOMNODE(nsHTMLImageSuper::)
NS_FORWARD_IDOMELEMENT(nsHTMLImageSuper::)
NS_FORWARD_IDOMHTMLELEMENT(nsHTMLImageSuper::)
NS_DECL_IDOMHTMLIMAGEELEMENT
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
protected:
virtual ~nsHTMLImage();
void SizeOfWithoutThis(nsISizeOfHandler* aHandler) const;
void TriggerReflow();
};
#endif
#define ImageFrameSuper nsLeafFrame
class ImageFrame : public ImageFrameSuper {
public:
ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_METHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD GetCursorAndContentAt(nsIPresContext& aPresContext,
const nsPoint& aPoint,
nsIFrame** aFrame,
nsIContent** aContent,
PRInt32& aCursor);
NS_IMETHOD ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent);
protected:
virtual ~ImageFrame();
void SizeOfWithoutThis(nsISizeOfHandler* aHandler) const;
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize);
nsIImageMap* GetImageMap();
nsHTMLImageLoader mImageLoader;
nsIImageMap* mImageMap;
PRBool mSizeFrozen;
void TriggerLink(nsIPresContext& aPresContext,
const nsString& aURLSpec,
const nsString& aTargetSpec,
PRBool aClick);
PRBool IsServerImageMap();
PRIntn GetSuppress();
nscoord MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit);
void DisplayAltText(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsString& aAltText,
const nsRect& aRect);
};
// Value's for mSuppress
#define SUPPRESS_UNSET 0
#define DONT_SUPPRESS 1
#define SUPPRESS 2
#define DEFAULT_SUPPRESS 3
// Default alignment value (so we can tell an unset value from a set value)
#define ALIGN_UNSET PRUint8(-1)
//----------------------------------------------------------------------
nsHTMLImageLoader::nsHTMLImageLoader()
{
mImageLoader = nsnull;
mLoadImageFailed = PR_FALSE;
mLoadBrokenImageFailed = PR_FALSE;
mURLSpec = nsnull;
mBaseHREF = nsnull;
}
nsHTMLImageLoader::~nsHTMLImageLoader()
{
NS_IF_RELEASE(mImageLoader);
if (nsnull != mURLSpec) {
delete mURLSpec;
}
if (nsnull != mBaseHREF) {
delete mBaseHREF;
}
}
void
nsHTMLImageLoader::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
if (!aHandler->HaveSeen(mURLSpec)) {
mURLSpec->SizeOf(aHandler);
}
if (!aHandler->HaveSeen(mImageLoader)) {
mImageLoader->SizeOf(aHandler);
}
}
nsIImage*
nsHTMLImageLoader::GetImage()
{
nsIImage* image = nsnull;
if (nsnull != mImageLoader) {
mImageLoader->GetImage(image);
}
return image;
}
nsresult
nsHTMLImageLoader::SetURL(const nsString& aURLSpec)
{
if (nsnull != mURLSpec) {
delete mURLSpec;
}
mURLSpec = new nsString(aURLSpec);
if (nsnull == mURLSpec) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsresult
nsHTMLImageLoader::SetBaseHREF(const nsString& aBaseHREF)
{
if (nsnull != mBaseHREF) {
delete mBaseHREF;
}
mBaseHREF = new nsString(aBaseHREF);
if (nsnull == mBaseHREF) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsresult
nsHTMLImageLoader::StartLoadImage(nsIPresContext* aPresContext,
nsIFrame* aForFrame,
PRBool aNeedSizeUpdate,
PRIntn& aLoadStatus)
{
aLoadStatus = NS_IMAGE_LOAD_STATUS_NONE;
// Get absolute url the first time through
nsresult rv;
nsAutoString src;
if (mLoadImageFailed || (nsnull == mURLSpec)) {
src.Append(BROKEN_IMAGE_URL);
} else {
nsAutoString baseURL;
if (nsnull != mBaseHREF) {
baseURL = *mBaseHREF;
}
// Get documentURL
nsIPresShell* shell;
shell = aPresContext->GetShell();
nsIDocument* doc = shell->GetDocument();
nsIURL* docURL = doc->GetDocumentURL();
// Create an absolute URL
nsresult rv = NS_MakeAbsoluteURL(docURL, baseURL, *mURLSpec, src);
// Release references
NS_RELEASE(shell);
NS_RELEASE(docURL);
NS_RELEASE(doc);
if (NS_OK != rv) {
return rv;
}
}
if (nsnull == mImageLoader) {
// Start image loading. Note that we don't specify a background color
// so transparent images are always rendered using a transparency mask
rv = aPresContext->StartLoadImage(src, nsnull, aForFrame, aNeedSizeUpdate,
mImageLoader);
if (NS_OK != rv) {
return rv;
}
}
// Examine current image load status
mImageLoader->GetImageLoadStatus(aLoadStatus);
if (0 != (aLoadStatus & NS_IMAGE_LOAD_STATUS_ERROR)) {
NS_RELEASE(mImageLoader);
if (mLoadImageFailed) {
// We are doomed. Loading the broken image has just failed.
mLoadBrokenImageFailed = PR_TRUE;
}
else {
// Try again, this time using the broke-image url
mLoadImageFailed = PR_TRUE;
return StartLoadImage(aPresContext, aForFrame, aNeedSizeUpdate, aLoadStatus);
}
}
return NS_OK;
}
void
nsHTMLImageLoader::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize)
{
nsSize styleSize;
PRIntn ss = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, styleSize);
PRIntn loadStatus;
if (0 != ss) {
if (NS_SIZE_HAS_BOTH == ss) {
StartLoadImage(aPresContext, aReflowState.frame, PR_FALSE, loadStatus);
aDesiredSize.width = styleSize.width;
aDesiredSize.height = styleSize.height;
}
else {
// Preserve aspect ratio of image with unbound dimension.
StartLoadImage(aPresContext, aReflowState.frame, PR_TRUE, loadStatus);
if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) ||
(nsnull == mImageLoader)) {
// Provide a dummy size for now; later on when the image size
// shows up we will reflow to the new size.
aDesiredSize.width = 1;
aDesiredSize.height = 1;
}
else {
float p2t = aPresContext->GetPixelsToTwips();
nsSize imageSize;
mImageLoader->GetSize(imageSize);
float imageWidth = imageSize.width * p2t;
float imageHeight = imageSize.height * p2t;
if (0.0f != imageHeight) {
if (0 != (ss & NS_SIZE_HAS_WIDTH)) {
// We have a width, and an auto height. Compute height
// from width.
aDesiredSize.width = styleSize.width;
aDesiredSize.height =
(nscoord)NSToIntRound(styleSize.width * imageHeight / imageWidth);
}
else {
// We have a height and an auto width. Compute width from
// height.
aDesiredSize.height = styleSize.height;
aDesiredSize.width =
(nscoord)NSToIntRound(styleSize.height * imageWidth / imageHeight);
}
}
else {
// Screwy image
aDesiredSize.width = 1;
aDesiredSize.height = 1;
}
}
}
}
else {
StartLoadImage(aPresContext, aReflowState.frame, PR_TRUE, loadStatus);
if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) ||
(nsnull == mImageLoader)) {
// Provide a dummy size for now; later on when the image size
// shows up we will reflow to the new size.
aDesiredSize.width = 1;
aDesiredSize.height = 1;
// printf ("in image loader, dummy size of 1 returned\n");
} else {
float p2t = aPresContext->GetPixelsToTwips();
nsSize imageSize;
mImageLoader->GetSize(imageSize);
aDesiredSize.width = NSIntPixelsToTwips(imageSize.width, p2t);
aDesiredSize.height = NSIntPixelsToTwips(imageSize.height, p2t);
// printf ("in image loader, real size of %d returned\n", aDesiredSize.width);
}
}
}
//----------------------------------------------------------------------
nsresult
NS_NewImageFrame(nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame*& aResult)
{
ImageFrame* frame = new ImageFrame(aContent, aParentFrame);
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
aResult = frame;
return NS_OK;
}
ImageFrame::ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsLeafFrame(aContent, aParentFrame)
{
}
ImageFrame::~ImageFrame()
{
}
NS_METHOD
ImageFrame::DeleteFrame(nsIPresContext& aPresContext)
{
NS_IF_RELEASE(mImageMap);
// Release image loader first so that it's refcnt can go to zero
mImageLoader.DestroyLoader();
return nsLeafFrame::DeleteFrame(aPresContext);
}
NS_IMETHODIMP
ImageFrame::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
ImageFrame::SizeOfWithoutThis(aHandler);
return NS_OK;
}
void
ImageFrame::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
{
ImageFrameSuper::SizeOfWithoutThis(aHandler);
mImageLoader.SizeOf(aHandler);
if (!aHandler->HaveSeen(mImageMap)) {
mImageMap->SizeOf(aHandler);
}
}
void
ImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize)
{
if (mSizeFrozen) {
aDesiredSize.width = mRect.width;
aDesiredSize.height = mRect.height;
}
else {
// XXX Don't create a view, because we want whatever is below the image
// to show through while the image is loading; Likewise for transparent
// images and broken images
//
// What we really want to do is to create a view, and indicate that the
// view has a transparent content area. Do this while it's loading,
// and then when it's fully loaded mark the view as opaque if the
// image is opaque.
//
// We can't use that approach yet, because currently the compositor doesn't
// support transparent views...
//#if 0
nsHTMLBase::CreateViewForFrame(aPresContext, this, mStyleContext, PR_TRUE);
//#endif
// Setup url before starting the image load
nsAutoString src, base;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("SRC", src)) {
mImageLoader.SetURL(src);
if (NS_CONTENT_ATTR_HAS_VALUE ==
mContent->GetAttribute(NS_HTML_BASE_HREF, base)) {
mImageLoader.SetBaseHREF(base);
}
}
mImageLoader.GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
}
}
// Computes the width of the specified string. aMaxWidth specifies the maximum
// width available. Once this limit is reached no more characters are measured.
// The number of characters that fit within the maximum width are returned in
// aMaxFit
nscoord
ImageFrame::MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit)
{
nscoord totalWidth = 0;
nscoord spaceWidth;
aFontMetrics->GetWidth(' ', spaceWidth);
aMaxFit = 0;
while (aLength > 0) {
// Find the next place we can line break
PRUint32 len = aLength;
PRBool trailingSpace = PR_FALSE;
for (PRInt32 i = 0; i < aLength; i++) {
if (XP_IS_SPACE(aString[i]) && (i > 0)) {
len = i; // don't include the space when measuring
trailingSpace = PR_TRUE;
break;
}
}
// Measure this chunk of text, and see if it fits
nscoord width;
aFontMetrics->GetWidth(aString, len, width);
PRBool fits = (totalWidth + width) <= aMaxWidth;
// If it fits on the line, or it's the first word we've processed then
// include it
if (fits || (0 == totalWidth)) {
// New piece fits
totalWidth += width;
// If there's a trailing space then see if it fits as well
if (trailingSpace) {
if ((totalWidth + spaceWidth) <= aMaxWidth) {
totalWidth += spaceWidth;
} else {
// Space won't fit. Leave it at the end but don't include it in
// the width
fits = PR_FALSE;
}
len++;
}
aMaxFit += len;
aString += len;
aLength -= len;
}
if (!fits) {
break;
}
}
return totalWidth;
}
// Formats the alt-text to fit within the specified rectangle. Breaks lines
// between words if a word would extend past the edge of the rectangle
void
ImageFrame::DisplayAltText(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsString& aAltText,
const nsRect& aRect)
{
// Clip so we don't render outside of the rect.
aRenderingContext.PushState();
aRenderingContext.SetClipRect(aRect, nsClipCombine_kIntersect);
const nsStyleColor* color =
(const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleFont* font =
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
// Set font and color
aRenderingContext.SetColor(color->mColor);
aRenderingContext.SetFont(font->mFont);
// Format the text to display within the formatting rect
nsIFontMetrics* fm = aRenderingContext.GetFontMetrics();
nscoord maxDescent, height;
fm->GetMaxDescent(maxDescent);
fm->GetHeight(height);
// XXX It would be nice if there was a way to have the font metrics tell
// use where to break the text given a maximum width. At a minimum we need
// to be able to get the break character...
const PRUnichar* str = aAltText.GetUnicode();
PRInt32 strLen = aAltText.Length();
nscoord y = aRect.y;
while ((strLen > 0) && ((y + maxDescent) < aRect.YMost())) {
// Determine how much of the text to display on this line
PRUint32 maxFit; // number of characters that fit
nscoord width = MeasureString(fm, str, strLen, aRect.width, maxFit);
// Display the text
aRenderingContext.DrawString(str, maxFit, aRect.x, y, 0);
// Move to the next line
str += maxFit;
strLen -= maxFit;
y += height;
}
NS_RELEASE(fm);
aRenderingContext.PopState();
}
struct nsRecessedBorder : public nsStyleSpacing {
nsRecessedBorder(nscoord aBorderWidth)
: nsStyleSpacing()
{
nsStyleCoord styleCoord(aBorderWidth);
mBorder.SetLeft(styleCoord);
mBorder.SetTop(styleCoord);
mBorder.SetRight(styleCoord);
mBorder.SetBottom(styleCoord);
mBorderStyle[0] = NS_STYLE_BORDER_STYLE_INSET;
mBorderStyle[1] = NS_STYLE_BORDER_STYLE_INSET;
mBorderStyle[2] = NS_STYLE_BORDER_STYLE_INSET;
mBorderStyle[3] = NS_STYLE_BORDER_STYLE_INSET;
mBorderColor[0] = 0;
mBorderColor[1] = 0;
mBorderColor[2] = 0;
mBorderColor[3] = 0;
mHasCachedMargin = mHasCachedPadding = mHasCachedBorder = PR_FALSE;
}
};
NS_METHOD
ImageFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
if ((0 == mRect.width) || (0 == mRect.height)) {
// Do not render when given a zero area. This avoids some useless
// scaling work while we wait for our image dimensions to arrive
// asynchronously.
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
// First paint background and borders
nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
nsIImage* image = mImageLoader.GetImage();
if (nsnull == image) {
// No image yet. Draw the icon that indicates we're loading, and display
// the alt-text
nsAutoString altText;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("ALT", altText)) {
// Display a recessed one-pixel border in the inner area
nsRect inner;
GetInnerArea(&aPresContext, inner);
float p2t = aPresContext.GetPixelsToTwips();
nsRecessedBorder recessedBorder(NSIntPixelsToTwips(1, p2t));
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, inner,
inner, recessedBorder, 0);
inner.Deflate(NSIntPixelsToTwips(1, p2t), NSIntPixelsToTwips(1, p2t));
// Leave a 8 pixel left/right padding, and a 5 pixel top/bottom padding
inner.Deflate(NSIntPixelsToTwips(8, p2t), NSIntPixelsToTwips(5, p2t));
// If there's room, then display the alt-text
if (!inner.IsEmpty()) {
DisplayAltText(aPresContext, aRenderingContext, altText, inner);
}
}
return NS_OK;
}
// Now render the image into our inner area (the area without the
// borders and padding)
nsRect inner;
GetInnerArea(&aPresContext, inner);
if (mImageLoader.GetLoadImageFailed()) {
float p2t = aPresContext.GetPixelsToTwips();
inner.width = NSIntPixelsToTwips(image->GetWidth(), p2t);
inner.height = NSIntPixelsToTwips(image->GetHeight(), p2t);
}
aRenderingContext.DrawImage(image, inner);
if (GetShowFrameBorders()) {
nsIImageMap* map = GetImageMap();
if (nsnull != map) {
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
aRenderingContext.PushState();
aRenderingContext.Translate(inner.x, inner.y);
map->Draw(aPresContext, aRenderingContext);
aRenderingContext.PopState();
}
}
}
return NS_OK;
}
nsIImageMap*
ImageFrame::GetImageMap()
{
if (nsnull == mImageMap) {
nsAutoString usemap;
mContent->GetAttribute("usemap", usemap);
if (0 == usemap.Length()) {
return nsnull;
}
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull == doc) {
return nsnull;
}
if (usemap.First() == '#') {
usemap.Cut(0, 1);
}
nsIHTMLDocument* hdoc;
nsresult rv = doc->QueryInterface(kIHTMLDocumentIID, (void**)&hdoc);
NS_RELEASE(doc);
if (NS_OK == rv) {
nsIImageMap* map;
rv = hdoc->GetImageMap(usemap, &map);
NS_RELEASE(hdoc);
if (NS_OK == rv) {
mImageMap = map;
}
}
}
NS_IF_ADDREF(mImageMap);
return mImageMap;
}
void
ImageFrame::TriggerLink(nsIPresContext& aPresContext,
const nsString& aURLSpec,
const nsString& aTargetSpec,
PRBool aClick)
{
nsILinkHandler* handler = nsnull;
aPresContext.GetLinkHandler(&handler);
if (nsnull != handler) {
if (aClick) {
handler->OnLinkClick(this, aURLSpec, aTargetSpec);
}
else {
handler->OnOverLink(this, aURLSpec, aTargetSpec);
}
}
}
PRBool
ImageFrame::IsServerImageMap()
{
nsAutoString ismap;
return NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("ismap", ismap);
}
PRIntn
ImageFrame::GetSuppress()
{
nsAutoString s;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("suppress", s)) {
if (s.EqualsIgnoreCase("true")) {
return SUPPRESS;
} else if (s.EqualsIgnoreCase("false")) {
return DONT_SUPPRESS;
}
}
return DEFAULT_SUPPRESS;
}
// XXX what should clicks on transparent pixels do?
NS_METHOD
ImageFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsIImageMap* map;
aEventStatus = nsEventStatus_eIgnore;
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MOVE:
map = GetImageMap();
if ((nsnull != map) || IsServerImageMap()) {
nsIURL* docURL = nsnull;
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull != doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
}
// Ask map if the x,y coordinates are in a clickable area
float t2p = aPresContext.GetTwipsToPixels();
nsAutoString absURL, target, altText;
PRBool suppress;
if (nsnull != map) {
// Subtract out border and padding here so that we are looking
// at the right coordinates. Hit detection against area tags
// is done after the mouse wanders over the image, not over
// the image's borders.
nsRect inner;
GetInnerArea(&aPresContext, inner);
PRInt32 x = NSTwipsToIntPixels((aEvent->point.x - inner.x), t2p);
PRInt32 y = NSTwipsToIntPixels((aEvent->point.y - inner.y), t2p);
nsresult r = map->IsInside(x, y, docURL, absURL, target, altText,
&suppress);
NS_IF_RELEASE(docURL);
NS_RELEASE(map);
if (NS_OK == r) {
// We hit a clickable area. Time to go somewhere...
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
aEventStatus = nsEventStatus_eConsumeNoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
}
else {
suppress = GetSuppress();
nsAutoString baseURL;
mContent->GetAttribute(NS_HTML_BASE_HREF, baseURL);
nsAutoString src;
mContent->GetAttribute("src", src);
NS_MakeAbsoluteURL(docURL, baseURL, src, absURL);
// Note: We don't subtract out the border/padding here to remain
// compatible with navigator. [ick]
PRInt32 x = NSTwipsToIntPixels(aEvent->point.x, t2p);
PRInt32 y = NSTwipsToIntPixels(aEvent->point.y, t2p);
char cbuf[50];
PR_snprintf(cbuf, sizeof(cbuf), "?%d,%d", x, y);
absURL.Append(cbuf);
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
aEventStatus = nsEventStatus_eConsumeNoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
break;
}
// FALL THROUGH
default:
// Let default event handler deal with it
return nsLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
}
NS_METHOD
ImageFrame::GetCursorAndContentAt(nsIPresContext& aPresContext,
const nsPoint& aPoint,
nsIFrame** aFrame,
nsIContent** aContent,
PRInt32& aCursor)
{
// The default cursor is to have no cursor
aCursor = NS_STYLE_CURSOR_INHERIT;
*aContent = mContent;
const nsStyleColor* styleColor = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
if (styleColor->mCursor != NS_STYLE_CURSOR_INHERIT) {
// If we have a particular cursor, use it
*aFrame = this;
aCursor = (PRInt32) styleColor->mCursor;
}
nsIImageMap* map = GetImageMap();
if (nsnull != map) {
nsRect inner;
GetInnerArea(&aPresContext, inner);
aCursor = NS_STYLE_CURSOR_DEFAULT;
float t2p = aPresContext.GetTwipsToPixels();
PRInt32 x = NSTwipsToIntPixels((aPoint.x - inner.x), t2p);
PRInt32 y = NSTwipsToIntPixels((aPoint.y - inner.y), t2p);
if (NS_OK == map->IsInside(x, y)) {
aCursor = NS_STYLE_CURSOR_HAND;
}
NS_RELEASE(map);
}
return NS_OK;
}
NS_IMETHODIMP
ImageFrame::ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent)
{
// See if the src attribute changed; if it did then trigger a redraw
// by firing up a new image load request. Otherwise let our base
// class handle the content-changed request.
nsAutoString oldSRC;
mImageLoader.GetURL(oldSRC);
// Get src attribute's value and construct a new absolute url from it
nsAutoString newSRC;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("SRC", newSRC)) {
if (!oldSRC.Equals(newSRC)) {
mSizeFrozen = PR_TRUE;
#ifdef NS_DEBUG
char oldcbuf[100], newcbuf[100];
oldSRC.ToCString(oldcbuf, sizeof(oldcbuf));
newSRC.ToCString(newcbuf, sizeof(newcbuf));
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("ImageFrame::ContentChanged: new image source; old='%s' new='%s'",
oldcbuf, newcbuf));
#endif
// Get rid of old image loader and start a new image load going
mImageLoader.DestroyLoader();
// Fire up a new image load request
PRIntn loadStatus;
mImageLoader.SetURL(newSRC);
mImageLoader.StartLoadImage(aPresContext, this, PR_FALSE, loadStatus);
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("ImageFrame::ContentChanged: loadImage status=%x",
loadStatus));
// If the image is already ready then we need to trigger a
// redraw because the image loader won't.
if (loadStatus & NS_IMAGE_LOAD_STATUS_IMAGE_READY) {
// XXX Stuff this into a method on nsIPresShell/Context
nsIViewManager* vm;
nsIView* view;
GetView(view);
if (nsnull != view) {
view->GetViewManager(vm);
vm->UpdateView(view, nsnull, 0);
}
else {
nsRect bounds;
nsPoint offset;
GetOffsetFromView(offset, view);
bounds.x = offset.x;
bounds.y = offset.y;
bounds.width = mRect.width;
bounds.height = mRect.height;
view->GetViewManager(vm);
vm->UpdateView(view, bounds, 0);
}
NS_RELEASE(vm);
}
return NS_OK;
}
}
return ImageFrameSuper::ContentChanged(aShell, aPresContext, aChild,
aSubContent);
}

Просмотреть файл

@ -136,7 +136,8 @@ void nsHTMLReflowCommand::BuildPath()
NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
const nsSize& aMaxSize,
nsIRenderingContext& aRendContext)
{
// Build the path from the target frame (index 0) to the root frame
BuildPath();
@ -155,7 +156,7 @@ NS_IMETHODIMP nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
if (nsnull != root) {
mPath.RemoveElementAt(mPath.Count() - 1);
nsReflowState reflowState(root, *this, aMaxSize);
nsReflowState reflowState(root, *this, aMaxSize, &aRendContext);
nsIHTMLReflow* htmlReflow;
nsReflowStatus status;

Просмотреть файл

@ -52,7 +52,8 @@ public:
// nsIReflowCommand
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsSize& aMaxSize);
const nsSize& aMaxSize,
nsIRenderingContext& aRendContext);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD SetTarget(nsIFrame* aTargetFrame);

Просмотреть файл

@ -98,11 +98,11 @@ protected:
PRBool IsServerImageMap();
PRIntn GetSuppress();
nscoord MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit);
nscoord MeasureString(const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit,
nsIRenderingContext& aContext);
void DisplayAltText(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
@ -459,17 +459,18 @@ ImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
// Computes the width of the specified string. aMaxWidth specifies the maximum
// width available. Once this limit is reached no more characters are measured.
// The number of characters that fit within the maximum width are returned in
// aMaxFit
// aMaxFit. NOTE: it is assumed that the fontmetrics have already been selected
// into the rendering context before this is called (for performance). MMP
nscoord
ImageFrame::MeasureString(nsIFontMetrics* aFontMetrics,
const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit)
ImageFrame::MeasureString(const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit,
nsIRenderingContext& aContext)
{
nscoord totalWidth = 0;
nscoord spaceWidth;
aFontMetrics->GetWidth(' ', spaceWidth);
aContext.GetWidth(' ', spaceWidth);
aMaxFit = 0;
while (aLength > 0) {
@ -486,7 +487,7 @@ ImageFrame::MeasureString(nsIFontMetrics* aFontMetrics,
// Measure this chunk of text, and see if it fits
nscoord width;
aFontMetrics->GetWidth(aString, len, width);
aContext.GetWidth(aString, len, width);
PRBool fits = (totalWidth + width) <= aMaxWidth;
// If it fits on the line, or it's the first word we've processed then
@ -554,7 +555,7 @@ ImageFrame::DisplayAltText(nsIPresContext& aPresContext,
while ((strLen > 0) && ((y + maxDescent) < aRect.YMost())) {
// Determine how much of the text to display on this line
PRUint32 maxFit; // number of characters that fit
nscoord width = MeasureString(fm, str, strLen, aRect.width, maxFit);
nscoord width = MeasureString(str, strLen, aRect.width, maxFit, aRenderingContext);
// Display the text
aRenderingContext.DrawString(str, maxFit, aRect.x, y, 0);

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsIViewObserver.h"
#include "nsContainerFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIDeviceContext.h"
static PRBool gsNoisyRefs = PR_FALSE;
#undef NOISY
@ -207,8 +208,7 @@ public:
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand);
virtual void ProcessReflowCommands();
//nsIViewObserver
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame, nsIRenderingContext *&aContext);
//nsIViewObserver interface
@ -496,13 +496,17 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
mRootFrame->VerifyTree();
}
#endif
nsRect bounds;
nsRect bounds;
mPresContext->GetVisibleArea(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, eReflowReason_Initial, maxSize);
nsIHTMLReflow* htmlReflow;
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsIHTMLReflow* htmlReflow;
nsIRenderingContext* rcx = nsnull;
CreateRenderingContext(mRootFrame, rcx);
nsReflowState reflowState(mRootFrame, eReflowReason_Initial, maxSize, rcx);
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
@ -513,6 +517,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
}
#endif
}
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::InitialReflow"));
}
@ -542,13 +547,17 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
mRootFrame->VerifyTree();
}
#endif
nsRect bounds;
nsRect bounds;
mPresContext->GetVisibleArea(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsReflowState reflowState(mRootFrame, eReflowReason_Resize, maxSize);
nsIHTMLReflow* htmlReflow;
nsSize maxSize(bounds.width, bounds.height);
nsHTMLReflowMetrics desiredSize(nsnull);
nsReflowStatus status;
nsIHTMLReflow* htmlReflow;
nsIRenderingContext* rcx = nsnull;
CreateRenderingContext(mRootFrame, rcx);
nsReflowState reflowState(mRootFrame, eReflowReason_Resize, maxSize, rcx);
if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status);
@ -559,6 +568,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
}
#endif
}
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
// XXX if debugging then we should assert that the cache is empty
@ -631,7 +641,10 @@ void
PresShell::ProcessReflowCommands()
{
if (0 != mReflowCommands.Count()) {
nsHTMLReflowMetrics desiredSize(nsnull);
nsHTMLReflowMetrics desiredSize(nsnull);
nsIRenderingContext* rcx;
CreateRenderingContext(mRootFrame, rcx);
while (0 != mReflowCommands.Count()) {
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(0);
@ -647,7 +660,7 @@ PresShell::ProcessReflowCommands()
("PresShell::ProcessReflowCommands: begin reflow command type=%d",
type));
#endif
rc->Dispatch(*mPresContext, desiredSize, maxSize);
rc->Dispatch(*mPresContext, desiredSize, maxSize, *rcx);
NS_RELEASE(rc);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("PresShell::ProcessReflowCommands: end reflow command"));
@ -663,9 +676,53 @@ PresShell::ProcessReflowCommands()
VerifyIncrementalReflow();
}
#endif
NS_IF_RELEASE(rcx);
}
}
NS_IMETHODIMP PresShell :: CreateRenderingContext(nsIFrame *aFrame,
nsIRenderingContext *&aContext)
{
nsIWidget *widget = nsnull;
nsIView *view = nsnull;
nsPoint pt;
nsresult rv;
aFrame->GetView(view);
if (nsnull == view)
aFrame->GetOffsetFromView(pt, view);
while (nsnull != view)
{
view->GetWidget(widget);
if (nsnull != widget)
{
NS_RELEASE(widget);
break;
}
view->GetParent(view);
}
if (nsnull != view)
{
nsIDeviceContext *dx;
dx = mPresContext->GetDeviceContext();
rv = dx->CreateRenderingContext(view, aContext);
NS_RELEASE(dx);
}
else
{
rv = NS_ERROR_FAILURE;
aContext = nsnull;
}
return rv;
}
#ifdef NS_DEBUG
static char*
ContentTag(nsIContent* aContent, PRIntn aSlot)

Просмотреть файл

@ -78,7 +78,7 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
#define XP_IS_SPACE(_ch) \
(((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
// XXX need more of this in nsIFontMetrics.GetWidth
// XXX need more of this in nsIRenderingContext.GetWidth
#define CH_NBSP 160
// XXX use a PreTextFrame for pre-formatted text?
@ -141,10 +141,12 @@ public:
NS_IMETHOD ListTag(FILE* out) const;
virtual PRInt32 GetPosition(nsIPresContext& aCX,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset);
NS_IMETHOD GetPosition(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aAcutalContentOffset,
PRInt32& aOffset);
// nsIInlineReflow
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout,
@ -1009,7 +1011,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
if (si.mEmptySelection) {
aRenderingContext.DrawString(text, textLength, dx, dy, mRect.width);
PaintTextDecorations(aRenderingContext, aDecorations, dx, dy, mRect.width);
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
@ -1019,7 +1021,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
if (0 != si.mStartOffset) {
// Render first (unselected) section
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.DrawString(text, si.mStartOffset,
x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1028,7 +1030,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
PRInt32 secondLen = si.mEndOffset - si.mStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
fm->GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
aRenderingContext.GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aSelectionBGColor);
@ -1044,7 +1046,7 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext,
PRInt32 thirdLen = textLength - si.mEndOffset;
// Render third (unselected) section
fm->GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.DrawString(text + si.mEndOffset,
thirdLen, x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1104,7 +1106,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
if (si.mEmptySelection) {
aRenderingContext.DrawString(text, textLength, dx, dy, mRect.width);
PaintTextDecorations(aRenderingContext, aDecorations, dx, dy, mRect.width);
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
@ -1114,7 +1116,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
if (0 != si.mStartOffset) {
// Render first (unselected) section
fm->GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.GetWidth(text, PRUint32(si.mStartOffset), textWidth);
aRenderingContext.DrawString(text, si.mStartOffset,
x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1123,7 +1125,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
PRInt32 secondLen = si.mEndOffset - si.mStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
fm->GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
aRenderingContext.GetWidth(text + si.mStartOffset, PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aSelectionBGColor);
@ -1139,7 +1141,7 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext,
PRInt32 thirdLen = textLength - si.mEndOffset;
// Render third (unselected) section
fm->GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.GetWidth(text + si.mEndOffset, PRUint32(thirdLen), textWidth);
aRenderingContext.DrawString(text + si.mEndOffset,
thirdLen, x, dy, textWidth);
PaintTextDecorations(aRenderingContext, aDecorations, x, dy, textWidth);
@ -1182,7 +1184,7 @@ TextFrame::FindTextRuns(nsLineLayout& aLineLayout,
// aTextWidth returns the (in twips) the length of the text that falls before the cursor
// aIndex contains the index of the text where the cursor falls
static PRBool
BinarySearchForPosition(nsIFontMetrics* aFM,
BinarySearchForPosition(nsIRenderingContext* acx,
PRUnichar* aText,
PRInt32 aBaseWidth,
PRInt32 aBaseInx,
@ -1200,7 +1202,7 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
PRInt32 inx = aStartInx + (range / 2);
PRInt32 textWidth;
aFM->GetWidth(aText, inx, textWidth);
acx->GetWidth(aText, inx, textWidth);
PRInt32 fullWidth = aBaseWidth + textWidth;
if (fullWidth == aCursorPos) {
@ -1208,13 +1210,13 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
return PR_TRUE;
} else if (aCursorPos < fullWidth) {
aTextWidth = aBaseWidth;
if (BinarySearchForPosition(aFM, aText, aBaseWidth, aBaseInx, aStartInx, inx, aCursorPos, aIndex, aTextWidth)) {
if (BinarySearchForPosition(acx, aText, aBaseWidth, aBaseInx, aStartInx, inx, aCursorPos, aIndex, aTextWidth)) {
return PR_TRUE;
}
} else {
aTextWidth = fullWidth;
PRInt32 end = aEndInx - inx;
if (BinarySearchForPosition(aFM, aText+inx, fullWidth, aBaseInx+inx, 0, end, aCursorPos, aIndex, aTextWidth)) {
if (BinarySearchForPosition(acx, aText+inx, fullWidth, aBaseInx+inx, 0, end, aCursorPos, aIndex, aTextWidth)) {
return PR_TRUE;
}
}
@ -1227,11 +1229,13 @@ BinarySearchForPosition(nsIFontMetrics* aFM,
// un-compressed text, selection is based on the un-compressed text, the visual
// display of selection is based on the compressed text.
//---------------------------------------------------------------------------
PRInt32
NS_IMETHODIMP
TextFrame::GetPosition(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame* aNewFrame,
PRUint32& aAcutalContentOffset)
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
const PRInt16 kNumIndices = 512;
@ -1259,10 +1263,12 @@ TextFrame::GetPosition(nsIPresContext& aCX,
PRInt32 index;
PRInt32 textWidth;
PRBool found = BinarySearchForPosition(fm, text, 0, 0, 0, PRInt32(textLength), PRInt32(aEvent->point.x), index, textWidth);
aRendContext->SetFont(fm);
PRBool found = BinarySearchForPosition(aRendContext, text, 0, 0, 0, PRInt32(textLength), PRInt32(aEvent->point.x), index, textWidth);
if (found) {
PRInt32 charWidth;
fm->GetWidth(text[index], charWidth);
aRendContext->GetWidth(text[index], charWidth);
charWidth /= 2;
if (PRInt32(aEvent->point.x) > textWidth+charWidth) {
@ -1290,7 +1296,9 @@ TextFrame::GetPosition(nsIPresContext& aCX,
}
aAcutalContentOffset = ((TextFrame *)aNewFrame)->mContentOffset;
return offset;
aOffset = offset;
return NS_OK;
}
NS_IMETHODIMP
@ -1363,7 +1371,8 @@ TextFrame::ReflowNormal(nsLineLayout& aLineLayout,
nsIFontMetrics* fm = aLineLayout.mPresContext.GetMetricsFor(aFont.mFont);
PRInt32 spaceWidth;
fm->GetWidth(' ', spaceWidth);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(' ', spaceWidth);
PRBool wrapping = PR_TRUE;
if (NS_STYLE_WHITESPACE_NORMAL != aTextStyle.mWhiteSpace) {
wrapping = PR_FALSE;
@ -1435,7 +1444,7 @@ TextFrame::ReflowNormal(nsLineLayout& aLineLayout,
}
break;
}
fm->GetWidth(wordStart, PRUint32(cp - wordStart), width);
aReflowState.rendContext->GetWidth(wordStart, PRUint32(cp - wordStart), width);
skipWhitespace = PR_FALSE;
isWhitespace = PR_FALSE;
}
@ -1543,7 +1552,8 @@ TextFrame::ReflowPre(nsLineLayout& aLineLayout,
PRUint16 col = aLineLayout.GetColumn();
mColumn = col;
nscoord spaceWidth;
fm->GetWidth(' ', spaceWidth);
aReflowState.rendContext->SetFont(fm);
aReflowState.rendContext->GetWidth(' ', spaceWidth);
// XXX change this to measure a line at a time
while (cp < end) {
@ -1569,11 +1579,11 @@ TextFrame::ReflowPre(nsLineLayout& aLineLayout,
}
if (ch < 256) {
nscoord charWidth;
fm->GetWidth(ch, charWidth);
aReflowState.rendContext->GetWidth(ch, charWidth);
width += charWidth;
} else {
nscoord charWidth;
fm->GetWidth(ch, charWidth);
aReflowState.rendContext->GetWidth(ch, charWidth);
width += charWidth;
hasMultibyte = PR_TRUE;
}

Просмотреть файл

@ -1396,7 +1396,12 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext& aPresContext, nsGUIEvent* aEvent)
nsHTMLReflowMetrics metrics(nsnull);
nsSize size;
GetSize(size);
nsReflowState state(this, eReflowReason_Initial, size);
nsIPresShell *shell;
nsIRenderingContext *acx;
shell = aPresContext.GetShell();
shell->CreateRenderingContext(this, acx);
NS_RELEASE(shell);
nsReflowState state(this, eReflowReason_Initial, size, acx);
state.reason = eReflowReason_Incremental;
nsReflowStatus status;
nsDidReflowStatus didStatus;
@ -1404,6 +1409,7 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext& aPresContext, nsGUIEvent* aEvent)
nsFramesetDrag drag(mDragger->mVertical, mDragger->mPrevNeighbor, change, this);
Reflow(aPresContext, &drag, metrics, state, status);
DidReflow(aPresContext, didStatus);
NS_IF_RELEASE(acx);
}
mLastDragPoint.x = aEvent->point.x;

Просмотреть файл

@ -334,7 +334,8 @@ nsButtonControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value,
&defaultLabel, 1, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, spec, size,
widthExplicit, heightExplicit, ignore);
widthExplicit, heightExplicit, ignore,
aReflowState.rendContext);
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height= size.height;
}

Просмотреть файл

@ -580,7 +580,8 @@ GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2)
nscoord
nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize)
const nsString& aString, nsSize& aSize,
nsIRenderingContext *aRendContext)
{
nsFont font(aPresContext.GetDefaultFixedFont());
aFrame->GetFont(&aPresContext, font);
@ -589,14 +590,15 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
nsIFontMetrics* fontMet;
deviceContext->GetMetricsFor(font, fontMet);
fontMet->GetWidth(aString, aSize.width);
aRendContext->SetFont(fontMet);
aRendContext->GetWidth(aString, aSize.width);
fontMet->GetHeight(aSize.height);
char char1, char2;
GetRepChars(aPresContext, char1, char2);
nscoord char1Width, char2Width;
fontMet->GetWidth(char1, char1Width);
fontMet->GetWidth(char2, char2Width);
aRendContext->GetWidth(char1, char1Width);
aRendContext->GetWidth(char2, char2Width);
NS_RELEASE(fontMet);
NS_RELEASE(deviceContext);
@ -606,7 +608,8 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
nscoord
nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize)
PRInt32 aNumChars, nsSize& aSize,
nsIRenderingContext *aRendContext)
{
nsAutoString val;
char char1, char2;
@ -618,14 +621,15 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame
for (i = 1; i < aNumChars; i+=2) {
val += char2;
}
return GetTextSize(aPresContext, aFrame, val, aSize);
return GetTextSize(aPresContext, aFrame, val, aSize, aRendContext);
}
PRInt32
nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowHeight)
PRBool& aHeightExplicit, nscoord& aRowHeight,
nsIRenderingContext *aRendContext)
{
nscoord charWidth = 0;
PRInt32 numRows = ATTR_NOTSET;
@ -669,7 +673,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else {
col = (col <= 0) ? 1 : col;
charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds, aRendContext);
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
if (aSpec.mColSizeAttrInPixels) {
@ -683,17 +687,17 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) { // use width of initial value
charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds, aRendContext);
}
else if (aSpec.mColDefaultValue) { // use default value
charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds, aRendContext);
}
else if (aSpec.mColDefaultSizeInPixels) { // use default width in pixels
charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds, aRendContext);
aBounds.width = aSpec.mColDefaultSize;
}
else { // use default width in num characters
charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds);
charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds, aRendContext);
}
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
@ -709,7 +713,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
PRInt32 rowAttrInt = ((rowAttr.GetUnit() == eHTMLUnit_Pixel) ? rowAttr.GetPixelValue() : rowAttr.GetIntValue());
adjSize = (rowAttrInt > 0) ? rowAttrInt : 1;
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aBounds.height = textSize.height * adjSize;
aRowHeight = textSize.height;
numRows = adjSize;
@ -724,7 +728,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
else { // use default height in num lines
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aBounds.height = textSize.height * aSpec.mRowDefaultSize;
aRowHeight = textSize.height;
}
@ -734,7 +738,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr
}
if ((0 == charWidth) || (0 == textSize.width)) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize, aRendContext);
aRowHeight = textSize.height;
}

Просмотреть файл

@ -92,7 +92,8 @@ public:
static nscoord CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowSize);
PRBool& aHeightExplicit, nscoord& aRowSize,
nsIRenderingContext *aRendContext);
/**
* Respond to a gui event
@ -179,9 +180,11 @@ public:
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize);
const nsString& aString, nsSize& aSize,
nsIRenderingContext *aRendContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize);
PRInt32 aNumChars, nsSize& aSize,
nsIRenderingContext *aRendContext);
void GetWidgetSize(nsSize& aSize) const { aSize.width = mWidgetSize.width;
aSize.height = mWidgetSize.height; }

Просмотреть файл

@ -223,7 +223,7 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
}
nsSize textSize;
// use the style for the select rather that the option, since widgets don't support it
nsFormControlFrame::GetTextSize(*aPresContext, this, text, textSize);
nsFormControlFrame::GetTextSize(*aPresContext, this, text, textSize, aReflowState.rendContext);
if (textSize.width > maxWidth) {
maxWidth = textSize.width;
}
@ -238,7 +238,8 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
maxWidth, PR_TRUE, nsHTMLAtoms::size, 1);
// XXX fix CalculateSize to return PRUint32
PRUint32 numRows = (PRUint32)CalculateSize(aPresContext, this, styleSize, textSpec,
calcSize, widthExplicit, heightExplicit, rowHeight);
calcSize, widthExplicit, heightExplicit, rowHeight,
aReflowState.rendContext);
// here it is determined whether we are a combo box
PRInt32 sizeAttr;

Просмотреть файл

@ -197,12 +197,14 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, textSpec, size,
widthExplicit, heightExplicit, ignore);
widthExplicit, heightExplicit, ignore,
aReflowState.rendContext);
} else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20,
PR_FALSE, nsHTMLAtoms::rows, 1);
CalculateSize(aPresContext, this, styleSize, areaSpec, size,
widthExplicit, heightExplicit, ignore);
widthExplicit, heightExplicit, ignore,
aReflowState.rendContext);
}
if (NS_FORM_TEXTAREA == type) {

Просмотреть файл

@ -895,9 +895,12 @@ void nsImageButton::PerformAlignment(const nsRect & aRect,
if (mShowText) {
nsIFontMetrics* metrics;
mContext->GetMetricsFor(mFont, metrics);
nsIRenderingContext *cx;
mContext->CreateRenderingContext(this, cx);
cx->SetFont(metrics);
metrics->GetHeight(string_height);
metrics->GetWidth(aText, string_width);
cx->GetWidth(aText, string_width);
NS_RELEASE(cx);
NS_RELEASE(metrics);

Просмотреть файл

@ -204,9 +204,13 @@ NS_METHOD nsLabel::GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight)
nsString text;
GetLabel(text);
nsIRenderingContext *cx;
mContext->CreateRenderingContext(this, cx);
cx->SetFont(metrics);
nscoord string_height, string_width;
metrics->GetHeight(string_height);
metrics->GetWidth(text, string_width);
cx->GetWidth(text, string_width);
NS_RELEASE(cx);
NS_RELEASE(metrics);
if (mPreferredWidth != 0) {