/* 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; SDL_Event event; PopplerDocument *document; GError *error; const char *pdf_file; gchar *absolute, *uri; int page_num = 1, num_pages; cairo_t *cr; double width, height; float ofs; PopplerPage *page; SDL_TimerID t = 0; SDL_Surface *pg_sf; SDL_Surface *n1, *n2, *n1l, *n2l; SDL_Surface **preld_sf = NULL; SDL_Surface *src_sf = NULL; int prerender = 1; if (argc < 2) { printf("Usage: %s input_file.pdf (pagenum)\n",argv[0]); return 0; } pdf_file = argv[1]; if (argc > 2) page_num = atoi(argv[2]); g_type_init(); error = NULL; n1 = IMG_Load("1_32.png"); n2 = IMG_Load("2_32.png"); if (g_path_is_absolute(pdf_file)) { absolute = g_strdup(pdf_file); } else { gchar *dir = g_get_current_dir(); absolute = g_build_filename(dir, pdf_file, (gchar *) 0); free(dir); } uri = g_filename_to_uri(absolute, NULL, &error); free(absolute); if (uri == NULL) { printf("%s\n", error->message); return 1; } document = poppler_document_new_from_file(uri, NULL, &error); if (document == NULL) { printf("%s\n", error->message); return 1; } num_pages = poppler_document_get_n_pages(document); if (page_num < 1 || page_num > num_pages) { printf("page must be between 1 and %d\n", num_pages); return 1; } page = poppler_document_get_page(document, 0); if (page == NULL) { printf("poppler fail: page not found\n"); return 1; } /* Initialize SDL, open a screen */ screen = init_screen(1024, 768, 32); n1l = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCALPHA, screen->w, 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); n2l = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCALPHA, screen->w, 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); make_nyans(n1l, n1); make_nyans(n2l, n2); pg_sf = SDL_CreateRGBSurface(SDL_HWSURFACE | 0, screen->w, screen->h, 32, CAIROSDL_RMASK, CAIROSDL_GMASK, CAIROSDL_BMASK, 0); cr = cairosdl_create(pg_sf); poppler_page_get_size(page, &width, &height); g_object_unref(page); cairo_scale(cr, screen->w / width, screen->h / height); draw_page(pg_sf, cr, document, page_num); SDL_BlitSurface(pg_sf, NULL, screen, NULL); SDL_Flip(screen); if (prerender) { int i; preld_sf = malloc(sizeof(SDL_Surface *) * num_pages); for (i = 0; i < num_pages; i++) { preld_sf[i] = SDL_CreateRGBSurface(SDL_HWSURFACE | 0, screen->w, screen->h, 32, CAIROSDL_RMASK, CAIROSDL_GMASK, CAIROSDL_BMASK, 0); draw_page(pg_sf, cr, document, i + 1); SDL_BlitSurface(pg_sf, NULL, preld_sf[i], NULL); } } while (SDL_WaitEvent(&event)) { int new_page = 0; switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { goto done; } else if (event.key.keysym.sym == SDLK_SPACE) { new_page = 1; ++page_num; } else if (event.key.keysym.sym == SDLK_RIGHT) { new_page = 1; ++page_num; } else if (event.key.keysym.sym == SDLK_LEFT) { new_page = 1; --page_num; } else if (event.key.keysym.sym == SDLK_PAGEUP) { new_page = 1; --page_num; } else if (event.key.keysym.sym == SDLK_PAGEDOWN) { new_page = 1; ++page_num; } if (new_page) { SDL_Rect sr, sd; float x; SDL_RemoveTimer(t); if (page_num > num_pages) page_num = num_pages; if (page_num < 1) page_num = 1; src_sf = pg_sf; if (!prerender) draw_page(pg_sf, cr, document, page_num); else { src_sf = preld_sf[page_num - 1]; } SDL_BlitSurface(src_sf, NULL, screen, NULL); ofs = num_pages - page_num; ofs /= num_pages; x = n1l->w; x *= ofs; sr.x = x; sr.w = n1l->w - x; sr.h = n1l->h; sr.y = 0; #ifndef NYAN_TOP sd.y = screen->h - n1l->h; #else sd.y = 0; #endif sd.w = sr.w; sd.x = 0; sd.h = sr.h; SDL_BlitSurface(page_num & 1 ? n1l : n2l, &sr, screen, &sd); SDL_Flip(screen); t = SDL_AddTimer(1000, timer_cb, NULL); } break; case SDL_QUIT: goto done; case SDL_USEREVENT: SDL_BlitSurface(src_sf, NULL, screen, NULL); SDL_Flip(screen); break; default: break; } } done: SDL_FreeSurface(screen); SDL_Quit(); return 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); }