123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744 |
- <!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
-
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <title>Detailed Design Template</title>
- </head>
- <body>
-
- <h1><font color="#cc0000">Gecko Layout Detailed Design Document</font></h1>
-
- <h1>Space Manager Detailed Design</h1>
-
- <h2>Overview</h2>
- <p>
- The Space Manager and related classes and structures are an important of
- the Gecko Layout system, specifically Block Layout. See the High Level
- Design document for an overview of the Space Manager, and as an introduction
- to the classes, structures and algorithms container in this, the Detailed
- Design Document.
- </p>
-
-
- <hr width="100%" size="2">
- <h2>nsSpaceManager</h2>
- <p>
- The Space Manager is the central class is a group of classes that manage
- the occupied and available space that exists in horizontal bands across
- a canvas. The primary goal of the Space Manager is to provide information
- about those bands of space to support the CSS notion of floated elements.
- </p>
-
- <p>
- There are three important parts to the Space Manager API: the parts that
- deal with the coordinate space of the Space Manager, the parts that deal with
- the regions managed by the Space Manager, and the parts that manage float
- impact intervals.
- </p>
-
- <p>
- The class nsSpaceManager is declared in the file <a href="http://lxr.mozilla.org/seamonkey/source/layout/base/src/nsSpaceManager.h">
- nsSpaceManger.h</a>
- . The class is only used in the layout module and cannot be exported
- outside of that module (nor does it need to be). It is not a general
- purpose class, and is not intended to be subclasses<font color="#cc0000">
- .</font>
- </p>
-
- <p>
- Here is the class declaration, taken from the source file as of 01.08.02
- </p>
-
-
- <pre>/**
- * Class for dealing with bands of available space. The space manager
- * defines a coordinate space with an origin at (0, 0) that grows down
- * and to the right.
- */
- class nsSpaceManager {
- public:
- nsSpaceManager(nsIPresShell* aPresShell, nsIFrame* aFrame);
- ~nsSpaceManager();
- void* operator new(size_t aSize);
- void operator delete(void* aPtr, size_t aSize);
- static void Shutdown();
- /*
- * Get the frame that's associated with the space manager. This frame
- * created the space manager, and the world coordinate space is
- * relative to this frame.
- *
- * You can use QueryInterface() on this frame to get any additional
- * interfaces.
- */
- nsIFrame* GetFrame() const { return mFrame; }
- /**
- * Translate the current origin by the specified (dx, dy). This
- * creates a new local coordinate space relative to the current
- * coordinate space.
- */
- void Translate(nscoord aDx, nscoord aDy) { mX += aDx; mY += aDy; }
- /**
- * Returns the current translation from local coordinate space to
- * world coordinate space. This represents the accumulated calls to
- * Translate().
- */
- void GetTranslation(nscoord& aX, nscoord& aY) const { aX = mX; aY = mY; }
- /**
- * Returns the y-most of the bottommost band or 0 if there are no bands.
- *
- * @return PR_TRUE if there are bands and PR_FALSE if there are no bands
- */
- PRBool YMost(nscoord& aYMost) const;
- /**
- * Returns a band starting at the specified y-offset. The band data
- * indicates which parts of the band are available, and which parts
- * are unavailable
- *
- * The band data that is returned is in the coordinate space of the
- * local coordinate system.
- *
- * The local coordinate space origin, the y-offset, and the max size
- * describe a rectangle that's used to clip the underlying band of
- * available space, i.e.
- * {0, aYOffset, aMaxSize.width, aMaxSize.height} in the local
- * coordinate space
- *
- * @param aYOffset the y-offset of where the band begins. The coordinate is
- * relative to the upper-left corner of the local coordinate space
- * @param aMaxSize the size to use to constrain the band data
- * @param aBandData [in,out] used to return the list of trapezoids that
- * describe the available space and the unavailable space
- * @return NS_OK if successful and NS_ERROR_FAILURE if the band data is not
- * not large enough. The 'count' member of the band data struct
- * indicates how large the array of trapezoids needs to be
- */
- nsresult GetBandData(nscoord aYOffset,
- const nsSize& aMaxSize,
- nsBandData& aBandData) const;
- /**
- * Add a rectangular region of unavailable space. The space is
- * relative to the local coordinate system.
- *
- * The region is tagged with a frame
- *
- * @param aFrame the frame used to identify the region. Must not be NULL
- * @param aUnavailableSpace the bounding rect of the unavailable space
- * @return NS_OK if successful
- * NS_ERROR_FAILURE if there is already a region tagged with aFrame
- */
- nsresult AddRectRegion(nsIFrame* aFrame,
- const nsRect& aUnavailableSpace);
- /**
- * Resize the rectangular region associated with aFrame by the specified
- * deltas. The height change always applies to the bottom edge or the existing
- * rect. You specify whether the width change applies to the left or right edge
- *
- * Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- enum AffectedEdge {LeftEdge, RightEdge};
- nsresult ResizeRectRegion(nsIFrame* aFrame,
- nscoord aDeltaWidth,
- nscoord aDeltaHeight,
- AffectedEdge aEdge = RightEdge);
- /**
- * Offset the region associated with aFrame by the specified amount.
- *
- * Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- nsresult OffsetRegion(nsIFrame* aFrame, nscoord dx, nscoord dy);
- /**
- * Remove the region associated with aFrane.
- *
- * Returns NS_OK if successful and NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- nsresult RemoveRegion(nsIFrame* aFrame);
- /**
- * Clears the list of regions representing the unavailable space.
- */
- void ClearRegions();
- /**
- * Methods for dealing with the propagation of float damage during
- * reflow.
- */
- PRBool HasFloatDamage()
- {
- return !mFloatDamage.IsEmpty();
- }
- void IncludeInDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
- {
- mFloatDamage.IncludeInterval(aIntervalBegin + mY, aIntervalEnd + mY);
- }
- PRBool IntersectsDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
- {
- return mFloatDamage.Intersects(aIntervalBegin + mY, aIntervalEnd + mY);
- }
- #ifdef DEBUG
- /**
- * Dump the state of the spacemanager out to a file
- */
- nsresult List(FILE* out);
- void SizeOf(nsISizeOfHandler* aHandler, uint32_t* aResult) const;
- #endif
- private:
- // Structure that maintains information about the region associated
- // with a particular frame
- struct FrameInfo {
- nsIFrame* const mFrame;
- nsRect mRect; // rectangular region
- FrameInfo* mNext;
- FrameInfo(nsIFrame* aFrame, const nsRect& aRect);
- #ifdef NS_BUILD_REFCNT_LOGGING
- ~FrameInfo();
- #endif
- };
- // Doubly linked list of band rects
- struct BandRect : PRCListStr {
- nscoord mLeft, mTop;
- nscoord mRight, mBottom;
- int32_t mNumFrames; // number of frames occupying this rect
- union {
- nsIFrame* mFrame; // single frame occupying the space
- nsVoidArray* mFrames; // list of frames occupying the space
- };
- BandRect(nscoord aLeft, nscoord aTop,
- nscoord aRight, nscoord aBottom,
- nsIFrame*);
- BandRect(nscoord aLeft, nscoord aTop,
- nscoord aRight, nscoord aBottom,
- nsVoidArray*);
- ~BandRect();
- // List operations
- BandRect* Next() const {return (BandRect*)PR_NEXT_LINK(this);}
- BandRect* Prev() const {return (BandRect*)PR_PREV_LINK(this);}
- void InsertBefore(BandRect* aBandRect) {PR_INSERT_BEFORE(aBandRect, this);}
- void InsertAfter(BandRect* aBandRect) {PR_INSERT_AFTER(aBandRect, this);}
- void Remove() {PR_REMOVE_LINK(this);}
- // Split the band rect into two vertically, with this band rect becoming
- // the top part, and a new band rect being allocated and returned for the
- // bottom part
- //
- // Does not insert the new band rect into the linked list
- BandRect* SplitVertically(nscoord aBottom);
- // Split the band rect into two horizontally, with this band rect becoming
- // the left part, and a new band rect being allocated and returned for the
- // right part
- //
- // Does not insert the new band rect into the linked list
- BandRect* SplitHorizontally(nscoord aRight);
- // Accessor functions
- PRBool IsOccupiedBy(const nsIFrame*) const;
- void AddFrame(const nsIFrame*);
- void RemoveFrame(const nsIFrame*);
- PRBool HasSameFrameList(const BandRect* aBandRect) const;
- int32_t Length() const;
- };
- // Circular linked list of band rects
- struct BandList : BandRect {
- BandList();
- // Accessors
- PRBool IsEmpty() const {return PR_CLIST_IS_EMPTY((PRCListStr*)this);}
- BandRect* Head() const {return (BandRect*)PR_LIST_HEAD(this);}
- BandRect* Tail() const {return (BandRect*)PR_LIST_TAIL(this);}
- // Operations
- void Append(BandRect* aBandRect) {PR_APPEND_LINK(aBandRect, this);}
- // Remove and delete all the band rects in the list
- void Clear();
- };
- FrameInfo* GetFrameInfoFor(nsIFrame* aFrame);
- FrameInfo* CreateFrameInfo(nsIFrame* aFrame, const nsRect& aRect);
- void DestroyFrameInfo(FrameInfo*);
- void ClearFrameInfo();
- void ClearBandRects();
- BandRect* GetNextBand(const BandRect* aBandRect) const;
- void DivideBand(BandRect* aBand, nscoord aBottom);
- PRBool CanJoinBands(BandRect* aBand, BandRect* aPrevBand);
- PRBool JoinBands(BandRect* aBand, BandRect* aPrevBand);
- void AddRectToBand(BandRect* aBand, BandRect* aBandRect);
- void InsertBandRect(BandRect* aBandRect);
- nsresult GetBandAvailableSpace(const BandRect* aBand,
- nscoord aY,
- const nsSize& aMaxSize,
- nsBandData& aAvailableSpace) const;
- nsIFrame* const mFrame; // frame associated with the space manager
- nscoord mX, mY; // translation from local to global coordinate space
- BandList mBandList; // header/sentinel for circular linked list of band rects
- FrameInfo* mFrameInfoMap;
- nsIntervalSet mFloatDamage;
- static int32_t sCachedSpaceManagerCount;
- static void* sCachedSpaceManagers[NS_SPACE_MANAGER_CACHE_SIZE];
- nsSpaceManager(const nsSpaceManager&); // no implementation
- void operator=(const nsSpaceManager&); // no implementation
- };
- </pre>
-
- <h3>Public API</h3>
-
- <h4>Life Cycle:</h4>
- <p>
- The Constructor requires a Presentation Shell, used for arena allocations
- mostly, and a frame that this Space Manager is rooted on. The coordinate
- space of this Space Manager is relative to the frame passed in to the constructor.
- </p>
-
- <pre> nsSpaceManager(nsIPresShell* aPresShell, nsIFrame* aFrame);
- ~nsSpaceManager();
- </pre>
- <p>
- Operators 'new' and 'delete' are overridden to support a recycler. Space
- Manager instances come and go pretty frequently, and this recycler prevents
- excessive heap allocations and the performance penalties associated with
- it. The #define NS_SPACE_MANAGER_CACHE_SIZE is used to control the number
- of Space Manager instances that can be present in the recycler, currently
- 4. If more than NS_SPACE_MANAGER_CACHE_SIZE are allocated at a time,
- then standard allocation is used.
- </p>
-
- <pre>
- void* operator new(size_t aSize);
- void operator delete(void* aPtr, size_t aSize);
- </pre>
- <p>
- A Static method is used to shutdown the Space Manager recycling. This
- method deletes all of the Space Mangers inthe recycler,and prevents further
- recycling. It is meant to be called only when the layout module is being
- terminated.
- </p>
-
- <pre> static void Shutdown();
- </pre>
-
- <h4>Origin / Coordinate Space Translation</h4>
-
- <pre> /**
- * Translate the current origin by the specified (dx, dy). This
- * creates a new local coordinate space relative to the current
- * coordinate space.
- */
- void Translate(nscoord aDx, nscoord aDy) { mX += aDx; mY += aDy; }
- /**
- * Returns the current translation from local coordinate space to
- * world coordinate space. This represents the accumulated calls to
- * Translate().
- */
- void GetTranslation(nscoord& aX, nscoord& aY) const { aX = mX; aY = mY; }
- /**
- * Returns the y-most of the bottommost band or 0 if there are no bands.
- *
- * @return PR_TRUE if there are bands and PR_FALSE if there are no bands
- */
- PRBool YMost(nscoord& aYMost) const;
- </pre>
-
- <h4>Region Management</h4>
-
- <pre> /**
- * Returns a band starting at the specified y-offset. The band data
- * indicates which parts of the band are available, and which parts
- * are unavailable
- *
- * The band data that is returned is in the coordinate space of the
- * local coordinate system.
- *
- * The local coordinate space origin, the y-offset, and the max size
- * describe a rectangle that's used to clip the underlying band of
- * available space, i.e.
- * {0, aYOffset, aMaxSize.width, aMaxSize.height} in the local
- * coordinate space
- *
- * @param aYOffset the y-offset of where the band begins. The coordinate is
- * relative to the upper-left corner of the local coordinate space
- * @param aMaxSize the size to use to constrain the band data
- * @param aBandData [in,out] used to return the list of trapezoids that
- * describe the available space and the unavailable space
- * @return NS_OK if successful and NS_ERROR_FAILURE if the band data is not
- * not large enough. The 'count' member of the band data struct
- * indicates how large the array of trapezoids needs to be
- */
- nsresult GetBandData(nscoord aYOffset,
- const nsSize& aMaxSize,
- nsBandData& aBandData) const;
- /**
- * Add a rectangular region of unavailable space. The space is
- * relative to the local coordinate system.
- *
- * The region is tagged with a frame
- *
- * @param aFrame the frame used to identify the region. Must not be NULL
- * @param aUnavailableSpace the bounding rect of the unavailable space
- * @return NS_OK if successful
- * NS_ERROR_FAILURE if there is already a region tagged with aFrame
- */
- nsresult AddRectRegion(nsIFrame* aFrame,
- const nsRect& aUnavailableSpace);
- /**
- * Resize the rectangular region associated with aFrame by the specified
- * deltas. The height change always applies to the bottom edge or the existing
- * rect. You specify whether the width change applies to the left or right edge
- *
- * Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- enum AffectedEdge {LeftEdge, RightEdge};
- nsresult ResizeRectRegion(nsIFrame* aFrame,
- nscoord aDeltaWidth,
- nscoord aDeltaHeight,
- AffectedEdge aEdge = RightEdge);
- /**
- * Offset the region associated with aFrame by the specified amount.
- *
- * Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- nsresult OffsetRegion(nsIFrame* aFrame, nscoord dx, nscoord dy);
- /**
- * Remove the region associated with aFrane.
- *
- * Returns NS_OK if successful and NS_ERROR_INVALID_ARG if there is no region
- * tagged with aFrame
- */
- nsresult RemoveRegion(nsIFrame* aFrame);
- /**
- * Clears the list of regions representing the unavailable space.
- */
- void ClearRegions();
- </pre>
-
- <h4>Float Impact</h4>
-
- <pre> /**
- * Methods for dealing with the propagation of float damage during
- * reflow.
- */
- PRBool HasFloatDamage()
- {
- return !mFloatDamage.IsEmpty();
- }
- void IncludeInDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
- {
- mFloatDamage.IncludeInterval(aIntervalBegin + mY, aIntervalEnd + mY);
- }
- PRBool IntersectsDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
- {
- return mFloatDamage.Intersects(aIntervalBegin + mY, aIntervalEnd + mY);
- }
- </pre>
-
- <h4>Debug Only Methods</h4>
-
- <pre> /**
- * Dump the state of the spacemanager out to a file
- */
- nsresult List(FILE* out);
- void SizeOf(nsISizeOfHandler* aHandler, uint32_t* aResult) const;
- </pre>
-
- <h4>Unused / Obsolete Methods</h4>
-
- <pre> /*
- * Get the frame that's associated with the space manager. This frame
- * created the space manager, and the world coordinate space is
- * relative to this frame.
- *
- * You can use QueryInterface() on this frame to get any additional
- * interfaces.
- */
- nsIFrame* GetFrame() const { return mFrame; }
- </pre>
-
- <h3>Implementation Notes</h3>
-
- <h4></h4>
-
- <h4>Algorithm 1: GetBandData</h4>
- <p>
- GetBandData is used to provide information to clients about what space if
- available and unavailable in a band of space. The client provides a
- vertical offset, the yOffset, that corresponds to the band that is of interest.
- This will be the y offset of the frame that is being reflowed. The
- caller also provides a collection of BandData objects (an array) and the
- number of items that the collection can handle. If the collection is
- too small, then an error is returned and the count is updated to indicate
- the size required.
- </p>
- <p>
- The algorithm to provide the band data is as follows:
- </p>
- <ul>
- <li>Get a vertical offset in world coordinates (instead of frame-relative
- coordinates) by adding the y-origin of the SpaceManager to the y offset passed
- in</li>
- <li>If the (adjusted) y value passed in is greater than the greatest band
- being managed, then all space is available so a single trapezoid is returned,
- marked as available and sized to the maximum size value (passed in).</li>
- <li>If the (adjusted) y offset intersects a band, then gather the band
- data:</li>
- <ul>
- <li>walk the internal bandData list from head to tail</li>
- <li>for each band data entry, see if the top of the band is greater than
- the (adjusted) y offset requested</li>
- <li>if it is, then band is below the offset requested, so the area between
- the band and the y offset is available - create a trapezoid with that region
- and return it.</li>
- <li>if the (adjusted) y offset is between the band top and bottom, then
- get the available space for the band by calling GetBandAvailableSpace</li>
- <li>otherwise, move to the next band</li>
- </ul>
- </ul>
- <h5>GetBandAvailableSpace:</h5>
- This method is called from GetBandData only. It walks all of the bands in
- the space manager and determines which bands intersect with the band passed
- in, and if within those bands there are regions that are available or occupied.
- <ul>
- <li>First, walk all of the bands until a band that is to the right of the
- desired offset is located</li>
- <li>Starting at that band, walk the remaining bands:</li>
- <ul>
- <li>if the current band is to the right of the requested band, then there
- is available space. </li>
- <ul>
- <li>if there is more room in the bandData collection, then add a trapezoid
- to the bandData collection such that it is marked as available and has a
- rect that represents the space between the reference band tna dht band being
- examined</li>
- <li>if there is no more room in the BandData collection, estimate the
- number of entries requires as the current count + twice the number of bands
- below the reference band, plus two. Return an error code so the caller
- can reallocate the collection and try again.</li>
- </ul>
- <li>check the size of the collection again, if there is no room left
- then estimate the number of items requires as the current count + twice the
- number of bands below the band in question plus one. </li>
- <li>create a new trapezoid in the band collection that has a region corresponding
- to the reference band rect, marked as occupied by either a single or multiple
- frames.</li>
- <li>move to the next band</li>
- </ul>
- <li>after walking all of the band data, se if we have reached the right
- edge of the band. </li>
- <ul>
- <li>If not, then check for space in the band collection</li>
- <ul>
- <li>if there is no room left, then set the count to the current count
- plus 1 and return an error.</li>
- <li>otherwise, create another entry in the band collection, marked
- as available, and with a rect corresponding to the area remainin in the band
- (eg. from the right edge of the last band rect to the right edge of the band).</li>
- </ul>
- </ul>
- </ul>
-
- <h4>Algorithm 2: AddRectRegion</h4>
- Clients call into this method to notify the Space Manager that a new frame
- is occupying some space.
- <ul>
- <li>First, try to get frame info for the frame. If it is found, return
- an error since the frame is already associated with a region in the Space
- Manager.</li>
- <li>Next, create a rect from the occupied space passed in by the caller,
- transforming it first to world-coordinates by adding the Space Manager's
- offset to the occupied space rect passed in.</li>
- <li>Create a new Frame Info instance for the frame and rect, returning
- an error if allocation fails.</li>
- <li>Check if the occupied space rect (adjusted) is empty, if so, return
- an error (<font color="#cc0000">NOTE: this could be done earlier, or
- prevented by the caller</font>)</li>
- <li>Allocate a new BandRect instance with the rect and frame as constructor
- arguments, and insert it into the collection via InsertBandRect</li>
- </ul>
- <h5>InsertBandRect:</h5>
- Internal method to insert a band rect into the BandList in the correct location.
- There are several cases it has to handle, as specified in the source file
- comments:
- <pre>// When comparing a rect to a band there are seven cases to consider.
- // 'R' is the rect and 'B' is the band.
- //
- // Case 1 Case 2 Case 3 Case 4
- // ------ ------ ------ ------
- // +-----+ +-----+ +-----+ +-----+
- // | R | | R | +-----+ +-----+ | | | |
- // +-----+ +-----+ | | | R | | B | | B |
- // +-----+ | B | +-----+ | | +-----+ | |
- // | | | | +-----+ | R | +-----+
- // | B | +-----+ +-----+
- // | |
- // +-----+
- //
- //
- //
- // Case 5 Case 6 Case 7
- // ------ ------ ------
- // +-----+ +-----+ +-----+ +-----+
- // | | | R | | B | | | +-----+
- // | B | +-----+ +-----+ | R | | B |
- // | | | | +-----+
- // +-----+ +-----+
- // +-----+
- // | R |
- // +-----+
- //
- </pre>
- <ul>
- <li>First, check for the easiest case, where there are no existing band
- rects, or the band rect passed in is below the bottommost rect. In this case,
- just append the band rect and return.</li>
- <li>Starting at the head of the list of bandRects, check for intersection
- with the rect passed in:</li>
- <ul>
- <li>case #1: the rect is totally above the current band rect, so insert
- a new band rect before the current bandRect</li>
- <li>cases #2 and #7: the rect is partially above the band rect, so it
- is divided into two bandRects, one entirely above the band, and one containing
- the remainder of the rect. Insert the part that is totally above the
- bandRect before the current bandRect, as in case #1 above, and adjust the
- other band rect to exclude the part already added.</li>
- <li>case #5: the rect is totally below the current bandRect, so just
- skip to the next band</li>
- <li>case #3 and #4: rect is at least partially intersection with the
- bandRect, so divide the current band into two parts, where the top part is
- above the current rect. Move to the new band just created, which is
- the next band.</li>
- <li>case #6: the rect shares the bottom and height with the bandRect,
- so just add the rect to the band.</li>
- <li>case #4 and #7: create a new rect for the part that overlaps the
- bandRect, and add it to the current bandRect (similar to case #6) and then
- move on to the next band, removing that part from the rect passed in. If
- no more bands, append the rect passed in to the end of the bandRect list.</li>
- </ul>
- </ul>
- <i>This algorithm is pretty confusing - basically what needs to happen is
- that rects and bands need to be divided up so that complicated cases like
- #2, #4, and #7, are reduced to simpler cases where the rects is totally above,
- below, or between a band rect. From the current implementation, it
- might be worth verifying that the final result of the inserts is a correctly
- ordered liest of bandRects (debug mode only).</i>
-
- <h4>Algorithm 3: RemoveRegion</h4>
- When a float is removed, the Space Manager is notified by a call to RemoveRegion,
- passing in the frame that is being removed.
- <ul>
- <li>Get the FrameInfo for the frame passed in. If not found, an error is
- returned.</li>
- <li>If the rect for the frame is not empty, then visit each band in the
- bandList:</li>
- <ul>
- <li>for each rect in the band:
- </li>
- </ul>
- <ul>
- <ul>
- <li>if the bandRect is occupied by the frame, either remove the frame
- from the bandRect (if there are other frames sharing it) and remember that
- it was shared</li>
- <li>otherwise simply remove the bandRect (no other frames share it).</li>
- <li>if the bandRect was shared, then try to coalesce adjacent bandRects</li>
- <ul>
- <li>if the previous bandRect is directly next to the current bandRect,
- and they have the same frame list, then make the current bandRect cover the
- previous bandRect's full region (adjust the left edge to be that of the previous
- bandRect) and remove the previous bandRect.</li>
- </ul>
- </ul>
- </ul>
- <ul>
- <li>if the current band or prior band had a rect occupied byu the frame,
- then try to join the two bands via JoinBands</li>
- </ul>
- <li>Finally, destroy the frameInfo for the frame.
- </li>
- </ul>
-
- <br>
-
- <hr width="100%" size="2">
- <h2>Cross-Component Algorithms</h2>
- <br>
-
-
- <hr width="100%" size="2">
- <h2>Tech Notes</h2>
- <ul>
- <li>
- </li>
-
- </ul>
-
-
-
- </body>
- </html>
|