[ooo-build-commit] .: patches/dev300

Petr Mladek pmladek at kemper.freedesktop.org
Tue Apr 20 09:10:10 PDT 2010


 patches/dev300/apply                                                      |  104 
 patches/dev300/calc-perf-filtering-with-notes-m14.diff                    |   62 
 patches/dev300/calc-perf-filtering-with-notes.diff                        |    8 
 patches/dev300/calc-perf-page-and-manual-breaks-m14.diff                  | 1595 ++++
 patches/dev300/calc-perf-page-and-manual-breaks.diff                      |   30 
 patches/dev300/calc-perf-speedup-pagebreak-update-m14.diff                | 1263 +++
 patches/dev300/calc-perf-speedup-pagebreak-update.diff                    |   18 
 patches/dev300/calc-perf-table-hidden-flags-m14.diff                      | 3736 ++++++++++
 patches/dev300/calc-perf-table-hidden-flags.diff                          |   18 
 patches/dev300/cws-impressmedia01-backport-m14.diff                       | 2605 ++++++
 patches/dev300/cws-impressmedia01-backport.diff                           |  113 
 patches/dev300/docx-export-enable-m14.diff                                |  433 +
 patches/dev300/docx-export-enable.diff                                    |   10 
 patches/dev300/fit-list-to-size-ooxml-m14.diff                            |   38 
 patches/dev300/fix-es-accelerators-m14.diff                               |  241 
 patches/dev300/fix-es-accelerators.diff                                   |  216 
 patches/dev300/oox-fix-list-style-apply-m14.diff                          |   14 
 patches/dev300/oox-fix-list-style-apply.diff                              |    4 
 patches/dev300/oox-fix-placeholder-layout-m14.diff                        |  105 
 patches/dev300/oox-fix-placeholder-layout.diff                            |    8 
 patches/dev300/oox-import-drawing-font-spacing-m14.diff                   |   83 
 patches/dev300/oox-import-drawing-font-spacing.diff                       |    9 
 patches/dev300/oox-import-text-vert-anchor-and-anchorctr-m14.diff         |  130 
 patches/dev300/oox-pptx-import-fix-placeholder-text-style-m14.diff        |  168 
 patches/dev300/oox-pptx-import-fix-subtitle-placeholder-m14.diff          |   17 
 patches/dev300/oox-pptx-import-fix-text-body-properties-priority-m14.diff |   60 
 patches/dev300/oox-pptx-import-fix-text-body-vert-2-m14.diff              |   26 
 patches/dev300/oox-pptx-import-fix-text-body-vert-m14.diff                |   13 
 patches/dev300/pptx-gfx-layout-fix-m14.diff                               |  351 
 patches/dev300/xlsx-shared-import-and-export-m14.diff                     |  544 +
 patches/dev300/xlsx-shared-import-and-export.diff                         |    2 
 31 files changed, 11632 insertions(+), 392 deletions(-)

New commits:
commit 62b7d61a9418d2c14b57b931046ba0fa265ce080
Author: Petr Mladek <pmladek at suse.cz>
Date:   Tue Apr 20 17:57:39 2010 +0200

    Update diffs to apply on ooo320-m15
    
    * patches/dev300/calc-perf-filtering-with-notes-m14.diff:
    * patches/dev300/calc-perf-filtering-with-notes.diff:
    * patches/dev300/calc-perf-page-and-manual-breaks-m14.diff:
    * patches/dev300/calc-perf-page-and-manual-breaks.diff:
    * patches/dev300/calc-perf-speedup-pagebreak-update-m14.diff:
    * patches/dev300/calc-perf-speedup-pagebreak-update.diff:
    * patches/dev300/calc-perf-table-hidden-flags-m14.diff:
    * patches/dev300/calc-perf-table-hidden-flags.diff:
    * patches/dev300/cws-impressmedia01-backport-m14.diff:
    * patches/dev300/cws-impressmedia01-backport.diff:
    * patches/dev300/docx-export-enable-m14.diff:
    * patches/dev300/docx-export-enable.diff:
    * patches/dev300/fit-list-to-size-ooxml-m14.diff:
    * patches/dev300/fix-es-accelerators-m14.diff:
    * patches/dev300/fix-es-accelerators.diff:
    * patches/dev300/oox-fix-list-style-apply-m14.diff:
    * patches/dev300/oox-fix-list-style-apply.diff:
    * patches/dev300/oox-fix-placeholder-layout-m14.diff:
    * patches/dev300/oox-fix-placeholder-layout.diff:
    * patches/dev300/oox-import-drawing-font-spacing-m14.diff:
    * patches/dev300/oox-import-drawing-font-spacing.diff:
    * patches/dev300/oox-import-text-vert-anchor-and-anchorctr-m14.diff:
    * patches/dev300/oox-pptx-import-fix-placeholder-text-style-m14.diff:
    * patches/dev300/oox-pptx-import-fix-subtitle-placeholder-m14.diff:
    * patches/dev300/oox-pptx-import-fix-text-body-properties-priority-m14.diff:
    * patches/dev300/oox-pptx-import-fix-text-body-vert-2-m14.diff:
    * patches/dev300/oox-pptx-import-fix-text-body-vert-m14.diff:
    * patches/dev300/pptx-gfx-layout-fix-m14.diff:
    * patches/dev300/xlsx-shared-import-and-export-m14.diff:
    * patches/dev300/xlsx-shared-import-and-export.diff:
    * patches/dev300/apply: update for ooo320-m15
    
    * the following difs are remporary disabled :-(
    
    * oox-fix-placeholder-layout.diff
    * oox-import-text-vert-anchor-and-anchorctr.diff
    * oox-pptx-import-fix-subtitle-placeholder.diff
    * oox-pptx-import-fix-text-body-vert.diff
    * pptx-gfx-layout-fix.diff
    * oox-pptx-import-fix-placeholder-text-style.diff
    * oox-pptx-import-fix-text-body-properties-priority.diff
    * oox-pptx-import-fix-text-body-vert-2.diff

diff --git a/patches/dev300/apply b/patches/dev300/apply
index fa16d48..56f1913 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -945,9 +945,15 @@ calc-xls-import-slanted-border-oox.diff, n#549728, i#38709, kohei
 # TAB key to auto-complete word and move the cell cursor.
 calc-auto-tab-complete.diff, i#18748, muthusuba/kohei
 
+[ CalcFixes < ooo320-m15 ]
+# Speed up filtering performance with notes.
+calc-perf-filtering-with-notes-m14.diff, n#556927, kohei
+
+[ CalcFixes >= ooo320-m15 ]
 # Speed up filtering performance with notes.
 calc-perf-filtering-with-notes.diff, n#556927, kohei
 
+[ CalcFixes ]
 # Use current range separator for range lists.
 calc-formula-range-separator-fix.diff, n#556268, kohei
 
@@ -988,6 +994,16 @@ calc-perf-ods-import-properties.diff, n#498547, i#109384, kohei
 # squash USHORT where SCROW or SCCOL should have been used.
 calc-row-limit-bad-ushort.diff, n#509768, i#109385, kohei
 
+[ CalcRowLimit < ooo320-m15 ]
+# better algorithm to search for best-fit zoom level during page break calculation,
+# and to optimize pagenations by as much as 900% by using better data structure
+# for flag storage.
+calc-perf-page-and-manual-breaks-m14.diff, n#503482, i#109386, kohei
+
+# refactor to store hidden and filtered flags in flat_segment_tree structure.
+calc-perf-table-hidden-flags-m14.diff, n#495140, i#109387, kohei
+
+[ CalcRowLimit >= ooo320-m15 ]
 # better algorithm to search for best-fit zoom level during page break calculation,
 # and to optimize pagenations by as much as 900% by using better data structure
 # for flag storage.
@@ -996,6 +1012,7 @@ calc-perf-page-and-manual-breaks.diff, n#503482, i#109386, kohei
 # refactor to store hidden and filtered flags in flat_segment_tree structure.
 calc-perf-table-hidden-flags.diff, n#495140, i#109387, kohei
 
+[ CalcRowLimit ]
 # type cast to SCROW and SCCOL for row and column, not to USHORT!
 calc-ods-export-no-more-ushort.diff, n#501029, i#109385, kohei
 
@@ -1015,9 +1032,15 @@ calc-perf-rowheight-no-progress-bar.diff, n#514156, kohei
 # speed up row's hidden state query during pagenation.
 calc-perf-page-and-manual-breaks-fwd-iterator.diff, n#503482, i#109386, kohei
 
+[ CalcRowLimit < ooo320-m15 ]
+# Refactor row height storage to speed up page break updates.
+calc-perf-speedup-pagebreak-update-m14.diff, n#554955, i#109391, kohei
+
+[ CalcRowLimit >= ooo320-m15 ]
 # Refactor row height storage to speed up page break updates.
 calc-perf-speedup-pagebreak-update.diff, n#554955, i#109391, kohei
 
+[ CalcRowLimit ]
 # Use manual breaks hidden/filtered flags when querying for last flagged row.
 calc-perf-last-rowflags-fix.diff, n#568146, i#109391, kohei
 
@@ -2296,9 +2319,18 @@ docx-ugly-fix.diff, n#548701, cbosdo
 
 buildfix-oox-depends-on-unotools.diff
 
-oox-fix-placeholder-layout.diff, n#485316, n#480223, rodo
+[ OOXML < ooo320-m15 ]
+oox-fix-placeholder-layout-m14.diff, n#485316, n#480223, rodo
+[ OOXML < ooo320-m15 ]
+# FIXME_ 2010-04-20: need port to ooo320-m15, --pmladek
+#oox-fix-placeholder-layout.diff, n#485316, n#480223, rodo
+
+[ OOXML < ooo320-m15 ]
+oox-fix-list-style-apply-m14.diff, n#485417, rodo
+[ OOXML >= ooo320-m15 ]
 oox-fix-list-style-apply.diff, n#485417, rodo
 
+[ OOXML ]
 # FIXME: 2009-09-02: Applies but causes compilation errors. --tml
 # oox-import-chart-externalref.diff, n#480868, janneke
 
@@ -2322,19 +2354,32 @@ oox-custom-shape-polygons.diff, n#485418, rodo
 # FIXME_ 2009-09-02: Applies but causes compilation errors. --tml
 # oox-import-sheet-protect.diff, n#481317, janneke
 
+[ OOXML < ooo320-m15 ]
+oox-import-drawing-font-spacing-m14.diff, n#479822, rodo
+oox-import-text-vert-anchor-and-anchorctr-m14.diff, n#479829, rodo
+[ OOXML >= ooo320-m15 ]
 oox-import-drawing-font-spacing.diff, n#479822, rodo
-oox-import-text-vert-anchor-and-anchorctr.diff, n#479829, rodo
+# FIXME_ 2010-04-20: need port to ooo320-m15, --pmladek
+#oox-import-text-vert-anchor-and-anchorctr.diff, n#479829, rodo
 
+[ OOXML ]
 oox-pptx-import-fix-layout.diff, n#480223, rodo
 oox-pptx-import-fix-wipe-transition.diff, n#480243, rodo
 
 [ OpenGLTransitions and OOXML ]
 oox-pptx-import-fix-transition-auto-advance.diff, n#480243, rodo
 
+[ OOXML < ooo320-m15 ]
+oox-pptx-import-fix-subtitle-placeholder-m14.diff, n#480243, rodo
+oox-pptx-import-fix-text-body-vert-m14.diff, n#479829, rodo
+[ OOXML >= ooo320-m15 ]
+# FIXME_ 2010-04-20: another implementation is in ooo320-m15. --pmladek
+#oox-pptx-import-fix-subtitle-placeholder.diff, n#480243, rodo
+# FIXME_ 2010-04-20: depends on the disabled oox-import-text-vert-anchor-and-anchorctr.diff, --pmladek
+#oox-pptx-import-fix-text-body-vert.diff, n#479829, rodo
+
 [ OOXML ]
-oox-pptx-import-fix-subtitle-placeholder.diff, n#480243, rodo
 oox-pptx-import-fix-hidden-slides.diff, n#480229, rodo
-oox-pptx-import-fix-text-body-vert.diff, n#479829, rodo
 
 
 [ OOXML ]
@@ -3207,6 +3252,9 @@ svtools-svrtf-token-ignore-case.diff, n#417818, flr
 # fix wrong en-US accelerators in Impress
 fix-sd-accelerators.diff, n#463733, i#97088, jholesov
 
+[ Fixes < ooo320-m15 ]
+fix-es-accelerators-m14.diff, i#102645
+[ Fixes >= ooo320-m15]
 fix-es-accelerators.diff, i#102645
 
 [ MinGW ]
@@ -3294,10 +3342,14 @@ pptx-filter-as-a-separate-lib-sd-build-lst-with-transogl.diff
 [ OOXMLExport < ooo320-m14 ]
 # Enable the DOCX export (and few related features in oox)
 docx-export-enable-m13.diff, jholesov
-[ OOXMLExport >= ooo320-m14 ]
+[ OOXMLExport == ooo320-m14 ]
+# Enable the DOCX export (and few related features in oox)
+docx-export-enable-m14.diff, jholesov
+[ OOXMLExport >= ooo320-m15 ]
 # Enable the DOCX export (and few related features in oox)
 docx-export-enable.diff, jholesov
 
+
 [ OOXMLExport ]
 # Snapshot of the pptx export filter at the time of creation of ooxml03
 # This is until 0475--fix-crash-introduced-by-Jonathan-s-changes-in-eppt.patch
@@ -3311,9 +3363,15 @@ pptx-snapshot-at-ooxml03-creation.diff
 pptx-the-rest-from-git.diff
 pptx-export-empty-animations-node-and-groupshape-fix.diff, rodo
 
+[ OOXMLExport < ooo320-m15 ]
 # ugly temp fix to make GraphicShapeContext recognise layout
-pptx-gfx-layout-fix.diff, thorsten
+pptx-gfx-layout-fix-m14.diff, thorsten
+[ OOXMLExport >= ooo320-15 ]
+# FIXME_ 2010-04-20: need port to ooo320-m15, --pmladek
+# ugly temp fix to make GraphicShapeContext recognise layout
+#pptx-gfx-layout-fix.diff, thorsten
 
+[ OOXMLExport ]
 # handles case where a connector shape is not connected
 
 pptx-fix-connector-crash.diff, n#499129, thorsten
@@ -3336,10 +3394,16 @@ xlsx-filter-as-a-separate-lib-guards.diff
 # should contain all the available changes.
 xlsx-snapshot.diff
 
+[ OOXMLExport321 < ooo320-m15 ]
+# Make the xlsx export and import work at the same time
+# (converts the xlsx export to a UNO filter)
+xlsx-shared-import-and-export-m14.diff
+[ OOXMLExport321 >= ooo320-m15 ]
 # Make the xlsx export and import work at the same time
 # (converts the xlsx export to a UNO filter)
 xlsx-shared-import-and-export.diff
 
+[ OOXMLExport321 ]
 xlsx-arabic-export-crash.diff, n#497419, janneke
 
 xlsx-export-notes-avoid-dereferencing-0-svx.diff, n#497417, janneke
@@ -3452,9 +3516,17 @@ edit-links-decode-unicode-uri.diff, i#104166, kohei
 # cache fontconfig's pre-substitution result for better rendering performance.
 fontconfig-cache-pre-substitution.diff, n#529532, kohei
 
-[ OOXML ]
-oox-pptx-import-fix-placeholder-text-style.diff, n#479834, rodo
-oox-pptx-import-fix-text-body-properties-priority.diff, n#403402, rodo
+[ OOXML < ooo320-m15 ]
+oox-pptx-import-fix-placeholder-text-style-m14.diff, n#479834, rodo
+oox-pptx-import-fix-text-body-properties-priority-m14.diff, n#403402, rodo
+[ OOXML >= ooo320-m15 ]
+# FIXME_ 2010-04-20: big part is applied in ooo320-m15, is it still needed? --pmladek
+# oox-pptx-import-fix-placeholder-text-style.diff, n#479834, rodo
+# FIXME_ 2010-04-20: needs porting for ooo320-m15 --pmladek
+# oox-pptx-import-fix-text-body-properties-priority.diff, n#403402, rodo
+
+[ OOXML < ooo320-m15 ]
+# FIXME_ 2010-04-20: can be enabled for ooo320-m15 after we port oox-import-text-vert-anchor-and-anchorctr.diff, --pmladek
 fit-list-to-size-ooxml.diff, i#94086, thorsten
 
 [ OOXMLExport ]
@@ -3964,10 +4036,15 @@ transogl-crossplatform.diff, ericb
 # embed generic media files inside odf docs, 1st part
 # FIXME: svx-sound.diff depends on this diff
 cws-impressmedia01-backport-m13.diff, i#83753, thorsten
-[ Features >= ooo320-m14 ]
+[ Features == ooo320-m14 ]
+# embed generic media files inside odf docs, 1st part
+# FIXME: svx-sound.diff depends on this diff
+cws-impressmedia01-backport-m14.diff, i#83753, thorsten
+[ Features >= ooo320-m15 ]
 # embed generic media files inside odf docs, 1st part
 # FIXME: svx-sound.diff depends on this diff
 cws-impressmedia01-backport.diff, i#83753, thorsten
+
 [ Features ]
 cws-impressmedia01-crash-fix.diff, n#588570, thorsten
 
@@ -4046,4 +4123,9 @@ magyarlinuxlibertine-fonts.diff
 
 [ OOXML ]
 oox-import-helper-property-map-dump.diff, rodo
-oox-pptx-import-fix-text-body-vert-2.diff, n#479829, rodo
+[ OOXML < ooo320-m15 ]
+# FIXME_ 2010-04-20: depends on the disabled oox-import-text-vert-anchor-and-anchorctr.diff, --pmladek
+oox-pptx-import-fix-text-body-vert-2-m14.diff, n#479829, rodo
+[ OOXML >= ooo320-m15 ]
+# FIXME_ 2010-04-20: depends on the disabled oox-import-text-vert-anchor-and-anchorctr.diff, --pmladek
+#oox-pptx-import-fix-text-body-vert-2.diff, n#479829, rodo
diff --git a/patches/dev300/calc-perf-filtering-with-notes-m14.diff b/patches/dev300/calc-perf-filtering-with-notes-m14.diff
new file mode 100644
index 0000000..2e5ae6a
--- /dev/null
+++ b/patches/dev300/calc-perf-filtering-with-notes-m14.diff
@@ -0,0 +1,62 @@
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index c6c41f1..c7836c5 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -638,7 +638,7 @@ public:
+     void		DBShowRow(SCROW nRow, BOOL bShow);
+ 
+     void		ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow);
+-    void		DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow);
++    void		DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bDrawPageSize);
+ 
+     void		SetColFlags( SCCOL nCol, BYTE nNewFlags );
+     void		SetRowFlags( SCROW nRow, BYTE nNewFlags );
+diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
+index 319a7e5..f0a0815 100644
+--- sc/source/core/data/table2.cxx
++++ sc/source/core/data/table2.cxx
+@@ -2540,7 +2540,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
+ }
+ 
+ 
+-void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
++void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bDrawPageSize)
+ {
+     SCROW nStartRow = nRow1;
+     nRecalcLvl++;
+@@ -2585,7 +2585,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+     if (pOutlineTable)
+         UpdateOutlineRow( nRow1, nRow2, bShow );
+ 
+-    if( !--nRecalcLvl )
++    if( !--nRecalcLvl && bDrawPageSize)
+         SetDrawPageSize();
+ }
+ 
+diff --git sc/source/core/data/table3.cxx sc/source/core/data/table3.cxx
+index 52d7d32..7c9af91 100644
+--- sc/source/core/data/table3.cxx
++++ sc/source/core/data/table3.cxx
+@@ -1668,7 +1668,7 @@ SCSIZE ScTable::Query(ScQueryParam& rParamOrg, BOOL bKeepSub)
+             else
+             {
+                 if (bStarted)
+-                    DBShowRows(nOldStart,nOldEnd, bOldResult);
++                    DBShowRows(nOldStart,nOldEnd, bOldResult, false);
+                 nOldStart = nOldEnd = j;
+                 bOldResult = bResult;
+             }
+@@ -1687,10 +1687,12 @@ SCSIZE ScTable::Query(ScQueryParam& rParamOrg, BOOL bKeepSub)
+     }
+ 
+     if (aParam.bInplace && bStarted)
+-        DBShowRows(nOldStart,nOldEnd, bOldResult);
++        DBShowRows(nOldStart,nOldEnd, bOldResult, false);
+ 
+     delete[] pSpecial;
+ 
++    SetDrawPageSize();
++
+     return nCount;
+ }
+ 
diff --git a/patches/dev300/calc-perf-filtering-with-notes.diff b/patches/dev300/calc-perf-filtering-with-notes.diff
index 2e5ae6a..3f7f20c 100644
--- a/patches/dev300/calc-perf-filtering-with-notes.diff
+++ b/patches/dev300/calc-perf-filtering-with-notes.diff
@@ -23,16 +23,16 @@ index 319a7e5..f0a0815 100644
 +void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bDrawPageSize)
  {
      SCROW nStartRow = nRow1;
-     nRecalcLvl++;
+     IncRecalcLevel();
 @@ -2585,7 +2585,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
      if (pOutlineTable)
          UpdateOutlineRow( nRow1, nRow2, bShow );
  
--    if( !--nRecalcLvl )
-+    if( !--nRecalcLvl && bDrawPageSize)
-         SetDrawPageSize();
+-    DecRecalcLevel();
++    if (!--nRecalcLvl && bDrawPageSize) SetDrawPageSize(true, true); 
  }
  
+ 
 diff --git sc/source/core/data/table3.cxx sc/source/core/data/table3.cxx
 index 52d7d32..7c9af91 100644
 --- sc/source/core/data/table3.cxx
diff --git a/patches/dev300/calc-perf-page-and-manual-breaks-m14.diff b/patches/dev300/calc-perf-page-and-manual-breaks-m14.diff
new file mode 100644
index 0000000..eab9b62
--- /dev/null
+++ b/patches/dev300/calc-perf-page-and-manual-breaks-m14.diff
@@ -0,0 +1,1595 @@
+--- sc/inc/document.hxx.old	2010-03-03 16:59:15.000000000 +0100
++++ sc/inc/document.hxx	2010-03-03 16:59:18.000000000 +0100
+@@ -47,6 +47,7 @@
+ 
+ #include <memory>
+ #include <map>
++#include <set>
+ 
+ class KeyEvent;
+ class OutputDevice;
+@@ -154,6 +155,9 @@ namespace com { namespace sun { namespac
+     namespace embed {
+         class XEmbeddedObject;
+     }
++    namespace sheet {
++        struct TablePageBreakData;
++    }
+ } } }
+ 
+ #include <svtools/zforlist.hxx>
+@@ -1290,6 +1294,24 @@ public:
+     SC_DLLPUBLIC const ScBitMaskCompressedArray< SCROW, BYTE> & GetRowFlagsArray( SCTAB nTab ) const;
+     SC_DLLPUBLIC       ScBitMaskCompressedArray< SCROW, BYTE> & GetRowFlagsArrayModifiable( SCTAB nTab );
+ 
++    SC_DLLPUBLIC void           GetAllRowBreaks(::std::set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const;
++    SC_DLLPUBLIC void           GetAllColBreaks(::std::set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const;
++    SC_DLLPUBLIC ScBreakType    HasRowBreak(SCROW nRow, SCTAB nTab) const;
++    SC_DLLPUBLIC ScBreakType    HasColBreak(SCCOL nCol, SCTAB nTab) const;
++    SC_DLLPUBLIC void           SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual);
++    SC_DLLPUBLIC void           SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual);
++    void                        RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual);
++    void                        RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual);
++    ::com::sun::star::uno::Sequence<
++        ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData(SCTAB nTab) const;
++
++    /** 
++     * Write all column row flags to table's flag data, because not all column 
++     * row attributes are stored in the flag data members.  This is necessary 
++     * for ods export. 
++     */
++    void                        SyncColRowFlags();
++
+                     /// @return  the index of the last row with any set flags (auto-pagebreak is ignored).
+     SC_DLLPUBLIC SCROW			GetLastFlaggedRow( SCTAB nTab ) const;
+ 
+@@ -1329,6 +1351,7 @@ public:
+     Size			GetPageSize( SCTAB nTab ) const;
+     void			SetPageSize( SCTAB nTab, const Size& rSize );
+     void			SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow );
++    void            InvalidatePageBreaks(SCTAB nTab);
+     void			UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea = NULL );
+     void			RemoveManualBreaks( SCTAB nTab );
+     BOOL			HasManualBreaks( SCTAB nTab ) const;
+--- sc/inc/global.hxx.old	2010-03-03 16:59:11.000000000 +0100
++++ sc/inc/global.hxx	2010-03-03 16:59:18.000000000 +0100
+@@ -206,13 +206,16 @@ const SCSIZE PIVOT_MAXPAGEFIELD = 10;
+                                     // FILTERED und MANUALSIZE nur fuer Zeilen moeglich
+ const BYTE   CR_HIDDEN      = 1;
+ //const BYTE CR_MARKED      = 2;
+-const BYTE   CR_PAGEBREAK   = 4;
++//const BYTE CR_PAGEBREAK   = 4;
+ const BYTE   CR_MANUALBREAK = 8;
+ const BYTE   CR_FILTERED    = 16;
+ const BYTE   CR_MANUALSIZE  = 32;
++const BYTE   CR_ALL         = (CR_HIDDEN | CR_MANUALBREAK | CR_FILTERED | CR_MANUALSIZE);
+ 
+-//	was davon kommt in die Datei:
+-#define CR_SAVEMASK		( ~CR_PAGEBREAK )
++typedef BYTE ScBreakType;
++const ScBreakType BREAK_NONE   = 0;
++const ScBreakType BREAK_PAGE   = 1;
++const ScBreakType BREAK_MANUAL = 2;
+ 
+ // Insert-/Delete-Flags
+ const USHORT IDF_NONE       = 0x0000;
+--- sc/inc/table.hxx.old	2010-03-03 16:59:17.000000000 +0100
++++ sc/inc/table.hxx	2010-03-03 16:59:18.000000000 +0100
+@@ -42,12 +42,19 @@
+ #include "compressedarray.hxx"
+ 
+ #include <memory>
++#include <set>
+ 
+ namespace utl {
+     class SearchParam;
+     class TextSearch;
+ }
+ 
++namespace com { namespace sun { namespace star {
++    namespace sheet {
++        struct TablePageBreakData;
++    }
++} } }
++
+ class SfxItemSet;
+ class SfxStyleSheetBase;
+ class SvxBoxInfoItem;
+@@ -119,6 +126,11 @@ private:
+     BYTE*			pColFlags;
+     ScBitMaskCompressedArray< SCROW, BYTE>*     pRowFlags;
+ 
++    ::std::set<SCROW>                      maRowPageBreaks;
++    ::std::set<SCROW>                      maRowManualBreaks;
++    ::std::set<SCCOL>                      maColPageBreaks;
++    ::std::set<SCCOL>                      maColManualBreaks;
++
+     ScOutlineTable*	pOutlineTable;
+ 
+     SCCOL			nTableAreaX;
+@@ -158,6 +170,7 @@ private:
+     Color			aScenarioColor;
+     USHORT			nScenarioFlags;
+     BOOL			bActiveScenario;
++    bool            mbPageBreaksValid;
+ 
+ friend class ScDocument;					// fuer FillInfo
+ friend class ScDocumentIterator;
+@@ -363,7 +376,8 @@ public:
+ 
+     void		CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const;
+ 
+-    void		InvalidateTableArea()						{ bTableAreaValid = FALSE; }
++    void        InvalidateTableArea();
++    void        InvalidatePageBreaks();
+ 
+     BOOL		GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const;			// FALSE = leer
+     BOOL		GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const;
+@@ -633,6 +647,21 @@ public:
+     void		RemoveManualBreaks();
+     BOOL		HasManualBreaks() const;
+ 
++    void        GetAllRowBreaks(::std::set<SCROW>& rBreaks, bool bPage, bool bManual) const;
++    void        GetAllColBreaks(::std::set<SCCOL>& rBreaks, bool bPage, bool bManual) const;
++    bool        HasRowPageBreak(SCROW nRow) const;
++    bool        HasColPageBreak(SCCOL nCol) const;
++    bool        HasRowManualBreak(SCROW nRow) const;
++    bool        HasColManualBreak(SCCOL nCol) const;
++    void        RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow);
++    void        RemoveRowBreak(SCROW nRow, bool bPage, bool bManual);
++    void        RemoveColBreak(SCCOL nCol, bool bPage, bool bManual);
++    void        SetRowBreak(SCROW nRow, bool bPage, bool bManual);
++    void        SetColBreak(SCCOL nCol, bool bPage, bool bManual);
++    ::com::sun::star::uno::Sequence<
++        ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData() const;
++    void        SyncColRowFlags();
++
+     void		StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+     void		ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+ 
+--- sc/source/core/data/document.cxx.old	2010-03-03 16:59:15.000000000 +0100
++++ sc/source/core/data/document.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -54,6 +54,7 @@
+ #include <tools/tenccvt.hxx>
+ 
+ #include <com/sun/star/text/WritingMode2.hpp>
++#include <com/sun/star/sheet/TablePageBreakData.hpp>
+ 
+ #include "document.hxx"
+ #include "table.hxx"
+@@ -98,6 +99,9 @@
+ #include <map>
+ 
+ namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
++using ::com::sun::star::uno::Sequence;
++using ::com::sun::star::sheet::TablePageBreakData;
++using ::std::set;
+ 
+ struct ScDefaultAttr
+ {
+@@ -3390,6 +3394,102 @@ const ScBitMaskCompressedArray< SCROW, B
+     return *pFlags;
+ }
+ 
++void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++        return;
++
++    pTab[nTab]->GetAllRowBreaks(rBreaks, bPage, bManual);
++}
++
++void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++        return;
++
++    pTab[nTab]->GetAllColBreaks(rBreaks, bPage, bManual);
++}
++
++ScBreakType ScDocument::HasRowBreak(SCROW nRow, SCTAB nTab) const
++{
++    ScBreakType nType = BREAK_NONE;
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
++        return nType;
++
++    if (pTab[nTab]->HasRowPageBreak(nRow))
++        nType |= BREAK_PAGE;
++
++    if (pTab[nTab]->HasRowManualBreak(nRow))
++        nType |= BREAK_MANUAL;
++
++    return nType;
++}
++
++ScBreakType ScDocument::HasColBreak(SCCOL nCol, SCTAB nTab) const
++{
++    ScBreakType nType = BREAK_NONE;
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
++        return nType;
++
++    if (pTab[nTab]->HasColPageBreak(nCol))
++        nType |= BREAK_PAGE;
++
++    if (pTab[nTab]->HasColManualBreak(nCol))
++        nType |= BREAK_MANUAL;
++
++    return nType;
++}
++
++void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
++{
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
++        return;
++
++    pTab[nTab]->SetRowBreak(nRow, bPage, bManual);
++}
++
++void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
++{
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
++        return;
++
++    pTab[nTab]->SetColBreak(nCol, bPage, bManual);
++}
++
++void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual)
++{
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow))
++        return;
++
++    pTab[nTab]->RemoveRowBreak(nRow, bPage, bManual);
++}
++
++void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual)
++{
++    if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol))
++        return;
++
++    pTab[nTab]->RemoveColBreak(nCol, bPage, bManual);
++}
++
++Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++        return Sequence<TablePageBreakData>();
++
++    return pTab[nTab]->GetRowBreakData();
++}
++
++void ScDocument::SyncColRowFlags()
++{
++    for (SCTAB i = 0; i <= nMaxTableNumber; ++i)
++    {
++        if (!ValidTab(i) || !pTab[i])
++            continue;
++
++        pTab[i]->SyncColRowFlags();
++    }
++}
+ 
+ SCROW ScDocument::GetLastFlaggedRow( SCTAB nTab ) const
+ {
+@@ -4775,6 +4875,11 @@ void ScDocument::SetRepeatArea( SCTAB nT
+         pTab[nTab]->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow );
+ }
+ 
++void ScDocument::InvalidatePageBreaks(SCTAB nTab)
++{
++    if (ValidTab(nTab) && pTab[nTab])
++        pTab[nTab]->InvalidatePageBreaks();
++}
+ 
+ void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea )
+ {
+--- sc/source/core/data/table1.cxx.old	2010-03-03 16:59:11.000000000 +0100
++++ sc/source/core/data/table1.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -156,7 +156,8 @@ ScTable::ScTable( ScDocument* pDoc, SCTA
+     pScenarioRanges( NULL ),
+     aScenarioColor( COL_LIGHTGRAY ),
+     nScenarioFlags( 0 ),
+-    bActiveScenario( FALSE )
++	bActiveScenario( FALSE ),
++    mbPageBreaksValid(false)
+ {
+ 
+     if (bColInfo)
+--- sc/source/core/data/table2.cxx.old	2010-03-03 16:59:18.000000000 +0100
++++ sc/source/core/data/table2.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -138,6 +138,8 @@ void ScTable::InsertRow( SCCOL nStartCol
+         aCol[j].InsertRow( nStartRow, nSize );
+     if( !--nRecalcLvl )
+         SetDrawPageSize();
++
++    InvalidatePageBreaks();
+ }
+ 
+ 
+@@ -166,6 +168,8 @@ void ScTable::DeleteRow( SCCOL nStartCol
+     }
+     if( !--nRecalcLvl )
+         SetDrawPageSize();
++
++    InvalidatePageBreaks();
+ }
+ 
+ 
+@@ -233,6 +237,8 @@ void ScTable::InsertCol( SCCOL nStartCol
+     }
+     if( !--nRecalcLvl )
+         SetDrawPageSize();
++
++    InvalidatePageBreaks();
+ }
+ 
+ 
+@@ -276,6 +282,8 @@ void ScTable::DeleteCol( SCCOL nStartCol
+     }
+     if( !--nRecalcLvl )
+         SetDrawPageSize();
++
++    InvalidatePageBreaks();
+ }
+ 
+ 
+@@ -652,29 +660,39 @@ void ScTable::CopyToTable(SCCOL nCol1, S
+                 if (bWidth)
+                     for (SCCOL i=nCol1; i<=nCol2; i++)
+                     {
+-                        BOOL bChange = pCharts &&
+-                            ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN );
++						bool bHiddenChange = ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN );
++						bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]);
+                         pDestTab->pColWidth[i] = pColWidth[i];
+                         pDestTab->pColFlags[i] = pColFlags[i];
+                         //!	Aenderungen zusammenfassen?
+-                        if (bChange)
++						if (bHiddenChange && pCharts) 
+                             pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
++
++						if (bChange)
++							pDestTab->InvalidatePageBreaks();
+                     }
+ 
+                 if (bHeight)
+                 {
++					bool bChange = pDestTab->pRowHeight->SumValues(nRow1, nRow2) != pRowHeight->SumValues(nRow1, nRow2);
++
++					if (bChange)
++						pDestTab->InvalidatePageBreaks();
++
+                     pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2);
+                     for (SCROW i=nRow1; i<=nRow2; i++)
+                     {
+                         // TODO: might need some performance improvement, block
+                         // operations instead of single GetValue()/SetValue() calls.
+                         BYTE nThisRowFlags = pRowFlags->GetValue(i);
+-                        BOOL bChange = pCharts &&
+-                            ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN );
++						bool bHiddenChange = ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN );
+                         pDestTab->pRowFlags->SetValue( i, nThisRowFlags );
+                         //!	Aenderungen zusammenfassen?
+-                        if (bChange)
++						if (bHiddenChange && pCharts)
+                             pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab ));
++
++						if (bHiddenChange)
++							pDestTab->InvalidatePageBreaks();
+                     }
+                 }
+                 pDestTab->DecRecalcLevel();
+@@ -726,6 +744,16 @@ void ScTable::CopyUpdated( const ScTable
+         aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
+ }
+ 
++void ScTable::InvalidateTableArea()
++{
++    bTableAreaValid = FALSE;
++}
++
++void ScTable::InvalidatePageBreaks()
++{
++    mbPageBreaksValid = false;
++}
++
+ void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
+ {
+     DBG_ASSERT( bScenario, "bScenario == FALSE" );
+@@ -1969,6 +1997,8 @@ void ScTable::SetColWidth( SCCOL nCol, U
+             pColWidth[nCol] = nNewWidth;
+             if( !--nRecalcLvl )
+                 SetDrawPageSize();
++
++            InvalidatePageBreaks();
+         }
+     }
+     else
+@@ -1999,6 +2029,8 @@ void ScTable::SetRowHeight( SCROW nRow,
+             pRowHeight->SetValue( nRow, nNewHeight);
+             if( !--nRecalcLvl )
+                 SetDrawPageSize();
++
++            InvalidatePageBreaks();
+         }
+     }
+     else
+@@ -2099,6 +2131,9 @@ BOOL ScTable::SetRowHeightRange( SCROW n
+         }
+         if( !--nRecalcLvl )
+             SetDrawPageSize();
++
++        if (bChanged)
++            InvalidatePageBreaks();
+     }
+     else
+     {
+@@ -2340,6 +2375,8 @@ void ScTable::ShowRow(SCROW nRow, BOOL b
+             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+             if ( pCharts )
+                 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab ));
++
++            InvalidatePageBreaks();
+         }
+     }
+     else
+@@ -2385,6 +2422,8 @@ void ScTable::DBShowRow(SCROW nRow, BOOL
+ 
+             if (pOutlineTable)
+                 UpdateOutlineRow( nRow, nRow, bShow );
++
++            InvalidatePageBreaks();
+         }
+     }
+     else
+@@ -2484,6 +2523,8 @@ void ScTable::ShowRows(SCROW nRow1, SCRO
+             ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection();
+             if ( pCharts )
+                 pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ));
++
++            InvalidatePageBreaks();
+         }
+ 
+         nStartRow = nEndRow + 1;
+@@ -2559,7 +2600,7 @@ SCROW ScTable::GetLastFlaggedRow() const
+     if ( !pRowFlags )
+         return 0;
+ 
+-    SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++    SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
+     return ValidRow(nLastFound) ? nLastFound : 0;
+ }
+ 
+@@ -2571,7 +2612,7 @@ SCCOL ScTable::GetLastChangedCol() const
+ 
+     SCCOL nLastFound = 0;
+     for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++)
+-        if ((pColFlags[nCol] & ~CR_PAGEBREAK) || (pColWidth[nCol] != STD_COL_WIDTH))
++        if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH))
+             nLastFound = nCol;
+ 
+     return nLastFound;
+@@ -2583,7 +2624,7 @@ SCROW ScTable::GetLastChangedRow() const
+     if ( !pRowFlags )
+         return 0;
+ 
+-    SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++    SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) );
+     if (!ValidRow(nLastFlags))
+         nLastFlags = 0;
+ 
+--- sc/source/core/data/table3.cxx.old	2010-03-03 16:59:17.000000000 +0100
++++ sc/source/core/data/table3.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -771,7 +771,7 @@ void ScTable::RemoveSubTotals( ScSubTota
+             if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+                 if (((ScFormulaCell*)pCell)->IsSubTotal())
+                 {
+-                    SetRowFlags(nRow+1,GetRowFlags(nRow+1)&(~CR_MANUALBREAK));
++                    RemoveRowBreak(nRow+1, false, true);
+                     pDocument->DeleteRow( 0,nTab, MAXCOL,nTab, nRow, 1 );
+                     --nEndRow;
+                     aIter = ScColumnIterator( &aCol[nCol],nRow,nEndRow );
+@@ -939,9 +939,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalPar
+                     bBlockVis = FALSE;
+                     if ( rParam.bPagebreak && nRow < MAXROW &&
+                             aRowEntry.nSubStartRow != nStartRow && nLevel == 0)
+-                        SetRowFlags( aRowEntry.nSubStartRow,
+-                                GetRowFlags(aRowEntry.nSubStartRow) |
+-                                CR_MANUALBREAK);
++                        SetRowBreak(aRowEntry.nSubStartRow, false, true);
+ 
+                     if (bSpaceLeft)
+                     {
+--- sc/source/core/data/table5.cxx.old	2010-03-03 16:59:12.000000000 +0100
++++ sc/source/core/data/table5.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -53,8 +53,13 @@
+ #include "brdcst.hxx"
+ #include "tabprotection.hxx"
+ #include "globstr.hrc"
++#include <com/sun/star/sheet/TablePageBreakData.hpp>
++
++#include <algorithm>
+ 
+ using ::com::sun::star::uno::Sequence;
++using ::com::sun::star::sheet::TablePageBreakData;
++using ::std::set;
+ 
+ // STATIC DATA -----------------------------------------------------------
+ 
+@@ -68,6 +73,9 @@ void ScTable::UpdatePageBreaks( const Sc
+     if ( !pUserArea && !bPageSizeValid )
+         return;
+ 
++    if (mbPageBreaksValid)
++        return;
++
+     SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()->
+                                     Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+     if ( !pStyle )
+@@ -79,7 +87,6 @@ void ScTable::UpdatePageBreaks( const Sc
+     const SfxPoolItem* pItem;
+ 
+     SCCOL nX;
+-    SCROW nY;
+     SCCOL nStartCol = 0;
+     SCROW nStartRow = 0;
+     SCCOL nEndCol = MAXCOL;
+@@ -99,8 +106,9 @@ void ScTable::UpdatePageBreaks( const Sc
+             //	bei mehreren Bereichen nichts anzeigen:
+ 
+             for (nX=0; nX<MAXCOL; nX++)
+-                pColFlags[nX] &= ~CR_PAGEBREAK;
+-            pRowFlags->AndValue( 0, MAXROW-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++                RemoveColBreak(nX, true, false);
++
++            RemoveRowPageBreaks(0, MAXROW-1);
+ 
+             return;
+         }
+@@ -144,13 +152,13 @@ void ScTable::UpdatePageBreaks( const Sc
+         //	Anfang: Breaks loeschen
+ 
+     for (nX=0; nX<nStartCol; nX++)
+-        pColFlags[nX] &= ~CR_PAGEBREAK;
+-    pRowFlags->AndValue( 0, nStartRow-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++        RemoveColBreak(nX, true, false);
++    RemoveRowPageBreaks(0, nStartRow-1);
+ 
+     if (nStartCol > 0)
+-        pColFlags[nStartCol] |= CR_PAGEBREAK;			//! AREABREAK
++        SetColBreak(nStartCol, true, false);  // AREABREAK
+     if (nStartRow > 0)
+-        pRowFlags->OrValue( nStartRow, CR_PAGEBREAK);			//! AREABREAK
++        SetRowBreak(nStartRow, true, false);  // AREABREAK
+ 
+         //	Mittelteil: Breaks verteilen
+ 
+@@ -161,14 +169,15 @@ void ScTable::UpdatePageBreaks( const Sc
+     {
+         BOOL bStartOfPage = FALSE;
+         long nThisX = ( pColFlags[nX] & CR_HIDDEN ) ? 0 : pColWidth[nX];
+-        if ( (nSizeX+nThisX > nPageSizeX) || ((pColFlags[nX] & CR_MANUALBREAK) && !bSkipBreaks) )
++        bool bManualBreak = HasColManualBreak(nX);
++        if ( (nSizeX+nThisX > nPageSizeX) || (bManualBreak && !bSkipBreaks) )
+         {
+-            pColFlags[nX] |= CR_PAGEBREAK;
++            SetColBreak(nX, true, false);
+             nSizeX = 0;
+             bStartOfPage = TRUE;
+         }
+         else if (nX != nStartCol)
+-            pColFlags[nX] &= ~CR_PAGEBREAK;
++            RemoveColBreak(nX, true, false);
+         else
+             bStartOfPage = TRUE;
+ 
+@@ -178,7 +187,7 @@ void ScTable::UpdatePageBreaks( const Sc
+             for (SCCOL i=nRepeatStartX; i<=nRepeatEndX; i++)
+                 nPageSizeX -= ( pColFlags[i] & CR_HIDDEN ) ? 0 : pColWidth[i];
+             while (nX<=nRepeatEndX)
+-                pColFlags[++nX] &= ~CR_PAGEBREAK;
++                RemoveColBreak(++nX, true, false);
+             bColFound = TRUE;
+         }
+ 
+@@ -186,23 +195,21 @@ void ScTable::UpdatePageBreaks( const Sc
+     }
+ 
+     // Remove all page breaks in range.
+-    pRowFlags->AndValue( nStartRow+1, nEndRow, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++    RemoveRowPageBreaks(nStartRow+1, nEndRow);
++
+     // And set new page breaks.
+     BOOL bRepeatRow = ( nRepeatStartY != SCROW_REPEAT_NONE );
+     BOOL bRowFound = FALSE;
+     long nSizeY = 0;
+-    ScCompressedArrayIterator< SCROW, BYTE> aFlagsIter( *pRowFlags, nStartRow, nEndRow);
+-    ScCompressedArrayIterator< SCROW, USHORT> aHeightIter( *pRowHeight, nStartRow, nEndRow);
+-    for ( ; aFlagsIter; ++aFlagsIter, ++aHeightIter)
++    for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
+     {
+-        nY = aFlagsIter.GetPos();
+         BOOL bStartOfPage = FALSE;
+-        BYTE nFlags = *aFlagsIter;
+-        long nThisY = (nFlags & CR_HIDDEN) ? 0 : *aHeightIter;
+-        if ( (nSizeY+nThisY > nPageSizeY) || ((nFlags & CR_MANUALBREAK) && !bSkipBreaks) )
++        BYTE nFlags = pRowFlags->GetValue(nY);
++        long nThisY = (nFlags & CR_HIDDEN) ? 0 : pRowHeight->GetValue(nY);
++        bool bManualBreak = HasRowManualBreak(nY);
++		if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipBreaks) )
+         {
+-            pRowFlags->SetValue( nY, nFlags | CR_PAGEBREAK);
+-            aFlagsIter.Resync( nY);
++            SetRowBreak(nY, true, false);
+             nSizeY = 0;
+             bStartOfPage = TRUE;
+         }
+@@ -222,12 +229,7 @@ void ScTable::UpdatePageBreaks( const Sc
+ #endif
+             nPageSizeY -= nHeights;
+             if (nY <= nRepeatEndY)
+-            {
+-                pRowFlags->AndValue( nY, nRepeatEndY, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
+-                nY = nRepeatEndY + 1;
+-                aFlagsIter.Resync( nY);
+-                aHeightIter.Resync( nY);
+-            }
++                RemoveRowPageBreaks(nY, nRepeatEndY);
+             bRowFound = TRUE;
+         }
+ 
+@@ -238,26 +240,24 @@ void ScTable::UpdatePageBreaks( const Sc
+ 
+     if (nEndCol < MAXCOL)
+     {
+-        pColFlags[nEndCol+1] |= CR_PAGEBREAK;			//! AREABREAK
++        SetColBreak(nEndCol+1, true, false);  // AREABREAK
+         for (nX=nEndCol+2; nX<=MAXCOL; nX++)
+-            pColFlags[nX] &= ~CR_PAGEBREAK;
++            RemoveColBreak(nX, true, false);
+     }
+     if (nEndRow < MAXROW)
+     {
+-        pRowFlags->OrValue( nEndRow+1, CR_PAGEBREAK);			//! AREABREAK
++        SetRowBreak(nEndRow+1, true, false);  // AREABREAK
+         if (nEndRow+2 <= MAXROW)
+-            pRowFlags->AndValue( nEndRow+2, MAXROW, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) );
++            RemoveRowPageBreaks(nEndRow+2, MAXROW);
+     }
++    mbPageBreaksValid = true;
+ }
+ 
+ void ScTable::RemoveManualBreaks()
+ {
+-    if (pColFlags)
+-        for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++)
+-            pColFlags[nCol] &= ~CR_MANUALBREAK;
+-
+-    if (pRowFlags)
+-        pRowFlags->AndValue( 0, MAXROW, sal::static_int_cast<BYTE>(~CR_MANUALBREAK) );
++    maRowManualBreaks.clear();
++    maColManualBreaks.clear();
++    InvalidatePageBreaks();
+ 
+     if (IsStreamValid())
+         SetStreamValid(FALSE);
+@@ -265,22 +265,192 @@ void ScTable::RemoveManualBreaks()
+ 
+ BOOL ScTable::HasManualBreaks() const
+ {
+-    if (pColFlags)
+-        for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++)
+-            if ( pColFlags[nCol] & CR_MANUALBREAK )
+-                return TRUE;
+-
+-    if (pRowFlags)
+-        if (ValidRow( pRowFlags->GetLastAnyBitAccess( 0, CR_MANUALBREAK)))
+-            return TRUE;
++    return !maRowManualBreaks.empty() || !maColManualBreaks.empty();
++}
++
++void ScTable::GetAllRowBreaks(set<SCROW>& rBreaks, bool bPage, bool bManual) const
++{
++    if (bPage)
++        rBreaks = maRowPageBreaks;
++
++    if (bManual)
++    {
++        using namespace std;    
++        copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
++    }
++}
++
++void ScTable::GetAllColBreaks(set<SCCOL>& rBreaks, bool bPage, bool bManual) const
++{
++    if (bPage)
++        rBreaks = maColPageBreaks;
++
++    if (bManual)
++    {
++        using namespace std;
++        copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
++    }
++}
++
++bool ScTable::HasRowPageBreak(SCROW nRow) const
++{
++    if (!ValidRow(nRow))
++        return false;
++
++    return maRowPageBreaks.count(nRow) > 0;
++}
++
++bool ScTable::HasColPageBreak(SCCOL nCol) const
++{
++    if (!ValidCol(nCol))
++        return false;
++
++    return maColPageBreaks.count(nCol) > 0;
++}
++
++bool ScTable::HasRowManualBreak(SCROW nRow) const
++{
++    if (!ValidRow(nRow))
++        return false;
++
++    return maRowManualBreaks.count(nRow) > 0;
++}
++
++bool ScTable::HasColManualBreak(SCCOL nCol) const
++{
++    if (!ValidCol(nCol))
++        return false;
++
++    return (maColManualBreaks.count(nCol) > 0);
++}
++
++void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow)
++{
++    using namespace std;
++
++    if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
++        return;
++
++    set<SCROW>::iterator low  = maRowPageBreaks.lower_bound(nStartRow);
++    set<SCROW>::iterator high = maRowPageBreaks.upper_bound(nEndRow);
++    maRowPageBreaks.erase(low, high);
++}
++
++void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual)
++{
++    if (!ValidRow(nRow))
++        return;
++
++    if (bPage)
++        maRowPageBreaks.erase(nRow);
++
++    if (bManual)
++    {    
++        maRowManualBreaks.erase(nRow);
++        InvalidatePageBreaks();
++    }
++}
++
++void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual)
++{
++    if (!ValidCol(nCol))
++        return;
++
++    if (bPage)
++        maColPageBreaks.erase(nCol);
+ 
+-    return FALSE;
++    if (bManual)
++    {    
++        maColManualBreaks.erase(nCol);
++        InvalidatePageBreaks();
++    }
++}
++
++void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual)
++{
++    if (!ValidRow(nRow))
++        return;
++
++    if (bPage)
++        maRowPageBreaks.insert(nRow);
++
++    if (bManual)
++    {    
++        maRowManualBreaks.insert(nRow);
++        InvalidatePageBreaks();
++    }
++}
++
++void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual)
++{
++    if (!ValidCol(nCol))
++        return;
++
++    if (bPage)
++        maColPageBreaks.insert(nCol);
++
++    if (bManual)
++    {    
++        maColManualBreaks.insert(nCol);
++        InvalidatePageBreaks();
++    }
++}
++
++Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
++{
++    using ::std::copy;
++    using ::std::inserter;
++
++    set<SCROW> aRowBreaks = maRowPageBreaks;
++    copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin()));
++
++    set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end();
++    Sequence<TablePageBreakData> aSeq(aRowBreaks.size());
++
++    for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i)
++    {
++        SCROW nRow = *itr;
++        TablePageBreakData aData;
++        aData.Position = nRow;
++        aData.ManualBreak = HasRowManualBreak(nRow);
++        aSeq[i] = aData;
++    }
++
++    return aSeq;
++}
++
++void ScTable::SyncColRowFlags()
++{
++    using ::sal::static_int_cast;
++
++    // For now, we only need to sync the manual breaks.
++
++    pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
++    for (SCCOL i = 0; i <= MAXCOL; ++i)
++        pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
++
++    if (!maRowManualBreaks.empty())
++    {
++        for (set<SCROW>::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end();
++              itr != itrEnd; ++itr)
++            pRowFlags->OrValue(*itr, static_int_cast<BYTE>(CR_MANUALBREAK));
++    }
++
++    if (!maColManualBreaks.empty())
++    {
++        for (set<SCCOL>::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end();
++              itr != itrEnd; ++itr)
++            pColFlags[*itr] |= CR_MANUALBREAK;
++    }
+ }
+ 
+ void ScTable::SetPageSize( const Size& rSize )
+ {
+     if ( rSize.Width() != 0 && rSize.Height() != 0 )
+     {
++        if (aPageSizeTwips != rSize)
++            InvalidatePageBreaks();
++
+         bPageSizeValid = TRUE;
+         aPageSizeTwips = rSize;
+     }
+--- sc/source/filter/excel/xepage.cxx.old	2009-10-07 15:06:14.000000000 +0200
++++ sc/source/filter/excel/xepage.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -48,9 +48,14 @@
+ #include "xehelper.hxx"
+ #include "xeescher.hxx"
+ 
++#include <set>
++#include <limits>
++
+ #include <oox/core/tokens.hxx>
+ 
+ using ::rtl::OString;
++using ::std::set;
++using ::std::numeric_limits;
+ 
+ // Page settings records ======================================================
+ 
+@@ -302,17 +307,23 @@ XclExpPageSettings::XclExpPageSettings(
+ 
+     // *** page breaks ***
+ 
+-    ScCompressedArrayIterator< SCROW, BYTE> aIter( rDoc.GetRowFlagsArray( nScTab), 1, GetMaxPos().Row());
+-    do
++    set<SCROW> aRowBreaks;
++    rDoc.GetAllRowBreaks(aRowBreaks, nScTab, false, true);
++
++    SCROW nMaxRow = numeric_limits<sal_uInt16>::max();
++    for (set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); itr != itrEnd; ++itr)
+     {
+-        if (*aIter & CR_MANUALBREAK)
+-            for (SCROW j=aIter.GetRangeStart(); j<=aIter.GetRangeEnd(); ++j)
+-                maData.maHorPageBreaks.push_back( static_cast< sal_uInt16 >( j ) );
+-    } while (aIter.NextRange());
+-
+-    for( SCCOL nScCol = 1, nScMaxCol = GetMaxPos().Col(); nScCol <= nScMaxCol; ++nScCol )
+-        if( rDoc.GetColFlags( nScCol, nScTab ) & CR_MANUALBREAK )
+-            maData.maVerPageBreaks.push_back( static_cast< sal_uInt16 >( nScCol ) );
++        SCROW nRow = *itr;
++        if (nRow > nMaxRow)
++            break;
++        
++        maData.maHorPageBreaks.push_back(nRow);
++    }
++
++    set<SCCOL> aColBreaks;
++    rDoc.GetAllColBreaks(aColBreaks, nScTab, false, true);
++    for (set<SCCOL>::const_iterator itr = aColBreaks.begin(), itrEnd = aColBreaks.end(); itr != itrEnd; ++itr)
++        maData.maVerPageBreaks.push_back(*itr);
+ }
+ 
+ static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm )
+--- sc/source/filter/excel/xipage.cxx.old	2009-10-07 15:06:14.000000000 +0200
++++ sc/source/filter/excel/xipage.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -378,14 +378,14 @@ void XclImpPageSettings::Finalize()
+     {
+         SCROW nScRow = static_cast< SCROW >( *aIt );
+         if( nScRow <= MAXROW )
+-            rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALBREAK );
++            rDoc.SetRowBreak(nScRow, nScTab, false, true);
+     }
+ 
+     for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt )
+     {
+         SCCOL nScCol = static_cast< SCCOL >( *aIt );
+         if( nScCol <= MAXCOL )
+-            rDoc.SetColFlags( nScCol, nScTab, rDoc.GetColFlags( nScCol, nScTab ) | CR_MANUALBREAK );
++            rDoc.SetColBreak(nScCol, nScTab, false, true);
+     }
+ }
+ 
+--- sc/source/filter/starcalc/scflt.cxx.old	2009-10-08 16:17:08.000000000 +0200
++++ sc/source/filter/starcalc/scflt.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -1552,13 +1552,15 @@ void Sc10Import::LoadTables()
+             if (DataValue != 0)
+             {
+                 BYTE nFlags = 0;
+-                if ((DataValue & crfSoftBreak) == crfSoftBreak)
+-                    nFlags |= CR_PAGEBREAK;
+-                if ((DataValue & crfHardBreak) == crfHardBreak)
+-                    nFlags |= CR_MANUALBREAK;
++				bool bPageBreak   = ((DataValue & crfSoftBreak) == crfSoftBreak);
++				bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+                 if ((DataValue & crfHidden) == crfHidden)
+                     nFlags |= CR_HIDDEN;
+-                for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++) pDoc->SetColFlags(k, static_cast<SCTAB> (TabNo), nFlags);
++				for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++) 
++                {    
++                    pDoc->SetColFlags(k, static_cast<SCTAB> (TabNo), nFlags);
++                    pDoc->SetColBreak(k, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
++                }
+             }
+             DataStart = DataEnd + 1;
+         }
+@@ -1602,13 +1604,15 @@ void Sc10Import::LoadTables()
+             if (DataValue != 0)
+             {
+                 BYTE nFlags = 0;
+-                if ((DataValue & crfSoftBreak) == crfSoftBreak)
+-                    nFlags |= CR_PAGEBREAK;
+-                if ((DataValue & crfHardBreak) == crfHardBreak)
+-                    nFlags |= CR_MANUALBREAK;
++				bool bPageBreak   = ((DataValue & crfSoftBreak) == crfSoftBreak);
++				bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak);
+                 if ((DataValue & crfHidden) == crfHidden)
+                     nFlags |= CR_HIDDEN;
+-                for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++) pDoc->SetRowFlags(l, static_cast<SCTAB> (TabNo), nFlags);
++                for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++) 
++                {    
++                    pDoc->SetRowFlags(l, static_cast<SCTAB> (TabNo), nFlags);
++                    pDoc->SetRowBreak(l, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
++                }
+             }
+             DataStart = DataEnd + 1;
+         }
+--- sc/source/filter/xml/xmlexprt.cxx.old	2010-03-03 16:59:17.000000000 +0100
++++ sc/source/filter/xml/xmlexprt.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -2559,6 +2559,7 @@ void ScXMLExport::_ExportAutoStyles()
+                             {
+                                 if (pDoc)
+                                 {
++                                    pDoc->SyncColRowFlags();
+                                     uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+                                     if (xTableColumns.is())
+                                     {
+--- sc/source/ui/docshell/dbdocfun.cxx.old	2010-03-03 16:59:09.000000000 +0100
++++ sc/source/ui/docshell/dbdocfun.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -939,7 +939,10 @@ BOOL ScDBDocFunc::Query( SCTAB nTab, con
+     }
+ 
+     if (!bCopy)
++    {
++        pDoc->InvalidatePageBreaks(nTab);    
+         pDoc->UpdatePageBreaks( nTab );
++    }
+ 
+     // #i23299# because of Subtotal functions, the whole rows must be set dirty
+     ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab,
+--- sc/source/ui/docshell/docfunc.cxx.old	2010-03-03 16:59:14.000000000 +0100
++++ sc/source/ui/docshell/docfunc.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -3212,20 +3212,22 @@ BOOL ScDocFunc::InsertPageBreak( BOOL bC
+     if (nPos == 0)
+         return FALSE;					// erste Spalte / Zeile
+ 
+-    BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab )
+-        : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab );
+-    if (nFlags & CR_MANUALBREAK)
+-        return TRUE;					// Umbruch schon gesetzt
++    ScBreakType nBreak = bColumn ? 
++        pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) : 
++        pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
++    if (nBreak & BREAK_MANUAL)
++        return true;
+ 
+     if (bRecord)
+         rDocShell.GetUndoManager()->AddUndoAction(
+             new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, TRUE ) );
+ 
+-    nFlags |= CR_MANUALBREAK;
+     if (bColumn)
+-        pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags );
++        pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
+     else
+-        pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags );
++        pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
++
++    pDoc->InvalidatePageBreaks(nTab);
+     pDoc->UpdatePageBreaks( nTab );
+ 
+     if (pDoc->IsStreamValid(nTab))
+@@ -3271,20 +3273,25 @@ BOOL ScDocFunc::RemovePageBreak( BOOL bC
+ 
+     SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
+         static_cast<SCCOLROW>(rPos.Row());
+-    BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab )
+-        : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab );
+-    if ((nFlags & CR_MANUALBREAK)==0)
+-        return FALSE;							// kein Umbruch gesetzt
++
++    ScBreakType nBreak;
++    if (bColumn)
++        nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab);
++    else
++        nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
++    if ((nBreak & BREAK_MANUAL) == 0)
++        // There is no manual break.
++        return false;
+ 
+     if (bRecord)
+         rDocShell.GetUndoManager()->AddUndoAction(
+             new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, FALSE ) );
+ 
+-    nFlags &= ~CR_MANUALBREAK;
+     if (bColumn)
+-        pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags );
++        pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
+     else
+-        pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags );
++        pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
++
+     pDoc->UpdatePageBreaks( nTab );
+ 
+     if (pDoc->IsStreamValid(nTab))
+--- sc/source/ui/docshell/olinefun.cxx.old	2009-11-20 11:38:03.000000000 +0100
++++ sc/source/ui/docshell/olinefun.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -704,6 +704,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTA
+ 
+     pArray->SetVisibleBelow( nLevel, nEntry, TRUE, TRUE );
+ 
++    pDoc->InvalidatePageBreaks(nTab);
+     pDoc->UpdatePageBreaks( nTab );
+ 
+     if (bPaint)
+@@ -769,6 +770,7 @@ BOOL ScOutlineDocFunc::HideOutline( SCTA
+ 
+     pArray->SetVisibleBelow( nLevel, nEntry, FALSE );
+ 
++    pDoc->InvalidatePageBreaks(nTab);
+     pDoc->UpdatePageBreaks( nTab );
+ 
+     if (bPaint)
+--- sc/source/ui/undo/undocell.cxx.old	2010-03-03 16:59:11.000000000 +0100
++++ sc/source/ui/undo/undocell.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -587,6 +587,8 @@ void ScUndoPageBreak::DoChange( BOOL bIn
+             pViewShell->InsertPageBreak(bColumn, FALSE);
+         else
+             pViewShell->DeletePageBreak(bColumn, FALSE);
++
++        pDocShell->GetDocument()->InvalidatePageBreaks(nTab);
+     }
+ }
+ 
+--- sc/source/ui/undo/undodat.cxx.old	2010-03-03 16:44:01.000000000 +0100
++++ sc/source/ui/undo/undodat.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -1029,7 +1029,10 @@ void __EXPORT ScUndoQuery::Undo()
+         pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE );
+ 
+     if (!bCopy)
++    {
++        pDoc->InvalidatePageBreaks(nTab);    
+         pDoc->UpdatePageBreaks( nTab );
++    }
+ 
+     ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab,
+         MAXCOL, aQueryParam.nRow2, nTab );
+--- sc/source/ui/unoobj/cellsuno.cxx.old	2010-03-03 16:59:13.000000000 +0100
++++ sc/source/ui/unoobj/cellsuno.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -7056,7 +7056,7 @@ uno::Sequence<sheet::TablePageBreakData>
+         SCCOL nCount = 0;
+         SCCOL nCol;
+         for (nCol=0; nCol<=MAXCOL; nCol++)
+-            if (pDoc->GetColFlags( nCol, nTab ) & ( CR_PAGEBREAK | CR_MANUALBREAK ))
++            if (pDoc->HasColBreak(nCol, nTab))
+                 ++nCount;
+ 
+         sheet::TablePageBreakData aData;
+@@ -7065,11 +7065,11 @@ uno::Sequence<sheet::TablePageBreakData>
+         USHORT nPos = 0;
+         for (nCol=0; nCol<=MAXCOL; nCol++)
+         {
+-            BYTE nFlags = pDoc->GetColFlags( nCol, nTab );
+-            if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK ))
++            ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
++            if (nBreak)
+             {
+                 aData.Position	  = nCol;
+-                aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0;
++                aData.ManualBreak = (nBreak & BREAK_MANUAL);
+                 pAry[nPos] = aData;
+                 ++nPos;
+             }
+@@ -7098,33 +7098,7 @@ uno::Sequence<sheet::TablePageBreakData>
+             ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
+             aPrintFunc.UpdatePages();
+         }
+-
+-        SCROW nCount = pDoc->GetRowFlagsArray( nTab).CountForAnyBitCondition(
+-                0, MAXROW, (CR_PAGEBREAK | CR_MANUALBREAK));
+-
+-        uno::Sequence<sheet::TablePageBreakData> aSeq(nCount);
+-        if (nCount)
+-        {
+-            sheet::TablePageBreakData aData;
+-            sheet::TablePageBreakData* pAry = aSeq.getArray();
+-            size_t nPos = 0;
+-            ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( nTab), 0, MAXROW);
+-            do
+-            {
+-                BYTE nFlags = *aIter;
+-                if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK ))
+-                {
+-                    for (SCROW nRow = aIter.GetRangeStart(); nRow <= aIter.GetRangeEnd(); ++nRow)
+-                    {
+-                        aData.Position	  = nRow;
+-                        aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0;
+-                        pAry[nPos] = aData;
+-                        ++nPos;
+-                    }
+-                }
+-            } while (aIter.NextRange());
+-        }
+-        return aSeq;
++        return pDoc->GetRowBreakData(nTab);
+     }
+     return uno::Sequence<sheet::TablePageBreakData>(0);
+ }
+@@ -8893,13 +8867,13 @@ void ScTableColumnObj::GetOnePropertyVal
+         }
+         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
+         {
+-            BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) );
+-            ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak );
++            ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
++            ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+         }
+         else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
+         {
+-            BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_MANUALBREAK)) );
+-            ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak );
++            ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
++            ScUnoHelpFunctions::SetBoolInAny(rAny, (nBreak & BREAK_MANUAL));
+         }
+         else
+             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+@@ -9057,13 +9031,13 @@ void ScTableRowObj::GetOnePropertyValue(
+         }
+         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
+         {
+-            BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) );
+-            ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak );
++            ScBreakType nBreak = pDoc->HasRowBreak(nRow, nTab);
++            ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+         }
+         else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
+         {
+-            BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_MANUALBREAK)) );
+-            ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak );
++            ScBreakType nBreak = (pDoc->HasRowBreak(nRow, nTab) & BREAK_MANUAL);
++            ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
+         }
+         else
+             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
+--- sc/source/ui/unoobj/docuno.cxx.old	2009-12-03 13:50:47.000000000 +0100
++++ sc/source/ui/unoobj/docuno.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -2666,13 +2666,13 @@ uno::Any SAL_CALL ScTableColumnsObj::get
+     }
+     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
+     {
+-        BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) );
+-        ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak );
++        ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
++        ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
+     }
+     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
+     {
+-        BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_MANUALBREAK)) );
+-        ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak );
++        ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab);
++        ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
+     }
+ 
+     return aAny;
+@@ -2929,13 +2929,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPro
+     }
+     else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) )
+     {
+-        BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) );
+-        ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak );
++        ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
++        ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak );
+     }
+     else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) )
+     {
+-        BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_MANUALBREAK)) );
+-        ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak );
++        ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab);
++        ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) );
+     }
+     else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) )
+     {
+--- sc/source/ui/vba/vbarange.cxx.old	2009-10-08 16:17:09.000000000 +0200
++++ sc/source/ui/vba/vbarange.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -3712,16 +3712,16 @@ ScVbaRange::getPageBreak() throw (uno::R
+         {
+             ScDocument* pDoc =  getDocumentFromRange( mxRange );
+             
+-            BYTE nFlag = 0;
++            ScBreakType nBreak = BREAK_NONE;
+             if ( !bColumn )
+-                nFlag = pDoc -> GetRowFlags(thisAddress.StartRow, thisAddress.Sheet);
++                nBreak = pDoc->HasRowBreak(thisAddress.StartRow, thisAddress.Sheet);
+             else
+-                nFlag = pDoc -> GetColFlags(static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.Sheet);
++                nBreak = pDoc->HasColBreak(thisAddress.StartColumn, thisAddress.Sheet);
+                 
+-            if ( nFlag & CR_PAGEBREAK)
++            if (nBreak & BREAK_PAGE)
+                 nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic;
+                 
+-            if ( nFlag & CR_MANUALBREAK)
++            if (nBreak & BREAK_MANUAL)
+                 nPageBreak = excel::XlPageBreak::xlPageBreakManual;
+         }		
+     }
+--- sc/source/ui/view/cellsh.cxx.old	2009-10-08 16:17:09.000000000 +0200
++++ sc/source/ui/view/cellsh.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -717,22 +717,22 @@ void ScCellShell::GetState(SfxItemSet &r
+                 break;
+ 
+             case FID_INS_ROWBRK:
+-                if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK) )
++                if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
+                     rSet.DisableItem( nWhich );
+                 break;
+ 
+             case FID_INS_COLBRK:
+-                if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK) )
++                if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
+                     rSet.DisableItem( nWhich );
+                 break;
+ 
+             case FID_DEL_ROWBRK:
+-                if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK)==0 )
++                if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
+                     rSet.DisableItem( nWhich );
+                 break;
+ 
+             case FID_DEL_COLBRK:
+-                if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK)==0 )
++                if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
+                     rSet.DisableItem( nWhich );
+                 break;
+ 
+--- sc/source/ui/view/gridwin2.cxx.old	2010-03-03 16:44:01.000000000 +0100
++++ sc/source/ui/view/gridwin2.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -936,7 +936,7 @@ void ScGridWindow::PagebreakMove( const
+                 BOOL bGrow = !bHide && nNew > nPagebreakBreak;
+                 if ( bColumn )
+                 {
+-                    if ( pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakBreak), nTab ) & CR_MANUALBREAK )
++                    if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL)
+                     {
+                         ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
+                         pViewFunc->DeletePageBreak( TRUE, TRUE, &aOldAddr, FALSE );
+@@ -949,8 +949,8 @@ void ScGridWindow::PagebreakMove( const
+                     if ( bGrow )
+                     {
+                         //	vorigen Break auf hart, und Skalierung aendern
+-                        if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() &&
+-                                !(pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakPrev), nTab ) & CR_MANUALBREAK) )
++                        bool bManualBreak = (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & BREAK_MANUAL);
++                        if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak )
+                         {
+                             ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab );
+                             pViewFunc->InsertPageBreak( TRUE, TRUE, &aPrev, FALSE );
+@@ -963,7 +963,7 @@ void ScGridWindow::PagebreakMove( const
+                 }
+                 else
+                 {
+-                    if ( pDoc->GetRowFlags( nPagebreakBreak, nTab ) & CR_MANUALBREAK )
++                    if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL)
+                     {
+                         ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
+                         pViewFunc->DeletePageBreak( FALSE, TRUE, &aOldAddr, FALSE );
+@@ -976,8 +976,8 @@ void ScGridWindow::PagebreakMove( const
+                     if ( bGrow )
+                     {
+                         //	vorigen Break auf hart, und Skalierung aendern
+-                        if ( nPagebreakPrev > aPagebreakSource.aStart.Row() &&
+-                                !(pDoc->GetRowFlags( nPagebreakPrev, nTab ) & CR_MANUALBREAK) )
++                        bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL);
++                        if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
+                         {
+                             ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
+                             pViewFunc->InsertPageBreak( FALSE, TRUE, &aPrev, FALSE );
+--- sc/source/ui/view/gridwin4.cxx.old	2010-03-03 16:59:12.000000000 +0100
++++ sc/source/ui/view/gridwin4.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -1091,7 +1091,7 @@ void ScGridWindow::DrawPagePreview( SCCO
+                     if ( nBreak >= nX1 && nBreak <= nX2+1 )
+                     {
+                         //! hidden suchen
+-                        if ( pDoc->GetColFlags( nBreak, nTab ) & CR_MANUALBREAK )
++                        if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL)
+                             pContentDev->SetFillColor( aManual );
+                         else
+                             pContentDev->SetFillColor( aAutomatic );
+@@ -1110,7 +1110,7 @@ void ScGridWindow::DrawPagePreview( SCCO
+                     if ( nBreak >= nY1 && nBreak <= nY2+1 )
+                     {
+                         //! hidden suchen
+-                        if ( pDoc->GetRowFlags( nBreak, nTab ) & CR_MANUALBREAK )
++                        if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL)
+                             pContentDev->SetFillColor( aManual );
+                         else
+                             pContentDev->SetFillColor( aAutomatic );
+--- sc/source/ui/view/output.cxx.old	2010-03-03 16:59:12.000000000 +0100
++++ sc/source/ui/view/output.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -325,8 +325,9 @@ void ScOutputData::DrawGrid( BOOL bGrid,
+     long nPosX;
+     long nPosY;
+     SCSIZE nArrY;
+-    BYTE nOldFlags = 0;
+-    BYTE nFlags;
++    ScBreakType nBreak    = BREAK_NONE;
++    ScBreakType nBreakOld = BREAK_NONE;
++
+     BOOL bSingle;
+     Color aPageColor;
+     Color aManualColor;
+@@ -381,27 +382,27 @@ void ScOutputData::DrawGrid( BOOL bGrid,
+             if ( bPage )
+             {
+                 //	Seitenumbrueche auch in ausgeblendeten suchen
+-                nFlags = 0;
+                 SCCOL nCol = nXplus1;
+                 while (nCol <= MAXCOL)
+                 {
+                     BYTE nDocFl = pDoc->GetColFlags( nCol, nTab );
+-                    nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK );
+-                    if ( nFlags || !(nDocFl & CR_HIDDEN) )
++                    nBreak = pDoc->HasColBreak(nCol, nTab);
++
++                    if ( nBreak || !(nDocFl & CR_HIDDEN) )
+                         break;
+                     ++nCol;
+                 }
+ 
+-                if (nFlags != nOldFlags)
++                if (nBreak != nBreakOld)
+                 {
+                     aGrid.Flush();
+-                    pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor :
+-                                     (nFlags) ? aPageColor : aGridColor );
+-                    nOldFlags = nFlags;
++                    pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
++                                        nBreak ? aPageColor : aGridColor );
++                    nBreakOld = nBreak;
+                 }
+             }
+ 
+-            BOOL bDraw = bGrid || nOldFlags;	// einfaches Gitter nur wenn eingestellt
++			BOOL bDraw = bGrid || nBreakOld;	// einfaches Gitter nur wenn eingestellt
+ 
+             //!	Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+             //!	Umbruch mitten in den Wiederholungsspalten liegt.
+@@ -412,7 +413,7 @@ void ScOutputData::DrawGrid( BOOL bGrid,
+             {
+                 if ( nX == MAXCOL )
+                     bDraw = FALSE;
+-                else if (pDoc->GetColFlags(nXplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK ))
++                else if (pDoc->HasColBreak(nXplus1, nTab))
+                     bDraw = FALSE;
+             }
+ #endif
+@@ -503,28 +504,24 @@ void ScOutputData::DrawGrid( BOOL bGrid,
+         {
+             if ( bPage )
+             {
+-                //	Seitenumbrueche auch in ausgeblendeten suchen
+-                nFlags = 0;
+-                ScCompressedArrayIterator< SCROW, BYTE > aIter(
+-                        pDoc->GetRowFlagsArray( nTab), nYplus1, MAXROW);
+-                do
+-                {
+-                    BYTE nDocFl = *aIter;
+-                    nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK );
+-                    if ( nFlags || !(nDocFl & CR_HIDDEN) )
++                for (SCROW i = nYplus1; i <= MAXROW; ++i)
++                {
++                    nBreak = pDoc->HasRowBreak(i, nTab);
++                    bool bHidden = (pDoc->GetRowFlags(i, nTab) & CR_HIDDEN);
++                    if (nBreak || !bHidden)
+                         break;
+-                } while (aIter.NextRange());
++                }
+ 
+-                if (nFlags != nOldFlags)
++                if (nBreakOld != nBreak)
+                 {
+                     aGrid.Flush();
+-                    pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor :
+-                                     (nFlags) ? aPageColor : aGridColor );
+-                    nOldFlags = nFlags;
++					pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
++                                        (nBreak) ? aPageColor : aGridColor );
++                    nBreakOld = nBreak;
+                 }
+             }
+ 
+-            BOOL bDraw = bGrid || nOldFlags;	// einfaches Gitter nur wenn eingestellt
++			BOOL bDraw = bGrid || nBreakOld;	// einfaches Gitter nur wenn eingestellt
+ 
+             //!	Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+             //!	Umbruch mitten in den Wiederholungszeilen liegt.
+@@ -535,7 +532,7 @@ void ScOutputData::DrawGrid( BOOL bGrid,
+             {
+                 if ( nY == MAXROW )
+                     bDraw = FALSE;
+-                else if (pDoc->GetRowFlags(nYplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK ))
++                else if (pDoc->HasRowBreak(nYplus1, nTab))
+                     bDraw = FALSE;
+             }
+ #endif
+--- sc/source/ui/view/printfun.cxx.old	2009-10-08 16:17:09.000000000 +0200
++++ sc/source/ui/view/printfun.cxx	2010-03-03 16:59:18.000000000 +0100
+@@ -2875,30 +2875,84 @@ void ScPrintFunc::CalcZoom( USHORT nRang
+     if (aTableParam.bScalePageNum)
+     {
+         nZoom = 100;
+-        BOOL bFound = FALSE;
+         USHORT nPagesToFit = aTableParam.nScalePageNum;
+-        while (!bFound)
++
++        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
++        while (true)
+         {
++            if (nZoom <= ZOOM_MIN)
++                break;
++
+             CalcPages();
+-            if ( nPagesX * nPagesY <= nPagesToFit || nZoom <= ZOOM_MIN )
+-                bFound = TRUE;
++            bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
++
++            if (bFitsPage)
++            {
++                if (nZoom == 100)
++                    // If it fits at 100 %, it's good enough for me.
++                    break;
++                
++                nLastFitZoom = nZoom;
++                nZoom = (nLastNonFitZoom + nZoom) / 2;
++
++                if (nLastFitZoom == nZoom)
++                    // It converged.  Use this zoom level.
++                    break;
++            }
+             else
+-                --nZoom;
++            {
++                if (nZoom - nLastFitZoom <= 1)
++                {
++                    nZoom = nLastFitZoom;
++                    CalcPages();
++                    break;
++                }
++
++                nLastNonFitZoom = nZoom;
++                nZoom = (nLastFitZoom + nZoom) / 2;
++            }
+         }
+     }
+     else if (aTableParam.bScaleTo)
+     {
+         nZoom = 100;
+-        BOOL bFound = FALSE;
+         USHORT nW = aTableParam.nScaleWidth;
+         USHORT nH = aTableParam.nScaleHeight;
+-        while (!bFound)
++
++        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
++        while (true)
+         {
++            if (nZoom <= ZOOM_MIN)
++                break;
++
+             CalcPages();
+-            if ( ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))) || (nZoom <= ZOOM_MIN) )
+-                bFound = TRUE;
++            bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
++
++            if (bFitsPage)
++            {
++                if (nZoom == 100)
++                    // If it fits at 100 %, it's good enough for me.
++                    break;
++                
++                nLastFitZoom = nZoom;
++                nZoom = (nLastNonFitZoom + nZoom) / 2;
++
++                if (nLastFitZoom == nZoom)
++                    // It converged.  Use this zoom level.
++                    break;
++            }
+             else
+-                --nZoom;
++            {
++                if (nZoom - nLastFitZoom <= 1)
++                {
++                    nZoom = nLastFitZoom;
++                    CalcPages();
++                    break;
++                }
++
++                nLastNonFitZoom = nZoom;
++                nZoom = (nLastFitZoom + nZoom) / 2;
++            }
+         }
+     }
+     else if (aTableParam.bScaleAll)
+@@ -3022,7 +3076,8 @@ void ScPrintFunc::CalcPages()				// bere
+     for (SCCOL i=nStartCol; i<=nEndCol; i++)
+     {
+         BYTE nFlags = pDoc->GetColFlags(i,nPrintTab);
+-        if ( i>nStartCol && bVisCol && (nFlags & CR_PAGEBREAK) )
++        bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
++        if ( i>nStartCol && bVisCol && bPageBreak )
+         {
+             pPageEndX[nPagesX] = i-1;
+             ++nPagesX;
+@@ -3047,7 +3102,8 @@ void ScPrintFunc::CalcPages()				// bere
+         SCROW nRangeEnd = aIter.GetRangeEnd();
+         for (SCROW j=aIter.GetRangeStart(); j<=nRangeEnd; ++j)
+         {
+-            if ( j>nStartRow && bVisRow && (nFlags & CR_PAGEBREAK) )
++            bool bPageBreak = (pDoc->HasRowBreak(j, nPrintTab) & BREAK_PAGE);
++            if ( j>nStartRow && bVisRow && bPageBreak )
+             {
+                 pPageEndY[nTotalY] = j-1;
+                 ++nTotalY;
diff --git a/patches/dev300/calc-perf-page-and-manual-breaks.diff b/patches/dev300/calc-perf-page-and-manual-breaks.diff
index eab9b62..491ca98 100644
--- a/patches/dev300/calc-perf-page-and-manual-breaks.diff
+++ b/patches/dev300/calc-perf-page-and-manual-breaks.diff
@@ -297,36 +297,36 @@
 --- sc/source/core/data/table2.cxx.old	2010-03-03 16:59:18.000000000 +0100
 +++ sc/source/core/data/table2.cxx	2010-03-03 16:59:18.000000000 +0100
 @@ -138,6 +138,8 @@ void ScTable::InsertRow( SCCOL nStartCol
+ 	for (SCCOL j=nStartCol; j<=nEndCol; j++)
          aCol[j].InsertRow( nStartRow, nSize );
-     if( !--nRecalcLvl )
-         SetDrawPageSize();
+     DecRecalcLevel( false );
 +
 +    InvalidatePageBreaks();
  }
  
  
 @@ -166,6 +168,8 @@ void ScTable::DeleteRow( SCCOL nStartCol
+             aCol[j].DeleteRow( nStartRow, nSize );
      }
-     if( !--nRecalcLvl )
-         SetDrawPageSize();
+     DecRecalcLevel();
 +
 +    InvalidatePageBreaks();
  }
  
  
 @@ -233,6 +237,8 @@ void ScTable::InsertCol( SCCOL nStartCol
-     }
-     if( !--nRecalcLvl )
-         SetDrawPageSize();
+ 		}
+ 	}
+     DecRecalcLevel();
 +
 +    InvalidatePageBreaks();
  }
  
  
 @@ -276,6 +282,8 @@ void ScTable::DeleteCol( SCCOL nStartCol
+ 			aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]);
      }
-     if( !--nRecalcLvl )
-         SetDrawPageSize();
+     DecRecalcLevel();
 +
 +    InvalidatePageBreaks();
  }
@@ -396,27 +396,27 @@
  {
      DBG_ASSERT( bScenario, "bScenario == FALSE" );
 @@ -1969,6 +1997,8 @@ void ScTable::SetColWidth( SCCOL nCol, U
+ 				pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] );
              pColWidth[nCol] = nNewWidth;
-             if( !--nRecalcLvl )
-                 SetDrawPageSize();
+             DecRecalcLevel();
 +
 +            InvalidatePageBreaks();
          }
      }
      else
 @@ -1999,6 +2029,8 @@ void ScTable::SetRowHeight( SCROW nRow,
+ 				pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight );
              pRowHeight->SetValue( nRow, nNewHeight);
-             if( !--nRecalcLvl )
-                 SetDrawPageSize();
+             DecRecalcLevel();
 +
 +            InvalidatePageBreaks();
          }
      }
      else
 @@ -2099,6 +2131,9 @@ BOOL ScTable::SetRowHeightRange( SCROW n
+             pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight);
          }
-         if( !--nRecalcLvl )
-             SetDrawPageSize();
+         DecRecalcLevel();
 +
 +        if (bChanged)
 +            InvalidatePageBreaks();
diff --git a/patches/dev300/calc-perf-speedup-pagebreak-update-m14.diff b/patches/dev300/calc-perf-speedup-pagebreak-update-m14.diff
new file mode 100644
index 0000000..34b43ce
--- /dev/null
+++ b/patches/dev300/calc-perf-speedup-pagebreak-update-m14.diff
@@ -0,0 +1,1263 @@
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index b9f3ee3..7158086 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -1228,7 +1228,6 @@ public:
+     SC_DLLPUBLIC USHORT			GetRowHeight( SCROW nRow, SCTAB nTab ) const;
+     SC_DLLPUBLIC ULONG			GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const;
+     ULONG			GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const;
+-    SC_DLLPUBLIC const ScSummableCompressedArray< SCROW, USHORT> & GetRowHeightArray( SCTAB nTab ) const;
+     SC_DLLPUBLIC ULONG			GetColOffset( SCCOL nCol, SCTAB nTab ) const;
+     SC_DLLPUBLIC ULONG			GetRowOffset( SCROW nRow, SCTAB nTab ) const;
+ 
+@@ -1248,9 +1247,6 @@ public:
+                         SCTAB nTab, double fScale ) const;
+     SC_DLLPUBLIC inline USHORT	FastGetRowHeight( SCROW nRow, SCTAB nTab ) const;
+     inline SCROW	FastGetRowForHeight( SCTAB nTab, ULONG nHeight ) const;
+-                    /** No check for flags whether row is hidden, height value
+-                        is returned unconditionally. */
+-    inline USHORT   FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const;
+ 
+     SCROW			GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const;
+ 
+@@ -1838,11 +1834,6 @@ inline SCROW ScDocument::FastGetRowForHeight( SCTAB nTab, ULONG nHeight ) const
+ {
+     return pTab[nTab]->GetRowForHeight(nHeight);
+ }
+-
+-inline USHORT ScDocument::FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const
+-{
+-    return pTab[nTab]->pRowHeight->GetValue(nRow);
+-}
+  
+ #endif
+ 
+diff --git sc/inc/mdds/flatsegmenttree.hxx sc/inc/mdds/flatsegmenttree.hxx
+index 40a912a..23dfc04 100644
+--- sc/inc/mdds/flatsegmenttree.hxx
++++ sc/inc/mdds/flatsegmenttree.hxx
+@@ -160,7 +160,7 @@ private:
+             return *this;
+         }
+ 
+-        void operator++()
++        const ::std::pair<key_type, value_type>* operator++()
+         {
+             assert(m_pos);
+             if (m_forward)
+@@ -177,15 +177,19 @@ private:
+                 else
+                     m_pos = get_node(m_pos->left);
+             }
++
++            return operator->();
+         }
+ 
+-        void operator--()
++        const ::std::pair<key_type, value_type>* operator--()
+         {
+             assert(m_pos);
+             if (m_end_pos)
+                 m_end_pos = false;
+             else
+                 m_pos = m_forward ? get_node(m_pos->left) : get_node(m_pos->right);
++
++            return operator->();
+         }
+ 
+         bool operator==(const const_iterator_base& r) const
+@@ -231,7 +235,7 @@ public:
+             const_iterator_base(NULL, false, true) {}
+ 
+     private:
+-        explicit const_iterator(typename const_iterator_base::fst_type* _db, bool _end) : 
++        explicit const_iterator(const typename const_iterator_base::fst_type* _db, bool _end) : 
+             const_iterator_base(_db, _end, true) {}
+     };
+ 
+@@ -242,26 +246,26 @@ public:
+         const_reverse_iterator() :
+             const_iterator_base(NULL, false, false) {}
+     private:
+-        explicit const_reverse_iterator(typename const_iterator_base::fst_type* _db, bool _end) : 
++        explicit const_reverse_iterator(const typename const_iterator_base::fst_type* _db, bool _end) : 
+             const_iterator_base(_db, _end, false) {}
+     };
+ 
+-    const_iterator begin()
++    const_iterator begin() const
+     {
+         return const_iterator(this, false);
+     }
+ 
+-    const_iterator end()
++    const_iterator end() const
+     {
+         return const_iterator(this, true);
+     }
+ 
+-    const_reverse_iterator rbegin()
++    const_reverse_iterator rbegin() const
+     {
+         return const_reverse_iterator(this, false);
+     }
+ 
+-    const_reverse_iterator rend()
++    const_reverse_iterator rend() const
+     {
+         return const_reverse_iterator(this, true);
+     }
+diff --git sc/inc/segmenttree.hxx sc/inc/segmenttree.hxx
+index 64ba898..9b9d753 100644
+--- sc/inc/segmenttree.hxx
++++ sc/inc/segmenttree.hxx
+@@ -53,6 +53,7 @@ public:
+         explicit ForwardIterator(ScFlatBoolRowSegments& rSegs);
+ 
+         bool getValue(SCROW nPos, bool& rVal);
++        SCROW getLastPos() const;
+ 
+     private:
+         ScFlatBoolRowSegments&  mrSegs;
+@@ -101,5 +102,50 @@ private:
+     ::std::auto_ptr<ScFlatBoolSegmentsImpl> mpImpl;
+ };
+ 
++// ============================================================================
++
++class ScFlatUInt16SegmentsImpl;
++
++class ScFlatUInt16RowSegments
++{
++public:
++    struct RangeData
++    {
++        SCROW       mnRow1;
++        SCROW       mnRow2;
++        sal_uInt16  mnValue;
++    };
++
++    class ForwardIterator
++    {
++    public:
++        explicit ForwardIterator(ScFlatUInt16RowSegments& rSegs);
++
++        bool getValue(SCROW nPos, sal_uInt16& rVal);
++        SCROW getLastPos() const;
++
++    private:
++        ScFlatUInt16RowSegments&  mrSegs;
++
++        SCROW       mnCurPos;
++        SCROW       mnLastPos;
++        sal_uInt16  mnCurValue;
++    };
++
++    ScFlatUInt16RowSegments(sal_uInt16 nDefault);
++    ~ScFlatUInt16RowSegments();
++
++    void setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue);
++    sal_uInt16 getValue(SCROW nRow);
++    sal_uInt32 getSumValue(SCROW nRow1, SCROW nRow2);
++    bool getRangeData(SCROW nRow, RangeData& rData);
++    void removeSegment(SCROW nRow1, SCROW nRow2);
++    void insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary);
++
++    SCROW findLastNotOf(sal_uInt16 nValue) const;
++
++private:
++    ::std::auto_ptr<ScFlatUInt16SegmentsImpl> mpImpl;
++};
+ 
+ #endif
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index cf638b2..6547ee6 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -85,6 +85,7 @@ struct ScFunctionData;
+ struct ScLineFlags;
+ class CollatorWrapper;
+ struct ScSetStringParam;
++class ScFlatUInt16RowSegments;
+ class ScFlatBoolRowSegments;
+ class ScFlatBoolColSegments;
+ 
+@@ -124,7 +125,7 @@ private:
+     ::std::auto_ptr<ScTableProtection> pTabProtection;
+ 
+     USHORT*			pColWidth;
+-    ScSummableCompressedArray< SCROW, USHORT>*  pRowHeight;
++    ::boost::shared_ptr<ScFlatUInt16RowSegments> mpRowHeights;
+ 
+     BYTE*			pColFlags;
+     ScBitMaskCompressedArray< SCROW, BYTE>*     pRowFlags;
+@@ -605,7 +606,7 @@ public:
+     void		SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual );
+ 
+ 	USHORT		GetColWidth( SCCOL nCol );
+-    SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow );
++    SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCROW* pStartRow = NULL, SCROW* pEndRow = NULL );
+ 	ULONG		GetRowHeight( SCROW nStartRow, SCROW nEndRow );
+ 	ULONG		GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale );
+ 	ULONG		GetColOffset( SCCOL nCol );
+@@ -652,8 +653,6 @@ public:
+ 
+     const ScBitMaskCompressedArray< SCROW, BYTE> * GetRowFlagsArray() const
+                     { return pRowFlags; }
+-    const ScSummableCompressedArray< SCROW, USHORT> * GetRowHeightArray() const
+-                    { return pRowHeight; }
+ 
+     BOOL		UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow );
+     BOOL		UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow );
+@@ -668,6 +667,19 @@ public:
+     bool        HasColPageBreak(SCCOL nCol) const;
+     bool        HasRowManualBreak(SCROW nRow) const;
+     bool        HasColManualBreak(SCCOL nCol) const;
++
++    /** 
++     * Get the row position of the next manual break that occurs at or below 
++     * specified row.  When no more manual breaks are present at or below 
++     * the specified row, -1 is returned. 
++     *  
++     * @param nRow row at which the search begins. 
++     *  
++     * @return SCROW next row position with manual page break, or -1 if no 
++     *         more manual breaks are present.
++     */
++    SCROW       GetNextManualBreak(SCROW nRow) const;
++
+     void        RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow);
+     void        RemoveRowBreak(SCROW nRow, bool bPage, bool bManual);
+     void        RemoveColBreak(SCCOL nCol, bool bPage, bool bManual);
+@@ -685,6 +697,7 @@ public:
+     void        SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden);
+     void        CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol);
+     void        CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow);
++    void        CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset);
+     SCROW       FirstVisibleRow(SCROW nStartRow, SCROW nEndRow);
+     SCROW       LastVisibleRow(SCROW nStartRow, SCROW nEndRow);
+     SCROW       CountVisibleRows(SCROW nStartRow, SCROW nEndRow);
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 083c5c4..daacd45 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3194,28 +3194,6 @@ ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
+ }
+ 
+ 
+-const ScSummableCompressedArray< SCROW, USHORT> & ScDocument::GetRowHeightArray(
+-        SCTAB nTab ) const
+-{
+-    const ScSummableCompressedArray< SCROW, USHORT> * pHeight;
+-    if ( ValidTab(nTab) && pTab[nTab] )
+-        pHeight = pTab[nTab]->GetRowHeightArray();
+-    else
+-    {
+-        DBG_ERROR("wrong sheet number");
+-        pHeight = 0;
+-    }
+-    if (!pHeight)
+-    {
+-        DBG_ERROR("no row heights at sheet");
+-        static ScSummableCompressedArray< SCROW, USHORT> aDummy( MAXROW,
+-                ScGlobal::nStdRowHeight);
+-        pHeight = &aDummy;
+-    }
+-    return *pHeight;
+-}
+-
+-
+ SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const
+ {
+     if ( ValidTab(nTab) && pTab[nTab] )
+@@ -3695,7 +3673,7 @@ SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const
+ 
+ SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const
+ {
+-    if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->GetRowHeightArray() )
++    if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->mpRowHeights )
+     {
+         BYTE nStartFlags = pTab[nTab]->GetRowFlags(nStart);
+         USHORT nStartHeight = pTab[nTab]->GetOriginalHeight(nStart);
+@@ -3705,7 +3683,7 @@ SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCa
+             SCROW nFlagsEndRow;
+             SCROW nHeightEndRow;
+             BYTE nFlags = pTab[nTab]->GetRowFlagsArray()->GetValue( nRow, nIndex, nFlagsEndRow );
+-            USHORT nHeight = pTab[nTab]->GetRowHeightArray()->GetValue( nRow, nIndex, nHeightEndRow );
++            USHORT nHeight = pTab[nTab]->GetRowHeight(nRow, NULL, &nHeightEndRow);
+             if (((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) ||
+                 ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) ||
+                 (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) ||
+diff --git sc/source/core/data/segmenttree.cxx sc/source/core/data/segmenttree.cxx
+index 0ee889b..98c5032 100644
+--- sc/source/core/data/segmenttree.cxx
++++ sc/source/core/data/segmenttree.cxx
+@@ -34,100 +34,182 @@
+ #include "segmenttree.hxx"
+ #include "mdds/flatsegmenttree.hxx"
+ 
+-#define USE_TREE_SEARCH 1
++#include <limits>
+ 
+-class ScFlatBoolSegmentsImpl
++using ::std::numeric_limits;
++
++// ============================================================================
++
++template<typename _ValueType, typename _ExtValueType = _ValueType>
++class ScFlatSegmentsImpl
+ {
+ public:
++    typedef _ValueType ValueType;
++    typedef _ExtValueType ExtValueType;
++
+     struct RangeData
+     {
+         SCCOLROW    mnPos1;
+         SCCOLROW    mnPos2;
+-        bool        mbValue;
++        ValueType   mnValue;
+     };
+-    ScFlatBoolSegmentsImpl(SCCOLROW nMax);
+-    ~ScFlatBoolSegmentsImpl();
+ 
+-    void setTrue(SCCOLROW nPos1, SCCOLROW nPos2);
+-    void setFalse(SCCOLROW nPos1, SCCOLROW nPos2);
+-    bool getValue(SCCOLROW nPos);
++    inline ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
++    ~ScFlatSegmentsImpl();
++
++    void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue);
++    ValueType getValue(SCCOLROW nPos);
++    ExtValueType getSumValue(SCCOLROW nPos1, SCCOLROW nPos2);
+     bool getRangeData(SCCOLROW nPos, RangeData& rData);
+     void removeSegment(SCCOLROW nPos1, SCCOLROW nPos2);
+     void insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary);
+ 
+-private:
+-    ScFlatBoolSegmentsImpl();
+-    ScFlatBoolSegmentsImpl(const ScFlatBoolSegmentsImpl&);
++    SCROW findLastNotOf(ValueType nValue) const;
+ 
+-    ::mdds::flat_segment_tree<SCCOLROW, bool> maSegments;
++private:
++    typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type;
++    fst_type maSegments;
+ };
+ 
+-ScFlatBoolSegmentsImpl::ScFlatBoolSegmentsImpl(SCCOLROW nMax) :
+-    maSegments(0, nMax+1, false)
++template<typename _ValueType, typename _ExtValueType>
++ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault) :
++    maSegments(0, nMax+1, nDefault)
+ {
+ }
+ 
+-ScFlatBoolSegmentsImpl::~ScFlatBoolSegmentsImpl()
++template<typename _ValueType, typename _ExtValueType>
++ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl()
+ {
+ }
+ 
+-void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
++template<typename _ValueType, typename _ExtValueType>
++void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue)
+ {
+-    maSegments.insert_segment(nPos1, nPos2+1, true);
++    maSegments.insert_segment(nPos1, nPos2+1, nValue);
+ }
+ 
+-void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
++template<typename _ValueType, typename _ExtValueType>
++typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ValueType ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getValue(SCCOLROW nPos)
+ {
+-    maSegments.insert_segment(nPos1, nPos2+1, false);
++    ValueType nValue = 0;
++    if (!maSegments.is_tree_valid())
++        maSegments.build_tree();
++
++    maSegments.search_tree(nPos, nValue);
++    return nValue;
+ }
+ 
+-bool ScFlatBoolSegmentsImpl::getValue(SCCOLROW nPos)
++template<typename _ValueType, typename _ExtValueType>
++typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ExtValueType 
++ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getSumValue(SCCOLROW nPos1, SCCOLROW nPos2)
+ {
+-    bool bValue = false;
+-#if USE_TREE_SEARCH
+-    if (!maSegments.is_tree_valid())
+-        maSegments.build_tree();
++    RangeData aData;
++    if (!getRangeData(nPos1, aData))
++        return 0;
+ 
+-    maSegments.search_tree(nPos, bValue);
+-#else
+-    maSegments.search(nPos, bValue);
+-#endif
+-    return bValue;
++    sal_uInt32 nValue = 0;
++
++    SCROW nCurPos = nPos1;
++    SCROW nEndPos = aData.mnPos2;
++    while (nEndPos <= nPos2)
++    {
++        nValue += aData.mnValue * (nEndPos - nCurPos + 1);
++        nCurPos = nEndPos + 1;
++        if (!getRangeData(nCurPos, aData))
++            break;
++
++        nEndPos = aData.mnPos2;
++    }
++    if (nCurPos <= nPos2)
++    {
++        nEndPos = ::std::min(nEndPos, nPos2);
++        nValue += aData.mnValue * (nEndPos - nCurPos + 1);
++    }
++    return nValue;
+ }
+ 
+-bool ScFlatBoolSegmentsImpl::getRangeData(SCCOLROW nPos, RangeData& rData)
++template<typename _ValueType, typename _ExtValueType>
++bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getRangeData(SCCOLROW nPos, RangeData& rData)
+ {
+-#if USE_TREE_SEARCH
+     if (!maSegments.is_tree_valid())
+         maSegments.build_tree();
+-#endif
+ 
+-    bool bValue;
++    ValueType nValue;
+     SCCOLROW nPos1, nPos2;
+-#if USE_TREE_SEARCH
+-    if (!maSegments.search_tree(nPos, bValue, &nPos1, &nPos2))
++    if (!maSegments.search_tree(nPos, nValue, &nPos1, &nPos2))
+         return false;
+-#else
+-    if (!maSegments.search(nPos, bValue, &nPos1, &nPos2))
+-        return false;
+-#endif
+ 
+     rData.mnPos1 = nPos1;
+     rData.mnPos2 = nPos2-1; // end point is not inclusive.
+-    rData.mbValue = bValue;
++    rData.mnValue = nValue;
+     return true;
+ }
+ 
+-void ScFlatBoolSegmentsImpl::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2)
++template<typename _ValueType, typename _ExtValueType>
++void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2)
+ {
+     maSegments.shift_segment_left(nPos1, nPos2);
+ }
+ 
+-void ScFlatBoolSegmentsImpl::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary)
++template<typename _ValueType, typename _ExtValueType>
++void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary)
+ {
+     maSegments.shift_segment_right(nPos, nSize, bSkipStartBoundary);
+ }
+ 
++template<typename _ValueType, typename _ExtValueType>
++SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType nValue) const
++{
++    SCCOLROW nPos = numeric_limits<SCCOLROW>::max(); // position not found.
++    typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend();
++    // Note that when searching in reverse direction, we need to skip the first 
++    // node, since the right-most leaf node does not store a valid value.
++    for (++itr; itr != itrEnd; ++itr)
++    {
++        if (itr->second != nValue)
++        {
++            nPos = (--itr)->first - 1;
++            break;
++        }
++    }
++    return nPos;
++}
++
++// ============================================================================
++
++class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>
++{
++public:
++    explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault) :
++        ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault)
++    {
++    }
++};
++
++// ----------------------------------------------------------------------------
++
++class ScFlatBoolSegmentsImpl : public ScFlatSegmentsImpl<bool>
++{
++public:
++    explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax) :
++        ScFlatSegmentsImpl<bool>(nMax, false)
++    {
++    }
++
++    void setTrue(SCCOLROW nPos1, SCCOLROW nPos2);
++    void setFalse(SCCOLROW nPos1, SCCOLROW nPos2);
++};
++
++void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2)
++{
++    setValue(nPos1, nPos2, true);
++}
++
++void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2)
++{
++    setValue(nPos1, nPos2, false);
++}
++
+ // ============================================================================
+ 
+ ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments& rSegs) :
+@@ -156,6 +238,11 @@ bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos, bool& rVal)
+     return true;
+ }
+ 
++SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const
++{
++    return mnLastPos;
++}
++
+ // ----------------------------------------------------------------------------
+ 
+ ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+@@ -188,7 +275,7 @@ bool ScFlatBoolRowSegments::getRangeData(SCROW nRow, RangeData& rData)

... etc. - the rest is truncated


More information about the ooo-build-commit mailing list