tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/java/com/google/scrollview/ScrollView.java
Go to the documentation of this file.
00001 // Copyright 2007 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License"); You may not
00004 // use this file except in compliance with the License. You may obtain a copy of
00005 // the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
00006 // applicable law or agreed to in writing, software distributed under the
00007 // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
00008 // OF ANY KIND, either express or implied. See the License for the specific
00009 // language governing permissions and limitations under the License.
00010 
00011 package com.google.scrollview;
00012 
00013 import com.google.scrollview.events.SVEvent;
00014 import com.google.scrollview.ui.SVImageHandler;
00015 import com.google.scrollview.ui.SVWindow;
00016 import org.piccolo2d.nodes.PImage;
00017 
00018 import java.io.BufferedReader;
00019 import java.io.IOException;
00020 import java.io.InputStreamReader;
00021 import java.io.PrintStream;
00022 import java.net.ServerSocket;
00023 import java.net.Socket;
00024 import java.util.ArrayList;
00025 import java.util.regex.Pattern;
00026 
00032 public class ScrollView {
00033 
00035   public static int SERVER_PORT = 8461;
00036 
00042   private static Socket socket;
00043   private static PrintStream out;
00044   public static BufferedReader in;
00045   public static float polylineXCoords[];  // The coords being received.
00046   public static float polylineYCoords[];  // The coords being received.
00047   public static int polylineSize;       // The size of the coords arrays.
00048   public static int polylineScanned;    // The size read so far.
00049   private static ArrayList<SVWindow> windows;  // The id to SVWindow map.
00050   private static Pattern intPattern;        // For checking integer arguments.
00051   private static Pattern floatPattern;     // For checking float arguments.
00052 
00054   static int nrInputLines = 0;
00055 
00057   static boolean debugViewNetworkTraffic = false;
00058 
00060   public static void addMessage(SVEvent e) {
00061     if (debugViewNetworkTraffic) {
00062       System.out.println("(S->c) " + e.toString());
00063     }
00064     String str = e.toString();
00065     // Send the whole thing as UTF8.
00066     try {
00067       byte [] utf8 = str.getBytes("UTF8");
00068       out.write(utf8, 0, utf8.length);
00069     } catch (java.io.UnsupportedEncodingException ex) {
00070       System.out.println("Oops... can't encode to UTF8... Exiting");
00071       System.exit(0);
00072     }
00073     out.println();
00074     // Flush the output and check for errors.
00075     boolean error = out.checkError();
00076     if (error) {
00077       System.out.println("Connection error. Quitting ScrollView Server...");
00078       System.exit(0);
00079     }
00080   }
00081 
00083   public static String receiveMessage() throws IOException {
00084     return in.readLine();
00085   }
00086 
00091   private static void IOLoop() {
00092     String inputLine;
00093 
00094     try {
00095       while (!socket.isClosed() && !socket.isInputShutdown() &&
00096              !socket.isOutputShutdown() &&
00097              socket.isConnected() && socket.isBound()) {
00098         inputLine = receiveMessage();
00099         nrInputLines++;
00100         if (debugViewNetworkTraffic) {
00101           System.out.println("(c->S," + nrInputLines + ")" + inputLine);
00102         }
00103 
00104         if (polylineSize > polylineScanned) {
00105           // We are processing a polyline.
00106           // Read pairs of coordinates separated by commas.
00107           boolean first = true;
00108           for (String coordStr : inputLine.split(",")) {
00109             int coord = Integer.parseInt(coordStr);
00110             if (first) {
00111               polylineXCoords[polylineScanned] = coord;
00112             } else {
00113               polylineYCoords[polylineScanned++] = coord;
00114             }
00115             first = !first;
00116           }
00117           assert first;
00118         } else {
00119           // Process this normally.
00120           processInput(inputLine);
00121         }
00122       }
00123     }
00124     // Some connection error
00125     catch (IOException e) {
00126       System.out.println("Connection error. Quitting ScrollView Server...");
00127     }
00128     System.exit(0);
00129   }
00130 
00131   // Parse a comma-separated list of arguments into ArrayLists of the
00132   // possible types. Each type is stored in order, but the order
00133   // distinction between types is lost.
00134   // Note that the format is highly constrained to what the client used
00135   // to send to LUA:
00136   // Quoted string -> String.
00137   // true or false -> Boolean.
00138   // %f format number -> Float (no %e allowed)
00139   // Sequence of digits -> Integer
00140   // Nothing else allowed.
00141   private static void parseArguments(String argList,
00142                                      ArrayList<Integer> intList,
00143                                      ArrayList<Float> floatList,
00144                                      ArrayList<String> stringList,
00145                                      ArrayList<Boolean> boolList) {
00146     // str is only non-null if an argument starts with a single or double
00147     // quote. str is set back to null on completion of the string with a
00148     // matching quote. If the string contains a comma then str will stay
00149     // non-null across multiple argStr values until a matching closing quote.
00150     // Backslash escaped quotes do not count as terminating the string.
00151     String str = null;
00152     for (String argStr : argList.split(",")) {
00153       if (str != null) {
00154         // Last string was incomplete. Append argStr to it and restore comma.
00155         // Execute str += "," + argStr in Java.
00156         int length = str.length() + 1 + argStr.length();
00157         StringBuilder appended = new StringBuilder(length);
00158         appended.append(str);
00159         appended.append(",");
00160         appended.append(argStr);
00161         str =  appended.toString();
00162       } else if (argStr.length() == 0) {
00163         continue;
00164       } else {
00165         char quote = argStr.charAt(0);
00166         // If it begins with a quote then it is a string, but may not
00167         // end this time if it contained a comma.
00168         if (quote == '\'' || quote == '"') {
00169           str = argStr;
00170         }
00171       }
00172       if (str != null) {
00173         // It began with a quote. Check that it still does.
00174         assert str.charAt(0) == '\'' || str.charAt(0) == '"';
00175         int len = str.length();
00176         if (len > 1 && str.charAt(len - 1) == str.charAt(0)) {
00177           // We have an ending quote of the right type. Now check that
00178           // it is not escaped. Must have an even number of slashes before.
00179           int slash = len - 1;
00180           while (slash > 0 && str.charAt(slash - 1) == '\\')
00181             --slash;
00182           if ((len - 1 - slash) % 2 == 0) {
00183             // It is now complete. Chop off the quotes and save.
00184             // TODO(rays) remove the first backslash of each pair.
00185             stringList.add(str.substring(1, len - 1));
00186             str = null;
00187           }
00188         }
00189         // If str is not null here, then we have a string with a comma in it.
00190         // Append , and the next argument at the next iteration, but check
00191         // that str is null after the loop terminates in case it was an
00192         // unterminated string.
00193       } else if (floatPattern.matcher(argStr).matches()) {
00194         // It is a float.
00195         floatList.add(Float.parseFloat(argStr));
00196       } else if (argStr.equals("true")) {
00197         boolList.add(true);
00198       } else if (argStr.equals("false")) {
00199         boolList.add(false);
00200       } else if (intPattern.matcher(argStr).matches()) {
00201         // Only contains digits so must be an int.
00202         intList.add(Integer.parseInt(argStr));
00203       }
00204       // else ignore all incompatible arguments for forward compatibility.
00205     }
00206     // All strings must have been terminated.
00207     assert str == null;
00208   }
00209 
00211   private static void processInput(String inputLine) {
00212     if (inputLine == null) {
00213       return;
00214     }
00215     // Execute a function encoded as a LUA statement! Yuk!
00216     if (inputLine.charAt(0) == 'w') {
00217       // This is a method call on a window. Parse it.
00218       String noWLine = inputLine.substring(1);
00219       String[] idStrs = noWLine.split("[ :]", 2);
00220       int windowID = Integer.parseInt(idStrs[0]);
00221       // Find the parentheses.
00222       int start = inputLine.indexOf('(');
00223       int end = inputLine.lastIndexOf(')');
00224       // Parse the args.
00225       ArrayList<Integer> intList = new ArrayList<Integer>(4);
00226       ArrayList<Float> floatList = new ArrayList<Float>(2);
00227       ArrayList<String> stringList = new ArrayList<String>(4);
00228       ArrayList<Boolean> boolList = new ArrayList<Boolean>(3);
00229       parseArguments(inputLine.substring(start + 1, end),
00230                      intList, floatList, stringList, boolList);
00231       int colon = inputLine.indexOf(':');
00232       if (colon > 1 && colon < start) {
00233         // This is a regular function call. Look for the name and call it.
00234         String func = inputLine.substring(colon + 1, start);
00235         if (func.equals("drawLine")) {
00236           windows.get(windowID).drawLine(intList.get(0), intList.get(1),
00237                                          intList.get(2), intList.get(3));
00238         } else if (func.equals("createPolyline")) {
00239           windows.get(windowID).createPolyline(intList.get(0));
00240         } else if (func.equals("drawPolyline")) {
00241           windows.get(windowID).drawPolyline();
00242         } else if (func.equals("drawRectangle")) {
00243           windows.get(windowID).drawRectangle(intList.get(0), intList.get(1),
00244                                               intList.get(2), intList.get(3));
00245         } else if (func.equals("setVisible")) {
00246           windows.get(windowID).setVisible(boolList.get(0));
00247         } else if (func.equals("setAlwaysOnTop")) {
00248           windows.get(windowID).setAlwaysOnTop(boolList.get(0));
00249         } else if (func.equals("addMessage")) {
00250           windows.get(windowID).addMessage(stringList.get(0));
00251         } else if (func.equals("addMessageBox")) {
00252           windows.get(windowID).addMessageBox();
00253         } else if (func.equals("clear")) {
00254           windows.get(windowID).clear();
00255         } else if (func.equals("setStrokeWidth")) {
00256           windows.get(windowID).setStrokeWidth(floatList.get(0));
00257         } else if (func.equals("drawEllipse")) {
00258           windows.get(windowID).drawEllipse(intList.get(0), intList.get(1),
00259                                             intList.get(2), intList.get(3));
00260         } else if (func.equals("pen")) {
00261           if (intList.size() == 4) {
00262             windows.get(windowID).pen(intList.get(0), intList.get(1),
00263                                       intList.get(2), intList.get(3));
00264           } else {
00265             windows.get(windowID).pen(intList.get(0), intList.get(1),
00266                                       intList.get(2));
00267           }
00268         } else if (func.equals("brush")) {
00269           if (intList.size() == 4) {
00270             windows.get(windowID).brush(intList.get(0), intList.get(1),
00271                                         intList.get(2), intList.get(3));
00272           } else {
00273             windows.get(windowID).brush(intList.get(0), intList.get(1),
00274                                         intList.get(2));
00275           }
00276         } else if (func.equals("textAttributes")) {
00277           windows.get(windowID).textAttributes(stringList.get(0),
00278                                                intList.get(0),
00279                                                boolList.get(0),
00280                                                boolList.get(1),
00281                                                boolList.get(2));
00282         } else if (func.equals("drawText")) {
00283           windows.get(windowID).drawText(intList.get(0), intList.get(1),
00284                                          stringList.get(0));
00285         } else if (func.equals("addMenuBarItem")) {
00286           if (boolList.size() > 0) {
00287             windows.get(windowID).addMenuBarItem(stringList.get(0),
00288                                                  stringList.get(1),
00289                                                  intList.get(0),
00290                                                  boolList.get(0));
00291           } else if (intList.size() > 0) {
00292             windows.get(windowID).addMenuBarItem(stringList.get(0),
00293                                                  stringList.get(1),
00294                                                  intList.get(0));
00295           } else {
00296             windows.get(windowID).addMenuBarItem(stringList.get(0),
00297                                                  stringList.get(1));
00298           }
00299         } else if (func.equals("addPopupMenuItem")) {
00300           if (stringList.size() == 4) {
00301             windows.get(windowID).addPopupMenuItem(stringList.get(0),
00302                                                    stringList.get(1),
00303                                                    intList.get(0),
00304                                                    stringList.get(2),
00305                                                    stringList.get(3));
00306           } else {
00307              windows.get(windowID).addPopupMenuItem(stringList.get(0),
00308                                                     stringList.get(1));
00309           }
00310         } else if (func.equals("update")) {
00311           windows.get(windowID).update();
00312         } else if (func.equals("showInputDialog")) {
00313           windows.get(windowID).showInputDialog(stringList.get(0));
00314         } else if (func.equals("showYesNoDialog")) {
00315           windows.get(windowID).showYesNoDialog(stringList.get(0));
00316         } else if (func.equals("zoomRectangle")) {
00317           windows.get(windowID).zoomRectangle(intList.get(0), intList.get(1),
00318                                               intList.get(2), intList.get(3));
00319         } else if (func.equals("readImage")) {
00320           PImage image = SVImageHandler.readImage(intList.get(2), in);
00321           windows.get(windowID).drawImage(image, intList.get(0), intList.get(1));
00322         } else if (func.equals("drawImage")) {
00323           PImage image = new PImage(stringList.get(0));
00324           windows.get(windowID).drawImage(image, intList.get(0), intList.get(1));
00325         } else if (func.equals("destroy")) {
00326           windows.get(windowID).destroy();
00327         }
00328         // else for forward compatibility purposes, silently ignore any
00329         // unrecognized function call.
00330       } else {
00331         // No colon. Check for create window.
00332         if (idStrs[1].startsWith("= luajava.newInstance")) {
00333           while (windows.size() <= windowID) {
00334             windows.add(null);
00335           }
00336           windows.set(windowID, new SVWindow(stringList.get(1),
00337                                              intList.get(0), intList.get(1),
00338                                              intList.get(2), intList.get(3),
00339                                              intList.get(4), intList.get(5),
00340                                              intList.get(6)));
00341         }
00342         // else for forward compatibility purposes, silently ignore any
00343         // unrecognized function call.
00344       }
00345     } else if (inputLine.startsWith("svmain")) {
00346         // Startup or end. Startup is a lua bind, which is now a no-op.
00347         if (inputLine.startsWith("svmain:exit")) {
00348           exit();
00349         }
00350         // else for forward compatibility purposes, silently ignore any
00351         // unrecognized function call.
00352     }
00353     // else for forward compatibility purposes, silently ignore any
00354     // unrecognized function call.
00355   }
00356 
00358   public static void exit() {
00359     System.exit(0);
00360   }
00361 
00366   public static void main(String[] args) {
00367     if (args.length > 0) {
00368       SERVER_PORT = Integer.parseInt(args[0]);
00369     }
00370     windows = new ArrayList<SVWindow>(100);
00371     intPattern = Pattern.compile("[0-9-][0-9]*");
00372     floatPattern = Pattern.compile("[0-9-][0-9]*\\.[0-9]*");
00373 
00374     try {
00375       // Open a socket to listen on.
00376       ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
00377       System.out.println("Socket started on port " + SERVER_PORT);
00378 
00379       // Wait (blocking) for an incoming connection
00380       socket = serverSocket.accept();
00381       System.out.println("Client connected");
00382 
00383       // Setup the streams
00384       out = new PrintStream(socket.getOutputStream(), true);
00385       in =
00386           new BufferedReader(new InputStreamReader(socket.getInputStream(),
00387               "UTF8"));
00388     } catch (IOException e) {
00389       // Something went wrong and we were unable to set up a connection. This is
00390       // pretty
00391       // much a fatal error.
00392       // Note: The server does not get restarted automatically if this happens.
00393       e.printStackTrace();
00394       System.exit(1);
00395     }
00396 
00397     // Enter the main program loop.
00398     IOLoop();
00399   }
00400 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines