⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scrollview.cpp

📁 一个google的OCR源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////// File:        scrollview.cc// Description: ScrollView// Author:      Joern Wanke// Created:     Thu Nov 29 2007//// (C) Copyright 2007, Google Inc.// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.///////////////////////////////////////////////////////////////////////////// This class contains the main ScrollView-logic,// e.g. parsing & sending messages, images etc.#ifdef WIN32#pragma warning(disable:4786)  // Don't give stupid warnings for stl#endifconst int kSvPort = 8461;const int kMaxMsgSize = 4096;const int kMaxIntPairSize = 45;  // Holds %d,%d, for upto 64 bit.#include "scrollview.h"#include <stdarg.h>#include <map>#include <utility>#include <algorithm>#include <vector>#include <string>#include "svutil.h"#ifdef HAVE_LIBLEPT#include "allheaders.h"#endifstruct SVPolyLineBuffer {  bool empty;  // Independent indicator to allow SendMsg to call SendPolygon.  std::vector<int> xcoords;  std::vector<int> ycoords;};// A map between the window IDs and their corresponding pointers.static std::map<int, ScrollView*> svmap;// A map of all semaphores waiting for a specific event on a specific window.static std::map<std::pair<ScrollView*, SVEventType>,                std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;SVMutex* mutex_waiting;SVEvent* SVEvent::copy() {  SVEvent* any = new SVEvent;  any->command_id = command_id;  any->counter = counter;  any->parameter = new char[strlen(parameter) + 1];  strncpy(any->parameter, parameter, strlen(parameter));  any->parameter[strlen(parameter)] = '\0';  any->type = type;  any->x = x;  any->y = y;  any->x_size = x_size;  any->y_size = y_size;  any->window = window;  return any;}// This is the main loop which handles the ScrollView-logic from the server// to the client. It basically loops through messages, parses them to events// and distributes it to the waiting handlers.// It is run from a different thread and synchronizes via SVSync.void* ScrollView::MessageReceiver(void* a) {  int counter_event_id = 0;  // ongoing counter  char* message = NULL;  // Wait until a new message appears in the input stream_.  do {    message = ScrollView::GetStream()->Receive();  } while (message == NULL);// This is the main loop which iterates until the server is dead (strlen = -1).// It basically parses for 3 different messagetypes and then distributes the// events accordingly.  while (strlen(message) != -1) {      // The new event we create.      SVEvent* cur = new SVEvent;      // The ID of the corresponding window.      int window_id;      int ev_type;      int n;      // Fill the new SVEvent properly.      sscanf(message, "%d,%d,%d,%d,%d,%d,%d,%n", &window_id, &ev_type, &cur->x,             &cur->y, &cur->x_size, &cur->y_size, &cur->command_id, &n);      char* p = (message + n);      cur->window = svmap[window_id];      if (cur->window != NULL) {        cur->parameter = new char[strlen(p) + 1];        strncpy(cur->parameter, p, strlen(p) + 1);        if (strlen(p) > 0) {  // remove the last \n          cur->parameter[strlen(p)] = '\0';        }        cur->type = static_cast<SVEventType>(ev_type);        cur->y = cur->window->TranslateYCoordinate(cur->y);        cur->counter = counter_event_id;        // Increase by 2 since we will also create an SVET_ANY event from cur,        // which will have a counter_id of cur + 1 (and thus gets processed        // after cur).        counter_event_id += 2;        // In case of an SVET_EXIT event, quit the whole application.        if (ev_type == SVET_EXIT) { ScrollView::Exit(); }        // Place two copies of it in the table for the window.        cur->window->SetEvent(cur);        // Check if any of the threads currently waiting want it.        std::pair<ScrollView*, SVEventType> awaiting_list(cur->window,                                                          cur->type);        std::pair<ScrollView*, SVEventType> awaiting_list_any(cur->window,                                                              SVET_ANY);        std::pair<ScrollView*, SVEventType> awaiting_list_any_window(NULL,                                                              SVET_ANY);        mutex_waiting->Lock();        if (waiting_for_events.count(awaiting_list) > 0) {          waiting_for_events[awaiting_list].second = cur;          waiting_for_events[awaiting_list].first->Signal();        } else if (waiting_for_events.count(awaiting_list_any) > 0) {          waiting_for_events[awaiting_list_any].second = cur;          waiting_for_events[awaiting_list_any].first->Signal();        } else if (waiting_for_events.count(awaiting_list_any_window) > 0) {          waiting_for_events[awaiting_list_any_window].second = cur;          waiting_for_events[awaiting_list_any_window].first->Signal();        } else {          // No one wanted it, so delete it.          delete cur;        }        mutex_waiting->Unlock();        // Signal the corresponding semaphore twice (for both copies).        ScrollView* sv = svmap[window_id];        if (sv != NULL) {          sv->Signal();          sv->Signal();        }      }      // Wait until a new message appears in the input stream_.      do {        message = ScrollView::GetStream()->Receive();      } while (message == NULL);    }  return 0;}// Table to implement the color index values in the old system.int table_colors[ScrollView::GREEN_YELLOW+1][4]= {  {0, 0, 0, 0},        // NONE (transparent)  {0, 0, 0, 255},        // BLACK.  {255, 255, 255, 255},  // WHITE.  {255, 0, 0, 255},      // RED.  {255, 255, 0, 255},    // YELLOW.  {0, 255, 0, 255},      // GREEN.  {0, 255, 255, 255},    // CYAN.  {0, 0, 255, 255},      // BLUE.  {255, 0, 255, 255},    // MAGENTA.  {0, 128, 255, 255},    // AQUAMARINE.  {0, 0, 64, 255},       // DARK_SLATE_BLUE.  {128, 128, 255, 255},  // LIGHT_BLUE.  {64, 64, 255, 255},    // MEDIUM_BLUE.  {0, 0, 32, 255},       // MIDNIGHT_BLUE.  {0, 0, 128, 255},      // NAVY_BLUE.  {192, 192, 255, 255},  // SKY_BLUE.  {64, 64, 128, 255},    // SLATE_BLUE.  {32, 32, 64, 255},     // STEEL_BLUE.  {255, 128, 128, 255},  // CORAL.  {128, 64, 0, 255},     // BROWN.  {128, 128, 0, 255},    // SANDY_BROWN.  {192, 192, 0, 255},    // GOLD.  {192, 192, 128, 255},  // GOLDENROD.  {0, 64, 0, 255},       // DARK_GREEN.  {32, 64, 0, 255},      // DARK_OLIVE_GREEN.  {64, 128, 0, 255},     // FOREST_GREEN.  {128, 255, 0, 255},    // LIME_GREEN.  {192, 255, 192, 255},  // PALE_GREEN.  {192, 255, 0, 255},    // YELLOW_GREEN.  {192, 192, 192, 255},  // LIGHT_GREY.  {64, 64, 128, 255},    // DARK_SLATE_GREY.  {64, 64, 64, 255},     // DIM_GREY.  {128, 128, 128, 255},  // GREY.  {64, 192, 0, 255},     // KHAKI.  {255, 0, 192, 255},    // MAROON.  {255, 128, 0, 255},    // ORANGE.  {255, 128, 64, 255},   // ORCHID.  {255, 192, 192, 255},  // PINK.  {128, 0, 128, 255},    // PLUM.  {255, 0, 64, 255},     // INDIAN_RED.  {255, 64, 0, 255},     // ORANGE_RED.  {255, 0, 192, 255},    // VIOLET_RED.  {255, 192, 128, 255},  // SALMON.  {128, 128, 0, 255},    // TAN.  {0, 255, 255, 255},    // TURQUOISE.  {0, 128, 128, 255},    // DARK_TURQUOISE.  {192, 0, 255, 255},    // VIOLET.  {128, 128, 0, 255},    // WHEAT.  {128, 255, 0, 255}     // GREEN_YELLOW};/******************************************************************************** Scrollview implementation.*******************************************************************************/SVNetwork* ScrollView::stream_ = NULL;int ScrollView::nr_created_windows_ = 0;// Calls Initialize with all arguments given.ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,                       int y_size, int x_canvas_size, int y_canvas_size,                       bool y_axis_reversed, const char* server_name) {  Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,             y_axis_reversed, server_name);}// Calls Initialize with default argument for server_name_.ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,                       int y_size, int x_canvas_size, int y_canvas_size,                       bool y_axis_reversed) {  Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,             y_axis_reversed, "localhost");}// Calls Initialize with default argument for server_name_ & y_axis_reversed.ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,                       int y_size, int x_canvas_size, int y_canvas_size) {  Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,             false, "localhost");}// Sets up a ScrollView window, depending on the constructor variables.void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,                            int y_size, int x_canvas_size, int y_canvas_size,                            bool y_axis_reversed, const char* server_name) {  // If this is the first ScrollView Window which gets created, there is no  // network connection yet and we have to set it up in a different thread.  if (stream_ == NULL) {    nr_created_windows_ = 0;    stream_ = new SVNetwork(server_name, kSvPort);    mutex_waiting = new SVMutex();    SendRawMessage(        "svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");    SVSync::StartThread(MessageReceiver, NULL);  }  // Set up the variables on the clientside.  nr_created_windows_++;  event_handler_ = NULL;  y_axis_is_reversed_ = y_axis_reversed;  y_size_ = y_canvas_size;  window_name_ = name;  window_id_ = nr_created_windows_;  // Set up polygon buffering.  points_ = new SVPolyLineBuffer;  points_->empty = true;  svmap[window_id_] = this;  for (int i = 0; i < SVET_COUNT; i++) {    event_table_[i] = NULL;  }  mutex_ = new SVMutex();  semaphore_ = new SVSemaphore();  // Set up an actual Window on the client side.  char message[kMaxMsgSize];  snprintf(message, sizeof(message),           "w%u = luajava.newInstance('com.google.scrollview.ui"           ".SVWindow','%s',%u,%u,%u,%u,%u,%u,%u)\n",           window_id_, window_name_, window_id_,           x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size);  SendRawMessage(message);  SVSync::StartThread(StartEventHandler, this);}// Sits and waits for events on this window.void* ScrollView::StartEventHandler(void* a) {  ScrollView* sv = reinterpret_cast<ScrollView*>(a);  SVEvent* new_event;  do {    stream_->Flush();    sv->semaphore_->Wait();    new_event = NULL;    int serial = INT_MAX;    int k = -1;    sv->mutex_->Lock();    // Check every table entry if he is is valid and not already processed.    for (int i = 0; i < SVET_COUNT; i++) {      if ((sv->event_table_[i] != NULL) &&          (sv->event_table_[i]->counter < serial)) {        new_event = sv->event_table_[i];        serial = sv->event_table_[i]->counter;        k = i;      }    }    // If we didnt find anything we had an old alarm and just sleep again.    if (new_event != NULL) {      sv->event_table_[k] = NULL;      sv->mutex_->Unlock();      if (sv->event_handler_ != NULL) { sv->event_handler_->Notify(new_event); }      if (new_event->type == SVET_DESTROY) { sv = NULL; }      delete new_event;  // Delete the pointer after it has been processed.    } else { sv->mutex_->Unlock(); }  // The thread should run as long as its associated window is alive.  } while (sv != NULL);  return 0;}ScrollView::~ScrollView() {  if (svmap[window_id_] != NULL) {    // So the event handling thread can quit.    SendMsg("destroy()");    SVEvent* sve = AwaitEvent(SVET_DESTROY);    delete sve;  }  delete mutex_;  delete semaphore_;  delete points_;  svmap.erase(window_id_);}// Send a message to the server, attaching the window id.void ScrollView::SendMsg(const char* format, ...) {  if (!points_->empty)    SendPolygon();  va_list args;  char message[kMaxMsgSize];  va_start(args, format);  // variable list  vsnprintf(message, kMaxMsgSize, format, args);  va_end(args);  char form[kMaxMsgSize];  snprintf(form, kMaxMsgSize, "w%u:%s\n", window_id_, message);  stream_->Send(form);}// Send a message to the server without a// window id. Used for global events like exit().void ScrollView::SendRawMessage(const char* msg) {  stream_->Send(msg);}// Add an Event Listener to this ScrollView Windowvoid ScrollView::AddEventHandler(SVEventHandler* listener) {  event_handler_ = listener;}void ScrollView::Signal() {  semaphore_->Signal();}void ScrollView::SetEvent(SVEvent* svevent) {// Copy event  SVEvent* any = svevent->copy();  SVEvent* specific = svevent->copy();  any->counter = specific->counter + 1;// Place both events into the queue.  mutex_->Lock();  // Delete the old objects..  if (event_table_[specific->type] != NULL) {    delete event_table_[specific->type]; }  if (event_table_[SVET_ANY] != NULL) {    delete event_table_[SVET_ANY]; }  // ...and put the new ones in the table.  event_table_[specific->type] = specific;  event_table_[SVET_ANY] = any;  mutex_->Unlock();}// Block until an event of the given type is received.// Note: The calling function is responsible for deleting the returned// SVEvent afterwards!SVEvent* ScrollView::AwaitEvent(SVEventType type) {  // Initialize the waiting semaphore.  SVSemaphore* sem = new SVSemaphore();  std::pair<ScrollView*, SVEventType> ea(this, type);  mutex_waiting->Lock();  waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);  mutex_waiting->Unlock();  // Wait on it, but first flush.  stream_->Flush();  sem->Wait();  // Process the event we got woken up for (its in waiting_for_events pair).  mutex_waiting->Lock();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -