Lets try to sort out the layout issues and come up with some ideas. First of all assume that there is nothing there. We have an FO Tree and an Area Tree and nothing in between.
Now how do we get the layout to work. Some requirements: - separation between deciding layout and adding areas - ability to make layout decisions at multiple levels depending on context (harder to define: things like simple, minimal, always progressing, eg. create a set of information on first pass as close as possible to solution then if not solution use that information to create the solution) There is one definite "view" of a layout manager that is required. When it is created to correspond to an formatting object. - create and set variables: fobj, user agent - some inline areas are basic and can be handled by an simple inline manager - allow for retrieve marker which later resolves to a different layout manager This creates a required interface. The other "view" is through the use of layout manager to do the layout and create the areas. It will need some way to decide layout and then to add the areas. There are also methods that can help out: - retrieve marker - get page numger - resolving id When adding areas: - adding areas - add marker - adding id - adding unresolved area Now, hope you are still with me. How are the fobj's handled, the layout managers and the layout. (A note about the current code (not fully implemented obviously): The layout managers are retrieved on demand so that it can operate in parallel to the fo tree building and wait until an fo is ready. Breaks are created by the layout manager by using a break from the child until the child is finished. It is possible to know when starting and finishing with breaks which is important for keeps and other layout. Breaks can be collected and returned as a single break to a parent. It can also return each break to the parent depending on certain situations. This allows it to break when there is an out-of-line formatting event so it can go to the ancestor that deals with it and then return to getting breaks with needing to do anything different. Once the breaks are decided then the areas are added. When adding areas up to a particular break it automatically collects breaks for a particular layout manager. This goes with the spec: "No area may have more than one normal child area returned by the same fo:block formatting object." Once the areas are added we can dispose of, reset or keep the breaks for future use. In theory it could send every break to the top level so that it can make the decision if that is the right break. It could also collect breaks until a definite event has occurred where it can make a final decision about all the breaks to create a correct layout. Other layout managers may not need to make a decision and simply collect all breaks. ) Handling fobj's. This does depend on the fo tree. It needs to get layout managers from the fobjects. Preferably in a way that does not create extra work and can be separated (for threading) from the fo tree building. (note: pull parsing would make a difference) Currently done with LMiter and a method on the fobj. Implementing an iterator means it can be used as a normal iterator but it does abstract away the fobjs and layout managers. How can thay be released once finished with. Is it overkill and a basic class could be used instead that does exactly what is needed. Layout managers themselves. They provide a useful sevice in a number of areas: - separation from fo tree so fo tree is a data structure - allow for release parts of fo tree finished with - allow for alternate layout alogrithms - can create layout managers for situations such as: line areas, lead use content, title, table cells under table body, undefined table columns, page columns. - handling of things like side floats: a side float needs to be handled by the nearest reference area. The layout manager can then adjust the inline dimension - clean separation of doing layout and then adding areas. When areas added then it can also add id references, unresolved areas, markers. - can hold generated areas that are repeated without changing - can restart at the right place depending on a change of: ipd or page The layout algorithm: - decides what to put where - needs to decide based on a whole set of information until a definite break - layout always starts at a position and flows forward, so need to reset to a position - line areas only change if a page or ipd changes - block areas are stacked line and block areas - spacing determines optimum space and is resolved temporarily when deciding page breaks and finalised when adding areas - keeps, widows and orphans. These depend on the full algorithm working across all data So how are footnotes and floats handled along with this. A footnote or float is always ossociated with a line area. That line area adds to the current stacking and to an out of line stacking. Side floats also effect the ipd for a given amount. The layout managers will need to be able to take this information into consideration and to make it easy to consider each possible line addition and how it fits into the page. The actual space that area take up can only be decided for the situation and calculating line by line could give it the chance to determine when a particular situation is reached. Auto table layout. Need to get the min and max for each table column. Min is found by getting each smallest possible inline break and finding the maximum. Max is found by placing all content in one line area which will has a hard limit. So need a way to do layout which will report a max ipd result for the content. Break Positions and iterating. So we need some wort of way to consider where a break can be made between lines and blocks. This also may need to be reflowed in the case of change in page or ipd. These breaks then need to be used in some way when adding areas so that it is known what areas should be added and resolving spacing. So how do we gather this information. Reuse the information as much as possible for the layout and then add the areas to the area tree. We need some sort of break information that specifies things like: - relationship to break in child layout manager - spacing and how it could be resolved - how to restart flow layout at a particular break - how to use that break to add the areas Now it may also be useful to collect breaks for situations where it effects the flow bpd in a different way. For example block container with 90 degree reference orientation, table rows depend on all cells in row. So how do we handle the information that comes from an ancestor. Could this be done by passing down some context information that is set where appropriate, ipd, bpd calculation, area traits (for layout purpose) such as is-first. Could the way that line areas are constructed and block area be different. Since they are generally doing a number of different types of tasks. Lines need to know about min/opt/max and spaces, ipd, handling side floats, hyphenation. Block layout is generally stacking blocks down the page it needs min/opt/max, some sort of bpd calculation, handling footnotes, before floats, side floats with clear. So do we need both a break possibility and a position. What will the actual algorithm that decides the breaks from this information look like. Can it use this information, reflowing where needed and resolving spacing. Will the result come from looking at the constraints starting from the optimum spacing or should it start from some other position. How can the decision be as separate as possible from all the layout processes (so that it can be coded better) while still actively responding to the flow. It will need to work from the breaks and constraints broken and the spacing. Can the break information be held inside the layout managers and only some sort of status return. The break algorithm then uses the layout managers to make the decisions. How can we simplify the line area layout manager which is complex and bug prone. Iterating of breaks. Since there may be a number of breaks for any layout manager how do these get used to add up until the last decided break. Is it misleading to combine all breaks for a particular layout manager. What is the best way to specify that it should add areas up until a particular position which refers all the way down the hierarchy. Is it enough to say that position N is this child layout manager. Should breaks only be internal information (to a layout manager) that somehow the algorithm works with. Putting all this together we need to store the information somewhere so that an algorithm can work out the best solution. The flow can be redone where required when selecting a particular break. The spaces can be temporarily resolved. Out of line areas are part of the calculation when doing the decisions. This solution should then be used to add the areas. It may be possible that it should start in a particular position and move in a particular way in order to find the solution. The solution may only be possible by checking every possibility within a range. So the current assertion is that the idea of break possibilities can be used to achieve this. There are some areas that could do with some cleanup and maybe a better approach. It can return or group breaks, it can reflow. It should be able to work with a layout decision algorithm and to resolving spacing and determine what constraints are broken. It could then redo what is needed until solution is found. So there is a brief summary of the layout. Thanks for reading this far. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]