forked from JMS-1/DVB.NET---VCR.NET
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDigitManager.cs
More file actions
214 lines (181 loc) · 6.74 KB
/
DigitManager.cs
File metadata and controls
214 lines (181 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Drawing;
namespace JMS.DVB.TS.VideoText
{
/// <summary>
/// Diese Klasse verwaltet die Ziffern auf einer Videotextseite.
/// </summary>
public class DigitManager
{
/// <summary>
/// Die gesamte Breite der Seite als Bild.
/// </summary>
private int m_Width;
/// <summary>
/// Die gesamte Höhe der Seite als Bild.
/// </summary>
private int m_Height;
/// <summary>
/// Alle Zahlen.
/// </summary>
private List<int> m_Digits = new List<int>();
/// <summary>
/// Die zugehörigen Rahmen.
/// </summary>
private List<RectangleF> m_Positions = new List<RectangleF>();
/// <summary>
/// Erzeugt eine neue Verwaltung.
/// </summary>
/// <param name="page">Die zugehörige Bildseite.</param>
/// <exception cref="ArgumentNullException">Es wurde keine Seite angegegen.</exception>
public DigitManager( Bitmap page )
{
// Validate
if (page == null)
throw new ArgumentNullException( "page" );
// Remember
m_Width = page.Width;
m_Height = page.Height;
}
/// <summary>
/// Meldet eine Ziffer an.
/// </summary>
/// <param name="digit">Die dargestellte Ziffer.</param>
/// <param name="at">Der Rahmen um die Ziffer.</param>
public void Add( int digit, RectangleF at )
{
// Store
if (m_Width > 0)
if (m_Height > 0)
{
// Number as is
m_Digits.Add( digit );
// Normalized rectangle
m_Positions.Add( new RectangleF( at.X / m_Width, at.Y / m_Height, at.Width / m_Width, at.Height / m_Height ) );
}
}
/// <summary>
/// Prüft, ob an einer bestimmten Position auf der Videotextseite eine Ziffer angezeigt wird.
/// </summary>
/// <param name="point">Die relative Position.</param>
/// <param name="rect">Das die Zahl umschließende Rechteck.</param>
/// <returns>Die zugehörige Ziffer oder <i>null</i>.</returns>
public int? GetTTXDigitAt( PointF point, out RectangleF rect )
{
// Forward
return GetTTXDigitAt( point.X, point.Y, out rect );
}
/// <summary>
/// Prüft, ob an einer bestimmten Position auf der Videotextseite eine Ziffer angezeigt wird.
/// </summary>
/// <param name="x">Die relative horizontale Position.</param>
/// <param name="y">Die relative vertikale Position.</param>
/// <param name="rect">Das die Zahl umschließende Rechteck.</param>
/// <returns>Die zugehörige Ziffer oder <i>null</i>.</returns>
public int? GetTTXDigitAt( float x, float y, out RectangleF rect )
{
// Scan
for (int i = m_Positions.Count; i-- > 0; )
{
// Load
rect = m_Positions[i];
// Test
if (x >= rect.Left)
if (x <= rect.Right)
if (y >= rect.Top)
if (y <= rect.Bottom)
return m_Digits[i];
}
// Clear
rect = RectangleF.Empty;
// Not found
return null;
}
/// <summary>
/// Ermittelt eine dreistellige Seitennummer auf einer Videotextseite.
/// </summary>
/// <param name="point">Die relative Position, an der die Suche beginnen soll.</param>
/// <returns>Die gefundene Seitennummer im Bereich 100 bis 899 oder <i>null</i>.</returns>
public int? GetPageAt( PointF point )
{
// Forward
return GetPageAt( point.X, point.Y );
}
/// <summary>
/// Ermittelt eine dreistellige Seitennummer auf einer Videotextseite.
/// </summary>
/// <param name="x">Die relative horizontale Position, an der die Suche beginnen soll.</param>
/// <param name="y">Die relative vertikale Position, an der die Suche beginnen soll.</param>
/// <returns>Die gefundene Seitennummer im Bereich 100 bis 899 oder <i>null</i>.</returns>
public int? GetPageAt( float x, float y )
{
// Find the hit
RectangleF rect;
int? dig = GetTTXDigitAt( x, y, out rect );
// None
if (!dig.HasValue)
return null;
// Get the center position
float centerX = rect.X + rect.Width / 2, centerY = rect.Y + rect.Height / 2;
// Create helper array
int[] digits = { -1, -1, -1, dig.Value, -1, -1, -1 };
// Forward fill
for (int i = 4; i < 7; i++)
{
// Locate it
RectangleF test;
int? next = GetTTXDigitAt( centerX + (i - 3) * rect.Width, centerY, out test );
// None
if (!next.HasValue)
break;
// Check parameters
if (test.Width != rect.Width)
break;
if (test.Height != rect.Height)
break;
// Remember
digits[i] = next.Value;
}
// Too long
if (digits[6] != -1)
return null;
// Backward fill
for (int i = 3; i-- > 0; )
{
// Locate it
RectangleF test;
int? next = GetTTXDigitAt( centerX - (3 - i) * rect.Width, centerY, out test );
// None
if (!next.HasValue)
break;
// Check parameters
if (test.Width != rect.Width)
break;
if (test.Height != rect.Height)
break;
// Remember
digits[i] = next.Value;
}
// To long
if (digits[0] != -1)
return null;
// Analyse result
int start = Array.FindIndex( digits, d => d != -1 );
int end = Array.FindLastIndex( digits, d => d != -1 );
// Get the dimension
if ((end - start) != 2)
return null;
// Create
int page = digits[start + 2] + 10 * (digits[start + 1] + 10 * digits[start + 0]);
// Check bounds
if (page >= 100)
if (page <= 899)
return page;
// Not allowed
return null;
}
}
}