Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
f5a1e923
Kaydet (Commit)
f5a1e923
authored
Tem 12, 2004
tarafından
Rüdiger Timm
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
INTEGRATION: CWS cellborders (1.1.4); FILE ADDED
2004/05/27 14:39:18 fme 1.1.4.1: #i29552# Collapsing table borders
üst
8f9bc157
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1567 additions
and
0 deletions
+1567
-0
framelink.cxx
svx/source/dialog/framelink.cxx
+1567
-0
No files found.
svx/source/dialog/framelink.cxx
0 → 100644
Dosyayı görüntüle @
f5a1e923
/*************************************************************************
*
* $RCSfile: framelink.cxx,v $
*
* $Revision: 1.2 $
*
* last change: $Author: rt $ $Date: 2004-07-12 13:46:55 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef SVX_FRAMELINK_HXX
#include "framelink.hxx"
#endif
#include <math.h>
#ifndef _SV_OUTDEV_HXX
#include <vcl/outdev.hxx>
#endif
#ifndef SVX_BORDERLINE_HXX
#include "borderline.hxx"
#endif
// ----------------------------------------------------------------------------
/** Define to select the drawing mode of thin dotted lines.
0 = Draw lines using an own implementation (recommended). Draws always
little dots in an appropriate distance.
1 = Draw dotted lines using vcl/LineInfo. Results in dashed lines instead
of dotted lines, which may look ugly for diagonal lines.
*/
#define SVX_FRAME_USE_LINEINFO 0
// ----------------------------------------------------------------------------
#if SVX_FRAME_USE_LINEINFO
#ifndef _SV_LINEINFO_HXX
#include <vcl/lineinfo.hxx>
#endif
#endif
namespace
svx
{
namespace
frame
{
// ============================================================================
// ============================================================================
namespace
{
typedef
std
::
vector
<
Point
>
PointVec
;
// ----------------------------------------------------------------------------
// Link result structs for horizontal and vertical lines and borders.
/** Result struct used by the horizontal/vertical frame link functions.
This struct is used to return coordinate offsets for one end of a single
line in a frame border, i.e. the left end of the primary line of a
horizontal frame border.
1) Usage for horizontal lines
If this struct is returned by the lclLinkHorFrameBorder() function, each
member refers to the X coordinate of one edge of a single line end in a
horizontal frame border. They specify an offset to modify this coordinate
when the line is painted. The values in this struct may change a
rectangular line shape into a line with slanted left or right border, which
is used to connect the line with diagonal lines.
Usage for a left line end: Usage for a right line end:
mnOffs1 mnOffs1
<-------> <------->
+-------------------------------+
| the original horizontal line |
+-------------------------------+
<-------> <------->
mnOffs2 mnOffs2
2) Usage for vertical lines
If this struct is returned by the lclLinkVerFrameBorder() function, each
member refers to the Y coordinate of one edge of a single line end in a
vertical frame border. They specify an offset to modify this coordinate
when the line is painted. The values in this struct may change a
rectangular line shape into a line with slanted top or bottom border, which
is used to connect the line with diagonal lines.
Usage for a top line end: mnOffs1 ^ ^ mnOffs2
| +-------+ |
v | | v
| |
| |
the original vertical line ---> | |
| |
| |
^ | | ^
| +-------+ |
Usage for a bottom line end: mnOffs1 v v mnOffs2
*/
struct
LineEndResult
{
long
mnOffs1
;
/// Offset for top or left edge, dependent of context.
long
mnOffs2
;
/// Offset for bottom or right edge, dependent of context
inline
explicit
LineEndResult
()
:
mnOffs1
(
0
),
mnOffs2
(
0
)
{}
inline
void
Swap
()
{
std
::
swap
(
mnOffs1
,
mnOffs2
);
}
inline
void
Negate
()
{
mnOffs1
=
-
mnOffs1
;
mnOffs2
=
-
mnOffs2
;
}
};
/** Result struct used by the horizontal/vertical frame link functions.
This struct contains the linking results for one end of a frame border,
including both the primary and secondary line ends.
*/
struct
BorderEndResult
{
LineEndResult
maPrim
;
/// Result for primary line.
LineEndResult
maSecn
;
/// Result for secondary line.
inline
void
Negate
()
{
maPrim
.
Negate
();
maSecn
.
Negate
();
}
};
/** Result struct used by the horizontal/vertical frame link functions.
This struct contains the linking results for both frame border ends, and
therefore for the complete frame border.
*/
struct
BorderResult
{
BorderEndResult
maBeg
;
/// Result for begin of border line (left or top end).
BorderEndResult
maEnd
;
/// Result for end of border line (right or bottom end).
};
// ----------------------------------------------------------------------------
// Link result structs for diagonal lines and borders.
/** Result struct used by the diagonal frame link functions.
This struct contains the linking results for one line of a diagonal frame
border.
*/
struct
DiagLineResult
{
long
mnLClip
;
/// Offset for left border of clipping rectangle.
long
mnRClip
;
/// Offset for right border of clipping rectangle.
long
mnTClip
;
/// Offset for top border of clipping rectangle.
long
mnBClip
;
/// Offset for bottom border of clipping rectangle.
inline
explicit
DiagLineResult
()
:
mnLClip
(
0
),
mnRClip
(
0
),
mnTClip
(
0
),
mnBClip
(
0
)
{}
};
/** Result struct used by the diagonal frame link functions.
This struct contains the linking results for one diagonal frame border.
*/
struct
DiagBorderResult
{
DiagLineResult
maPrim
;
/// Result for primary line.
DiagLineResult
maSecn
;
/// Result for secondary line.
};
/** Result struct used by the diagonal frame link functions.
This struct contains the linking results for both diagonal frame borders.
*/
struct
DiagBordersResult
{
DiagBorderResult
maTLBR
;
/// Result for top-left to bottom-right frame border.
DiagBorderResult
maBLTR
;
/// Result for bottom-left to top-right frame border.
};
// ----------------------------------------------------------------------------
/** A helper struct containing two points of a line.
*/
struct
LinePoints
{
Point
maBeg
;
/// Start position of the line.
Point
maEnd
;
/// End position of the line.
explicit
LinePoints
(
const
Point
&
rBeg
,
const
Point
&
rEnd
)
:
maBeg
(
rBeg
),
maEnd
(
rEnd
)
{}
explicit
LinePoints
(
const
Rectangle
&
rRect
,
bool
bTLBR
)
:
maBeg
(
bTLBR
?
rRect
.
TopLeft
()
:
rRect
.
TopRight
()
),
maEnd
(
bTLBR
?
rRect
.
BottomRight
()
:
rRect
.
BottomLeft
()
)
{}
};
// ============================================================================
/** Rounds and casts a double value to a long value. */
inline
long
lclD2L
(
double
fValue
)
{
return
static_cast
<
long
>
(
(
fValue
<
0.0
)
?
(
fValue
-
0.5
)
:
(
fValue
+
0.5
)
);
}
/** Converts a width in twips to a width in another map unit (specified by fScale). */
sal_uInt16
lclScaleValue
(
long
nValue
,
double
fScale
,
sal_uInt16
nMaxWidth
)
{
// convert any width except 0 to at least 1 unit
return
nValue
?
static_cast
<
sal_uInt16
>
(
std
::
min
<
long
>
(
std
::
max
(
static_cast
<
long
>
(
nValue
*
fScale
+
0.25
),
1L
),
nMaxWidth
)
)
:
0
;
}
// ----------------------------------------------------------------------------
// Line width offset calculation.
/** Returns the start offset of the single/primary line across the frame border.
All following lclGet*Beg() and lclGet*End() functions return sub units to
increase the computational accuracy, where 256 sub units are equal to
1 map unit of the used OutputDevice.
The following pictures show the upper end of a vertical frame border and
illustrates the return values of all following lclGet*Beg() and lclGet*End()
functions. The first picture shows a single frame border, the second picture
shows a double frame border.
The functions regard the reference point handling mode of the passed border
style.
REFMODE_CENTERED:
All returned offsets are relative to the middle position of the frame
border (offsets left of the middle are returned negative, offsets right
of the middle are returned positive).
REFMODE_BEGIN:
All returned offsets are relative to the begin of the frame border
(lclGetBeg() always returns 0).
REFMODE_END:
All returned offsets are relative to the end of the frame border
(lclGetEnd() always returns 0).
|<- lclGetEnd()
|<- lclGetBeforeBeg() |<- lclGetPrimEnd()
| |
||<- lclGetBeg() ||<- lclGetBehindEnd()
|| ||
|#################################|
direction of | #################################
the frame | #################################
border is | #################################
vertical | #################################
v #################################
|
|<- middle of the frame border
lclGetDistEnd() ->||<- lclGetSecnBeg()
||
lclGetBeg() ->| lclGetDistBeg() ->| || |<- lclGetEnd()
| | || |
lclGetBeforeBeg()->|| lclGetPrimEnd() ->|| || ||<- lclGetBehindEnd()
|| || || ||
|######################| |#############|
direction of | ###################### #############
the frame | ###################### #############
border is | ###################### #############
vertical | ###################### | #############
v ###################### | #############
primary line | secondary line
|
|<- middle of the frame border
@return
The start offset of the single/primary line relative to the reference
position of the frame border (sub units; 0 for invisible or one pixel
wide single frame styles).
*/
long
lclGetBeg
(
const
Style
&
rBorder
)
{
long
nPos
=
0
;
switch
(
rBorder
.
GetRefMode
()
)
{
case
REFMODE_CENTERED
:
if
(
rBorder
.
Prim
()
)
nPos
=
-
128
*
(
rBorder
.
GetWidth
()
-
1
);
break
;
case
REFMODE_END
:
if
(
rBorder
.
Prim
()
)
nPos
=
-
256
*
(
rBorder
.
GetWidth
()
-
1
);
break
;
}
return
nPos
;
}
/** Returns the end offset of the single/secondary line across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The end offset of the single/secondary line relative to the
reference position of the frame border (sub units; 0 for invisible or one
pixel wide single frame styles). */
long
lclGetEnd
(
const
Style
&
rBorder
)
{
long
nPos
=
0
;
switch
(
rBorder
.
GetRefMode
()
)
{
case
REFMODE_CENTERED
:
if
(
rBorder
.
Prim
()
)
nPos
=
128
*
(
rBorder
.
GetWidth
()
-
1
);
break
;
case
REFMODE_BEGIN
:
if
(
rBorder
.
Prim
()
)
nPos
=
256
*
(
rBorder
.
GetWidth
()
-
1
);
break
;
}
return
nPos
;
}
/** Returns the end offset of the primary line across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The end offset of the primary line relative to the reference
position of the frame border (sub units; the end of the primary line in a
double frame style, otherwise the same as lclGetEnd()). */
inline
long
lclGetPrimEnd
(
const
Style
&
rBorder
)
{
return
rBorder
.
Prim
()
?
(
lclGetBeg
(
rBorder
)
+
256
*
(
rBorder
.
Prim
()
-
1
))
:
0
;
}
/** Returns the start offset of the secondary line across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The start offset of the secondary line relative to the reference
position of the frame border (sub units; 0 for single/invisible border
styles). */
inline
long
lclGetSecnBeg
(
const
Style
&
rBorder
)
{
return
rBorder
.
Secn
()
?
(
lclGetEnd
(
rBorder
)
-
256
*
(
rBorder
.
Secn
()
-
1
))
:
0
;
}
/** Returns the start offset of the distance space across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The start offset of the distance space relative to the reference
position of the frame border (sub units; 0 for single/invisible border
styles). */
inline
long
lclGetDistBeg
(
const
Style
&
rBorder
)
{
return
rBorder
.
Secn
()
?
(
lclGetBeg
(
rBorder
)
+
256
*
rBorder
.
Prim
())
:
0
;
}
/** Returns the end offset of the distance space across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The end offset of the distance space relative to the reference
position of the frame border (sub units; 0 for single/invisible border
styles). */
inline
long
lclGetDistEnd
(
const
Style
&
rBorder
)
{
return
rBorder
.
Secn
()
?
(
lclGetEnd
(
rBorder
)
-
256
*
rBorder
.
Secn
())
:
0
;
}
/** Returns the offset before start of single/primary line across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The offset directly before start of single/primary line relative
to the reference position of the frame border (sub units; a value one less
than lclGetBeg() for visible frame styles, or 0 for invisible frame style). */
inline
long
lclGetBeforeBeg
(
const
Style
&
rBorder
)
{
return
rBorder
.
Prim
()
?
(
lclGetBeg
(
rBorder
)
-
256
)
:
0
;
}
/** Returns the offset behind end of single/secondary line across the frame border.
@descr See description of lclGetBeg() for an illustration.
@return The offset directly behind end of single/secondary line relative
to the reference position of the frame border (sub units; a value one
greater than lclGetEnd() for visible frame styles, or 0 for invisible frame
style). */
inline
long
lclGetBehindEnd
(
const
Style
&
rBorder
)
{
return
rBorder
.
Prim
()
?
(
lclGetEnd
(
rBorder
)
+
256
)
:
0
;
}
// ============================================================================
// Linking functions
// ============================================================================
// ----------------------------------------------------------------------------
// Linking of single horizontal line ends.
/** Calculates X offsets for the left end of a single horizontal frame border.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of the left line end.
*/
void
lclLinkLeftEnd_Single
(
LineEndResult
&
rResult
,
const
Style
&
rBorder
,
const
DiagStyle
&
rLFromTR
,
const
Style
&
rLFromT
,
const
Style
&
rLFromL
,
const
Style
&
rLFromB
,
const
DiagStyle
&
rLFromBR
)
{
// both vertical and diagonal frame borders are double
if
(
rLFromT
.
Secn
()
&&
rLFromB
.
Secn
()
&&
rLFromTR
.
Secn
()
&&
rLFromBR
.
Secn
()
)
{
// take left position of upper and lower secondary start
rResult
.
mnOffs1
=
GetBLDiagOffset
(
lclGetBeg
(
rBorder
),
lclGetSecnBeg
(
rLFromTR
),
rLFromTR
.
GetAngle
()
);
rResult
.
mnOffs2
=
GetTLDiagOffset
(
lclGetEnd
(
rBorder
),
lclGetSecnBeg
(
rLFromBR
),
rLFromBR
.
GetAngle
()
);
}
else
{
// both vertical frame borders are double
if
(
rLFromT
.
Secn
()
&&
rLFromB
.
Secn
()
)
rResult
.
mnOffs1
=
(
!
rLFromTR
.
Secn
()
&&
!
rLFromBR
.
Secn
()
&&
(
rLFromT
.
GetWidth
()
==
rLFromB
.
GetWidth
()))
?
// don't overdraw vertical borders with equal width
lclGetBehindEnd
(
rLFromT
)
:
// take leftmost start of both secondary lines (#46488#)
rResult
.
mnOffs1
=
std
::
min
(
lclGetSecnBeg
(
rLFromT
),
lclGetSecnBeg
(
rLFromB
)
);
// single border with equal width coming from left
else
if
(
!
rLFromL
.
Secn
()
&&
(
rLFromL
.
Prim
()
==
rBorder
.
Prim
())
)
// draw to connection point
rResult
.
mnOffs1
=
0
;
// single border coming from left
else
if
(
!
rLFromL
.
Secn
()
&&
rLFromL
.
Prim
()
)
{
if
(
rLFromL
.
Prim
()
==
rBorder
.
Prim
()
)
// draw to reference position, if from left has equal width
rResult
.
mnOffs1
=
0
;
else
rResult
.
mnOffs1
=
(
rLFromL
<
rBorder
)
?
// take leftmost start of both frame borders, if from left is thinner
std
::
min
(
lclGetBeg
(
rLFromT
),
lclGetBeg
(
rLFromB
)
)
:
// do not overdraw vertical, if from left is thicker
std
::
max
(
lclGetBehindEnd
(
rLFromT
),
lclGetBehindEnd
(
rLFromB
)
);
}
// no border coming from left
else
if
(
!
rLFromL
.
Prim
()
)
// don't overdraw vertical borders with equal width
rResult
.
mnOffs1
=
(
rLFromT
.
GetWidth
()
==
rLFromB
.
GetWidth
())
?
lclGetBehindEnd
(
rLFromT
)
:
std
::
min
(
lclGetBeg
(
rLFromT
),
lclGetBeg
(
rLFromB
)
);
// double frame border coming from left and from top
else
if
(
rLFromT
.
Secn
()
)
// do not overdraw the vertical double frame border
rResult
.
mnOffs1
=
lclGetBehindEnd
(
rLFromT
);
// double frame border coming from left and from bottom
else
if
(
rLFromB
.
Secn
()
)
// do not overdraw the vertical double frame border
rResult
.
mnOffs1
=
lclGetBehindEnd
(
rLFromB
);
// double frame border coming from left, both vertical frame borders are single or off
else
// draw from leftmost start of both frame borders, if from left is not thicker
rResult
.
mnOffs1
=
(
rLFromL
<=
rBorder
)
?
std
::
min
(
lclGetBeg
(
rLFromT
),
lclGetBeg
(
rLFromB
)
)
:
std
::
max
(
lclGetBehindEnd
(
rLFromT
),
lclGetBehindEnd
(
rLFromB
)
);
// bottom-left point is equal to top-left point (results in rectangle)
rResult
.
mnOffs2
=
rResult
.
mnOffs1
;
}
}
/** Calculates X offsets for the left end of a primary horizontal line.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of the left end of the primary line.
*/
void
lclLinkLeftEnd_Prim
(
LineEndResult
&
rResult
,
const
Style
&
rBorder
,
const
DiagStyle
&
rLFromTR
,
const
Style
&
rLFromT
,
const
Style
&
rLFromL
,
const
Style
&
rLFromB
,
const
DiagStyle
&
rLFromBR
)
{
// double diagonal frame border coming from top right
if
(
rLFromTR
.
Secn
()
)
{
// draw from where secondary diagonal line meets the own primary
rResult
.
mnOffs1
=
GetBLDiagOffset
(
lclGetBeg
(
rBorder
),
lclGetSecnBeg
(
rLFromTR
),
rLFromTR
.
GetAngle
()
);
rResult
.
mnOffs2
=
GetBLDiagOffset
(
lclGetPrimEnd
(
rBorder
),
lclGetSecnBeg
(
rLFromTR
),
rLFromTR
.
GetAngle
()
);
}
// no or single diagonal frame border - ignore it
else
{
// double frame border coming from top
if
(
rLFromT
.
Secn
()
)
// draw from left edge of secondary vertical
rResult
.
mnOffs1
=
lclGetSecnBeg
(
rLFromT
);
// double frame border coming from left (from top is not double)
else
if
(
rLFromL
.
Secn
()
)
// do not overdraw single frame border coming from top
rResult
.
mnOffs1
=
(
rLFromL
.
GetWidth
()
==
rBorder
.
GetWidth
())
?
0
:
lclGetBehindEnd
(
rLFromT
);
// double frame border coming from bottom (from top and from left are not double)
else
if
(
rLFromB
.
Secn
()
)
// draw from left edge of primary vertical from bottom
rResult
.
mnOffs1
=
lclGetBeg
(
rLFromB
);
// no other frame border is double
else
// do not overdraw vertical frame borders
rResult
.
mnOffs1
=
std
::
max
(
lclGetBehindEnd
(
rLFromT
),
lclGetBehindEnd
(
rLFromB
)
);
// bottom-left point is equal to top-left point (results in rectangle)
rResult
.
mnOffs2
=
rResult
.
mnOffs1
;
}
}
/** Calculates X offsets for the left end of a secondary horizontal line.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of the left end of the secondary line.
*/
void
lclLinkLeftEnd_Secn
(
LineEndResult
&
rResult
,
const
Style
&
rBorder
,
const
DiagStyle
&
rLFromTR
,
const
Style
&
rLFromT
,
const
Style
&
rLFromL
,
const
Style
&
rLFromB
,
const
DiagStyle
&
rLFromBR
)
{
/* Recycle lclLinkLeftEnd_Prim() function with mirrored horizontal borders. */
lclLinkLeftEnd_Prim
(
rResult
,
rBorder
.
Mirror
(),
rLFromBR
,
rLFromB
,
rLFromL
.
Mirror
(),
rLFromT
,
rLFromTR
);
rResult
.
Swap
();
}
// ----------------------------------------------------------------------------
// Linking of horizontal frame border ends.
/** Calculates X offsets for the left end of a horizontal frame border.
This function can be used for single and double frame borders.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of the left end of the line(s) in the frame border.
*/
void
lclLinkLeftEnd
(
BorderEndResult
&
rResult
,
const
Style
&
rBorder
,
const
DiagStyle
&
rLFromTR
,
const
Style
&
rLFromT
,
const
Style
&
rLFromL
,
const
Style
&
rLFromB
,
const
DiagStyle
&
rLFromBR
)
{
if
(
rBorder
.
Secn
()
)
{
// current frame border is double
lclLinkLeftEnd_Prim
(
rResult
.
maPrim
,
rBorder
,
rLFromTR
,
rLFromT
,
rLFromL
,
rLFromB
,
rLFromBR
);
lclLinkLeftEnd_Secn
(
rResult
.
maSecn
,
rBorder
,
rLFromTR
,
rLFromT
,
rLFromL
,
rLFromB
,
rLFromBR
);
}
else
if
(
rBorder
.
Prim
()
)
{
// current frame border is single
lclLinkLeftEnd_Single
(
rResult
.
maPrim
,
rBorder
,
rLFromTR
,
rLFromT
,
rLFromL
,
rLFromB
,
rLFromBR
);
}
else
DBG_ERRORFILE
(
"lclLinkLeftEnd - called for invisible frame style"
);
}
/** Calculates X offsets for the right end of a horizontal frame border.
This function can be used for single and double frame borders.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of the right end of the line(s) in the frame border.
*/
void
lclLinkRightEnd
(
BorderEndResult
&
rResult
,
const
Style
&
rBorder
,
const
DiagStyle
&
rRFromTL
,
const
Style
&
rRFromT
,
const
Style
&
rRFromR
,
const
Style
&
rRFromB
,
const
DiagStyle
&
rRFromBL
)
{
/* Recycle lclLinkLeftEnd() function with mirrored vertical borders. */
lclLinkLeftEnd
(
rResult
,
rBorder
,
rRFromTL
.
Mirror
(),
rRFromT
.
Mirror
(),
rRFromR
,
rRFromB
.
Mirror
(),
rRFromBL
.
Mirror
()
);
rResult
.
Negate
();
}
// ----------------------------------------------------------------------------
// Linking of horizontal and vertical frame borders.
/** Calculates X offsets for all line ends of a horizontal frame border.
This function can be used for single and double frame borders.
See DrawHorFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
X coordinates of both ends of the line(s) in the frame border. To get
the actual X coordinates to draw the lines, these offsets have to be
added to the X coordinates of the reference points of the frame border
(the offsets may be negative).
*/
void
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
)
{
lclLinkLeftEnd
(
rResult
.
maBeg
,
rBorder
,
rLFromTR
,
rLFromT
,
rLFromL
,
rLFromB
,
rLFromBR
);
lclLinkRightEnd
(
rResult
.
maEnd
,
rBorder
,
rRFromTL
,
rRFromT
,
rRFromR
,
rRFromB
,
rRFromBL
);
}
/** Calculates Y offsets for all line ends of a vertical frame border.
This function can be used for single and double frame borders.
See DrawVerFrameBorder() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for the
Y coordinates of both ends of the line(s) in the frame border. To get
the actual Y coordinates to draw the lines, these offsets have to be
added to the Y coordinates of the reference points of the frame border
(the offsets may be negative).
*/
void
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
)
{
/* Recycle lclLinkHorFrameBorder() function with correct parameters. The
frame border is virtually mirrored at the top-left to bottom-right
diagonal. rTFromBR and rBFromTL are mirrored to process their primary
and secondary lines correctly. */
lclLinkHorFrameBorder
(
rResult
,
rBorder
,
rTFromBL
,
rTFromL
,
rTFromT
,
rTFromR
,
rTFromBR
.
Mirror
(),
rBFromTL
.
Mirror
(),
rBFromL
,
rBFromB
,
rBFromR
,
rBFromTR
);
}
// ============================================================================
#if 0
// Not used anymore, but not deleted for possible future usage.
/** Returns the relative Y offset of the intercept point of 2 diagonal borders.
@param nTLBROffs
Width offset (sub units) across the top-left to bottom-right frame border.
@param fTLBRAngle
Inner angle between horizontal and top-left to bottom-right frame border.
@param nBLTROffs
Width offset (sub units) across the bottom-left to top-right frame border.
@param fBLTRAngle
Inner angle between horizontal and bottom-left to top-right frame border.
@return
Offset (sub units) relative to the Y position of the centered intercept
point of both diagonal frame borders.
*/
long lclGetDiagDiagOffset( long nTLBROffs, double fTLBRAngle, long nBLTROffs, double fBLTRAngle )
{
double fASin = sin( fTLBRAngle );
double fACos = cos( fTLBRAngle );
double fAX = -nTLBROffs * fASin;
double fAY = nTLBROffs * fACos;
double fRAX = fACos;
double fRAY = fASin;
double fBSin = sin( fBLTRAngle );
double fBCos = cos( fBLTRAngle );
double fBX = nBLTROffs * fBSin;
double fBY = nBLTROffs * fBCos;
double fRBX = fBCos;
double fRBY = -fBSin;
double fKA = (fRBX * (fBY - fAY) - fRBY * (fBX - fAX)) / (fRBX * fRAY - fRAX * fRBY);
return lclD2L( fAY + fKA * fRAY );
}
#endif
// ----------------------------------------------------------------------------
// Linking of diagonal frame borders.
/** Calculates clipping offsets for a top-left to bottom-right frame border.
This function can be used for single and double frame borders.
See DrawDiagFrameBorders() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for all
borders of the reference rectangle containing the diagonal frame border.
*/
void
lclLinkTLBRFrameBorder
(
DiagBorderResult
&
rResult
,
const
Style
&
rBorder
,
const
Style
&
rTLFromB
,
const
Style
&
rTLFromR
,
const
Style
&
rBRFromT
,
const
Style
&
rBRFromL
)
{
bool
bIsDbl
=
rBorder
.
Secn
()
!=
0
;
rResult
.
maPrim
.
mnLClip
=
lclGetBehindEnd
(
rTLFromB
);
rResult
.
maPrim
.
mnRClip
=
(
bIsDbl
&&
rBRFromT
.
Secn
())
?
lclGetEnd
(
rBRFromT
)
:
lclGetBeforeBeg
(
rBRFromT
);
rResult
.
maPrim
.
mnTClip
=
(
bIsDbl
&&
rTLFromR
.
Secn
())
?
lclGetBeg
(
rTLFromR
)
:
lclGetBehindEnd
(
rTLFromR
);
rResult
.
maPrim
.
mnBClip
=
lclGetBeforeBeg
(
rBRFromL
);
if
(
bIsDbl
)
{
rResult
.
maSecn
.
mnLClip
=
rTLFromB
.
Secn
()
?
lclGetBeg
(
rTLFromB
)
:
lclGetBehindEnd
(
rTLFromB
);
rResult
.
maSecn
.
mnRClip
=
lclGetBeforeBeg
(
rBRFromT
);
rResult
.
maSecn
.
mnTClip
=
lclGetBehindEnd
(
rTLFromR
);
rResult
.
maSecn
.
mnBClip
=
rBRFromL
.
Secn
()
?
lclGetEnd
(
rBRFromL
)
:
lclGetBeforeBeg
(
rBRFromL
);
}
}
/** Calculates clipping offsets for a bottom-left to top-right frame border.
This function can be used for single and double frame borders.
See DrawDiagFrameBorders() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for all
borders of the reference rectangle containing the diagonal frame border.
*/
void
lclLinkBLTRFrameBorder
(
DiagBorderResult
&
rResult
,
const
Style
&
rBorder
,
const
Style
&
rBLFromT
,
const
Style
&
rBLFromR
,
const
Style
&
rTRFromB
,
const
Style
&
rTRFromL
)
{
bool
bIsDbl
=
rBorder
.
Secn
()
!=
0
;
rResult
.
maPrim
.
mnLClip
=
lclGetBehindEnd
(
rBLFromT
);
rResult
.
maPrim
.
mnRClip
=
(
bIsDbl
&&
rTRFromB
.
Secn
())
?
lclGetEnd
(
rTRFromB
)
:
lclGetBeforeBeg
(
rTRFromB
);
rResult
.
maPrim
.
mnTClip
=
lclGetBehindEnd
(
rTRFromL
);
rResult
.
maPrim
.
mnBClip
=
(
bIsDbl
&&
rBLFromR
.
Secn
())
?
lclGetEnd
(
rBLFromR
)
:
lclGetBeforeBeg
(
rBLFromR
);
if
(
bIsDbl
)
{
rResult
.
maSecn
.
mnLClip
=
rBLFromT
.
Secn
()
?
lclGetBeg
(
rBLFromT
)
:
lclGetBehindEnd
(
rBLFromT
);
rResult
.
maSecn
.
mnRClip
=
lclGetBeforeBeg
(
rTRFromB
);
rResult
.
maSecn
.
mnTClip
=
rTRFromL
.
Secn
()
?
lclGetBeg
(
rTRFromL
)
:
lclGetBehindEnd
(
rTRFromL
);
rResult
.
maSecn
.
mnBClip
=
lclGetBeforeBeg
(
rBLFromR
);
}
}
/** Calculates clipping offsets for both diagonal frame borders.
This function can be used for single and double frame borders.
See DrawDiagFrameBorders() function for a description of all parameters.
@param rResult
(out-param) The contained values (sub units) specify offsets for all
borders of the reference rectangle containing the diagonal frame
borders.
*/
void
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
)
{
lclLinkTLBRFrameBorder
(
rResult
.
maTLBR
,
rTLBR
,
rTLFromB
,
rTLFromR
,
rBRFromT
,
rBRFromL
);
lclLinkBLTRFrameBorder
(
rResult
.
maBLTR
,
rBLTR
,
rBLFromT
,
rBLFromR
,
rTRFromB
,
rTRFromL
);
}
// ============================================================================
// Drawing functions
// ============================================================================
// ----------------------------------------------------------------------------
// Simple helper functions
/** Converts sub units to OutputDevice map units. */
inline
long
lclToMapUnit
(
long
nSubUnits
)
{
return
((
nSubUnits
<
0
)
?
(
nSubUnits
-
127
)
:
(
nSubUnits
+
128
))
/
256
;
}
/** Converts a point in sub units to an OutputDevice point. */
inline
Point
lclToMapUnit
(
long
nSubXPos
,
long
nSubYPos
)
{
return
Point
(
lclToMapUnit
(
nSubXPos
),
lclToMapUnit
(
nSubYPos
)
);
}
/** Returns a polygon constructed from a vector of points. */
inline
Polygon
lclCreatePolygon
(
const
PointVec
&
rPoints
)
{
return
Polygon
(
static_cast
<
USHORT
>
(
rPoints
.
size
()
),
&
rPoints
[
0
]
);
}
/** Returns a polygon constructed from the four passed points. */
Polygon
lclCreatePolygon
(
const
Point
&
rP1
,
const
Point
&
rP2
,
const
Point
&
rP3
,
const
Point
&
rP4
)
{
PointVec
aPoints
;
aPoints
.
reserve
(
4
);
aPoints
.
push_back
(
rP1
);
aPoints
.
push_back
(
rP2
);
aPoints
.
push_back
(
rP3
);
aPoints
.
push_back
(
rP4
);
return
lclCreatePolygon
(
aPoints
);
}
/** Returns a polygon constructed from the five passed points. */
Polygon
lclCreatePolygon
(
const
Point
&
rP1
,
const
Point
&
rP2
,
const
Point
&
rP3
,
const
Point
&
rP4
,
const
Point
&
rP5
)
{
PointVec
aPoints
;
aPoints
.
reserve
(
5
);
aPoints
.
push_back
(
rP1
);
aPoints
.
push_back
(
rP2
);
aPoints
.
push_back
(
rP3
);
aPoints
.
push_back
(
rP4
);
aPoints
.
push_back
(
rP5
);
return
lclCreatePolygon
(
aPoints
);
}
/** Returns a polygon constructed from the two passed line positions. */
inline
Polygon
lclCreatePolygon
(
const
LinePoints
&
rPoints1
,
const
LinePoints
&
rPoints2
)
{
return
lclCreatePolygon
(
rPoints1
.
maBeg
,
rPoints1
.
maEnd
,
rPoints2
.
maEnd
,
rPoints2
.
maBeg
);
}
/** Sets the color of the passed frame style to the output device.
Sets the line color and fill color in the output device.
@param rDev
The output device the color has to be set to. The old colors are pushed
onto the device's stack and can be restored with a call to
OutputDevice::Pop(). Please take care about the correct calling order
of Pop() if this function is used with other functions pushing
something onto the stack.
@param rStyle
The border style that contains the line color to be set to the device.
*/
void
lclSetColorToOutDev
(
OutputDevice
&
rDev
,
const
Style
&
rStyle
,
const
Color
*
pForceColor
)
{
rDev
.
Push
(
PUSH_LINECOLOR
|
PUSH_FILLCOLOR
);
rDev
.
SetLineColor
(
pForceColor
?
*
pForceColor
:
rStyle
.
GetColor
()
);
rDev
.
SetFillColor
(
pForceColor
?
*
pForceColor
:
rStyle
.
GetColor
()
);
}
// ----------------------------------------------------------------------------
// Generic drawing functions.
/** Draws a thin (1 pixel wide) line, optionally dotted, into the passed output device. */
void
lclDrawThinLine
(
OutputDevice
&
rDev
,
const
Point
&
rBeg
,
const
Point
&
rEnd
,
bool
bDotted
)
{
#if SVX_FRAME_USE_LINEINFO
if
(
bDotted
&&
(
rBeg
!=
rEnd
)
)
{
// using LineInfo for dotted lines looks ugly and does not work well for diagonal lines
LineInfo
aLineInfo
(
LINE_DASH
,
1
);
aLineInfo
.
SetDotCount
(
1
);
aLineInfo
.
SetDotLen
(
1
);
aLineInfo
.
SetDistance
(
3
);
rDev
.
DrawLine
(
rBeg
,
rEnd
,
aLineInfo
);
}
#else
Point
aBeg
(
rDev
.
LogicToPixel
(
rBeg
)
);
Point
aEnd
(
rDev
.
LogicToPixel
(
rEnd
)
);
if
(
bDotted
&&
(
aBeg
!=
aEnd
)
)
{
bool
bHor
=
Abs
(
aEnd
.
X
()
-
aBeg
.
X
()
)
>
Abs
(
aEnd
.
Y
()
-
aBeg
.
Y
()
);
const
Point
&
rBegPos
(
bHor
?
((
aBeg
.
X
()
<
aEnd
.
X
())
?
aBeg
:
aEnd
)
:
((
aBeg
.
Y
()
<
aEnd
.
Y
())
?
aBeg
:
aEnd
)
);
const
Point
&
rEndPos
(
(
rBegPos
==
aBeg
)
?
aEnd
:
aBeg
);
long
nAlongBeg
=
bHor
?
rBegPos
.
X
()
:
rBegPos
.
Y
();
long
nAcrssBeg
=
bHor
?
rBegPos
.
Y
()
:
rBegPos
.
X
();
long
nAlongSize
=
(
bHor
?
rEndPos
.
X
()
:
rEndPos
.
Y
())
-
nAlongBeg
;
long
nAcrssSize
=
(
bHor
?
rEndPos
.
Y
()
:
rEndPos
.
X
())
-
nAcrssBeg
;
double
fGradient
=
static_cast
<
double
>
(
nAcrssSize
)
/
nAlongSize
;
PointVec
aPoints
;
aPoints
.
reserve
(
(
nAlongSize
+
1
)
/
2
);
for
(
long
nAlongIdx
=
0
;
nAlongIdx
<=
nAlongSize
;
nAlongIdx
+=
2
)
{
long
nAl
=
nAlongBeg
+
nAlongIdx
;
long
nAc
=
nAcrssBeg
+
lclD2L
(
fGradient
*
nAlongIdx
);
aPoints
.
push_back
(
Point
(
bHor
?
nAl
:
nAc
,
bHor
?
nAc
:
nAl
)
);
}
rDev
.
Push
(
PUSH_MAPMODE
);
rDev
.
SetMapMode
(
MAP_PIXEL
);
rDev
.
DrawPixel
(
lclCreatePolygon
(
aPoints
)
);
rDev
.
Pop
();
// map mode
}
#endif
else
rDev
.
DrawLine
(
rBeg
,
rEnd
);
}
/** Draws a thin (1 pixel wide) line, optionally dotted, into the passed output device. */
inline
void
lclDrawThinLine
(
OutputDevice
&
rDev
,
const
LinePoints
&
rPoints
,
bool
bDotted
)
{
lclDrawThinLine
(
rDev
,
rPoints
.
maBeg
,
rPoints
.
maEnd
,
bDotted
);
}
/** Draws a polygon with four points into the passed output device. */
inline
void
lclDrawPolygon
(
OutputDevice
&
rDev
,
const
Point
&
rP1
,
const
Point
&
rP2
,
const
Point
&
rP3
,
const
Point
&
rP4
)
{
rDev
.
DrawPolygon
(
lclCreatePolygon
(
rP1
,
rP2
,
rP3
,
rP4
)
);
}
/** Draws a polygon specified by two borders into the passed output device. */
inline
void
lclDrawPolygon
(
OutputDevice
&
rDev
,
const
LinePoints
&
rPoints1
,
const
LinePoints
&
rPoints2
)
{
rDev
.
DrawPolygon
(
lclCreatePolygon
(
rPoints1
,
rPoints2
)
);
}
// ============================================================================
// Drawing of horizontal frame borders.
/** Draws a horizontal thin or thick line into the passed output device.
The X coordinates of the edges of the line are adjusted according to the
passed LineEndResult structs. A one pixel wide line can be drawn dotted.
*/
void
lclDrawHorLine
(
OutputDevice
&
rDev
,
const
Point
&
rLPos
,
const
LineEndResult
&
rLRes
,
const
Point
&
rRPos
,
const
LineEndResult
&
rRRes
,
long
nTOffs
,
long
nBOffs
,
bool
bDotted
)
{
LinePoints
aTPoints
(
rLPos
+
lclToMapUnit
(
rLRes
.
mnOffs1
,
nTOffs
),
rRPos
+
lclToMapUnit
(
rRRes
.
mnOffs1
,
nTOffs
)
);
if
(
nTOffs
==
nBOffs
)
lclDrawThinLine
(
rDev
,
aTPoints
,
bDotted
);
else
{
LinePoints
aBPoints
(
rLPos
+
lclToMapUnit
(
rLRes
.
mnOffs2
,
nBOffs
),
rRPos
+
lclToMapUnit
(
rRRes
.
mnOffs2
,
nBOffs
)
);
lclDrawPolygon
(
rDev
,
aTPoints
,
aBPoints
);
}
}
/** Draws a horizontal frame border into the passed output device.
@param rLPos
The top-left or bottom-left reference point of the diagonal frame border.
@param rRPos
The top-right or bottom-right reference point of the diagonal frame border.
@param rBorder
The frame style used to draw the border.
@param rResult
The X coordinates of the edges of all lines of the frame border are
adjusted according to the offsets contained here.
*/
void
lclDrawHorFrameBorder
(
OutputDevice
&
rDev
,
const
Point
&
rLPos
,
const
Point
&
rRPos
,
const
Style
&
rBorder
,
const
BorderResult
&
rResult
,
const
Color
*
pForceColor
)
{
DBG_ASSERT
(
rBorder
.
Prim
(),
"svx::frame::lclDrawHorFrameBorder - line not visible"
);
DBG_ASSERT
(
rLPos
.
X
()
<=
rRPos
.
X
(),
"svx::frame::lclDrawHorFrameBorder - wrong order of line ends"
);
DBG_ASSERT
(
rLPos
.
Y
()
==
rRPos
.
Y
(),
"svx::frame::lclDrawHorFrameBorder - line not horizontal"
);
if
(
rLPos
.
X
()
<=
rRPos
.
X
()
)
{
lclSetColorToOutDev
(
rDev
,
rBorder
,
pForceColor
);
lclDrawHorLine
(
rDev
,
rLPos
,
rResult
.
maBeg
.
maPrim
,
rRPos
,
rResult
.
maEnd
.
maPrim
,
lclGetBeg
(
rBorder
),
lclGetPrimEnd
(
rBorder
),
rBorder
.
Dotted
()
);
if
(
rBorder
.
Secn
()
)
lclDrawHorLine
(
rDev
,
rLPos
,
rResult
.
maBeg
.
maSecn
,
rRPos
,
rResult
.
maEnd
.
maSecn
,
lclGetSecnBeg
(
rBorder
),
lclGetEnd
(
rBorder
),
rBorder
.
Dotted
()
);
rDev
.
Pop
();
// colors
}
}
// ----------------------------------------------------------------------------
// Drawing of vertical frame borders.
/** Draws a vertical thin or thick line into the passed output device.
The Y coordinates of the edges of the line are adjusted according to the
passed LineEndResult structs. A one pixel wide line can be drawn dotted.
*/
void
lclDrawVerLine
(
OutputDevice
&
rDev
,
const
Point
&
rTPos
,
const
LineEndResult
&
rTRes
,
const
Point
&
rBPos
,
const
LineEndResult
&
rBRes
,
long
nLOffs
,
long
nROffs
,
bool
bDotted
)
{
LinePoints
aLPoints
(
rTPos
+
lclToMapUnit
(
nLOffs
,
rTRes
.
mnOffs1
),
rBPos
+
lclToMapUnit
(
nLOffs
,
rBRes
.
mnOffs1
)
);
if
(
nLOffs
==
nROffs
)
lclDrawThinLine
(
rDev
,
aLPoints
,
bDotted
);
else
{
LinePoints
aRPoints
(
rTPos
+
lclToMapUnit
(
nROffs
,
rTRes
.
mnOffs2
),
rBPos
+
lclToMapUnit
(
nROffs
,
rBRes
.
mnOffs2
)
);
lclDrawPolygon
(
rDev
,
aLPoints
,
aRPoints
);
}
}
/** Draws a vertical frame border into the passed output device.
@param rTPos
The top-left or top-right reference point of the diagonal frame border.
@param rBPos
The bottom-left or bottom-right reference point of the diagonal frame border.
@param rBorder
The frame style used to draw the border.
@param rResult
The Y coordinates of the edges of all lines of the frame border are
adjusted according to the offsets contained here.
*/
void
lclDrawVerFrameBorder
(
OutputDevice
&
rDev
,
const
Point
&
rTPos
,
const
Point
&
rBPos
,
const
Style
&
rBorder
,
const
BorderResult
&
rResult
,
const
Color
*
pForceColor
)
{
DBG_ASSERT
(
rBorder
.
Prim
(),
"svx::frame::lclDrawVerFrameBorder - line not visible"
);
DBG_ASSERT
(
rTPos
.
Y
()
<=
rBPos
.
Y
(),
"svx::frame::lclDrawVerFrameBorder - wrong order of line ends"
);
DBG_ASSERT
(
rTPos
.
X
()
==
rBPos
.
X
(),
"svx::frame::lclDrawVerFrameBorder - line not vertical"
);
if
(
rTPos
.
Y
()
<=
rBPos
.
Y
()
)
{
lclSetColorToOutDev
(
rDev
,
rBorder
,
pForceColor
);
lclDrawVerLine
(
rDev
,
rTPos
,
rResult
.
maBeg
.
maPrim
,
rBPos
,
rResult
.
maEnd
.
maPrim
,
lclGetBeg
(
rBorder
),
lclGetPrimEnd
(
rBorder
),
rBorder
.
Dotted
()
);
if
(
rBorder
.
Secn
()
)
lclDrawVerLine
(
rDev
,
rTPos
,
rResult
.
maBeg
.
maSecn
,
rBPos
,
rResult
.
maEnd
.
maSecn
,
lclGetSecnBeg
(
rBorder
),
lclGetEnd
(
rBorder
),
rBorder
.
Dotted
()
);
rDev
.
Pop
();
// colors
}
}
// ============================================================================
// Drawing of diagonal frame borders, incudes clipping functions.
/** Returns the drawing coordinates for a diagonal thin line.
This function can be used for top-left to bottom-right and for bottom-left
to top-right lines.
@param rRect
The reference rectangle of the diagonal frame border.
@param bTLBR
true = top-left to bottom-right; false = bottom-left to top-right.
@param nDiagOffs
Width offset (sub units) across the diagonal frame border.
@return
A struct containg start and end position of the diagonal line.
*/
LinePoints
lclGetDiagLineEnds
(
const
Rectangle
&
rRect
,
bool
bTLBR
,
long
nDiagOffs
)
{
LinePoints
aPoints
(
rRect
,
bTLBR
);
bool
bVert
=
rRect
.
GetWidth
()
<
rRect
.
GetHeight
();
double
fAngle
=
bVert
?
GetVerDiagAngle
(
rRect
)
:
GetHorDiagAngle
(
rRect
);
// vertical top-left to bottom-right borders are handled mirrored
if
(
bVert
&&
bTLBR
)
nDiagOffs
=
-
nDiagOffs
;
long
nTOffs
=
bTLBR
?
GetTLDiagOffset
(
0
,
nDiagOffs
,
fAngle
)
:
GetTRDiagOffset
(
0
,
nDiagOffs
,
fAngle
);
long
nBOffs
=
bTLBR
?
GetBRDiagOffset
(
0
,
nDiagOffs
,
fAngle
)
:
GetBLDiagOffset
(
0
,
nDiagOffs
,
fAngle
);
// vertical bottom-left to top-right borders are handled with exchanged end points
if
(
bVert
&&
!
bTLBR
)
std
::
swap
(
nTOffs
,
nBOffs
);
(
bVert
?
aPoints
.
maBeg
.
Y
()
:
aPoints
.
maBeg
.
X
())
+=
lclToMapUnit
(
nTOffs
);
(
bVert
?
aPoints
.
maEnd
.
Y
()
:
aPoints
.
maEnd
.
X
())
+=
lclToMapUnit
(
nBOffs
);
return
aPoints
;
}
// ----------------------------------------------------------------------------
// Clipping functions for diagonal frame borders.
/** Limits the clipping region to the inner area of a rectange.
Takes the values from the passed DiagLineResult struct into account. They
may specify to not clip one or more borders of a rectangle.
@param rDev
The output device with the clipping region to be modified. The old
clipping region is pushed onto the device's stack and can be restored
with a call to OutputDevice::Pop(). Please take care about the correct
calling order of Pop() if this function is used with other functions
pushing something onto the stack.
@param rRect
The reference rectangle of the diagonal frame borders.
@param rResult
The result struct containing modifies for each border of the reference
rectangle.
*/
void
lclPushDiagClipRect
(
OutputDevice
&
rDev
,
const
Rectangle
&
rRect
,
const
DiagLineResult
&
rResult
)
{
// PixelToLogic() regards internal offset of the output device
Rectangle
aClipRect
(
rRect
);
aClipRect
.
Left
()
+=
lclToMapUnit
(
rResult
.
mnLClip
);
aClipRect
.
Top
()
+=
lclToMapUnit
(
rResult
.
mnTClip
);
aClipRect
.
Right
()
+=
lclToMapUnit
(
rResult
.
mnRClip
);
aClipRect
.
Bottom
()
+=
lclToMapUnit
(
rResult
.
mnBClip
);
// output device would adjust the rectangle -> invalidate it before
if
(
(
aClipRect
.
GetWidth
()
<
1
)
||
(
aClipRect
.
GetHeight
()
<
1
)
)
aClipRect
.
SetEmpty
();
rDev
.
Push
(
PUSH_CLIPREGION
);
rDev
.
IntersectClipRegion
(
aClipRect
);
}
/** Excludes inner area of a crossing double frame border from clipping region.
This function is used to modify the clipping region so that it excludes the
inner free area of a double diagonal frame border. This makes it possible
to draw a diagonal frame border in one step without taking care of the
crossing double frame border.
@param rDev
The output device with the clipping region to be modified. The old
clipping region is pushed onto the device's stack and can be restored
with a call to OutputDevice::Pop(). Please take care about the correct
calling order of Pop() if this function is used with other functions
pushing something onto the stack.
@param rRect
The reference rectangle of the diagonal frame borders.
@param bTLBR
The orientation of the processed frame border (not the orientation of
the crossing frame border).
@param bCrossStyle
The style of the crossing frame border. Must be a double frame style.
*/
void
lclPushCrossingClipRegion
(
OutputDevice
&
rDev
,
const
Rectangle
&
rRect
,
bool
bTLBR
,
const
Style
&
rCrossStyle
)
{
DBG_ASSERT
(
rCrossStyle
.
Secn
(),
"lclGetCrossingClipRegion - use only for double styles"
);
LinePoints
aLPoints
(
lclGetDiagLineEnds
(
rRect
,
!
bTLBR
,
lclGetPrimEnd
(
rCrossStyle
)
)
);
LinePoints
aRPoints
(
lclGetDiagLineEnds
(
rRect
,
!
bTLBR
,
lclGetSecnBeg
(
rCrossStyle
)
)
);
Region
aClipReg
;
if
(
bTLBR
)
{
aClipReg
=
lclCreatePolygon
(
aLPoints
.
maBeg
,
aLPoints
.
maEnd
,
rRect
.
BottomRight
(),
rRect
.
BottomLeft
(),
rRect
.
TopLeft
()
);
aClipReg
.
Union
(
lclCreatePolygon
(
aRPoints
.
maBeg
,
aRPoints
.
maEnd
,
rRect
.
BottomRight
(),
rRect
.
TopRight
(),
rRect
.
TopLeft
()
)
);
}
else
{
aClipReg
=
lclCreatePolygon
(
aLPoints
.
maBeg
,
aLPoints
.
maEnd
,
rRect
.
BottomLeft
(),
rRect
.
TopLeft
(),
rRect
.
TopRight
()
);
aClipReg
.
Union
(
lclCreatePolygon
(
aRPoints
.
maBeg
,
aRPoints
.
maEnd
,
rRect
.
BottomLeft
(),
rRect
.
BottomRight
(),
rRect
.
TopRight
()
)
);
}
rDev
.
Push
(
PUSH_CLIPREGION
);
rDev
.
IntersectClipRegion
(
aClipReg
);
}
// ----------------------------------------------------------------------------
// Drawing functions for diagonal frame borders.
/** Draws a diagonal thin or thick line into the passed output device.
The clipping region of the output device is modified according to the
passed DiagLineResult struct. A one pixel wide line can be drawn dotted.
*/
void
lclDrawDiagLine
(
OutputDevice
&
rDev
,
const
Rectangle
&
rRect
,
bool
bTLBR
,
const
DiagLineResult
&
rResult
,
long
nDiagOffs1
,
long
nDiagOffs2
,
bool
bDotted
)
{
lclPushDiagClipRect
(
rDev
,
rRect
,
rResult
);
LinePoints
aLPoints
(
lclGetDiagLineEnds
(
rRect
,
bTLBR
,
nDiagOffs1
)
);
if
(
nDiagOffs1
==
nDiagOffs2
)
lclDrawThinLine
(
rDev
,
aLPoints
,
bDotted
);
else
lclDrawPolygon
(
rDev
,
aLPoints
,
lclGetDiagLineEnds
(
rRect
,
bTLBR
,
nDiagOffs2
)
);
rDev
.
Pop
();
// clipping region
}
/** Draws a diagonal frame border into the passed output device.
The lines of the frame border are drawn interrupted, if the style of the
crossing frame border is double.
@param rRect
The reference rectangle of the diagonal frame border.
@param bTLBR
The orientation of the diagonal frame border.
@param rBorder
The frame style used to draw the border.
@param rResult
Offsets (sub units) to modify the clipping region of the output device.
@param rCrossStyle
Style of the crossing diagonal frame border.
*/
void
lclDrawDiagFrameBorder
(
OutputDevice
&
rDev
,
const
Rectangle
&
rRect
,
bool
bTLBR
,
const
Style
&
rBorder
,
const
DiagBorderResult
&
rResult
,
const
Style
&
rCrossStyle
,
const
Color
*
pForceColor
,
bool
bDiagDblClip
)
{
DBG_ASSERT
(
rBorder
.
Prim
(),
"svx::frame::lclDrawDiagFrameBorder - line not visible"
);
bool
bClip
=
bDiagDblClip
&&
rCrossStyle
.
Secn
();
if
(
bClip
)
lclPushCrossingClipRegion
(
rDev
,
rRect
,
bTLBR
,
rCrossStyle
);
lclSetColorToOutDev
(
rDev
,
rBorder
,
pForceColor
);
lclDrawDiagLine
(
rDev
,
rRect
,
bTLBR
,
rResult
.
maPrim
,
lclGetBeg
(
rBorder
),
lclGetPrimEnd
(
rBorder
),
rBorder
.
Dotted
()
);
if
(
rBorder
.
Secn
()
)
lclDrawDiagLine
(
rDev
,
rRect
,
bTLBR
,
rResult
.
maSecn
,
lclGetSecnBeg
(
rBorder
),
lclGetEnd
(
rBorder
),
rBorder
.
Dotted
()
);
rDev
.
Pop
();
// colors
if
(
bClip
)
rDev
.
Pop
();
// clipping region
}
/** Draws both diagonal frame borders into the passed output device.
The lines of each frame border is drawn interrupted, if the style of the
other crossing frame border is double.
@param rRect
The reference rectangle of the diagonal frame borders.
@param rTLBR
The frame style of the top-left to bottom-right frame border.
@param rBLTR
The frame style of the bottom-left to top-right frame border.
@param rResult
Offsets (sub units) to modify the clipping region of the output device.
*/
void
lclDrawDiagFrameBorders
(
OutputDevice
&
rDev
,
const
Rectangle
&
rRect
,
const
Style
&
rTLBR
,
const
Style
&
rBLTR
,
const
DiagBordersResult
&
rResult
,
const
Color
*
pForceColor
,
bool
bDiagDblClip
)
{
DBG_ASSERT
(
(
rRect
.
GetWidth
()
>
1
)
&&
(
rRect
.
GetHeight
()
>
1
),
"svx::frame::lclDrawDiagFrameBorders - rectangle too small"
);
if
(
(
rRect
.
GetWidth
()
>
1
)
&&
(
rRect
.
GetHeight
()
>
1
)
)
{
bool
bDrawTLBR
=
rTLBR
.
Prim
()
!=
0
;
bool
bDrawBLTR
=
rBLTR
.
Prim
()
!=
0
;
bool
bFirstDrawBLTR
=
rTLBR
.
Secn
()
!=
0
;
if
(
bDrawBLTR
&&
bFirstDrawBLTR
)
lclDrawDiagFrameBorder
(
rDev
,
rRect
,
false
,
rBLTR
,
rResult
.
maBLTR
,
rTLBR
,
pForceColor
,
bDiagDblClip
);
if
(
bDrawTLBR
)
lclDrawDiagFrameBorder
(
rDev
,
rRect
,
true
,
rTLBR
,
rResult
.
maTLBR
,
rBLTR
,
pForceColor
,
bDiagDblClip
);
if
(
bDrawBLTR
&&
!
bFirstDrawBLTR
)
lclDrawDiagFrameBorder
(
rDev
,
rRect
,
false
,
rBLTR
,
rResult
.
maBLTR
,
rTLBR
,
pForceColor
,
bDiagDblClip
);
}
}
// ============================================================================
}
// namespace
// ============================================================================
// Classes
// ============================================================================
#define SCALEVALUE( value ) lclScaleValue( value, fScale, nMaxWidth )
void
Style
::
Clear
()
{
Set
(
Color
(),
0
,
0
,
0
);
}
void
Style
::
Set
(
sal_uInt16
nP
,
sal_uInt16
nD
,
sal_uInt16
nS
)
{
/* nP nD nS -> mnPrim mnDist mnSecn
--------------------------------------
any any 0 nP 0 0
0 any >0 nS 0 0
>0 0 >0 nP 0 0
>0 >0 >0 nP nD nS
*/
mnPrim
=
nP
?
nP
:
nS
;
mnDist
=
(
nP
&&
nS
)
?
nD
:
0
;
mnSecn
=
(
nP
&&
nD
)
?
nS
:
0
;
}
void
Style
::
Set
(
const
Color
&
rColor
,
sal_uInt16
nP
,
sal_uInt16
nD
,
sal_uInt16
nS
)
{
maColor
=
rColor
;
Set
(
nP
,
nD
,
nS
);
}
void
Style
::
Set
(
const
SvxBorderLine
&
rBorder
,
double
fScale
,
sal_uInt16
nMaxWidth
,
bool
bUseDots
)
{
maColor
=
rBorder
.
GetColor
();
USHORT
nPrim
=
rBorder
.
GetOutWidth
();
USHORT
nDist
=
rBorder
.
GetDistance
();
USHORT
nSecn
=
rBorder
.
GetInWidth
();
if
(
!
nSecn
)
// no or single frame border
{
Set
(
SCALEVALUE
(
nPrim
),
0
,
0
);
mbDotted
=
bUseDots
&&
(
0
<
nPrim
)
&&
(
nPrim
<
10
);
}
else
{
Set
(
SCALEVALUE
(
nPrim
),
SCALEVALUE
(
nDist
),
SCALEVALUE
(
nSecn
)
);
mbDotted
=
false
;
// Enlarge the style if distance is too small due to rounding losses.
sal_uInt16
nPixWidth
=
SCALEVALUE
(
nPrim
+
nDist
+
nSecn
);
if
(
nPixWidth
>
GetWidth
()
)
mnDist
=
nPixWidth
-
mnPrim
-
mnSecn
;
// Shrink the style if it is too thick for the control.
while
(
GetWidth
()
>
nMaxWidth
)
{
// First decrease space between lines.
if
(
mnDist
)
--
mnDist
;
// Still too thick? Decrease the line widths.
if
(
GetWidth
()
>
nMaxWidth
)
{
if
(
mnPrim
&&
(
mnPrim
==
mnSecn
)
)
{
// Both lines equal - decrease both to keep symmetry.
--
mnPrim
;
--
mnSecn
;
}
else
{
// Decrease each line for itself
if
(
mnPrim
)
--
mnPrim
;
if
(
(
GetWidth
()
>
nMaxWidth
)
&&
mnSecn
)
--
mnSecn
;
}
}
}
}
}
void
Style
::
Set
(
const
SvxBorderLine
*
pBorder
,
double
fScale
,
sal_uInt16
nMaxWidth
,
bool
bUseDots
)
{
if
(
pBorder
)
Set
(
*
pBorder
,
fScale
,
nMaxWidth
,
bUseDots
);
else
{
Clear
();
mbDotted
=
false
;
}
}
Style
&
Style
::
ScaleSelf
(
double
fScale
,
sal_uInt16
nMaxWidth
)
{
Set
(
SCALEVALUE
(
mnPrim
),
SCALEVALUE
(
mnDist
),
SCALEVALUE
(
mnSecn
),
mbDotted
);
return
*
this
;
}
Style
Style
::
Scale
(
double
fScale
,
sal_uInt16
nMaxWidth
)
const
{
return
Style
(
*
this
).
ScaleSelf
(
fScale
,
nMaxWidth
);
}
Style
&
Style
::
MirrorSelf
()
{
if
(
mnSecn
)
std
::
swap
(
mnPrim
,
mnSecn
);
if
(
meRefMode
!=
REFMODE_CENTERED
)
meRefMode
=
(
meRefMode
==
REFMODE_BEGIN
)
?
REFMODE_END
:
REFMODE_BEGIN
;
return
*
this
;
}
Style
Style
::
Mirror
()
const
{
return
Style
(
*
this
).
MirrorSelf
();
}
bool
operator
==
(
const
Style
&
rL
,
const
Style
&
rR
)
{
return
(
rL
.
Prim
()
==
rR
.
Prim
())
&&
(
rL
.
Dist
()
==
rR
.
Dist
())
&&
(
rL
.
Secn
()
==
rR
.
Secn
())
&&
(
rL
.
GetColor
()
==
rR
.
GetColor
())
&&
(
rL
.
GetRefMode
()
==
rR
.
GetRefMode
())
&&
(
rL
.
Dotted
()
==
rR
.
Dotted
());
}
bool
operator
<
(
const
Style
&
rL
,
const
Style
&
rR
)
{
// different total widths -> rL<rR, if rL is thinner
sal_uInt16
nLW
=
rL
.
GetWidth
();
sal_uInt16
nRW
=
rR
.
GetWidth
();
if
(
nLW
!=
nRW
)
return
nLW
<
nRW
;
// one line double, the other single -> rL<rR, if rL is single
if
(
(
rL
.
Secn
()
==
0
)
!=
(
rR
.
Secn
()
==
0
)
)
return
rL
.
Secn
()
==
0
;
// both lines double with different distances -> rL<rR, if distance of rL greater
if
(
(
rL
.
Secn
()
&&
rR
.
Secn
())
&&
(
rL
.
Dist
()
!=
rR
.
Dist
())
)
return
rL
.
Dist
()
>
rR
.
Dist
();
// both lines single and 1 unit thick, only one is dotted -> rL<rR, if rL is dotted
if
(
(
nLW
==
1
)
&&
(
rL
.
Dotted
()
!=
rR
.
Dotted
())
)
return
rL
.
Dotted
();
// seem to be equal
return
false
;
}
#undef SCALEVALUE
// ============================================================================
// Various helper functions
// ============================================================================
double
GetHorDiagAngle
(
long
nWidth
,
long
nHeight
)
{
return
atan2
(
static_cast
<
double
>
(
Abs
(
nHeight
)
),
static_cast
<
double
>
(
Abs
(
nWidth
)
)
);
}
// ============================================================================
long
GetTLDiagOffset
(
long
nVerOffs
,
long
nDiagOffs
,
double
fAngle
)
{
return
lclD2L
(
nVerOffs
/
tan
(
fAngle
)
+
nDiagOffs
/
sin
(
fAngle
)
);
}
long
GetBLDiagOffset
(
long
nVerOffs
,
long
nDiagOffs
,
double
fAngle
)
{
return
lclD2L
(
-
nVerOffs
/
tan
(
fAngle
)
+
nDiagOffs
/
sin
(
fAngle
)
);
}
long
GetBRDiagOffset
(
long
nVerOffs
,
long
nDiagOffs
,
double
fAngle
)
{
return
-
lclD2L
(
-
nVerOffs
/
tan
(
fAngle
)
-
nDiagOffs
/
sin
(
fAngle
)
);
}
long
GetTRDiagOffset
(
long
nVerOffs
,
long
nDiagOffs
,
double
fAngle
)
{
return
-
lclD2L
(
nVerOffs
/
tan
(
fAngle
)
-
nDiagOffs
/
sin
(
fAngle
)
);
}
// ============================================================================
bool
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
)
{
return
// returns 1 AND (2a OR 2b)
// 1) only, if both frame borders are equal
(
rLBorder
==
rRBorder
)
&&
(
(
// 2a) if the borders are not double, at least one of the vertical must not be double
!
rLBorder
.
Secn
()
&&
(
!
rTFromT
.
Secn
()
||
!
rBFromB
.
Secn
())
)
||
(
// 2b) if the borders are double, all other borders must not be double
rLBorder
.
Secn
()
&&
!
rTFromTL
.
Secn
()
&&
!
rTFromT
.
Secn
()
&&
!
rTFromTR
.
Secn
()
&&
!
rBFromBL
.
Secn
()
&&
!
rBFromB
.
Secn
()
&&
!
rBFromBR
.
Secn
()
)
);
}
// ============================================================================
// Drawing functions
// ============================================================================
void
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
)
{
if
(
rBorder
.
Prim
()
)
{
BorderResult
aResult
;
lclLinkHorFrameBorder
(
aResult
,
rBorder
,
rLFromTR
,
rLFromT
,
rLFromL
,
rLFromB
,
rLFromBR
,
rRFromTL
,
rRFromT
,
rRFromR
,
rRFromB
,
rRFromBL
);
lclDrawHorFrameBorder
(
rDev
,
rLPos
,
rRPos
,
rBorder
,
aResult
,
pForceColor
);
}
}
void
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
)
{
/* Recycle complex version of the DrawHorFrameBorder() function with empty diagonals. */
const
DiagStyle
aNoStyle
;
DrawHorFrameBorder
(
rDev
,
rLPos
,
rRPos
,
rBorder
,
aNoStyle
,
rLFromT
,
rLFromL
,
rLFromB
,
aNoStyle
,
aNoStyle
,
rRFromT
,
rRFromR
,
rRFromB
,
aNoStyle
,
pForceColor
);
}
void
DrawHorFrameBorder
(
OutputDevice
&
rDev
,
const
Point
&
rLPos
,
const
Point
&
rRPos
,
const
Style
&
rBorder
,
const
Color
*
pForceColor
)
{
if
(
rBorder
.
Prim
()
)
lclDrawHorFrameBorder
(
rDev
,
rLPos
,
rRPos
,
rBorder
,
BorderResult
(),
pForceColor
);
}
// ----------------------------------------------------------------------------
void
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
)
{
if
(
rBorder
.
Prim
()
)
{
BorderResult
aResult
;
lclLinkVerFrameBorder
(
aResult
,
rBorder
,
rTFromBL
,
rTFromL
,
rTFromT
,
rTFromR
,
rTFromBR
,
rBFromTL
,
rBFromL
,
rBFromB
,
rBFromR
,
rBFromTR
);
lclDrawVerFrameBorder
(
rDev
,
rTPos
,
rBPos
,
rBorder
,
aResult
,
pForceColor
);
}
}
void
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
)
{
/* Recycle complex version of the DrawVerFrameBorder() function with empty diagonals. */
const
DiagStyle
aNoStyle
;
DrawVerFrameBorder
(
rDev
,
rTPos
,
rBPos
,
rBorder
,
aNoStyle
,
rTFromL
,
rTFromT
,
rTFromR
,
aNoStyle
,
aNoStyle
,
rBFromL
,
rBFromB
,
rBFromR
,
aNoStyle
,
pForceColor
);
}
void
DrawVerFrameBorder
(
OutputDevice
&
rDev
,
const
Point
&
rTPos
,
const
Point
&
rBPos
,
const
Style
&
rBorder
,
const
Color
*
pForceColor
)
{
if
(
rBorder
.
Prim
()
)
lclDrawVerFrameBorder
(
rDev
,
rTPos
,
rBPos
,
rBorder
,
BorderResult
(),
pForceColor
);
}
// ----------------------------------------------------------------------------
void
DrawVerFrameBorderSlanted
(
OutputDevice
&
rDev
,
const
Point
&
rTPos
,
const
Point
&
rBPos
,
const
Style
&
rBorder
,
const
Color
*
pForceColor
)
{
DBG_ASSERT
(
rTPos
.
Y
()
<
rBPos
.
Y
(),
"svx::frame::DrawVerFrameBorderSlanted - wrong order of line ends"
);
if
(
rBorder
.
Prim
()
&&
(
rTPos
.
Y
()
<
rBPos
.
Y
())
)
{
if
(
rTPos
.
X
()
==
rBPos
.
X
()
)
{
DrawVerFrameBorder
(
rDev
,
rTPos
,
rBPos
,
rBorder
,
pForceColor
);
}
else
{
const
LineEndResult
aRes
;
Style
aScaled
(
rBorder
);
aScaled
.
ScaleSelf
(
1.0
/
cos
(
GetVerDiagAngle
(
rTPos
,
rBPos
)
)
);
lclSetColorToOutDev
(
rDev
,
aScaled
,
pForceColor
);
lclDrawVerLine
(
rDev
,
rTPos
,
aRes
,
rBPos
,
aRes
,
lclGetBeg
(
aScaled
),
lclGetPrimEnd
(
aScaled
),
aScaled
.
Dotted
()
);
if
(
aScaled
.
Secn
()
)
lclDrawVerLine
(
rDev
,
rTPos
,
aRes
,
rBPos
,
aRes
,
lclGetSecnBeg
(
aScaled
),
lclGetEnd
(
aScaled
),
aScaled
.
Dotted
()
);
rDev
.
Pop
();
// colors
}
}
}
// ============================================================================
void
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
)
{
if
(
rTLBR
.
Prim
()
||
rBLTR
.
Prim
()
)
{
DiagBordersResult
aResult
;
lclLinkDiagFrameBorders
(
aResult
,
rTLBR
,
rBLTR
,
rTLFromB
,
rTLFromR
,
rBRFromT
,
rBRFromL
,
rBLFromT
,
rBLFromR
,
rTRFromB
,
rTRFromL
);
lclDrawDiagFrameBorders
(
rDev
,
rRect
,
rTLBR
,
rBLTR
,
aResult
,
pForceColor
,
bDiagDblClip
);
}
}
// ============================================================================
}
// namespace frame
}
// namespace svx
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment