Branch data Line data Source code
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 : : #include <drawinglayer/primitive2d/texteffectprimitive2d.hxx>
21 : : #include <drawinglayer/geometry/viewinformation2d.hxx>
22 : : #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
23 : : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
24 : : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
25 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 : :
27 : : //////////////////////////////////////////////////////////////////////////////
28 : :
29 : : namespace drawinglayer
30 : : {
31 : : namespace primitive2d
32 : : {
33 : : static double fDiscreteSize(1.1);
34 : :
35 : 678 : Primitive2DSequence TextEffectPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
36 : : {
37 [ + - ]: 678 : Primitive2DSequence aRetval;
38 : :
39 : : // get the distance of one discrete units from target display. Use between 1.0 and sqrt(2) to
40 : : // have good results on rotated objects, too
41 [ + - ]: 678 : const basegfx::B2DVector aDistance(rViewInformation.getInverseObjectToViewTransformation() *
42 [ + - ]: 1356 : basegfx::B2DVector(fDiscreteSize, fDiscreteSize));
43 : 678 : const basegfx::B2DVector aDiagonalDistance(aDistance * (1.0 / 1.44));
44 : :
45 [ + + - ]: 678 : switch(getTextEffectStyle2D())
46 : : {
47 : : case TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED:
48 : : case TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED:
49 : : case TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT:
50 : : case TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT:
51 : : {
52 : : // prepare transform of sub-group back to (0,0) and align to X-Axis
53 : : basegfx::B2DHomMatrix aBackTransform(basegfx::tools::createTranslateB2DHomMatrix(
54 [ + - ]: 525 : -getRotationCenter().getX(), -getRotationCenter().getY()));
55 [ + - ]: 525 : aBackTransform.rotate(-getDirection());
56 : :
57 : : // prepare transform of sub-group back to it's position and rotation
58 [ + - ]: 525 : basegfx::B2DHomMatrix aForwardTransform(basegfx::tools::createRotateB2DHomMatrix(getDirection()));
59 [ + - ]: 525 : aForwardTransform.translate(getRotationCenter().getX(), getRotationCenter().getY());
60 : :
61 : : // create transformation for one discrete unit
62 : : const bool bEmbossed(
63 : 525 : TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED == getTextEffectStyle2D()
64 [ # # ][ - + ]: 525 : || TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT == getTextEffectStyle2D());
65 : : const bool bDefaultTextColor(
66 : 525 : TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT == getTextEffectStyle2D()
67 [ - + ][ + - ]: 525 : || TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT == getTextEffectStyle2D());
68 [ + - ]: 525 : basegfx::B2DHomMatrix aTransform(aBackTransform);
69 [ + - ]: 525 : aRetval.realloc(2);
70 : :
71 [ + - ]: 525 : if(bEmbossed)
72 : : {
73 : : // to bottom-right
74 [ + - ]: 525 : aTransform.translate(aDiagonalDistance.getX(), aDiagonalDistance.getY());
75 : : }
76 : : else
77 : : {
78 : : // to top-left
79 [ # # ]: 0 : aTransform.translate(-aDiagonalDistance.getX(), -aDiagonalDistance.getY());
80 : : }
81 : :
82 [ + - ]: 525 : aTransform *= aForwardTransform;
83 : :
84 [ - + ]: 525 : if(bDefaultTextColor)
85 : : {
86 : : // emboss/engrave in black, original forced to white
87 : 0 : const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.0));
88 [ # # ][ # # ]: 0 : const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToGray));
[ # # ]
89 [ # # ][ # # ]: 0 : aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1)));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
90 : :
91 : : // add original, too
92 : 0 : const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0));
93 [ # # ][ # # ]: 0 : aRetval[1] = Primitive2DReference(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToWhite));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
94 : : }
95 : : else
96 : : {
97 : : // emboss/engrave in gray, keep original's color
98 : 525 : const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.75)); // 192
99 [ + - ][ + - ]: 525 : const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToGray));
[ + - ]
100 [ + - ][ + - ]: 525 : aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1)));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
101 : :
102 : : // add original, too
103 [ + - ][ + - ]: 525 : aRetval[1] = Primitive2DReference(new GroupPrimitive2D(getTextContent()));
[ + - ][ + - ]
[ + - ][ + - ]
104 : : }
105 : :
106 [ + - ][ + - ]: 525 : break;
[ + - ]
107 : : }
108 : : case TEXTEFFECTSTYLE2D_OUTLINE:
109 : : {
110 : : // create transform primitives in all directions
111 [ + - ]: 153 : basegfx::B2DHomMatrix aTransform;
112 [ + - ]: 153 : aRetval.realloc(9);
113 : :
114 [ + - ]: 153 : aTransform.set(0, 2, aDistance.getX());
115 [ + - ]: 153 : aTransform.set(1, 2, 0.0);
116 [ + - ][ + - ]: 153 : aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
117 : :
118 [ + - ]: 153 : aTransform.set(0, 2, aDiagonalDistance.getX());
119 [ + - ]: 153 : aTransform.set(1, 2, aDiagonalDistance.getY());
120 [ + - ][ + - ]: 153 : aRetval[1] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
121 : :
122 [ + - ]: 153 : aTransform.set(0, 2, 0.0);
123 [ + - ]: 153 : aTransform.set(1, 2, aDistance.getY());
124 [ + - ][ + - ]: 153 : aRetval[2] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
125 : :
126 [ + - ]: 153 : aTransform.set(0, 2, -aDiagonalDistance.getX());
127 [ + - ]: 153 : aTransform.set(1, 2, aDiagonalDistance.getY());
128 [ + - ][ + - ]: 153 : aRetval[3] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
129 : :
130 [ + - ]: 153 : aTransform.set(0, 2, -aDistance.getX());
131 [ + - ]: 153 : aTransform.set(1, 2, 0.0);
132 [ + - ][ + - ]: 153 : aRetval[4] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
133 : :
134 [ + - ]: 153 : aTransform.set(0, 2, -aDiagonalDistance.getX());
135 [ + - ]: 153 : aTransform.set(1, 2, -aDiagonalDistance.getY());
136 [ + - ][ + - ]: 153 : aRetval[5] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
137 : :
138 [ + - ]: 153 : aTransform.set(0, 2, 0.0);
139 [ + - ]: 153 : aTransform.set(1, 2, -aDistance.getY());
140 [ + - ][ + - ]: 153 : aRetval[6] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
141 : :
142 [ + - ]: 153 : aTransform.set(0, 2, aDiagonalDistance.getX());
143 [ + - ]: 153 : aTransform.set(1, 2, -aDiagonalDistance.getY());
144 [ + - ][ + - ]: 153 : aRetval[7] = Primitive2DReference(new TransformPrimitive2D(aTransform, getTextContent()));
[ + - ][ + - ]
[ + - ]
145 : :
146 : : // at last, place original over it, but force to white
147 : 153 : const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0, 1.0, 1.0));
148 [ + - ][ + - ]: 153 : aRetval[8] = Primitive2DReference(new ModifiedColorPrimitive2D(getTextContent(), aBColorModifierToWhite));
[ + - ][ + - ]
[ + - ]
149 : :
150 [ + - ][ + - ]: 153 : break;
151 : : }
152 : : }
153 : :
154 : 678 : return aRetval;
155 : : }
156 : :
157 : 1799 : TextEffectPrimitive2D::TextEffectPrimitive2D(
158 : : const Primitive2DSequence& rTextContent,
159 : : const basegfx::B2DPoint& rRotationCenter,
160 : : double fDirection,
161 : : TextEffectStyle2D eTextEffectStyle2D)
162 : : : BufferedDecompositionPrimitive2D(),
163 : : maTextContent(rTextContent),
164 : : maRotationCenter(rRotationCenter),
165 : : mfDirection(fDirection),
166 [ + - ][ + - ]: 1799 : meTextEffectStyle2D(eTextEffectStyle2D)
167 : : {
168 : 1799 : }
169 : :
170 : 0 : bool TextEffectPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
171 : : {
172 [ # # ]: 0 : if(BasePrimitive2D::operator==(rPrimitive))
173 : : {
174 : 0 : const TextEffectPrimitive2D& rCompare = (TextEffectPrimitive2D&)rPrimitive;
175 : :
176 : 0 : return (getTextContent() == rCompare.getTextContent()
177 : 0 : && getRotationCenter() == rCompare.getRotationCenter()
178 : 0 : && getDirection() == rCompare.getDirection()
179 [ # # ][ # # : 0 : && getTextEffectStyle2D() == rCompare.getTextEffectStyle2D());
# # # # ]
180 : : }
181 : :
182 : 0 : return false;
183 : : }
184 : :
185 : 13018 : basegfx::B2DRange TextEffectPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
186 : : {
187 : : // get range of content and grow by used fDiscreteSize. That way it is not necessary to ask
188 : : // the whole decomposition for it's ranges (which may be expensive with outline mode which
189 : : // then will ask 9 times at nearly the same content. This may even be refined here using the
190 : : // TextEffectStyle information, e.g. for TEXTEFFECTSTYLE2D_RELIEF the grow needs only to
191 : : // be in two directions
192 : 13018 : basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getTextContent(), rViewInformation));
193 : 13018 : aRetval.grow(fDiscreteSize);
194 : :
195 : 13018 : return aRetval;
196 : : }
197 : :
198 : 724 : Primitive2DSequence TextEffectPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
199 : : {
200 [ + - ]: 724 : ::osl::MutexGuard aGuard( m_aMutex );
201 : :
202 [ + + ]: 724 : if(getBuffered2DDecomposition().hasElements())
203 : : {
204 [ + - ][ + - ]: 126 : if(maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
[ + + ]
205 : : {
206 : : // conditions of last local decomposition have changed, delete
207 [ + - ][ + - ]: 80 : const_cast< TextEffectPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
[ + - ]
208 : : }
209 : : }
210 : :
211 [ + + ]: 724 : if(!getBuffered2DDecomposition().hasElements())
212 : : {
213 : : // remember ViewRange and ViewTransformation
214 [ + - ][ + - ]: 678 : const_cast< TextEffectPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
215 : : }
216 : :
217 : : // use parent implementation
218 [ + - ][ + - ]: 724 : return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
219 : : }
220 : :
221 : : // provide unique ID
222 : 724 : ImplPrimitrive2DIDBlock(TextEffectPrimitive2D, PRIMITIVE2D_ID_TEXTEFFECTPRIMITIVE2D)
223 : :
224 : : } // end of namespace primitive2d
225 : : } // end of namespace drawinglayer
226 : :
227 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|