fix bug 5458 - made ApplyRenderingChangeToTree handle overflow content

as well as floaters and positioned children
also improved handling of view invalidation and syncing
removed warning
approved chofman
This commit is contained in:
peterl%netscape.com 1999-09-25 05:02:52 +00:00
Родитель d1882ffe5e
Коммит ebc6169f45
2 изменённых файлов: 228 добавлений и 94 удалений

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

@ -6417,80 +6417,143 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} }
static void static void
UpdateViewsForTree(nsIFrame* aFrame, nsIViewManager* aViewManager, nsRect& aBoundsRect) ApplyRenderingChangeToTree(nsIPresContext& aPresContext,
{ nsIFrame* aFrame,
nsIView* view; nsIViewManager* aViewManager);
aFrame->GetView(&view);
nsFrameState state; static void
aFrame->GetFrameState(&state); SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame,
if (view) { nsIViewManager* aViewManager)
{
const nsStyleColor* color; const nsStyleColor* color;
const nsStyleDisplay* disp; const nsStyleDisplay* disp;
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?nsViewVisibility_kHide:nsViewVisibility_kShow); aViewManager->SetViewOpacity(aView, color->mOpacity);
PRBool viewVisible = (NS_STYLE_VISIBILITY_VISIBLE == disp->mVisible);
// XXX Troy, you need to hook in the leaf node logic here.
aViewManager->SetViewOpacity(view, color->mOpacity); // XXX also need to set transparency in the view
if (! viewVisible) {
nsIView* parentView = nsnull;
aView->GetParent(parentView);
if (parentView) {
nsRect bounds;
aView->GetBounds(bounds);
aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC);
}
else {
// XXX??? how to deal with this??? Do we even have to?
}
aView->SetVisibility(nsViewVisibility_kHide);
}
else {
aView->SetVisibility(nsViewVisibility_kShow);
aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC);
}
}
static void
UpdateViewsForTree(nsIPresContext& aPresContext, nsIFrame* aFrame,
nsIViewManager* aViewManager, nsRect& aBoundsRect)
{
nsIView* view;
aFrame->GetView(&view);
if (view) {
SyncAndInvalidateView(view, aFrame, aViewManager);
} }
// now do children fo frame nsRect bounds;
aFrame->GetRect(bounds);
nsPoint parentOffset(bounds.x, bounds.y);
bounds.x = 0;
bounds.y = 0;
// now do children of frame
PRInt32 listIndex = 0; PRInt32 listIndex = 0;
nsIAtom* childList = nsnull; nsIAtom* childList = nsnull;
nsIAtom* frameType = nsnull;
do { do {
nsIFrame* child = nsnull; nsIFrame* child = nsnull;
aFrame->FirstChild(childList, &child); aFrame->FirstChild(childList, &child);
while (child) { while (child) {
nsRect childRect; nsFrameState childState;
if (state & NS_FRAME_OUTSIDE_CHILDREN) { // update bounds rect to include children child->GetFrameState(&childState);
if (NS_FRAME_OUT_OF_FLOW != (childState & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
child->GetFrameType(&frameType);
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
// get out of flow frame and start over there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
ApplyRenderingChangeToTree(aPresContext, outOfFlowFrame, aViewManager);
}
else { // regular frame
nsRect childBounds;
UpdateViewsForTree(aPresContext, child, aViewManager, childBounds);
bounds.UnionRect(bounds, childBounds);
}
NS_IF_RELEASE(frameType);
} }
UpdateViewsForTree(child, aViewManager, childRect);
child->GetNextSibling(&child); child->GetNextSibling(&child);
} }
NS_IF_RELEASE(childList); NS_IF_RELEASE(childList);
aFrame->GetAdditionalChildListName(listIndex++, &childList); aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList); } while (childList);
NS_IF_RELEASE(childList); NS_IF_RELEASE(childList);
aBoundsRect = bounds;
aBoundsRect += parentOffset;
} }
static void static void
ApplyRenderingChangeToTree(nsIPresContext* aPresContext, ApplyRenderingChangeToTree(nsIPresContext& aPresContext,
nsIFrame* aFrame) nsIFrame* aFrame,
nsIViewManager* aViewManager)
{ {
nsIViewManager* viewManager = nsnull; nsIViewManager* viewManager = aViewManager;
// Trigger rendering updates by damaging this frame and any // Trigger rendering updates by damaging this frame and any
// continuations of this frame. // continuations of this frame.
// XXX this needs to detect the need for a view due to an opacity change and deal with it... // XXX this needs to detect the need for a view due to an opacity change and deal with it...
if (viewManager) {
NS_ADDREF(viewManager); // add local ref
viewManager->BeginUpdateViewBatch();
}
while (nsnull != aFrame) { while (nsnull != aFrame) {
// Get the frame's bounding rect // Get the frame's bounding rect
nsRect r; nsRect invalidRect;
aFrame->GetRect(r); nsPoint viewOffset;
r.x = 0;
r.y = 0;
// Get view if this frame has one and trigger an update. If the // Get view if this frame has one and trigger an update. If the
// frame doesn't have a view, find the nearest containing view // frame doesn't have a view, find the nearest containing view
// (adjusting r's coordinate system to reflect the nesting) and // (adjusting r's coordinate system to reflect the nesting) and
// update there. // update there.
nsIView* view; nsIView* view = nsnull;
aFrame->GetView(&view); aFrame->GetView(&view);
if (view) { // XXX can view have children outside it? nsIView* parentView;
} else { if (! view) { // XXX can view have children outside it?
nsPoint offset; aFrame->GetOffsetFromView(viewOffset, &parentView);
aFrame->GetOffsetFromView(offset, &view); NS_ASSERTION(nsnull != parentView, "no view");
NS_ASSERTION(nsnull != view, "no view"); if (! viewManager) {
r += offset; parentView->GetViewManager(viewManager);
viewManager->BeginUpdateViewBatch();
} }
if (nsnull == viewManager) { }
else {
if (! viewManager) {
view->GetViewManager(viewManager); view->GetViewManager(viewManager);
viewManager->BeginUpdateViewBatch();
} }
UpdateViewsForTree(aFrame, viewManager, r); }
UpdateViewsForTree(aPresContext, aFrame, viewManager, invalidRect);
if (! view) { // if frame has view, will already be invalidated
// XXX Instead of calling this we should really be calling // XXX Instead of calling this we should really be calling
// Invalidate on on the nsFrame (which does this) // Invalidate on on the nsFrame (which does this)
const nsStyleSpacing* spacing; const nsStyleSpacing* spacing;
@ -6498,16 +6561,21 @@ ApplyRenderingChangeToTree(nsIPresContext* aPresContext,
nscoord width; nscoord width;
spacing->GetOutlineWidth(width); spacing->GetOutlineWidth(width);
if (width > 0) { if (width > 0) {
r.Inflate(width, width); invalidRect.Inflate(width, width);
}
nsPoint frameOrigin;
aFrame->GetOrigin(frameOrigin);
invalidRect -= frameOrigin;
invalidRect += viewOffset;
viewManager->UpdateView(parentView, invalidRect, NS_VMREFRESH_NO_SYNC);
} }
viewManager->UpdateView(view, r, NS_VMREFRESH_NO_SYNC);
aFrame->GetNextInFlow(&aFrame); aFrame->GetNextInFlow(&aFrame);
} }
if (nsnull != viewManager) { if (viewManager) {
viewManager->Composite(); viewManager->EndUpdateViewBatch();
// viewManager->Composite();
NS_RELEASE(viewManager); NS_RELEASE(viewManager);
} }
} }
@ -6586,7 +6654,7 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
StyleChangeReflow(aPresContext, frame, nsnull); StyleChangeReflow(aPresContext, frame, nsnull);
break; break;
case NS_STYLE_HINT_VISUAL: case NS_STYLE_HINT_VISUAL:
ApplyRenderingChangeToTree(aPresContext, frame); ApplyRenderingChangeToTree(*aPresContext, frame, nsnull);
break; break;
case NS_STYLE_HINT_CONTENT: case NS_STYLE_HINT_CONTENT:
default: default:
@ -6812,7 +6880,6 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
// is there? // is there?
if (primaryFrame) { if (primaryFrame) {
PRInt32 maxHint = aHint; PRInt32 maxHint = aHint;
nsIFrame* frame = primaryFrame;
nsStyleChangeList changeList; nsStyleChangeList changeList;
// put primary frame on list to deal with, re-resolve may update or add next in flows // put primary frame on list to deal with, re-resolve may update or add next in flows
changeList.AppendChange(primaryFrame, maxHint); changeList.AppendChange(primaryFrame, maxHint);
@ -6901,7 +6968,7 @@ nsCSSFrameConstructor::StyleRuleChanged(nsIPresContext* aPresContext,
StyleChangeReflow(aPresContext, frame, nsnull); StyleChangeReflow(aPresContext, frame, nsnull);
} }
else if (render) { else if (render) {
ApplyRenderingChangeToTree(aPresContext, frame); ApplyRenderingChangeToTree(*aPresContext, frame, nsnull);
} }
} }

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

@ -6417,80 +6417,143 @@ nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
} }
static void static void
UpdateViewsForTree(nsIFrame* aFrame, nsIViewManager* aViewManager, nsRect& aBoundsRect) ApplyRenderingChangeToTree(nsIPresContext& aPresContext,
{ nsIFrame* aFrame,
nsIView* view; nsIViewManager* aViewManager);
aFrame->GetView(&view);
nsFrameState state; static void
aFrame->GetFrameState(&state); SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame,
if (view) { nsIViewManager* aViewManager)
{
const nsStyleColor* color; const nsStyleColor* color;
const nsStyleDisplay* disp; const nsStyleDisplay* disp;
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?nsViewVisibility_kHide:nsViewVisibility_kShow); aViewManager->SetViewOpacity(aView, color->mOpacity);
PRBool viewVisible = (NS_STYLE_VISIBILITY_VISIBLE == disp->mVisible);
// XXX Troy, you need to hook in the leaf node logic here.
aViewManager->SetViewOpacity(view, color->mOpacity); // XXX also need to set transparency in the view
if (! viewVisible) {
nsIView* parentView = nsnull;
aView->GetParent(parentView);
if (parentView) {
nsRect bounds;
aView->GetBounds(bounds);
aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC);
}
else {
// XXX??? how to deal with this??? Do we even have to?
}
aView->SetVisibility(nsViewVisibility_kHide);
}
else {
aView->SetVisibility(nsViewVisibility_kShow);
aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC);
}
}
static void
UpdateViewsForTree(nsIPresContext& aPresContext, nsIFrame* aFrame,
nsIViewManager* aViewManager, nsRect& aBoundsRect)
{
nsIView* view;
aFrame->GetView(&view);
if (view) {
SyncAndInvalidateView(view, aFrame, aViewManager);
} }
// now do children fo frame nsRect bounds;
aFrame->GetRect(bounds);
nsPoint parentOffset(bounds.x, bounds.y);
bounds.x = 0;
bounds.y = 0;
// now do children of frame
PRInt32 listIndex = 0; PRInt32 listIndex = 0;
nsIAtom* childList = nsnull; nsIAtom* childList = nsnull;
nsIAtom* frameType = nsnull;
do { do {
nsIFrame* child = nsnull; nsIFrame* child = nsnull;
aFrame->FirstChild(childList, &child); aFrame->FirstChild(childList, &child);
while (child) { while (child) {
nsRect childRect; nsFrameState childState;
if (state & NS_FRAME_OUTSIDE_CHILDREN) { // update bounds rect to include children child->GetFrameState(&childState);
if (NS_FRAME_OUT_OF_FLOW != (childState & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
child->GetFrameType(&frameType);
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
// get out of flow frame and start over there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
ApplyRenderingChangeToTree(aPresContext, outOfFlowFrame, aViewManager);
}
else { // regular frame
nsRect childBounds;
UpdateViewsForTree(aPresContext, child, aViewManager, childBounds);
bounds.UnionRect(bounds, childBounds);
}
NS_IF_RELEASE(frameType);
} }
UpdateViewsForTree(child, aViewManager, childRect);
child->GetNextSibling(&child); child->GetNextSibling(&child);
} }
NS_IF_RELEASE(childList); NS_IF_RELEASE(childList);
aFrame->GetAdditionalChildListName(listIndex++, &childList); aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList); } while (childList);
NS_IF_RELEASE(childList); NS_IF_RELEASE(childList);
aBoundsRect = bounds;
aBoundsRect += parentOffset;
} }
static void static void
ApplyRenderingChangeToTree(nsIPresContext* aPresContext, ApplyRenderingChangeToTree(nsIPresContext& aPresContext,
nsIFrame* aFrame) nsIFrame* aFrame,
nsIViewManager* aViewManager)
{ {
nsIViewManager* viewManager = nsnull; nsIViewManager* viewManager = aViewManager;
// Trigger rendering updates by damaging this frame and any // Trigger rendering updates by damaging this frame and any
// continuations of this frame. // continuations of this frame.
// XXX this needs to detect the need for a view due to an opacity change and deal with it... // XXX this needs to detect the need for a view due to an opacity change and deal with it...
if (viewManager) {
NS_ADDREF(viewManager); // add local ref
viewManager->BeginUpdateViewBatch();
}
while (nsnull != aFrame) { while (nsnull != aFrame) {
// Get the frame's bounding rect // Get the frame's bounding rect
nsRect r; nsRect invalidRect;
aFrame->GetRect(r); nsPoint viewOffset;
r.x = 0;
r.y = 0;
// Get view if this frame has one and trigger an update. If the // Get view if this frame has one and trigger an update. If the
// frame doesn't have a view, find the nearest containing view // frame doesn't have a view, find the nearest containing view
// (adjusting r's coordinate system to reflect the nesting) and // (adjusting r's coordinate system to reflect the nesting) and
// update there. // update there.
nsIView* view; nsIView* view = nsnull;
aFrame->GetView(&view); aFrame->GetView(&view);
if (view) { // XXX can view have children outside it? nsIView* parentView;
} else { if (! view) { // XXX can view have children outside it?
nsPoint offset; aFrame->GetOffsetFromView(viewOffset, &parentView);
aFrame->GetOffsetFromView(offset, &view); NS_ASSERTION(nsnull != parentView, "no view");
NS_ASSERTION(nsnull != view, "no view"); if (! viewManager) {
r += offset; parentView->GetViewManager(viewManager);
viewManager->BeginUpdateViewBatch();
} }
if (nsnull == viewManager) { }
else {
if (! viewManager) {
view->GetViewManager(viewManager); view->GetViewManager(viewManager);
viewManager->BeginUpdateViewBatch();
} }
UpdateViewsForTree(aFrame, viewManager, r); }
UpdateViewsForTree(aPresContext, aFrame, viewManager, invalidRect);
if (! view) { // if frame has view, will already be invalidated
// XXX Instead of calling this we should really be calling // XXX Instead of calling this we should really be calling
// Invalidate on on the nsFrame (which does this) // Invalidate on on the nsFrame (which does this)
const nsStyleSpacing* spacing; const nsStyleSpacing* spacing;
@ -6498,16 +6561,21 @@ ApplyRenderingChangeToTree(nsIPresContext* aPresContext,
nscoord width; nscoord width;
spacing->GetOutlineWidth(width); spacing->GetOutlineWidth(width);
if (width > 0) { if (width > 0) {
r.Inflate(width, width); invalidRect.Inflate(width, width);
}
nsPoint frameOrigin;
aFrame->GetOrigin(frameOrigin);
invalidRect -= frameOrigin;
invalidRect += viewOffset;
viewManager->UpdateView(parentView, invalidRect, NS_VMREFRESH_NO_SYNC);
} }
viewManager->UpdateView(view, r, NS_VMREFRESH_NO_SYNC);
aFrame->GetNextInFlow(&aFrame); aFrame->GetNextInFlow(&aFrame);
} }
if (nsnull != viewManager) { if (viewManager) {
viewManager->Composite(); viewManager->EndUpdateViewBatch();
// viewManager->Composite();
NS_RELEASE(viewManager); NS_RELEASE(viewManager);
} }
} }
@ -6586,7 +6654,7 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
StyleChangeReflow(aPresContext, frame, nsnull); StyleChangeReflow(aPresContext, frame, nsnull);
break; break;
case NS_STYLE_HINT_VISUAL: case NS_STYLE_HINT_VISUAL:
ApplyRenderingChangeToTree(aPresContext, frame); ApplyRenderingChangeToTree(*aPresContext, frame, nsnull);
break; break;
case NS_STYLE_HINT_CONTENT: case NS_STYLE_HINT_CONTENT:
default: default:
@ -6812,7 +6880,6 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
// is there? // is there?
if (primaryFrame) { if (primaryFrame) {
PRInt32 maxHint = aHint; PRInt32 maxHint = aHint;
nsIFrame* frame = primaryFrame;
nsStyleChangeList changeList; nsStyleChangeList changeList;
// put primary frame on list to deal with, re-resolve may update or add next in flows // put primary frame on list to deal with, re-resolve may update or add next in flows
changeList.AppendChange(primaryFrame, maxHint); changeList.AppendChange(primaryFrame, maxHint);
@ -6901,7 +6968,7 @@ nsCSSFrameConstructor::StyleRuleChanged(nsIPresContext* aPresContext,
StyleChangeReflow(aPresContext, frame, nsnull); StyleChangeReflow(aPresContext, frame, nsnull);
} }
else if (render) { else if (render) {
ApplyRenderingChangeToTree(aPresContext, frame); ApplyRenderingChangeToTree(*aPresContext, frame, nsnull);
} }
} }