LibreOffice Module drawinglayer (master) 1
texteffectprimitive2d.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
26
28{
29const double fDiscreteSize(1.1);
30
32 Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const
33{
34 // get the distance of one discrete units from target display. Use between 1.0 and sqrt(2) to
35 // have good results on rotated objects, too
38 const basegfx::B2DVector aDiagonalDistance(aDistance * (1.0 / 1.44));
39
40 switch (getTextEffectStyle2D())
41 {
46 {
47 // prepare transform of sub-group back to (0,0) and align to X-Axis
49 -getRotationCenter().getX(), -getRotationCenter().getY()));
50 aBackTransform.rotate(-getDirection());
51
52 // prepare transform of sub-group back to its position and rotation
53 basegfx::B2DHomMatrix aForwardTransform(
55 aForwardTransform.translate(getRotationCenter().getX(), getRotationCenter().getY());
56
57 // create transformation for one discrete unit
61 const bool bDefaultTextColor(
64 basegfx::B2DHomMatrix aTransform(aBackTransform);
65
66 if (bEmbossed)
67 {
68 // to bottom-right
69 aTransform.translate(aDiagonalDistance.getX(), aDiagonalDistance.getY());
70 }
71 else
72 {
73 // to top-left
74 aTransform.translate(-aDiagonalDistance.getX(), -aDiagonalDistance.getY());
75 }
76
77 aTransform *= aForwardTransform;
78
79 if (bDefaultTextColor)
80 {
81 // emboss/engrave in black, original forced to white
82 const basegfx::BColorModifierSharedPtr aBColorModifierToGray
83 = std::make_shared<basegfx::BColorModifier_replace>(basegfx::BColor(0.0));
84 const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(
85 Primitive2DContainer(getTextContent()), aBColorModifierToGray));
86
87 rContainer.push_back(
88 new TransformPrimitive2D(aTransform, Primitive2DContainer{ xModifiedColor }));
89
90 // add original, too
91 const basegfx::BColorModifierSharedPtr aBColorModifierToWhite
92 = std::make_shared<basegfx::BColorModifier_replace>(basegfx::BColor(1.0));
93
94 rContainer.push_back(new ModifiedColorPrimitive2D(
95 Primitive2DContainer(getTextContent()), aBColorModifierToWhite));
96 }
97 else
98 {
99 // emboss/engrave in gray, keep original's color
100 const basegfx::BColorModifierSharedPtr aBColorModifierToGray
101 = std::make_shared<basegfx::BColorModifier_replace>(
102 basegfx::BColor(0.75)); // 192
103 const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(
104 Primitive2DContainer(getTextContent()), aBColorModifierToGray));
105
106 rContainer.push_back(
107 new TransformPrimitive2D(aTransform, Primitive2DContainer{ xModifiedColor }));
108
109 // add original, too
110 rContainer.push_back(new GroupPrimitive2D(Primitive2DContainer(getTextContent())));
111 }
112
113 break;
114 }
116 {
117 // create transform primitives in all directions
118 basegfx::B2DHomMatrix aTransform;
119
120 aTransform.set(0, 2, aDistance.getX());
121 aTransform.set(1, 2, 0.0);
122 rContainer.push_back(
124
125 aTransform.set(0, 2, aDiagonalDistance.getX());
126 aTransform.set(1, 2, aDiagonalDistance.getY());
127 rContainer.push_back(
129
130 aTransform.set(0, 2, 0.0);
131 aTransform.set(1, 2, aDistance.getY());
132 rContainer.push_back(
134
135 aTransform.set(0, 2, -aDiagonalDistance.getX());
136 aTransform.set(1, 2, aDiagonalDistance.getY());
137 rContainer.push_back(
139
140 aTransform.set(0, 2, -aDistance.getX());
141 aTransform.set(1, 2, 0.0);
142 rContainer.push_back(
144
145 aTransform.set(0, 2, -aDiagonalDistance.getX());
146 aTransform.set(1, 2, -aDiagonalDistance.getY());
147 rContainer.push_back(
149
150 aTransform.set(0, 2, 0.0);
151 aTransform.set(1, 2, -aDistance.getY());
152 rContainer.push_back(
154
155 aTransform.set(0, 2, aDiagonalDistance.getX());
156 aTransform.set(1, 2, -aDiagonalDistance.getY());
157 rContainer.push_back(
159
160 // at last, place original over it, but force to white
161 const basegfx::BColorModifierSharedPtr aBColorModifierToWhite
162 = std::make_shared<basegfx::BColorModifier_replace>(basegfx::BColor(1.0, 1.0, 1.0));
163 rContainer.push_back(new ModifiedColorPrimitive2D(
164 Primitive2DContainer(getTextContent()), aBColorModifierToWhite));
165
166 break;
167 }
168 }
169}
170
172 const basegfx::B2DPoint& rRotationCenter,
173 double fDirection,
174 TextEffectStyle2D eTextEffectStyle2D)
175 : maTextContent(std::move(rTextContent))
176 , maRotationCenter(rRotationCenter)
177 , mfDirection(fDirection)
178 , meTextEffectStyle2D(eTextEffectStyle2D)
179{
180}
181
183{
184 if (BasePrimitive2D::operator==(rPrimitive))
185 {
186 const TextEffectPrimitive2D& rCompare
187 = static_cast<const TextEffectPrimitive2D&>(rPrimitive);
188
189 return (getTextContent() == rCompare.getTextContent()
190 && getRotationCenter() == rCompare.getRotationCenter()
191 && getDirection() == rCompare.getDirection()
192 && getTextEffectStyle2D() == rCompare.getTextEffectStyle2D());
193 }
194
195 return false;
196}
197
200{
201 // get range of content and grow by used fDiscreteSize. That way it is not necessary to ask
202 // the whole decomposition for its ranges (which may be expensive with outline mode which
203 // then will ask 9 times at nearly the same content. This may even be refined here using the
204 // TextEffectStyle information, e.g. for TEXTEFFECTSTYLE2D_RELIEF the grow needs only to
205 // be in two directions
206 basegfx::B2DRange aRetval(getTextContent().getB2DRange(rViewInformation));
207 aRetval.grow(fDiscreteSize);
208
209 return aRetval;
210}
211
214 const geometry::ViewInformation2D& rViewInformation) const
215{
216 if (!getBuffered2DDecomposition().empty())
217 {
219 {
220 // conditions of last local decomposition have changed, delete
223 }
224 }
225
226 if (getBuffered2DDecomposition().empty())
227 {
228 // remember ViewRange and ViewTransformation
230 = rViewInformation.getObjectToViewTransformation();
231 }
232
233 // use parent implementation
235}
236
237// provide unique ID
239{
241}
242
243} // end of namespace
244
245/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void rotate(double fRadiant)
void translate(double fX, double fY)
void grow(TYPE fValue)
TYPE getX() const
TYPE getY() const
const basegfx::B2DHomMatrix & getInverseObjectToViewTransformation() const
const basegfx::B2DHomMatrix & getObjectToViewTransformation() const
On-demand prepared Object to View transformation and its inverse for convenience.
const Primitive2DContainer & getBuffered2DDecomposition() const
access methods to maBuffered2DDecomposition.
virtual void get2DDecomposition(Primitive2DDecompositionVisitor &rVisitor, const geometry::ViewInformation2D &rViewInformation) const override
The getDecomposition default implementation will on demand use create2DDecomposition() if maBuffered2...
virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D &rViewInformation) const override
own get range implementation to solve more effective.
TextEffectPrimitive2D(Primitive2DContainer &&rTextContent, const basegfx::B2DPoint &rRotationCenter, double fDirection, TextEffectStyle2D eTextEffectStyle2D)
constructor
virtual void get2DDecomposition(Primitive2DDecompositionVisitor &rVisitor, const geometry::ViewInformation2D &rViewInformation) const override
Override standard getDecomposition to be view-dependent here.
const Primitive2DContainer & getTextContent() const
data read access
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
create local decomposition
basegfx::B2DHomMatrix maLastObjectToViewTransformation
the last used object to view transformtion used from getDecomposition for decide buffering
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
compare operator
virtual sal_uInt32 getPrimitive2DID() const override
provide unique ID
#define PRIMITIVE2D_ID_TEXTEFFECTPRIMITIVE2D
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
B2DHomMatrix createRotateB2DHomMatrix(double fRadiant)
std::shared_ptr< BColorModifier > BColorModifierSharedPtr
TextEffectStyle2D
TextEffectStyle2D definition.
const double fDiscreteSize(1.1)
o3tl::enumarray< SvxBoxItemLine, sal_uInt16 > aDistance