1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <primitive2d/textstrikeoutprimitive2d.hxx>
21 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
22 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
23 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
24 #include <basegfx/polygon/b2dpolygon.hxx>
25 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <drawinglayer/attribute/lineattribute.hxx>
27 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
28 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
29 #include <osl/diagnose.h>
30 #include <rtl/ustrbuf.hxx>
34 namespace drawinglayer::primitive2d
36 BaseTextStrikeoutPrimitive2D::BaseTextStrikeoutPrimitive2D(
37 basegfx::B2DHomMatrix aObjectTransformation
,
39 const basegfx::BColor
& rFontColor
)
40 : maObjectTransformation(std::move(aObjectTransformation
)),
42 maFontColor(rFontColor
)
46 bool BaseTextStrikeoutPrimitive2D::operator==( const BasePrimitive2D
& rPrimitive
) const
48 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive
))
50 const BaseTextStrikeoutPrimitive2D
& rCompare
= static_cast<const BaseTextStrikeoutPrimitive2D
&>(rPrimitive
);
52 return (getObjectTransformation() == rCompare
.getObjectTransformation()
53 && getWidth() == rCompare
.getWidth()
54 && getFontColor() == rCompare
.getFontColor());
61 void TextCharacterStrikeoutPrimitive2D::create2DDecomposition(Primitive2DContainer
& rContainer
, const geometry::ViewInformation2D
& /*rViewInformation*/) const
63 // strikeout with character
64 const OUString
aSingleCharString(getStrikeoutChar());
65 basegfx::B2DVector aScale
, aTranslate
;
66 double fRotate
, fShearX
;
69 getObjectTransformation().decompose(aScale
, aTranslate
, fRotate
, fShearX
);
71 // prepare TextLayouter
72 TextLayouterDevice aTextLayouter
;
74 aTextLayouter
.setFontAttribute(
80 const double fStrikeCharWidth(aTextLayouter
.getTextWidth(aSingleCharString
, 0, 1));
81 const double fStrikeCharCount(fabs(getWidth()/fStrikeCharWidth
));
82 const sal_uInt32
nStrikeCharCount(static_cast< sal_uInt32
>(fStrikeCharCount
+ 0.5));
83 std::vector
<double> aDXArray(nStrikeCharCount
);
84 OUStringBuffer aStrikeoutString
;
86 for(sal_uInt32
a(0); a
< nStrikeCharCount
; a
++)
88 aStrikeoutString
.append(aSingleCharString
);
89 aDXArray
[a
] = (a
+ 1) * fStrikeCharWidth
;
92 auto len
= aStrikeoutString
.getLength();
94 new TextSimplePortionPrimitive2D(
95 getObjectTransformation(),
96 aStrikeoutString
.makeStringAndClear(),
106 TextCharacterStrikeoutPrimitive2D::TextCharacterStrikeoutPrimitive2D(
107 const basegfx::B2DHomMatrix
& rObjectTransformation
,
109 const basegfx::BColor
& rFontColor
,
110 sal_Unicode aStrikeoutChar
,
111 attribute::FontAttribute aFontAttribute
,
112 css::lang::Locale aLocale
)
113 : BaseTextStrikeoutPrimitive2D(rObjectTransformation
, fWidth
, rFontColor
),
114 maStrikeoutChar(aStrikeoutChar
),
115 maFontAttribute(std::move(aFontAttribute
)),
116 maLocale(std::move(aLocale
))
120 bool TextCharacterStrikeoutPrimitive2D::operator==( const BasePrimitive2D
& rPrimitive
) const
122 if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive
))
124 const TextCharacterStrikeoutPrimitive2D
& rCompare
= static_cast<const TextCharacterStrikeoutPrimitive2D
&>(rPrimitive
);
126 return (getStrikeoutChar() == rCompare
.getStrikeoutChar()
127 && getFontAttribute() == rCompare
.getFontAttribute()
128 && LocalesAreEqual(getLocale(), rCompare
.getLocale()));
135 sal_uInt32
TextCharacterStrikeoutPrimitive2D::getPrimitive2DID() const
137 return PRIMITIVE2D_ID_TEXTCHARACTERSTRIKEOUTPRIMITIVE2D
;
140 void TextGeometryStrikeoutPrimitive2D::create2DDecomposition(Primitive2DContainer
& rContainer
, const geometry::ViewInformation2D
& /*rViewInformation*/) const
142 OSL_ENSURE(TEXT_STRIKEOUT_SLASH
!= getTextStrikeout() && TEXT_STRIKEOUT_X
!= getTextStrikeout(),
143 "Wrong TEXT_STRIKEOUT type; a TextCharacterStrikeoutPrimitive2D should be used (!)");
145 // strikeout with geometry
146 double fStrikeoutHeight(getHeight());
147 double fStrikeoutOffset(getOffset());
148 bool bDoubleLine(false);
151 basegfx::B2DVector aScale
, aTranslate
;
152 double fRotate
, fShearX
;
153 getObjectTransformation().decompose(aScale
, aTranslate
, fRotate
, fShearX
);
155 // set line attribute
156 switch(getTextStrikeout())
158 default : // case primitive2d::TEXT_STRIKEOUT_SINGLE:
162 case primitive2d::TEXT_STRIKEOUT_DOUBLE
:
167 case primitive2d::TEXT_STRIKEOUT_BOLD
:
169 fStrikeoutHeight
*= 2.0;
176 fStrikeoutOffset
-= 0.50 * fStrikeoutHeight
;
177 fStrikeoutHeight
*= 0.64;
180 // create base polygon and new primitive
181 basegfx::B2DPolygon aStrikeoutLine
;
183 aStrikeoutLine
.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset
));
184 aStrikeoutLine
.append(basegfx::B2DPoint(getWidth(), -fStrikeoutOffset
));
186 const basegfx::B2DHomMatrix
aUnscaledTransform(
187 basegfx::utils::createShearXRotateTranslateB2DHomMatrix(
188 fShearX
, fRotate
, aTranslate
));
190 aStrikeoutLine
.transform(aUnscaledTransform
);
193 const attribute::LineAttribute
aLineAttribute(getFontColor(), fStrikeoutHeight
, basegfx::B2DLineJoin::NONE
);
194 Primitive2DContainer
xRetval(1);
195 xRetval
[0] = new PolygonStrokePrimitive2D(std::move(aStrikeoutLine
), aLineAttribute
);
199 // double line, create 2nd primitive with offset using TransformPrimitive based on
200 // already created NewPrimitive
201 const double fLineDist(2.0 * fStrikeoutHeight
);
203 // move base point of text to 0.0 and de-rotate
204 basegfx::B2DHomMatrix
aTransform(basegfx::utils::createTranslateB2DHomMatrix(
205 -aTranslate
.getX(), -aTranslate
.getY()));
206 aTransform
.rotate(-fRotate
);
208 // translate in Y by offset
209 aTransform
.translate(0.0, -fLineDist
);
211 // move back and rotate
212 aTransform
.rotate(fRotate
);
213 aTransform
.translate(aTranslate
.getX(), aTranslate
.getY());
215 // add transform primitive
217 new TransformPrimitive2D(
219 Primitive2DContainer(xRetval
)));
222 rContainer
.append(std::move(xRetval
));
225 TextGeometryStrikeoutPrimitive2D::TextGeometryStrikeoutPrimitive2D(
226 const basegfx::B2DHomMatrix
& rObjectTransformation
,
228 const basegfx::BColor
& rFontColor
,
231 TextStrikeout eTextStrikeout
)
232 : BaseTextStrikeoutPrimitive2D(rObjectTransformation
, fWidth
, rFontColor
),
235 meTextStrikeout(eTextStrikeout
)
239 bool TextGeometryStrikeoutPrimitive2D::operator==( const BasePrimitive2D
& rPrimitive
) const
241 if(BaseTextStrikeoutPrimitive2D::operator==(rPrimitive
))
243 const TextGeometryStrikeoutPrimitive2D
& rCompare
= static_cast<const TextGeometryStrikeoutPrimitive2D
&>(rPrimitive
);
245 return (getHeight() == rCompare
.getHeight()
246 && getOffset() == rCompare
.getOffset()
247 && getTextStrikeout() == rCompare
.getTextStrikeout());
254 sal_uInt32
TextGeometryStrikeoutPrimitive2D::getPrimitive2DID() const
256 return PRIMITIVE2D_ID_TEXTGEOMETRYSTRIKEOUTPRIMITIVE2D
;
259 } // end of namespace
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */