/* 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); } }
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); }