/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// add fill if(!getSdrFTAttribute().getFill().isDefault())
{
basegfx::B2DPolyPolygon aTransformed(aUnitPolyPolygon);
aTransformed.transform(getTransform());
aContainer.push_back(
createPolyPolygonFillPrimitive(
aTransformed,
getSdrFTAttribute().getFill(),
getSdrFTAttribute().getFillFloatTransGradient()));
} else
{ // if no fill create one for HitTest and BoundRect fallback
aContainer.push_back(
createHiddenGeometryPrimitives2D( true,
aUnitPolyPolygon,
getTransform()));
}
if(xTable.is())
{ // create primitive representation for table. Cell info goes // directly to aRetval, Border info to aBorderSequence and added // later to get the correct overlapping
drawinglayer::primitive2d::Primitive2DContainer aRetval;
drawinglayer::primitive2d::Primitive2DContainer aRetvalForShadow; const sal_Int32 nRowCount(xTable->getRowCount()); const sal_Int32 nColCount(xTable->getColumnCount()); const sal_Int32 nAllCount(nRowCount * nColCount);
SdrPage const*const pPage(rTableObj.getSdrPageFromSdrObject());
// create range using the model data directly. This is in SdrTextObj::aRect which i will access using // GetGeoRect() to not trigger any calculations. It's the unrotated geometry. const basegfx::B2DRange aObjectRange = vcl::unotools::b2DRectangleFromRectangle(rTableObj.GetGeoRect());
// To create the CellBorderPrimitives, use the tooling from svx::frame::Array // which is capable of creating the needed visualization. Fill it during the // anyways needed run over the table.
svx::frame::Array aArray;
// initialize CellBorderArray for primitive creation
aArray.Initialize(nColCount, nRowCount);
// create single primitives per cell for(aCellPos.mnRow = 0; aCellPos.mnRow < nRowCount; aCellPos.mnRow++)
{
drawinglayer::primitive2d::Primitive2DContainer row; // add RowHeight to CellBorderArray for primitive creation
aArray.SetRowHeight(aCellPos.mnRow, rTableLayouter.getRowHeight(aCellPos.mnRow));
for(aCellPos.mnCol = 0; aCellPos.mnCol < nColCount; aCellPos.mnCol++)
{
drawinglayer::primitive2d::Primitive2DContainer cell; // add ColWidth to CellBorderArray for primitive creation, only // needs to be done in the 1st run if(0 == aCellPos.mnRow)
{
aArray.SetColWidth(aCellPos.mnCol, rTableLayouter.getColumnWidth(aCellPos.mnCol));
}
// access the cell
xCurrentCell = xTable->getCell(aCellPos.mnCol, aCellPos.mnRow);
if(xCurrentCell.is())
{ // tdf#135843: Find correct neighbor cell index for merged cells auto nNextCol = aCellPos.mnCol + xCurrentCell->getColumnSpan(); auto nNextRow = aCellPos.mnRow + xCurrentCell->getRowSpan();
// ignore merged cells (all except the top-left of a merged cell) if(!xCurrentCell->isMerged())
{ // check if we are the top-left of a merged cell const sal_Int32 nXSpan(xCurrentCell->getColumnSpan()); const sal_Int32 nYSpan(xCurrentCell->getRowSpan());
if(nXSpan > 1 || nYSpan > 1)
{ // if merged, set so at CellBorderArray for primitive creation
aArray.SetMergedRange(aCellPos.mnCol, aCellPos.mnRow, aCellPos.mnCol + nXSpan - 1, aCellPos.mnRow + nYSpan - 1);
}
}
}
// always create cell primitives for BoundRect and HitTest
{ const drawinglayer::primitive2d::Primitive2DReference xCellReference( new drawinglayer::primitive2d::SdrCellPrimitive2D(
aCellMatrix, aAttribute));
cell.append(xCellReference);
}
// Create cell primitive without text.
aAttribute
= drawinglayer::primitive2d::createNewSdrFillTextAttribute(
rCellItemSet, nullptr);
rtl::Reference pCellReference
= new drawinglayer::primitive2d::SdrCellPrimitive2D(
aCellMatrix, aAttribute);
sal_uInt16 nTransparence(
rCellItemSet.Get(XATTR_FILLTRANSPARENCE).GetValue()); if (nTransparence != 0)
{
pCellReference->setTransparenceForShadow(nTransparence);
}
const drawinglayer::primitive2d::Primitive2DReference
xCellReference(pCellReference);
aRetvalForShadow.append(xCellReference);
}
} if (isTaggedPDF && pPage)
{ // heuristic: if there's a special formatting on // first row, assume that it's a header row autoconst eType(
aCellPos.mnRow == 0 && rTableObj.getTableStyleSettings().mbUseFirstRow
? vcl::pdf::StructElement::TableHeader
: vcl::pdf::StructElement::TableData);
cell = drawinglayer::primitive2d::Primitive2DContainer { new drawinglayer::primitive2d::StructureTagPrimitive2D(
eType,
pPage->IsMasterPage(), false, false,
std::move(cell)) };
}
row.append(cell);
}
if (isTaggedPDF && pPage)
{
row = drawinglayer::primitive2d::Primitive2DContainer { new drawinglayer::primitive2d::StructureTagPrimitive2D(
vcl::pdf::StructElement::TableRow,
pPage->IsMasterPage(), false, false,
std::move(row)) };
}
aRetval.append(row);
}
// now create all CellBorderPrimitives
drawinglayer::primitive2d::Primitive2DContainer aCellBorderPrimitives(aArray.CreateB2DPrimitiveArray());
if(!aCellBorderPrimitives.empty())
{ // this is already scaled (due to Table in non-uniform coordinates), so // first transform removing scale
basegfx::B2DHomMatrix aTransform(
basegfx::utils::createScaleB2DHomMatrix(
1.0 / aObjectRange.getWidth(),
1.0 / aObjectRange.getHeight()));
// If RTL, mirror the whole unified table in X and move right. // This is much easier than taking this into account for the whole // index calculations if(bIsRTL)
{
aTransform.scale(-1.0, 1.0);
aTransform.translate(1.0, 0.0);
}
// add object matrix to transform. By doing so theoretically // CellBorders could be also rotated/sheared for the first time ever. // To completely make that work, the primitives already created in // aRetval would also have to be based on ObjectMatrix, not only on // ObjectRange as it currently is.
aTransform *= aObjectMatrix;
// create a transform primitive with this and embed CellBorders // and append to retval
aRetval.append( new drawinglayer::primitive2d::TransformPrimitive2D(
aTransform,
drawinglayer::primitive2d::Primitive2DContainer(aCellBorderPrimitives)));
// Borders are always the same for shadow as well.
aRetvalForShadow.append(new drawinglayer::primitive2d::TransformPrimitive2D(
aTransform, std::move(aCellBorderPrimitives)));
}
if(!aRetval.empty())
{ // check and create evtl. shadow for created content const SfxItemSet& rObjectItemSet = rTableObj.GetMergedItemSet(); const drawinglayer::attribute::SdrShadowAttribute aNewShadowAttribute(
drawinglayer::primitive2d::createNewSdrShadowAttribute(rObjectItemSet));
if(!aNewShadowAttribute.isDefault())
{ // pass in table's transform and scale matrix, to // correctly scale and align shadows const basegfx::B2DHomMatrix aTransformScaleMatrix
= basegfx::utils::createScaleTranslateB2DHomMatrix(
aObjectRange.getRange(), aObjectRange.getMinimum());
bool bDirectShadow
= rObjectItemSet.Get(SDRATTR_SHADOW, /*bSrchInParent=*/false)
.GetValue(); if (bDirectShadow)
{ // Shadow as direct formatting: no shadow for text, to be compatible // with PowerPoint.
aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(
std::move(aRetval), aNewShadowAttribute, aTransformScaleMatrix,
&aRetvalForShadow);
} else
{ // Shadow as style: shadow for text, to be backwards-compatible.
aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(
std::move(aRetval), aNewShadowAttribute, aTransformScaleMatrix);
}
}
}
}
rVisitor.visit(std::move(aRetval));
} else
{ // take unrotated snap rect (direct model data) for position and size const basegfx::B2DRange aObjectRange = vcl::unotools::b2DRectangleFromRectangle(rTableObj.GetGeoRect());
// created an invisible outline for the cases where no visible content exists const drawinglayer::primitive2d::Primitive2DReference xReference(
drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(
aObjectMatrix));
rVisitor.visit(xReference);
}
}
void ViewObjectContactOfTableObj::createPrimitive2DSequence(
DisplayInfo const& rDisplayInfo,
drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const
{ boolconst isTaggedPDF(GetObjectContact().isExportTaggedPDF()); if (isTaggedPDF)
{ // this will be unbuffered and contain structure tags const sdr::table::SdrTableObj& rTableObj = static_cast<const sdr::table::SdrTableObj&>(*GetViewContact().TryToGetSdrObject()); return createPrimitive2DSequenceImpl(rTableObj, true, rVisitor);
} else
{ // call it via the base class - this is supposed to be buffered return sdr::contact::ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo, rVisitor);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.