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