xref: /aoo41x/main/svx/source/dialog/framelink.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/framelink.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <math.h>
29cdf0e10cSrcweir #include <vcl/outdev.hxx>
30cdf0e10cSrcweir #include <editeng/borderline.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir // ----------------------------------------------------------------------------
33cdf0e10cSrcweir 
34cdf0e10cSrcweir /** Define to select the drawing mode of thin dotted lines.
35cdf0e10cSrcweir 
36cdf0e10cSrcweir     0 = Draw lines using an own implementation (recommended). Draws always
37cdf0e10cSrcweir         little dots in an appropriate distance.
38cdf0e10cSrcweir     1 = Draw dotted lines using vcl/LineInfo. Results in dashed lines instead
39cdf0e10cSrcweir         of dotted lines, which may look ugly for diagonal lines.
40cdf0e10cSrcweir  */
41cdf0e10cSrcweir #define SVX_FRAME_USE_LINEINFO 0
42cdf0e10cSrcweir 
43cdf0e10cSrcweir // ----------------------------------------------------------------------------
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #if SVX_FRAME_USE_LINEINFO
46cdf0e10cSrcweir #include <vcl/lineinfo.hxx>
47cdf0e10cSrcweir #endif
48cdf0e10cSrcweir 
49cdf0e10cSrcweir namespace svx {
50cdf0e10cSrcweir namespace frame {
51cdf0e10cSrcweir 
52cdf0e10cSrcweir // ============================================================================
53cdf0e10cSrcweir // ============================================================================
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace {
56cdf0e10cSrcweir 
57cdf0e10cSrcweir typedef std::vector< Point > PointVec;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir // ----------------------------------------------------------------------------
60cdf0e10cSrcweir // Link result structs for horizontal and vertical lines and borders.
61cdf0e10cSrcweir 
62cdf0e10cSrcweir /** Result struct used by the horizontal/vertical frame link functions.
63cdf0e10cSrcweir 
64cdf0e10cSrcweir     This struct is used to return coordinate offsets for one end of a single
65cdf0e10cSrcweir     line in a frame border, i.e. the left end of the primary line of a
66cdf0e10cSrcweir     horizontal frame border.
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     1) Usage for horizontal lines
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     If this struct is returned by the lclLinkHorFrameBorder() function, each
71cdf0e10cSrcweir     member refers to the X coordinate of one edge of a single line end in a
72cdf0e10cSrcweir     horizontal frame border. They specify an offset to modify this coordinate
73cdf0e10cSrcweir     when the line is painted. The values in this struct may change a
74cdf0e10cSrcweir     rectangular line shape into a line with slanted left or right border, which
75cdf0e10cSrcweir     is used to connect the line with diagonal lines.
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     Usage for a left line end:          Usage for a right line end:
78cdf0e10cSrcweir                 mnOffs1                         mnOffs1
79cdf0e10cSrcweir                 <------->                       <------->
80cdf0e10cSrcweir                     +-------------------------------+
81cdf0e10cSrcweir                     | the original horizontal line  |
82cdf0e10cSrcweir                     +-------------------------------+
83cdf0e10cSrcweir                 <------->                       <------->
84cdf0e10cSrcweir                 mnOffs2                         mnOffs2
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     2) Usage for vertical lines
87cdf0e10cSrcweir 
88cdf0e10cSrcweir     If this struct is returned by the lclLinkVerFrameBorder() function, each
89cdf0e10cSrcweir     member refers to the Y coordinate of one edge of a single line end in a
90cdf0e10cSrcweir     vertical frame border. They specify an offset to modify this coordinate
91cdf0e10cSrcweir     when the line is painted. The values in this struct may change a
92cdf0e10cSrcweir     rectangular line shape into a line with slanted top or bottom border, which
93cdf0e10cSrcweir     is used to connect the line with diagonal lines.
94cdf0e10cSrcweir 
95cdf0e10cSrcweir     Usage for a top line end:       mnOffs1 ^               ^ mnOffs2
96cdf0e10cSrcweir                                             |   +-------+   |
97cdf0e10cSrcweir                                             v   |       |   v
98cdf0e10cSrcweir                                                 |       |
99cdf0e10cSrcweir                                                 |       |
100cdf0e10cSrcweir                 the original vertical line ---> |       |
101cdf0e10cSrcweir                                                 |       |
102cdf0e10cSrcweir                                                 |       |
103cdf0e10cSrcweir                                             ^   |       |   ^
104cdf0e10cSrcweir                                             |   +-------+   |
105cdf0e10cSrcweir     Usage for a bottom line end:    mnOffs1 v               v mnOffs2
106cdf0e10cSrcweir  */
107cdf0e10cSrcweir struct LineEndResult
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     long                mnOffs1;    /// Offset for top or left edge, dependent of context.
110cdf0e10cSrcweir     long                mnOffs2;    /// Offset for bottom or right edge, dependent of context
111cdf0e10cSrcweir 
LineEndResultsvx::frame::__anon7a87fd3f0111::LineEndResult112cdf0e10cSrcweir     inline explicit     LineEndResult() : mnOffs1( 0 ), mnOffs2( 0 ) {}
113cdf0e10cSrcweir 
Swapsvx::frame::__anon7a87fd3f0111::LineEndResult114cdf0e10cSrcweir     inline void         Swap() { std::swap( mnOffs1, mnOffs2 ); }
Negatesvx::frame::__anon7a87fd3f0111::LineEndResult115cdf0e10cSrcweir     inline void         Negate() { mnOffs1 = -mnOffs1; mnOffs2 = -mnOffs2; }
116cdf0e10cSrcweir };
117cdf0e10cSrcweir 
118cdf0e10cSrcweir /** Result struct used by the horizontal/vertical frame link functions.
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     This struct contains the linking results for one end of a frame border,
121cdf0e10cSrcweir     including both the primary and secondary line ends.
122cdf0e10cSrcweir  */
123cdf0e10cSrcweir struct BorderEndResult
124cdf0e10cSrcweir {
125cdf0e10cSrcweir     LineEndResult       maPrim;     /// Result for primary line.
126cdf0e10cSrcweir     LineEndResult       maSecn;     /// Result for secondary line.
127cdf0e10cSrcweir 
Negatesvx::frame::__anon7a87fd3f0111::BorderEndResult128cdf0e10cSrcweir     inline void         Negate() { maPrim.Negate(); maSecn.Negate(); }
129cdf0e10cSrcweir };
130cdf0e10cSrcweir 
131cdf0e10cSrcweir /** Result struct used by the horizontal/vertical frame link functions.
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     This struct contains the linking results for both frame border ends, and
134cdf0e10cSrcweir     therefore for the complete frame border.
135cdf0e10cSrcweir  */
136cdf0e10cSrcweir struct BorderResult
137cdf0e10cSrcweir {
138cdf0e10cSrcweir     BorderEndResult     maBeg;      /// Result for begin of border line (left or top end).
139cdf0e10cSrcweir     BorderEndResult     maEnd;      /// Result for end of border line (right or bottom end).
140cdf0e10cSrcweir };
141cdf0e10cSrcweir 
142cdf0e10cSrcweir // ----------------------------------------------------------------------------
143cdf0e10cSrcweir // Link result structs for diagonal lines and borders.
144cdf0e10cSrcweir 
145cdf0e10cSrcweir /** Result struct used by the diagonal frame link functions.
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     This struct contains the linking results for one line of a diagonal frame
148cdf0e10cSrcweir     border.
149cdf0e10cSrcweir  */
150cdf0e10cSrcweir struct DiagLineResult
151cdf0e10cSrcweir {
152cdf0e10cSrcweir     long                mnLClip;    /// Offset for left border of clipping rectangle.
153cdf0e10cSrcweir     long                mnRClip;    /// Offset for right border of clipping rectangle.
154cdf0e10cSrcweir     long                mnTClip;    /// Offset for top border of clipping rectangle.
155cdf0e10cSrcweir     long                mnBClip;    /// Offset for bottom border of clipping rectangle.
156cdf0e10cSrcweir 
DiagLineResultsvx::frame::__anon7a87fd3f0111::DiagLineResult157cdf0e10cSrcweir     inline explicit     DiagLineResult() : mnLClip( 0 ), mnRClip( 0 ), mnTClip( 0 ), mnBClip( 0 ) {}
158cdf0e10cSrcweir };
159cdf0e10cSrcweir 
160cdf0e10cSrcweir /** Result struct used by the diagonal frame link functions.
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     This struct contains the linking results for one diagonal frame border.
163cdf0e10cSrcweir  */
164cdf0e10cSrcweir struct DiagBorderResult
165cdf0e10cSrcweir {
166cdf0e10cSrcweir     DiagLineResult      maPrim;     /// Result for primary line.
167cdf0e10cSrcweir     DiagLineResult      maSecn;     /// Result for secondary line.
168cdf0e10cSrcweir };
169cdf0e10cSrcweir 
170cdf0e10cSrcweir /** Result struct used by the diagonal frame link functions.
171cdf0e10cSrcweir 
172cdf0e10cSrcweir     This struct contains the linking results for both diagonal frame borders.
173cdf0e10cSrcweir  */
174cdf0e10cSrcweir struct DiagBordersResult
175cdf0e10cSrcweir {
176cdf0e10cSrcweir     DiagBorderResult    maTLBR;     /// Result for top-left to bottom-right frame border.
177cdf0e10cSrcweir     DiagBorderResult    maBLTR;     /// Result for bottom-left to top-right frame border.
178cdf0e10cSrcweir };
179cdf0e10cSrcweir 
180cdf0e10cSrcweir // ----------------------------------------------------------------------------
181cdf0e10cSrcweir 
182cdf0e10cSrcweir /** A helper struct containing two points of a line.
183cdf0e10cSrcweir  */
184cdf0e10cSrcweir struct LinePoints
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     Point               maBeg;      /// Start position of the line.
187cdf0e10cSrcweir     Point               maEnd;      /// End position of the line.
188cdf0e10cSrcweir 
LinePointssvx::frame::__anon7a87fd3f0111::LinePoints189cdf0e10cSrcweir     explicit            LinePoints( const Point& rBeg, const Point& rEnd ) :
190cdf0e10cSrcweir                             maBeg( rBeg ), maEnd( rEnd ) {}
LinePointssvx::frame::__anon7a87fd3f0111::LinePoints191cdf0e10cSrcweir     explicit            LinePoints( const Rectangle& rRect, bool bTLBR ) :
192cdf0e10cSrcweir                             maBeg( bTLBR ? rRect.TopLeft() : rRect.TopRight() ),
193cdf0e10cSrcweir                             maEnd( bTLBR ? rRect.BottomRight() : rRect.BottomLeft() ) {}
194cdf0e10cSrcweir };
195cdf0e10cSrcweir 
196cdf0e10cSrcweir // ============================================================================
197cdf0e10cSrcweir 
198cdf0e10cSrcweir /** Rounds and casts a double value to a long value. */
lclD2L(double fValue)199cdf0e10cSrcweir inline long lclD2L( double fValue )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     return static_cast< long >( (fValue < 0.0) ? (fValue - 0.5) : (fValue + 0.5) );
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir /** Converts a width in twips to a width in another map unit (specified by fScale). */
lclScaleValue(long nValue,double fScale,sal_uInt16 nMaxWidth)205cdf0e10cSrcweir sal_uInt16 lclScaleValue( long nValue, double fScale, sal_uInt16 nMaxWidth )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir     // convert any width except 0 to at least 1 unit
208cdf0e10cSrcweir     // #i61324# 1 twip must scale to 1/100mm
209cdf0e10cSrcweir     return nValue ? static_cast< sal_uInt16 >( std::min< long >( std::max(
210cdf0e10cSrcweir         static_cast< long >( nValue * fScale ), 1L ), nMaxWidth ) ) : 0;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir // ----------------------------------------------------------------------------
214cdf0e10cSrcweir // Line width offset calculation.
215cdf0e10cSrcweir 
216cdf0e10cSrcweir /** Returns the start offset of the single/primary line across the frame border.
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     All following lclGet*Beg() and lclGet*End() functions return sub units to
219cdf0e10cSrcweir     increase the computational accuracy, where 256 sub units are equal to
220cdf0e10cSrcweir     1 map unit of the used OutputDevice.
221cdf0e10cSrcweir 
222cdf0e10cSrcweir     The following pictures show the upper end of a vertical frame border and
223cdf0e10cSrcweir     illustrates the return values of all following lclGet*Beg() and lclGet*End()
224cdf0e10cSrcweir     functions. The first picture shows a single frame border, the second picture
225cdf0e10cSrcweir     shows a double frame border.
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     The functions regard the reference point handling mode of the passed border
228cdf0e10cSrcweir     style.
229cdf0e10cSrcweir     REFMODE_CENTERED:
230cdf0e10cSrcweir         All returned offsets are relative to the middle position of the frame
231cdf0e10cSrcweir         border (offsets left of the middle are returned negative, offsets right
232cdf0e10cSrcweir         of the middle are returned positive).
233cdf0e10cSrcweir     REFMODE_BEGIN:
234cdf0e10cSrcweir         All returned offsets are relative to the begin of the frame border
235cdf0e10cSrcweir         (lclGetBeg() always returns 0).
236cdf0e10cSrcweir     REFMODE_END:
237cdf0e10cSrcweir         All returned offsets are relative to the end of the frame border
238cdf0e10cSrcweir         (lclGetEnd() always returns 0).
239cdf0e10cSrcweir 
240cdf0e10cSrcweir                                                         |<- lclGetEnd()
241cdf0e10cSrcweir                        |<- lclGetBeforeBeg()            |<- lclGetPrimEnd()
242cdf0e10cSrcweir                        |                                |
243cdf0e10cSrcweir                        ||<- lclGetBeg()                 ||<- lclGetBehindEnd()
244cdf0e10cSrcweir                        ||                               ||
245cdf0e10cSrcweir                        |#################################|
246cdf0e10cSrcweir        direction of |   #################################
247cdf0e10cSrcweir           the frame |   #################################
248cdf0e10cSrcweir           border is |   #################################
249cdf0e10cSrcweir            vertical |   #################################
250cdf0e10cSrcweir                     v   #################################
251cdf0e10cSrcweir                                         |
252cdf0e10cSrcweir                                         |<- middle of the frame border
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 
255cdf0e10cSrcweir                                          lclGetDistEnd() ->||<- lclGetSecnBeg()
256cdf0e10cSrcweir                                                            ||
257cdf0e10cSrcweir           lclGetBeg() ->|   lclGetDistBeg() ->|            ||           |<- lclGetEnd()
258cdf0e10cSrcweir                         |                     |            ||           |
259cdf0e10cSrcweir     lclGetBeforeBeg()->||  lclGetPrimEnd() ->||            ||           ||<- lclGetBehindEnd()
260cdf0e10cSrcweir                        ||                    ||            ||           ||
261cdf0e10cSrcweir                        |######################|            |#############|
262cdf0e10cSrcweir        direction of |   ######################              #############
263cdf0e10cSrcweir           the frame |   ######################              #############
264cdf0e10cSrcweir           border is |   ######################              #############
265cdf0e10cSrcweir            vertical |   ######################  |           #############
266cdf0e10cSrcweir                     v   ######################  |           #############
267cdf0e10cSrcweir                         primary line            |           secondary line
268cdf0e10cSrcweir                                                 |
269cdf0e10cSrcweir                                                 |<- middle of the frame border
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     @return
272cdf0e10cSrcweir         The start offset of the single/primary line relative to the reference
273cdf0e10cSrcweir         position of the frame border (sub units; 0 for invisible or one pixel
274cdf0e10cSrcweir         wide single frame styles).
275cdf0e10cSrcweir  */
lclGetBeg(const Style & rBorder)276cdf0e10cSrcweir long lclGetBeg( const Style& rBorder )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir     long nPos = 0;
279cdf0e10cSrcweir     switch( rBorder.GetRefMode() )
280cdf0e10cSrcweir     {
281cdf0e10cSrcweir         case REFMODE_CENTERED:  if( rBorder.Prim() ) nPos = -128 * (rBorder.GetWidth() - 1); break;
282cdf0e10cSrcweir         case REFMODE_END:       if( rBorder.Prim() ) nPos = -256 * (rBorder.GetWidth() - 1); break;
283cdf0e10cSrcweir         case REFMODE_BEGIN:     break;
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir     return nPos;
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir /** Returns the end offset of the single/secondary line across the frame border.
289cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
290cdf0e10cSrcweir     @return  The end offset of the single/secondary line relative to the
291cdf0e10cSrcweir     reference position of the frame border (sub units; 0 for invisible or one
292cdf0e10cSrcweir     pixel wide single frame styles). */
lclGetEnd(const Style & rBorder)293cdf0e10cSrcweir long lclGetEnd( const Style& rBorder )
294cdf0e10cSrcweir {
295cdf0e10cSrcweir     long nPos = 0;
296cdf0e10cSrcweir     switch( rBorder.GetRefMode() )
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         case REFMODE_CENTERED:  if( rBorder.Prim() ) nPos = 128 * (rBorder.GetWidth() - 1); break;
299cdf0e10cSrcweir         case REFMODE_BEGIN:     if( rBorder.Prim() ) nPos = 256 * (rBorder.GetWidth() - 1); break;
300cdf0e10cSrcweir         case REFMODE_END:     break;
301cdf0e10cSrcweir     }
302cdf0e10cSrcweir     return nPos;
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir /** Returns the end offset of the primary line across the frame border.
306cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
307cdf0e10cSrcweir     @return  The end offset of the primary line relative to the reference
308cdf0e10cSrcweir     position of the frame border (sub units; the end of the primary line in a
309cdf0e10cSrcweir     double frame style, otherwise the same as lclGetEnd()). */
lclGetPrimEnd(const Style & rBorder)310cdf0e10cSrcweir inline long lclGetPrimEnd( const Style& rBorder )
311cdf0e10cSrcweir { return rBorder.Prim() ? (lclGetBeg( rBorder ) + 256 * (rBorder.Prim() - 1)) : 0; }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir /** Returns the start offset of the secondary line across the frame border.
314cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
315cdf0e10cSrcweir     @return  The start offset of the secondary line relative to the reference
316cdf0e10cSrcweir     position of the frame border (sub units; 0 for single/invisible border
317cdf0e10cSrcweir     styles). */
lclGetSecnBeg(const Style & rBorder)318cdf0e10cSrcweir inline long lclGetSecnBeg( const Style& rBorder )
319cdf0e10cSrcweir { return rBorder.Secn() ? (lclGetEnd( rBorder ) - 256 * (rBorder.Secn() - 1)) : 0; }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir /** Returns the start offset of the distance space across the frame border.
322cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
323cdf0e10cSrcweir     @return  The start offset of the distance space relative to the reference
324cdf0e10cSrcweir     position of the frame border (sub units; 0 for single/invisible border
325cdf0e10cSrcweir     styles). */
lclGetDistBeg(const Style & rBorder)326cdf0e10cSrcweir inline long lclGetDistBeg( const Style& rBorder )
327cdf0e10cSrcweir { return rBorder.Secn() ? (lclGetBeg( rBorder ) + 256 * rBorder.Prim()) : 0; }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir /** Returns the end offset of the distance space across the frame border.
330cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
331cdf0e10cSrcweir     @return  The end offset of the distance space relative to the reference
332cdf0e10cSrcweir     position of the frame border (sub units; 0 for single/invisible border
333cdf0e10cSrcweir     styles). */
lclGetDistEnd(const Style & rBorder)334cdf0e10cSrcweir inline long lclGetDistEnd( const Style& rBorder )
335cdf0e10cSrcweir { return rBorder.Secn() ? (lclGetEnd( rBorder ) - 256 * rBorder.Secn()) : 0; }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir /** Returns the offset before start of single/primary line across the frame border.
338cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
339cdf0e10cSrcweir     @return  The offset directly before start of single/primary line relative
340cdf0e10cSrcweir     to the reference position of the frame border (sub units; a value one less
341cdf0e10cSrcweir     than lclGetBeg() for visible frame styles, or 0 for invisible frame style). */
lclGetBeforeBeg(const Style & rBorder)342cdf0e10cSrcweir inline long lclGetBeforeBeg( const Style& rBorder )
343cdf0e10cSrcweir { return rBorder.Prim() ? (lclGetBeg( rBorder ) - 256) : 0; }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir /** Returns the offset behind end of single/secondary line across the frame border.
346cdf0e10cSrcweir     @descr  See description of lclGetBeg() for an illustration.
347cdf0e10cSrcweir     @return  The offset directly behind end of single/secondary line relative
348cdf0e10cSrcweir     to the reference position of the frame border (sub units; a value one
349cdf0e10cSrcweir     greater than lclGetEnd() for visible frame styles, or 0 for invisible frame
350cdf0e10cSrcweir     style). */
lclGetBehindEnd(const Style & rBorder)351cdf0e10cSrcweir inline long lclGetBehindEnd( const Style& rBorder )
352cdf0e10cSrcweir { return rBorder.Prim() ? (lclGetEnd( rBorder ) + 256) : 0; }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir // ============================================================================
355cdf0e10cSrcweir // Linking functions
356cdf0e10cSrcweir // ============================================================================
357cdf0e10cSrcweir 
358cdf0e10cSrcweir // ----------------------------------------------------------------------------
359cdf0e10cSrcweir // Linking of single horizontal line ends.
360cdf0e10cSrcweir 
361cdf0e10cSrcweir /** Calculates X offsets for the left end of a single horizontal frame border.
362cdf0e10cSrcweir 
363cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
364cdf0e10cSrcweir 
365cdf0e10cSrcweir     @param rResult
366cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
367cdf0e10cSrcweir         X coordinates of the left line end.
368cdf0e10cSrcweir  */
lclLinkLeftEnd_Single(LineEndResult & rResult,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle & rLFromBR)369cdf0e10cSrcweir void lclLinkLeftEnd_Single(
370cdf0e10cSrcweir         LineEndResult& rResult, const Style& rBorder,
371cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& rLFromBR )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir     // both vertical and diagonal frame borders are double
374cdf0e10cSrcweir     if( rLFromT.Secn() && rLFromB.Secn() && rLFromTR.Secn() && rLFromBR.Secn() )
375cdf0e10cSrcweir     {
376cdf0e10cSrcweir         // take left position of upper and lower secondary start
377cdf0e10cSrcweir         rResult.mnOffs1 = GetBLDiagOffset( lclGetBeg( rBorder ), lclGetSecnBeg( rLFromTR ), rLFromTR.GetAngle() );
378cdf0e10cSrcweir         rResult.mnOffs2 = GetTLDiagOffset( lclGetEnd( rBorder ), lclGetSecnBeg( rLFromBR ), rLFromBR.GetAngle() );
379cdf0e10cSrcweir     }
380cdf0e10cSrcweir     else
381cdf0e10cSrcweir     {
382cdf0e10cSrcweir         // both vertical frame borders are double
383cdf0e10cSrcweir         if( rLFromT.Secn() && rLFromB.Secn() )
3842baf5de7SEike Rathke 		{
385cdf0e10cSrcweir             rResult.mnOffs1 = (!rLFromTR.Secn() && !rLFromBR.Secn() && (rLFromT.GetWidth() == rLFromB.GetWidth())) ?
386cdf0e10cSrcweir                 // don't overdraw vertical borders with equal width
387cdf0e10cSrcweir                 lclGetBehindEnd( rLFromT ) :
388cdf0e10cSrcweir                 // take leftmost start of both secondary lines (#46488#)
3892baf5de7SEike Rathke                 std::min( lclGetSecnBeg( rLFromT ), lclGetSecnBeg( rLFromB ) );
3902baf5de7SEike Rathke 		}
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         // single border with equal width coming from left
393cdf0e10cSrcweir         else if( !rLFromL.Secn() && (rLFromL.Prim() == rBorder.Prim()) )
394cdf0e10cSrcweir             // draw to connection point
395cdf0e10cSrcweir             rResult.mnOffs1 = 0;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir         // single border coming from left
398cdf0e10cSrcweir         else if( !rLFromL.Secn() && rLFromL.Prim() )
399cdf0e10cSrcweir         {
400cdf0e10cSrcweir             if( rLFromL.Prim() == rBorder.Prim() )
401cdf0e10cSrcweir                 // draw to reference position, if from left has equal width
402cdf0e10cSrcweir                 rResult.mnOffs1 = 0;
403cdf0e10cSrcweir             else
404cdf0e10cSrcweir                 rResult.mnOffs1 = (rLFromL < rBorder) ?
405cdf0e10cSrcweir                     // take leftmost start of both frame borders, if from left is thinner
406cdf0e10cSrcweir                     std::min( lclGetBeg( rLFromT ), lclGetBeg( rLFromB ) ) :
407cdf0e10cSrcweir                     // do not overdraw vertical, if from left is thicker
408cdf0e10cSrcweir                     std::max( lclGetBehindEnd( rLFromT ), lclGetBehindEnd( rLFromB ) );
409cdf0e10cSrcweir         }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir         // no border coming from left
412cdf0e10cSrcweir         else if( !rLFromL.Prim() )
413cdf0e10cSrcweir             // don't overdraw vertical borders with equal width
414cdf0e10cSrcweir             rResult.mnOffs1 = (rLFromT.GetWidth() == rLFromB.GetWidth()) ?
415cdf0e10cSrcweir                 lclGetBehindEnd( rLFromT ) :
416cdf0e10cSrcweir                 std::min( lclGetBeg( rLFromT ), lclGetBeg( rLFromB ) );
417cdf0e10cSrcweir 
418cdf0e10cSrcweir         // double frame border coming from left and from top
419cdf0e10cSrcweir         else if( rLFromT.Secn() )
420cdf0e10cSrcweir             // do not overdraw the vertical double frame border
421cdf0e10cSrcweir             rResult.mnOffs1 = lclGetBehindEnd( rLFromT );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir         // double frame border coming from left and from bottom
424cdf0e10cSrcweir         else if( rLFromB.Secn() )
425cdf0e10cSrcweir             // do not overdraw the vertical double frame border
426cdf0e10cSrcweir             rResult.mnOffs1 = lclGetBehindEnd( rLFromB );
427cdf0e10cSrcweir 
428cdf0e10cSrcweir         // double frame border coming from left, both vertical frame borders are single or off
429cdf0e10cSrcweir         else
430cdf0e10cSrcweir             // draw from leftmost start of both frame borders, if from left is not thicker
431cdf0e10cSrcweir             rResult.mnOffs1 = (rLFromL <= rBorder) ?
432cdf0e10cSrcweir                 std::min( lclGetBeg( rLFromT ), lclGetBeg( rLFromB ) ) :
433cdf0e10cSrcweir                 std::max( lclGetBehindEnd( rLFromT ), lclGetBehindEnd( rLFromB ) );
434cdf0e10cSrcweir 
435cdf0e10cSrcweir         // bottom-left point is equal to top-left point (results in rectangle)
436cdf0e10cSrcweir         rResult.mnOffs2 = rResult.mnOffs1;
437cdf0e10cSrcweir     }
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir /** Calculates X offsets for the left end of a primary horizontal line.
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     @param rResult
445cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
446cdf0e10cSrcweir         X coordinates of the left end of the primary line.
447cdf0e10cSrcweir  */
lclLinkLeftEnd_Prim(LineEndResult & rResult,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle &)448cdf0e10cSrcweir void lclLinkLeftEnd_Prim(
449cdf0e10cSrcweir         LineEndResult& rResult, const Style& rBorder,
450cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& /*rLFromBR*/ )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir     // double diagonal frame border coming from top right
453cdf0e10cSrcweir     if( rLFromTR.Secn() )
454cdf0e10cSrcweir     {
455cdf0e10cSrcweir         // draw from where secondary diagonal line meets the own primary
456cdf0e10cSrcweir         rResult.mnOffs1 = GetBLDiagOffset( lclGetBeg( rBorder ), lclGetSecnBeg( rLFromTR ), rLFromTR.GetAngle() );
457cdf0e10cSrcweir         rResult.mnOffs2 = GetBLDiagOffset( lclGetPrimEnd( rBorder ), lclGetSecnBeg( rLFromTR ), rLFromTR.GetAngle() );
458cdf0e10cSrcweir     }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir     // no or single diagonal frame border - ignore it
461cdf0e10cSrcweir     else
462cdf0e10cSrcweir     {
463cdf0e10cSrcweir         // double frame border coming from top
464cdf0e10cSrcweir         if( rLFromT.Secn() )
465cdf0e10cSrcweir             // draw from left edge of secondary vertical
466cdf0e10cSrcweir             rResult.mnOffs1 = lclGetSecnBeg( rLFromT );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir         // double frame border coming from left (from top is not double)
469cdf0e10cSrcweir         else if( rLFromL.Secn() )
470cdf0e10cSrcweir             // do not overdraw single frame border coming from top
471cdf0e10cSrcweir             rResult.mnOffs1 = (rLFromL.GetWidth() == rBorder.GetWidth()) ?
472cdf0e10cSrcweir                 0 : lclGetBehindEnd( rLFromT );
473cdf0e10cSrcweir 
474cdf0e10cSrcweir         // double frame border coming from bottom (from top and from left are not double)
475cdf0e10cSrcweir         else if( rLFromB.Secn() )
476cdf0e10cSrcweir             // draw from left edge of primary vertical from bottom
477cdf0e10cSrcweir             rResult.mnOffs1 = lclGetBeg( rLFromB );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir         // no other frame border is double
480cdf0e10cSrcweir         else
481cdf0e10cSrcweir             // do not overdraw vertical frame borders
482cdf0e10cSrcweir             rResult.mnOffs1 = std::max( lclGetBehindEnd( rLFromT ), lclGetBehindEnd( rLFromB ) );
483cdf0e10cSrcweir 
484cdf0e10cSrcweir         // bottom-left point is equal to top-left point (results in rectangle)
485cdf0e10cSrcweir         rResult.mnOffs2 = rResult.mnOffs1;
486cdf0e10cSrcweir     }
487cdf0e10cSrcweir }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir /** Calculates X offsets for the left end of a secondary horizontal line.
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     @param rResult
494cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
495cdf0e10cSrcweir         X coordinates of the left end of the secondary line.
496cdf0e10cSrcweir  */
lclLinkLeftEnd_Secn(LineEndResult & rResult,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle & rLFromBR)497cdf0e10cSrcweir void lclLinkLeftEnd_Secn(
498cdf0e10cSrcweir         LineEndResult& rResult, const Style& rBorder,
499cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& rLFromBR )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir     /*  Recycle lclLinkLeftEnd_Prim() function with mirrored horizontal borders. */
502cdf0e10cSrcweir     lclLinkLeftEnd_Prim( rResult, rBorder.Mirror(), rLFromBR, rLFromB, rLFromL.Mirror(), rLFromT, rLFromTR );
503cdf0e10cSrcweir     rResult.Swap();
504cdf0e10cSrcweir }
505cdf0e10cSrcweir 
506cdf0e10cSrcweir // ----------------------------------------------------------------------------
507cdf0e10cSrcweir // Linking of horizontal frame border ends.
508cdf0e10cSrcweir 
509cdf0e10cSrcweir /** Calculates X offsets for the left end of a horizontal frame border.
510cdf0e10cSrcweir 
511cdf0e10cSrcweir     This function can be used for single and double frame borders.
512cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
513cdf0e10cSrcweir 
514cdf0e10cSrcweir     @param rResult
515cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
516cdf0e10cSrcweir         X coordinates of the left end of the line(s) in the frame border.
517cdf0e10cSrcweir  */
lclLinkLeftEnd(BorderEndResult & rResult,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle & rLFromBR)518cdf0e10cSrcweir void lclLinkLeftEnd(
519cdf0e10cSrcweir         BorderEndResult& rResult, const Style& rBorder,
520cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& rLFromBR )
521cdf0e10cSrcweir {
522cdf0e10cSrcweir     if( rBorder.Secn() )
523cdf0e10cSrcweir     {
524cdf0e10cSrcweir         // current frame border is double
525cdf0e10cSrcweir         lclLinkLeftEnd_Prim( rResult.maPrim, rBorder, rLFromTR, rLFromT, rLFromL, rLFromB, rLFromBR );
526cdf0e10cSrcweir         lclLinkLeftEnd_Secn( rResult.maSecn, rBorder, rLFromTR, rLFromT, rLFromL, rLFromB, rLFromBR );
527cdf0e10cSrcweir     }
528cdf0e10cSrcweir     else if( rBorder.Prim() )
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         // current frame border is single
531cdf0e10cSrcweir         lclLinkLeftEnd_Single( rResult.maPrim, rBorder, rLFromTR, rLFromT, rLFromL, rLFromB, rLFromBR );
532cdf0e10cSrcweir     }
533cdf0e10cSrcweir     else
534cdf0e10cSrcweir     {
535cdf0e10cSrcweir         DBG_ERRORFILE( "lclLinkLeftEnd - called for invisible frame style" );
536cdf0e10cSrcweir     }
537cdf0e10cSrcweir }
538cdf0e10cSrcweir 
539cdf0e10cSrcweir /** Calculates X offsets for the right end of a horizontal frame border.
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     This function can be used for single and double frame borders.
542cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     @param rResult
545cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
546cdf0e10cSrcweir         X coordinates of the right end of the line(s) in the frame border.
547cdf0e10cSrcweir  */
lclLinkRightEnd(BorderEndResult & rResult,const Style & rBorder,const DiagStyle & rRFromTL,const Style & rRFromT,const Style & rRFromR,const Style & rRFromB,const DiagStyle & rRFromBL)548cdf0e10cSrcweir void lclLinkRightEnd(
549cdf0e10cSrcweir         BorderEndResult& rResult, const Style& rBorder,
550cdf0e10cSrcweir         const DiagStyle& rRFromTL, const Style& rRFromT, const Style& rRFromR, const Style& rRFromB, const DiagStyle& rRFromBL )
551cdf0e10cSrcweir {
552cdf0e10cSrcweir     /*  Recycle lclLinkLeftEnd() function with mirrored vertical borders. */
553cdf0e10cSrcweir     lclLinkLeftEnd( rResult, rBorder, rRFromTL.Mirror(), rRFromT.Mirror(), rRFromR, rRFromB.Mirror(), rRFromBL.Mirror() );
554cdf0e10cSrcweir     rResult.Negate();
555cdf0e10cSrcweir }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir // ----------------------------------------------------------------------------
558cdf0e10cSrcweir // Linking of horizontal and vertical frame borders.
559cdf0e10cSrcweir 
560cdf0e10cSrcweir /** Calculates X offsets for all line ends of a horizontal frame border.
561cdf0e10cSrcweir 
562cdf0e10cSrcweir     This function can be used for single and double frame borders.
563cdf0e10cSrcweir     See DrawHorFrameBorder() function for a description of all parameters.
564cdf0e10cSrcweir 
565cdf0e10cSrcweir     @param rResult
566cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
567cdf0e10cSrcweir         X coordinates of both ends of the line(s) in the frame border. To get
568cdf0e10cSrcweir         the actual X coordinates to draw the lines, these offsets have to be
569cdf0e10cSrcweir         added to the X coordinates of the reference points of the frame border
570cdf0e10cSrcweir         (the offsets may be negative).
571cdf0e10cSrcweir  */
lclLinkHorFrameBorder(BorderResult & rResult,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle & rLFromBR,const DiagStyle & rRFromTL,const Style & rRFromT,const Style & rRFromR,const Style & rRFromB,const DiagStyle & rRFromBL)572cdf0e10cSrcweir void lclLinkHorFrameBorder(
573cdf0e10cSrcweir         BorderResult& rResult, const Style& rBorder,
574cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& rLFromBR,
575cdf0e10cSrcweir         const DiagStyle& rRFromTL, const Style& rRFromT, const Style& rRFromR, const Style& rRFromB, const DiagStyle& rRFromBL )
576cdf0e10cSrcweir {
577cdf0e10cSrcweir     lclLinkLeftEnd( rResult.maBeg, rBorder, rLFromTR, rLFromT, rLFromL, rLFromB, rLFromBR );
578cdf0e10cSrcweir     lclLinkRightEnd( rResult.maEnd, rBorder, rRFromTL, rRFromT, rRFromR, rRFromB, rRFromBL );
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir /** Calculates Y offsets for all line ends of a vertical frame border.
582cdf0e10cSrcweir 
583cdf0e10cSrcweir     This function can be used for single and double frame borders.
584cdf0e10cSrcweir     See DrawVerFrameBorder() function for a description of all parameters.
585cdf0e10cSrcweir 
586cdf0e10cSrcweir     @param rResult
587cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for the
588cdf0e10cSrcweir         Y coordinates of both ends of the line(s) in the frame border. To get
589cdf0e10cSrcweir         the actual Y coordinates to draw the lines, these offsets have to be
590cdf0e10cSrcweir         added to the Y coordinates of the reference points of the frame border
591cdf0e10cSrcweir         (the offsets may be negative).
592cdf0e10cSrcweir  */
lclLinkVerFrameBorder(BorderResult & rResult,const Style & rBorder,const DiagStyle & rTFromBL,const Style & rTFromL,const Style & rTFromT,const Style & rTFromR,const DiagStyle & rTFromBR,const DiagStyle & rBFromTL,const Style & rBFromL,const Style & rBFromB,const Style & rBFromR,const DiagStyle & rBFromTR)593cdf0e10cSrcweir void lclLinkVerFrameBorder(
594cdf0e10cSrcweir         BorderResult& rResult, const Style& rBorder,
595cdf0e10cSrcweir         const DiagStyle& rTFromBL, const Style& rTFromL, const Style& rTFromT, const Style& rTFromR, const DiagStyle& rTFromBR,
596cdf0e10cSrcweir         const DiagStyle& rBFromTL, const Style& rBFromL, const Style& rBFromB, const Style& rBFromR, const DiagStyle& rBFromTR )
597cdf0e10cSrcweir {
598cdf0e10cSrcweir     /*  Recycle lclLinkHorFrameBorder() function with correct parameters. The
599cdf0e10cSrcweir         frame border is virtually mirrored at the top-left to bottom-right
600cdf0e10cSrcweir         diagonal. rTFromBR and rBFromTL are mirrored to process their primary
601cdf0e10cSrcweir         and secondary lines correctly. */
602cdf0e10cSrcweir     lclLinkHorFrameBorder( rResult, rBorder,
603cdf0e10cSrcweir         rTFromBL, rTFromL, rTFromT, rTFromR, rTFromBR.Mirror(),
604cdf0e10cSrcweir         rBFromTL.Mirror(), rBFromL, rBFromB, rBFromR, rBFromTR );
605cdf0e10cSrcweir }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir // ============================================================================
608cdf0e10cSrcweir 
609cdf0e10cSrcweir #if 0
610cdf0e10cSrcweir //  Not used anymore, but not deleted for possible future usage.
611cdf0e10cSrcweir 
612cdf0e10cSrcweir /** Returns the relative Y offset of the intercept point of 2 diagonal borders.
613cdf0e10cSrcweir 
614cdf0e10cSrcweir     @param nTLBROffs
615cdf0e10cSrcweir         Width offset (sub units) across the top-left to bottom-right frame border.
616cdf0e10cSrcweir     @param fTLBRAngle
617cdf0e10cSrcweir         Inner angle between horizontal and top-left to bottom-right frame border.
618cdf0e10cSrcweir     @param nBLTROffs
619cdf0e10cSrcweir         Width offset (sub units) across the bottom-left to top-right frame border.
620cdf0e10cSrcweir     @param fBLTRAngle
621cdf0e10cSrcweir         Inner angle between horizontal and bottom-left to top-right frame border.
622cdf0e10cSrcweir     @return
623cdf0e10cSrcweir         Offset (sub units) relative to the Y position of the centered intercept
624cdf0e10cSrcweir         point of both diagonal frame borders.
625cdf0e10cSrcweir  */
626cdf0e10cSrcweir long lclGetDiagDiagOffset( long nTLBROffs, double fTLBRAngle, long nBLTROffs, double fBLTRAngle )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir     double fASin = sin( fTLBRAngle );
629cdf0e10cSrcweir     double fACos = cos( fTLBRAngle );
630cdf0e10cSrcweir     double fAX = -nTLBROffs * fASin;
631cdf0e10cSrcweir     double fAY = nTLBROffs * fACos;
632cdf0e10cSrcweir     double fRAX = fACos;
633cdf0e10cSrcweir     double fRAY = fASin;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir     double fBSin = sin( fBLTRAngle );
636cdf0e10cSrcweir     double fBCos = cos( fBLTRAngle );
637cdf0e10cSrcweir     double fBX = nBLTROffs * fBSin;
638cdf0e10cSrcweir     double fBY = nBLTROffs * fBCos;
639cdf0e10cSrcweir     double fRBX = fBCos;
640cdf0e10cSrcweir     double fRBY = -fBSin;
641cdf0e10cSrcweir 
642cdf0e10cSrcweir     double fKA = (fRBX * (fBY - fAY) - fRBY * (fBX - fAX)) / (fRBX * fRAY - fRAX * fRBY);
643cdf0e10cSrcweir     return lclD2L( fAY + fKA * fRAY );
644cdf0e10cSrcweir }
645cdf0e10cSrcweir #endif
646cdf0e10cSrcweir 
647cdf0e10cSrcweir // ----------------------------------------------------------------------------
648cdf0e10cSrcweir // Linking of diagonal frame borders.
649cdf0e10cSrcweir 
650cdf0e10cSrcweir /** Calculates clipping offsets for a top-left to bottom-right frame border.
651cdf0e10cSrcweir 
652cdf0e10cSrcweir     This function can be used for single and double frame borders.
653cdf0e10cSrcweir     See DrawDiagFrameBorders() function for a description of all parameters.
654cdf0e10cSrcweir 
655cdf0e10cSrcweir     @param rResult
656cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for all
657cdf0e10cSrcweir         borders of the reference rectangle containing the diagonal frame border.
658cdf0e10cSrcweir  */
lclLinkTLBRFrameBorder(DiagBorderResult & rResult,const Style & rBorder,const Style & rTLFromB,const Style & rTLFromR,const Style & rBRFromT,const Style & rBRFromL)659cdf0e10cSrcweir void lclLinkTLBRFrameBorder(
660cdf0e10cSrcweir         DiagBorderResult& rResult, const Style& rBorder,
661cdf0e10cSrcweir         const Style& rTLFromB, const Style& rTLFromR, const Style& rBRFromT, const Style& rBRFromL )
662cdf0e10cSrcweir {
663cdf0e10cSrcweir     bool bIsDbl = rBorder.Secn() != 0;
664cdf0e10cSrcweir 
665cdf0e10cSrcweir     rResult.maPrim.mnLClip = lclGetBehindEnd( rTLFromB );
666cdf0e10cSrcweir     rResult.maPrim.mnRClip = (bIsDbl && rBRFromT.Secn()) ? lclGetEnd( rBRFromT ) : lclGetBeforeBeg( rBRFromT );
667cdf0e10cSrcweir     rResult.maPrim.mnTClip = (bIsDbl && rTLFromR.Secn()) ? lclGetBeg( rTLFromR ) : lclGetBehindEnd( rTLFromR );
668cdf0e10cSrcweir     rResult.maPrim.mnBClip = lclGetBeforeBeg( rBRFromL );
669cdf0e10cSrcweir 
670cdf0e10cSrcweir     if( bIsDbl )
671cdf0e10cSrcweir     {
672cdf0e10cSrcweir         rResult.maSecn.mnLClip = rTLFromB.Secn() ? lclGetBeg( rTLFromB ) : lclGetBehindEnd( rTLFromB );
673cdf0e10cSrcweir         rResult.maSecn.mnRClip = lclGetBeforeBeg( rBRFromT );
674cdf0e10cSrcweir         rResult.maSecn.mnTClip = lclGetBehindEnd( rTLFromR );
675cdf0e10cSrcweir         rResult.maSecn.mnBClip = rBRFromL.Secn() ? lclGetEnd( rBRFromL ) : lclGetBeforeBeg( rBRFromL );
676cdf0e10cSrcweir     }
677cdf0e10cSrcweir }
678cdf0e10cSrcweir 
679cdf0e10cSrcweir /** Calculates clipping offsets for a bottom-left to top-right frame border.
680cdf0e10cSrcweir 
681cdf0e10cSrcweir     This function can be used for single and double frame borders.
682cdf0e10cSrcweir     See DrawDiagFrameBorders() function for a description of all parameters.
683cdf0e10cSrcweir 
684cdf0e10cSrcweir     @param rResult
685cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for all
686cdf0e10cSrcweir         borders of the reference rectangle containing the diagonal frame border.
687cdf0e10cSrcweir  */
lclLinkBLTRFrameBorder(DiagBorderResult & rResult,const Style & rBorder,const Style & rBLFromT,const Style & rBLFromR,const Style & rTRFromB,const Style & rTRFromL)688cdf0e10cSrcweir void lclLinkBLTRFrameBorder(
689cdf0e10cSrcweir         DiagBorderResult& rResult, const Style& rBorder,
690cdf0e10cSrcweir         const Style& rBLFromT, const Style& rBLFromR, const Style& rTRFromB, const Style& rTRFromL )
691cdf0e10cSrcweir {
692cdf0e10cSrcweir     bool bIsDbl = rBorder.Secn() != 0;
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     rResult.maPrim.mnLClip = lclGetBehindEnd( rBLFromT );
695cdf0e10cSrcweir     rResult.maPrim.mnRClip = (bIsDbl && rTRFromB.Secn()) ? lclGetEnd( rTRFromB ) : lclGetBeforeBeg( rTRFromB );
696cdf0e10cSrcweir     rResult.maPrim.mnTClip = lclGetBehindEnd( rTRFromL );
697cdf0e10cSrcweir     rResult.maPrim.mnBClip = (bIsDbl && rBLFromR.Secn()) ? lclGetEnd( rBLFromR ) : lclGetBeforeBeg( rBLFromR );
698cdf0e10cSrcweir 
699cdf0e10cSrcweir     if( bIsDbl )
700cdf0e10cSrcweir     {
701cdf0e10cSrcweir         rResult.maSecn.mnLClip = rBLFromT.Secn() ? lclGetBeg( rBLFromT ) : lclGetBehindEnd( rBLFromT );
702cdf0e10cSrcweir         rResult.maSecn.mnRClip = lclGetBeforeBeg( rTRFromB );
703cdf0e10cSrcweir         rResult.maSecn.mnTClip = rTRFromL.Secn() ? lclGetBeg( rTRFromL ) : lclGetBehindEnd( rTRFromL );
704cdf0e10cSrcweir         rResult.maSecn.mnBClip = lclGetBeforeBeg( rBLFromR );
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir /** Calculates clipping offsets for both diagonal frame borders.
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     This function can be used for single and double frame borders.
711cdf0e10cSrcweir     See DrawDiagFrameBorders() function for a description of all parameters.
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     @param rResult
714cdf0e10cSrcweir         (out-param) The contained values (sub units) specify offsets for all
715cdf0e10cSrcweir         borders of the reference rectangle containing the diagonal frame
716cdf0e10cSrcweir         borders.
717cdf0e10cSrcweir  */
lclLinkDiagFrameBorders(DiagBordersResult & rResult,const Style & rTLBR,const Style & rBLTR,const Style & rTLFromB,const Style & rTLFromR,const Style & rBRFromT,const Style & rBRFromL,const Style & rBLFromT,const Style & rBLFromR,const Style & rTRFromB,const Style & rTRFromL)718cdf0e10cSrcweir void lclLinkDiagFrameBorders(
719cdf0e10cSrcweir         DiagBordersResult& rResult, const Style& rTLBR, const Style& rBLTR,
720cdf0e10cSrcweir         const Style& rTLFromB, const Style& rTLFromR, const Style& rBRFromT, const Style& rBRFromL,
721cdf0e10cSrcweir         const Style& rBLFromT, const Style& rBLFromR, const Style& rTRFromB, const Style& rTRFromL )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir     lclLinkTLBRFrameBorder( rResult.maTLBR, rTLBR, rTLFromB, rTLFromR, rBRFromT, rBRFromL );
724cdf0e10cSrcweir     lclLinkBLTRFrameBorder( rResult.maBLTR, rBLTR, rBLFromT, rBLFromR, rTRFromB, rTRFromL );
725cdf0e10cSrcweir }
726cdf0e10cSrcweir 
727cdf0e10cSrcweir // ============================================================================
728cdf0e10cSrcweir // Drawing functions
729cdf0e10cSrcweir // ============================================================================
730cdf0e10cSrcweir 
731cdf0e10cSrcweir // ----------------------------------------------------------------------------
732cdf0e10cSrcweir // Simple helper functions
733cdf0e10cSrcweir 
734cdf0e10cSrcweir /** Converts sub units to OutputDevice map units. */
lclToMapUnit(long nSubUnits)735cdf0e10cSrcweir inline long lclToMapUnit( long nSubUnits )
736cdf0e10cSrcweir {
737cdf0e10cSrcweir     return ((nSubUnits < 0) ? (nSubUnits - 127) : (nSubUnits + 128)) / 256;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir /** Converts a point in sub units to an OutputDevice point. */
lclToMapUnit(long nSubXPos,long nSubYPos)741cdf0e10cSrcweir inline Point lclToMapUnit( long nSubXPos, long nSubYPos )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir     return Point( lclToMapUnit( nSubXPos ), lclToMapUnit( nSubYPos ) );
744cdf0e10cSrcweir }
745cdf0e10cSrcweir 
746cdf0e10cSrcweir /** Returns a polygon constructed from a vector of points. */
lclCreatePolygon(const PointVec & rPoints)747cdf0e10cSrcweir inline Polygon lclCreatePolygon( const PointVec& rPoints )
748cdf0e10cSrcweir {
749cdf0e10cSrcweir     return Polygon( static_cast< sal_uInt16 >( rPoints.size() ), &rPoints[ 0 ] );
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
752cdf0e10cSrcweir /** Returns a polygon constructed from the four passed points. */
lclCreatePolygon(const Point & rP1,const Point & rP2,const Point & rP3,const Point & rP4)753cdf0e10cSrcweir Polygon lclCreatePolygon( const Point& rP1, const Point& rP2, const Point& rP3, const Point& rP4 )
754cdf0e10cSrcweir {
755cdf0e10cSrcweir     PointVec aPoints;
756cdf0e10cSrcweir     aPoints.reserve( 4 );
757cdf0e10cSrcweir     aPoints.push_back( rP1 );
758cdf0e10cSrcweir     aPoints.push_back( rP2 );
759cdf0e10cSrcweir     aPoints.push_back( rP3 );
760cdf0e10cSrcweir     aPoints.push_back( rP4 );
761cdf0e10cSrcweir     return lclCreatePolygon( aPoints );
762cdf0e10cSrcweir }
763cdf0e10cSrcweir 
764cdf0e10cSrcweir /** Returns a polygon constructed from the five passed points. */
lclCreatePolygon(const Point & rP1,const Point & rP2,const Point & rP3,const Point & rP4,const Point & rP5)765cdf0e10cSrcweir Polygon lclCreatePolygon( const Point& rP1, const Point& rP2, const Point& rP3, const Point& rP4, const Point& rP5 )
766cdf0e10cSrcweir {
767cdf0e10cSrcweir     PointVec aPoints;
768cdf0e10cSrcweir     aPoints.reserve( 5 );
769cdf0e10cSrcweir     aPoints.push_back( rP1 );
770cdf0e10cSrcweir     aPoints.push_back( rP2 );
771cdf0e10cSrcweir     aPoints.push_back( rP3 );
772cdf0e10cSrcweir     aPoints.push_back( rP4 );
773cdf0e10cSrcweir     aPoints.push_back( rP5 );
774cdf0e10cSrcweir     return lclCreatePolygon( aPoints );
775cdf0e10cSrcweir }
776cdf0e10cSrcweir 
777cdf0e10cSrcweir /** Returns a polygon constructed from the two passed line positions. */
lclCreatePolygon(const LinePoints & rPoints1,const LinePoints & rPoints2)778cdf0e10cSrcweir inline Polygon lclCreatePolygon( const LinePoints& rPoints1, const LinePoints& rPoints2 )
779cdf0e10cSrcweir {
780cdf0e10cSrcweir     return lclCreatePolygon( rPoints1.maBeg, rPoints1.maEnd, rPoints2.maEnd, rPoints2.maBeg );
781cdf0e10cSrcweir }
782cdf0e10cSrcweir 
783cdf0e10cSrcweir /** Sets the color of the passed frame style to the output device.
784cdf0e10cSrcweir 
785cdf0e10cSrcweir     Sets the line color and fill color in the output device.
786cdf0e10cSrcweir 
787cdf0e10cSrcweir     @param rDev
788cdf0e10cSrcweir         The output device the color has to be set to. The old colors are pushed
789cdf0e10cSrcweir         onto the device's stack and can be restored with a call to
790cdf0e10cSrcweir         OutputDevice::Pop(). Please take care about the correct calling order
791cdf0e10cSrcweir         of Pop() if this function is used with other functions pushing
792cdf0e10cSrcweir         something onto the stack.
793cdf0e10cSrcweir     @param rStyle
794cdf0e10cSrcweir         The border style that contains the line color to be set to the device.
795cdf0e10cSrcweir  */
lclSetColorToOutDev(OutputDevice & rDev,const Style & rStyle,const Color * pForceColor)796cdf0e10cSrcweir void lclSetColorToOutDev( OutputDevice& rDev, const Style& rStyle, const Color* pForceColor )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir     rDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
799cdf0e10cSrcweir     rDev.SetLineColor( pForceColor ? *pForceColor : rStyle.GetColor() );
800cdf0e10cSrcweir     rDev.SetFillColor( pForceColor ? *pForceColor : rStyle.GetColor() );
801cdf0e10cSrcweir }
802cdf0e10cSrcweir 
803cdf0e10cSrcweir // ----------------------------------------------------------------------------
804cdf0e10cSrcweir // Generic drawing functions.
805cdf0e10cSrcweir 
806cdf0e10cSrcweir /** Draws a thin (1 pixel wide) line, optionally dotted, into the passed output device. */
lclDrawThinLine(OutputDevice & rDev,const Point & rBeg,const Point & rEnd,bool bDotted)807cdf0e10cSrcweir void lclDrawThinLine( OutputDevice& rDev, const Point& rBeg, const Point& rEnd, bool bDotted )
808cdf0e10cSrcweir {
809cdf0e10cSrcweir #if SVX_FRAME_USE_LINEINFO
810cdf0e10cSrcweir     if( bDotted && (rBeg != rEnd) )
811cdf0e10cSrcweir     {
812cdf0e10cSrcweir // using LineInfo for dotted lines looks ugly and does not work well for diagonal lines
813cdf0e10cSrcweir         LineInfo aLineInfo( LINE_DASH, 1 );
814cdf0e10cSrcweir         aLineInfo.SetDotCount( 1 );
815cdf0e10cSrcweir         aLineInfo.SetDotLen( 1 );
816cdf0e10cSrcweir         aLineInfo.SetDistance( 3 );
817cdf0e10cSrcweir         rDev.DrawLine( rBeg, rEnd, aLineInfo );
818cdf0e10cSrcweir     }
819cdf0e10cSrcweir #else
820cdf0e10cSrcweir     Point aBeg( rDev.LogicToPixel( rBeg ) );
821cdf0e10cSrcweir     Point aEnd( rDev.LogicToPixel( rEnd ) );
822cdf0e10cSrcweir     if( bDotted && (aBeg != aEnd) )
823cdf0e10cSrcweir     {
824cdf0e10cSrcweir         bool bHor = Abs( aEnd.X() - aBeg.X() ) > Abs( aEnd.Y() - aBeg.Y() );
825cdf0e10cSrcweir         const Point& rBegPos( bHor ? ((aBeg.X() < aEnd.X()) ? aBeg : aEnd) : ((aBeg.Y() < aEnd.Y()) ? aBeg : aEnd ) );
826cdf0e10cSrcweir         const Point& rEndPos( (rBegPos == aBeg) ? aEnd : aBeg );
827cdf0e10cSrcweir 
828cdf0e10cSrcweir         long nAlongBeg = bHor ? rBegPos.X() : rBegPos.Y();
829cdf0e10cSrcweir         long nAcrssBeg = bHor ? rBegPos.Y() : rBegPos.X();
830cdf0e10cSrcweir         long nAlongSize = (bHor ? rEndPos.X() : rEndPos.Y()) - nAlongBeg;
831cdf0e10cSrcweir         long nAcrssSize = (bHor ? rEndPos.Y() : rEndPos.X()) - nAcrssBeg;
832cdf0e10cSrcweir         double fGradient = static_cast< double >( nAcrssSize ) / nAlongSize;
833cdf0e10cSrcweir 
834cdf0e10cSrcweir         PointVec aPoints;
835cdf0e10cSrcweir         aPoints.reserve( (nAlongSize + 1) / 2 );
836cdf0e10cSrcweir         for( long nAlongIdx = 0; nAlongIdx <= nAlongSize; nAlongIdx += 2 )
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             long nAl = nAlongBeg + nAlongIdx;
839cdf0e10cSrcweir             long nAc = nAcrssBeg + lclD2L( fGradient * nAlongIdx );
840cdf0e10cSrcweir             aPoints.push_back( Point( bHor ? nAl : nAc, bHor ? nAc : nAl ) );
841cdf0e10cSrcweir         }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         rDev.Push( PUSH_MAPMODE );
844cdf0e10cSrcweir         rDev.SetMapMode( MAP_PIXEL );
845cdf0e10cSrcweir         rDev.DrawPixel( lclCreatePolygon( aPoints ) );
846cdf0e10cSrcweir         rDev.Pop(); // map mode
847cdf0e10cSrcweir     }
848cdf0e10cSrcweir #endif
849cdf0e10cSrcweir     else
850cdf0e10cSrcweir         rDev.DrawLine( rBeg, rEnd );
851cdf0e10cSrcweir }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir /** Draws a thin (1 pixel wide) line, optionally dotted, into the passed output device. */
lclDrawThinLine(OutputDevice & rDev,const LinePoints & rPoints,bool bDotted)854cdf0e10cSrcweir inline void lclDrawThinLine( OutputDevice& rDev, const LinePoints& rPoints, bool bDotted )
855cdf0e10cSrcweir {
856cdf0e10cSrcweir     lclDrawThinLine( rDev, rPoints.maBeg, rPoints.maEnd, bDotted );
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir /** Draws a polygon with four points into the passed output device. */
lclDrawPolygon(OutputDevice & rDev,const Point & rP1,const Point & rP2,const Point & rP3,const Point & rP4)860cdf0e10cSrcweir inline void lclDrawPolygon( OutputDevice& rDev, const Point& rP1, const Point& rP2, const Point& rP3, const Point& rP4 )
861cdf0e10cSrcweir {
862cdf0e10cSrcweir     rDev.DrawPolygon( lclCreatePolygon( rP1, rP2, rP3, rP4 ) );
863cdf0e10cSrcweir }
864cdf0e10cSrcweir 
865cdf0e10cSrcweir /** Draws a polygon specified by two borders into the passed output device. */
lclDrawPolygon(OutputDevice & rDev,const LinePoints & rPoints1,const LinePoints & rPoints2)866cdf0e10cSrcweir inline void lclDrawPolygon( OutputDevice& rDev, const LinePoints& rPoints1, const LinePoints& rPoints2 )
867cdf0e10cSrcweir {
868cdf0e10cSrcweir     rDev.DrawPolygon( lclCreatePolygon( rPoints1, rPoints2 ) );
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
871cdf0e10cSrcweir // ============================================================================
872cdf0e10cSrcweir // Drawing of horizontal frame borders.
873cdf0e10cSrcweir 
874cdf0e10cSrcweir /** Draws a horizontal thin or thick line into the passed output device.
875cdf0e10cSrcweir 
876cdf0e10cSrcweir     The X coordinates of the edges of the line are adjusted according to the
877cdf0e10cSrcweir     passed LineEndResult structs. A one pixel wide line can be drawn dotted.
878cdf0e10cSrcweir  */
lclDrawHorLine(OutputDevice & rDev,const Point & rLPos,const LineEndResult & rLRes,const Point & rRPos,const LineEndResult & rRRes,long nTOffs,long nBOffs,bool bDotted)879cdf0e10cSrcweir void lclDrawHorLine(
880cdf0e10cSrcweir         OutputDevice& rDev,
881cdf0e10cSrcweir         const Point& rLPos, const LineEndResult& rLRes,
882cdf0e10cSrcweir         const Point& rRPos, const LineEndResult& rRRes,
883cdf0e10cSrcweir         long nTOffs, long nBOffs, bool bDotted )
884cdf0e10cSrcweir {
885cdf0e10cSrcweir     LinePoints aTPoints( rLPos + lclToMapUnit( rLRes.mnOffs1, nTOffs ), rRPos + lclToMapUnit( rRRes.mnOffs1, nTOffs ) );
886cdf0e10cSrcweir     if( nTOffs == nBOffs )
887cdf0e10cSrcweir         lclDrawThinLine( rDev, aTPoints, bDotted );
888cdf0e10cSrcweir     else
889cdf0e10cSrcweir     {
890cdf0e10cSrcweir         LinePoints aBPoints( rLPos + lclToMapUnit( rLRes.mnOffs2, nBOffs ), rRPos + lclToMapUnit( rRRes.mnOffs2, nBOffs ) );
891cdf0e10cSrcweir         lclDrawPolygon( rDev, aTPoints, aBPoints );
892cdf0e10cSrcweir     }
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir /** Draws a horizontal frame border into the passed output device.
896cdf0e10cSrcweir 
897cdf0e10cSrcweir     @param rLPos
898cdf0e10cSrcweir         The top-left or bottom-left reference point of the diagonal frame border.
899cdf0e10cSrcweir     @param rRPos
900cdf0e10cSrcweir         The top-right or bottom-right reference point of the diagonal frame border.
901cdf0e10cSrcweir     @param rBorder
902cdf0e10cSrcweir         The frame style used to draw the border.
903cdf0e10cSrcweir     @param rResult
904cdf0e10cSrcweir         The X coordinates of the edges of all lines of the frame border are
905cdf0e10cSrcweir         adjusted according to the offsets contained here.
906cdf0e10cSrcweir  */
lclDrawHorFrameBorder(OutputDevice & rDev,const Point & rLPos,const Point & rRPos,const Style & rBorder,const BorderResult & rResult,const Color * pForceColor)907cdf0e10cSrcweir void lclDrawHorFrameBorder(
908cdf0e10cSrcweir         OutputDevice& rDev, const Point& rLPos, const Point& rRPos,
909cdf0e10cSrcweir         const Style& rBorder, const BorderResult& rResult, const Color* pForceColor )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir     DBG_ASSERT( rBorder.Prim(), "svx::frame::lclDrawHorFrameBorder - line not visible" );
912cdf0e10cSrcweir     DBG_ASSERT( rLPos.X() <= rRPos.X(), "svx::frame::lclDrawHorFrameBorder - wrong order of line ends" );
913cdf0e10cSrcweir     DBG_ASSERT( rLPos.Y() == rRPos.Y(), "svx::frame::lclDrawHorFrameBorder - line not horizontal" );
914cdf0e10cSrcweir     if( rLPos.X() <= rRPos.X() )
915cdf0e10cSrcweir     {
916cdf0e10cSrcweir         lclSetColorToOutDev( rDev, rBorder, pForceColor );
917cdf0e10cSrcweir         lclDrawHorLine( rDev, rLPos, rResult.maBeg.maPrim, rRPos, rResult.maEnd.maPrim,
918cdf0e10cSrcweir             lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Dotted() );
919cdf0e10cSrcweir         if( rBorder.Secn() )
920cdf0e10cSrcweir             lclDrawHorLine( rDev, rLPos, rResult.maBeg.maSecn, rRPos, rResult.maEnd.maSecn,
921cdf0e10cSrcweir                 lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Dotted() );
922cdf0e10cSrcweir         rDev.Pop(); // colors
923cdf0e10cSrcweir     }
924cdf0e10cSrcweir }
925cdf0e10cSrcweir 
926cdf0e10cSrcweir // ----------------------------------------------------------------------------
927cdf0e10cSrcweir // Drawing of vertical frame borders.
928cdf0e10cSrcweir 
929cdf0e10cSrcweir /** Draws a vertical thin or thick line into the passed output device.
930cdf0e10cSrcweir 
931cdf0e10cSrcweir     The Y coordinates of the edges of the line are adjusted according to the
932cdf0e10cSrcweir     passed LineEndResult structs. A one pixel wide line can be drawn dotted.
933cdf0e10cSrcweir  */
lclDrawVerLine(OutputDevice & rDev,const Point & rTPos,const LineEndResult & rTRes,const Point & rBPos,const LineEndResult & rBRes,long nLOffs,long nROffs,bool bDotted)934cdf0e10cSrcweir void lclDrawVerLine(
935cdf0e10cSrcweir         OutputDevice& rDev,
936cdf0e10cSrcweir         const Point& rTPos, const LineEndResult& rTRes,
937cdf0e10cSrcweir         const Point& rBPos, const LineEndResult& rBRes,
938cdf0e10cSrcweir         long nLOffs, long nROffs, bool bDotted )
939cdf0e10cSrcweir {
940cdf0e10cSrcweir     LinePoints aLPoints( rTPos + lclToMapUnit( nLOffs, rTRes.mnOffs1 ), rBPos + lclToMapUnit( nLOffs, rBRes.mnOffs1 ) );
941cdf0e10cSrcweir     if( nLOffs == nROffs )
942cdf0e10cSrcweir         lclDrawThinLine( rDev, aLPoints, bDotted );
943cdf0e10cSrcweir     else
944cdf0e10cSrcweir     {
945cdf0e10cSrcweir         LinePoints aRPoints( rTPos + lclToMapUnit( nROffs, rTRes.mnOffs2 ), rBPos + lclToMapUnit( nROffs, rBRes.mnOffs2 ) );
946cdf0e10cSrcweir         lclDrawPolygon( rDev, aLPoints, aRPoints );
947cdf0e10cSrcweir     }
948cdf0e10cSrcweir }
949cdf0e10cSrcweir 
950cdf0e10cSrcweir /** Draws a vertical frame border into the passed output device.
951cdf0e10cSrcweir 
952cdf0e10cSrcweir     @param rTPos
953cdf0e10cSrcweir         The top-left or top-right reference point of the diagonal frame border.
954cdf0e10cSrcweir     @param rBPos
955cdf0e10cSrcweir         The bottom-left or bottom-right reference point of the diagonal frame border.
956cdf0e10cSrcweir     @param rBorder
957cdf0e10cSrcweir         The frame style used to draw the border.
958cdf0e10cSrcweir     @param rResult
959cdf0e10cSrcweir         The Y coordinates of the edges of all lines of the frame border are
960cdf0e10cSrcweir         adjusted according to the offsets contained here.
961cdf0e10cSrcweir  */
lclDrawVerFrameBorder(OutputDevice & rDev,const Point & rTPos,const Point & rBPos,const Style & rBorder,const BorderResult & rResult,const Color * pForceColor)962cdf0e10cSrcweir void lclDrawVerFrameBorder(
963cdf0e10cSrcweir         OutputDevice& rDev, const Point& rTPos, const Point& rBPos,
964cdf0e10cSrcweir         const Style& rBorder, const BorderResult& rResult, const Color* pForceColor )
965cdf0e10cSrcweir {
966cdf0e10cSrcweir     DBG_ASSERT( rBorder.Prim(), "svx::frame::lclDrawVerFrameBorder - line not visible" );
967cdf0e10cSrcweir     DBG_ASSERT( rTPos.Y() <= rBPos.Y(), "svx::frame::lclDrawVerFrameBorder - wrong order of line ends" );
968cdf0e10cSrcweir     DBG_ASSERT( rTPos.X() == rBPos.X(), "svx::frame::lclDrawVerFrameBorder - line not vertical" );
969cdf0e10cSrcweir     if( rTPos.Y() <= rBPos.Y() )
970cdf0e10cSrcweir     {
971cdf0e10cSrcweir         lclSetColorToOutDev( rDev, rBorder, pForceColor );
972cdf0e10cSrcweir         lclDrawVerLine( rDev, rTPos, rResult.maBeg.maPrim, rBPos, rResult.maEnd.maPrim,
973cdf0e10cSrcweir             lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Dotted() );
974cdf0e10cSrcweir         if( rBorder.Secn() )
975cdf0e10cSrcweir             lclDrawVerLine( rDev, rTPos, rResult.maBeg.maSecn, rBPos, rResult.maEnd.maSecn,
976cdf0e10cSrcweir                 lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Dotted() );
977cdf0e10cSrcweir         rDev.Pop(); // colors
978cdf0e10cSrcweir     }
979cdf0e10cSrcweir }
980cdf0e10cSrcweir 
981cdf0e10cSrcweir // ============================================================================
982cdf0e10cSrcweir // Drawing of diagonal frame borders, incudes clipping functions.
983cdf0e10cSrcweir 
984cdf0e10cSrcweir /** Returns the drawing coordinates for a diagonal thin line.
985cdf0e10cSrcweir 
986cdf0e10cSrcweir     This function can be used for top-left to bottom-right and for bottom-left
987cdf0e10cSrcweir     to top-right lines.
988cdf0e10cSrcweir 
989cdf0e10cSrcweir     @param rRect
990cdf0e10cSrcweir         The reference rectangle of the diagonal frame border.
991cdf0e10cSrcweir     @param bTLBR
992cdf0e10cSrcweir         true = top-left to bottom-right; false = bottom-left to top-right.
993cdf0e10cSrcweir     @param nDiagOffs
994cdf0e10cSrcweir         Width offset (sub units) across the diagonal frame border.
995cdf0e10cSrcweir     @return
996cdf0e10cSrcweir         A struct containg start and end position of the diagonal line.
997cdf0e10cSrcweir  */
lclGetDiagLineEnds(const Rectangle & rRect,bool bTLBR,long nDiagOffs)998cdf0e10cSrcweir LinePoints lclGetDiagLineEnds( const Rectangle& rRect, bool bTLBR, long nDiagOffs )
999cdf0e10cSrcweir {
1000cdf0e10cSrcweir     LinePoints aPoints( rRect, bTLBR );
1001cdf0e10cSrcweir     bool bVert = rRect.GetWidth() < rRect.GetHeight();
1002cdf0e10cSrcweir     double fAngle = bVert ? GetVerDiagAngle( rRect ) : GetHorDiagAngle( rRect );
1003cdf0e10cSrcweir     // vertical top-left to bottom-right borders are handled mirrored
1004cdf0e10cSrcweir     if( bVert && bTLBR )
1005cdf0e10cSrcweir         nDiagOffs = -nDiagOffs;
1006cdf0e10cSrcweir     long nTOffs = bTLBR ? GetTLDiagOffset( 0, nDiagOffs, fAngle ) : GetTRDiagOffset( 0, nDiagOffs, fAngle );
1007cdf0e10cSrcweir     long nBOffs = bTLBR ? GetBRDiagOffset( 0, nDiagOffs, fAngle ) : GetBLDiagOffset( 0, nDiagOffs, fAngle );
1008cdf0e10cSrcweir     // vertical bottom-left to top-right borders are handled with exchanged end points
1009cdf0e10cSrcweir     if( bVert && !bTLBR )
1010cdf0e10cSrcweir         std::swap( nTOffs, nBOffs );
1011cdf0e10cSrcweir     (bVert ? aPoints.maBeg.Y() : aPoints.maBeg.X()) += lclToMapUnit( nTOffs );
1012cdf0e10cSrcweir     (bVert ? aPoints.maEnd.Y() : aPoints.maEnd.X()) += lclToMapUnit( nBOffs );
1013cdf0e10cSrcweir     return aPoints;
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir // ----------------------------------------------------------------------------
1017cdf0e10cSrcweir // Clipping functions for diagonal frame borders.
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir /** Limits the clipping region to the inner area of a rectange.
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir     Takes the values from the passed DiagLineResult struct into account. They
1022cdf0e10cSrcweir     may specify to not clip one or more borders of a rectangle.
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir     @param rDev
1025cdf0e10cSrcweir         The output device with the clipping region to be modified. The old
1026cdf0e10cSrcweir         clipping region is pushed onto the device's stack and can be restored
1027cdf0e10cSrcweir         with a call to OutputDevice::Pop(). Please take care about the correct
1028cdf0e10cSrcweir         calling order of Pop() if this function is used with other functions
1029cdf0e10cSrcweir         pushing something onto the stack.
1030cdf0e10cSrcweir     @param rRect
1031cdf0e10cSrcweir         The reference rectangle of the diagonal frame borders.
1032cdf0e10cSrcweir     @param rResult
1033cdf0e10cSrcweir         The result struct containing modifies for each border of the reference
1034cdf0e10cSrcweir         rectangle.
1035cdf0e10cSrcweir  */
lclPushDiagClipRect(OutputDevice & rDev,const Rectangle & rRect,const DiagLineResult & rResult)1036cdf0e10cSrcweir void lclPushDiagClipRect( OutputDevice& rDev, const Rectangle& rRect, const DiagLineResult& rResult )
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir     // PixelToLogic() regards internal offset of the output device
1039cdf0e10cSrcweir     Rectangle aClipRect( rRect );
1040cdf0e10cSrcweir     aClipRect.Left()   += lclToMapUnit( rResult.mnLClip );
1041cdf0e10cSrcweir     aClipRect.Top()    += lclToMapUnit( rResult.mnTClip );
1042cdf0e10cSrcweir     aClipRect.Right()  += lclToMapUnit( rResult.mnRClip );
1043cdf0e10cSrcweir     aClipRect.Bottom() += lclToMapUnit( rResult.mnBClip );
1044cdf0e10cSrcweir     // output device would adjust the rectangle -> invalidate it before
1045cdf0e10cSrcweir     if( (aClipRect.GetWidth() < 1) ||(aClipRect.GetHeight() < 1) )
1046cdf0e10cSrcweir         aClipRect.SetEmpty();
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir     rDev.Push( PUSH_CLIPREGION );
1049cdf0e10cSrcweir     rDev.IntersectClipRegion( aClipRect );
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir /** Excludes inner area of a crossing double frame border from clipping region.
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir     This function is used to modify the clipping region so that it excludes the
1055cdf0e10cSrcweir     inner free area of a double diagonal frame border. This makes it possible
1056cdf0e10cSrcweir     to draw a diagonal frame border in one step without taking care of the
1057cdf0e10cSrcweir     crossing double frame border.
1058cdf0e10cSrcweir 
1059cdf0e10cSrcweir     @param rDev
1060cdf0e10cSrcweir         The output device with the clipping region to be modified. The old
1061cdf0e10cSrcweir         clipping region is pushed onto the device's stack and can be restored
1062cdf0e10cSrcweir         with a call to OutputDevice::Pop(). Please take care about the correct
1063cdf0e10cSrcweir         calling order of Pop() if this function is used with other functions
1064cdf0e10cSrcweir         pushing something onto the stack.
1065cdf0e10cSrcweir     @param rRect
1066cdf0e10cSrcweir         The reference rectangle of the diagonal frame borders.
1067cdf0e10cSrcweir     @param bTLBR
1068cdf0e10cSrcweir         The orientation of the processed frame border (not the orientation of
1069cdf0e10cSrcweir         the crossing frame border).
1070cdf0e10cSrcweir     @param bCrossStyle
1071cdf0e10cSrcweir         The style of the crossing frame border. Must be a double frame style.
1072cdf0e10cSrcweir  */
lclPushCrossingClipRegion(OutputDevice & rDev,const Rectangle & rRect,bool bTLBR,const Style & rCrossStyle)1073cdf0e10cSrcweir void lclPushCrossingClipRegion( OutputDevice& rDev, const Rectangle& rRect, bool bTLBR, const Style& rCrossStyle )
1074cdf0e10cSrcweir {
1075cdf0e10cSrcweir     DBG_ASSERT( rCrossStyle.Secn(), "lclGetCrossingClipRegion - use only for double styles" );
1076cdf0e10cSrcweir     LinePoints aLPoints( lclGetDiagLineEnds( rRect, !bTLBR, lclGetPrimEnd( rCrossStyle ) ) );
1077cdf0e10cSrcweir     LinePoints aRPoints( lclGetDiagLineEnds( rRect, !bTLBR, lclGetSecnBeg( rCrossStyle ) ) );
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir     Region aClipReg;
1080cdf0e10cSrcweir     if( bTLBR )
1081cdf0e10cSrcweir     {
1082cdf0e10cSrcweir         aClipReg = lclCreatePolygon(
1083cdf0e10cSrcweir             aLPoints.maBeg, aLPoints.maEnd, rRect.BottomRight(), rRect.BottomLeft(), rRect.TopLeft() );
1084cdf0e10cSrcweir         aClipReg.Union( lclCreatePolygon(
1085cdf0e10cSrcweir             aRPoints.maBeg, aRPoints.maEnd, rRect.BottomRight(), rRect.TopRight(), rRect.TopLeft() ) );
1086cdf0e10cSrcweir     }
1087cdf0e10cSrcweir     else
1088cdf0e10cSrcweir     {
1089cdf0e10cSrcweir         aClipReg = lclCreatePolygon(
1090cdf0e10cSrcweir             aLPoints.maBeg, aLPoints.maEnd, rRect.BottomLeft(), rRect.TopLeft(), rRect.TopRight() );
1091cdf0e10cSrcweir         aClipReg.Union( lclCreatePolygon(
1092cdf0e10cSrcweir             aRPoints.maBeg, aRPoints.maEnd, rRect.BottomLeft(), rRect.BottomRight(), rRect.TopRight() ) );
1093cdf0e10cSrcweir     }
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir     rDev.Push( PUSH_CLIPREGION );
1096cdf0e10cSrcweir     rDev.IntersectClipRegion( aClipReg );
1097cdf0e10cSrcweir }
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir // ----------------------------------------------------------------------------
1100cdf0e10cSrcweir // Drawing functions for diagonal frame borders.
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir /** Draws a diagonal thin or thick line into the passed output device.
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir     The clipping region of the output device is modified according to the
1105cdf0e10cSrcweir     passed DiagLineResult struct. A one pixel wide line can be drawn dotted.
1106cdf0e10cSrcweir  */
lclDrawDiagLine(OutputDevice & rDev,const Rectangle & rRect,bool bTLBR,const DiagLineResult & rResult,long nDiagOffs1,long nDiagOffs2,bool bDotted)1107cdf0e10cSrcweir void lclDrawDiagLine(
1108cdf0e10cSrcweir         OutputDevice& rDev, const Rectangle& rRect, bool bTLBR,
1109cdf0e10cSrcweir         const DiagLineResult& rResult, long nDiagOffs1, long nDiagOffs2, bool bDotted )
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir     lclPushDiagClipRect( rDev, rRect, rResult );
1112cdf0e10cSrcweir     LinePoints aLPoints( lclGetDiagLineEnds( rRect, bTLBR, nDiagOffs1 ) );
1113cdf0e10cSrcweir     if( nDiagOffs1 == nDiagOffs2 )
1114cdf0e10cSrcweir         lclDrawThinLine( rDev, aLPoints, bDotted );
1115cdf0e10cSrcweir     else
1116cdf0e10cSrcweir         lclDrawPolygon( rDev, aLPoints, lclGetDiagLineEnds( rRect, bTLBR, nDiagOffs2 ) );
1117cdf0e10cSrcweir     rDev.Pop(); // clipping region
1118cdf0e10cSrcweir }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir /** Draws a diagonal frame border into the passed output device.
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir     The lines of the frame border are drawn interrupted, if the style of the
1123cdf0e10cSrcweir     crossing frame border is double.
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir     @param rRect
1126cdf0e10cSrcweir         The reference rectangle of the diagonal frame border.
1127cdf0e10cSrcweir     @param bTLBR
1128cdf0e10cSrcweir         The orientation of the diagonal frame border.
1129cdf0e10cSrcweir     @param rBorder
1130cdf0e10cSrcweir         The frame style used to draw the border.
1131cdf0e10cSrcweir     @param rResult
1132cdf0e10cSrcweir         Offsets (sub units) to modify the clipping region of the output device.
1133cdf0e10cSrcweir     @param rCrossStyle
1134cdf0e10cSrcweir         Style of the crossing diagonal frame border.
1135cdf0e10cSrcweir  */
lclDrawDiagFrameBorder(OutputDevice & rDev,const Rectangle & rRect,bool bTLBR,const Style & rBorder,const DiagBorderResult & rResult,const Style & rCrossStyle,const Color * pForceColor,bool bDiagDblClip)1136cdf0e10cSrcweir void lclDrawDiagFrameBorder(
1137cdf0e10cSrcweir         OutputDevice& rDev, const Rectangle& rRect, bool bTLBR,
1138cdf0e10cSrcweir         const Style& rBorder, const DiagBorderResult& rResult, const Style& rCrossStyle,
1139cdf0e10cSrcweir         const Color* pForceColor, bool bDiagDblClip )
1140cdf0e10cSrcweir {
1141cdf0e10cSrcweir     DBG_ASSERT( rBorder.Prim(), "svx::frame::lclDrawDiagFrameBorder - line not visible" );
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir     bool bClip = bDiagDblClip && rCrossStyle.Secn();
1144cdf0e10cSrcweir     if( bClip )
1145cdf0e10cSrcweir         lclPushCrossingClipRegion( rDev, rRect, bTLBR, rCrossStyle );
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir     lclSetColorToOutDev( rDev, rBorder, pForceColor );
1148cdf0e10cSrcweir     lclDrawDiagLine( rDev, rRect, bTLBR, rResult.maPrim, lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Dotted() );
1149cdf0e10cSrcweir     if( rBorder.Secn() )
1150cdf0e10cSrcweir         lclDrawDiagLine( rDev, rRect, bTLBR, rResult.maSecn, lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Dotted() );
1151cdf0e10cSrcweir     rDev.Pop(); // colors
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir     if( bClip )
1154cdf0e10cSrcweir         rDev.Pop(); // clipping region
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir /** Draws both diagonal frame borders into the passed output device.
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir     The lines of each frame border is drawn interrupted, if the style of the
1160cdf0e10cSrcweir     other crossing frame border is double.
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     @param rRect
1163cdf0e10cSrcweir         The reference rectangle of the diagonal frame borders.
1164cdf0e10cSrcweir     @param rTLBR
1165cdf0e10cSrcweir         The frame style of the top-left to bottom-right frame border.
1166cdf0e10cSrcweir     @param rBLTR
1167cdf0e10cSrcweir         The frame style of the bottom-left to top-right frame border.
1168cdf0e10cSrcweir     @param rResult
1169cdf0e10cSrcweir         Offsets (sub units) to modify the clipping region of the output device.
1170cdf0e10cSrcweir  */
lclDrawDiagFrameBorders(OutputDevice & rDev,const Rectangle & rRect,const Style & rTLBR,const Style & rBLTR,const DiagBordersResult & rResult,const Color * pForceColor,bool bDiagDblClip)1171cdf0e10cSrcweir void lclDrawDiagFrameBorders(
1172cdf0e10cSrcweir         OutputDevice& rDev, const Rectangle& rRect,
1173cdf0e10cSrcweir         const Style& rTLBR, const Style& rBLTR, const DiagBordersResult& rResult,
1174cdf0e10cSrcweir         const Color* pForceColor, bool bDiagDblClip )
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir     DBG_ASSERT( (rRect.GetWidth() > 1) && (rRect.GetHeight() > 1), "svx::frame::lclDrawDiagFrameBorders - rectangle too small" );
1177cdf0e10cSrcweir     if( (rRect.GetWidth() > 1) && (rRect.GetHeight() > 1) )
1178cdf0e10cSrcweir     {
1179cdf0e10cSrcweir         bool bDrawTLBR = rTLBR.Prim() != 0;
1180cdf0e10cSrcweir         bool bDrawBLTR = rBLTR.Prim() != 0;
1181cdf0e10cSrcweir         bool bFirstDrawBLTR = rTLBR.Secn() != 0;
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir         if( bDrawBLTR && bFirstDrawBLTR )
1184cdf0e10cSrcweir             lclDrawDiagFrameBorder( rDev, rRect, false, rBLTR, rResult.maBLTR, rTLBR, pForceColor, bDiagDblClip );
1185cdf0e10cSrcweir         if( bDrawTLBR )
1186cdf0e10cSrcweir             lclDrawDiagFrameBorder( rDev, rRect, true, rTLBR, rResult.maTLBR, rBLTR, pForceColor, bDiagDblClip );
1187cdf0e10cSrcweir         if( bDrawBLTR && !bFirstDrawBLTR )
1188cdf0e10cSrcweir             lclDrawDiagFrameBorder( rDev, rRect, false, rBLTR, rResult.maBLTR, rTLBR, pForceColor, bDiagDblClip );
1189cdf0e10cSrcweir     }
1190cdf0e10cSrcweir }
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir // ============================================================================
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir } // namespace
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir // ============================================================================
1197cdf0e10cSrcweir // Classes
1198cdf0e10cSrcweir // ============================================================================
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir #define SCALEVALUE( value ) lclScaleValue( value, fScale, nMaxWidth )
1201cdf0e10cSrcweir 
Clear()1202cdf0e10cSrcweir void Style::Clear()
1203cdf0e10cSrcweir {
1204cdf0e10cSrcweir     Set( Color(), 0, 0, 0 );
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir 
Set(sal_uInt16 nP,sal_uInt16 nD,sal_uInt16 nS)1207cdf0e10cSrcweir void Style::Set( sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS )
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir     /*  nP  nD  nS  ->  mnPrim  mnDist  mnSecn
1210cdf0e10cSrcweir         --------------------------------------
1211cdf0e10cSrcweir         any any 0       nP      0       0
1212cdf0e10cSrcweir         0   any >0      nS      0       0
1213cdf0e10cSrcweir         >0  0   >0      nP      0       0
1214cdf0e10cSrcweir         >0  >0  >0      nP      nD      nS
1215cdf0e10cSrcweir      */
1216cdf0e10cSrcweir     mnPrim = nP ? nP : nS;
1217cdf0e10cSrcweir     mnDist = (nP && nS) ? nD : 0;
1218cdf0e10cSrcweir     mnSecn = (nP && nD) ? nS : 0;
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir 
Set(const Color & rColor,sal_uInt16 nP,sal_uInt16 nD,sal_uInt16 nS)1221cdf0e10cSrcweir void Style::Set( const Color& rColor, sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS )
1222cdf0e10cSrcweir {
1223cdf0e10cSrcweir     maColor = rColor;
1224cdf0e10cSrcweir     Set( nP, nD, nS );
1225cdf0e10cSrcweir }
1226cdf0e10cSrcweir 
Set(const SvxBorderLine & rBorder,double fScale,sal_uInt16 nMaxWidth,bool bUseDots)1227cdf0e10cSrcweir void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWidth, bool bUseDots )
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir     maColor = rBorder.GetColor();
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir     sal_uInt16 nPrim = rBorder.GetOutWidth();
1232cdf0e10cSrcweir     sal_uInt16 nDist = rBorder.GetDistance();
1233cdf0e10cSrcweir     sal_uInt16 nSecn = rBorder.GetInWidth();
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir     if( !nSecn )    // no or single frame border
1236cdf0e10cSrcweir     {
1237cdf0e10cSrcweir         Set( SCALEVALUE( nPrim ), 0, 0 );
1238cdf0e10cSrcweir         mbDotted = bUseDots && (0 < nPrim) && (nPrim < 10);
1239cdf0e10cSrcweir     }
1240cdf0e10cSrcweir     else
1241cdf0e10cSrcweir     {
1242cdf0e10cSrcweir         Set( SCALEVALUE( nPrim ), SCALEVALUE( nDist ), SCALEVALUE( nSecn ) );
1243cdf0e10cSrcweir         mbDotted = false;
1244cdf0e10cSrcweir         // Enlarge the style if distance is too small due to rounding losses.
1245cdf0e10cSrcweir         sal_uInt16 nPixWidth = SCALEVALUE( nPrim + nDist + nSecn );
1246cdf0e10cSrcweir         if( nPixWidth > GetWidth() )
1247cdf0e10cSrcweir             mnDist = nPixWidth - mnPrim - mnSecn;
1248cdf0e10cSrcweir         // Shrink the style if it is too thick for the control.
1249cdf0e10cSrcweir         while( GetWidth() > nMaxWidth )
1250cdf0e10cSrcweir         {
1251cdf0e10cSrcweir             // First decrease space between lines.
1252cdf0e10cSrcweir             if( mnDist )
1253cdf0e10cSrcweir                 --mnDist;
1254cdf0e10cSrcweir             // Still too thick? Decrease the line widths.
1255cdf0e10cSrcweir             if( GetWidth() > nMaxWidth )
1256cdf0e10cSrcweir             {
1257cdf0e10cSrcweir                 if( mnPrim && (mnPrim == mnSecn) )
1258cdf0e10cSrcweir                 {
1259cdf0e10cSrcweir                     // Both lines equal - decrease both to keep symmetry.
1260cdf0e10cSrcweir                     --mnPrim;
1261cdf0e10cSrcweir                     --mnSecn;
1262cdf0e10cSrcweir                 }
1263cdf0e10cSrcweir                 else
1264cdf0e10cSrcweir                 {
1265cdf0e10cSrcweir                     // Decrease each line for itself
1266cdf0e10cSrcweir                     if( mnPrim )
1267cdf0e10cSrcweir                         --mnPrim;
1268cdf0e10cSrcweir                     if( (GetWidth() > nMaxWidth) && mnSecn )
1269cdf0e10cSrcweir                         --mnSecn;
1270cdf0e10cSrcweir                 }
1271cdf0e10cSrcweir             }
1272cdf0e10cSrcweir         }
1273cdf0e10cSrcweir     }
1274cdf0e10cSrcweir }
1275cdf0e10cSrcweir 
Set(const SvxBorderLine * pBorder,double fScale,sal_uInt16 nMaxWidth,bool bUseDots)1276cdf0e10cSrcweir void Style::Set( const SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth, bool bUseDots )
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir     if( pBorder )
1279cdf0e10cSrcweir         Set( *pBorder, fScale, nMaxWidth, bUseDots );
1280cdf0e10cSrcweir     else
1281cdf0e10cSrcweir     {
1282cdf0e10cSrcweir         Clear();
1283cdf0e10cSrcweir         mbDotted = false;
1284cdf0e10cSrcweir     }
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir 
ScaleSelf(double fScale,sal_uInt16 nMaxWidth)1287cdf0e10cSrcweir Style& Style::ScaleSelf( double fScale, sal_uInt16 nMaxWidth )
1288cdf0e10cSrcweir {
1289cdf0e10cSrcweir     Set( SCALEVALUE( mnPrim ), SCALEVALUE( mnDist ), SCALEVALUE( mnSecn ) );
1290cdf0e10cSrcweir     return *this;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir 
Scale(double fScale,sal_uInt16 nMaxWidth) const1293cdf0e10cSrcweir Style Style::Scale( double fScale, sal_uInt16 nMaxWidth ) const
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir     return Style( *this ).ScaleSelf( fScale, nMaxWidth );
1296cdf0e10cSrcweir }
1297cdf0e10cSrcweir 
MirrorSelf()1298cdf0e10cSrcweir Style& Style::MirrorSelf()
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir     if( mnSecn )
1301cdf0e10cSrcweir         std::swap( mnPrim, mnSecn );
1302cdf0e10cSrcweir     if( meRefMode != REFMODE_CENTERED )
1303cdf0e10cSrcweir         meRefMode = (meRefMode == REFMODE_BEGIN) ? REFMODE_END : REFMODE_BEGIN;
1304cdf0e10cSrcweir     return *this;
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir 
Mirror() const1307cdf0e10cSrcweir Style Style::Mirror() const
1308cdf0e10cSrcweir {
1309cdf0e10cSrcweir     return Style( *this ).MirrorSelf();
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir 
operator ==(const Style & rL,const Style & rR)1312cdf0e10cSrcweir bool operator==( const Style& rL, const Style& rR )
1313cdf0e10cSrcweir {
1314cdf0e10cSrcweir     return (rL.Prim() == rR.Prim()) && (rL.Dist() == rR.Dist()) && (rL.Secn() == rR.Secn()) &&
1315cdf0e10cSrcweir         (rL.GetColor() == rR.GetColor()) && (rL.GetRefMode() == rR.GetRefMode()) && (rL.Dotted() == rR.Dotted());
1316cdf0e10cSrcweir }
1317cdf0e10cSrcweir 
operator <(const Style & rL,const Style & rR)1318cdf0e10cSrcweir bool operator<( const Style& rL, const Style& rR )
1319cdf0e10cSrcweir {
1320cdf0e10cSrcweir     // different total widths -> rL<rR, if rL is thinner
1321cdf0e10cSrcweir     sal_uInt16 nLW = rL.GetWidth();
1322cdf0e10cSrcweir     sal_uInt16 nRW = rR.GetWidth();
1323cdf0e10cSrcweir     if( nLW != nRW ) return nLW < nRW;
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir     // one line double, the other single -> rL<rR, if rL is single
1326cdf0e10cSrcweir     if( (rL.Secn() == 0) != (rR.Secn() == 0) ) return rL.Secn() == 0;
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir     // both lines double with different distances -> rL<rR, if distance of rL greater
1329cdf0e10cSrcweir     if( (rL.Secn() && rR.Secn()) && (rL.Dist() != rR.Dist()) ) return rL.Dist() > rR.Dist();
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir     // both lines single and 1 unit thick, only one is dotted -> rL<rR, if rL is dotted
1332cdf0e10cSrcweir     if( (nLW == 1) && (rL.Dotted() != rR.Dotted()) ) return rL.Dotted();
1333cdf0e10cSrcweir 
1334cdf0e10cSrcweir     // seem to be equal
1335cdf0e10cSrcweir     return false;
1336cdf0e10cSrcweir }
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir #undef SCALEVALUE
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir // ============================================================================
1341cdf0e10cSrcweir // Various helper functions
1342cdf0e10cSrcweir // ============================================================================
1343cdf0e10cSrcweir 
GetHorDiagAngle(long nWidth,long nHeight)1344cdf0e10cSrcweir double GetHorDiagAngle( long nWidth, long nHeight )
1345cdf0e10cSrcweir {
1346cdf0e10cSrcweir     return atan2( static_cast< double >( Abs( nHeight ) ), static_cast< double >( Abs( nWidth ) ) );
1347cdf0e10cSrcweir }
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir // ============================================================================
1350cdf0e10cSrcweir 
GetTLDiagOffset(long nVerOffs,long nDiagOffs,double fAngle)1351cdf0e10cSrcweir long GetTLDiagOffset( long nVerOffs, long nDiagOffs, double fAngle )
1352cdf0e10cSrcweir {
1353cdf0e10cSrcweir     return lclD2L( nVerOffs / tan( fAngle ) + nDiagOffs / sin( fAngle ) );
1354cdf0e10cSrcweir }
1355cdf0e10cSrcweir 
GetBLDiagOffset(long nVerOffs,long nDiagOffs,double fAngle)1356cdf0e10cSrcweir long GetBLDiagOffset( long nVerOffs, long nDiagOffs, double fAngle )
1357cdf0e10cSrcweir {
1358cdf0e10cSrcweir     return lclD2L( -nVerOffs / tan( fAngle ) + nDiagOffs / sin( fAngle ) );
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir 
GetBRDiagOffset(long nVerOffs,long nDiagOffs,double fAngle)1361cdf0e10cSrcweir long GetBRDiagOffset( long nVerOffs, long nDiagOffs, double fAngle )
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir     return -lclD2L( -nVerOffs / tan( fAngle ) - nDiagOffs / sin( fAngle ) );
1364cdf0e10cSrcweir }
1365cdf0e10cSrcweir 
GetTRDiagOffset(long nVerOffs,long nDiagOffs,double fAngle)1366cdf0e10cSrcweir long GetTRDiagOffset( long nVerOffs, long nDiagOffs, double fAngle )
1367cdf0e10cSrcweir {
1368cdf0e10cSrcweir     return -lclD2L( nVerOffs / tan( fAngle ) - nDiagOffs / sin( fAngle ) );
1369cdf0e10cSrcweir }
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir // ============================================================================
1372cdf0e10cSrcweir 
CheckFrameBorderConnectable(const Style & rLBorder,const Style & rRBorder,const Style & rTFromTL,const Style & rTFromT,const Style & rTFromTR,const Style & rBFromBL,const Style & rBFromB,const Style & rBFromBR)1373cdf0e10cSrcweir bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
1374cdf0e10cSrcweir         const Style& rTFromTL, const Style& rTFromT, const Style& rTFromTR,
1375cdf0e10cSrcweir         const Style& rBFromBL, const Style& rBFromB, const Style& rBFromBR )
1376cdf0e10cSrcweir {
1377cdf0e10cSrcweir     return      // returns 1 AND (2a OR 2b)
1378cdf0e10cSrcweir         // 1) only, if both frame borders are equal
1379cdf0e10cSrcweir         (rLBorder == rRBorder)
1380cdf0e10cSrcweir         &&
1381cdf0e10cSrcweir         (
1382cdf0e10cSrcweir             (
1383cdf0e10cSrcweir                 // 2a) if the borders are not double, at least one of the vertical must not be double
1384cdf0e10cSrcweir                 !rLBorder.Secn() && (!rTFromT.Secn() || !rBFromB.Secn())
1385cdf0e10cSrcweir             )
1386cdf0e10cSrcweir             ||
1387cdf0e10cSrcweir             (
1388cdf0e10cSrcweir                 // 2b) if the borders are double, all other borders must not be double
1389cdf0e10cSrcweir                 rLBorder.Secn() &&
1390cdf0e10cSrcweir                 !rTFromTL.Secn() && !rTFromT.Secn() && !rTFromTR.Secn() &&
1391cdf0e10cSrcweir                 !rBFromBL.Secn() && !rBFromB.Secn() && !rBFromBR.Secn()
1392cdf0e10cSrcweir             )
1393cdf0e10cSrcweir         );
1394cdf0e10cSrcweir }
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir // ============================================================================
1397cdf0e10cSrcweir // Drawing functions
1398cdf0e10cSrcweir // ============================================================================
1399cdf0e10cSrcweir 
DrawHorFrameBorder(OutputDevice & rDev,const Point & rLPos,const Point & rRPos,const Style & rBorder,const DiagStyle & rLFromTR,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const DiagStyle & rLFromBR,const DiagStyle & rRFromTL,const Style & rRFromT,const Style & rRFromR,const Style & rRFromB,const DiagStyle & rRFromBL,const Color * pForceColor)1400cdf0e10cSrcweir void DrawHorFrameBorder( OutputDevice& rDev,
1401cdf0e10cSrcweir         const Point& rLPos, const Point& rRPos, const Style& rBorder,
1402cdf0e10cSrcweir         const DiagStyle& rLFromTR, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& rLFromBR,
1403cdf0e10cSrcweir         const DiagStyle& rRFromTL, const Style& rRFromT, const Style& rRFromR, const Style& rRFromB, const DiagStyle& rRFromBL,
1404cdf0e10cSrcweir         const Color* pForceColor )
1405cdf0e10cSrcweir {
1406cdf0e10cSrcweir     if( rBorder.Prim() )
1407cdf0e10cSrcweir     {
1408cdf0e10cSrcweir         BorderResult aResult;
1409cdf0e10cSrcweir         lclLinkHorFrameBorder( aResult, rBorder,
1410cdf0e10cSrcweir             rLFromTR, rLFromT, rLFromL, rLFromB, rLFromBR,
1411cdf0e10cSrcweir             rRFromTL, rRFromT, rRFromR, rRFromB, rRFromBL );
1412cdf0e10cSrcweir         lclDrawHorFrameBorder( rDev, rLPos, rRPos, rBorder, aResult, pForceColor );
1413cdf0e10cSrcweir     }
1414cdf0e10cSrcweir }
1415cdf0e10cSrcweir 
DrawHorFrameBorder(OutputDevice & rDev,const Point & rLPos,const Point & rRPos,const Style & rBorder,const Style & rLFromT,const Style & rLFromL,const Style & rLFromB,const Style & rRFromT,const Style & rRFromR,const Style & rRFromB,const Color * pForceColor)1416cdf0e10cSrcweir void DrawHorFrameBorder( OutputDevice& rDev,
1417cdf0e10cSrcweir         const Point& rLPos, const Point& rRPos, const Style& rBorder,
1418cdf0e10cSrcweir         const Style& rLFromT, const Style& rLFromL, const Style& rLFromB,
1419cdf0e10cSrcweir         const Style& rRFromT, const Style& rRFromR, const Style& rRFromB,
1420cdf0e10cSrcweir         const Color* pForceColor )
1421cdf0e10cSrcweir {
1422cdf0e10cSrcweir     /*  Recycle complex version of the DrawHorFrameBorder() function with empty diagonals. */
1423cdf0e10cSrcweir     const DiagStyle aNoStyle;
1424cdf0e10cSrcweir     DrawHorFrameBorder(
1425cdf0e10cSrcweir         rDev, rLPos, rRPos, rBorder,
1426cdf0e10cSrcweir         aNoStyle, rLFromT, rLFromL, rLFromB, aNoStyle,
1427cdf0e10cSrcweir         aNoStyle, rRFromT, rRFromR, rRFromB, aNoStyle,
1428cdf0e10cSrcweir         pForceColor );
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir 
DrawHorFrameBorder(OutputDevice & rDev,const Point & rLPos,const Point & rRPos,const Style & rBorder,const Color * pForceColor)1431cdf0e10cSrcweir void DrawHorFrameBorder( OutputDevice& rDev,
1432cdf0e10cSrcweir         const Point& rLPos, const Point& rRPos, const Style& rBorder, const Color* pForceColor )
1433cdf0e10cSrcweir {
1434cdf0e10cSrcweir     if( rBorder.Prim() )
1435cdf0e10cSrcweir         lclDrawHorFrameBorder( rDev, rLPos, rRPos, rBorder, BorderResult(), pForceColor );
1436cdf0e10cSrcweir }
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir // ----------------------------------------------------------------------------
1439cdf0e10cSrcweir 
DrawVerFrameBorder(OutputDevice & rDev,const Point & rTPos,const Point & rBPos,const Style & rBorder,const DiagStyle & rTFromBL,const Style & rTFromL,const Style & rTFromT,const Style & rTFromR,const DiagStyle & rTFromBR,const DiagStyle & rBFromTL,const Style & rBFromL,const Style & rBFromB,const Style & rBFromR,const DiagStyle & rBFromTR,const Color * pForceColor)1440cdf0e10cSrcweir void DrawVerFrameBorder( OutputDevice& rDev,
1441cdf0e10cSrcweir         const Point& rTPos, const Point& rBPos, const Style& rBorder,
1442cdf0e10cSrcweir         const DiagStyle& rTFromBL, const Style& rTFromL, const Style& rTFromT, const Style& rTFromR, const DiagStyle& rTFromBR,
1443cdf0e10cSrcweir         const DiagStyle& rBFromTL, const Style& rBFromL, const Style& rBFromB, const Style& rBFromR, const DiagStyle& rBFromTR,
1444cdf0e10cSrcweir         const Color* pForceColor )
1445cdf0e10cSrcweir {
1446cdf0e10cSrcweir     if( rBorder.Prim() )
1447cdf0e10cSrcweir     {
1448cdf0e10cSrcweir         BorderResult aResult;
1449cdf0e10cSrcweir         lclLinkVerFrameBorder( aResult, rBorder,
1450cdf0e10cSrcweir             rTFromBL, rTFromL, rTFromT, rTFromR, rTFromBR,
1451cdf0e10cSrcweir             rBFromTL, rBFromL, rBFromB, rBFromR, rBFromTR );
1452cdf0e10cSrcweir         lclDrawVerFrameBorder( rDev, rTPos, rBPos, rBorder, aResult, pForceColor );
1453cdf0e10cSrcweir     }
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir 
DrawVerFrameBorder(OutputDevice & rDev,const Point & rTPos,const Point & rBPos,const Style & rBorder,const Style & rTFromL,const Style & rTFromT,const Style & rTFromR,const Style & rBFromL,const Style & rBFromB,const Style & rBFromR,const Color * pForceColor)1456cdf0e10cSrcweir void DrawVerFrameBorder( OutputDevice& rDev,
1457cdf0e10cSrcweir         const Point& rTPos, const Point& rBPos, const Style& rBorder,
1458cdf0e10cSrcweir         const Style& rTFromL, const Style& rTFromT, const Style& rTFromR,
1459cdf0e10cSrcweir         const Style& rBFromL, const Style& rBFromB, const Style& rBFromR,
1460cdf0e10cSrcweir         const Color* pForceColor )
1461cdf0e10cSrcweir {
1462cdf0e10cSrcweir     /*  Recycle complex version of the DrawVerFrameBorder() function with empty diagonals. */
1463cdf0e10cSrcweir     const DiagStyle aNoStyle;
1464cdf0e10cSrcweir     DrawVerFrameBorder(
1465cdf0e10cSrcweir         rDev, rTPos, rBPos, rBorder,
1466cdf0e10cSrcweir         aNoStyle, rTFromL, rTFromT, rTFromR, aNoStyle,
1467cdf0e10cSrcweir         aNoStyle, rBFromL, rBFromB, rBFromR, aNoStyle,
1468cdf0e10cSrcweir         pForceColor );
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir 
DrawVerFrameBorder(OutputDevice & rDev,const Point & rTPos,const Point & rBPos,const Style & rBorder,const Color * pForceColor)1471cdf0e10cSrcweir void DrawVerFrameBorder( OutputDevice& rDev,
1472cdf0e10cSrcweir         const Point& rTPos, const Point& rBPos, const Style& rBorder, const Color* pForceColor )
1473cdf0e10cSrcweir {
1474cdf0e10cSrcweir     if( rBorder.Prim() )
1475cdf0e10cSrcweir         lclDrawVerFrameBorder( rDev, rTPos, rBPos, rBorder, BorderResult(), pForceColor );
1476cdf0e10cSrcweir }
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir // ----------------------------------------------------------------------------
1479cdf0e10cSrcweir 
DrawVerFrameBorderSlanted(OutputDevice & rDev,const Point & rTPos,const Point & rBPos,const Style & rBorder,const Color * pForceColor)1480cdf0e10cSrcweir void DrawVerFrameBorderSlanted( OutputDevice& rDev,
1481cdf0e10cSrcweir         const Point& rTPos, const Point& rBPos, const Style& rBorder, const Color* pForceColor )
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir     DBG_ASSERT( rTPos.Y() < rBPos.Y(), "svx::frame::DrawVerFrameBorderSlanted - wrong order of line ends" );
1484cdf0e10cSrcweir     if( rBorder.Prim() && (rTPos.Y() < rBPos.Y()) )
1485cdf0e10cSrcweir     {
1486cdf0e10cSrcweir         if( rTPos.X() == rBPos.X() )
1487cdf0e10cSrcweir         {
1488cdf0e10cSrcweir             DrawVerFrameBorder( rDev, rTPos, rBPos, rBorder, pForceColor );
1489cdf0e10cSrcweir         }
1490cdf0e10cSrcweir         else
1491cdf0e10cSrcweir         {
1492cdf0e10cSrcweir             const LineEndResult aRes;
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir             Style aScaled( rBorder );
1495cdf0e10cSrcweir             aScaled.ScaleSelf( 1.0 / cos( GetVerDiagAngle( rTPos, rBPos ) ) );
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir             lclSetColorToOutDev( rDev, aScaled, pForceColor );
1498cdf0e10cSrcweir             lclDrawVerLine( rDev, rTPos, aRes, rBPos, aRes,
1499cdf0e10cSrcweir                 lclGetBeg( aScaled ), lclGetPrimEnd( aScaled ), aScaled.Dotted() );
1500cdf0e10cSrcweir             if( aScaled.Secn() )
1501cdf0e10cSrcweir                 lclDrawVerLine( rDev, rTPos, aRes, rBPos, aRes,
1502cdf0e10cSrcweir                     lclGetSecnBeg( aScaled ), lclGetEnd( aScaled ), aScaled.Dotted() );
1503cdf0e10cSrcweir             rDev.Pop(); // colors
1504cdf0e10cSrcweir         }
1505cdf0e10cSrcweir     }
1506cdf0e10cSrcweir }
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir // ============================================================================
1509cdf0e10cSrcweir 
DrawDiagFrameBorders(OutputDevice & rDev,const Rectangle & rRect,const Style & rTLBR,const Style & rBLTR,const Style & rTLFromB,const Style & rTLFromR,const Style & rBRFromT,const Style & rBRFromL,const Style & rBLFromT,const Style & rBLFromR,const Style & rTRFromB,const Style & rTRFromL,const Color * pForceColor,bool bDiagDblClip)1510cdf0e10cSrcweir void DrawDiagFrameBorders(
1511cdf0e10cSrcweir         OutputDevice& rDev, const Rectangle& rRect, const Style& rTLBR, const Style& rBLTR,
1512cdf0e10cSrcweir         const Style& rTLFromB, const Style& rTLFromR, const Style& rBRFromT, const Style& rBRFromL,
1513cdf0e10cSrcweir         const Style& rBLFromT, const Style& rBLFromR, const Style& rTRFromB, const Style& rTRFromL,
1514cdf0e10cSrcweir         const Color* pForceColor, bool bDiagDblClip )
1515cdf0e10cSrcweir {
1516cdf0e10cSrcweir     if( rTLBR.Prim() || rBLTR.Prim() )
1517cdf0e10cSrcweir     {
1518cdf0e10cSrcweir         DiagBordersResult aResult;
1519cdf0e10cSrcweir         lclLinkDiagFrameBorders( aResult, rTLBR, rBLTR,
1520cdf0e10cSrcweir             rTLFromB, rTLFromR, rBRFromT, rBRFromL, rBLFromT, rBLFromR, rTRFromB, rTRFromL );
1521cdf0e10cSrcweir         lclDrawDiagFrameBorders( rDev, rRect, rTLBR, rBLTR, aResult, pForceColor, bDiagDblClip );
1522cdf0e10cSrcweir     }
1523cdf0e10cSrcweir }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir // ============================================================================
1526cdf0e10cSrcweir 
1527cdf0e10cSrcweir } // namespace frame
1528cdf0e10cSrcweir } // namespace svx
1529cdf0e10cSrcweir 
1530