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 <vcl/outdev.hxx>
21 :
22 : #include "gridmerg.hxx"
23 :
24 3915 : ScGridMerger::ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY )
25 : : pDev(pOutDev)
26 : , nOneX(nOnePixelX)
27 : , nOneY(nOnePixelY)
28 : , nFixStart(0)
29 : , nFixEnd(0)
30 : , nVarStart(0)
31 : , nVarDiff(0)
32 : , nCount(0)
33 3915 : , bVertical(false)
34 : {
35 : // optimize (DrawGrid) only for pixel MapMode,
36 : // to avoid rounding errors
37 :
38 3915 : bOptimize = ( pDev->GetMapMode().GetMapUnit() == MAP_PIXEL );
39 3915 : }
40 :
41 7830 : ScGridMerger::~ScGridMerger()
42 : {
43 3915 : Flush();
44 3915 : }
45 :
46 15596 : void ScGridMerger::AddLine( long nStart, long nEnd, long nPos )
47 : {
48 15596 : if ( nCount )
49 : {
50 : // not first line - test fix position
51 : // more than one previous line - test distance
52 :
53 13838 : if ( nStart != nFixStart || nEnd != nFixEnd )
54 : {
55 0 : if ( nCount == 1 && nPos == nVarStart &&
56 0 : ( nStart == nFixEnd ||
57 0 : nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
58 : {
59 : // additional optimization: extend connected lines
60 : // keep nCount at 1
61 0 : nFixEnd = nEnd;
62 : }
63 : else
64 0 : Flush();
65 : }
66 13838 : else if ( nCount == 1 )
67 : {
68 1671 : nVarDiff = nPos - nVarStart;
69 1671 : ++nCount;
70 : }
71 12167 : else if ( nPos != nVarStart + nCount * nVarDiff ) //! keep VarEnd?
72 444 : Flush();
73 : else
74 11723 : ++nCount;
75 : }
76 :
77 15596 : if ( !nCount )
78 : {
79 : // first line (or flushed above) - just store
80 :
81 2202 : nFixStart = nStart;
82 2202 : nFixEnd = nEnd;
83 2202 : nVarStart = nPos;
84 2202 : nVarDiff = 0;
85 2202 : nCount = 1;
86 : }
87 15596 : }
88 :
89 34986 : void ScGridMerger::AddHorLine(bool bWorksInPixels, long nX1, long nX2, long nY)
90 : {
91 34986 : if (bWorksInPixels)
92 : {
93 34986 : Point aPoint(pDev->PixelToLogic(Point(nX1, nY)));
94 34986 : nX1 = aPoint.X();
95 34986 : nY = aPoint.Y();
96 34986 : nX2 = pDev->PixelToLogic(Point(nX2, 0)).X();
97 : }
98 :
99 34986 : if ( bOptimize )
100 : {
101 11402 : if ( bVertical )
102 : {
103 0 : Flush();
104 0 : bVertical = false;
105 : }
106 11402 : AddLine( nX1, nX2, nY );
107 : }
108 : else
109 23584 : pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
110 34986 : }
111 :
112 27030 : void ScGridMerger::AddVerLine(bool bWorksInPixels, long nX, long nY1, long nY2)
113 : {
114 27030 : if (bWorksInPixels)
115 : {
116 27030 : Point aPoint(pDev->PixelToLogic(Point(nX, nY1)));
117 27030 : nX = aPoint.X();
118 27030 : nY1 = aPoint.Y();
119 27030 : nY2 = pDev->PixelToLogic(Point(0, nY2)).Y();
120 : }
121 :
122 27030 : if ( bOptimize )
123 : {
124 4194 : if ( !bVertical )
125 : {
126 452 : Flush();
127 452 : bVertical = true;
128 : }
129 4194 : AddLine( nY1, nY2, nX );
130 : }
131 : else
132 22836 : pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
133 27030 : }
134 :
135 7674 : void ScGridMerger::Flush()
136 : {
137 7674 : if (nCount)
138 : {
139 2202 : if (bVertical)
140 : {
141 1047 : if ( nCount == 1 )
142 262 : pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
143 : else
144 : {
145 785 : long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
146 785 : if ( nVarDiff < 0 )
147 : {
148 : // nVarDiff is negative in RTL layout mode
149 : // Change the positions so DrawGrid is called with a positive distance
150 : // (nVarStart / nVarDiff can be modified, aren't used after Flush)
151 :
152 1 : nVarDiff = -nVarDiff;
153 1 : long nTemp = nVarStart;
154 1 : nVarStart = nVarEnd;
155 1 : nVarEnd = nTemp;
156 : }
157 : pDev->DrawGrid( Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
158 : Size( nVarDiff, nFixEnd - nFixStart ),
159 785 : DrawGridFlags::VertLines );
160 : }
161 : }
162 : else
163 : {
164 1155 : if ( nCount == 1 )
165 269 : pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
166 : else
167 : {
168 886 : long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
169 : pDev->DrawGrid( Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
170 : Size( nFixEnd - nFixStart, nVarDiff ),
171 886 : DrawGridFlags::HorzLines );
172 : }
173 : }
174 2202 : nCount = 0;
175 : }
176 7674 : }
177 :
178 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|