[Libreoffice-commits] core.git: Branch 'feature/BorderlineFix' - 152 commits - accessibility/source android/source avmedia/source basctl/source basic/qa basic/source bridges/source canvas/source chart2/source codemaker/source comphelper/source compilerplugins/clang config.guess config.sub configure.ac connectivity/source cppcanvas/source cui/source dbaccess/source desktop/source desktop/win32 download.lst drawinglayer/source dtrans/source editeng/source embeddedobj/source embedserv/source emfio/source extensions/source external/boost external/firebird external/libcmis external/libepubgen extras/source filter/Library_svgfilter.mk filter/source forms/source fpicker/source framework/source helpcontent2 hwpfilter/source i18npool/inc i18npool/source icon-themes/sifr icon-themes/sifr_dark idlc/inc idlc/source idl/inc idl/source include/basegfx include/editeng include/rtl include/sfx2 include/svtools include/svx include/tools include/vcl include/xmloff ios/CustomTarget_iOS_setup.mk ios/LibreOfficeLight jvmfwk/plugins l10ntools/inc lingucomponent/source lotuswordpro/inc lotuswordpro/source officecfg/registry oox/source reportdesign/source RepositoryExternal.mk sal/osl sal/qa sal/rtl sc/inc sc/Library_sc.mk scp2/source sc/qa sc/source sc/uiconfig sdext/Library_pdfimport.mk sdext/source sd/inc sd/qa sd/source sd/uiconfig setup_native/source sfx2/source shell/source solenv/CompilerTest_compilerplugins_clang.mk solenv/flatpak-manifest.in solenv/gbuild sot/source starmath/inc starmath/qa starmath/source stoc/source svgio/source svl/source svtools/source svx/source svx/uiconfig sw/inc sw/qa sw/source sw/uiconfig sysui/desktop test/source tools/source ucb/source unotools/source vcl/inc vcl/opengl vcl/osx vcl/quartz vcl/source vcl/unx vcl/win winaccessibility/source writerfilter/source writerperfect/Library_wpftwriter.mk writerperfect/Module_writerperfect.mk writerperfect/qa writerperfect/source xmloff/source xmlsecurity/inc xmlsecurity/qa xmlsecurity/source
Armin Le Grand
Armin.Le.Grand at cib.de
Tue Jan 23 11:23:22 UTC 2018
Rebased ref, commits from common ancestor:
commit 3789ce8e92f99ab438844ec31a7854d9489a88e0
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Tue Jan 23 10:29:44 2018 +0100
BorderlineFix: Corrected handling for 'rotated' CellBorders
CellBorders can be rotated (including their Text) and need special
visualization that is based on an own sheared/rotated coordinate
system. Currently only possible for single cells (not merged ones)
and needs to handle all borders (also bottom-right directly in the
rotated cell, not in the neighboured ones to have the geometry,
plus avoiding these in the non-rotated neighbour cells.
Also corrected adding CellRotation data to svx::frame::Array
in calc using SetCellRotations() which now gets called in the
ScOutputData constructor to ensure it gets called in all places
where it is used.
Change-Id: I47bdfc29ba5ca76bbc07d98cb64733f867b1ee20
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index f23dabae3de0..c41433609b9e 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -255,6 +255,11 @@ private:
long SetEngineTextAndGetWidth( DrawEditParam& rParam, const OUString& rSetString,
long& rNeededPixel, long nAddWidthPixels );
+ // Check for and set cell rotations at OutputData to have it available
+ // in the svx tooling to render the borders. Moved to private section
+ // and the single call to end of constructor to be sure this always happens
+ void SetCellRotations();
+
public:
/**
* @param nNewScrX: X-Offset in the output device for the table
@@ -311,8 +316,6 @@ public:
// with logic MapMode set!
void DrawEdit(bool bPixelToLogic);
-
- void SetCellRotations();
void DrawRotated(bool bPixelToLogic); // logical
void DrawClear();
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 22e07763decb..64cd440e9902 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -696,10 +696,6 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
pContentDev->SetMapMode(aCurrentMapMode);
}
- // check for and set cell rotations at OutputData to have it available
- // in the svx tooling to render the borders
- aOutputData.SetCellRotations();
-
if ( rDoc.HasBackgroundDraw( nTab, aDrawingRectLogic ) )
{
pContentDev->SetMapMode(MapMode(MapUnit::MapPixel));
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index bd3687cd1cd3..064bb14ce1a1 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -214,6 +214,9 @@ ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
bTabProtected = mpDoc->IsTabProtected( nTab );
bLayoutRTL = mpDoc->IsLayoutRTL( nTab );
+
+ // always needed, so call at the end of the constructor
+ SetCellRotations();
}
ScOutputData::~ScOutputData()
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 096216210585..ab6db75799e3 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -1092,9 +1092,21 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
const bool bFirstRow(nRow == nFirstRow);
const bool bLastRow(nRow == nLastRow);
+ // handle rotation: If cell is rotated, handle lower/right edge inside
+ // this local geometry due to the created CoordinateSystem already representing
+ // the needed transformations.
+ const bool bRotated(rCell.IsRotated());
+
+ // Additionally avoid double-handling by supressing handling when self not roated,
+ // but above/left is rotated and thus already handled. Two directly connected
+ // rotated will paint/create both edges, they might be rotated differently.
+ const bool bSuppressAbove(!bRotated && nRow > nFirstRow && CELL(nCol, nRow - 1).IsRotated());
+ const bool bSupressLeft(!bRotated && nCol > nFirstCol && CELL(nCol - 1, nRow).IsRotated());
+
// create upper line for this Cell
- if (!bOverlapY // true for first line in merged cells or cells
- || bFirstRow) // true for non_Calc usages of this tooling
+ if ((!bOverlapY // true for first line in merged cells or cells
+ || bFirstRow) // true for non_Calc usages of this tooling
+ && !bSuppressAbove) // true when above is not rotated, so edge is already handled (see bRotated)
{
// get CellStyle - method will take care to get the correct one, e.g.
// for merged cells (it uses ORIGCELL that works with topLeft's of these)
@@ -1107,7 +1119,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
}
// create lower line for this Cell
- if (bLastRow) // true for non_Calc usages of this tooling
+ if (bLastRow // true for non_Calc usages of this tooling
+ || bRotated) // true if cell is rotated, handle lower edge in local geometry
{
const Style& rBottom(GetCellStyleBottom(nCol, nRow));
@@ -1118,8 +1131,9 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
}
// create left line for this Cell
- if (!bOverlapX // true for first column in merged cells or cells
- || bFirstCol) // true for non_Calc usages of this tooling
+ if ((!bOverlapX // true for first column in merged cells or cells
+ || bFirstCol) // true for non_Calc usages of this tooling
+ && !bSupressLeft) // true when left is not rotated, so edge is already handled (see bRotated)
{
const Style& rLeft(GetCellStyleLeft(nCol, nRow));
@@ -1130,7 +1144,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
}
// create right line for this Cell
- if (bLastCol) // true for non_Calc usages of this tooling
+ if (bLastCol // true for non_Calc usages of this tooling
+ || bRotated) // true if cell is rotated, handle right edge in local geometry
{
const Style& rRight(GetCellStyleRight(nCol, nRow));
commit 492b1ad690a3c3de6903f667e0e6793f81345221
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Mon Jan 22 14:33:20 2018 +0100
BorderlineFix: Avoid BorderLines to be too prolonged
For MergedCells there was an effect that the BorderLines
were painted too far in PrintPreview/Print/PDF visualization,
found reason and changed. Checked (hopefully) all usages,
looks good.
Change-Id: I0acf8dcb20548a98533f3ab317ac72c0d0f0a947
diff --git a/include/svx/framelinkarray.hxx b/include/svx/framelinkarray.hxx
index e135e371319c..b73531b06e47 100644
--- a/include/svx/framelinkarray.hxx
+++ b/include/svx/framelinkarray.hxx
@@ -290,7 +290,7 @@ public:
long GetHeight() const;
/** Returns the output range of the cell (nCol,nRow).
- Returns total output range of merged ranges. */
+ Returns total output range of merged ranges, if bExpandMerged is true. */
basegfx::B2DRange GetCellRange( size_t nCol, size_t nRow, bool bExpandMerged ) const;
// mirroring --------------------------------------------------------------
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index ac47053155ec..096216210585 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -840,24 +840,44 @@ long Array::GetHeight() const
basegfx::B2DRange Array::GetCellRange( size_t nCol, size_t nRow, bool bExpandMerged ) const
{
- size_t nFirstCol = bExpandMerged ? mxImpl->GetMergedFirstCol( nCol, nRow ) : nCol;
- size_t nFirstRow = bExpandMerged ? mxImpl->GetMergedFirstRow( nCol, nRow ) : nRow;
- size_t nLastCol = bExpandMerged ? mxImpl->GetMergedLastCol( nCol, nRow ) : nCol;
- size_t nLastRow = bExpandMerged ? mxImpl->GetMergedLastRow( nCol, nRow ) : nRow;
- const Point aPoint( GetColPosition( nFirstCol ), GetRowPosition( nFirstRow ) );
- const Size aSize( GetColWidth( nFirstCol, nLastCol ) + 1, GetRowHeight( nFirstRow, nLastRow ) + 1 );
- tools::Rectangle aRect(aPoint, aSize);
-
- // adjust rectangle for partly visible merged cells
- const Cell& rCell = CELL( nCol, nRow );
- if( rCell.IsMerged() )
+ if(bExpandMerged)
{
- aRect.Left() -= rCell.mnAddLeft;
- aRect.Right() += rCell.mnAddRight;
- aRect.Top() -= rCell.mnAddTop;
- aRect.Bottom() += rCell.mnAddBottom;
+ // get the Range of the fully expanded cell (if merged)
+ const size_t nFirstCol(mxImpl->GetMergedFirstCol( nCol, nRow ));
+ const size_t nFirstRow(mxImpl->GetMergedFirstRow( nCol, nRow ));
+ const size_t nLastCol(mxImpl->GetMergedLastCol( nCol, nRow ));
+ const size_t nLastRow(mxImpl->GetMergedLastRow( nCol, nRow ));
+ const Point aPoint( GetColPosition( nFirstCol ), GetRowPosition( nFirstRow ) );
+ const Size aSize( GetColWidth( nFirstCol, nLastCol ) + 1, GetRowHeight( nFirstRow, nLastRow ) + 1 );
+ tools::Rectangle aRect(aPoint, aSize);
+
+ // adjust rectangle for partly visible merged cells
+ const Cell& rCell = CELL( nCol, nRow );
+
+ if( rCell.IsMerged() )
+ {
+ // not *sure* what exactly this is good for,
+ // it is just a hard set extension at merged cells,
+ // probably *should* be included in the above extended
+ // GetColPosition/GetColWidth already. This might be
+ // added due to GetColPosition/GetColWidth not working
+ // correcly over PageChanges (if used), but not sure.
+ aRect.Left() -= rCell.mnAddLeft;
+ aRect.Right() += rCell.mnAddRight;
+ aRect.Top() -= rCell.mnAddTop;
+ aRect.Bottom() += rCell.mnAddBottom;
+ }
+
+ return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+ }
+ else
+ {
+ const Point aPoint( GetColPosition( nCol ), GetRowPosition( nRow ) );
+ const Size aSize( GetColWidth( nCol, nCol ) + 1, GetRowHeight( nRow, nRow ) + 1 );
+ const tools::Rectangle aRect(aPoint, aSize);
+
+ return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
}
- return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
}
// mirroring
@@ -1054,7 +1074,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
{
for (size_t nCol = nFirstCol; nCol <= nLastCol; ++nCol)
{
- // get Cell and CoordinateSystem (*only* for this Cell), check if used (not empty)
+ // get Cell and CoordinateSystem (*only* for this Cell, do *not* expand for
+ // merged cells (!)), check if used (non-empty vectors)
const Cell& rCell(CELL(nCol, nRow));
basegfx::B2DHomMatrix aCoordinateSystem(rCell.CreateCoordinateSystem(*this, nCol, nRow, false));
basegfx::B2DVector aX(basegfx::utils::getColumn(aCoordinateSystem, 0));
@@ -1153,9 +1174,6 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
if(bContinue)
{
- const size_t _nLastCol(mxImpl->GetMergedLastCol(nCol, nRow));
- const size_t _nLastRow(mxImpl->GetMergedLastRow(nCol, nRow));
-
if(rTLBR.IsUsed())
{
/// top-left and bottom-right Style Tables
commit 2070b2185e8fef5222654fdf84d7654d32d8aaab
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Fri Jan 19 14:43:24 2018 +0100
BorderlineFix: Corrected missing borders in print
In Print/PDF/PrintPreview border lines were missing, this
happened for merged cells. It has to do with access to the
involved Styles and/or 'Clip' set (to avoid creating everything).
Thus a 'mixed' usage of cell and merged-cell stuff was needed.
As it turns out support for this is already there, need to use
it.
Change-Id: Ic16085b97eef5c79a4501279432f43491bca350e
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 2feaab5af8bf..9b532a2d0d29 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -143,10 +143,6 @@ private:
/// the impl class holding the data
std::shared_ptr< implStyle > maImplStyle;
- /// pointer to Cell using this style. Not member of the
- /// impl class since multiple Cells may use the same style
- const Cell* mpUsingCell;
-
/// call to set maImplStyle on demand
void implEnsureImplStyle();
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index ecb3eaace1c6..ac47053155ec 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -1055,17 +1055,14 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
for (size_t nCol = nFirstCol; nCol <= nLastCol; ++nCol)
{
// get Cell and CoordinateSystem (*only* for this Cell), check if used (not empty)
- const Cell& rCell = CELL(nCol, nRow);
+ const Cell& rCell(CELL(nCol, nRow));
basegfx::B2DHomMatrix aCoordinateSystem(rCell.CreateCoordinateSystem(*this, nCol, nRow, false));
basegfx::B2DVector aX(basegfx::utils::getColumn(aCoordinateSystem, 0));
basegfx::B2DVector aY(basegfx::utils::getColumn(aCoordinateSystem, 1));
if(!aX.equalZero() && !aY.equalZero())
{
- // for getting correct Style(s) for merged Cells, we need the First(Col/Row)
- // for access (see accessing Styles below)
- const size_t _nFirstCol(mxImpl->GetMergedFirstCol(nCol, nRow));
- const size_t _nFirstRow(mxImpl->GetMergedFirstRow(nCol, nRow));
+ // get needed local values
basegfx::B2DPoint aOrigin(basegfx::utils::getColumn(aCoordinateSystem, 2));
const bool bOverlapX(rCell.mbOverlapX);
const bool bOverlapY(rCell.mbOverlapY);
@@ -1078,7 +1075,9 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
if (!bOverlapY // true for first line in merged cells or cells
|| bFirstRow) // true for non_Calc usages of this tooling
{
- const Style& rTop = GetCellStyleTop(_nFirstCol, _nFirstRow);
+ // get CellStyle - method will take care to get the correct one, e.g.
+ // for merged cells (it uses ORIGCELL that works with topLeft's of these)
+ const Style& rTop(GetCellStyleTop(nCol, nRow));
if(rTop.IsUsed())
{
@@ -1089,7 +1088,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
// create lower line for this Cell
if (bLastRow) // true for non_Calc usages of this tooling
{
- const Style& rBottom = GetCellStyleBottom(_nFirstCol, _nFirstRow);
+ const Style& rBottom(GetCellStyleBottom(nCol, nRow));
if(rBottom.IsUsed())
{
@@ -1101,7 +1100,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
if (!bOverlapX // true for first column in merged cells or cells
|| bFirstCol) // true for non_Calc usages of this tooling
{
- const Style& rLeft(GetCellStyleLeft(_nFirstCol, _nFirstRow));
+ const Style& rLeft(GetCellStyleLeft(nCol, nRow));
if(rLeft.IsUsed())
{
@@ -1112,7 +1111,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
// create right line for this Cell
if (bLastCol) // true for non_Calc usages of this tooling
{
- const Style& rRight(GetCellStyleRight(_nFirstCol, _nFirstRow));
+ const Style& rRight(GetCellStyleRight(nCol, nRow));
if(rRight.IsUsed())
{
@@ -1122,8 +1121,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
// check for crossed lines, these need special treatment, especially
// for merged cells, see below
- const Style& rTLBR = GetCellStyleTLBR(_nFirstCol, _nFirstRow);
- const Style& rBLTR = GetCellStyleBLTR(_nFirstCol, _nFirstRow);
+ const Style& rTLBR(GetCellStyleTLBR(nCol, nRow));
+ const Style& rBLTR(GetCellStyleBLTR(nCol, nRow));
if(rTLBR.IsUsed() || rBLTR.IsUsed())
{
@@ -1131,8 +1130,11 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
if(rCell.IsMerged())
{
- // first check if this merged cell was already handled
- const size_t nIndexOfMergedCell(mxImpl->GetIndex(_nFirstCol, _nFirstRow));
+ // first check if this merged cell was already handled. To do so,
+ // calculate and use the index of the TopLeft cell
+ const size_t _nMergedFirstCol(mxImpl->GetMergedFirstCol(nCol, nRow));
+ const size_t _nMergedFirstRow(mxImpl->GetMergedFirstRow(nCol, nRow));
+ const size_t nIndexOfMergedCell(mxImpl->GetIndex(_nMergedFirstCol, _nMergedFirstRow));
bContinue = (aMergedCells.end() == aMergedCells.find(nIndexOfMergedCell));
if(bContinue)
@@ -1140,7 +1142,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
// not found, add now to mark as handled
aMergedCells.insert(nIndexOfMergedCell);
- // when merged, get extended coordinate system and dependent values
+ // when merged, get extended coordinate system and derived values
+ // for the full range of this merged cell
aCoordinateSystem = rCell.CreateCoordinateSystem(*this, nCol, nRow, true);
aX = basegfx::utils::getColumn(aCoordinateSystem, 0);
aY = basegfx::utils::getColumn(aCoordinateSystem, 1);
@@ -1157,8 +1160,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
{
/// top-left and bottom-right Style Tables
/// Fill top-left Style Table
- const Style& rTLFromRight(GetCellStyleTop(_nFirstCol, _nFirstRow));
- const Style& rTLFromBottom(GetCellStyleLeft(_nFirstCol, _nFirstRow));
+ const Style& rTLFromRight(GetCellStyleTop(nCol, nRow));
+ const Style& rTLFromBottom(GetCellStyleLeft(nCol, nRow));
StyleVectorTable aStart;
const basegfx::B2DVector aAxisA(aX + aY);
@@ -1167,8 +1170,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
aStart.sort();
/// Fill bottom-right Style Table
- const Style& rBRFromBottom(GetCellStyleRight(_nLastCol, _nLastRow));
- const Style& rBRFromLeft(GetCellStyleBottom(_nLastCol, _nLastRow));
+ const Style& rBRFromBottom(GetCellStyleRight(nCol, nRow));
+ const Style& rBRFromLeft(GetCellStyleBottom(nCol, nRow));
StyleVectorTable aEnd;
const basegfx::B2DVector aAxisB(-aX -aY);
@@ -1191,8 +1194,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
{
/// bottom-left and top-right Style Tables
/// Fill bottom-left Style Table
- const Style& rBLFromTop(GetCellStyleLeft(_nFirstCol, _nLastRow));
- const Style& rBLFromBottom(GetCellStyleBottom(_nFirstCol, _nLastRow));
+ const Style& rBLFromTop(GetCellStyleLeft(nCol, nRow));
+ const Style& rBLFromBottom(GetCellStyleBottom(nCol, nRow));
StyleVectorTable aStart;
const basegfx::B2DVector aAxisA(aX - aY);
@@ -1201,8 +1204,8 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
aStart.sort();
/// Fill top-right Style Table
- const Style& rTRFromLeft(GetCellStyleTop(_nLastCol, _nFirstRow));
- const Style& rTRFromBottom(GetCellStyleRight(_nLastCol, _nFirstRow));
+ const Style& rTRFromLeft(GetCellStyleTop(nCol, nRow));
+ const Style& rTRFromBottom(GetCellStyleRight(nCol, nRow));
StyleVectorTable aEnd;
const basegfx::B2DVector aAxisB(aY - aX);
commit b386311104c52e61b86be48e9ffe8417e9ff1fec
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Thu Jan 18 17:07:43 2018 +0100
BorderlineFix: Need to redesign Borderline paint for Calc
To fix some errors, need to change svx::frame::Array conversion
to Primitives, especially regarding handling of merged cells.
These make problems in the currtent form where the full extended
merged cell tries to be converted. This is bad for cropped stuff
and also wrong for double-line stuff attaching to a merged cell.
The solution is to handle cells single and merge created primitives
which is more expensive but will work. This will involve special
handling for X-Ed (crossed) and 'roated' Cells. Also need to be
very careful since all this is used in the meantime for all
visualizations of Tables in multiple apps/situations.
Change-Id: If0652a3ba97a6f27dd5d782ea22b1514303f3710
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index ce7f09345a80..2feaab5af8bf 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -150,11 +150,6 @@ private:
/// call to set maImplStyle on demand
void implEnsureImplStyle();
- /// need information which cell this style info comes from due to needed
- /// rotation info (which is in the cell). Rotation depends on the cell.
- friend class Cell;
- void SetUsingCell(const Cell* pCell) { mpUsingCell = pCell; }
-
public:
/** Constructs an invisible frame style. */
explicit Style();
@@ -203,9 +198,6 @@ public:
/** Mirrors this style (exchanges primary and secondary), if it is a double frame style. */
Style& MirrorSelf();
- /** return the Cell using this style (if set) */
- const Cell* GetUsingCell() const { return mpUsingCell; }
-
bool operator==( const Style& rOther) const;
bool operator<( const Style& rOther) const;
};
diff --git a/include/svx/framelinkarray.hxx b/include/svx/framelinkarray.hxx
index 2b06d29a41b2..e135e371319c 100644
--- a/include/svx/framelinkarray.hxx
+++ b/include/svx/framelinkarray.hxx
@@ -291,8 +291,7 @@ public:
/** Returns the output range of the cell (nCol,nRow).
Returns total output range of merged ranges. */
- basegfx::B2DRange GetCellRange( size_t nCol, size_t nRow ) const;
- basegfx::B2DRange GetCellRange( size_t nCellIndex ) const;
+ basegfx::B2DRange GetCellRange( size_t nCol, size_t nRow, bool bExpandMerged ) const;
// mirroring --------------------------------------------------------------
@@ -312,9 +311,6 @@ public:
/** Draws the part of the array, that is inside the clipping range. */
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveArray() const;
- // fill the Cell::maCellIndex entries to allow referencing back from Cell to Array Col/Row coordinates
- void AddCellIndices() const;
-
private:
std::unique_ptr<ArrayImpl> mxImpl;
};
diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx
index a6ffdfe75389..f8f2dae645a6 100644
--- a/sc/source/ui/miscdlgs/autofmt.cxx
+++ b/sc/source/ui/miscdlgs/autofmt.cxx
@@ -250,7 +250,7 @@ void ScAutoFmtPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCo
Size aStrSize;
sal_uInt16 nFmtIndex = GetFormatIndex( nCol, nRow );
- const basegfx::B2DRange cellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange cellRange(maArray.GetCellRange( nCol, nRow, true ));
Point aPos = Point(basegfx::fround(cellRange.getMinX()), basegfx::fround(cellRange.getMinY()));
sal_uInt16 nRightX = 0;
bool bJustify = pCurData->GetIncludeJustify();
@@ -374,7 +374,7 @@ void ScAutoFmtPreview::DrawBackground(vcl::RenderContext& rRenderContext)
rRenderContext.SetLineColor();
rRenderContext.SetFillColor( pItem->GetColor() );
- const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
rRenderContext.DrawRect(
tools::Rectangle(
basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 827def10ed2f..50ddd110fa04 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -51,14 +51,12 @@ void Style::implEnsureImplStyle()
}
Style::Style() :
- maImplStyle(),
- mpUsingCell(nullptr)
+ maImplStyle()
{
}
Style::Style( double nP, double nD, double nS, SvxBorderLineStyle nType, double fScale ) :
- maImplStyle(new implStyle()),
- mpUsingCell(nullptr)
+ maImplStyle(new implStyle())
{
maImplStyle->mnType = nType;
maImplStyle->mfPatternScale = fScale;
@@ -66,8 +64,7 @@ Style::Style( double nP, double nD, double nS, SvxBorderLineStyle nType, double
}
Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS, SvxBorderLineStyle nType, double fScale ) :
- maImplStyle(new implStyle()),
- mpUsingCell(nullptr)
+ maImplStyle(new implStyle())
{
maImplStyle->mnType = nType;
maImplStyle->mfPatternScale = fScale;
@@ -75,8 +72,7 @@ Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rCo
}
Style::Style( const editeng::SvxBorderLine* pBorder, double fScale ) :
- maImplStyle(),
- mpUsingCell(nullptr)
+ maImplStyle()
{
if(nullptr != pBorder)
{
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 560eefd775ce..ecb3eaace1c6 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -45,10 +45,8 @@ public:
long mnAddTop;
long mnAddBottom;
- SvxRotateMode meRotMode;
- double mfOrientation;
- basegfx::B2DHomMatrix maCoordinateSystem;
- size_t maCellIndex;
+ SvxRotateMode meRotMode;
+ double mfOrientation;
bool mbMergeOrig;
bool mbOverlapX;
@@ -57,12 +55,12 @@ public:
public:
explicit Cell();
- void SetStyleLeft(const Style& rStyle) { maLeft = rStyle; maLeft.SetUsingCell(this); }
- void SetStyleRight(const Style& rStyle) { maRight = rStyle; maRight.SetUsingCell(this); }
- void SetStyleTop(const Style& rStyle) { maTop = rStyle; maTop.SetUsingCell(this); }
- void SetStyleBottom(const Style& rStyle) { maBottom = rStyle; maBottom.SetUsingCell(this); }
- void SetStyleTLBR(const Style& rStyle) { maTLBR = rStyle; maTLBR.SetUsingCell(this); }
- void SetStyleBLTR(const Style& rStyle) { maBLTR = rStyle; maBLTR.SetUsingCell(this); }
+ void SetStyleLeft(const Style& rStyle) { maLeft = rStyle; }
+ void SetStyleRight(const Style& rStyle) { maRight = rStyle; }
+ void SetStyleTop(const Style& rStyle) { maTop = rStyle; }
+ void SetStyleBottom(const Style& rStyle) { maBottom = rStyle; }
+ void SetStyleTLBR(const Style& rStyle) { maTLBR = rStyle; }
+ void SetStyleBLTR(const Style& rStyle) { maBLTR = rStyle; }
const Style& GetStyleLeft() const { return maLeft; }
const Style& GetStyleRight() const { return maRight; }
@@ -76,74 +74,54 @@ public:
void MirrorSelfX();
- basegfx::B2DHomMatrix const & CreateCoordinateSystem(const Array& rArray) const;
- size_t GetCellIndex(const Array& rArray) const;
+ basegfx::B2DHomMatrix CreateCoordinateSystem(const Array& rArray, size_t nCol, size_t nRow, bool bExpandMerged) const;
};
typedef std::vector< long > LongVec;
typedef std::vector< Cell > CellVec;
-size_t Cell::GetCellIndex(const Array& rArray) const
+basegfx::B2DHomMatrix Cell::CreateCoordinateSystem(const Array& rArray, size_t nCol, size_t nRow, bool bExpandMerged) const
{
- if(static_cast<size_t>(-1) == maCellIndex)
- {
- rArray.AddCellIndices();
- }
-
- return maCellIndex;
-}
+ basegfx::B2DHomMatrix aRetval;
+ const basegfx::B2DRange aRange(rArray.GetCellRange(nCol, nRow, bExpandMerged));
-basegfx::B2DHomMatrix const & Cell::CreateCoordinateSystem(const Array& rArray) const
-{
- if(!maCoordinateSystem.isIdentity())
+ if(!aRange.isEmpty())
{
- return maCoordinateSystem;
- }
-
- const size_t nCellIndex(GetCellIndex(rArray));
+ basegfx::B2DPoint aOrigin(aRange.getMinimum());
+ basegfx::B2DVector aX(aRange.getWidth(), 0.0);
+ basegfx::B2DVector aY(0.0, aRange.getHeight());
- if(static_cast<size_t>(-1) != nCellIndex)
- {
- const basegfx::B2DRange aRange(rArray.GetCellRange(nCellIndex));
-
- if(!aRange.isEmpty())
+ if (IsRotated() && SvxRotateMode::SVX_ROTATE_MODE_STANDARD != meRotMode)
{
- basegfx::B2DPoint aOrigin(aRange.getMinimum());
- basegfx::B2DVector aX(aRange.getWidth(), 0.0);
- basegfx::B2DVector aY(0.0, aRange.getHeight());
+ // when rotated, adapt values. Get Skew (cos/sin == 1/tan)
+ const double fSkew(aY.getY() * (cos(mfOrientation) / sin(mfOrientation)));
- if (IsRotated() && SvxRotateMode::SVX_ROTATE_MODE_STANDARD != meRotMode)
+ switch (meRotMode)
{
- // when rotated, adapt values. Get Skew (cos/sin == 1/tan)
- const double fSkew(aY.getY() * (cos(mfOrientation) / sin(mfOrientation)));
-
- switch (meRotMode)
- {
- case SvxRotateMode::SVX_ROTATE_MODE_TOP:
- // shear Y-Axis
- aY.setX(-fSkew);
- break;
- case SvxRotateMode::SVX_ROTATE_MODE_CENTER:
- // shear origin half, Y full
- aOrigin.setX(aOrigin.getX() + (fSkew * 0.5));
- aY.setX(-fSkew);
- break;
- case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
- // shear origin full, Y full
- aOrigin.setX(aOrigin.getX() + fSkew);
- aY.setX(-fSkew);
- break;
- default: // SvxRotateMode::SVX_ROTATE_MODE_STANDARD, already excluded above
- break;
- }
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ // shear Y-Axis
+ aY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_CENTER:
+ // shear origin half, Y full
+ aOrigin.setX(aOrigin.getX() + (fSkew * 0.5));
+ aY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ // shear origin full, Y full
+ aOrigin.setX(aOrigin.getX() + fSkew);
+ aY.setX(-fSkew);
+ break;
+ default: // SvxRotateMode::SVX_ROTATE_MODE_STANDARD, already excluded above
+ break;
}
-
- // use column vectors as coordinate axes, homogen column for translation
- const_cast<Cell*>(this)->maCoordinateSystem = basegfx::utils::createCoordinateSystemTransform(aOrigin, aX, aY);
}
+
+ // use column vectors as coordinate axes, homogen column for translation
+ aRetval = basegfx::utils::createCoordinateSystemTransform(aOrigin, aX, aY);
}
- return maCoordinateSystem;
+ return aRetval;
}
Cell::Cell() :
@@ -153,8 +131,6 @@ Cell::Cell() :
mnAddBottom( 0 ),
meRotMode(SvxRotateMode::SVX_ROTATE_MODE_STANDARD ),
mfOrientation( 0.0 ),
- maCoordinateSystem(),
- maCellIndex(static_cast<size_t>(-1)),
mbMergeOrig( false ),
mbOverlapX( false ),
mbOverlapY( false )
@@ -168,8 +144,6 @@ void Cell::MirrorSelfX()
maLeft.MirrorSelf();
maRight.MirrorSelf();
mfOrientation = -mfOrientation;
- maCoordinateSystem.identity();
- maCellIndex = static_cast<size_t>(-1);
}
@@ -864,17 +838,12 @@ long Array::GetHeight() const
return GetRowPosition( mxImpl->mnHeight ) - GetRowPosition( 0 );
}
-basegfx::B2DRange Array::GetCellRange( size_t nCellIndex ) const
-{
- return GetCellRange(nCellIndex % GetColCount(), nCellIndex / GetColCount());
-}
-
-basegfx::B2DRange Array::GetCellRange( size_t nCol, size_t nRow ) const
+basegfx::B2DRange Array::GetCellRange( size_t nCol, size_t nRow, bool bExpandMerged ) const
{
- size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
- size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
- size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
- size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
+ size_t nFirstCol = bExpandMerged ? mxImpl->GetMergedFirstCol( nCol, nRow ) : nCol;
+ size_t nFirstRow = bExpandMerged ? mxImpl->GetMergedFirstRow( nCol, nRow ) : nRow;
+ size_t nLastCol = bExpandMerged ? mxImpl->GetMergedLastCol( nCol, nRow ) : nCol;
+ size_t nLastRow = bExpandMerged ? mxImpl->GetMergedLastRow( nCol, nRow ) : nRow;
const Point aPoint( GetColPosition( nFirstCol ), GetRowPosition( nFirstRow ) );
const Size aSize( GetColWidth( nFirstCol, nLastCol ) + 1, GetRowHeight( nFirstRow, nLastRow ) + 1 );
tools::Rectangle aRect(aPoint, aSize);
@@ -1023,45 +992,6 @@ void HelperCreateVerticalEntry(
);
}
-void HelperCreateEntry(const Array& rArray, const Style& rStyle, drawinglayer::primitive2d::Primitive2DContainer& rSequence, const Color* pForceColor)
-{
- const Cell* pCell = rStyle.GetUsingCell();
-
- if(nullptr != pCell)
- {
- const size_t nCellIndex(pCell->GetCellIndex(rArray));
-
- if(static_cast<size_t>(-1) != nCellIndex)
- {
- size_t col(nCellIndex % rArray.GetColCount());
- size_t row(nCellIndex / rArray.GetColCount());
- const bool bL(&rStyle == &pCell->GetStyleLeft());
- const bool bR(&rStyle == &pCell->GetStyleRight());
- const bool bT(&rStyle == &pCell->GetStyleTop());
- const bool bB(&rStyle == &pCell->GetStyleBottom());
-
- if(bL || bR || bT || bB)
- {
- const basegfx::B2DHomMatrix aCoordinateSystem(pCell->CreateCoordinateSystem(rArray));
- const basegfx::B2DVector aX(basegfx::utils::getColumn(aCoordinateSystem, 0));
- const basegfx::B2DVector aY(basegfx::utils::getColumn(aCoordinateSystem, 1));
- const basegfx::B2DPoint aOrigin(basegfx::utils::getColumn(aCoordinateSystem, 2));
-
- if(bL || bR)
- {
- // left/right
- HelperCreateVerticalEntry(rArray, rStyle, bL ? col : col + 1, row, aOrigin, aX, aY, rSequence, bL, pForceColor);
- }
- else if(bT || bB)
- {
- // top/bottom
- HelperCreateHorizontalEntry(rArray, rStyle, col, bT ? row : row + 1, aOrigin, aX, aY, rSequence, bT, pForceColor);
- }
- }
- }
- }
-}
-
void HelperMergeInB2DPrimitiveArray(
const drawinglayer::primitive2d::Primitive2DContainer& rSource,
drawinglayer::primitive2d::Primitive2DContainer& rTarget)
@@ -1116,23 +1046,27 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
std::vector< drawinglayer::primitive2d::Primitive2DContainer > aVerticalSequences(nLastCol - nFirstCol + 1);
drawinglayer::primitive2d::Primitive2DContainer aCrossSequence;
+ // remember for which merged cells crossed lines were already created. To
+ // do so, hold the size_t cell index in a set for fast check
+ std::set< size_t > aMergedCells;
+
for (size_t nRow = nFirstRow; nRow <= nLastRow; ++nRow)
{
for (size_t nCol = nFirstCol; nCol <= nLastCol; ++nCol)
{
+ // get Cell and CoordinateSystem (*only* for this Cell), check if used (not empty)
const Cell& rCell = CELL(nCol, nRow);
- const basegfx::B2DHomMatrix aCoordinateSystem(rCell.CreateCoordinateSystem(*this));
- const basegfx::B2DVector aX(basegfx::utils::getColumn(aCoordinateSystem, 0));
- const basegfx::B2DVector aY(basegfx::utils::getColumn(aCoordinateSystem, 1));
+ basegfx::B2DHomMatrix aCoordinateSystem(rCell.CreateCoordinateSystem(*this, nCol, nRow, false));
+ basegfx::B2DVector aX(basegfx::utils::getColumn(aCoordinateSystem, 0));
+ basegfx::B2DVector aY(basegfx::utils::getColumn(aCoordinateSystem, 1));
if(!aX.equalZero() && !aY.equalZero())
{
- size_t _nFirstCol = mxImpl->GetMergedFirstCol(nCol, nRow);
- size_t _nFirstRow = mxImpl->GetMergedFirstRow(nCol, nRow);
- size_t _nLastCol = mxImpl->GetMergedLastCol(nCol, nRow);
- size_t _nLastRow = mxImpl->GetMergedLastRow(nCol, nRow);
- const basegfx::B2DPoint aOrigin(basegfx::utils::getColumn(aCoordinateSystem, 2));
-
+ // for getting correct Style(s) for merged Cells, we need the First(Col/Row)
+ // for access (see accessing Styles below)
+ const size_t _nFirstCol(mxImpl->GetMergedFirstCol(nCol, nRow));
+ const size_t _nFirstRow(mxImpl->GetMergedFirstRow(nCol, nRow));
+ basegfx::B2DPoint aOrigin(basegfx::utils::getColumn(aCoordinateSystem, 2));
const bool bOverlapX(rCell.mbOverlapX);
const bool bOverlapY(rCell.mbOverlapY);
const bool bFirstCol(nCol == nFirstCol);
@@ -1140,116 +1074,152 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
const bool bFirstRow(nRow == nFirstRow);
const bool bLastRow(nRow == nLastRow);
- if (!bOverlapX || bFirstRow)
+ // create upper line for this Cell
+ if (!bOverlapY // true for first line in merged cells or cells
+ || bFirstRow) // true for non_Calc usages of this tooling
{
const Style& rTop = GetCellStyleTop(_nFirstCol, _nFirstRow);
if(rTop.IsUsed())
{
- HelperCreateEntry(*this, rTop, aHorizontalSequence, pForceColor);
+ HelperCreateHorizontalEntry(*this, rTop, nCol, nRow, aOrigin, aX, aY, aHorizontalSequence, true, pForceColor);
}
}
- if (bLastRow)
+ // create lower line for this Cell
+ if (bLastRow) // true for non_Calc usages of this tooling
{
const Style& rBottom = GetCellStyleBottom(_nFirstCol, _nFirstRow);
if(rBottom.IsUsed())
{
- HelperCreateEntry(*this, rBottom, aHorizontalSequence, pForceColor);
+ HelperCreateHorizontalEntry(*this, rBottom, nCol, nRow + 1, aOrigin, aX, aY, aHorizontalSequence, false, pForceColor);
}
}
- if (!bOverlapY || bFirstCol)
+ // create left line for this Cell
+ if (!bOverlapX // true for first column in merged cells or cells
+ || bFirstCol) // true for non_Calc usages of this tooling
{
const Style& rLeft(GetCellStyleLeft(_nFirstCol, _nFirstRow));
if(rLeft.IsUsed())
{
- HelperCreateEntry(*this, rLeft, aVerticalSequences[nCol - nFirstCol], pForceColor);
+ HelperCreateVerticalEntry(*this, rLeft, nCol, nRow, aOrigin, aX, aY, aVerticalSequences[nCol - nFirstCol], true, pForceColor);
}
}
- if (bLastCol)
+ // create right line for this Cell
+ if (bLastCol) // true for non_Calc usages of this tooling
{
const Style& rRight(GetCellStyleRight(_nFirstCol, _nFirstRow));
if(rRight.IsUsed())
{
- HelperCreateEntry(*this, rRight, aVerticalSequences[nCol - nFirstCol], pForceColor);
+ HelperCreateVerticalEntry(*this, rRight, nCol + 1, nRow, aOrigin, aX, aY, aVerticalSequences[nCol - nFirstCol], false, pForceColor);
}
}
- if ((!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) || (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow))
+ // check for crossed lines, these need special treatment, especially
+ // for merged cells, see below
+ const Style& rTLBR = GetCellStyleTLBR(_nFirstCol, _nFirstRow);
+ const Style& rBLTR = GetCellStyleBLTR(_nFirstCol, _nFirstRow);
+
+ if(rTLBR.IsUsed() || rBLTR.IsUsed())
{
- const Style& rTLBR = GetCellStyleTLBR(_nFirstCol, _nFirstRow);
- if(rTLBR.IsUsed())
+ bool bContinue(true);
+
+ if(rCell.IsMerged())
{
- /// top-left and bottom-right Style Tables
- /// Fill top-left Style Table
- const Style& rTLFromRight(GetCellStyleTop(_nFirstCol, _nFirstRow));
- const Style& rTLFromBottom(GetCellStyleLeft(_nFirstCol, _nFirstRow));
- StyleVectorTable aStart;
- const basegfx::B2DVector aAxisA(aX + aY);
-
- aStart.add(rTLFromRight, aAxisA, aX, false);
- aStart.add(rTLFromBottom, aAxisA, aY, false);
- aStart.sort();
-
- /// Fill bottom-right Style Table
- const Style& rBRFromBottom(GetCellStyleRight(_nLastCol, _nLastRow));
- const Style& rBRFromLeft(GetCellStyleBottom(_nLastCol, _nLastRow));
- StyleVectorTable aEnd;
- const basegfx::B2DVector aAxisB(-aX -aY);
-
- aEnd.add(rBRFromBottom, aAxisB, -aY, true);
- aEnd.add(rBRFromLeft, aAxisB, -aX, true);
- aEnd.sort();
-
- CreateBorderPrimitives(
- aCrossSequence,
- aOrigin,
- aX + aY,
- rTLBR,
- aStart,
- aEnd,
- pForceColor
- );
+ // first check if this merged cell was already handled
+ const size_t nIndexOfMergedCell(mxImpl->GetIndex(_nFirstCol, _nFirstRow));
+ bContinue = (aMergedCells.end() == aMergedCells.find(nIndexOfMergedCell));
+
+ if(bContinue)
+ {
+ // not found, add now to mark as handled
+ aMergedCells.insert(nIndexOfMergedCell);
+
+ // when merged, get extended coordinate system and dependent values
+ aCoordinateSystem = rCell.CreateCoordinateSystem(*this, nCol, nRow, true);
+ aX = basegfx::utils::getColumn(aCoordinateSystem, 0);
+ aY = basegfx::utils::getColumn(aCoordinateSystem, 1);
+ aOrigin = basegfx::utils::getColumn(aCoordinateSystem, 2);
+ }
}
- const Style& rBLTR = GetCellStyleBLTR(_nFirstCol, _nFirstRow);
- if(rBLTR.IsUsed())
+ if(bContinue)
{
- /// bottom-left and top-right Style Tables
- /// Fill bottom-left Style Table
- const Style& rBLFromTop(GetCellStyleLeft(_nFirstCol, _nLastRow));
- const Style& rBLFromBottom(GetCellStyleBottom(_nFirstCol, _nLastRow));
- StyleVectorTable aStart;
- const basegfx::B2DVector aAxisA(aX - aY);
-
- aStart.add(rBLFromTop, aAxisA, -aY, true);
- aStart.add(rBLFromBottom, aAxisA, aX, false);
- aStart.sort();
-
- /// Fill top-right Style Table
- const Style& rTRFromLeft(GetCellStyleTop(_nLastCol, _nFirstRow));
- const Style& rTRFromBottom(GetCellStyleRight(_nLastCol, _nFirstRow));
- StyleVectorTable aEnd;
- const basegfx::B2DVector aAxisB(aY - aX);
-
- aEnd.add(rTRFromLeft, aAxisB, -aX, true);
- aEnd.add(rTRFromBottom, aAxisB, aY, false);
- aEnd.sort();
-
- CreateBorderPrimitives(
- aCrossSequence,
- aOrigin + aY,
- aX - aY,
- rBLTR,
- aStart,
- aEnd,
- pForceColor
- );
+ const size_t _nLastCol(mxImpl->GetMergedLastCol(nCol, nRow));
+ const size_t _nLastRow(mxImpl->GetMergedLastRow(nCol, nRow));
+
+ if(rTLBR.IsUsed())
+ {
+ /// top-left and bottom-right Style Tables
+ /// Fill top-left Style Table
+ const Style& rTLFromRight(GetCellStyleTop(_nFirstCol, _nFirstRow));
+ const Style& rTLFromBottom(GetCellStyleLeft(_nFirstCol, _nFirstRow));
+ StyleVectorTable aStart;
+ const basegfx::B2DVector aAxisA(aX + aY);
+
+ aStart.add(rTLFromRight, aAxisA, aX, false);
+ aStart.add(rTLFromBottom, aAxisA, aY, false);
+ aStart.sort();
+
+ /// Fill bottom-right Style Table
+ const Style& rBRFromBottom(GetCellStyleRight(_nLastCol, _nLastRow));
+ const Style& rBRFromLeft(GetCellStyleBottom(_nLastCol, _nLastRow));
+ StyleVectorTable aEnd;
+ const basegfx::B2DVector aAxisB(-aX -aY);
+
+ aEnd.add(rBRFromBottom, aAxisB, -aY, true);
+ aEnd.add(rBRFromLeft, aAxisB, -aX, true);
+ aEnd.sort();
+
+ CreateBorderPrimitives(
+ aCrossSequence,
+ aOrigin,
+ aX + aY,
+ rTLBR,
+ aStart,
+ aEnd,
+ pForceColor
+ );
+ }
+
+ if(rBLTR.IsUsed())
+ {
+ /// bottom-left and top-right Style Tables
+ /// Fill bottom-left Style Table
+ const Style& rBLFromTop(GetCellStyleLeft(_nFirstCol, _nLastRow));
+ const Style& rBLFromBottom(GetCellStyleBottom(_nFirstCol, _nLastRow));
+ StyleVectorTable aStart;
+ const basegfx::B2DVector aAxisA(aX - aY);
+
+ aStart.add(rBLFromTop, aAxisA, -aY, true);
+ aStart.add(rBLFromBottom, aAxisA, aX, false);
+ aStart.sort();
+
+ /// Fill top-right Style Table
+ const Style& rTRFromLeft(GetCellStyleTop(_nLastCol, _nFirstRow));
+ const Style& rTRFromBottom(GetCellStyleRight(_nLastCol, _nFirstRow));
+ StyleVectorTable aEnd;
+ const basegfx::B2DVector aAxisB(aY - aX);
+
+ aEnd.add(rTRFromLeft, aAxisB, -aX, true);
+ aEnd.add(rTRFromBottom, aAxisB, aY, false);
+ aEnd.sort();
+
+ CreateBorderPrimitives(
+ aCrossSequence,
+ aOrigin + aY,
+ aX - aY,
+ rBLTR,
+ aStart,
+ aEnd,
+ pForceColor
+ );
+ }
}
}
}
@@ -1259,6 +1229,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
// to stay compatible, create order as it was formally. Also try to
// merge primitives as far as possible
HelperMergeInB2DPrimitiveArray(aHorizontalSequence, aCrossSequence);
+
for(const auto& aVert : aVerticalSequences)
{
HelperMergeInB2DPrimitiveArray(aVert, aCrossSequence);
@@ -1279,19 +1250,9 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveArray()
return aPrimitives;
}
-void Array::AddCellIndices() const
-{
- for (size_t a(0); a < mxImpl->maCells.size(); a++)
- {
- const_cast<Array*>(this)->mxImpl->maCells[a].maCellIndex = a;
- }
-}
-
#undef ORIGCELL
#undef CELLACC
#undef CELL
-
-
#undef DBG_FRAME_CHECK_ROW_1
#undef DBG_FRAME_CHECK_COL_1
#undef DBG_FRAME_CHECK_COLROW
@@ -1299,7 +1260,6 @@ void Array::AddCellIndices() const
#undef DBG_FRAME_CHECK_COL
#undef DBG_FRAME_CHECK
-
}
}
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index d54e1b083e65..f65693d44b58 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -410,7 +410,7 @@ void FrameSelectorImpl::InitBorderGeometry()
{
for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
{
- const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
const tools::Rectangle aRect(
basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()));
@@ -469,7 +469,7 @@ void FrameSelectorImpl::InitBorderGeometry()
for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
{
// the usable area between horizonal/vertical frame borders of current quadrant
- const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
const tools::Rectangle aRect(
basegfx::fround(aCellRange.getMinX()) + nClV + 1, basegfx::fround(aCellRange.getMinY()) + nClH + 1,
basegfx::fround(aCellRange.getMaxX()) - nClV + 1, basegfx::fround(aCellRange.getMaxY()) - nClH + 1);
diff --git a/sw/source/ui/table/tautofmt.cxx b/sw/source/ui/table/tautofmt.cxx
index 7a342f1ff83e..5336024736fa 100644
--- a/sw/source/ui/table/tautofmt.cxx
+++ b/sw/source/ui/table/tautofmt.cxx
@@ -716,7 +716,7 @@ MAKENUMSTR:
SvtScriptedTextHelper aScriptedText(rRenderContext);
Size aStrSize;
sal_uInt8 nFormatIndex = GetFormatIndex( nCol, nRow );
- const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
const tools::Rectangle cellRect(
basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()));
@@ -811,7 +811,7 @@ void AutoFormatPreview::DrawBackground(vcl::RenderContext& rRenderContext)
rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::FILLCOLOR);
rRenderContext.SetLineColor();
rRenderContext.SetFillColor(aBrushItem.GetColor());
- const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow, true ));
rRenderContext.DrawRect(
tools::Rectangle(
basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
commit ea20bc176cbf575e39c602a91dd3e6919b3fc31e
Author: Stephan Bergmann <sbergman at redhat.com>
Date: Mon Jan 22 18:49:40 2018 +0100
USHRT_MAX -> SAL_MAX_UINT16
...that had presumably been forgotten when the surrounding code had been changed
from USHORT to sal_uInt16 in cd42389ad67b403a07a0dda8e2a6e213def49251
"removetooltypes01: #i112600# remove tooltypes from sc". Plus, turning the
preprocessor checks into static_asserts.
Change-Id: I78271f7027af701699865913813d6dea8b0c570b
Reviewed-on: https://gerrit.libreoffice.org/48358
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index bedeaa75c7c9..f08c09ce69eb 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -284,10 +284,8 @@ bool ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
{
// Old Add-Ins are hard limited to sal_uInt16 values.
-#if MAXCOLCOUNT_DEFINE > USHRT_MAX
-#error Add check for columns > USHRT_MAX!
-#endif
- if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ static_assert(MAXCOLCOUNT <= SAL_MAX_UINT16, "Add check for columns > SAL_MAX_UINT16!");
+ if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
return false;
sal_uInt16 nCount = 0;
@@ -369,10 +367,8 @@ bool ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
{
// Old Add-Ins are hard limited to sal_uInt16 values.
-#if MAXCOLCOUNT_DEFINE > USHRT_MAX
-#error Add check for columns > USHRT_MAX!
-#endif
- if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ static_assert(MAXCOLCOUNT <= SAL_MAX_UINT16, "Add check for columns > SAL_MAX_UINT16!");
+ if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
return false;
sal_uInt16 nCount = 0;
@@ -468,10 +464,8 @@ bool ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
{
// Old Add-Ins are hard limited to sal_uInt16 values.
-#if MAXCOLCOUNT_DEFINE > USHRT_MAX
-#error Add check for columns > USHRT_MAX!
-#endif
- if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX)
+ static_assert(MAXCOLCOUNT <= SAL_MAX_UINT16, "Add check for columns > SAL_MAX_UINT16!");
+ if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
return false;
sal_uInt16 nCount = 0;
commit 8d37253e50aca502a1f80ef648deb6f5178c4c46
Author: Matthias Seidel <mseidel at apache.org>
Date: Fri Jan 19 18:45:59 2018 +0000
Fixed wording
(cherry picked from commit 106d959da4cccda4c0342715cc06854f152c99d1)
Change-Id: I51c86dfef0e0eff59ce2892d8ea07dd066fd9667
diff --git a/include/svx/gallery.hxx b/include/svx/gallery.hxx
index cb2da0a856ba..19a2c9e226c7 100644
--- a/include/svx/gallery.hxx
+++ b/include/svx/gallery.hxx
@@ -44,7 +44,7 @@
// * share/gallery (theme files are identified by id)
//
// Since galleries may be copied from older offices to newer, do *never* change
-// this IDs except adding new ones (and adapting GALLERY_THEME_LAST). The ID
+// these IDs except adding new ones (and adapting GALLERY_THEME_LAST). The ID
// *is* written into the binary file *.thm (which is a gallery theme combined
// of three files, *.thm, *.sdv and *.sdg)
commit 8b1a83bffe35ae0e71735569512c1586bcb37b25
Author: Michael Stahl <mstahl at redhat.com>
Date: Mon Jan 22 19:48:06 2018 +0100
ofz#5566 sw: HTML import: ignore <DIV> in table structure elements
Looking at the HTML4 DTD https://www.w3.org/TR/html4/sgml/dtd.html,
inside TABLE only various elements defining the structure of the table
allowed, except inside cells (TD and TH elements).
DIV in a table but outside cells may cause cursor positions to go
off the rails, so better ignore such invalid DIV tags.
Change-Id: Ia6195d80670631669c252d572242874b13642b74
Reviewed-on: https://gerrit.libreoffice.org/48359
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sw/source/filter/html/htmltab.cxx b/sw/source/filter/html/htmltab.cxx
index d2fff4c1a907..8ed2ca32707e 100644
--- a/sw/source/filter/html/htmltab.cxx
+++ b/sw/source/filter/html/htmltab.cxx
@@ -19,6 +19,7 @@
#include <memory>
#include <hintids.hxx>
+#include <comphelper/flagguard.hxx>
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <editeng/boxitem.hxx>
@@ -3133,6 +3134,7 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions,
if( !IsParserWorking() && !m_pPendStack )
return;
+ ::comphelper::FlagRestorationGuard g(m_isInTableStructure, false);
std::unique_ptr<CellSaveStruct> xSaveStruct;
HtmlTokenId nToken = HtmlTokenId::NONE;
@@ -4946,6 +4948,7 @@ std::shared_ptr<HTMLTable> SwHTMLParser::BuildTable(SvxAdjust eParentAdjust,
if (!IsParserWorking() && !m_pPendStack)
return std::shared_ptr<HTMLTable>();
+ ::comphelper::FlagRestorationGuard g(m_isInTableStructure, true);
HtmlTokenId nToken = HtmlTokenId::NONE;
bool bPending = false;
std::unique_ptr<TableSaveStruct> xSaveStruct;
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
index aad798936453..4d939b4cba8d 100644
--- a/sw/source/filter/html/swhtml.cxx
+++ b/sw/source/filter/html/swhtml.cxx
@@ -300,6 +300,7 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn,
m_bRemoveHidden( false ),
m_bBodySeen( false ),
m_bReadingHeaderOrFooter( false ),
+ m_isInTableStructure(false),
m_nTableDepth( 0 ),
m_pTempViewFrame(nullptr)
{
@@ -1557,26 +1558,32 @@ void SwHTMLParser::NextToken( HtmlTokenId nToken )
// divisions
case HtmlTokenId::DIVISION_ON:
case HtmlTokenId::CENTER_ON:
- if( m_nOpenParaToken != HtmlTokenId::NONE )
+ if (!m_isInTableStructure)
{
- if( IsReadPRE() )
- m_nOpenParaToken = HtmlTokenId::NONE;
- else
- EndPara();
+ if (m_nOpenParaToken != HtmlTokenId::NONE)
+ {
+ if (IsReadPRE())
+ m_nOpenParaToken = HtmlTokenId::NONE;
+ else
+ EndPara();
+ }
+ NewDivision( nToken );
}
- NewDivision( nToken );
break;
case HtmlTokenId::DIVISION_OFF:
case HtmlTokenId::CENTER_OFF:
- if( m_nOpenParaToken != HtmlTokenId::NONE )
+ if (!m_isInTableStructure)
{
- if( IsReadPRE() )
- m_nOpenParaToken = HtmlTokenId::NONE;
- else
- EndPara();
+ if (m_nOpenParaToken != HtmlTokenId::NONE)
+ {
+ if (IsReadPRE())
+ m_nOpenParaToken = HtmlTokenId::NONE;
+ else
+ EndPara();
+ }
+ EndDivision();
}
- EndDivision();
break;
case HtmlTokenId::MULTICOL_ON:
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index cd43c8f3f065..9674a8892eaf 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -492,6 +492,7 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient
bool m_bBodySeen : 1;
bool m_bReadingHeaderOrFooter : 1;
+ bool m_isInTableStructure;
sal_Int32 m_nTableDepth;
commit 551e6881538189d03604730456ddd5563b1872dd
Author: Caolán McNamara <caolanm at redhat.com>
Date: Mon Jan 22 17:37:33 2018 +0000
its defineresource not define resource
regression from
commit 64d624b65124ac02d8ee59b135593fd9d8eb9067
Date: Sat Jan 9 22:55:28 2016 +0100
Fix typos
Change-Id: I9a5940027423ff0791fa7da0b79b617412ce6b86
Reviewed-on: https://gerrit.libreoffice.org/21209
Tested-by: Jenkins <ci at libreoffice.org>
Change-Id: Ifdf45e97b81523c84c73b93d14ed75b7b6909f77
Reviewed-on: https://gerrit.libreoffice.org/48355
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index fc3ef412cb34..7d0d12772c42 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -3058,7 +3058,7 @@ sal_Int32 PDFWriterImpl::createToUnicodeCMap( sal_uInt8 const * pEncoding,
}
aContents.append( "endbfchar\n"
"endcmap\n"
- "CMapName currentdict /CMap define resource pop\n"
+ "CMapName currentdict /CMap defineresource pop\n"
"end\n"
"end\n" );
SvMemoryStream aStream;
commit 44af50465a02b6f5566be45913a34fdbdba90133
Author: Telesto <telesto at surfxs.nl>
Date: Mon Jan 22 16:49:21 2018 +0200
tdf#112153: Set button theme properly
Change-Id: I0665880c0d0348fcbb3bcf04d9172405c8e31eb7
Reviewed-on: https://gerrit.libreoffice.org/48334
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Tor Lillqvist <tml at collabora.com>
diff --git a/vcl/osx/salnativewidgets.cxx b/vcl/osx/salnativewidgets.cxx
index d311526c0168..811960f1b92e 100644
--- a/vcl/osx/salnativewidgets.cxx
+++ b/vcl/osx/salnativewidgets.cxx
@@ -106,11 +106,11 @@ static ThemeButtonValue ImplGetButtonValue( ButtonValue aButtonValue )
break;
case ButtonValue::Off:
+ case ButtonValue::DontKnow:
return kThemeButtonOff;
break;
case ButtonValue::Mixed:
- case ButtonValue::DontKnow:
default:
return kThemeButtonMixed;
break;
commit ce88f2a7374bb8c53d57e8263e0701db19d62f30
Author: Telesto <telesto at surfxs.nl>
Date: Mon Jan 22 15:16:52 2018 +0200
tdf#114985: Tell NSWindow to never use automatic window tabbing
Based on https://codereview.chromium.org/2325313002/
Change-Id: I8838449d57b1d1b010491a405c87645d38199fdf
Reviewed-on: https://gerrit.libreoffice.org/48330
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Tor Lillqvist <tml at collabora.com>
diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index f805df6959d4..26f826467677 100644
--- a/vcl/osx/vclnsapp.mm
+++ b/vcl/osx/vclnsapp.mm
@@ -75,6 +75,11 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH
SAL_WNODEPRECATED_DECLARATIONS_POP
assert( pEvent );
[NSApp postEvent: pEvent atStart: NO];
+
+ if( [NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)] )
+ {
+ NSWindow.allowsAutomaticWindowTabbing = NO;
+ }
}
-(void)sendEvent:(NSEvent*)pEvent
commit f58a16d5987c8e8c16580c514ce0c7b0895b4105
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Jan 22 22:12:04 2018 +0100
tdf#114460 vcl: handle nested parentheses in PDF roundtrip
The roundtrip of the pdf image failed due to this.
Change-Id: I88a9657e242dd2659f9bf06233e5fcbfeb43ceb5
Reviewed-on: https://gerrit.libreoffice.org/48362
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 6921683d5054..af1eea1f57cf 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -2015,11 +2015,20 @@ bool PDFLiteralStringElement::Read(SvStream& rStream)
nPrevCh = ch;
rStream.ReadChar(ch);
+ // Start with 1 nesting level as we read a '(' above already.
+ int nDepth = 1;
OStringBuffer aBuf;
while (!rStream.eof())
{
+ if (ch == '(' && nPrevCh != '\\')
+ ++nDepth;
+
if (ch == ')' && nPrevCh != '\\')
+ --nDepth;
+
+ if (nDepth == 0)
{
+ // ')' of the outermost '(' is reached.
m_aValue = aBuf.makeStringAndClear();
SAL_INFO("vcl.filter", "PDFLiteralStringElement::Read: m_aValue is '" << m_aValue << "'");
return true;
diff --git a/xmlsecurity/qa/unit/pdfsigning/data/tdf114460.pdf b/xmlsecurity/qa/unit/pdfsigning/data/tdf114460.pdf
new file mode 100644
index 000000000000..a736e5bb90cd
Binary files /dev/null and b/xmlsecurity/qa/unit/pdfsigning/data/tdf114460.pdf differ
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index b36d926a4a34..cb7fd4cfe945 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -450,6 +450,8 @@ void PDFSigningTest::testTokenize()
// File that's intentionally smaller than 1024 bytes.
"small.pdf",
"tdf107149.pdf",
+ // Nested parentheses were not handled.
+ "tdf114460.pdf",
};
for (const auto& rName : aNames)
commit 90ae1e1bbbce7be9b2ff7add75923b1891e65df6
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Jan 22 16:00:10 2018 +0100
EPUB export, fxl: silence Page <N> toc entries when have chapter names
The EPUB ToC is now on par with the PDF ToC.
Change-Id: Iea714fdb68c825aa14345037e909c354bbd7cf00
Reviewed-on: https://gerrit.libreoffice.org/48346
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/external/libepubgen/libepubgen-epub3.patch.1 b/external/libepubgen/libepubgen-epub3.patch.1
index bcec187b5218..f102eaefe7a6 100644
--- a/external/libepubgen/libepubgen-epub3.patch.1
+++ b/external/libepubgen/libepubgen-epub3.patch.1
@@ -355,3 +355,71 @@ index 8e88adb..38ddcdf 100644
--
2.13.6
+From b6081f659e3000d9f3d5851278d8abdd33448353 Mon Sep 17 00:00:00 2001
+From: Miklos Vajna <vmiklos at collabora.co.uk>
+Date: Mon, 22 Jan 2018 15:54:43 +0100
+Subject: [PATCH] fixed layout: avoid Page <N> entries when chapter names are
+ provided
+
+---
+ src/lib/EPUBHTMLManager.cpp | 31 ++++++++++++++++++-------------
+ src/test/EPUBTextGeneratorTest.cpp | 16 ++++++++++++++++
+ 2 files changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/src/lib/EPUBHTMLManager.cpp b/src/lib/EPUBHTMLManager.cpp
+index d35bc3f..35d82e8 100644
+--- a/src/lib/EPUBHTMLManager.cpp
++++ b/src/lib/EPUBHTMLManager.cpp
+@@ -7,6 +7,7 @@
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
++#include <algorithm>
+ #include <cassert>
+ #include <iomanip>
+ #include <sstream>
+@@ -91,24 +92,28 @@ void EPUBHTMLManager::writeTocTo(EPUBXMLSink &sink, const EPUBPath &tocPath, int
+ {
+ if (version >= 30)
+ {
++ bool hasChapterNames = std::find_if(m_paths.begin(), m_paths.end(), [](const EPUBPath &path)
++ {
++ return !path.getChapters().empty();
++ }) != m_paths.end();
+ for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
+ {
+ const std::vector<std::string> &chapters = m_paths[i].getChapters();
+- if (!chapters.empty())
++ for (const auto &chapter : chapters)
+ {
+- for (const auto &chapter : chapters)
+- {
+- sink.openElement("li");
+- librevenge::RVNGPropertyList anchorAttrs;
+- anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
+- sink.openElement("a", anchorAttrs);
+- std::ostringstream label;
+- sink.insertCharacters(chapter.c_str());
+- sink.closeElement("a");
+- sink.closeElement("li");
+- }
+- continue;
++ sink.openElement("li");
++ librevenge::RVNGPropertyList anchorAttrs;
++ anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
++ sink.openElement("a", anchorAttrs);
++ std::ostringstream label;
++ sink.insertCharacters(chapter.c_str());
++ sink.closeElement("a");
++ sink.closeElement("li");
+ }
++ if (hasChapterNames)
++ // Chapter names are provided for this document, so never write Page
++ // <N> entries.
++ continue;
+
+ sink.openElement("li");
+ librevenge::RVNGPropertyList anchorAttrs;
+--
+2.13.6
+
diff --git a/writerperfect/Module_writerperfect.mk b/writerperfect/Module_writerperfect.mk
index 6fa274bc8ce5..01f8a0dc5e59 100644
--- a/writerperfect/Module_writerperfect.mk
+++ b/writerperfect/Module_writerperfect.mk
@@ -40,7 +40,7 @@ $(eval $(call gb_Module_add_check_targets,writerperfect,\
$(eval $(call gb_Module_add_slowcheck_targets,writerperfect,\
CppunitTest_writerperfect_calc \
CppunitTest_writerperfect_draw \
- CppunitTest_writerperfect_epubexport \
+ $(if $(SYSTEM_EPUBGEN),,CppunitTest_writerperfect_epubexport) \
CppunitTest_writerperfect_import \
CppunitTest_writerperfect_impress \
CppunitTest_writerperfect_writer \
commit a54787669b9283efdfdd18b0cbafc3184cdde58f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Jan 22 15:18:45 2018 +0100
EPUB export, fixed layout: add chapter names to the navigation document
Extend vcl::PDFExtOutDevData so that it's possible to use it outside the
PDF export; this way the EPUB export can know which chapters start on
which page.
This means fixed and reflowable layout has the same table of contents,
instead of just Page <N> in the fixed layout case.
Change-Id: I935fb23c66ec747431b91e83b0e677d4e5f704b9
Reviewed-on: https://gerrit.libreoffice.org/48332
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
diff --git a/external/libepubgen/libepubgen-epub3.patch.1 b/external/libepubgen/libepubgen-epub3.patch.1
index 4b7fe5215f05..bcec187b5218 100644
--- a/external/libepubgen/libepubgen-epub3.patch.1
+++ b/external/libepubgen/libepubgen-epub3.patch.1
@@ -197,3 +197,161 @@ index bdf3bf0..cb4efee 100644
--
2.13.6
+From c081609849b18113340c39a73b6af432a103a102 Mon Sep 17 00:00:00 2001
+From: Miklos Vajna <vmiklos at collabora.co.uk>
+Date: Mon, 22 Jan 2018 14:39:19 +0100
+Subject: [PATCH] fixed layout: allow defining chapter names
+
+Fixed layout normally just works with SVG images (one image / page), but
+readable navigation document is still expected, e.g. PDF provides it. So
+add a way to mention what chapters start on a given page.
+---
+ src/lib/EPUBHTMLManager.cpp | 25 +++++++++++++++++++++++++
+ src/lib/EPUBHTMLManager.h | 3 +++
+ src/lib/EPUBPath.cpp | 11 +++++++++++
+ src/lib/EPUBPath.h | 4 ++++
+ src/lib/EPUBTextGenerator.cpp | 15 +++++++++++++++
+ src/test/EPUBTextGeneratorTest.cpp | 37 +++++++++++++++++++++++++++++++++++++
+ 6 files changed, 95 insertions(+)
+
+diff --git a/src/lib/EPUBHTMLManager.cpp b/src/lib/EPUBHTMLManager.cpp
+index 5e96d1d..d35bc3f 100644
+--- a/src/lib/EPUBHTMLManager.cpp
++++ b/src/lib/EPUBHTMLManager.cpp
+@@ -93,6 +93,23 @@ void EPUBHTMLManager::writeTocTo(EPUBXMLSink &sink, const EPUBPath &tocPath, int
+ {
+ for (std::vector<EPUBPath>::size_type i = 0; m_paths.size() != i; ++i)
+ {
++ const std::vector<std::string> &chapters = m_paths[i].getChapters();
++ if (!chapters.empty())
++ {
++ for (const auto &chapter : chapters)
++ {
++ sink.openElement("li");
++ librevenge::RVNGPropertyList anchorAttrs;
++ anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
++ sink.openElement("a", anchorAttrs);
++ std::ostringstream label;
++ sink.insertCharacters(chapter.c_str());
++ sink.closeElement("a");
++ sink.closeElement("li");
++ }
++ continue;
++ }
++
+ sink.openElement("li");
+ librevenge::RVNGPropertyList anchorAttrs;
+ anchorAttrs.insert("href", m_paths[i].relativeTo(tocPath).str().c_str());
+@@ -140,6 +157,14 @@ void EPUBHTMLManager::insertHeadingText(const std::string &text)
+ m_paths.back().appendTitle(text);
+ }
+
++void EPUBHTMLManager::addChapterName(const std::string &text)
++{
++ if (m_paths.empty())
++ return;
++
++ m_paths.back().addChapter(text);
++}
++
+ bool EPUBHTMLManager::hasHeadingText() const
+ {
+ if (m_paths.empty())
+diff --git a/src/lib/EPUBHTMLManager.h b/src/lib/EPUBHTMLManager.h
+index 157896b..d48ddf2 100644
+--- a/src/lib/EPUBHTMLManager.h
++++ b/src/lib/EPUBHTMLManager.h
+@@ -51,6 +51,9 @@ public:
+ /// Appends text to the title of the current heading.
+ void insertHeadingText(const std::string &text);
+
++ /// Registers a chapter name for the current page (fixed layout case).
++ void addChapterName(const std::string &text);
++
+ /// If the current heading has a title.
+ bool hasHeadingText() const;
+
+diff --git a/src/lib/EPUBPath.cpp b/src/lib/EPUBPath.cpp
+index e1c05ed..be24de5 100644
+--- a/src/lib/EPUBPath.cpp
++++ b/src/lib/EPUBPath.cpp
+@@ -54,6 +54,7 @@ EPUBPath::Relative::Relative(const std::vector<std::string> &components)
+ EPUBPath::EPUBPath(const std::string &path)
+ : m_components()
+ , m_title()
++ , m_chapters()
+ {
+ const std::string trimmed(algorithm::trim_left_copy_if(path, algorithm::is_any_of("/")));
+ algorithm::split(m_components, trimmed, algorithm::is_any_of("/"), algorithm::token_compress_on);
+@@ -116,6 +117,16 @@ void EPUBPath::appendTitle(const std::string &title)
+ m_title += title;
+ }
+
++void EPUBPath::addChapter(const std::string &chapter)
++{
++ m_chapters.push_back(chapter);
++}
++
++const std::vector<std::string> &EPUBPath::getChapters() const
++{
++ return m_chapters;
++}
++
+ std::string EPUBPath::getTitle() const
+ {
+ return m_title;
+diff --git a/src/lib/EPUBPath.h b/src/lib/EPUBPath.h
+index 12b8f25..76f2d7b 100644
+--- a/src/lib/EPUBPath.h
++++ b/src/lib/EPUBPath.h
+@@ -51,9 +51,13 @@ public:
+ void appendTitle(const std::string &title);
+ std::string getTitle() const;
+
++ /// Adds chapter name (fixed layout).
++ void addChapter(const std::string &chapter);
++ const std::vector<std::string> &getChapters() const;
+ private:
+ std::vector<std::string> m_components;
+ std::string m_title;
++ std::vector<std::string> m_chapters;
+ };
+
+ bool operator==(const EPUBPath &left, const EPUBPath &right);
+diff --git a/src/lib/EPUBTextGenerator.cpp b/src/lib/EPUBTextGenerator.cpp
+index 8e88adb..38ddcdf 100644
+--- a/src/lib/EPUBTextGenerator.cpp
++++ b/src/lib/EPUBTextGenerator.cpp
+@@ -270,7 +270,9 @@ void EPUBTextGenerator::openParagraph(const librevenge::RVNGPropertyList &propLi
+ {
+ const RVNGProperty *const breakBefore = propList["fo:break-before"];
+ if (isPageBreak(breakBefore) && m_impl->getSplitGuard().splitOnPageBreak())
++ {
+ m_impl->startNewHtmlFile();
++ }
+ const RVNGProperty *const breakAfter = propList["fo:break-after"];
+ m_impl->m_breakAfterPara = isPageBreak(breakAfter);
+ if (m_impl->getSplitGuard().splitOnSize())
+@@ -282,6 +284,19 @@ void EPUBTextGenerator::openParagraph(const librevenge::RVNGPropertyList &propLi
+ m_impl->startNewHtmlFile();
+ m_impl->getSplitGuard().setCurrentHeadingLevel(outlineLevel ? outlineLevel->getInt() : 0);
+
++ if (const librevenge::RVNGPropertyListVector *chapterNames = m_impl->m_pageSpanProps.child("librevenge:chapter-names"))
++ {
++ for (unsigned long i = 0; i < chapterNames->count(); i++)
++ {
++ RVNGPropertyList const &chapter=(*chapterNames)[i];
++ const RVNGProperty *const chapterName = chapter["librevenge:name"];
++ if (!chapterName)
++ continue;
++
++ m_impl->getHtmlManager().addChapterName(chapterName->getStr().cstr());
++ }
++ }
++
+ m_impl->getSplitGuard().openLevel();
+
+ if (m_impl->m_inHeader || m_impl->m_inFooter)
+--
+2.13.6
+
diff --git a/filter/source/graphic/GraphicExportFilter.cxx b/filter/source/graphic/GraphicExportFilter.cxx
index 5990c2d001c7..8d91d4edc605 100644
--- a/filter/source/graphic/GraphicExportFilter.cxx
+++ b/filter/source/graphic/GraphicExportFilter.cxx
@@ -138,7 +138,7 @@ bool GraphicExportFilter::filterRenderDocument() const
if (mnTargetWidth == 0 || mnTargetHeight == 0)
aTargetSizePixel = aDocumentSizePixel;
- Graphic aGraphic = aRenderer.renderToGraphic(nCurrentPage, aDocumentSizePixel, aTargetSizePixel, COL_WHITE);
+ Graphic aGraphic = aRenderer.renderToGraphic(nCurrentPage, aDocumentSizePixel, aTargetSizePixel, COL_WHITE, /*bExtOutDevData=*/false);
GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
diff --git a/include/svtools/DocumentToGraphicRenderer.hxx b/include/svtools/DocumentToGraphicRenderer.hxx
index 5ed6f2ce4434..a7af217597c7 100644
--- a/include/svtools/DocumentToGraphicRenderer.hxx
+++ b/include/svtools/DocumentToGraphicRenderer.hxx
@@ -21,6 +21,8 @@
#ifndef INCLUDED_SVTOOLS_DOCUMENTTOGRAPHICRENDERER_HXX
#define INCLUDED_SVTOOLS_DOCUMENTTOGRAPHICRENDERER_HXX
+#include <vector>
+
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/view/XRenderable.hpp>
@@ -51,6 +53,7 @@ class SVT_DLLPUBLIC DocumentToGraphicRenderer
css::uno::Any maSelection;
bool mbSelectionOnly;
bool mbIsWriter;
+ std::vector<OUString> maChapterNames;
bool hasSelection() const;
@@ -66,13 +69,18 @@ public:
~DocumentToGraphicRenderer();
sal_Int32 getCurrentPage();
+ /**
+ * Get list of chapter names for a page, current page is set by
+ * renderToGraphic().
+ */
+ const std::vector<OUString>& getChapterNames() const;
Size getDocumentSizeInPixels( sal_Int32 nCurrentPage );
Size getDocumentSizeIn100mm( sal_Int32 nCurrentPage );
Graphic renderToGraphic( sal_Int32 nCurrentPage, Size aDocumentSizePixel,
- Size aTargetSizePixel, Color aPageColor);
+ Size aTargetSizePixel, Color aPageColor, bool bExtOutDevData);
/** Determine whether rxController has a css::view::XSelectionSupplier at
which either a css::drawing::XShapes or css::drawing::XShape is
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index 377760d7655c..e9a2ad04fb04 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -92,6 +92,7 @@ class VCL_DLLPUBLIC PDFExtOutDevData : public ExtOutDevData
std::unique_ptr<GlobalSyncData> mpGlobalSyncData;
std::vector< PDFExtOutDevBookmarkEntry > maBookmarks;
+ std::vector<OUString> maChapterNames;
public:
@@ -143,6 +144,7 @@ public:
void SetDocumentLocale( const css::lang::Locale& rLoc );
std::vector< PDFExtOutDevBookmarkEntry >& GetBookmarks() { return maBookmarks;}
+ const std::vector<OUString>& GetChapterNames() { return maChapterNames; }
const Graphic& GetCurrentGraphic() const;
diff --git a/svtools/source/filter/DocumentToGraphicRenderer.cxx b/svtools/source/filter/DocumentToGraphicRenderer.cxx
index 74275afa5c79..8d48bca87706 100644
--- a/svtools/source/filter/DocumentToGraphicRenderer.cxx
+++ b/svtools/source/filter/DocumentToGraphicRenderer.cxx
@@ -22,6 +22,7 @@
#include <vcl/graphicfilter.hxx>
#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
#include <tools/fract.hxx>
@@ -154,7 +155,8 @@ Graphic DocumentToGraphicRenderer::renderToGraphic(
sal_Int32 nCurrentPage,
Size aDocumentSizePixel,
Size aTargetSizePixel,
- Color aPageColor)
+ Color aPageColor,
+ bool bExtOutDevData)
{
if (!mxModel.is() || !mxController.is() || !mxRenderable.is())
@@ -171,7 +173,7 @@ Graphic DocumentToGraphicRenderer::renderToGraphic(
double fScaleY = aTargetSizePixel.Height() / static_cast<double>(aDocumentSizePixel.Height());
PropertyValues renderProps;
- renderProps.realloc( 4 );
+ renderProps.realloc( 6 );
renderProps[0].Name = "IsPrinter";
renderProps[0].Value <<= true;
renderProps[1].Name = "RenderDevice";
@@ -180,10 +182,22 @@ Graphic DocumentToGraphicRenderer::renderToGraphic(
renderProps[2].Value <<= mxController;
renderProps[3].Name = "RenderToGraphic";
renderProps[3].Value <<= true;
+ renderProps[4].Name = "HasPDFExtOutDevData";
+ renderProps[4].Value <<= bExtOutDevData;
+ renderProps[5].Name = "PageRange";
+ renderProps[5].Value <<= OUString::number(nCurrentPage);
GDIMetaFile aMtf;
OutputDevice* pOutputDev = VCLUnoHelper::GetOutputDevice( xDevice );
+
+ vcl::PDFExtOutDevData aPDFExtOutDevData(*pOutputDev);
+ if (bExtOutDevData)
+ {
+ aPDFExtOutDevData.SetIsExportBookmarks(true);
+ pOutputDev->SetExtOutDevData(&aPDFExtOutDevData);
+ }
+
pOutputDev->SetAntialiasing(pOutputDev->GetAntialiasing() | AntialiasingFlags::EnableB2dDraw);
MapMode mm = pOutputDev->GetMapMode();
mm.SetScaleX( Fraction(fScaleX) );
@@ -205,9 +219,17 @@ Graphic DocumentToGraphicRenderer::renderToGraphic(
aMtf.WindStart();
aMtf.SetPrefSize( aTargetSizePixel );
+ if (bExtOutDevData)
+ maChapterNames = aPDFExtOutDevData.GetChapterNames();
+
return Graphic(aMtf);
}
+const std::vector<OUString>& DocumentToGraphicRenderer::getChapterNames() const
+{
+ return maChapterNames;
+}
+
sal_Int32 DocumentToGraphicRenderer::getCurrentPage()
{
if (hasSelection())
diff --git a/svtools/source/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx
index a309b748e096..931e4008dd27 100644
--- a/svtools/source/filter/exportdialog.cxx
+++ b/svtools/source/filter/exportdialog.cxx
@@ -434,7 +434,7 @@ void ExportDialog::GetGraphicStream()
aDocumentSizePixel );
Graphic aGraphic( aRenderer.renderToGraphic( nCurrentPage,
- aDocumentSizePixel, aTargetSizePixel, COL_WHITE));
+ aDocumentSizePixel, aTargetSizePixel, COL_WHITE, /*bExtOutDevData=*/false));
xGraphic = aGraphic.GetXGraphic();
}
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index c03857e128b6..9d2ccc5cdd11 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -2893,7 +2893,8 @@ void SAL_CALL SwXTextDocument::render(
if (0 > nRenderer)
throw IllegalArgumentException();
- const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
+ const bool bHasPDFExtOutDevData = lcl_SeqHasProperty( rxOptions, "HasPDFExtOutDevData" );
+ const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ) || bHasPDFExtOutDevData;
bool bIsSwSrcView = false;
SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
@@ -2976,7 +2977,7 @@ void SAL_CALL SwXTextDocument::render(
SwPrintData const& rSwPrtOptions =
*m_pRenderData->GetSwPrtOptions();
- if (bIsPDFExport && bFirstPage && pWrtShell)
+ if (bIsPDFExport && (bFirstPage || bHasPDFExtOutDevData) && pWrtShell)
{
SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, false, rSwPrtOptions );
}
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index db5b731393c9..d5197a04d41c 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -684,6 +684,10 @@ void PDFExtOutDevData::SetScreenStream(sal_Int32 nScreenId, const OUString& rURL
sal_Int32 PDFExtOutDevData::CreateOutlineItem( sal_Int32 nParent, const OUString& rText, sal_Int32 nDestID )
{
+ if (nParent == -1)
+ // Has no parent, it's a chapter / heading 1.
+ maChapterNames.push_back(rText);
+
mpGlobalSyncData->mActions.push_back( PDFExtOutDevDataSync::CreateOutlineItem );
mpGlobalSyncData->mParaInts.push_back( nParent );
mpGlobalSyncData->mParaOUStrings.push_back( rText );
diff --git a/writerperfect/qa/unit/EPUBExportTest.cxx b/writerperfect/qa/unit/EPUBExportTest.cxx
index 176324b0dff7..47e84ebf1bbc 100644
--- a/writerperfect/qa/unit/EPUBExportTest.cxx
+++ b/writerperfect/qa/unit/EPUBExportTest.cxx
@@ -348,6 +348,13 @@ void EPUBExportTest::testEPUBFixedLayoutImplicitBreak()
// This was missing, implicit page break (as calculated by the layout) was lost on export.
CPPUNIT_ASSERT(mxZipFile->hasByName("OEBPS/sections/section0002.xhtml"));
CPPUNIT_ASSERT(!mxZipFile->hasByName("OEBPS/sections/section0003.xhtml"));
+
+ // Make sure that fixed layout has chapter names in the navigation
+ // document.
+ mpXmlDoc = parseExport("OEBPS/toc.xhtml");
+ // This was 'Page 1' instead.
+ assertXPathContent(mpXmlDoc, "//xhtml:li[1]/xhtml:a", "First chapter");
+ assertXPathContent(mpXmlDoc, "//xhtml:li[2]/xhtml:a", "Second chapter");
}
void EPUBExportTest::testPageBreakSplit()
diff --git a/writerperfect/qa/unit/data/writer/epubexport/fxl-2page.fodt b/writerperfect/qa/unit/data/writer/epubexport/fxl-2page.fodt
index 6a22acd0821f..40f628b5e646 100644
--- a/writerperfect/qa/unit/data/writer/epubexport/fxl-2page.fodt
+++ b/writerperfect/qa/unit/data/writer/epubexport/fxl-2page.fodt
@@ -44,6 +44,10 @@
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="12pt" style:font-name-complex="Lucida Sans1" style:font-family-complex="'Lucida Sans'" style:font-family-generic-complex="swiss"/>
</style:style>
+ <style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text">
+ <style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" loext:contextual-spacing="false"/>
+ <style:text-properties fo:font-size="130%" fo:font-weight="bold" style:font-size-asian="130%" style:font-weight-asian="bold" style:font-size-complex="130%" style:font-weight-complex="bold"/>
+ </style:style>
</office:styles>
<office:automatic-styles>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
@@ -65,7 +69,10 @@
</office:master-styles>
<office:body>
<office:text text:use-soft-page-breaks="true">
+ <text:h text:style-name="Heading_20_1" text:outline-level="1">First chapter</text:h>
<text:p text:style-name="P1"><text:span text:style-name="T1">He heard quiet steps behind him. That didn't bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who'd had the same idea, and was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around. Suddenly he saw the alley. Like lightning he darted off to the left and disappeared between the two warehouses almost falling over the trash can lying in the middle of the sidewalk. He tried to nervously tap </text:span><text:soft-page-break/><text:span text:style-name="T1">his way along in the inky darkness and suddenly stiffened: it was a dead-end, he would h
ave to go back the way he had come. The steps got louder and louder, he saw the black outline of a figure coming around the corner. Is this the end of the line?</text:span></text:p>
+ <text:h text:style-name="Heading_20_1" text:outline-level="1">Second chapter</text:h>
+ <text:p text:style-name="Standard">This is the end.</text:p>
</office:text>
</office:body>
</office:document>
diff --git a/writerperfect/source/writer/EPUBExportFilter.cxx b/writerperfect/source/writer/EPUBExportFilter.cxx
index b25118350193..2e4286e1f80b 100644
--- a/writerperfect/source/writer/EPUBExportFilter.cxx
+++ b/writerperfect/source/writer/EPUBExportFilter.cxx
@@ -94,7 +94,7 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
if (xSourceModel.is())
aSourceURL = xSourceModel->getURL();
- std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> aPageMetafiles;
+ std::vector<exp::FixedLayoutPage> aPageMetafiles;
if (nLayoutMethod == libepubgen::EPUB_LAYOUT_METHOD_FIXED)
CreateMetafiles(aPageMetafiles);
@@ -119,7 +119,7 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
return xFilter->filter(rDescriptor);
}
-void EPUBExportFilter::CreateMetafiles(std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &rPageMetafiles)
+void EPUBExportFilter::CreateMetafiles(std::vector<exp::FixedLayoutPage> &rPageMetafiles)
{
DocumentToGraphicRenderer aRenderer(mxSourceDocument, /*bSelectionOnly=*/false);
uno::Reference<frame::XModel> xModel(mxSourceDocument, uno::UNO_QUERY);
@@ -142,7 +142,7 @@ void EPUBExportFilter::CreateMetafiles(std::vector<std::pair<uno::Sequence<sal_I
Size aLogic = aRenderer.getDocumentSizeIn100mm(nPage);
// Get the CSS pixel size of the page (mm100 -> pixel using 96 DPI, independent from system DPI).
Size aCss(static_cast<double>(aLogic.getWidth()) / 26.4583, static_cast<double>(aLogic.getHeight()) / 26.4583);
- Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aCss, COL_WHITE);
+ Graphic aGraphic = aRenderer.renderToGraphic(nPage, aDocumentSizePixel, aCss, COL_WHITE, /*bExtOutDevData=*/true);
auto &rGDIMetaFile = const_cast<GDIMetaFile &>(aGraphic.GetGDIMetaFile());
// Set preferred map unit and size on the metafile, so the SVG size
@@ -156,7 +156,11 @@ void EPUBExportFilter::CreateMetafiles(std::vector<std::pair<uno::Sequence<sal_I
rGDIMetaFile.Write(aMemoryStream);
uno::Sequence<sal_Int8> aSequence(static_cast<const sal_Int8 *>(aMemoryStream.GetData()), aMemoryStream.Tell());
- rPageMetafiles.emplace_back(aSequence, aCss);
+ exp::FixedLayoutPage aPage;
+ aPage.aMetafile = aSequence;
+ aPage.aCssPixels = aCss;
+ aPage.aChapterNames = aRenderer.getChapterNames();
+ rPageMetafiles.push_back(aPage);
}
}
diff --git a/writerperfect/source/writer/EPUBExportFilter.hxx b/writerperfect/source/writer/EPUBExportFilter.hxx
index 188139a32843..ee676d3e1701 100644
--- a/writerperfect/source/writer/EPUBExportFilter.hxx
+++ b/writerperfect/source/writer/EPUBExportFilter.hxx
@@ -19,7 +19,7 @@
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
-class Size;
+#include "exp/xmlimp.hxx"
namespace writerperfect
{
@@ -59,7 +59,7 @@ public:
private:
/// Create page metafiles in case of fixed layout.
- void CreateMetafiles(std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &rPageMetafiles);
+ void CreateMetafiles(std::vector<exp::FixedLayoutPage> &rPageMetafiles);
};
} // namespace writerperfect
diff --git a/writerperfect/source/writer/exp/xmlimp.cxx b/writerperfect/source/writer/exp/xmlimp.cxx
index ef681119d4cf..3ef02f69f008 100644
--- a/writerperfect/source/writer/exp/xmlimp.cxx
+++ b/writerperfect/source/writer/exp/xmlimp.cxx
@@ -238,7 +238,7 @@ public:
rtl::Reference<XMLImportContext> CreateChildContext(const OUString &rName, const uno::Reference<xml::sax::XAttributeList> &/*xAttribs*/) override;
// Handles metafile for a single page.
- void HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &rPage, const Size &rSize, bool bFirst);
+ void HandleFixedLayoutPage(const FixedLayoutPage &rPage, bool bFirst);
};
XMLOfficeDocContext::XMLOfficeDocContext(XMLImport &rImport)
@@ -266,7 +266,7 @@ rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const O
bool bFirst = true;
for (const auto &rPage : mrImport.GetPageMetafiles())
{
- HandleFixedLayoutPage(rPage.first, rPage.second, bFirst);
+ HandleFixedLayoutPage(rPage, bFirst);
if (bFirst)
bFirst = false;
}
@@ -274,7 +274,7 @@ rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const O
return nullptr;
}
-void XMLOfficeDocContext::HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &rPage, const Size &rSize, bool bFirst)
+void XMLOfficeDocContext::HandleFixedLayoutPage(const FixedLayoutPage &rPage, bool bFirst)
{
uno::Reference<uno::XComponentContext> xCtx = mrImport.GetComponentContext();
uno::Reference<xml::sax::XWriter> xSaxWriter = xml::sax::Writer::create(xCtx);
@@ -292,17 +292,31 @@ void XMLOfficeDocContext::HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &r
SvMemoryStream aMemoryStream;
xSaxWriter->setOutputStream(new utl::OStreamWrapper(aMemoryStream));
- xSVGWriter->write(xSaxWriter, rPage);
+ xSVGWriter->write(xSaxWriter, rPage.aMetafile);
- // Have all the info, invoke libepubgen.
+ // Have all the info, invoke the generator.
librevenge::RVNGPropertyList aPageProperties;
// Pixel -> inch.
- double fWidth = rSize.getWidth();
+ double fWidth = rPage.aCssPixels.getWidth();
fWidth /= 96;
aPageProperties.insert("fo:page-width", fWidth);
- double fHeight = rSize.getHeight();
+ double fHeight = rPage.aCssPixels.getHeight();
fHeight /= 96;
aPageProperties.insert("fo:page-height", fHeight);
+
+ if (!rPage.aChapterNames.empty())
+ {
+ // Name of chapters starting on this page.
+ librevenge::RVNGPropertyListVector aChapterNames;
+ for (const auto &rName : rPage.aChapterNames)
+ {
+ librevenge::RVNGPropertyList aChapter;
+ aChapter.insert("librevenge:name", rName.toUtf8().getStr());
+ aChapterNames.append(aChapter);
+ }
+ aPageProperties.insert("librevenge:chapter-names", aChapterNames);
+ }
+
mrImport.GetGenerator().openPageSpan(aPageProperties);
librevenge::RVNGPropertyList aParagraphProperties;
if (!bFirst)
@@ -320,7 +334,7 @@ void XMLOfficeDocContext::HandleFixedLayoutPage(const uno::Sequence<sal_Int8> &r
mrImport.GetGenerator().closePageSpan();
}
-XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &rDescriptor, const std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &rPageMetafiles)
+XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &rDescriptor, const std::vector<FixedLayoutPage> &rPageMetafiles)
: mrGenerator(rGenerator),
mxContext(xContext),
mrPageMetafiles(rPageMetafiles)
@@ -421,7 +435,7 @@ PopupState XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGProper
return PopupState::Consumed;
}
-const std::vector<std::pair<uno::Sequence<sal_Int8>, Size>> &XMLImport::GetPageMetafiles() const
+const std::vector<FixedLayoutPage> &XMLImport::GetPageMetafiles() const
{
return mrPageMetafiles;
}
diff --git a/writerperfect/source/writer/exp/xmlimp.hxx b/writerperfect/source/writer/exp/xmlimp.hxx
index 246eb45dbd16..1953c7196772 100644
--- a/writerperfect/source/writer/exp/xmlimp.hxx
+++ b/writerperfect/source/writer/exp/xmlimp.hxx
@@ -23,8 +23,7 @@
#include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx>
-
-class Size;
+#include <tools/gen.hxx>
namespace writerperfect
{
@@ -33,6 +32,14 @@ namespace exp
class XMLImportContext;
+/// Contains info about a fixed-layout page.
+struct FixedLayoutPage
+{
+ css::uno::Sequence<sal_Int8> aMetafile;
+ Size aCssPixels;
+ std::vector<OUString> aChapterNames;
+};
+
/// States describing the result of a link -> popup conversion.
enum class PopupState
{
@@ -74,10 +81,10 @@ class XMLImport : public cppu::WeakImplHelper
const css::uno::Reference<css::uno::XComponentContext> &mxContext;
css::uno::Reference<css::uri::XUriReferenceFactory> mxUriReferenceFactory;
OUString maMediaDir;
- const std::vector<std::pair<css::uno::Sequence<sal_Int8>, Size>> &mrPageMetafiles;
+ const std::vector<FixedLayoutPage> &mrPageMetafiles;
public:
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list