summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-20 15:11:30 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-28 17:51:56 +0200
commite32c12a444e5bd0c6735db8e8008340c29a7e25e (patch)
tree50262efd53047ee92f5f39f9a1fd6c9e00917fc7 /svx
parent1118e5b986e4df8a417edcd4ee23a40fb64a0a38 (diff)
borderline: adaptions to primitives
Handling and paint of borderlines greatly adapted to primitive usage. Solved the double paint mechanisn to no longer use the sc-local special cases. The svx tooling for borderline paint is now the only one and was extended to also handle diagonal lines. Big cleanups/removals of old paint to OutputDevice and sc-specific rendering. All other app-usages of borderline also adapted. Preparations for careful line-start/end adaption prepared and possible due to unified coordinate-system usages and basegfx class-usage Change-Id: If9e4efcfc0fe25e14d4052907038ca5cf222a432
Diffstat (limited to 'svx')
-rw-r--r--svx/source/dialog/framelink.cxx1216
-rw-r--r--svx/source/dialog/framelinkarray.cxx577
-rw-r--r--svx/source/dialog/frmsel.cxx45
3 files changed, 361 insertions, 1477 deletions
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 3dd1b5fa1e2b..c193285b1a25 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -44,146 +44,6 @@ 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
-
- explicit LineEndResult() : mnOffs1( 0 ), mnOffs2( 0 ) {}
-
- void Swap() { std::swap( mnOffs1, mnOffs2 ); }
- 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.
- LineEndResult maGap; /// Result for gap line.
-
- void Negate() { maPrim.Negate(); maSecn.Negate(); maGap.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.
-
- 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 tools::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 )
{
@@ -196,920 +56,6 @@ double lclScaleValue( double nValue, double fScale, sal_uInt16 nMaxWidth )
return std::min<double>(nValue * fScale, nMaxWidth);
}
-
-// 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;
- case RefMode::Begin: 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;
- case RefMode::End: 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() && rtl::math::approxEqual(rLFromT.GetWidth(), rLFromB.GetWidth())) ?
- // don't overdraw vertical borders with equal width
- lclGetBehindEnd( rLFromT ) :
- // take leftmost start of both secondary lines (#46488#)
- std::min( lclGetSecnBeg( rLFromT ), lclGetSecnBeg( rLFromB ) );
- }
-
- // single border with equal width coming from left
- else if( !rLFromL.Secn() && rtl::math::approxEqual(rLFromL.Prim(), rBorder.Prim()) )
- // draw to connection point
- rResult.mnOffs1 = 0;
-
- // single border coming from left
- else if( !rLFromL.Secn() && rLFromL.Prim() )
- {
- if( rtl::math::approxEqual(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 = rtl::math::approxEqual(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 = rtl::math::approxEqual(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();
-}
-
-void lclLinkLeftEnd_Gap(
- LineEndResult& rResult, const Style& rBorder,
- const DiagStyle& /*rLFromTR*/, const Style& rLFromT, const Style& rLFromL, const Style& rLFromB, const DiagStyle& /*rLFromBR*/ )
-
-{
- if ( rLFromT.Secn() )
- rResult.mnOffs1 = lclGetDistBeg( rLFromT );
- else if ( rLFromL.Secn( ) )
- rResult.mnOffs1 = rtl::math::approxEqual( rLFromL.GetWidth(), rBorder.GetWidth() ) ?
- 0 : lclGetBehindEnd( rLFromT );
- else if ( rLFromB.Secn( ) )
- rResult.mnOffs1 = lclGetDistBeg( rLFromB );
- else
- rResult.mnOffs1 = std::max( lclGetBehindEnd( rLFromT ), lclGetBehindEnd( rLFromB ) );
-
- rResult.mnOffs2 = rResult.mnOffs1;
-}
-
-// 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 );
- lclLinkLeftEnd_Gap( rResult.maGap, 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
- {
- SAL_WARN( "svx.dialog", "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 );
-}
-
-
-// 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 tools::Polygon lclCreatePolygon( const PointVec& rPoints )
-{
- return tools::Polygon( static_cast< sal_uInt16 >( rPoints.size() ), &rPoints[ 0 ] );
-}
-
-/** Returns a polygon constructed from the five passed points. */
-vcl::Region 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 vcl::Region(lclCreatePolygon(aPoints));
-}
-
-/** 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 Color& rColor, const Color* pForceColor )
-{
- rDev.Push( PushFlags::LINECOLOR | PushFlags::FILLCOLOR );
- rDev.SetLineColor( pForceColor ? *pForceColor : rColor );
- rDev.SetFillColor( pForceColor ? *pForceColor : rColor );
-}
-
-
-// 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, SvxBorderLineStyle nDashing )
-{
- LinePoints aTPoints( rLPos + lclToMapUnit( rLRes.mnOffs1, nTOffs ), rRPos + lclToMapUnit( rRRes.mnOffs1, nTOffs ) );
- LinePoints aBPoints( rLPos + lclToMapUnit( rLRes.mnOffs2, nBOffs ), rRPos + lclToMapUnit( rRRes.mnOffs2, nBOffs ) );
-
- sal_uInt32 nWidth = lclToMapUnit( std::abs( nTOffs ) ) + lclToMapUnit( std::abs( nBOffs ) );
- if ( ( nTOffs >= 0 && nBOffs >= 0 ) || ( nTOffs <= 0 && nBOffs <= 0 ) )
- nWidth = std::abs( lclToMapUnit( nTOffs ) - lclToMapUnit( nBOffs ) ) + 1;
- Point rLMid = ( aTPoints.maBeg + aBPoints.maBeg ) / 2;
- Point rRMid = ( aTPoints.maEnd + aBPoints.maEnd ) / 2;
-
- ::svtools::DrawLine( rDev, rLMid, rRMid, nWidth, nDashing );
-}
-
-/** 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() )
- {
- if ( rBorder.UseGapColor( ) )
- {
- lclSetColorToOutDev( rDev, rBorder.GetColorGap(), pForceColor );
- lclDrawHorLine( rDev, rLPos, rResult.maBeg.maGap, rRPos, rResult.maEnd.maGap,
- lclGetPrimEnd( rBorder ), lclGetSecnBeg( rBorder ), rBorder.Type() );
- rDev.Pop(); // Gap color
- }
-
- lclSetColorToOutDev( rDev, rBorder.GetColorPrim(), pForceColor );
- lclDrawHorLine( rDev, rLPos, rResult.maBeg.maPrim, rRPos, rResult.maEnd.maPrim,
- lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Type() );
- rDev.Pop(); // colors
-
- if( rBorder.Secn() )
- {
- lclSetColorToOutDev( rDev, rBorder.GetColorSecn(), pForceColor );
- lclDrawHorLine( rDev, rLPos, rResult.maBeg.maSecn, rRPos, rResult.maEnd.maSecn,
- lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Type() );
- 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, SvxBorderLineStyle nDashing )
-{
- LinePoints aLPoints( rTPos + lclToMapUnit( nLOffs, rTRes.mnOffs1 ), rBPos + lclToMapUnit( nLOffs, rBRes.mnOffs1 ) );
- LinePoints aRPoints( rTPos + lclToMapUnit( nROffs, rTRes.mnOffs2 ), rBPos + lclToMapUnit( nROffs, rBRes.mnOffs2 ) );
-
- sal_uInt32 nWidth = lclToMapUnit( std::abs( nLOffs ) ) + lclToMapUnit( std::abs( nROffs ) );
- if ( ( nLOffs >= 0 && nROffs >= 0 ) || ( nLOffs <= 0 && nROffs <= 0 ) )
- nWidth = std::abs( lclToMapUnit( nLOffs ) - lclToMapUnit( nROffs ) ) + 1;
- Point rTMid = ( aLPoints.maBeg + aRPoints.maBeg ) / 2;
- Point rBMid = ( aLPoints.maEnd + aRPoints.maEnd ) / 2;
-
- ::svtools::DrawLine( rDev, rTMid, rBMid, nWidth, nDashing );
-}
-
-/** 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() )
- {
- if ( rBorder.UseGapColor( ) )
- {
- lclSetColorToOutDev( rDev, rBorder.GetColorGap(), pForceColor );
- lclDrawVerLine( rDev, rTPos, rResult.maBeg.maGap, rBPos, rResult.maEnd.maGap,
- lclGetPrimEnd( rBorder ), lclGetSecnBeg( rBorder ), rBorder.Type() );
- rDev.Pop(); // Gap color
- }
-
- lclSetColorToOutDev( rDev, rBorder.GetColorPrim(), pForceColor );
- lclDrawVerLine( rDev, rTPos, rResult.maBeg.maPrim, rBPos, rResult.maEnd.maPrim,
- lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Type() );
- rDev.Pop(); // colors
- if( rBorder.Secn() )
- {
- lclSetColorToOutDev( rDev, rBorder.GetColorSecn(), pForceColor );
- lclDrawVerLine( rDev, rTPos, rResult.maBeg.maSecn, rBPos, rResult.maEnd.maSecn,
- lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Type() );
- rDev.Pop(); // colors
- }
- }
-}
-
-
-// Drawing of diagonal frame borders, includes 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 tools::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( nDiagOffs, fAngle );
- long nBOffs = bTLBR ? GetBRDiagOffset( 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 rectangle.
-
- 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 tools::Rectangle& rRect, const DiagLineResult& rResult )
-{
- // PixelToLogic() regards internal offset of the output device
- tools::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( PushFlags::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 tools::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 ) ) );
-
- vcl::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( PushFlags::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 tools::Rectangle& rRect, bool bTLBR,
- const DiagLineResult& rResult, long nDiagOffs1, long nDiagOffs2, SvxBorderLineStyle nDashing )
-{
- lclPushDiagClipRect( rDev, rRect, rResult );
- LinePoints aLPoints( lclGetDiagLineEnds( rRect, bTLBR, nDiagOffs1 ) );
- LinePoints aL2Points( lclGetDiagLineEnds( rRect, bTLBR, nDiagOffs2 ) );
- Point aSMid( ( aLPoints.maBeg + aL2Points.maBeg ) / 2 );
- Point aEMid( ( aLPoints.maEnd + aL2Points.maEnd ) / 2 );
-
- sal_uInt32 nWidth = lclToMapUnit( std::abs( nDiagOffs1 ) ) + lclToMapUnit( std::abs( nDiagOffs2 ) );
- if ( ( nDiagOffs1 <= 0 && nDiagOffs2 <= 0 ) || ( nDiagOffs1 >=0 && nDiagOffs2 >=0 ) )
- nWidth = lclToMapUnit( std::abs( nDiagOffs1 - nDiagOffs2 ) );
-
- svtools::DrawLine( rDev, aSMid, aEMid, nWidth, nDashing );
- 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 tools::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.GetColorPrim(), pForceColor );
- lclDrawDiagLine( rDev, rRect, bTLBR, rResult.maPrim, lclGetBeg( rBorder ), lclGetPrimEnd( rBorder ), rBorder.Type() );
- rDev.Pop(); // colors
- if( rBorder.Secn() )
- {
- if ( rBorder.UseGapColor( ) )
- {
- lclSetColorToOutDev( rDev, rBorder.GetColorGap(), pForceColor );
- lclDrawDiagLine( rDev, rRect, bTLBR, rResult.maSecn, lclGetDistBeg( rBorder ), lclGetDistEnd( rBorder ), rBorder.Type() );
- rDev.Pop(); // colors
- }
-
- lclSetColorToOutDev( rDev, rBorder.GetColorSecn(), pForceColor );
- lclDrawDiagLine( rDev, rRect, bTLBR, rResult.maSecn, lclGetSecnBeg( rBorder ), lclGetEnd( rBorder ), rBorder.Type() );
- 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 tools::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
@@ -1121,7 +67,8 @@ void lclDrawDiagFrameBorders(
Style::Style() :
meRefMode(RefMode::Centered),
mfPatternScale(1.0),
- mnType(SvxBorderLineStyle::SOLID)
+ mnType(SvxBorderLineStyle::SOLID),
+ mpUsingCell(nullptr)
{
Clear();
}
@@ -1129,7 +76,8 @@ Style::Style() :
Style::Style( double nP, double nD, double nS, SvxBorderLineStyle nType ) :
meRefMode(RefMode::Centered),
mfPatternScale(1.0),
- mnType(nType)
+ mnType(nType),
+ mpUsingCell(nullptr)
{
Clear();
Set( nP, nD, nS );
@@ -1139,14 +87,16 @@ Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rCo
double nP, double nD, double nS, SvxBorderLineStyle nType ) :
meRefMode(RefMode::Centered),
mfPatternScale(1.0),
- mnType(nType)
+ mnType(nType),
+ mpUsingCell(nullptr)
{
Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS );
}
Style::Style( const editeng::SvxBorderLine* pBorder, double fScale ) :
meRefMode(RefMode::Centered),
- mfPatternScale(fScale)
+ mfPatternScale(fScale),
+ mpUsingCell(nullptr)
{
Set( pBorder, fScale );
}
@@ -1293,35 +243,16 @@ bool operator<( const Style& rL, const Style& rR )
// Various helper functions
-
-
double GetHorDiagAngle( long nWidth, long nHeight )
{
return atan2( static_cast< double >( std::abs( nHeight ) ), static_cast< double >( std::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 nDiagOffs, double fAngle )
-{
- return -lclD2L( - nDiagOffs / sin( fAngle ) );
-}
-
-long GetTRDiagOffset( long nDiagOffs, double fAngle )
-{
- return -lclD2L( - 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 )
@@ -1347,7 +278,6 @@ bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
// Drawing functions
-
// get offset to center of line in question
double lcl_getCenterOfLineOffset(const Style& rBorder, bool bLeftEdge)
{
@@ -1417,8 +347,9 @@ double lcl_GetExtent(
void CreateBorderPrimitives(
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
- const Point& rLPos,
- const Point& rRPos,
+ const basegfx::B2DPoint& rOrigin,
+ const basegfx::B2DVector& rX,
+ const basegfx::B2DVector& rY,
const Style& rBorder,
const DiagStyle& /*rLFromTR*/,
const Style& rLFromT,
@@ -1430,14 +361,14 @@ void CreateBorderPrimitives(
const Style& /*rRFromR*/,
const Style& rRFromB,
const DiagStyle& /*rRFromBL*/,
- const Color* /*pForceColor*/,
- const long nRotateT,
- const long nRotateB)
+ const Color* pForceColor)
{
if (rBorder.Prim() || rBorder.Secn())
{
- basegfx::B2DPoint aStart(rLPos.getX(), rLPos.getY());
- basegfx::B2DPoint aEnd(rRPos.getX(), rRPos.getY());
+ basegfx::B2DPoint aStart(rOrigin);
+ basegfx::B2DPoint aEnd(rOrigin + rX);
+ const long nRotateT = 9000; /// Angle of the top slanted frames in 100th of degree
+ const long nRotateB = 9000; /// Angle of the bottom slanted frames in 100th of degree
rTarget.append(
drawinglayer::primitive2d::Primitive2DReference(
@@ -1450,17 +381,18 @@ void CreateBorderPrimitives(
lcl_GetExtent(rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000, true, true), // top-right
lcl_GetExtent(rBorder, rLFromB, rLFromT, nRotateB, -nRotateT, false, false), // bottom-left
lcl_GetExtent(rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000, false, true), // bottom-right
- rBorder.GetColorSecn().getBColor(),
- rBorder.GetColorPrim().getBColor(),
- rBorder.GetColorGap().getBColor(),
+ (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
+ (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
+ (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale())));
}
}
void CreateBorderPrimitives(
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
- const Point& rLPos,
- const Point& rRPos,
+ const basegfx::B2DPoint& rOrigin,
+ const basegfx::B2DVector& rX,
+ const basegfx::B2DVector& rY,
const Style& rBorder,
const Style& rLFromT,
const Style& rLFromL,
@@ -1468,16 +400,15 @@ void CreateBorderPrimitives(
const Style& rRFromT,
const Style& rRFromR,
const Style& rRFromB,
- const Color* pForceColor,
- const long nRotateT,
- const long nRotateB)
+ const Color* pForceColor)
{
if (rBorder.Prim() || rBorder.Secn())
{
CreateBorderPrimitives(
rTarget,
- rLPos,
- rRPos,
+ rOrigin,
+ rX,
+ rY,
rBorder,
DiagStyle(),
rLFromT,
@@ -1489,15 +420,15 @@ void CreateBorderPrimitives(
rRFromR,
rRFromB,
DiagStyle(),
- pForceColor,
- nRotateT,
- nRotateB);
+ pForceColor);
}
}
void CreateDiagFrameBorderPrimitives(
drawinglayer::primitive2d::Primitive2DContainer& rTarget,
- const basegfx::B2DRange& rRange,
+ const basegfx::B2DPoint& rOrigin,
+ const basegfx::B2DVector& rXAxis,
+ const basegfx::B2DVector& rYAxis,
const Style& rTLBR,
const Style& rBLTR,
const Style& rTLFromB,
@@ -1508,23 +439,25 @@ void CreateDiagFrameBorderPrimitives(
const Style& rBLFromR,
const Style& rTRFromB,
const Style& rTRFromL,
- const Color* /*pForceColor*/,
- const long /*nRotationT*/,
- const long /*nRotationB*/)
+ const Color* pForceColor)
{
if (rTLBR.Prim())
{
+ // top-left to bottom-right
rTarget.append(
new drawinglayer::primitive2d::BorderLinePrimitive2D(
- rRange.getMinimum(),
- rRange.getMaximum(),
+ rOrigin,
+ rOrigin + rXAxis + rYAxis,
rTLBR.Prim(),
rTLBR.Dist(),
rTLBR.Secn(),
- 0.0, 0.0, 0.0, 0.0,
- rTLBR.GetColorSecn().getBColor(),
- rTLBR.GetColorPrim().getBColor(),
- rTLBR.GetColorGap().getBColor(),
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor(),
+ (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor(),
+ (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor(),
rTLBR.UseGapColor(),
rTLBR.Type(),
rTLBR.PatternScale()));
@@ -1532,73 +465,26 @@ void CreateDiagFrameBorderPrimitives(
if (rBLTR.Prim())
{
+ // bottom-left to top-right
rTarget.append(
new drawinglayer::primitive2d::BorderLinePrimitive2D(
- basegfx::B2DPoint(rRange.getMinX(), rRange.getMaxY()),
- basegfx::B2DPoint(rRange.getMaxX(), rRange.getMinY()),
+ rOrigin + rYAxis,
+ rOrigin + rXAxis,
rBLTR.Prim(),
rBLTR.Dist(),
rBLTR.Secn(),
- 0.0, 0.0, 0.0, 0.0,
- rBLTR.GetColorSecn().getBColor(),
- rBLTR.GetColorPrim().getBColor(),
- rBLTR.GetColorGap().getBColor(),
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ (pForceColor ? *pForceColor : rBLTR.GetColorSecn()).getBColor(),
+ (pForceColor ? *pForceColor : rBLTR.GetColorPrim()).getBColor(),
+ (pForceColor ? *pForceColor : rBLTR.GetColorGap()).getBColor(),
rBLTR.UseGapColor(),
rBLTR.Type(),
rBLTR.PatternScale()));
}
}
-
-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 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 DrawDiagFrameBorders(
- OutputDevice& rDev, const tools::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 );
- }
-}
-
-
}
}
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 09f4e3a53376..839e9bef5d77 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -28,25 +28,52 @@
namespace svx {
namespace frame {
-struct Cell
+/// single exclusive friend method to change mpUsingCell at style when style
+/// is set at Cell, see friend definition for more info
+void exclusiveSetUsigCellAtStyle(Style& rStyle, const Cell* pCell) { rStyle.mpUsingCell = pCell; }
+
+class Cell
{
+private:
Style maLeft;
Style maRight;
Style maTop;
Style maBottom;
Style maTLBR;
Style maBLTR;
+
+public:
long mnAddLeft;
long mnAddRight;
long mnAddTop;
long mnAddBottom;
+
+ SvxRotateMode meRotMode;
+ double mfOrientation;
+
bool mbMergeOrig;
bool mbOverlapX;
bool mbOverlapY;
+public:
explicit Cell();
- bool IsMerged() const { return mbMergeOrig || mbOverlapX || mbOverlapY; }
+ void SetStyleLeft(const Style& rStyle) { maLeft = rStyle; exclusiveSetUsigCellAtStyle(maLeft, this); }
+ void SetStyleRight(const Style& rStyle) { maRight = rStyle; exclusiveSetUsigCellAtStyle(maRight, this); }
+ void SetStyleTop(const Style& rStyle) { maTop = rStyle; exclusiveSetUsigCellAtStyle(maTop, this); }
+ void SetStyleBottom(const Style& rStyle) { maBottom = rStyle; exclusiveSetUsigCellAtStyle(maBottom, this); }
+ void SetStyleTLBR(const Style& rStyle) { maTLBR = rStyle; exclusiveSetUsigCellAtStyle(maTLBR, this); }
+ void SetStyleBLTR(const Style& rStyle) { maBLTR = rStyle; exclusiveSetUsigCellAtStyle(maBLTR, this); }
+
+ const Style& GetStyleLeft() const { return maLeft; }
+ const Style& GetStyleRight() const { return maRight; }
+ const Style& GetStyleTop() const { return maTop; }
+ const Style& GetStyleBottom() const { return maBottom; }
+ const Style& GetStyleTLBR() const { return maTLBR; }
+ const Style& GetStyleBLTR() const { return maBLTR; }
+
+ bool IsMerged() const { return mbMergeOrig || mbOverlapX || mbOverlapY; }
+ bool IsRotated() const { return mfOrientation != 0.0; }
void MirrorSelfX();
};
@@ -59,6 +86,8 @@ Cell::Cell() :
mnAddRight( 0 ),
mnAddTop( 0 ),
mnAddBottom( 0 ),
+ meRotMode(SvxRotateMode::SVX_ROTATE_MODE_STANDARD ),
+ mfOrientation( 0.0 ),
mbMergeOrig( false ),
mbOverlapX( false ),
mbOverlapY( false )
@@ -71,6 +100,7 @@ void Cell::MirrorSelfX()
std::swap( mnAddLeft, mnAddRight );
maLeft.MirrorSelf();
maRight.MirrorSelf();
+ mfOrientation = -mfOrientation;
}
@@ -119,9 +149,9 @@ struct ArrayImpl
size_t mnLastClipRow;
mutable bool mbXCoordsDirty;
mutable bool mbYCoordsDirty;
- bool mbDiagDblClip;
+ bool mbMayHaveCellRotation;
- explicit ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip );
+ explicit ArrayImpl( size_t nWidth, size_t nHeight );
bool IsValidPos( size_t nCol, size_t nRow ) const
{ return (nCol < mnWidth) && (nRow < mnHeight); }
@@ -157,9 +187,11 @@ struct ArrayImpl
double GetHorDiagAngle( size_t nCol, size_t nRow ) const;
double GetVerDiagAngle( size_t nCol, size_t nRow ) const;
+
+ bool HasCellRotation() const;
};
-ArrayImpl::ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip ) :
+ArrayImpl::ArrayImpl( size_t nWidth, size_t nHeight ) :
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFirstClipCol( 0 ),
@@ -168,7 +200,7 @@ ArrayImpl::ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip ) :
mnLastClipRow( nHeight - 1 ),
mbXCoordsDirty( false ),
mbYCoordsDirty( false ),
- mbDiagDblClip( bDiagDblClip )
+ mbMayHaveCellRotation( false )
{
// default-construct all vectors
maCells.resize( mnWidth * mnHeight );
@@ -318,6 +350,19 @@ double ArrayImpl::GetVerDiagAngle( size_t nCol, size_t nRow ) const
return (fAngle > 0.0) ? (F_PI2 - fAngle) : 0.0;
}
+bool ArrayImpl::HasCellRotation() const
+{
+ // check cell array
+ for (const auto& aCell : maCells)
+ {
+ if (aCell.IsRotated())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
class MergedCellIterator
{
@@ -385,8 +430,7 @@ Array::~Array()
// array size and column/row indexes
void Array::Initialize( size_t nWidth, size_t nHeight )
{
- bool bDiagDblClip = mxImpl.get() ? mxImpl->mbDiagDblClip : DIAG_DBL_CLIP_DEFAULT;
- mxImpl.reset( new ArrayImpl( nWidth, nHeight, bDiagDblClip ) );
+ mxImpl.reset( new ArrayImpl( nWidth, nHeight ) );
}
size_t Array::GetColCount() const
@@ -416,45 +460,45 @@ size_t Array::GetCellIndex( size_t nCol, size_t nRow, bool bRTL ) const
void Array::SetCellStyleLeft( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleLeft" );
- CELLACC( nCol, nRow ).maLeft = rStyle;
+ CELLACC( nCol, nRow ).SetStyleLeft(rStyle);
}
void Array::SetCellStyleRight( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleRight" );
- CELLACC( nCol, nRow ).maRight = rStyle;
+ CELLACC( nCol, nRow ).SetStyleRight(rStyle);
}
void Array::SetCellStyleTop( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTop" );
- CELLACC( nCol, nRow ).maTop = rStyle;
+ CELLACC( nCol, nRow ).SetStyleTop(rStyle);
}
void Array::SetCellStyleBottom( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBottom" );
- CELLACC( nCol, nRow ).maBottom = rStyle;
+ CELLACC( nCol, nRow ).SetStyleBottom(rStyle);
}
void Array::SetCellStyleTLBR( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTLBR" );
- CELLACC( nCol, nRow ).maTLBR = rStyle;
+ CELLACC( nCol, nRow ).SetStyleTLBR(rStyle);
}
void Array::SetCellStyleBLTR( size_t nCol, size_t nRow, const Style& rStyle )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBLTR" );
- CELLACC( nCol, nRow ).maBLTR = rStyle;
+ CELLACC( nCol, nRow ).SetStyleBLTR(rStyle);
}
void Array::SetCellStyleDiag( size_t nCol, size_t nRow, const Style& rTLBR, const Style& rBLTR )
{
DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleDiag" );
Cell& rCell = CELLACC( nCol, nRow );
- rCell.maTLBR = rTLBR;
- rCell.maBLTR = rBLTR;
+ rCell.SetStyleTLBR(rTLBR);
+ rCell.SetStyleBLTR(rBLTR);
}
void Array::SetColumnStyleLeft( size_t nCol, const Style& rStyle )
@@ -485,6 +529,32 @@ void Array::SetRowStyleBottom( size_t nRow, const Style& rStyle )
SetCellStyleBottom( nCol, nRow, rStyle );
}
+void Array::SetCellRotation(size_t nCol, size_t nRow, SvxRotateMode eRotMode, double fOrientation)
+{
+ DBG_FRAME_CHECK_COLROW(nCol, nRow, "SetCellRotation");
+ Cell& rTarget = CELLACC(nCol, nRow);
+ rTarget.meRotMode = eRotMode;
+ rTarget.mfOrientation = fOrientation;
+
+ if (!mxImpl->mbMayHaveCellRotation)
+ {
+ // activate once when a cell gets actually rotated to allow fast
+ // answering HasCellRotation() calls
+ mxImpl->mbMayHaveCellRotation = rTarget.IsRotated();
+ }
+}
+
+bool Array::HasCellRotation() const
+{
+ if (!mxImpl->mbMayHaveCellRotation)
+ {
+ // never set, no need to check
+ return false;
+ }
+
+ return mxImpl->HasCellRotation();
+}
+
const Style& Array::GetCellStyleLeft( size_t nCol, size_t nRow ) const
{
// outside clipping rows or overlapped in merged cells: invisible
@@ -492,15 +562,15 @@ const Style& Array::GetCellStyleLeft( size_t nCol, size_t nRow ) const
return OBJ_STYLE_NONE;
// left clipping border: always own left style
if( nCol == mxImpl->mnFirstClipCol )
- return ORIGCELL( nCol, nRow ).maLeft;
+ return ORIGCELL( nCol, nRow ).GetStyleLeft();
// right clipping border: always right style of left neighbor cell
if( nCol == mxImpl->mnLastClipCol + 1 )
- return ORIGCELL( nCol - 1, nRow ).maRight;
+ return ORIGCELL( nCol - 1, nRow ).GetStyleRight();
// outside clipping columns: invisible
if( !mxImpl->IsColInClipRange( nCol ) )
return OBJ_STYLE_NONE;
// inside clipping range: maximum of own left style and right style of left neighbor cell
- return std::max( ORIGCELL( nCol, nRow ).maLeft, ORIGCELL( nCol - 1, nRow ).maRight );
+ return std::max( ORIGCELL( nCol, nRow ).GetStyleLeft(), ORIGCELL( nCol - 1, nRow ).GetStyleRight() );
}
const Style& Array::GetCellStyleRight( size_t nCol, size_t nRow ) const
@@ -510,15 +580,15 @@ const Style& Array::GetCellStyleRight( size_t nCol, size_t nRow ) const
return OBJ_STYLE_NONE;
// left clipping border: always left style of right neighbor cell
if( nCol + 1 == mxImpl->mnFirstClipCol )
- return ORIGCELL( nCol + 1, nRow ).maLeft;
+ return ORIGCELL( nCol + 1, nRow ).GetStyleLeft();
// right clipping border: always own right style
if( nCol == mxImpl->mnLastClipCol )
- return ORIGCELL( nCol, nRow ).maRight;
+ return ORIGCELL( nCol, nRow ).GetStyleRight();
// outside clipping columns: invisible
if( !mxImpl->IsColInClipRange( nCol ) )
return OBJ_STYLE_NONE;
// inside clipping range: maximum of own right style and left style of right neighbor cell
- return std::max( ORIGCELL( nCol, nRow ).maRight, ORIGCELL( nCol + 1, nRow ).maLeft );
+ return std::max( ORIGCELL( nCol, nRow ).GetStyleRight(), ORIGCELL( nCol + 1, nRow ).GetStyleLeft() );
}
const Style& Array::GetCellStyleTop( size_t nCol, size_t nRow ) const
@@ -528,15 +598,15 @@ const Style& Array::GetCellStyleTop( size_t nCol, size_t nRow ) const
return OBJ_STYLE_NONE;
// top clipping border: always own top style
if( nRow == mxImpl->mnFirstClipRow )
- return ORIGCELL( nCol, nRow ).maTop;
+ return ORIGCELL( nCol, nRow ).GetStyleTop();
// bottom clipping border: always bottom style of top neighbor cell
if( nRow == mxImpl->mnLastClipRow + 1 )
- return ORIGCELL( nCol, nRow - 1 ).maBottom;
+ return ORIGCELL( nCol, nRow - 1 ).GetStyleBottom();
// outside clipping rows: invisible
if( !mxImpl->IsRowInClipRange( nRow ) )
return OBJ_STYLE_NONE;
// inside clipping range: maximum of own top style and bottom style of top neighbor cell
- return std::max( ORIGCELL( nCol, nRow ).maTop, ORIGCELL( nCol, nRow - 1 ).maBottom );
+ return std::max( ORIGCELL( nCol, nRow ).GetStyleTop(), ORIGCELL( nCol, nRow - 1 ).GetStyleBottom() );
}
const Style& Array::GetCellStyleBottom( size_t nCol, size_t nRow ) const
@@ -546,25 +616,25 @@ const Style& Array::GetCellStyleBottom( size_t nCol, size_t nRow ) const
return OBJ_STYLE_NONE;
// top clipping border: always top style of bottom neighbor cell
if( nRow + 1 == mxImpl->mnFirstClipRow )
- return ORIGCELL( nCol, nRow + 1 ).maTop;
+ return ORIGCELL( nCol, nRow + 1 ).GetStyleTop();
// bottom clipping border: always own bottom style
if( nRow == mxImpl->mnLastClipRow )
- return ORIGCELL( nCol, nRow ).maBottom;
+ return ORIGCELL( nCol, nRow ).GetStyleBottom();
// outside clipping rows: invisible
if( !mxImpl->IsRowInClipRange( nRow ) )
return OBJ_STYLE_NONE;
// inside clipping range: maximum of own bottom style and top style of bottom neighbor cell
- return std::max( ORIGCELL( nCol, nRow ).maBottom, ORIGCELL( nCol, nRow + 1 ).maTop );
+ return std::max( ORIGCELL( nCol, nRow ).GetStyleBottom(), ORIGCELL( nCol, nRow + 1 ).GetStyleTop() );
}
const Style& Array::GetCellStyleTLBR( size_t nCol, size_t nRow ) const
{
- return CELL( nCol, nRow ).maTLBR;
+ return CELL( nCol, nRow ).GetStyleTLBR();
}
const Style& Array::GetCellStyleBLTR( size_t nCol, size_t nRow ) const
{
- return CELL( nCol, nRow ).maBLTR;
+ return CELL( nCol, nRow ).GetStyleBLTR();
}
const Style& Array::GetCellStyleTL( size_t nCol, size_t nRow ) const
@@ -576,7 +646,7 @@ const Style& Array::GetCellStyleTL( size_t nCol, size_t nRow ) const
size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
return ((nCol == nFirstCol) && (nRow == nFirstRow)) ?
- CELL( nFirstCol, nFirstRow ).maTLBR : OBJ_STYLE_NONE;
+ CELL( nFirstCol, nFirstRow ).GetStyleTLBR() : OBJ_STYLE_NONE;
}
const Style& Array::GetCellStyleBR( size_t nCol, size_t nRow ) const
@@ -588,7 +658,7 @@ const Style& Array::GetCellStyleBR( size_t nCol, size_t nRow ) const
size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
return ((nCol == nLastCol) && (nRow == nLastRow)) ?
- CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), mxImpl->GetMergedFirstRow( nCol, nRow ) ).maTLBR : OBJ_STYLE_NONE;
+ CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), mxImpl->GetMergedFirstRow( nCol, nRow ) ).GetStyleTLBR() : OBJ_STYLE_NONE;
}
const Style& Array::GetCellStyleBL( size_t nCol, size_t nRow ) const
@@ -600,7 +670,7 @@ const Style& Array::GetCellStyleBL( size_t nCol, size_t nRow ) const
size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
return ((nCol == nFirstCol) && (nRow == nLastRow)) ?
- CELL( nFirstCol, mxImpl->GetMergedFirstRow( nCol, nRow ) ).maBLTR : OBJ_STYLE_NONE;
+ CELL( nFirstCol, mxImpl->GetMergedFirstRow( nCol, nRow ) ).GetStyleBLTR() : OBJ_STYLE_NONE;
}
const Style& Array::GetCellStyleTR( size_t nCol, size_t nRow ) const
@@ -612,7 +682,7 @@ const Style& Array::GetCellStyleTR( size_t nCol, size_t nRow ) const
size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
return ((nCol == nLastCol) && (nRow == nFirstRow)) ?
- CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), nFirstRow ).maBLTR : OBJ_STYLE_NONE;
+ CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), nFirstRow ).GetStyleBLTR() : OBJ_STYLE_NONE;
}
// cell merging
@@ -709,15 +779,6 @@ void Array::SetClipRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, s
mxImpl->mnLastClipRow = nLastRow;
}
-tools::Rectangle Array::GetClipRangeRectangle() const
-{
- return tools::Rectangle(
- mxImpl->GetColPosition( mxImpl->mnFirstClipCol ),
- mxImpl->GetRowPosition( mxImpl->mnFirstClipRow ),
- mxImpl->GetColPosition( mxImpl->mnLastClipCol + 1 ),
- mxImpl->GetRowPosition( mxImpl->mnLastClipRow + 1 ) );
-}
-
// cell coordinates
void Array::SetXOffset( long nXOffset )
{
@@ -838,11 +899,6 @@ double Array::GetVerDiagAngle( size_t nCol, size_t nRow ) const
return mxImpl->GetVerDiagAngle( nCol, nRow );
}
-void Array::SetUseDiagDoubleClipping( bool bSet )
-{
- mxImpl->mbDiagDblClip = bSet;
-}
-
// mirroring
void Array::MirrorSelfX()
{
@@ -879,6 +935,46 @@ void Array::MirrorSelfX()
}
// drawing
+
+void CreateCoordinateSystemForCell(
+ const basegfx::B2DRange& rRange,
+ const Cell& rCell,
+ basegfx::B2DPoint& rOrigin,
+ basegfx::B2DVector& rX,
+ basegfx::B2DVector& rY)
+{
+ // fill in defaults
+ rOrigin = rRange.getMinimum();
+ rX = basegfx::B2DVector(rRange.getWidth(), 0.0);
+ rY = basegfx::B2DVector(0.0, rRange.getHeight());
+
+ if (rCell.IsRotated() && SvxRotateMode::SVX_ROTATE_MODE_STANDARD != rCell.meRotMode)
+ {
+ // when rotated, adapt values. Get Skew (cos/sin == 1/tan)
+ const double fSkew(rRange.getHeight() * (cos(rCell.mfOrientation) / sin(rCell.mfOrientation)));
+
+ switch (rCell.meRotMode)
+ {
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ // shear Y-Axis
+ rY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_CENTER:
+ // shear origin half, Y full
+ rOrigin.setX(rOrigin.getX() + (fSkew * 0.5));
+ rY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ // shear origin full, Y full
+ rOrigin.setX(rOrigin.getX() + fSkew);
+ rY.setX(-fSkew);
+ break;
+ default: // SvxRotateMode::SVX_ROTATE_MODE_STANDARD, altready excluded above
+ break;
+ }
+ }
+}
+
void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
const Color* pForceColor ) const
@@ -898,10 +994,11 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
bool bOverlapY = rCell.mbOverlapY;
bool bFirstCol = nCol == nFirstCol;
bool bFirstRow = nRow == nFirstRow;
- if ((!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) ||
- (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow))
+
+ if ((!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) || (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow))
{
const tools::Rectangle aRect(GetCellRect(nCol, nRow));
+
if ((aRect.GetWidth() > 1) && (aRect.GetHeight() > 1))
{
size_t _nFirstCol = mxImpl->GetMergedFirstCol(nCol, nRow);
@@ -915,10 +1012,17 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
{
drawinglayer::primitive2d::Primitive2DContainer aSequence;
const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+ basegfx::B2DPoint aOrigin;
+ basegfx::B2DVector aX;
+ basegfx::B2DVector aY;
+
+ CreateCoordinateSystemForCell(aRange, rCell, aOrigin, aX, aY);
CreateDiagFrameBorderPrimitives(
aSequence,
- aRange,
+ aOrigin,
+ aX,
+ aY,
rTLBR,
rBLTR,
GetCellStyleLeft(_nFirstCol, _nFirstRow),
@@ -929,7 +1033,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
GetCellStyleBottom(_nFirstCol, _nLastRow),
GetCellStyleRight(_nLastCol, _nFirstRow),
GetCellStyleTop(_nLastCol, _nFirstRow),
- nullptr);
+ pForceColor);
rProcessor.process(aSequence);
}
@@ -945,7 +1049,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
double fTAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow - 1 );
// *Start*** variables store the data of the left end of the cached frame border
- Point aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
+ basegfx::B2DPoint aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
const Style* pStart = &GetCellStyleTop( nFirstCol, nRow );
DiagStyle aStartLFromTR( GetCellStyleBL( nFirstCol, nRow - 1 ), fTAngle );
const Style* pStartLFromT = &GetCellStyleLeft( nFirstCol, nRow - 1 );
@@ -980,18 +1084,50 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
DiagStyle aRFromBL( GetCellStyleTR( nCol, nRow ), fAngle );
// check if current frame border can be connected to cached frame border
- if( !CheckFrameBorderConnectable( *pStart, rCurr,
- aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
+ if( !CheckFrameBorderConnectable( *pStart, rCurr, aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
{
// draw previous frame border
- Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if ((pStart->Prim() || pStart->Secn()) && (aStartPos.X() <= aEndPos.X()))
+ basegfx::B2DPoint aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.getY() );
+
+ if ((pStart->Prim() || pStart->Secn()) && (aStartPos.getX() <= aEndPos.getX()))
{
+ // prepare defaults for borderline coordinate system
+ basegfx::B2DPoint aOrigin(aStartPos);
+ basegfx::B2DVector aX(aEndPos - aStartPos);
+ basegfx::B2DVector aY(0.0, 1.0);
+ const Cell* pCell = pStart->GetUsingCell();
+
+ if (pCell && pCell->IsRotated())
+ {
+ // To apply the shear, we need to get the cell range. We have the defining cell,
+ // but there is no call at it to directly get it's range. To get the correct one,
+ // we need to take care if the borderline is at top or bottom, so use pointer
+ // compare here to find out
+ const bool bUpper(&pCell->GetStyleTop() == pStart);
+ const tools::Rectangle aRect(GetCellRect(nCol - 1, bUpper ? nRow : nRow - 1));
+ const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+
+ // adapt to cell coordinate system, including shear
+ CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
+
+ if (!bUpper)
+ {
+ // for the lower edge we need to translate to get to the
+ // borderline coordinate system. For the upper one, all is
+ // okay already
+ aOrigin += aY;
+ }
+
+ // borderline coordinate system uses normalized 2nd axis
+ aY.normalize();
+ }
+
drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
CreateBorderPrimitives(
aSequence,
- aStartPos,
- aEndPos,
+ aOrigin,
+ aX,
+ aY,
*pStart,
aStartLFromTR,
*pStartLFromT,
@@ -1026,14 +1162,38 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
}
// draw last frame border
- Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if ((pStart->Prim() || pStart->Secn()) && (aStartPos.X() <= aEndPos.X()))
+ basegfx::B2DPoint aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.getY() );
+ if ((pStart->Prim() || pStart->Secn()) && (aStartPos.getX() <= aEndPos.getX()))
{
+ // for description of involved coordinate systems have a look at
+ // the first CreateBorderPrimitives call above
+ basegfx::B2DPoint aOrigin(aStartPos);
+ basegfx::B2DVector aX(aEndPos - aStartPos);
+ basegfx::B2DVector aY(0.0, 1.0);
+ const Cell* pCell = pStart->GetUsingCell();
+
+ if (pCell && pCell->IsRotated())
+ {
+ const bool bUpper(&pCell->GetStyleTop() == pStart);
+ const tools::Rectangle aRect(GetCellRect(nCol - 1, bUpper ? nRow : nRow - 1));
+ const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+
+ CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
+
+ if (!bUpper)
+ {
+ aOrigin += aY;
+ }
+
+ aY.normalize();
+ }
+
drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
CreateBorderPrimitives(
aSequence,
- aStartPos,
- aEndPos,
+ aOrigin,
+ aX,
+ aY,
*pStart,
aStartLFromTR,
*pStartLFromT,
@@ -1057,7 +1217,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
double fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nFirstRow );
// *Start*** variables store the data of the top end of the cached frame border
- Point aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
+ basegfx::B2DPoint aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
const Style* pStart = &GetCellStyleLeft( nCol, nFirstRow );
DiagStyle aStartTFromBL( GetCellStyleTR( nCol - 1, nFirstRow ), fLAngle );
const Style* pStartTFromL = &GetCellStyleTop( nCol - 1, nFirstRow );
@@ -1096,9 +1256,38 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
aEndBFromTL, rTFromL, aTFromBL, aEndBFromTR, rTFromR, aTFromBR ) )
{
// draw previous frame border
- Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if ((pStart->Prim() || pStart->Secn()) && (aStartPos.Y() <= aEndPos.Y()))
+ basegfx::B2DPoint aEndPos( aStartPos.getX(), mxImpl->GetRowPosition( nRow ) );
+ if ((pStart->Prim() || pStart->Secn()) && (aStartPos.getY() <= aEndPos.getY()))
{
+ // for description of involved coordinate systems have a look at
+ // the first CreateBorderPrimitives call above. Additionally adapt to vertical
+ basegfx::B2DPoint aOrigin(aStartPos);
+ basegfx::B2DVector aX(aEndPos - aStartPos);
+ basegfx::B2DVector aY(-1.0, 0.0);
+ const Cell* pCell = pStart->GetUsingCell();
+
+ if (pCell && pCell->IsRotated())
+ {
+ const bool bLeft(&pCell->GetStyleLeft() == pStart);
+ const tools::Rectangle aRect(GetCellRect(bLeft ? nCol : nCol - 1, nRow - 1));
+ const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+
+ CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
+
+ if (!bLeft)
+ {
+ aOrigin += aX;
+ }
+
+ // The *coordinate system* of the edge has to be given, which for vertical
+ // lines uses the Y-Vector as X-Axis and the X-Vector as Y-Axis, so swap both
+ // and mirror aX to keep the same orientation (should be (-1.0, 0.0) for
+ // horizontal lines anyways, this could be used as thest here, checked in debug mode)
+ std::swap(aX, aY);
+ aY.normalize();
+ aY = -aY;
+ }
+
drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
CreateBorderPrimitives(
// This replaces DrawVerFrameBorder which went from top to bottom. To be able to use
@@ -1108,10 +1297,11 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
// In principle, the order of the five TFrom and BFrom has to be
// inverted to get the same orientation. Before, EndPos and StartPos were changed
// which avoids the reordering, but also leads to inverted line patters for vertical
- // lines
+ // lines.
aSequence,
- aStartPos,
- aEndPos,
+ aOrigin,
+ aX,
+ aY,
*pStart,
aStartTFromBR,
*pStartTFromR,
@@ -1146,15 +1336,44 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
}
// draw last frame border
- Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if ((pStart->Prim() || pStart->Secn()) && (aStartPos.Y() <= aEndPos.Y()))
+ basegfx::B2DPoint aEndPos( aStartPos.getX(), mxImpl->GetRowPosition( nRow ) );
+ if ((pStart->Prim() || pStart->Secn()) && (aStartPos.getY() <= aEndPos.getY()))
{
+ // for description of involved coordinate systems have a look at
+ // the first CreateBorderPrimitives call above, adapt to vertical
+ basegfx::B2DPoint aOrigin(aStartPos);
+ basegfx::B2DVector aX(aEndPos - aStartPos);
+ basegfx::B2DVector aY(-1.0, 0.0);
+ const Cell* pCell = pStart->GetUsingCell();
+
+ if (pCell && pCell->IsRotated())
+ {
+ const bool bLeft(&pCell->GetStyleLeft() == pStart);
+ const tools::Rectangle aRect(GetCellRect(bLeft ? nCol : nCol - 1, nRow - 1));
+ const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+
+ CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
+
+ if (!bLeft)
+ {
+ aOrigin += aX;
+ }
+
+ // The *coordinate system* of the edge has to be given, which for vertical
+ // lines uses the Y-Vector as X-Axis and the X-Vector as Y-Axis, so swap both
+ // and mirror aX to keep the same orientation (should be (-1.0, 0.0) for horizontal lines anyways)
+ std::swap(aX, aY);
+ aY.normalize();
+ aY = -aY;
+ }
+
drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
CreateBorderPrimitives(
// also reordered, see call to CreateBorderPrimitives above
aSequence,
- aStartPos,
- aEndPos,
+ aOrigin,
+ aX,
+ aY,
*pStart,
aStartTFromBR,
*pStartTFromR,
@@ -1172,224 +1391,12 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
}
}
-void Array::DrawRange( OutputDevice& rDev,
- size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow ) const
-{
- DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "DrawRange" );
- DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "DrawRange" );
-
- size_t nCol, nRow;
-
- // *** diagonal frame borders ***
-
- // set clipping region to clip partly visible merged cells
- rDev.Push( PushFlags::CLIPREGION );
- rDev.IntersectClipRegion( GetClipRangeRectangle() );
- for( nRow = nFirstRow; nRow <= nLastRow; ++nRow )
- {
- for( nCol = nFirstCol; nCol <= nLastCol; ++nCol )
- {
- const Cell& rCell = CELL( nCol, nRow );
- bool bOverlapX = rCell.mbOverlapX;
- bool bOverlapY = rCell.mbOverlapY;
- bool bFirstCol = nCol == nFirstCol;
- bool bFirstRow = nRow == nFirstRow;
- if( (!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) ||
- (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow) )
- {
- tools::Rectangle aRect( GetCellRect( nCol, nRow ) );
- if( (aRect.GetWidth() > 1) && (aRect.GetHeight() > 1) )
- {
- size_t _nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
- size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
- size_t _nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
- size_t _nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
-
- DrawDiagFrameBorders( rDev, aRect,
- GetCellStyleTLBR( _nFirstCol, _nFirstRow ), GetCellStyleBLTR( _nFirstCol, _nFirstRow ),
- GetCellStyleLeft( _nFirstCol, _nFirstRow ), GetCellStyleTop( _nFirstCol, _nFirstRow ),
- GetCellStyleRight( _nLastCol, _nLastRow ), GetCellStyleBottom( _nLastCol, _nLastRow ),
- GetCellStyleLeft( _nFirstCol, _nLastRow ), GetCellStyleBottom( _nFirstCol, _nLastRow ),
- GetCellStyleRight( _nLastCol, _nFirstRow ), GetCellStyleTop( _nLastCol, _nFirstRow ),
- nullptr, mxImpl->mbDiagDblClip );
- }
- }
- }
- }
- rDev.Pop(); // clip region
-
- // *** horizontal frame borders ***
-
- for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
- {
- double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
- double fTAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow - 1 );
-
- // *Start*** variables store the data of the left end of the cached frame border
- Point aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
- const Style* pStart = &GetCellStyleTop( nFirstCol, nRow );
- DiagStyle aStartLFromTR( GetCellStyleBL( nFirstCol, nRow - 1 ), fTAngle );
- const Style* pStartLFromT = &GetCellStyleLeft( nFirstCol, nRow - 1 );
- const Style* pStartLFromL = &GetCellStyleTop( nFirstCol - 1, nRow );
- const Style* pStartLFromB = &GetCellStyleLeft( nFirstCol, nRow );
- DiagStyle aStartLFromBR( GetCellStyleTL( nFirstCol, nRow ), fAngle );
-
- // *End*** variables store the data of the right end of the cached frame border
- DiagStyle aEndRFromTL( GetCellStyleBR( nFirstCol, nRow - 1 ), fTAngle );
- const Style* pEndRFromT = &GetCellStyleRight( nFirstCol, nRow - 1 );
- const Style* pEndRFromR = &GetCellStyleTop( nFirstCol + 1, nRow );
- const Style* pEndRFromB = &GetCellStyleRight( nFirstCol, nRow );
- DiagStyle aEndRFromBL( GetCellStyleTR( nFirstCol, nRow ), fAngle );
-
- for( nCol = nFirstCol + 1; nCol <= nLastCol; ++nCol )
- {
- fAngle = mxImpl->GetHorDiagAngle( nCol, nRow );
- fTAngle = mxImpl->GetHorDiagAngle( nCol, nRow - 1 );
-
- const Style& rCurr = *pEndRFromR;
-
- DiagStyle aLFromTR( GetCellStyleBL( nCol, nRow - 1 ), fTAngle );
- const Style& rLFromT = *pEndRFromT;
- const Style& rLFromL = *pStart;
- const Style& rLFromB = *pEndRFromB;
- DiagStyle aLFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
-
- DiagStyle aRFromTL( GetCellStyleBR( nCol, nRow - 1 ), fTAngle );
- const Style& rRFromT = GetCellStyleRight( nCol, nRow - 1 );
- const Style& rRFromR = GetCellStyleTop( nCol + 1, nRow );
- const Style& rRFromB = GetCellStyleRight( nCol, nRow );
- DiagStyle aRFromBL( GetCellStyleTR( nCol, nRow ), fAngle );
-
- // check if current frame border can be connected to cached frame border
- if( !CheckFrameBorderConnectable( *pStart, rCurr,
- aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
- {
- // draw previous frame border
- Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
- DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
- aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
- aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL );
-
- // re-init "*Start***" variables
- aStartPos = aEndPos;
- pStart = &rCurr;
- aStartLFromTR = aLFromTR;
- pStartLFromT = &rLFromT;
- pStartLFromL = &rLFromL;
- pStartLFromB = &rLFromB;
- aStartLFromBR = aLFromBR;
- }
-
- // store current styles in "*End***" variables
- aEndRFromTL = aRFromTL;
- pEndRFromT = &rRFromT;
- pEndRFromR = &rRFromR;
- pEndRFromB = &rRFromB;
- aEndRFromBL = aRFromBL;
- }
-
- // draw last frame border
- Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
- DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
- aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
- aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL );
- }
-
- // *** vertical frame borders ***
-
- for( nCol = nFirstCol; nCol <= nLastCol + 1; ++nCol )
- {
- double fAngle = mxImpl->GetVerDiagAngle( nCol, nFirstRow );
- double fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nFirstRow );
-
- // *Start*** variables store the data of the top end of the cached frame border
- Point aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
- const Style* pStart = &GetCellStyleLeft( nCol, nFirstRow );
- DiagStyle aStartTFromBL( GetCellStyleTR( nCol - 1, nFirstRow ), fLAngle );
- const Style* pStartTFromL = &GetCellStyleTop( nCol - 1, nFirstRow );
- const Style* pStartTFromT = &GetCellStyleLeft( nCol, nFirstRow - 1 );
- const Style* pStartTFromR = &GetCellStyleTop( nCol, nFirstRow );
- DiagStyle aStartTFromBR( GetCellStyleTL( nCol, nFirstRow ), fAngle );
-
- // *End*** variables store the data of the bottom end of the cached frame border
- DiagStyle aEndBFromTL( GetCellStyleBR( nCol - 1, nFirstRow ), fLAngle );
- const Style* pEndBFromL = &GetCellStyleBottom( nCol - 1, nFirstRow );
- const Style* pEndBFromB = &GetCellStyleLeft( nCol, nFirstRow + 1 );
- const Style* pEndBFromR = &GetCellStyleBottom( nCol, nFirstRow );
- DiagStyle aEndBFromTR( GetCellStyleBL( nCol, nFirstRow ), fAngle );
-
- for( nRow = nFirstRow + 1; nRow <= nLastRow; ++nRow )
- {
- fAngle = mxImpl->GetVerDiagAngle( nCol, nRow );
- fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nRow );
-
- const Style& rCurr = *pEndBFromB;
-
- DiagStyle aTFromBL( GetCellStyleTR( nCol - 1, nRow ), fLAngle );
- const Style& rTFromL = *pEndBFromL;
- const Style& rTFromT = *pStart;
- const Style& rTFromR = *pEndBFromR;
- DiagStyle aTFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
-
- DiagStyle aBFromTL( GetCellStyleBR( nCol - 1, nRow ), fLAngle );
- const Style& rBFromL = GetCellStyleBottom( nCol - 1, nRow );
- const Style& rBFromB = GetCellStyleLeft( nCol, nRow + 1 );
- const Style& rBFromR = GetCellStyleBottom( nCol, nRow );
- DiagStyle aBFromTR( GetCellStyleBL( nCol, nRow ), fAngle );
-
- // check if current frame border can be connected to cached frame border
- if( !CheckFrameBorderConnectable( *pStart, rCurr,
- aEndBFromTL, rTFromL, aTFromBL, aEndBFromTR, rTFromR, aTFromBR ) )
- {
- // draw previous frame border
- Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
- DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
- aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
- aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR );
-
- // re-init "*Start***" variables
- aStartPos = aEndPos;
- pStart = &rCurr;
- aStartTFromBL = aTFromBL;
- pStartTFromL = &rTFromL;
- pStartTFromT = &rTFromT;
- pStartTFromR = &rTFromR;
- aStartTFromBR = aTFromBR;
- }
-
- // store current styles in "*End***" variables
- aEndBFromTL = aBFromTL;
- pEndBFromL = &rBFromL;
- pEndBFromB = &rBFromB;
- pEndBFromR = &rBFromR;
- aEndBFromTR = aBFromTR;
- }
-
- // draw last frame border
- Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
- DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
- aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
- aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR );
- }
-}
-
-void Array::DrawArray( OutputDevice& rDev ) const
-{
- if( mxImpl->mnWidth && mxImpl->mnHeight )
- DrawRange( rDev, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1 );
-}
-
void Array::DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const
{
if (mxImpl->mnWidth && mxImpl->mnHeight)
DrawRange(rProcessor, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, nullptr);
}
-
#undef ORIGCELL
#undef CELLACC
#undef CELL
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index aaf935418702..93567852d1a9 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -380,7 +380,6 @@ void FrameSelectorImpl::InitBorderGeometry()
// Frame helper array
maArray.Initialize( mbVer ? 2 : 1, mbHor ? 2 : 1 );
- maArray.SetUseDiagDoubleClipping( true );
maArray.SetXOffset( mnLine1 );
maArray.SetAllColWidths( (mbVer ? mnLine2 : mnLine3) - mnLine1 );
@@ -671,33 +670,25 @@ void FrameSelectorImpl::DrawAllFrameBorders()
// Let the helper array draw itself
static bool bUsePrimitives(true);
- if (bUsePrimitives)
+ // This is used in the dialog/control for 'Border' attributes. When using
+ // the original paint below instead of primitives, the advantage currently
+ // is the correct visualization of diagonal line(s) including overlaying,
+ // but the rest is bad. Since the edit views use primitives and the preview
+ // should be 'real' I opt for also changing this to primitives. I will
+ // keep the old solution and add a switch (above) based on a static bool so
+ // that interested people may test this out in the debugger.
+ // This is one more hint to enhance the primitive visualization further to
+ // support diagonals better - that's the way to go.
+ const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
+ std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
+ drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(
+ *mpVirDev.get(),
+ aNewViewInformation2D));
+
+ if (pProcessor2D)
{
- // This is used in the dialog/control for 'Border' attributes. When using
- // the original paint below instead of primitives, the advantage currently
- // is the correct visualization of diagonal line(s) including overlaying,
- // but the rest is bad. Since the edit views use primitives and the preview
- // should be 'real' I opt for also changing this to primitives. I will
- // keep the old solution and add a switch (above) based on a static bool so
- // that interested people may test this out in the debugger.
- // This is one more hint to enhance the primitive visualization further to
- // support diagonals better - that's the way to go.
- const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
- std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
- drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(
- *mpVirDev.get(),
- aNewViewInformation2D));
-
- if (pProcessor2D)
- {
- maArray.DrawArray(*pProcessor2D.get());
- pProcessor2D.reset();
- }
- }
- else
- {
- // original paint
- maArray.DrawArray(*mpVirDev.get());
+ maArray.DrawArray(*pProcessor2D.get());
+ pProcessor2D.reset();
}
}