Пример #1
0
/* Shows how to draw with Cairo on SDL surfaces */
static void
draw_screen (SDL_Surface *screen)
{
    cairo_t *cr;
    cairo_status_t status;

    /* Create a cairo drawing context, normalize it and draw a clock. */
    SDL_LockSurface (screen); {
        cr = cairosdl_create (screen);

        cairo_scale (cr, screen->w, screen->h);
        draw (cr);

        status = cairo_status (cr);
        cairosdl_destroy (cr);
    }
    SDL_UnlockSurface (screen);
    SDL_Flip (screen);

    /* Nasty nasty error handling. */
    if (status != CAIRO_STATUS_SUCCESS) {
        fprintf (stderr, "Unable to create or draw with a cairo context "
                 "for the screen: %s\n",
                 cairo_status_to_string (status));
        exit (1);
    }
}
Пример #2
0
int main(int argc, char *argv[]) {
	SDL_Surface *screen;

	GError *error = NULL;
	RsvgHandle *handle;
	struct svgviewer_view vw;
	char *filename;
	//const char *output_filename = argv[2];
	cairo_surface_t *surface;
	cairo_t *cr;
	cairo_t *cr2;
	cairo_status_t status;
	int c;
	int rerender = 0;

	SDL_VideoInfo* info;
	vw.zoom = 1;

	/* Process options */
	while (1) {
	  int option_index = 0;
	  
	  c = getopt_long (argc, argv, "d:v:",
			   long_options, &option_index);

	  /* Detect the end of the options. */
	  if (c == -1) break;
	  switch (c) {
	  case 0:
	    break;
	  case 'z':
	    errno = 0;
	    vw.zoom = strtod(optarg, NULL);
	    DEBUG("Zoom set to %g\n", vw.zoom);
	    if (errno) FAIL("Usage: -z or --zoom requires a floating point argument");
	    break;
	  default:
	    abort();
	  };
	}
     
	if (argc != optind+1) FAIL("Usage: %s OPTIONS input_file.svg\n", argv[0]);
	filename = argv[optind];

	g_type_init();

	rsvg_set_default_dpi(72.0);
	handle = rsvg_handle_new_from_file(filename, &error);
	if (error != NULL)
		FAIL(error->message);

	rsvg_handle_get_dimensions(handle, &dim);
	vw.x = 0; vw.y = 0;
	vw.zoom    = 1;

	/* Initialize SDL */
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
		fprintf(stderr, "Unable to initialize SDL: %s\n",
			SDL_GetError());
		exit(1);
	}

	int videomodeflags;
	if (fullscreen_flag) {
	  screen = SDL_SetVideoMode(0, 0, 32,
				    videomodeflags =
				    SDL_FULLSCREEN | SDL_SWSURFACE | SDL_RESIZABLE);
	} else {
	  const SDL_VideoInfo* info = SDL_GetVideoInfo(); 
	  if ((dim.width  >= info->current_w) ||
	      (dim.height >= info->current_h)) {
	    screen = SDL_SetVideoMode(0, 0, 32,
				      videomodeflags =
				      SDL_SWSURFACE | SDL_RESIZABLE);
	  } else {
	    screen = SDL_SetVideoMode(dim.width, dim.height, 32,
				      videomodeflags =
				      SDL_SWSURFACE | SDL_RESIZABLE);
	  }
	}

	if (screen == NULL) {
	  fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
	  exit(1);
	}
	
	vw.pixel_width   = screen->w;
	vw.pixel_height  = screen->h;

	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, vw.pixel_width, vw.pixel_height);
	cr2 = cairo_create (surface); 
	//cairo_translate(cr2, ((double)dim.width)/-2, ((double)dim.height)/-2);
	//surface = cairo_pdf_surface_create (output_filename, width, height);
	// SDL_LockSurface(screen);
	//cairo_scale (cr, screen->w, screen->h);
	cairo_save(cr2);
	view_transform(cr2, &vw);
	rsvg_handle_render_cairo(handle, cr2);
	status = cairo_status(cr2);
	if (status) FAIL(cairo_status_to_string(status));
	cairo_restore(cr2);
	cr = cairosdl_create(screen);

	// cairo_set_source_rgb(cr, 1, 1, 1);
	// cairo_paint(cr);
	
	cairo_save(cr);
	//cairo_scale(cr, .5, .5);
	//cairo_translate(cr, width/2, height/2 );
	//cairo_rotate( cr, 3.14/2 );
	//cairo_translate(cr, -width/2, -height/2 );
	cairo_set_source_surface (cr, surface, 0, 0);
	cairo_paint(cr);
	cairo_restore(cr);
	
	status = cairo_status(cr);
	if (status)
	  FAIL(cairo_status_to_string(status));
	
	// SDL_UnlockSurface(screen);
	SDL_UpdateRect(screen, 0, 0, 0, 0);

	{
	  SDL_Event event;
	  while (SDL_WaitEvent(&event)) {
	    switch (event.type) {
	    case SDL_KEYDOWN:
	      switch (event.key.keysym.sym) {
	      case SDLK_UP:
		vw.y -= 0.1 / vw.zoom;
		rerender = 1;
		break;
	      case SDLK_DOWN:
		vw.y += 0.1 / vw.zoom;
		rerender = 1;
		break;
	      case SDLK_LEFT:
		vw.x -= 0.1 / vw.zoom;
		rerender = 1;
		break;
	      case SDLK_RIGHT:
		vw.x += 0.1 / vw.zoom;
		rerender = 1;
		break;
	      case SDLK_a:
		vw.zoom *= 1.025;
		rerender = 1;
		break;
	      case SDLK_z:
		vw.zoom /= 1.025;
		rerender = 1;
		break;
	      case SDLK_ESCAPE:
		goto exit;
	      default:
		break;
	      }
	      break;
	    case SDL_VIDEORESIZE:
	      {
		vw.pixel_width = event.resize.w;
		vw.pixel_height = event.resize.h;
		cairo_destroy(cr2);
		cairo_surface_destroy(surface);
		surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, vw.pixel_width, vw.pixel_height);
		cr2 = cairo_create(surface);
		//cairo_translate(cr2, ((double)dim.width)/-2, ((double)dim.height)/-2);
		cairo_save(cr2);
		view_transform(cr2, &vw);
		rsvg_handle_render_cairo(handle, cr2);
		cairo_restore(cr2);
		screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 32, videomodeflags);
		cairosdl_destroy(cr);
		cr = cairosdl_create(screen);
		cairo_save(cr);
		cairo_set_source_surface(cr, surface, 0, 0);
		cairo_paint(cr);
		cairo_restore(cr);
	      };
	      break;
	    case SDL_QUIT:
	      goto exit;
	    default:
	      break;
	    }
	    if (rerender) {
		cairo_save(cr2);
		view_transform(cr2, &vw);
		rsvg_handle_render_cairo(handle, cr2);
		status = cairo_status(cr2);
		if (status) FAIL(cairo_status_to_string(status));
		cairo_restore(cr2);
		cairo_set_source_surface(cr, surface, 0, 0);
		cairo_paint(cr);
		rerender = 0;
	    }
	    SDL_UpdateRect(screen, 0, 0, 0, 0);
	  };
	};

 exit:
	cairosdl_destroy(cr);
	if (status)
		FAIL(cairo_status_to_string(status));

	cairo_destroy (cr2);
	cairo_surface_destroy(surface);
	SDL_Quit();
	exit(EXIT_SUCCESS);
}