1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21 
22 package org.apache.openoffice.ooxml.viewer.tokenview;
23 
24 import java.util.Vector;
25 
26 public class LineContainer<TokenType>
27 {
LineContainer()28     LineContainer ()
29     {
30         maLines = new Vector<>();
31     }
32 
33 
34 
35 
IsLineInGroup( final Line<TokenType> aLine, final Run<TokenType> aGroup)36     boolean IsLineInGroup (
37         final Line<TokenType> aLine,
38         final Run<TokenType> aGroup)
39     {
40         if (aGroup == null)
41             return false;
42 
43         final Line<TokenType> aStartLine = aGroup.GetLine();
44         if (aLine.GetTop() < aStartLine.GetTop())
45             return false;
46         final Line<TokenType> aEndLine = aGroup.GetGroupEnd().GetLine();
47         if (aLine.GetTop() > aEndLine.GetTop())
48             return false;
49 
50         return true;
51     }
52 
53 
54 
55 
GetLineForY(final int nY)56     Line<TokenType> GetLineForY (final int nY)
57     {
58         int nMin = 0;
59         int nMax = maLines.size()-1;
60         if (nMin <= nMax)
61         {
62             while (nMin < nMax-1)
63             {
64                 final int nMed = (nMax+nMin)/2;
65                 if (nY < maLines.get(nMed).GetTop())
66                     nMax = nMed;
67                 else
68                     nMin = nMed;
69             }
70             for (int nIndex=nMin; nIndex<=nMax; ++nIndex)
71                 if (maLines.get(nIndex).Contains(nY))
72                     return maLines.get(nIndex);
73         }
74         return null;
75     }
76 
77 
78 
79 
GetLineForOffset(final int nOffset)80     public Line<TokenType> GetLineForOffset (final int nOffset)
81     {
82         final int nLineIndex = GetLineIndexForOffset(nOffset, 0);
83         if (nLineIndex < 0)
84             return null;
85         else
86             return maLines.get(nLineIndex);
87 
88     }
89 
90 
91 
92 
GetLinesForOffsets( final int nStartOffset, final int nEndOffset)93     public Iterable<Line<TokenType>> GetLinesForOffsets (
94         final int nStartOffset,
95         final int nEndOffset)
96     {
97         final Vector<Line<TokenType>> aLines = new Vector<>();
98 
99         final int nStartLineIndex = GetLineIndexForOffset(nStartOffset, -1);
100         final int nEndLineIndex = GetLineIndexForOffset(nEndOffset, +1);
101         if (nStartLineIndex >= 0)
102         {
103             if (nEndLineIndex < 0)
104                 aLines.add(maLines.get(nStartLineIndex));
105             else
106                 for (int nIndex=nStartLineIndex; nIndex<=nEndLineIndex; ++nIndex)
107                     aLines.add(maLines.get(nIndex));
108         }
109         return aLines;
110     }
111 
112 
113 
114 
GetLineCount()115     public int GetLineCount()
116     {
117         return maLines.size();
118     }
119 
120 
121 
122 
GetLine(final int nIndex)123     public Line<TokenType> GetLine (final int nIndex)
124     {
125         return maLines.get(nIndex);
126     }
127 
128 
129 
130 
GetLines()131     public Iterable<Line<TokenType>> GetLines ()
132     {
133         return maLines;
134     }
135 
136 
137 
138 
AddLine(final Line<TokenType> aLine)139     public void AddLine (final Line<TokenType> aLine)
140     {
141         maLines.add(aLine);
142     }
143 
144 
145 
146 
147     /** Return the index of the line that contains the given offset.
148      *  When there is no line that contains the line that look at the bias
149      *  to return the previous or next line.
150      */
GetLineIndexForOffset( final int nOffset, final int nBias)151     private int GetLineIndexForOffset (
152         final int nOffset,
153         final int nBias)
154     {
155         int nMinIndex = 0;
156         int nMaxIndex = maLines.size()-1;
157         while (nMinIndex < nMaxIndex-1)
158         {
159             final int nMedIndex = (nMinIndex + nMaxIndex) / 2;
160             if (maLines.get(nMedIndex).GetEndOffset() <= nOffset)
161                 nMinIndex = nMedIndex;
162             else
163                 nMaxIndex = nMedIndex;
164         }
165         for (int nIndex=nMinIndex; nIndex<=nMaxIndex; ++nIndex)
166         {
167             if (maLines.get(nIndex).ContainsOffset(nOffset))
168                 return nIndex;
169         }
170         if (nBias < 0)
171         {
172             for (int nIndex=nMinIndex; nIndex<=nMaxIndex; ++nIndex)
173             {
174                 if (maLines.get(nIndex).GetStartOffset() > nOffset)
175                     return nIndex;
176             }
177         }
178         else if (nBias > 0)
179         {
180             for (int nIndex=nMaxIndex; nIndex>=nMinIndex; ++nIndex)
181             {
182                 if (maLines.get(nIndex).GetEndOffset() < nOffset)
183                     return nIndex;
184             }
185         }
186 
187         return -1;
188     }
189 
190 
191 
192 
193     private final Vector<Line<TokenType>> maLines;
194 }
195