#include <rgnlist.h>
Inheritance diagram for RenderRegionList:
Public Member Functions | |
RenderRegionList () | |
Initialises the RenderRegionList - in particular, the pointer to the last render region to be rendered. | |
~RenderRegionList () | |
Destroys all render regions in the list, and then destroys the list. | |
void | Merge (RenderRegion *NewRegion) |
Add a render region object to the application's global list of render regions. | |
void | Remove (RenderRegion *) |
Removes a render region from the application's list of render regions, It DOES NOT delete the RenderRegion object itself. This is used when the region has been completely rendered and is no longer needed. | |
void | Remove (Document *) |
void | Remove (View *) |
Removes all render regions from the application's list of render regions that are associated with a particular document. Usually called because the document is being closed (deleted). It deletes all RenderRegion objects it removes.Removes all render regions from the application's list of render regions that are associated with a particular view. Usually called because the docview is being closed (deleted). It deletes all RenderRegion objects it removes. | |
BOOL | BackgroundRender () |
Cycles through the members of the render region list, rendering each one in turn. Only one render region is rendered on each call to BackgroundRender(). | |
void | ImmediateRender (BOOL bForceImmediate=FALSE) |
Finds all render regions associated with DocViews that have background rendering disabled, and renders them all immediately (i.e. to completion). | |
void | HandleNodeDeletion (Node *pNode) |
Tells RenderRegions that they should be afraid, very afraid, if they are holding a pointer to this node... | |
Private Member Functions | |
CC_DECLARE_MEMDUMP (RenderRegionList) | |
void | TidyUpAdjacentRegions (RenderRegion *) |
Goes through all the regions in the list and tests to see if any of them line up exactly. If they do, they are joined into a single region. | |
void | MergeRenderRegions (RenderRegion *NewRenderRegion) |
Attempts to find regions which can be merged together to make redrawing more efficient. At the moment, the two regions to be merged must satisfy the following conditions:. | |
void | StrictMerge (RenderRegion *pRegionToMerge) |
Tries to merge the render region supplied with the rest of the list. They must be exactly adjacent ie. They don't intersect, and the union contains no area outside the two rectangles. | |
void | RemoveRegionOverlap (RenderRegion *NewRenderRegion) |
Called when adding a new render region to the list. It checks the new render region for overlap with all the old render regions and if it overlapps any of them, the old region is slit up. This function should guarantee that you never get render regions that overlap, so that the EORed stuff does not get screwed up by getting rendered more than once. | |
void | ClipRectsToClient () |
Clips the RenderRegions in the list to the client area, incase it has been scrolled. | |
void | TryTotalUnion () |
For each DocView, try to union all the render regions, and see if the individual areas add up to more than 70% of the union area. If they do then we union all the regions together and just render one big one. | |
void | DoTotalUnion (RenderRegion *pRegion, View *pView, DocRect TotalUnion) |
For the specified DocView, find all the regions that are attached to it, and union them all together and use the region 'pRegion' to hold this new region. All the other regions of this DocView are removed from the list and deleted. | |
Private Attributes | |
RenderRegion * | LastRendered |
MILLIPOINT | PixelWidth |
BOOL | ListIsOptimal |
Definition at line 124 of file rgnlist.h.
|
Initialises the RenderRegionList - in particular, the pointer to the last render region to be rendered.
Definition at line 256 of file rgnlist.cpp. 00257 { 00258 LastRendered = NULL; 00259 ListIsOptimal = FALSE; 00260 }
|
|
Destroys all render regions in the list, and then destroys the list.
Definition at line 277 of file rgnlist.cpp. 00278 { 00279 // Call destructors on all objects in the list 00280 00281 RenderRegion *Item = (RenderRegion *) RemoveHead(); 00282 00283 while (Item != NULL) 00284 { 00285 // Delete the list item 00286 delete Item; 00287 00288 // Try the next item 00289 Item = (RenderRegion *) RemoveHead(); 00290 } 00291 }
|
|
Cycles through the members of the render region list, rendering each one in turn. Only one render region is rendered on each call to BackgroundRender().
Definition at line 1027 of file rgnlist.cpp. 01028 { 01029 if ( CCamApp::IsDisabled() ) 01030 { 01031 // TRACE( wxT("BGR - IsDisabled\n") ); 01032 return FALSE; // If he has got the system disabled, ignore 01033 } 01034 01035 // print monitor not present on viewer 01036 01037 // Make sure printing is ok. 01038 if (!PrintMonitor::IsPrintStatusOK()) 01039 { 01040 // No - a print job has gone wrong, so we delete all printing render regions 01041 // before continuing. 01042 RenderRegion *pRender = (RenderRegion *) GetHead(); 01043 while (pRender != NULL) 01044 { 01045 if (pRender->IsPrinting()) 01046 { 01047 // Render region is printing (well it's not really as an exception 01048 // has occured) so delete it. 01049 Remove(pRender); 01050 delete pRender; 01051 } 01052 01053 // Try next region 01054 pRender = (RenderRegion *) GetNext(pRender); 01055 } 01056 01057 // Reset the last rendered render region 01058 LastRendered = NULL; 01059 } 01060 01061 if (GetCount() == 0) 01062 { 01063 // TRACE( wxT("BGR - No regions\n") ); 01064 return FALSE; 01065 } 01066 01067 //GAT 01068 // if (ControlHelper::IsUserInterfaceCaptured()) 01069 // return FALSE; // No bg rendering if UI is captured (e.g. menu is up) 01070 // 01071 // if (DragManagerOp::IsDragActive()) 01072 // return FALSE; // No bg rendering if a DragManager op is active (NB this is for 01073 // colour/bitmap/bar drags only - not doc operation drags). 01074 if (ViewOps::IsFullScreenPending()) // no bg rendering if we are about to enter full screen mode 01075 { 01076 // TRACE( wxT("BGR - About to full screen\n") ); 01077 return FALSE; 01078 } 01079 01080 // Optimise list based on render region percentage coverage 01081 TryTotalUnion(); 01082 01083 // Work out which render region to render 01084 if (LastRendered != NULL) 01085 LastRendered = (RenderRegion*) GetNext(LastRendered); 01086 01087 if (LastRendered == NULL) 01088 LastRendered = (RenderRegion*) GetHead(); 01089 01090 if (LastRendered == NULL) 01091 { 01092 // TRACE( wxT("BGR - No last region\n") ); 01093 return FALSE; // No regions to render 01094 } 01095 01096 // Ignore the RenderRegion if we are Printing, because 01097 // we have probably been called from the Print AbortProc 01098 // and are already rendering. 01099 if (LastRendered->IsPrinting()) 01100 { 01101 // TRACE( wxT("BGR - Is printing\n") ); 01102 return FALSE; 01103 } 01104 01105 // TRACEUSER("Gerry", _T("BackgroundRender\n")); 01106 // Show the user we are rendering. 01107 if (GetApplication()->GetpStatusLine()) 01108 GetApplication()->GetpStatusLine()->SetRenderIndicator(Animate); 01109 GetApplication()->BgRendering = TRUE; 01110 01111 // Do the render. 01112 Error::RenderThreadIn(); // Make errors close window 01113 LastRendered->DefaultRender(); 01114 Error::RenderThreadOut(); // Normal errors 01115 01116 // Turn off render indicator if needed. 01117 if (GetCount() ==0) 01118 { 01119 if (GetApplication()->GetpStatusLine()) 01120 GetApplication()->GetpStatusLine()->SetRenderIndicator(NotRendering); 01121 GetApplication()->BgRendering = FALSE; 01122 } 01123 01124 // We did some rendering so return TRUE 01125 return TRUE; 01126 }
|
|
|
|
Clips the RenderRegions in the list to the client area, incase it has been scrolled.
Definition at line 804 of file rgnlist.cpp. 00805 { 00806 RenderRegion *pRegion = (RenderRegion*) GetHead(); 00807 while (pRegion != NULL) 00808 { 00809 // Find the view associated with the window and skip if null. 00810 View* pView = pRegion->GetRenderView(); 00811 if (pView != NULL && DocView::GetCurrent() == pView) 00812 { 00813 // Get the views rectangle, and convert it into spread coords 00814 DocRect ClientRect = pView->GetDocViewRect(pRegion->GetRenderSpread()); 00815 pRegion->GetRenderSpread()->DocCoordToSpreadCoord(&ClientRect); 00816 00817 // Get the clipping rectangle of this render region 00818 DocRect ClipRect = pRegion->GetRegionRect(); 00819 00820 // see if we need to lose any parts of the render region 00821 if (!ClientRect.ContainsRect(ClipRect)) 00822 { 00823 if (ClipRect.IsIntersectedWith(ClientRect)) 00824 { 00825 ClipRect = ClipRect.Intersection(ClientRect); 00826 pRegion->ResizeRegion(ClipRect); 00827 // pRegion->SetClipRect(ClipRect); 00828 // pRegion->ResetRegion(ClipRect); 00829 } 00830 else 00831 { 00832 // This render region is now off screen, so we can throw it away 00833 RenderRegion* pPrev = (RenderRegion *) GetPrev(pRegion); 00834 Remove(pRegion); 00835 delete pRegion; 00836 pRegion = pPrev; 00837 } 00838 } 00839 } 00840 00841 // Try the next item. 00842 pRegion = (RenderRegion*) ((pRegion != NULL) ? GetNext(pRegion) : GetHead()); 00843 } 00844 }
|
|
For the specified DocView, find all the regions that are attached to it, and union them all together and use the region 'pRegion' to hold this new region. All the other regions of this DocView are removed from the list and deleted.
Definition at line 1404 of file rgnlist.cpp. 01406 { 01407 pRegion->ResetRegion(TotalUnion); 01408 Spread* pSpread = pRegion->GetRenderSpread(); 01409 01410 // Delete all the others 01411 RenderRegion *pRegion2 =(RenderRegion *) GetNext(pRegion); 01412 01413 while (pRegion2 != NULL) 01414 { 01415 // Remember the 'next' region because we might delete this one. 01416 RenderRegion *pNextRegion = (RenderRegion *) GetNext(pRegion2); 01417 01418 // Is this the correct DocView and render context? 01419 if ((pRegion2->GetRenderView() == pView) && 01420 (pRegion2->GetRenderSpread() == pSpread) && 01421 (pRegion2->CanBeMerged())) 01422 { 01423 // Yes - delete this region 01424 pRegion->NeedsOSPaper = pRegion->NeedsOSPaper && pRegion2->NeedsOSPaper; 01425 Remove(pRegion2); 01426 delete pRegion2; 01427 01428 // Make sure we don't have a dangling pointer to this region. 01429 if (pRegion2 == LastRendered) 01430 // Start from the beginning of the list again. 01431 LastRendered = NULL; 01432 } 01433 01434 // Find the next render region 01435 pRegion2 = pNextRegion; 01436 } 01437 }
|
|
Tells RenderRegions that they should be afraid, very afraid, if they are holding a pointer to this node...
Definition at line 1245 of file rgnlist.cpp. 01246 { 01247 if (GetCount() == 0) 01248 return; 01249 01250 RenderRegion *pRegion = (RenderRegion *) GetHead(); 01251 01252 while (pRegion != NULL) 01253 { 01254 // Find the next region before this one is deleted 01255 RenderRegion* pNext = (RenderRegion *) GetNext(pRegion); 01256 01257 // TODO: Could attack the context pointer here as well! 01258 01259 // Make sure we're not holding onto a pointer to this node as the "backmost" 01260 pRegion->ClearBackmostChangedNode(pNode); 01261 // And hope that this region is about to get merged out of existence!!! 01262 01263 // Find the next render region 01264 pRegion = pNext; 01265 } 01266 01267 }
|
|
Finds all render regions associated with DocViews that have background rendering disabled, and renders them all immediately (i.e. to completion).
Definition at line 1140 of file rgnlist.cpp. 01141 { 01142 TRACE( wxT("Warning - RenderRegionList::ImmediateRender - removed code\n") ); 01143 // TRACE( _T("Look, I'm in RenderRegionList::ImmediateRender()\n")); 01144 01145 if ( CCamApp::IsDisabled() ) 01146 return; // If he has got the system disabled, ignore 01147 01148 #ifndef STANDALONE 01149 // Make sure printing is ok. 01150 if (!PrintMonitor::IsPrintStatusOK()) 01151 { 01152 // No - a print job has gone wrong, so we delete all printing render regions 01153 // before continuing. 01154 RenderRegion *pRender = (RenderRegion *) GetHead(); 01155 while (pRender != NULL) 01156 { 01157 if (pRender->IsPrinting()) 01158 { 01159 // Render region is printing (well it's not really as an exception 01160 // has occured) so delete it. 01161 Remove(pRender); 01162 delete pRender; 01163 } 01164 01165 // Try next region 01166 pRender = (RenderRegion *) GetNext(pRender); 01167 } 01168 01169 // Reset the last rendered render region 01170 LastRendered = NULL; 01171 } 01172 #endif 01173 if (GetCount() == 0) 01174 return; 01175 01176 PORTNOTE("other", "Disabled ControlHelper") 01177 #ifndef EXCLUDE_FROM_XARALX 01178 if (ControlHelper::IsUserInterfaceCaptured()) 01179 return; // No bg rendering if UI is captured (e.g. menu is up) 01180 #endif 01181 if (DragManagerOp::IsDragActive()) 01182 return; // No bg rendering if a DragManager op is active (NB this is for 01183 // colour/bitmap/bar drags only - not doc operation drags) 01184 01185 if(ViewOps::IsFullScreenPending()) // no bg rendering if we are about to enter full screen mode 01186 return; 01187 01188 // Optimise list based on render region percentage coverage 01189 TryTotalUnion(); 01190 RenderRegion *pRegion = (RenderRegion *) GetHead(); 01191 01192 // Start the rendering indicator going. 01193 if (GetApplication()->GetpStatusLine()) 01194 GetApplication()->GetpStatusLine()->SetRenderIndicator(Rendering); 01195 01196 while (pRegion != NULL) 01197 { 01198 // Find the next region before this one is deleted 01199 RenderRegion* pNext = (RenderRegion *) GetNext(pRegion); 01200 01201 if (pRegion->IsPrinting() == FALSE) 01202 { 01203 // If this render region's DocView does not have background rendering enabled, 01204 // then it must be an immediate render region, so render it. 01205 View *pView = pRegion->GetRenderView(); 01206 ENSURE(pView != NULL, "No DocView in ImmediateRender!"); 01207 01208 if ( !pView->GetForeBackMode() || bForceImmediate ) 01209 { 01210 // Keep user up to date 01211 if (GetApplication()->GetpStatusLine()) 01212 GetApplication()->GetpStatusLine()->SetRenderIndicator(Animate); 01213 //TRACE( _T("Immediate Render now\n")); 01214 01215 // Render it. 01216 Error::RenderThreadIn(); // Make errors close window 01217 pRegion->DefaultRender(bForceImmediate); 01218 Error::RenderThreadOut(); // Normal errors 01219 } 01220 } 01221 01222 // Find the next render region 01223 pRegion = pNext; 01224 } 01225 01226 // Disable rendering indicator. 01227 01228 if (GetApplication()->GetpStatusLine()) 01229 GetApplication()->GetpStatusLine()->SetRenderIndicator(NotRendering); 01230 }
|
|
Add a render region object to the application's global list of render regions.
Definition at line 336 of file rgnlist.cpp. 00337 { 00338 // If it's a printer region, just render it to completion and return, because 00339 // we don't do background printing yet. 00340 if (NewRenderRegion->IsPrinting()) 00341 { 00342 NewRenderRegion->DefaultRender(); 00343 return; 00344 } 00345 00346 // Adjust any render regions that are being scrolled away 00347 ClipRectsToClient(); 00348 00349 // TRACE( _T("RenderRegionList::Merge GetCount == %d\n"), GetCount()); 00350 00351 if (GetCount() == 0) 00352 { 00353 // Couldn't merge with any others, so just add it to the list. 00354 AddTail((ListItem *) NewRenderRegion); 00355 // IMMEDIATE REDRAW 00356 //#if _DEBUG 00357 // ImmediateRender(true); // Added by GAT 00358 //#endif 00359 return; 00360 } 00361 00362 // Find out how big a pixel is 00363 PixelWidth = NewRenderRegion->GetScaledPixelWidth(); 00364 00365 // Attempt to compact the list 00366 MergeRenderRegions(NewRenderRegion); 00367 00368 // Make sure that there are no render regions that overlap - ever! 00369 RemoveRegionOverlap(NewRenderRegion); 00370 00371 // add the New RenderRegion on the end of the List 00372 AddTail((ListItem *) NewRenderRegion); 00373 00374 // Go though all the regions in the list and try to strictly 00375 // merge them with all the other in the list 00376 TidyUpAdjacentRegions(NewRenderRegion); 00377 00378 // Set flag to indicate that one or more new regions have been added, and so we 00379 // should check for the possibility of merging all regions the next time we try a 00380 // background render. 00381 ListIsOptimal = FALSE; 00382 // IMMEDIATE REDRAW 00383 // ImmediateRender(); 00384 }
|
|
Attempts to find regions which can be merged together to make redrawing more efficient. At the moment, the two regions to be merged must satisfy the following conditions:.
They must be rendering into the same View and Chapter. One of the regions must completely enclose or be adjacent to the other.
Definition at line 573 of file rgnlist.cpp. 00574 { 00575 // set a flag to indicate if none of the render regions could be merged 00576 BOOL Merged; 00577 00578 // loop round until we can find no more render regions to merge together 00579 do 00580 { 00581 // We have not merged anything yet, so set the flag 00582 Merged = FALSE; 00583 00584 // Find the render region to merges clipping rectangle and context node 00585 DocRect MergeClipRect = pRegionToMerge->GetRegionRect(); 00586 00587 // Find which view the render region is to be rendering to 00588 View* MergeView = pRegionToMerge->GetRenderView(); 00589 00590 // Get the first render region in the list 00591 RenderRegion* pOldRegion = (RenderRegion*) GetHead(); 00592 RenderRegion* pNextRegion; 00593 00594 while (pOldRegion != NULL) 00595 { 00596 pNextRegion = (RenderRegion *) GetNext(pOldRegion); 00597 00598 if (pOldRegion != pRegionToMerge) 00599 { 00600 // Find this old render regions view 00601 View* OldView = pOldRegion->GetRenderView(); 00602 00603 // see if the two render regions can be merged 00604 if ( (MergeView == OldView) && 00605 (pOldRegion->GetRenderSpread()==pRegionToMerge->GetRenderSpread()) && 00606 (pOldRegion->CanBeMerged()) && (pRegionToMerge->CanBeMerged())) 00607 { 00608 // Find this regions clip rect 00609 DocRect OldClipRect = pOldRegion->GetRegionRect(); 00610 00611 // see if one of the render regions contains the other 00612 if (MergeClipRect.ContainsRect(OldClipRect)) 00613 { 00614 // Get rid of the region that is inside the other 00615 pRegionToMerge->SetBackmostChangedNode(pOldRegion->GetBackmostChangedNode()); 00616 pRegionToMerge->NeedsOSPaper = pRegionToMerge->NeedsOSPaper && pOldRegion->NeedsOSPaper; 00617 Remove(pOldRegion); 00618 delete pOldRegion; 00619 Merged = TRUE; 00620 break; 00621 } 00622 else if (OldClipRect.ContainsRect(MergeClipRect)) 00623 { 00624 // Get rid of the region that is inside the other 00625 // pRegionToMerge->SetClipRect(OldClipRect, TRUE); 00626 pRegionToMerge->SetBackmostChangedNode(pOldRegion->GetBackmostChangedNode()); 00627 pRegionToMerge->ResetRegion(OldClipRect); 00628 pRegionToMerge->NeedsOSPaper = pRegionToMerge->NeedsOSPaper && pOldRegion->NeedsOSPaper; 00629 Remove(pOldRegion); 00630 delete pOldRegion; 00631 Merged = TRUE; 00632 break; 00633 } 00634 else 00635 { 00636 // Find the smallest dimension of the new region 00637 INT32 ShortSide = MergeClipRect.Height(); 00638 if (MergeClipRect.Width() < ShortSide) 00639 ShortSide = MergeClipRect.Width(); 00640 00641 // Make sure that this figure is smaller than the sides 00642 ShortSide /= 3; 00643 00644 // Want a fuzzyness of at least 64 pixels 00645 INT32 MinFuzzy = PixelWidth * 64; 00646 if (ShortSide<MinFuzzy) 00647 ShortSide = MinFuzzy; 00648 00649 // If there is an overlap, then do some merging 00650 if (OldClipRect.IsAdjacent(MergeClipRect, ShortSide)) 00651 { 00652 DocRect ClipRect = OldClipRect.Union(MergeClipRect); 00653 // pRegionToMerge->SetClipRect(ClipRect, TRUE); 00654 pRegionToMerge->SetBackmostChangedNode(pOldRegion->GetBackmostChangedNode()); 00655 pRegionToMerge->ResetRegion(ClipRect); 00656 pRegionToMerge->NeedsOSPaper = pRegionToMerge->NeedsOSPaper && pOldRegion->NeedsOSPaper; 00657 Remove(pOldRegion); 00658 delete pOldRegion; 00659 Merged = TRUE; 00660 break; 00661 } 00662 } 00663 } 00664 } 00665 00666 // Get the next render region in the list 00667 // pOldRegion = (RenderRegion *) GetNext(pOldRegion); 00668 pOldRegion = pNextRegion; 00669 } 00670 } while( Merged ); 00671 }
|
|
Removes all render regions from the application's list of render regions that are associated with a particular document. Usually called because the document is being closed (deleted). It deletes all RenderRegion objects it removes.Removes all render regions from the application's list of render regions that are associated with a particular view. Usually called because the docview is being closed (deleted). It deletes all RenderRegion objects it removes.
Definition at line 979 of file rgnlist.cpp. 00980 { 00981 // Start at the beginning and try to find render regions attached to this CWnd object. 00982 RenderRegion *Item = (RenderRegion *) GetHead(); 00983 00984 while (Item != NULL) 00985 { 00986 // Is it the same as the View passed by the caller? 00987 if (Item->GetRenderView() == pView) 00988 { 00989 // Is it the LastRendered one? 00990 if (Item == LastRendered) 00991 { 00992 // Yes - so make LastRendered point to the previous render region 00993 // which means if Item is first in the list, LastRendered is set to 00994 // NULL, which is what we want - see BackgroundRender(). 00995 LastRendered = (RenderRegion *) GetPrev(Item); 00996 } 00997 00998 // Move to next region and remove this one from the list and delete it. 00999 RenderRegion *Tmp = Item; 01000 Item = (RenderRegion *) GetNext(Item); 01001 RemoveItem((ListItem *) Tmp); 01002 delete Tmp; 01003 } 01004 else 01005 // Try the next region 01006 Item = (RenderRegion *) GetNext(Item); 01007 } 01008 }
|
|
|
|
Removes a render region from the application's list of render regions, It DOES NOT delete the RenderRegion object itself. This is used when the region has been completely rendered and is no longer needed.
Definition at line 864 of file rgnlist.cpp. 00865 { 00866 ENSURE( FindPosition(RegionToRemove) != NOT_IN_LIST, 00867 "Could not find RenderRegion to Remove" ); 00868 00869 // Is it the LastRendered one? 00870 if (RegionToRemove == LastRendered) 00871 { 00872 // Yes - so make LastRendered point to the previous render region 00873 // which means if Item is first in the list, LastRendered is set to 00874 // NULL, which is what we want - see BackgroundRender(). 00875 LastRendered = (RenderRegion *) GetPrev(RegionToRemove); 00876 } 00877 00878 // Remove the item from the list 00879 RemoveItem((ListItem *) RegionToRemove); 00880 00881 }
|
|
Called when adding a new render region to the list. It checks the new render region for overlap with all the old render regions and if it overlapps any of them, the old region is slit up. This function should guarantee that you never get render regions that overlap, so that the EORed stuff does not get screwed up by getting rendered more than once.
Definition at line 691 of file rgnlist.cpp. 00692 { 00693 // Find the clipping rect of the new render region 00694 DocRect NewClipRect = NewRenderRegion->GetRegionRect(); 00695 DocRect OldClipRect; 00696 00697 // Find which view and spread the render region is to be rendering to 00698 View* NewView = NewRenderRegion->GetRenderView(); 00699 Spread* NewSpread = NewRenderRegion->GetRenderSpread(); 00700 00701 // Get the first render region in the list 00702 RenderRegion* pOldRegion = (RenderRegion*) GetHead(); 00703 00704 while (pOldRegion != NULL) 00705 { 00706 // Get the old render regions clipping rectangle 00707 OldClipRect = pOldRegion->GetRegionRect(); 00708 00709 // Find which view and spread the render region is to be rendering to 00710 View* OldView = pOldRegion->GetRenderView(); 00711 Spread* OldSpread = pOldRegion->GetRenderSpread(); 00712 00713 // If they intersect, split the old rectangle up into bits 00714 if ((OldView==NewView) && (OldSpread==NewSpread) && 00715 (OldClipRect.IsIntersectedWith(NewClipRect))) 00716 { 00717 if (NewClipRect.ContainsRect(OldClipRect)) 00718 { 00719 // The 2 regions were the same, so get rid of it, and go back around 00720 // the loop with the next region in the list. 00721 NewRenderRegion->SetBackmostChangedNode(pOldRegion->GetBackmostChangedNode()); 00722 NewRenderRegion->NeedsOSPaper = NewRenderRegion->NeedsOSPaper && pOldRegion->NeedsOSPaper; 00723 RenderRegion *Tmp = pOldRegion; 00724 pOldRegion = (RenderRegion *) GetNext(pOldRegion); 00725 Remove(Tmp); 00726 delete Tmp; 00727 continue; 00728 } 00729 else 00730 { 00731 // Split the old rect into sub-rects and add the new one 00732 DocRect SubRects[4]; 00733 INT32 RectCount = OldClipRect.SplitRect(NewClipRect, SubRects); 00734 ENSURE( RectCount!=0, "No rectangles found in SplitRect" ); 00735 00736 // Change the clip rect of the region already in the list 00737 // pOldRegion->ResizeRegion(SubRects[0]); 00738 // pOldRegion->SetClipRect(SubRects[0]); 00739 pOldRegion->ResetRegion(SubRects[0]); 00740 00741 // and create some new render regions if needed 00742 for (INT32 i=1; i<RectCount; i++) 00743 { 00744 // Create a new render region. 00745 // NB. important to pass in View pointer so that we get correct bitmap depth. 00746 RenderRegion* SubRenderRegion = OSRenderRegion::Create(SubRects[i], 00747 pOldRegion->GetMatrix(), 00748 OldView->GetViewScale(), 00749 RENDERTYPE_SCREEN, 00750 NewView); 00751 00752 //OSRenderRegion* SubRenderRegion = new OSRenderRegion(*(OSRenderRegion*)pOldRegion); 00753 00754 ENSURE( SubRenderRegion != NULL, "RenderRegionList::Merge: SubRenderRegion == 0"); 00755 if (SubRenderRegion == NULL) 00756 return; 00757 00758 // Set the new clip region and see if it joins exactly 00759 if (!SubRenderRegion->CopyRenderInfo(*pOldRegion)) 00760 { 00761 // copying failed, so tidy up 00762 delete SubRenderRegion; 00763 TRACE( _T("CopyRenderInfo %d failed\n"), i); 00764 continue; // carry on round loop 00765 } 00766 00767 // make sure the region is re-rendered 00768 // SubRenderRegion->IsPaperRendered = FALSE; 00769 // SubRenderRegion->IsInkRenderStarted = FALSE; 00770 00771 // SubRenderRegion->SetClipRect(SubRects[i]); 00772 SubRenderRegion->ResetRegion(SubRects[i]); 00773 // SubRenderRegion->ResizeRegion(SubRects[i]); 00774 StrictMerge(SubRenderRegion); 00775 } 00776 } 00777 } 00778 00779 // Get the next region in the list 00780 pOldRegion = (RenderRegion*) GetNext(pOldRegion); 00781 } 00782 }
|
|
Tries to merge the render region supplied with the rest of the list. They must be exactly adjacent ie. They don't intersect, and the union contains no area outside the two rectangles.
Definition at line 483 of file rgnlist.cpp. 00484 { 00485 // set a flag to indicate if none of the render regions could be merged 00486 BOOL Merged; 00487 00488 // loop round until we can find no more render regions to merge together 00489 do 00490 { 00491 // We have not merged anything yet, so set the flag 00492 Merged = FALSE; 00493 00494 // Find the render region to merges clipping rectangle and context node and 00495 // find which view the render region is to be rendering to 00496 DocRect MergeClipRect = pRegionToMerge->GetRegionRect(); 00497 View* MergeView = pRegionToMerge->GetRenderView(); 00498 Node* NewContext = pRegionToMerge->GetRenderState(); 00499 00500 // Get the first render region in the list 00501 RenderRegion* pOldRegion = (RenderRegion*) GetHead(); 00502 RenderRegion* pNextRegion; 00503 00504 while (pOldRegion != NULL) 00505 { 00506 pNextRegion = (RenderRegion *) GetNext(pOldRegion); 00507 00508 // Find this old render regions view 00509 View* OldView = pOldRegion->GetRenderView(); 00510 Node* OldContext = pOldRegion->GetRenderState(); 00511 00512 // see if the two render regions can be merged 00513 if ( (MergeView == OldView) && 00514 (pOldRegion->GetRenderSpread()==pRegionToMerge->GetRenderSpread()) && 00515 ((OldContext==NewContext) || 00516 ((pOldRegion->CanBeMerged()) && (pRegionToMerge->CanBeMerged())))) 00517 { 00518 // Find this regions clip rect 00519 DocRect OldClipRect = pOldRegion->GetRegionRect(); 00520 00521 // see if one of the render regions is EXACTLY adjacent to this one 00522 if (OldClipRect.IsAdjacent(MergeClipRect, 0)) 00523 { 00524 DocRect ClipRect = OldClipRect.Union(MergeClipRect); 00525 00526 // Set the clip rect and get the render region to find its starting context node again 00527 // as things could have changed. 00528 // pRegionToMerge->SetClipRect(ClipRect, TRUE); 00529 pRegionToMerge->ResetRegion(ClipRect); 00530 Remove(pOldRegion); 00531 delete pOldRegion; 00532 Merged = TRUE; 00533 break; 00534 } 00535 } 00536 00537 // Get the next render region in the list 00538 // pOldRegion = (RenderRegion *) GetNext(pOldRegion); 00539 pOldRegion = pNextRegion; 00540 } 00541 } while( Merged ); 00542 00543 AddTail( (ListItem *) pRegionToMerge); 00544 }
|
|
Goes through all the regions in the list and tests to see if any of them line up exactly. If they do, they are joined into a single region.
Definition at line 401 of file rgnlist.cpp. 00402 { 00403 // Need to perform an Nsquared loop through the regions 00404 RenderRegion* pRegion = (RenderRegion*) GetHead(); 00405 00406 while(pRegion!=NULL) 00407 { 00408 // Get info about the region that we will need to test 00409 DocRect MergeClipRect = pRegion->GetRegionRect(); 00410 View* MergeView = pRegion->GetRenderView(); 00411 Node* NewContext = pRegion->GetRenderState(); 00412 00413 // Find the region after pRegion to start searching from 00414 RenderRegion* pCompare = (RenderRegion*) GetNext(pRegion); 00415 00416 // loop through all the regions that come after pRegion 00417 // see if any are suitbale for merging 00418 while(pCompare!=NULL) 00419 { 00420 // Find the next one now, as we may delete pCompare on the way through 00421 RenderRegion* pNextOne = (RenderRegion*) GetNext(pCompare); 00422 00423 // We do not want to delete the brand new region, we should delete the others first 00424 if (pCompare!=pBrandNewRegion) 00425 { 00426 // Find the equivalent information in this region ready for testing 00427 View* OldView = pCompare->GetRenderView(); 00428 Node* OldContext = pCompare->GetRenderState(); 00429 00430 // See if they can be merged 00431 if ( (MergeView == OldView) && 00432 (pRegion->GetRenderSpread()==pCompare->GetRenderSpread()) && 00433 ((OldContext==NewContext) || 00434 ((pRegion->CanBeMerged()) && (pCompare->CanBeMerged())))) 00435 { 00436 // So far so good. Just check that they are adjacent 00437 // Find this regions clip rect 00438 DocRect OldClipRect = pCompare->GetRegionRect(); 00439 00440 // see if one of the render regions is EXACTLY adjacent to this one 00441 if (OldClipRect.IsAdjacent(MergeClipRect, 0)) 00442 { 00443 DocRect ClipRect = OldClipRect.Union(MergeClipRect); 00444 00445 // Set the clip rect of one of the regions to be the union of both regions 00446 // pRegion->SetClipRect(ClipRect, TRUE); 00447 pRegion->SetBackmostChangedNode(pCompare->GetBackmostChangedNode()); 00448 pRegion->ResetRegion(ClipRect); 00449 00450 // Get rid of the other region 00451 Remove(pCompare); 00452 delete pCompare; 00453 } 00454 } 00455 } 00456 00457 // Get the next region 00458 pCompare = pNextOne; 00459 } 00460 00461 // Get the next region in the outer loop 00462 pRegion = (RenderRegion*) GetNext(pRegion); 00463 } 00464 }
|
|
For each DocView, try to union all the render regions, and see if the individual areas add up to more than 70% of the union area. If they do then we union all the regions together and just render one big one.
Definition at line 1284 of file rgnlist.cpp. 01285 { 01286 if (ListIsOptimal) 01287 // No need to do our checks 01288 return; 01289 01290 DocRect TotalUnion; 01291 01292 // List of DocViews we have optimised so far 01293 ViewList Views; 01294 01295 // Go through each render region, and for each View, work out if it's worth 01296 // merging all the rectangles into one. 01297 RenderRegion *pRegion = (RenderRegion *) GetHead(); 01298 01299 while (pRegion != NULL) 01300 { 01301 View *pView = pRegion->GetRenderView(); 01302 Spread* pSpread = pRegion->GetRenderSpread(); 01303 01304 // Have we optimised this region's View already? 01305 if (!Views.IsViewOptimised(pView)) 01306 { 01307 // Haven't done this one yet - add it to the list for future reference 01308 if (!Views.AddView(pView)) 01309 { 01310 // Error - abort merging 01311 Views.DeleteAll(); 01312 return; 01313 } 01314 01315 // We only do this merging for regions that have not started ink rendering yet. 01316 if (pRegion->CanBeMerged()) 01317 { 01318 // Get the union of all regions in this View, and the total area of them 01319 RenderRegion *pRegion2 = pRegion; 01320 01321 // Indicates whether to test the percentage coverage - we don't if either: 01322 // (a) This View has only one region, or 01323 // (b) This View has regions which have started drawing ink already. 01324 BOOL TryUnion = FALSE; 01325 01326 DocRect TotalUnion; 01327 double CombinedArea = 0.0; 01328 01329 while (pRegion2 != NULL) 01330 { 01331 // Is this the correct View and render context? 01332 if (pRegion2->GetRenderView() == pView && 01333 pRegion2->GetRenderSpread() == pSpread 01334 ) 01335 { 01336 // More than one region - we can try to union them 01337 TryUnion = TRUE; 01338 01339 // Have we started rendering the ink into this region yet? 01340 if (!pRegion2->CanBeMerged()) 01341 { 01342 // Yes, and we can't union if any have started rendering ink 01343 TryUnion = FALSE; 01344 01345 // Quit the while loop 01346 break; 01347 } 01348 else 01349 { 01350 // No - so accumulate this region. 01351 DocRect ClipRect = pRegion2->GetRegionRect(); 01352 TotalUnion = TotalUnion.Union(ClipRect); 01353 CombinedArea += ((double) ClipRect.Width()) * ((double) ClipRect.Height()); 01354 } 01355 } 01356 01357 // Find the next render region 01358 pRegion2 = (RenderRegion *) GetNext(pRegion2); 01359 } 01360 01361 if (TryUnion) 01362 { 01363 // Ok - if the combined area is 70% or more of the area of the union, then 01364 // we might as well union all these regions. 01365 double UnionArea = (double) TotalUnion.Width() * (double) TotalUnion.Height(); 01366 double Coverage = CombinedArea / UnionArea; 01367 01368 if (Coverage > 0.60) 01369 { 01370 // Yes - let's union all these regions 01371 DoTotalUnion(pRegion, pView, TotalUnion); 01372 } 01373 } 01374 } 01375 } 01376 01377 // Find the next render region 01378 pRegion = (RenderRegion *) GetNext(pRegion); 01379 } 01380 01381 // Don't bother with this again unless a new render region is added. 01382 ListIsOptimal = TRUE; 01383 }
|
|
|
|
|
|
|