Coverage Report

Created: 2026-09-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tesseract/src/viewer/scrollview.h
Line
Count
Source
1
///////////////////////////////////////////////////////////////////////
2
// File:        scrollview.h
3
// Description: ScrollView
4
// Author:      Joern Wanke
5
//
6
// (C) Copyright 2007, Google Inc.
7
// Licensed under the Apache License, Version 2.0 (the "License");
8
// you may not use this file except in compliance with the License.
9
// You may obtain a copy of the License at
10
// http://www.apache.org/licenses/LICENSE-2.0
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
///////////////////////////////////////////////////////////////////////
18
//
19
// ScrollView is designed as an UI which can be run remotely. This is the
20
// client code for it, the server part is written in java. The client consists
21
// mainly of 2 parts:
22
// The "core" ScrollView which sets up the remote connection,
23
// takes care of event handling etc.
24
// The other part of ScrollView consists of predefined API calls through LUA,
25
// which can basically be used to get a zoomable canvas in which it is possible
26
// to draw lines, text etc.
27
// Technically, thanks to LUA, its even possible to bypass the here defined LUA
28
// API calls at all and generate a java user interface from scratch (or
29
// basically generate any kind of java program, possibly even dangerous ones).
30
31
#ifndef TESSERACT_VIEWER_SCROLLVIEW_H_
32
#define TESSERACT_VIEWER_SCROLLVIEW_H_
33
34
#include "image.h"
35
36
#include <tesseract/export.h>
37
38
#include <cstdio>
39
#include <memory>
40
#include <mutex>
41
#include <string>
42
43
namespace tesseract {
44
45
#if !defined(__GNUC__) && !defined(__attribute__)
46
# define __attribute__(attr) // compiler without support for __attribute__
47
#endif
48
49
class ScrollView;
50
class SVNetwork;
51
class SVSemaphore;
52
struct SVPolyLineBuffer;
53
54
enum SVEventType {
55
  SVET_DESTROY,   // Window has been destroyed by user.
56
  SVET_EXIT,      // User has destroyed the last window by clicking on the 'X'.
57
  SVET_CLICK,     // Left button pressed.
58
  SVET_SELECTION, // Left button selection.
59
  SVET_INPUT,     // There is some input (single key or a whole string).
60
  SVET_MOUSE,     // The mouse has moved with a button pressed.
61
  SVET_MOTION,    // The mouse has moved with no button pressed.
62
  SVET_HOVER,     // The mouse has stayed still for a second.
63
  SVET_POPUP,     // A command selected through a popup menu.
64
  SVET_MENU,      // A command selected through the menubar.
65
  SVET_ANY,       // Any of the above.
66
67
  SVET_COUNT // Array sizing.
68
};
69
70
struct SVEvent {
71
  std::unique_ptr<SVEvent> copy() const;
72
  SVEventType type = SVET_DESTROY; // What kind of event.
73
  ScrollView *window = nullptr;    // Window event relates to.
74
  std::string parameter;           // Any string that might have been passed as argument.
75
  int x = 0;                       // Coords of click or selection.
76
  int y = 0;
77
  int x_size = 0; // Size of selection.
78
  int y_size = 0;
79
  int command_id = 0; // The ID of the possibly associated event (e.g. MENU)
80
  int counter = 0;    // Used to detect which kind of event to process next.
81
82
  SVEvent() = default;
83
  SVEvent(const SVEvent &);
84
  SVEvent &operator=(const SVEvent &);
85
};
86
87
// The SVEventHandler class is used for Event handling: If you register your
88
// class as SVEventHandler to a ScrollView Window, the SVEventHandler will be
89
// called whenever an appropriate event occurs.
90
class TESS_API SVEventHandler {
91
public:
92
  virtual ~SVEventHandler();
93
94
  // Gets called by the SV Window. Does nothing on default, overwrite this
95
  // to implement the desired behaviour
96
0
  virtual void Notify([[maybe_unused]] const SVEvent *sve) {
97
0
  }
98
};
99
100
// The ScrollView class provides the external API to the scrollviewer process.
101
// The scrollviewer process manages windows and displays images, graphics and
102
// text while allowing the user to zoom and scroll the windows arbitrarily.
103
// Each ScrollView class instance represents one window, and stuff is drawn in
104
// the window through method calls on the class. The constructor is used to
105
// create the class instance (and the window).
106
class TESS_API ScrollView {
107
public:
108
  // Color enum for pens and brushes.
109
  enum Color {
110
    NONE,
111
    BLACK,
112
    WHITE,
113
    RED,
114
    YELLOW,
115
    GREEN,
116
    CYAN,
117
    BLUE,
118
    MAGENTA,
119
    AQUAMARINE,
120
    DARK_SLATE_BLUE,
121
    LIGHT_BLUE,
122
    MEDIUM_BLUE,
123
    MIDNIGHT_BLUE,
124
    NAVY_BLUE,
125
    SKY_BLUE,
126
    SLATE_BLUE,
127
    STEEL_BLUE,
128
    CORAL,
129
    BROWN,
130
    SANDY_BROWN,
131
    GOLD,
132
    GOLDENROD,
133
    DARK_GREEN,
134
    DARK_OLIVE_GREEN,
135
    FOREST_GREEN,
136
    LIME_GREEN,
137
    PALE_GREEN,
138
    YELLOW_GREEN,
139
    LIGHT_GREY,
140
    DARK_SLATE_GREY,
141
    DIM_GREY,
142
    GREY,
143
    KHAKI,
144
    MAROON,
145
    ORANGE,
146
    ORCHID,
147
    PINK,
148
    PLUM,
149
    INDIAN_RED,
150
    ORANGE_RED,
151
    VIOLET_RED,
152
    SALMON,
153
    TAN,
154
    TURQUOISE,
155
    DARK_TURQUOISE,
156
    VIOLET,
157
    WHEAT,
158
    GREEN_YELLOW // Make sure this one is last.
159
  };
160
161
  ~ScrollView();
162
163
#ifndef GRAPHICS_DISABLED
164
165
  // Create a window. The pixel size of the window may be 0,0, in which case
166
  // a default size is selected based on the size of your canvas.
167
  // The canvas may not be 0,0 in size!
168
  ScrollView(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size,
169
             int y_canvas_size);
170
  // With a flag whether the x axis is reversed.
171
  ScrollView(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size,
172
             int y_canvas_size, bool y_axis_reversed);
173
  // Connect to a server other than localhost.
174
  ScrollView(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size,
175
             int y_canvas_size, bool y_axis_reversed, const char *server_name);
176
  /*******************************************************************************
177
   * Event handling
178
   * To register as listener, the class has to derive from the SVEventHandler
179
   * class, which consists of a notifyMe(SVEvent*) function that should be
180
   * overwritten to process the event the way you want.
181
   *******************************************************************************/
182
183
  // Add an Event Listener to this ScrollView Window.
184
  void AddEventHandler(SVEventHandler *listener);
185
186
  // Block until an event of the given type is received.
187
  std::unique_ptr<SVEvent> AwaitEvent(SVEventType type);
188
189
  /*******************************************************************************
190
   * Getters and Setters
191
   *******************************************************************************/
192
193
  // Returns the title of the window.
194
  const char *GetName() {
195
    return window_name_;
196
  }
197
198
  // Returns the unique ID of the window.
199
  int GetId() {
200
    return window_id_;
201
  }
202
203
  /*******************************************************************************
204
   * API functions for LUA calls
205
   * the implementations for these can be found in svapi.cc
206
   * (keep in mind that the window is actually created through the ScrollView
207
   * constructor, so this is not listed here)
208
   *******************************************************************************/
209
210
  // Draw an image on (x,y).
211
  void Draw(Image image, int x_pos, int y_pos);
212
213
  // Flush buffers and update display.
214
  static void Update();
215
216
  // Exit the program.
217
  static void Exit();
218
219
  // Update the contents of a specific window.
220
  void UpdateWindow();
221
222
  // Erase all content from the window, but do not destroy it.
223
  void Clear();
224
225
  // Set pen color with an enum.
226
  void Pen(Color color);
227
228
  // Set pen color to RGB (0-255).
229
  void Pen(int red, int green, int blue);
230
231
  // Set pen color to RGBA (0-255).
232
  void Pen(int red, int green, int blue, int alpha);
233
234
  // Set brush color with an enum.
235
  void Brush(Color color);
236
237
  // Set brush color to RGB (0-255).
238
  void Brush(int red, int green, int blue);
239
240
  // Set brush color to RGBA (0-255).
241
  void Brush(int red, int green, int blue, int alpha);
242
243
  // Set attributes for future text, like font name (e.g.
244
  // "Times New Roman"), font size etc..
245
  // Note: The underlined flag is currently not supported
246
  void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined);
247
248
  // Draw line from (x1,y1) to (x2,y2) with the current pencolor.
249
  void Line(int x1, int y1, int x2, int y2);
250
251
  // Set the stroke width of the pen.
252
  void Stroke(float width);
253
254
  // Draw a rectangle given upper left corner and lower right corner.
255
  // The current pencolor is used as outline, the brushcolor to fill the shape.
256
  void Rectangle(int x1, int y1, int x2, int y2);
257
258
  // Draw an ellipse centered on (x,y).
259
  // The current pencolor is used as outline, the brushcolor to fill the shape.
260
  void Ellipse(int x, int y, int width, int height);
261
262
  // Draw text with the current pencolor
263
  void Text(int x, int y, const char *mystring);
264
265
  // Draw an image from a local filename. This should be faster than
266
  // createImage. WARNING: This only works on a local machine. This also only
267
  // works image types supported by java (like bmp,jpeg,gif,png) since the image
268
  // is opened by the server.
269
  void Draw(const char *image, int x_pos, int y_pos);
270
271
  // Set the current position to draw from (x,y). In conjunction with...
272
  void SetCursor(int x, int y);
273
274
  // ...this function, which draws a line from the current to (x,y) and then
275
  // sets the new position to the new (x,y), this can be used to easily draw
276
  // polygons using vertices
277
  void DrawTo(int x, int y);
278
279
  // Set the SVWindow visible/invisible.
280
  void SetVisible(bool visible);
281
282
  // Set the SVWindow always on top or not always on top.
283
  void AlwaysOnTop(bool b);
284
285
  // Shows a modal dialog with "msg" as question and returns 'y' or 'n'.
286
  int ShowYesNoDialog(const char *msg);
287
288
  // Shows a modal dialog with "msg" as question and returns a char* string.
289
  // Constraint: As return, only words (e.g. no whitespaces etc.) are allowed.
290
  char *ShowInputDialog(const char *msg);
291
292
  // Adds a messagebox to the SVWindow. This way, it can show the messages...
293
  void AddMessageBox();
294
295
  // ...which can be added by this command.
296
  // This is intended as an "debug" output window.
297
  void AddMessage(const char *message);
298
  void AddMessageF(const char *format, ...) __attribute__((format(printf, 2, 3)));
299
300
  // Zoom the window to the rectangle given upper left corner and
301
  // lower right corner.
302
  void ZoomToRectangle(int x1, int y1, int x2, int y2);
303
304
  // Custom messages (manipulating java code directly) can be send through this.
305
  // Send a message to the server and attach the Id of the corresponding window.
306
  // Note: This should only be called if you are know what you are doing, since
307
  // you are fiddling with the Java objects on the server directly. Calling
308
  // this just for fun will likely break your application!
309
  // It is public so you can actually take use of the LUA functionalities, but
310
  // be careful!
311
  void SendMsg(const char* msg, ...) __attribute__((format(printf, 2, 3)));
312
313
  // Custom messages (manipulating java code directly) can be send through this.
314
  // Send a message to the server without adding the
315
  // window id. Used for global events like Exit().
316
  // Note: This should only be called if you are know what you are doing, since
317
  // you are fiddling with the Java objects on the server directly. Calling
318
  // this just for fun will likely break your application!
319
  // It is public so you can actually take use of the LUA functionalities, but
320
  // be careful!
321
  static void SendRawMessage(const char *msg);
322
323
  /*******************************************************************************
324
   * Add new menu entries to parent. If parent is "", the entry gets added to
325
   *the main menubar (toplevel).
326
   *******************************************************************************/
327
  // This adds a new submenu to the menubar.
328
  void MenuItem(const char *parent, const char *name);
329
330
  // This adds a new (normal) menu entry with an associated eventID, which
331
  // should be unique among menubar eventIDs.
332
  void MenuItem(const char *parent, const char *name, int cmdEvent);
333
334
  // This adds a new checkbox entry, which might initially be flagged.
335
  void MenuItem(const char *parent, const char *name, int cmdEvent, bool flagged);
336
337
  // This adds a new popup submenu to the popup menu. If parent is "", the entry
338
  // gets added at "toplevel" popupmenu.
339
  void PopupItem(const char *parent, const char *name);
340
341
  // This adds a new popup entry with the associated eventID, which should be
342
  // unique among popup eventIDs.
343
  // If value and desc are given, on a click the server will ask you to modify
344
  // the value and return the new value.
345
  void PopupItem(const char *parent, const char *name, int cmdEvent, const char *value,
346
                 const char *desc);
347
348
  // Returns the correct Y coordinate for a window, depending on whether it
349
  // might have to be flipped (by ySize).
350
  int TranslateYCoordinate(int y);
351
352
  char Wait();
353
354
private:
355
  // Transfers a binary Image.
356
  void TransferBinaryImage(Image image);
357
  // Transfers a gray scale Image.
358
  void TransferGrayImage(Image image);
359
  // Transfers a 32-Bit Image.
360
  void Transfer32bppImage(Image image);
361
362
  // Sets up ScrollView, depending on the variables from the constructor.
363
  void Initialize(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size,
364
                  int y_canvas_size, bool y_axis_reversed, const char *server_name);
365
366
  // Send the current buffered polygon (if any) and clear it.
367
  void SendPolygon();
368
369
  // Start the message receiving thread.
370
  static void MessageReceiver();
371
372
  // Place an event into the event_table (synchronized).
373
  void SetEvent(const SVEvent *svevent);
374
375
  // Wake up the semaphore.
376
  void Signal();
377
378
  // Returns the unique, shared network stream.
379
  static SVNetwork &GetStream() {
380
    return *stream_;
381
  }
382
383
  // Starts a new event handler.
384
  // Called asynchronously whenever a new window is created.
385
  void StartEventHandler();
386
387
  // Escapes the ' character with a \, so it can be processed by LUA.
388
  char *AddEscapeChars(const char *input);
389
390
  // The event handler for this window.
391
  SVEventHandler *event_handler_;
392
  // The name of the window.
393
  const char *window_name_;
394
  // The id of the window.
395
  int window_id_;
396
  // The points of the currently under-construction polyline.
397
  std::unique_ptr<SVPolyLineBuffer> points_;
398
  // Whether the axis is reversed.
399
  bool y_axis_is_reversed_;
400
  // Set to true only after the event handler has terminated.
401
  bool event_handler_ended_;
402
  // If the y axis is reversed, flip all y values by ySize.
403
  int y_size_;
404
  // # of created windows (used to assign an id to each ScrollView* for svmap).
405
  static int nr_created_windows_;
406
  // Serial number of sent images to ensure that the viewer knows they
407
  // are distinct.
408
  static int image_index_;
409
410
  // The stream through which the c++ client is connected to the server.
411
  static std::unique_ptr<SVNetwork> stream_;
412
413
  // Table of all the currently queued events.
414
  std::unique_ptr<SVEvent> event_table_[SVET_COUNT];
415
416
  // Mutex to access the event_table_ in a synchronized fashion.
417
  std::mutex mutex_;
418
419
  // Semaphore to the thread belonging to this window.
420
  std::unique_ptr<SVSemaphore> semaphore_;
421
#endif // !GRAPHICS_DISABLED
422
};
423
424
} // namespace tesseract
425
426
#endif // TESSERACT_VIEWER_SCROLLVIEW_H_