LibreOffice Module svx (master) 1
viewcontactoftableobj.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22#include <svx/svdotable.hxx>
23#include <com/sun/star/table/XTable.hpp>
41#include <svx/svdpage.hxx>
42#include <svx/framelink.hxx>
44#include <svx/sdooitm.hxx>
45#include <utility>
46#include <vcl/canvastools.hxx>
48#include <svx/xfltrit.hxx>
49
50#include <cell.hxx>
51#include "tablelayouter.hxx"
52
53
55using namespace com::sun::star;
56
57
59{
60 namespace {
61
62 class SdrCellPrimitive2D : public BufferedDecompositionPrimitive2D
63 {
64 private:
66 attribute::SdrFillTextAttribute maSdrFTAttribute;
67
68 protected:
69 // local decomposition.
70 virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& aViewInformation) const override;
71
72 public:
73 SdrCellPrimitive2D(
74 basegfx::B2DHomMatrix aTransform,
75 const attribute::SdrFillTextAttribute& rSdrFTAttribute)
76 : maTransform(std::move(aTransform)),
77 maSdrFTAttribute(rSdrFTAttribute)
78 {
79 }
80
81 // data access
82 const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
83 const attribute::SdrFillTextAttribute& getSdrFTAttribute() const { return maSdrFTAttribute; }
84
85 // compare operator
86 virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
87
88 // provide unique ID
89 virtual sal_uInt32 getPrimitive2DID() const override;
90 };
91
92 }
93
94 void SdrCellPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*aViewInformation*/) const
95 {
96 // prepare unit polygon
98
99 // add fill
100 if(!getSdrFTAttribute().getFill().isDefault())
101 {
102 basegfx::B2DPolyPolygon aTransformed(aUnitPolyPolygon);
103
104 aTransformed.transform(getTransform());
105 rContainer.push_back(
107 aTransformed,
108 getSdrFTAttribute().getFill(),
109 getSdrFTAttribute().getFillFloatTransGradient()));
110 }
111 else
112 {
113 // if no fill create one for HitTest and BoundRect fallback
114 rContainer.push_back(
116 true,
117 aUnitPolyPolygon,
118 getTransform()));
119 }
120
121 // add text
122 if(!getSdrFTAttribute().getText().isDefault())
123 {
124 rContainer.push_back(
126 aUnitPolyPolygon,
127 getTransform(),
128 getSdrFTAttribute().getText(),
129 attribute::SdrLineAttribute(),
130 true,
131 false));
132 }
133 }
134
135 bool SdrCellPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
136 {
137 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
138 {
139 const SdrCellPrimitive2D& rCompare = static_cast<const SdrCellPrimitive2D&>(rPrimitive);
140
141 return (getTransform() == rCompare.getTransform()
142 && getSdrFTAttribute() == rCompare.getSdrFTAttribute());
143 }
144
145 return false;
146 }
147
148 // provide unique ID
149 sal_uInt32 SdrCellPrimitive2D::getPrimitive2DID() const
150 {
152 }
153
154} // end of namespace
155
156namespace sdr::contact
157{
158
159 namespace {
160 class ViewObjectContactOfTableObj : public ViewObjectContactOfSdrObj
161 {
162 public:
163 ViewObjectContactOfTableObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
164 : ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
165 {
166 }
167
168 protected:
169 virtual void createPrimitive2DSequence(DisplayInfo const& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const override;
170 };
171 } // namespace
172
174 const sdr::table::TableLayouter& rLayouter,
175 sal_Int32 nX,
176 sal_Int32 nY,
177 bool bHorizontal,
178 sal_Int32 nColCount,
179 sal_Int32 nRowCount,
180 bool bIsRTL)
181 {
182 if(nX >= 0 && nX <= nColCount && nY >= 0 && nY <= nRowCount)
183 {
184 const SvxBorderLine* pLine = rLayouter.getBorderLine(nX, nY, bHorizontal);
185
186 if(pLine)
187 {
188 // copy line content
189 SvxBorderLine aLine(*pLine);
190
191 // check for mirroring. This shall always be done when it is
192 // not a top- or rightmost line
193 bool bMirror(aLine.isDouble());
194
195 if(bMirror)
196 {
197 if(bHorizontal)
198 {
199 // mirror all bottom lines
200 bMirror = (0 != nY);
201 }
202 else
203 {
204 // mirror all left lines
205 bMirror = (bIsRTL ? 0 != nX : nX != nColCount);
206 }
207 }
208
209 if(bMirror)
210 {
211 aLine.SetMirrorWidths( );
212 }
213
214 constexpr double fTwipsToMM(
216 return svx::frame::Style(&aLine, fTwipsToMM);
217 }
218 }
219
220 // no success, copy empty line
221 return svx::frame::Style();
222 }
223
225 sdr::table::SdrTableObj const& rTableObj,
226 bool const isTaggedPDF,
228 {
229 const uno::Reference< css::table::XTable > xTable = rTableObj.getTable();
230
231 if(xTable.is())
232 {
233 // create primitive representation for table. Cell info goes
234 // directly to aRetval, Border info to aBorderSequence and added
235 // later to get the correct overlapping
238 const sal_Int32 nRowCount(xTable->getRowCount());
239 const sal_Int32 nColCount(xTable->getColumnCount());
240 const sal_Int32 nAllCount(nRowCount * nColCount);
241 SdrPage const*const pPage(rTableObj.getSdrPageFromSdrObject());
242
243 if(nAllCount)
244 {
245 const sdr::table::TableLayouter& rTableLayouter(rTableObj.getTableLayouter());
246 const bool bIsRTL(css::text::WritingMode_RL_TB == rTableObj.GetWritingMode());
247 sdr::table::CellPos aCellPos;
248 sdr::table::CellRef xCurrentCell;
249 basegfx::B2IRectangle aCellArea;
250
251 // create range using the model data directly. This is in SdrTextObj::aRect which i will access using
252 // GetGeoRect() to not trigger any calculations. It's the unrotated geometry.
254
255 // To create the CellBorderPrimitives, use the tooling from svx::frame::Array
256 // which is capable of creating the needed visualization. Fill it during the
257 // anyways needed run over the table.
258 svx::frame::Array aArray;
259
260 // initialize CellBorderArray for primitive creation
261 aArray.Initialize(nColCount, nRowCount);
262
263 // create single primitives per cell
264 for(aCellPos.mnRow = 0; aCellPos.mnRow < nRowCount; aCellPos.mnRow++)
265 {
267 // add RowHeight to CellBorderArray for primitive creation
268 aArray.SetRowHeight(aCellPos.mnRow, rTableLayouter.getRowHeight(aCellPos.mnRow));
269
270 for(aCellPos.mnCol = 0; aCellPos.mnCol < nColCount; aCellPos.mnCol++)
271 {
273 // add ColWidth to CellBorderArray for primitive creation, only
274 // needs to be done in the 1st run
275 if(0 == aCellPos.mnRow)
276 {
277 aArray.SetColWidth(aCellPos.mnCol, rTableLayouter.getColumnWidth(aCellPos.mnCol));
278 }
279
280 // access the cell
281 xCurrentCell.set(dynamic_cast< sdr::table::Cell* >(xTable->getCellByPosition(aCellPos.mnCol, aCellPos.mnRow).get()));
282
283 if(xCurrentCell.is())
284 {
285 // copy styles for current cell to CellBorderArray for primitive creation
286 aArray.SetCellStyleLeft(aCellPos.mnCol, aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow, false, nColCount, nRowCount, bIsRTL));
287 aArray.SetCellStyleRight(aCellPos.mnCol, aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol + 1, aCellPos.mnRow, false, nColCount, nRowCount, bIsRTL));
288 aArray.SetCellStyleTop(aCellPos.mnCol, aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow, true, nColCount, nRowCount, bIsRTL));
289 aArray.SetCellStyleBottom(aCellPos.mnCol, aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow + 1, true, nColCount, nRowCount, bIsRTL));
290
291 // ignore merged cells (all except the top-left of a merged cell)
292 if(!xCurrentCell->isMerged())
293 {
294 // check if we are the top-left of a merged cell
295 const sal_Int32 nXSpan(xCurrentCell->getColumnSpan());
296 const sal_Int32 nYSpan(xCurrentCell->getRowSpan());
297
298 if(nXSpan > 1 || nYSpan > 1)
299 {
300 // if merged, set so at CellBorderArray for primitive creation
301 aArray.SetMergedRange(aCellPos.mnCol, aCellPos.mnRow, aCellPos.mnCol + nXSpan - 1, aCellPos.mnRow + nYSpan - 1);
302 }
303 }
304 }
305
306 if(xCurrentCell.is() && !xCurrentCell->isMerged())
307 {
308 if(rTableLayouter.getCellArea(xCurrentCell, aCellPos, aCellArea))
309 {
310 // create cell transformation matrix
311 basegfx::B2DHomMatrix aCellMatrix;
312 aCellMatrix.set(0, 0, static_cast<double>(aCellArea.getWidth()));
313 aCellMatrix.set(1, 1, static_cast<double>(aCellArea.getHeight()));
314 aCellMatrix.set(0, 2, static_cast<double>(aCellArea.getMinX()) + aObjectRange.getMinX());
315 aCellMatrix.set(1, 2, static_cast<double>(aCellArea.getMinY()) + aObjectRange.getMinY());
316
317 // handle cell fillings and text
318 const SfxItemSet& rCellItemSet = xCurrentCell->GetItemSet();
319 const sal_uInt32 nTextIndex(nColCount * aCellPos.mnRow + aCellPos.mnCol);
320 const SdrText* pSdrText = rTableObj.getText(nTextIndex);
322
323 if(pSdrText)
324 {
325 // #i101508# take cell's local text frame distances into account
326 const sal_Int32 nLeft(xCurrentCell->GetTextLeftDistance());
327 const sal_Int32 nRight(xCurrentCell->GetTextRightDistance());
328 const sal_Int32 nUpper(xCurrentCell->GetTextUpperDistance());
329 const sal_Int32 nLower(xCurrentCell->GetTextLowerDistance());
330
332 rCellItemSet,
333 pSdrText,
334 &nLeft,
335 &nUpper,
336 &nRight,
337 &nLower);
338 }
339 else
340 {
342 rCellItemSet,
343 pSdrText);
344 }
345
346 // always create cell primitives for BoundRect and HitTest
347 {
349 new drawinglayer::primitive2d::SdrCellPrimitive2D(
350 aCellMatrix, aAttribute));
351 cell.append(xCellReference);
352 }
353
354 // Create cell primitive without text.
355 aAttribute
357 rCellItemSet, nullptr);
358 rtl::Reference pCellReference
359 = new drawinglayer::primitive2d::SdrCellPrimitive2D(
360 aCellMatrix, aAttribute);
361
362 sal_uInt16 nTransparence(
363 rCellItemSet.Get(XATTR_FILLTRANSPARENCE).GetValue());
364 if (nTransparence != 0)
365 {
366 pCellReference->setTransparenceForShadow(nTransparence);
367 }
368
370 xCellReference(pCellReference);
371 aRetvalForShadow.append(xCellReference);
372 }
373 }
374 if (isTaggedPDF && pPage)
375 {
376 // heuristic: if there's a special formatting on
377 // first row, assume that it's a header row
378 auto const eType(
379 aCellPos.mnRow == 0 && rTableObj.getTableStyleSettings().mbUseFirstRow
384 eType,
385 pPage->IsMasterPage(),
386 false,
387 std::move(cell)) };
388 }
389 row.append(cell);
390 }
391
392 if (isTaggedPDF && pPage)
393 {
397 pPage->IsMasterPage(),
398 false,
399 std::move(row)) };
400 }
401 aRetval.append(row);
402 }
403
404 // now create all CellBorderPrimitives
406
407 if(!aCellBorderPrimitives.empty())
408 {
409 // this is already scaled (due to Table in non-uniform coordinates), so
410 // first transform removing scale
411 basegfx::B2DHomMatrix aTransform(
413 1.0 / aObjectRange.getWidth(),
414 1.0 / aObjectRange.getHeight()));
415
416 // If RTL, mirror the whole unified table in X and move right.
417 // This is much easier than taking this into account for the whole
418 // index calculations
419 if(bIsRTL)
420 {
421 aTransform.scale(-1.0, 1.0);
422 aTransform.translate(1.0, 0.0);
423 }
424
425 // create object matrix
426 const GeoStat& rGeoStat(rTableObj.GetGeoStat());
427 const double fShearX(-rGeoStat.mfTanShearAngle);
428 const double fRotate(rGeoStat.nRotationAngle ? toRadians(36000_deg100 - rGeoStat.nRotationAngle) : 0.0);
430 aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate,
431 aObjectRange.getMinX(), aObjectRange.getMinY()));
432
433 // add object matrix to transform. By doing so theoretically
434 // CellBorders could be also rotated/sheared for the first time ever.
435 // To completely make that work, the primitives already created in
436 // aRetval would also have to be based on ObjectMatrix, not only on
437 // ObjectRange as it currently is.
438 aTransform *= aObjectMatrix;
439
440 // create a transform primitive with this and embed CellBorders
441 // and append to retval
442 aRetval.append(
444 aTransform,
446
447 // Borders are always the same for shadow as well.
449 aTransform, std::move(aCellBorderPrimitives)));
450 }
451 }
452
453 if(!aRetval.empty())
454 {
455 // check and create evtl. shadow for created content
456 const SfxItemSet& rObjectItemSet = rTableObj.GetMergedItemSet();
457 const drawinglayer::attribute::SdrShadowAttribute aNewShadowAttribute(
459
460 if(!aNewShadowAttribute.isDefault())
461 {
462 bool bDirectShadow
463 = rObjectItemSet.Get(SDRATTR_SHADOW, /*bSrchInParent=*/false)
464 .GetValue();
465 if (bDirectShadow)
466 {
467 // Shadow as direct formatting: no shadow for text, to be compatible
468 // with PowerPoint.
469 basegfx::B2DHomMatrix aMatrix;
471 std::move(aRetval), aNewShadowAttribute, aMatrix, &aRetvalForShadow);
472 }
473 else
474 {
475 // Shadow as style: shadow for text, to be backwards-compatible.
477 std::move(aRetval), aNewShadowAttribute);
478 }
479 }
480 }
481
482 rVisitor.visit(std::move(aRetval));
483 }
484 else
485 {
486 // take unrotated snap rect (direct model data) for position and size
488
489 // create object matrix
490 const GeoStat& rGeoStat(rTableObj.GetGeoStat());
491 const double fShearX(-rGeoStat.mfTanShearAngle);
492 const double fRotate(rGeoStat.nRotationAngle ? toRadians(36000_deg100 - rGeoStat.nRotationAngle) : 0.0);
494 aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate,
495 aObjectRange.getMinX(), aObjectRange.getMinY()));
496
497 // created an invisible outline for the cases where no visible content exists
500 aObjectMatrix));
501
502 rVisitor.visit(xReference);
503 }
504 }
505
506 void ViewObjectContactOfTableObj::createPrimitive2DSequence(
507 DisplayInfo const& rDisplayInfo,
509 {
510 bool const isTaggedPDF(GetObjectContact().isExportTaggedPDF());
511 if (isTaggedPDF)
512 {
513 // this will be unbuffered and contain structure tags
514 const sdr::table::SdrTableObj& rTableObj =
515 static_cast<const sdr::table::SdrTableObj&>(*GetViewContact().TryToGetSdrObject());
516 return createPrimitive2DSequenceImpl(rTableObj, true, rVisitor);
517 }
518 else
519 {
520 // call it via the base class - this is supposed to be buffered
522 }
523 }
524
527 {
528 const sdr::table::SdrTableObj& rTableObj =
529 static_cast<const sdr::table::SdrTableObj&>(GetSdrObject());
530 return createPrimitive2DSequenceImpl(rTableObj, false, rVisitor);
531 }
532
534 {
535 return *new ViewObjectContactOfTableObj(rObjectContact, *this);
536 }
537
539 : ViewContactOfSdrObj(rTableObj)
540 {
541 }
542
544 {
545 }
546} // end of namespace
547
548/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
The transformation of a rectangle into a polygon, by using angle parameters from GeoStat.
Definition: svdtrans.hxx:201
double mfTanShearAngle
Definition: svdtrans.hxx:205
Degree100 nRotationAngle
Definition: svdtrans.hxx:203
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:279
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1977
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:377
bool IsMasterPage() const
Definition: svdpage.hxx:462
const tools::Rectangle & GetGeoRect() const
Definition: svdotext.cxx:1454
const GeoStat & GetGeoStat() const
Definition: svdotext.hxx:390
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void translate(double fX, double fY)
void scale(double fX, double fY)
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getHeight() const
void append(const Primitive2DReference &)
virtual void visit(const Primitive2DReference &)=0
ViewContactOfTableObj(sdr::table::SdrTableObj &rTextObj)
virtual ViewObjectContact & CreateObjectSpecificViewObjectContact(ObjectContact &rObjectContact) override
virtual void createViewIndependentPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const override
virtual void createPrimitive2DSequence(const DisplayInfo &rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
const TableLayouter & getTableLayouter() const
Definition: svdotable.cxx:1378
const sdr::table::TableStyleSettings & getTableStyleSettings() const
Definition: svdotable.cxx:1126
css::text::WritingMode GetWritingMode() const
Definition: svdotable.cxx:1986
css::uno::Reference< css::table::XTable > getTable() const
Definition: svdotable.cxx:900
virtual SdrText * getText(sal_Int32 nIndex) const override
Returns the nth available text.
Definition: svdotable.cxx:1307
sal_Int32 getColumnWidth(sal_Int32 nColumn) const
editeng::SvxBorderLine * getBorderLine(sal_Int32 nEdgeX, sal_Int32 nEdgeY, bool bHorizontal) const
returns the requested borderline in rpBorderLine or a null pointer if there is no border at this edge
sal_Int32 getRowHeight(sal_Int32 nRow) const
bool getCellArea(const CellRef &xCell, const CellPos &rPos, basegfx::B2IRectangle &rArea) const
Stores frame styles of an array of cells, supports merged ranges.
void SetRowHeight(sal_Int32 nRow, sal_Int32 nHeight)
Sets the output height of the specified row.
void SetMergedRange(sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow)
Inserts a new merged cell range.
void SetCellStyleBottom(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
Sets the bottom frame style of the specified cell (nCol,nRow).
void SetCellStyleLeft(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
Sets the left frame style of the cell (nCol,nRow).
void SetCellStyleRight(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
Sets the right frame style of the cell (nCol,nRow).
void SetColWidth(sal_Int32 nCol, sal_Int32 nWidth)
Sets the output width of the specified column.
void Initialize(sal_Int32 nWidth, sal_Int32 nHeight)
Reinitializes the array with the specified size.
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveArray() const
Draws the part of the array, that is inside the clipping range.
void SetCellStyleTop(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
Sets the top frame style of the cell (nCol,nRow).
Contains the widths of primary and secondary line of a frame style.
Definition: framelink.hxx:99
double toRadians(D x)
DocumentType eType
B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
B2DPolygon const & createUnitPolygon()
Primitive2DReference createHiddenGeometryPrimitives2D(const basegfx::B2DHomMatrix &rMatrix)
Primitive2DContainer createEmbeddedShadowPrimitive(Primitive2DContainer &&rContent, const attribute::SdrShadowAttribute &rShadow, const basegfx::B2DHomMatrix &rObjectMatrix, const Primitive2DContainer *pContentForShadow)
attribute::SdrShadowAttribute createNewSdrShadowAttribute(const SfxItemSet &rSet)
Primitive2DReference createTextPrimitive(const basegfx::B2DPolyPolygon &rUnitPolyPolygon, const basegfx::B2DHomMatrix &rObjectTransform, const attribute::SdrTextAttribute &rText, const attribute::SdrLineAttribute &rStroke, bool bCellText, bool bWordWrap)
Primitive2DReference createPolyPolygonFillPrimitive(const basegfx::B2DPolyPolygon &rPolyPolygon, const attribute::SdrFillAttribute &rFill, const attribute::FillGradientAttribute &rFillGradient)
attribute::SdrFillTextAttribute createNewSdrFillTextAttribute(const SfxItemSet &rSet, const SdrText *pText, const sal_Int32 *pLeft, const sal_Int32 *pUpper, const sal_Int32 *pRight, const sal_Int32 *pLower)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
static svx::frame::Style impGetLineStyle(const sdr::table::TableLayouter &rLayouter, sal_Int32 nX, sal_Int32 nY, bool bHorizontal, sal_Int32 nColCount, sal_Int32 nRowCount, bool bIsRTL)
static void createPrimitive2DSequenceImpl(sdr::table::SdrTableObj const &rTableObj, bool const isTaggedPDF, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
#define PRIMITIVE2D_ID_SDRCELLPRIMITIVE2D
attribute::SdrFillTextAttribute maSdrFTAttribute
basegfx::B2DHomMatrix maTransform
constexpr TypedWhichId< XFillTransparenceItem > XATTR_FILLTRANSPARENCE(XATTR_FILL_FIRST+5)
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)