LCOV - code coverage report
Current view: top level - libreoffice/svx/source/dialog - framelink.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 98 449 21.8 %
Date: 2012-12-27 Functions: 14 70 20.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10