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 #ifndef INCLUDED_SVX_FRAMELINK_HXX
21 #define INCLUDED_SVX_FRAMELINK_HXX
22 
23 #include <sal/types.h>
24 #include <tools/color.hxx>
25 #include <svx/svxdllapi.h>
26 #include <editeng/borderline.hxx>
27 
28 #include <memory>
29 
30 namespace svx {
31 namespace frame {
32 
33 
34 // Enums
35 
36 
37 /** Specifies how the reference points for frame borders are used.
38  */
39 enum class RefMode
40 {
41     /** Frame borders are drawn centered to the reference points. */
42     Centered,
43 
44     /** The reference points specify the begin of the frame border width.
45 
46         The result is that horizontal lines are drawn below, and vertical lines
47         are drawn right of the reference points.
48      */
49     Begin,
50 
51     /** The reference points specify the end of the frame border width.
52 
53         The result is that horizontal lines are drawn above, and vertical lines
54         are drawn left of the reference points.
55      */
56     End
57 };
58 
59 
60 // Classes
61 
62 
63 /** Contains the widths of primary and secondary line of a frame style.
64 
65     In the following, "frame style" is a complete style of one frame border,
66     i.e. the double line at the left side of the frame. A "line" is always a
67     trivial single line, i.e. the first line of a double frame style.
68 
69     The following states of the members of this struct are valid:
70 
71     mnPrim      mnDist      mnSecn      frame style
72     -------------------------------------------------
73     0           0           0           invisible
74     >0          0           0           single
75     >0          >0          >0          double
76 
77     The behaviour of the member functions for other states is not defined.
78 
79     Per definition the primary line in double frame styles is:
80     -   The top line for horizontal frame borders.
81     -   The left line for vertical frame borders.
82     -   The bottom-left line for top-left to bottom-right diagonal frame borders.
83     -   The top-left line for bottom-left to top-right diagonal frame borders.
84 
85     The following picture shows the upper end of a vertical double frame
86     border.
87 
88         |<---------------- GetWidth() ----------------->|
89         |                                               |
90         |<----- mnPrim ----->||<- mnDist ->||<- mnSecn >|
91         |                    ||            ||           |
92         ######################              #############
93         ######################              #############
94         ######################              #############
95         ######################              #############
96         ######################  |           #############
97         ######################  |           #############
98                                 |
99                                 |<- middle of the frame border
100  */
101 class SAL_WARN_UNUSED SVX_DLLPUBLIC Style
102 {
103 private:
104     class implStyle
105     {
106     private:
107         friend class Style;
108 
109         Color               maColorPrim;
110         Color               maColorSecn;
111         Color               maColorGap;
112         bool                mbUseGapColor;
113         RefMode             meRefMode;  /// Reference point handling for this frame border.
114         double              mfPrim;     /// Width of primary (single, left, or top) line.
115         double              mfDist;     /// Distance between primary and secondary line.
116         double              mfSecn;     /// Width of secondary (right or bottom) line.
117         double              mfPatternScale; /// Scale used for line pattern spacing.
118         SvxBorderLineStyle  mnType;
119 
120     public:
121         /** Constructs an invisible frame style. */
implStyle()122         explicit implStyle() :
123             maColorPrim(),
124             maColorSecn(),
125             maColorGap(),
126             mbUseGapColor(false),
127             meRefMode(RefMode::Centered),
128             mfPrim(0.0),
129             mfDist(0.0),
130             mfSecn(0.0),
131             mfPatternScale(1.0),
132             mnType(SvxBorderLineStyle::SOLID)
133         {}
134     };
135 
136     /// the impl class holding the data
137     std::shared_ptr< implStyle >        maImplStyle;
138 
139     /// call to set maImplStyle on demand
140     void implEnsureImplStyle();
141 
142 public:
143     /** Constructs an invisible frame style. */
144     explicit Style();
145     /** Constructs a frame style with passed line widths. */
146     explicit Style( double nP, double nD, double nS, SvxBorderLineStyle nType, double fScale );
147     /** Constructs a frame style with passed color and line widths. */
148     explicit Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS, SvxBorderLineStyle nType, double fScale );
149     /** Constructs a frame style from the passed SvxBorderLine struct. */
150     explicit Style( const editeng::SvxBorderLine* pBorder, double fScale );
151 
GetRefMode() const152     RefMode GetRefMode() const { if(!maImplStyle) return RefMode::Centered; return maImplStyle->meRefMode; }
GetColorPrim() const153     Color GetColorPrim() const { if(!maImplStyle) return Color(); return maImplStyle->maColorPrim; }
GetColorSecn() const154     Color GetColorSecn() const { if(!maImplStyle) return Color(); return maImplStyle->maColorSecn; }
GetColorGap() const155     Color GetColorGap() const { if(!maImplStyle) return Color(); return maImplStyle->maColorGap; }
UseGapColor() const156     bool UseGapColor() const { if(!maImplStyle) return false; return maImplStyle->mbUseGapColor; }
Prim() const157     double Prim() const { if(!maImplStyle) return 0.0; return maImplStyle->mfPrim; }
Dist() const158     double Dist() const { if(!maImplStyle) return 0.0; return maImplStyle->mfDist; }
Secn() const159     double Secn() const { if(!maImplStyle) return 0.0; return maImplStyle->mfSecn; }
PatternScale() const160     double PatternScale() const { if(!maImplStyle) return 1.0; return maImplStyle->mfPatternScale;}
Type() const161     SvxBorderLineStyle Type() const { if(!maImplStyle) return SvxBorderLineStyle::SOLID; return maImplStyle->mnType; }
162 
163     /// Check if this style is used - this depends on it having any width definition.
164     /// As can be seen in the definition comment above, Prim() *must* be non zero to have a width
IsUsed() const165     bool IsUsed() const { if(!maImplStyle) return false; return 0.0 != maImplStyle->mfPrim; }
166 
167     /** Returns the total width of this frame style. */
GetWidth() const168     double GetWidth() const { if(!maImplStyle) return 0.0; implStyle* pTarget = maImplStyle.get(); return pTarget->mfPrim + pTarget->mfDist + pTarget->mfSecn; }
169 
170     /** Sets the frame style to invisible state. */
171     void Clear();
172     /** Sets the frame style to the passed line widths. */
173     void Set( double nP, double nD, double nS );
174     /** Sets the frame style to the passed line widths. */
175     void Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS );
176     /** Sets the frame style to the passed SvxBorderLine struct. If nullptr, resets the style */
177     void Set( const editeng::SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 );
178 
179     /** Sets a new reference point handling mode, does not modify other settings. */
180     void SetRefMode( RefMode eRefMode );
181     /** Sets a new color, does not modify other settings. */
182     void SetColorPrim( const Color& rColor );
183     void SetColorSecn( const Color& rColor );
184     /** Sets whether to use dotted style for single hair lines. */
185     void SetType( SvxBorderLineStyle nType );
186 
187     /** Mirrors this style (exchanges primary and secondary), if it is a double frame style. */
188     Style& MirrorSelf();
189 
190     bool operator==( const Style& rOther) const;
191     bool operator<( const Style& rOther) const;
192 };
193 
operator >(const Style & rL,const Style & rR)194 inline bool operator>( const Style& rL, const Style& rR ) { return rR.operator<(rL); }
195 
196 }
197 }
198 
199 #endif
200 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
201