Ejemplo n.º 1
0
Archivo: driver.c Proyecto: tuxfan/ska
int main(int argc, char *argv[])
{
	PetscErrorCode ierr;
	int i;
	grid *grd;

	MPI_Init(&argc,&argv);

	option options = parse_options(argc, argv);

	if (options.problem == JUMP) {
		grd = grid_create(-1, 1, options.nx,
		                  -1, 1, options.ny,
		                  -1, 1, options.nz);
	} else {
		grd = grid_create(0, 1, options.nx,
		                  0, 1, options.ny,
		                  0, 1, options.nz);
	}
	if (options.periodic > -1) grd->periodic[options.periodic] = 1;
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	if (rank == 0) print_intro(&options);

	map *mp = map_create(options.map);
	grid_apply_map(grd, mp);

	problem *pb = problem_create(options.problem, grd->nd, mp->id);
	solver *sol = solver_create(grd, pb);

	ierr = solver_init(sol, grd);CHKERRQ(ierr);
	ierr = solver_run(sol);CHKERRQ(ierr);

	double *u = (double*) malloc(grd->num_pts*sizeof(double));
	double *diff = (double*) malloc(grd->num_pts*sizeof(double));
	grid_eval(grd, pb->sol, u);

	for (i = 0; i < grd->num_pts; i++)
		diff[i] = sol->state->phi[i] - u[i];

	print_norm(diff, grd->num_pts);

	free(u); free(diff);
	grid_destroy(grd); free(grd);
	map_destroy(mp); free(mp);
	problem_destroy(pb); free(pb);
	ierr = solver_destroy(sol);CHKERRQ(ierr); free(sol);

	if (options.eig && rank == 0) {
		system("./python/plot.py");
	}

	MPI_Finalize();

	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
    srand(time(NULL));
    clock_t beg, end;

    int size = 50;
    grid *grd = grid_allocate(size, size);

    beg = clock();
    grid_create(grd, 0.6);
    cl_list* clusters = clusterization(grd);
    end = clock();
    
    int i, j;
    for (i = 0; i < size; i++)
    {
        for (j = 0; j < size; j++)
            printf("%d", grd->cells[i * size + j]);
        printf("\n");
    }
    cl_list_print(clusters);
    
    create_image("img.png", 2000, grd, clusters);
    
    grid_free(grd);
    
    printf("Finished in %g sec\n", (double)(end - beg) / CLOCKS_PER_SEC);
    
    return 0;
}
Ejemplo n.º 3
0
Archivo: preader.c Proyecto: CKehl/nn-c
preader* preader_create1(double xmin, double xmax, double ymin, double ymax, int nx, int ny)
{
    preader* pr = malloc(sizeof(preader));

    pr->r = NULL;
    pr->g = grid_create(xmin, xmax, ymin, ymax, nx, ny);

    return pr;
}
Ejemplo n.º 4
0
Archivo: grid.c Proyecto: progschj/TLDR
static int grid_create_lua(lua_State *L) {
    int top = lua_gettop(L);
    if(top<1 || !lua_isnumber(L, 1)) return typerror(L, 1, "number");
    if(top<2 || !lua_isnumber(L, 2)) return typerror(L, 2, "number");
    if(top<3 || !lua_isnumber(L, 3)) return typerror(L, 3, "number");
    if(top<4 || !lua_isnumber(L, 4)) return typerror(L, 4, "number");
    grid *g = lua_newuserdata(L, sizeof(grid));
    *g = grid_create(lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
    grid_create_metatable_lua(L);
    return 1;
}
Ejemplo n.º 5
0
/* Create a new screen. */
void
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
{
	s->grid = grid_create(sx, sy, hlimit);
	s->title = xstrdup("");

	s->cstyle = 0;
	s->ccolour = xstrdup("");
	s->tabs = NULL;

	screen_reinit(s);
}
Ejemplo n.º 6
0
/* Reflow wrapped lines. */
void
screen_reflow(struct screen *s, u_int new_x)
{
	struct grid	*old = s->grid;
	u_int		 change;

	s->grid = grid_create(old->sx, old->sy, old->hlimit);

	change = grid_reflow(s->grid, old, new_x);
	if (change < s->cy)
		s->cy -= change;
	else
		s->cy = 0;
}
Ejemplo n.º 7
0
/* Create a new screen. */
void
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
{
	char hn[MAXHOSTNAMELEN];

	s->grid = grid_create(sx, sy, hlimit);

	if (gethostname(hn, MAXHOSTNAMELEN) == 0)
		s->title = xstrdup(hn);
	else
		s->title = xstrdup("");

	s->tabs = NULL;

	screen_reinit(s);
}
Ejemplo n.º 8
0
/* Create a new screen. */
void
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
{
	char host[HOST_NAME_MAX];

	s->grid = grid_create(sx, sy, hlimit);

	if (gethostname(host, HOST_NAME_MAX) == 0)
		s->title = xstrdup(host);
	else
		s->title = xstrdup("");

	s->cstyle = 0;
	s->ccolour = xstrdup("");
	s->tabs = NULL;

	screen_reinit(s);
}
Ejemplo n.º 9
0
static void model_setgrids(model* m, char gfname[])
{
    int ngrid = 0;
    gridprm* prm = NULL;
    int i;

    gridprm_create(gfname, &ngrid, &prm);
    assert(ngrid > 0);

    for (i = 0; i < ngrid; ++i) {
        grid* g = NULL;

        g = grid_create(&prm[i], i);
        grid_settocartesian_fn(g, ll2xyz);
        model_setgrid(m, g);
    }

    gridprm_destroy(ngrid, prm);
}
Ejemplo n.º 10
0
Archivo: grid.c Proyecto: progschj/TLDR
static int grid_from_table_lua(lua_State *L) {
    if(!lua_istable(L, 1)) return typerror(L, 1, "table");
    lua_pushstring(L, "x0");
    lua_gettable(L, 1);
    int x0 = lua_tonumber(L, -1);
    lua_pop(L, 1);
    
    lua_pushstring(L, "y0");
    lua_gettable(L, 1);
    int y0 = lua_tonumber(L, -1);
    lua_pop(L, 1);
    
    lua_pushstring(L, "width");
    lua_gettable(L, 1);
    int width = lua_tonumber(L, -1);
    lua_pop(L, 1);
    
    lua_pushstring(L, "height");
    lua_gettable(L, 1);
    int height = lua_tonumber(L, -1);
    lua_pop(L, 1);
    
    grid *g = lua_newuserdata(L, sizeof(grid));
    *g = grid_create(x0, y0, width, height);
    grid_create_metatable_lua(L);
    
    lua_pushstring(L, "data");
    lua_gettable(L, 1);
    int size = g->width*g->height;
    for(int i = 0;i<size;++i) {
        lua_rawgeti(L, -1, i+1);
        g->data[i] = lua_tonumber(L, -1);
        lua_pop(L, 1);
    }
    lua_pop(L, 1);
    
    return 1;
}
Ejemplo n.º 11
0
/* Reflow lines on grid to new width. */
void
grid_reflow(struct grid *gd, u_int sx)
{
	struct grid		*target;
	struct grid_line	*gl;
	struct grid_cell	 gc;
	u_int			 yy, width, i, at, first;

	/*
	 * Create a destination grid. This is just used as a container for the
	 * line data and may not be fully valid.
	 */
	target = grid_create(gd->sx, 0, 0);

	/*
	 * Loop over each source line.
	 */
	for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
		gl = &gd->linedata[yy];
		if (gl->flags & GRID_LINE_DEAD)
			continue;

		/*
		 * Work out the width of this line. first is the width of the
		 * first character, at is the point at which the available
		 * width is hit, and width is the full line width.
		 */
		first = at = width = 0;
		if (~gl->flags & GRID_LINE_EXTENDED) {
			first = 1;
			width = gl->cellused;
			if (width > sx)
				at = sx;
			else
				at = width;
		} else {
			for (i = 0; i < gl->cellused; i++) {
				grid_get_cell1(gl, i, &gc);
				if (i == 0)
					first = gc.data.width;
				if (at == 0 && width + gc.data.width > sx)
					at = i;
				width += gc.data.width;
			}
		}

		/*
		 * If the line is exactly right or the first character is wider
		 * than the targe width, just move it across unchanged.
		 */
		if (width == sx || first > sx) {
			grid_reflow_move(target, gl);
			continue;
		}

		/*
		 * If the line is too big, it needs to be split, whether or not
		 * it was previously wrapped.
		 */
		if (width > sx) {
			grid_reflow_split(target, gd, sx, yy, at);
			continue;
		}

		/*
		 * If the line was previously wrapped, join as much as possible
		 * of the next line.
		 */
		if (gl->flags & GRID_LINE_WRAPPED)
			grid_reflow_join(target, gd, sx, yy, width, 0);
		else
			grid_reflow_move(target, gl);
	}

	/*
	 * Replace the old grid with the new.
	 */
	if (target->sy < gd->sy)
		grid_reflow_add(target, gd->sy - target->sy);
	gd->hsize = target->sy - gd->sy;
	if (gd->hscrolled > gd->hsize)
		gd->hscrolled = gd->hsize;
	free(gd->linedata);
	gd->linedata = target->linedata;
	free(target);
}
Ejemplo n.º 12
0
int32_t main(int32_t argc, char *argv[]) {
    if( init_sdl2() ) {
        return 1;
    }

    SDL_Window* window;
    sdl2_window("test-grid", 100, 60, 1280, 720, &window);

    SDL_GLContext* context;
    sdl2_glcontext(3, 2, window, &context);

    if( init_vbo() ) {
        return 1;
    }

    printf("vbo\n");
    struct Vbo vbo = {0};
    vbo_create(&vbo);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_STATIC_DRAW);
    vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_NORMAL, 3, GL_FLOAT, GL_STATIC_DRAW);

    struct Ibo ibo = {0};
    ibo_create(GL_TRIANGLES, GL_UNSIGNED_INT, GL_STATIC_DRAW, &ibo);

    struct Grid grid = {0};
    grid_create(4,4,1,&grid);

    struct GridPages pages = {0};
    grid_pages(&grid,2,2,1,&pages);

    grid_dump(grid,pages);

    struct GridIndex index = {0};
    for( uint64_t z = 0; z < grid.size.z; z++ ) {
        for( uint64_t y = 0; y < grid.size.y; y++ ) {
            for( uint64_t x = 0; x < grid.size.x; x++ ) {
                grid_index_xyz(&grid, &pages, NULL, x, y, z, &index);
                printf("x:%lu y:%lu z:%lu page:%lu cell:%lu\n", x, y, z, index.page, index.cell);
            }
        }
    }

    printf("-----------\n");

    struct GridBox box = {0};
    box.position.x = 1;
    box.position.y = 1;
    box.position.z = 0;
    box.size.x = 2;
    box.size.y = 2;
    box.size.z = 1;
    box.level = 0;

    for( uint64_t z = 0; z < box.size.z; z++ ) {
        for( uint64_t y = 0; y < box.size.y; y++ ) {
            for( uint64_t x = 0; x < box.size.x; x++ ) {
                grid_index_xyz(&grid, &pages, &box, x, y, z, &index);
                printf("x:%lu y:%lu z:%lu page:%lu cell:%lu\n", x, y, z, index.page, index.cell);
            }
        }
    }

    struct GridSize size = {0};
    uint64_t array_size = grid_levelsize(&grid, &pages, 0, &size)->array;
    for( int32_t i = 0; i < array_size; i++ ) {
        grid_index(&grid, &pages, NULL, i, &index);
    }

    uint64_t x = UINT64_MAX;
    printf("0x%lx\n", x);

    grid_alloc(&pages, 0, 0);
    grid_alloc(&pages, 1, 0);
    grid_alloc(&pages, 2, 0);
    grid_alloc(&pages, 3, 0);

    grid_set1(&grid, &pages, NULL, 23);
    grid_set1(&grid, &pages, &box, 42);

    printf("lala\n");

    grid_pagebox(&grid, &pages, 3, 0, &box);
    printf("%lu %lu %lu %lu %lu %lu %d\n", box.position.x, box.position.y, box.position.z, box.size.x, box.size.y, box.size.z, box.level);

    /* grid_pageout(&grid, &pages, 0, NULL); */
    /* printf("\n"); */
    /* grid_pageout(&grid, &pages, 1, NULL); */
    /* printf("\n"); */
    /* grid_pageout(&grid, &pages, 2, NULL); */
    /* printf("\n"); */
    /* grid_pageout(&grid, &pages, 3, NULL); */
    /* printf("\n"); */

    return 0;
}
Ejemplo n.º 13
0
int find_boundary(int n, double *x, double *y, double r, double (*r_function)(double, double), int n_contour,
                  int *contour)
{
  /*
   * Find the boundary of the `n` 2-dimensional points located at `x` and `y` using a ballpivot approach.
   * The indices of the contour points are stored in the `contour` array. There are several possibilities
   * to provide the ball radius used in the ballpivot algorithm:
   * - As a callback function (`r_function`) that returns the ball radius for the current position.
   * - As a constant ball radius `r`
   * - Automatically calculated / estimated from the data points
   *
   * If `r_function` is different from NULL it will be used to calculate the ball radius for each position.
   * In that case the parameter `r` is only used to set the cell size of the internal grid data structure storing
   * the points if it has a value greater 0.
   * If `r_function` is NULL and `r` is greater 0 it is used as a constant ball radius and determines the cell
   * size of the internal grid. Otherwise a (constant) ball radius is automatically calculated as 1.2 times the
   * the largest distance from a point to its nearest neighbor.
   *
   * If the algorithm is successful it returns the number of contour points that were written in `contour`.
   * Otherwise the return value is less than 0 indicating a too small (`FIND_BOUNDARY_BALL_TOO_SMALL`) or too
   * large (`FIND_BOUNDARY_BALL_TOO_LARGE`) ball radius, an invalid number of points (`FIND_BOUNDARY_INVALID_POINTS`)
   * or that the number of contour points exceed the available memory in `contour` given by `n_contour`.
   */
  double2 bb_bottom_left, bb_top_right;
  double2 *points;
  double cell_size;
  neighbor_point_list data;
  grid *grid_ptr;
  int i, start_point, current_index;
  int num_contour_points = 0;

  if (n < 2)
    {
      return FIND_BOUNDARY_INVALID_POINTS;
    }

  if (n_contour <= 1)
    {
      return FIND_BOUNDARY_MEMORY_EXCEEDED;
    }

  points = malloc(n * sizeof(double2));
  assert(points);
  for (i = 0; i < n; i++)
    {
      points[i].x = x[i];
      points[i].y = y[i];
      points[i].index = i;
    }
  calculate_bounding_box(n, points, &bb_bottom_left, &bb_top_right);
  if (r <= 0)
    {
      /* If no radius is given, estimate the cell size as 1/10 of the average of width and height of the data's
       * bounding box. */
      cell_size = ((bb_top_right.x - bb_bottom_left.x) + (bb_top_right.y - bb_bottom_left.y)) / 2. / 10.;
    }
  else
    {
      /* Scale radius by 1.1 to make sure that only direct neighbor cells have to be checked. */
      cell_size = r * 1.1;
    }
  grid_ptr = grid_create(n, points, cell_size);

  /* Start from the point closest to the bottom left corner of the bounding box*/
  start_point = grid_find_nearest_neighbor(grid_ptr, grid_ptr->bounding_box[0], -1, cell_size).index;
  contour[num_contour_points] = start_point;

  if (r <= 0 && r_function == NULL)
    { /* No radius given, calculate from data */
      for (i = 0; i < n; i++)
        {
          double nearest_neighbor = grid_find_nearest_neighbor(grid_ptr, grid_get_elem(grid_ptr, i), i, cell_size).x;
          if (nearest_neighbor > r)
            {
              /* Calculate r as the largest distance from one point to its nearest neighbor. This makes sure, that
               * at least one neighbor can be reached from each point. */
              r = nearest_neighbor;
            }
        }
      r = sqrt(r);
      r *= 1.2;
    }

  /* Initialize list structure that stores the possible neighbors in each step. */
  data.capacity = 10;
  data.point_list = malloc(data.capacity * sizeof(int));
  assert(data.point_list);

  current_index = start_point;
  while (num_contour_points == 0 || contour[num_contour_points] != contour[0])
    {
      double2 current_point;
      data.current = current_index;
      data.size = 0;
      data.num_points_reachable = 0;
      current_point = grid_get_elem(grid_ptr, current_index);

      if (num_contour_points >= n_contour)
        {
          return FIND_BOUNDARY_MEMORY_EXCEEDED;
        }

      if (r_function)
        {
          r = r_function(current_point.x, current_point.y);
          if (r <= 0)
            {
              return FIND_BOUNDARY_BALL_TOO_SMALL;
            }
        }

      /* Find the possible neighbors of `current_point` using the grid structure. */
      grid_apply_function(grid_ptr, current_point, 2 * r, grid_cb_find_possible_neighbors, (void *)&data, 1,
                          &current_index);
      if (data.size == 1)
        { /* Only one neighbor is possible */
          current_index = data.point_list[0];
          contour[++num_contour_points] = current_index;
        }
      else if (data.size > 1)
        { /* More than one point is a possible neighbor */
          int best_neighbor = 0;
          double best_angle = 0;
          int oldest = num_contour_points + 1;
          int unvisited_points = 0;

          /* If at least one possible neighbor is not included in the contour until now use the (unvisited) one
           * with the smallest angle. Otherwise use the one that was visited first to avoid (infinite) loops. */
          for (i = 0; i < (int)data.size; i++)
            {
              int contour_point_index = in_contour(data.point_list[i], num_contour_points, contour);
              if (contour_point_index < 0)
                {
                  double2 previous_contour_point = grid_get_elem(grid_ptr, contour[num_contour_points - 1]);
                  double2 possible_contour_point = grid_get_elem(grid_ptr, data.point_list[i]);
                  double a = angle(current_point, previous_contour_point, possible_contour_point);
                  if (a > best_angle)
                    {
                      best_angle = a;
                      best_neighbor = i;
                    }
                  unvisited_points++;
                }
              else if (!unvisited_points)
                {
                  if (contour_point_index < oldest)
                    {
                      oldest = contour_point_index;
                      best_neighbor = i;
                    }
                }
            }
          current_index = data.point_list[best_neighbor];
          contour[++num_contour_points] = current_index;
        }
      else
        { /* No possible neighbor is found. */
          if (data.num_points_reachable == 0)
            { /* No point was reachable -> ball too small */
              return FIND_BOUNDARY_BALL_TOO_SMALL;
            }
          else
            { /* No reachable point resulted in an empty ball -> ball too large */
              return FIND_BOUNDARY_BALL_TOO_LARGE;
            }
        }
    }
  /* The grid data structure reorders the points. Restore original indices of the contour points. */
  for (i = 0; i < num_contour_points; i++)
    {
      contour[i] = points[contour[i]].index;
    }

  free(points);
  free(data.point_list);
  grid_destroy(grid_ptr);

  return num_contour_points;
}
Ejemplo n.º 14
0
// This function defines the drawing sheet on which schematic will be drawn 
GtkWidget *
sheet_new (int width, int height)
{
	GooCanvas *sheet_canvas;
	GooCanvasGroup *sheet_group;
	GooCanvasPoints *points;
	Sheet *sheet;
	GtkWidget *sheet_widget;
  	GooCanvasItem *root;
	
	// Creation of the Canvas
	sheet = SHEET (g_object_new (TYPE_SHEET, NULL));

	sheet_canvas = GOO_CANVAS (sheet);
	g_object_set (G_OBJECT (sheet_canvas), 
	              "bounds-from-origin", FALSE,
	              "bounds-padding", 4.0,
	              "background-color-rgb", 0xFFFFFF,
	              NULL);

  	root = goo_canvas_get_root_item (sheet_canvas);
	
	sheet_group = GOO_CANVAS_GROUP (goo_canvas_group_new (
	                                root,
	                                NULL));
	sheet_widget = GTK_WIDGET (sheet);

	goo_canvas_set_bounds (GOO_CANVAS (sheet_canvas), 0, 0, 
	    width + 20, height + 20);

	// Define vicinity around GooCanvasItem
	//sheet_canvas->close_enough = 6.0;

	sheet->priv->width = width;
	sheet->priv->height = height;

	// Create the dot grid.
	sheet->grid = grid_create (GOO_CANVAS_ITEM (sheet_group),
	                           width,
	                           height);

	// Everything outside the sheet should be gray.
	// top //
	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     0.0, 
	                     0.0, 
	                     (double) width + 20.0, 
	                     20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     0.0, 
	                     (double) height, 
	                     (double) width + 20.0, 
	                     (double) height + 20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	// right //
	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     0.0, 
	                     0.0, 
	                     20.0, 
	                     (double) height + 20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	goo_canvas_rect_new (GOO_CANVAS_ITEM (sheet_group), 
	                     (double) width, 
	                     0.0, 
	                     (double) width + 20.0, 
	                     (double) height + 20.0, 
	                     "fill_color", "gray", 
	                     "line-width", 0.0, 
	                     NULL);

	//  Draw a thin black border around the sheet.
	points = goo_canvas_points_new (5);
	points->coords[0] = 20.0;
	points->coords[1] = 20.0;
	points->coords[2] = width;
	points->coords[3] = 20.0;
	points->coords[4] = width;
	points->coords[5] = height;
	points->coords[6] = 20.0;
	points->coords[7] = height;
	points->coords[8] = 20.0;
	points->coords[9] = 20.0;
	
	goo_canvas_polyline_new (GOO_CANVAS_ITEM (sheet_group),
	      FALSE, 0,
	      "line-width", 1.0, 
	      "points", points, 
	      NULL);

	goo_canvas_points_unref (points);

	// Finally, create the object group that holds all objects.
	sheet->object_group = GOO_CANVAS_GROUP (goo_canvas_group_new (
	                     root,
	                     "x", 0.0,
	                     "y", 0.0,
	                     NULL));
	NG_DEBUG ("root group %p", sheet->object_group);

	sheet->priv->selected_group = GOO_CANVAS_GROUP (goo_canvas_group_new (
	     GOO_CANVAS_ITEM (sheet->object_group),
	     "x", 0.0,
	     "y", 0.0,
	     NULL));
	NG_DEBUG ("selected group %p", sheet->priv->selected_group);

	sheet->priv->floating_group = GOO_CANVAS_GROUP (goo_canvas_group_new (
	     GOO_CANVAS_ITEM (sheet->object_group),
	     "x", 0.0,
	     "y", 0.0,
	     NULL));
	NG_DEBUG ("floating group %p", sheet->priv->floating_group);

	// Hash table that keeps maps coordinate to a specific dot.
	sheet->priv->node_dots = g_hash_table_new_full (dot_hash, dot_equal, g_free, NULL);

	//this requires object_group to be setup properly
	sheet->priv->rubberband_info = rubberband_info_new (sheet);
	sheet->priv->create_wire_info = create_wire_info_new (sheet);

	return sheet_widget;
}
Ejemplo n.º 15
0
/* Reflow lines on grid to new width. */
void
grid_reflow(struct grid *gd, u_int sx, u_int *cursor)
{
	struct grid		*target;
	struct grid_line	*gl;
	struct grid_cell	 gc;
	u_int			 yy, cy, width, i, at, first;
	struct timeval		 start, tv;

	gettimeofday(&start, NULL);

	log_debug("%s: %u lines, new width %u", __func__, gd->hsize + gd->sy,
	    sx);
	cy = gd->hsize + (*cursor);

	/*
	 * Create a destination grid. This is just used as a container for the
	 * line data and may not be fully valid.
	 */
	target = grid_create(gd->sx, 0, 0);

	/*
	 * Loop over each source line.
	 */
	for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
		gl = &gd->linedata[yy];
		if (gl->flags & GRID_LINE_DEAD)
			continue;

		/*
		 * Work out the width of this line. first is the width of the
		 * first character, at is the point at which the available
		 * width is hit, and width is the full line width.
		 */
		first = at = width = 0;
		if (~gl->flags & GRID_LINE_EXTENDED) {
			first = 1;
			width = gl->cellused;
			if (width > sx)
				at = sx;
			else
				at = width;
		} else {
			for (i = 0; i < gl->cellused; i++) {
				grid_get_cell1(gl, i, &gc);
				if (i == 0)
					first = gc.data.width;
				if (at == 0 && width + gc.data.width > sx)
					at = i;
				width += gc.data.width;
			}
		}

		/*
		 * If the line is exactly right or the first character is wider
		 * than the targe width, just move it across unchanged.
		 */
		if (width == sx || first > sx) {
			grid_reflow_move(target, gl);
			continue;
		}

		/*
		 * If the line is too big, it needs to be split, whether or not
		 * it was previously wrapped.
		 */
		if (width > sx) {
			grid_reflow_split(target, gd, sx, yy, at, &cy);
			continue;
		}

		/*
		 * If the line was previously wrapped, join as much as possible
		 * of the next line.
		 */
		if (gl->flags & GRID_LINE_WRAPPED)
			grid_reflow_join(target, gd, sx, yy, width, &cy, 0);
		else
			grid_reflow_move(target, gl);
	}

	/*
	 * Replace the old grid with the new.
	 */
	if (target->sy < gd->sy)
		grid_reflow_add(target, gd->sy - target->sy);
	gd->hsize = target->sy - gd->sy;
	free(gd->linedata);
	gd->linedata = target->linedata;
	free(target);

	/*
	 * Update scrolled and cursor positions.
	 */
	if (gd->hscrolled > gd->hsize)
		gd->hscrolled = gd->hsize;
	if (cy < gd->hsize)
		*cursor = 0;
	else
		*cursor = cy - gd->hsize;

	gettimeofday(&tv, NULL);
	timersub(&tv, &start, &tv);
	log_debug("%s: now %u lines (in %llu.%06u seconds)", __func__,
	    gd->hsize + gd->sy, (unsigned long long)tv.tv_sec,
	    (u_int)tv.tv_usec);
}
Ejemplo n.º 16
0
Archivo: grid.c Proyecto: UIKit0/mctrl
static LRESULT CALLBACK
grid_proc(HWND win, UINT msg, WPARAM wp, LPARAM lp)
{
    grid_t* grid = (grid_t*) GetWindowLongPtr(win, 0);

    switch(msg) {
        case WM_PAINT:
            return generic_paint(win, grid->no_redraw,
                                 (grid->style & MC_GS_DOUBLEBUFFER),
                                 grid_paint, grid);

        case WM_PRINTCLIENT:
            return generic_printclient(win, (HDC) wp, grid_paint, grid);

        case WM_NCPAINT:
            return generic_ncpaint(win, grid->theme_listview, (HRGN) wp);

        case WM_ERASEBKGND:
            return generic_erasebkgnd(win, grid->theme_listview, (HDC) wp);

        case MC_GM_GETTABLE:
            return (LRESULT) grid->table;

        case MC_GM_SETTABLE:
            return (grid_set_table(grid, (table_t*) lp) == 0 ? TRUE : FALSE);

        case MC_GM_GETCOLUMNCOUNT:
            return grid->col_count;

        case MC_GM_GETROWCOUNT:
            return grid->row_count;

        case MC_GM_RESIZE:
            return (grid_resize_table(grid, LOWORD(wp), HIWORD(wp)) == 0 ? TRUE : FALSE);

        case MC_GM_CLEAR:
            return (grid_clear(grid, wp) == 0 ? TRUE : FALSE);

        case MC_GM_SETCELLW:
        case MC_GM_SETCELLA:
            return (grid_set_cell(grid, LOWORD(wp), HIWORD(wp), (MC_TABLECELL*)lp,
                                  (msg == MC_GM_SETCELLW)) == 0 ? TRUE : FALSE);

        case MC_GM_GETCELLW:
        case MC_GM_GETCELLA:
            return (grid_get_cell(grid, LOWORD(wp), HIWORD(wp), (MC_TABLECELL*)lp,
                                  (msg == MC_GM_GETCELLW)) == 0 ? TRUE : FALSE);

        case MC_GM_SETGEOMETRY:
            return (grid_set_geometry(grid, (MC_GGEOMETRY*)lp, TRUE) == 0 ? TRUE : FALSE);

        case MC_GM_GETGEOMETRY:
            return (grid_get_geometry(grid, (MC_GGEOMETRY*)lp) == 0 ? TRUE : FALSE);

        case MC_GM_REDRAWCELLS:
            return (grid_redraw_cells(grid, LOWORD(wp), HIWORD(wp),
                                      LOWORD(lp), LOWORD(lp)) == 0 ? TRUE : FALSE);

        case MC_GM_SETCOLUMNWIDTH:
            return (grid_set_col_width(grid, wp, LOWORD(lp)) == 0 ? TRUE : FALSE);

        case MC_GM_GETCOLUMNWIDTH:
            return grid_get_col_width(grid, wp);

        case MC_GM_SETROWHEIGHT:
            return (grid_set_row_height(grid, wp, LOWORD(lp)) == 0 ? TRUE : FALSE);

        case MC_GM_GETROWHEIGHT:
            return grid_get_row_height(grid, wp);

        case WM_SETREDRAW:
            grid->no_redraw = !wp;
            return 0;

        case WM_VSCROLL:
        case WM_HSCROLL:
            grid_scroll(grid, (msg == WM_VSCROLL), LOWORD(wp), 1);
            return 0;

        case WM_MOUSEWHEEL:
        case WM_MOUSEHWHEEL:
            grid_mouse_wheel(grid, (msg == WM_MOUSEWHEEL), (int)(SHORT)HIWORD(wp));
            return 0;

        case WM_SIZE:
            if(!grid->no_redraw) {
                int old_scroll_x = grid->scroll_x;
                int old_scroll_y = grid->scroll_y;

                grid_setup_scrollbars(grid, FALSE);

                if(grid->scroll_x != old_scroll_x || grid->scroll_y != old_scroll_y)
                    InvalidateRect(win, NULL, TRUE);
            }
            return 0;

        case WM_GETFONT:
            return (LRESULT) grid->font;

        case WM_SETFONT:
            grid->font = (HFONT) wp;
            if((BOOL) lp  &&  !grid->no_redraw)
                InvalidateRect(win, NULL, TRUE);
            return 0;

        case WM_STYLECHANGED:
            if(wp == GWL_STYLE)
                grid_style_changed(grid, (STYLESTRUCT*) lp);
            break;

        case WM_THEMECHANGED:
            grid_close_theme(grid);
            grid_open_theme(grid);
            if(!grid->no_redraw)
                RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE);
            return 0;

        case WM_SYSCOLORCHANGE:
            if(!grid->no_redraw)
                RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE);
            return 0;

        case WM_NOTIFYFORMAT:
            if(lp == NF_REQUERY)
                grid_notify_format(grid);
            return (grid->unicode_notifications ? NFR_UNICODE : NFR_ANSI);

        case CCM_SETUNICODEFORMAT:
        {
            BOOL old = grid->unicode_notifications;
            grid->unicode_notifications = (wp != 0);
            return old;
        }

        case CCM_GETUNICODEFORMAT:
            return grid->unicode_notifications;

        case CCM_SETNOTIFYWINDOW:
        {
            HWND old = grid->notify_win;
            grid->notify_win = (wp ? (HWND) wp : GetAncestor(win, GA_PARENT));
            return (LRESULT) old;
        }

        case CCM_SETWINDOWTHEME:
            mcSetWindowTheme(win, (const WCHAR*) lp, NULL);
            return 0;

        case WM_NCCREATE:
            grid = grid_nccreate(win, (CREATESTRUCT*)lp);
            if(MC_ERR(grid == NULL))
                return FALSE;
            SetWindowLongPtr(win, 0, (LONG_PTR)grid);
            return TRUE;

        case WM_CREATE:
            return (grid_create(grid) == 0 ? 0 : -1);

        case WM_DESTROY:
            grid_destroy(grid);
            return 0;

        case WM_NCDESTROY:
            if(grid)
                grid_ncdestroy(grid);
            return 0;
    }

    return DefWindowProc(win, msg, wp, lp);
}