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 <overlayobject.hxx>
22 #include <drawinglayer/attribute/fontattribute.hxx>
23 #include <drawinglayer/geometry/viewinformation2d.hxx>
24 #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
25 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
26 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
27 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
28 #include <basegfx/polygon/b2dpolygontools.hxx>
29 #include <basegfx/matrix/b2dhommatrixtools.hxx>
30 #include <tools/lineend.hxx>
32 #include <vcl/outdev.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/metric.hxx>
35 #include <sal/log.hxx>
37 #define HINT_LINESPACE 2
41 ScOverlayHint::ScOverlayHint(OUString aTit
, const OUString
& rMsg
, const Color
& rColor
, vcl::Font aFont
)
42 : OverlayObject(rColor
)
43 , m_aTitle(std::move(aTit
))
44 , m_aMessage(convertLineEnd(rMsg
, LINEEND_CR
))
45 , m_aTextFont(std::move(aFont
))
46 , m_aMapMode(MapUnit::MapPixel
)
52 drawinglayer::primitive2d::Primitive2DContainer
ScOverlayHint::createOverlaySequence(sal_Int32 nLeft
, sal_Int32 nTop
,
53 const MapMode
&rMapMode
,
54 basegfx::B2DRange
&rRange
) const
56 OutputDevice
* pDefaultDev
= Application::GetDefaultDevice();
57 MapMode aOld
= pDefaultDev
->GetMapMode();
58 pDefaultDev
->SetMapMode(rMapMode
);
60 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
61 const Color
& rColor
= rStyleSettings
.GetLabelTextColor();
62 vcl::Font aTextFont
= m_aTextFont
;
63 aTextFont
.SetFontSize(pDefaultDev
->PixelToLogic(aTextFont
.GetFontSize(), rMapMode
));
64 vcl::Font aHeadFont
= aTextFont
;
65 aHeadFont
.SetWeight(WEIGHT_BOLD
);
67 // Create the text primitive for the title
68 basegfx::B2DVector aFontSize
;
69 drawinglayer::attribute::FontAttribute aFontAttr
=
70 drawinglayer::primitive2d::getFontAttributeFromVclFont(aFontSize
, aHeadFont
, false, false);
72 FontMetric aFontMetric
= pDefaultDev
->GetFontMetric(aHeadFont
);
73 Size aHintMargin
= pDefaultDev
->PixelToLogic(Size(HINT_MARGIN
, HINT_MARGIN
), rMapMode
);
74 Size aIndent
= pDefaultDev
->PixelToLogic(Size(HINT_INDENT
, HINT_LINESPACE
), rMapMode
);
75 double nTextOffsetY
= nTop
+ aHintMargin
.Height() + aFontMetric
.GetAscent();
76 Point
aTextPos(nLeft
+ aHintMargin
.Width() , nTextOffsetY
);
77 rRange
= basegfx::B2DRange(nLeft
, nTop
, nLeft
+ aHintMargin
.Width(), nTop
+ aHintMargin
.Height());
79 basegfx::B2DHomMatrix
aTextMatrix(basegfx::utils::createScaleTranslateB2DHomMatrix(
80 aFontSize
.getX(), aFontSize
.getY(),
81 aTextPos
.X(), aTextPos
.Y()));
83 rtl::Reference
<drawinglayer::primitive2d::TextSimplePortionPrimitive2D
> pTitle
=
84 new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
85 aTextMatrix
, m_aTitle
, 0, m_aTitle
.getLength(),
86 std::vector
<double>(), {}, std::move(aFontAttr
), css::lang::Locale(),
89 Point
aTextStart(nLeft
+ aHintMargin
.Width() + aIndent
.Width(),
90 nTop
+ aHintMargin
.Height() + aFontMetric
.GetLineHeight() + aIndent
.Height());
92 drawinglayer::geometry::ViewInformation2D aDummy
;
93 rRange
.expand(pTitle
->getB2DRange(aDummy
));
95 // insert two empty elements as placeholders for bg and border
96 drawinglayer::primitive2d::Primitive2DContainer aSeq
{ nullptr, nullptr, pTitle
};
98 aFontMetric
= pDefaultDev
->GetFontMetric(aTextFont
);
99 pDefaultDev
->SetMapMode(aOld
);
101 nTextOffsetY
= aFontMetric
.GetAscent();
102 sal_Int32 nLineHeight
= aFontMetric
.GetLineHeight();
104 aFontAttr
= drawinglayer::primitive2d::getFontAttributeFromVclFont(aFontSize
, aTextFont
, false, false);
106 sal_Int32 nIndex
= 0;
107 Point aLineStart
= aTextStart
;
108 sal_Int32 nLineCount
= 0;
111 OUString aLine
= m_aMessage
.getToken( 0, '\r', nIndex
);
112 if (aLine
.getLength() > 255)
114 // prevent silliness higher up from hanging up the program
115 SAL_WARN("sc", "ridiculously long line, truncating, len=" << aLine
.getLength());
116 aLine
= aLine
.copy(0,255);
119 aTextMatrix
= basegfx::utils::createScaleTranslateB2DHomMatrix(
120 aFontSize
.getX(), aFontSize
.getY(),
121 aLineStart
.X(), aLineStart
.Y() + nTextOffsetY
);
123 // Create the text primitive for each line of text
124 rtl::Reference
<drawinglayer::primitive2d::TextSimplePortionPrimitive2D
> pMessage
=
125 new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
126 aTextMatrix
, aLine
, 0, aLine
.getLength(),
127 std::vector
<double>(), {}, aFontAttr
, css::lang::Locale(),
130 rRange
.expand(pMessage
->getB2DRange(aDummy
));
132 aSeq
.push_back(pMessage
);
134 aLineStart
.AdjustY(nLineHeight
);
138 // prevent silliness higher up from hanging up the program
139 SAL_WARN("sc", "ridiculously long message, bailing out");
144 rRange
.expand(basegfx::B2DTuple(rRange
.getMaxX() + aHintMargin
.Width(),
145 rRange
.getMaxY() + aHintMargin
.Height()));
147 basegfx::B2DPolygon
aPoly(basegfx::utils::createPolygonFromRect(rRange
));
150 aSeq
[0] = drawinglayer::primitive2d::Primitive2DReference(
151 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPoly
), getBaseColor().getBColor()));
153 aSeq
[1] = drawinglayer::primitive2d::Primitive2DReference(
154 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
155 std::move(aPoly
), basegfx::BColor(0.5, 0.5, 0.5)));
160 drawinglayer::primitive2d::Primitive2DContainer
ScOverlayHint::createOverlayObjectPrimitive2DSequence()
162 basegfx::B2DRange aRange
;
163 return createOverlaySequence(m_nLeft
, m_nTop
, m_aMapMode
, aRange
);
166 Size
ScOverlayHint::GetSizePixel() const
168 basegfx::B2DRange aRange
;
169 createOverlaySequence(0, 0, MapMode(MapUnit::MapPixel
), aRange
);
170 return Size(aRange
.getWidth(), aRange
.getHeight());
173 void ScOverlayHint::SetPos(const Point
& rPos
, const MapMode
& rMode
)
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */