Use cairo to render page

This commit is contained in:
Moritz Lipp 2011-09-29 12:35:52 +02:00
parent 9f5d6cdd61
commit c3ad7faf1a
6 changed files with 92 additions and 88 deletions

View file

@ -471,19 +471,19 @@ zathura_page_form_fields_free(zathura_list_t* UNUSED(list))
return false; return false;
} }
zathura_image_buffer_t* bool
zathura_page_render(zathura_page_t* page) zathura_page_render(zathura_page_t* page, cairo_t* cairo)
{ {
if (page == NULL || page->document == NULL) { if (page == NULL || page->document == NULL || cairo == NULL) {
return NULL; return NULL;
} }
if (page->document->functions.page_render == NULL) { if (page->document->functions.page_render_cairo == NULL) {
girara_error("%s not implemented", __FUNCTION__); girara_error("%s not implemented", __FUNCTION__);
return NULL; return NULL;
} }
return page->document->functions.page_render(page); return page->document->functions.page_render_cairo(page, cairo);
} }
zathura_index_element_t* zathura_index_element_t*

View file

@ -150,7 +150,7 @@ struct zathura_page_s
GtkWidget* event_box; /**> Widget wrapper for mouse events */ GtkWidget* event_box; /**> Widget wrapper for mouse events */
GtkWidget* drawing_area; /**> Drawing area */ GtkWidget* drawing_area; /**> Drawing area */
GStaticMutex lock; /**> Lock */ GStaticMutex lock; /**> Lock */
cairo_surface_t* surface; /** Cairo surface */ cairo_surface_t* surface; /** Cairo surface */
}; };
/** /**
@ -363,9 +363,10 @@ bool zathura_page_form_fields_free(zathura_list_t* list);
* Render page * Render page
* *
* @param page The page object * @param page The page object
* @return Image buffer or NULL if an error occured * @param cairo Cairo object
* @return True if no error occured, otherwise false
*/ */
zathura_image_buffer_t* zathura_page_render(zathura_page_t* page); bool zathura_page_render(zathura_page_t* page, cairo_t* cairo);
/** /**
* Create new index element * Create new index element

43
print.c
View file

@ -51,32 +51,33 @@ void
cb_print_draw_page(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext* cb_print_draw_page(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext*
context, gint page_number, zathura_t* zathura) context, gint page_number, zathura_t* zathura)
{ {
cairo_t* cairo = gtk_print_context_get_cairo_context(context); /* TODO: Implement with cairo */
/*cairo_t* cairo = gtk_print_context_get_cairo_context(context);*/
girara_info("Printing page %d", page_number); /*girara_info("Printing page %d", page_number);*/
zathura_page_t* page = zathura->document->pages[page_number]; /*zathura_page_t* page = zathura->document->pages[page_number];*/
double requested_with = gtk_print_context_get_width(context); /*double requested_with = gtk_print_context_get_width(context);*/
double tmp_scale = zathura->document->scale; /*double tmp_scale = zathura->document->scale;*/
zathura->document->scale = requested_with / page->width; /*zathura->document->scale = requested_with / page->width;*/
g_static_mutex_lock(&(page->lock)); /*g_static_mutex_lock(&(page->lock));*/
zathura_image_buffer_t* image_buffer = zathura_page_render(page); /*zathura_image_buffer_t* image_buffer = zathura_page_render(page);*/
g_static_mutex_unlock(&(page->lock)); /*g_static_mutex_unlock(&(page->lock));*/
for (unsigned int y = 0; y < image_buffer->height; y++) { /*for (unsigned int y = 0; y < image_buffer->height; y++) {*/
unsigned char* src = image_buffer->data + y * image_buffer->rowstride; /*unsigned char* src = image_buffer->data + y * image_buffer->rowstride;*/
for (unsigned int x = 0; x < image_buffer->width; x++) { /*for (unsigned int x = 0; x < image_buffer->width; x++) {*/
if (src[0] != 255 && src[1] != 255 && src[2] != 255) { /*if (src[0] != 255 && src[1] != 255 && src[2] != 255) {*/
cairo_set_source_rgb(cairo, src[0], src[1], src[2]); /*cairo_set_source_rgb(cairo, src[0], src[1], src[2]);*/
cairo_rectangle(cairo, x, y, 1, 1); /*cairo_rectangle(cairo, x, y, 1, 1);*/
cairo_fill(cairo); /*cairo_fill(cairo);*/
} /*}*/
src += 3; /*src += 3;*/
} /*}*/
} /*}*/
zathura->document->scale = tmp_scale; /*zathura->document->scale = tmp_scale;*/
} }

View file

@ -21,6 +21,6 @@ void print(zathura_t* zathura);
* @param zathura Zathura object * @param zathura Zathura object
*/ */
void cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext* void cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext*
context, gint page_number, zathura_t* zathura); context, gint page_number, zathura_t* zathura);
#endif // PRINT_H #endif // PRINT_H

116
render.c
View file

@ -151,36 +151,73 @@ render(zathura_t* zathura, zathura_page_t* page)
gdk_threads_enter(); gdk_threads_enter();
g_static_mutex_lock(&(page->lock)); g_static_mutex_lock(&(page->lock));
zathura_image_buffer_t* image_buffer = zathura_page_render(page);
if (image_buffer == NULL) { /* create cairo surface */
unsigned int page_width = 0;
unsigned int page_height = 0;
if (page->document->rotate == 0 || page->document->rotate == 180) {
page_width = page->width * zathura->document->scale;
page_height = page->height * zathura->document->scale;
} else {
page_width = page->height * zathura->document->scale;
page_height = page->width * zathura->document->scale;
}
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
if (surface == NULL) {
g_static_mutex_unlock(&(page->lock)); g_static_mutex_unlock(&(page->lock));
gdk_threads_leave(); gdk_threads_leave();
return false; return false;
} }
/* create cairo surface */ cairo_t* cairo = cairo_create(surface);
unsigned int page_width = page->width * zathura->document->scale;
unsigned int page_height = page->height * zathura->document->scale;
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height); if (cairo == NULL) {
cairo_surface_destroy(surface);
g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return false;
}
cairo_save(cairo);
cairo_set_source_rgb(cairo, 1, 1, 1);
cairo_rectangle(cairo, 0, 0, page_width, page_height);
cairo_fill(cairo);
cairo_restore(cairo);
cairo_save(cairo);
switch(page->document->rotate) {
case 90:
cairo_translate(cairo, page_width, 0);
break;
case 180:
cairo_translate(cairo, page_width, page_height);
break;
case 270:
cairo_translate(cairo, 0, page_height);
break;
}
if (page->document->rotate != 0) {
cairo_rotate(cairo, page->document->rotate * G_PI / 180.0);
}
if (zathura_page_render(page, cairo) == false) {
cairo_destroy(cairo);
cairo_surface_destroy(surface);
g_static_mutex_unlock(&(page->lock));
gdk_threads_leave();
return false;
}
cairo_restore(cairo);
cairo_destroy(cairo);
int rowstride = cairo_image_surface_get_stride(surface); int rowstride = cairo_image_surface_get_stride(surface);
unsigned char* image = cairo_image_surface_get_data(surface); unsigned char* image = cairo_image_surface_get_data(surface);
for (unsigned int y = 0; y < page_height; y++) {
unsigned char* dst = image + y * rowstride;
unsigned char* src = image_buffer->data + y * image_buffer->rowstride;
for (unsigned int x = 0; x < page_width; x++) {
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
src += 3;
dst += 4;
}
}
/* recolor */ /* recolor */
if (zathura->global.recolor) { if (zathura->global.recolor) {
/* recolor code based on qimageblitz library flatten() function /* recolor code based on qimageblitz library flatten() function
@ -214,49 +251,14 @@ render(zathura_t* zathura, zathura_page_t* page)
} }
} }
/* rotate */
unsigned int width = page_width;
unsigned int height = page_height;
if (page->document->rotate == 90 || page->document->rotate == 270) {
width = page_height;
height = page_width;
}
cairo_surface_t* final_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
cairo_t* cairo = cairo_create(final_surface);
switch(page->document->rotate)
{
case 90:
cairo_translate(cairo, width, 0);
break;
case 180:
cairo_translate(cairo, width, height);
break;
case 270:
cairo_translate(cairo, 0, height);
break;
}
if (page->document->rotate != 0) {
cairo_rotate(cairo, page->document->rotate * G_PI / 180.0);
}
cairo_set_source_surface(cairo, surface, 0, 0);
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
cairo_paint(cairo);
cairo_destroy(cairo);
cairo_surface_destroy(surface);
/* draw to gtk widget */ /* draw to gtk widget */
page->surface = final_surface; page->surface = surface;
gtk_widget_set_size_request(page->drawing_area, width, height); gtk_widget_set_size_request(page->drawing_area, page_width, page_height);
gtk_widget_queue_draw(page->drawing_area); gtk_widget_queue_draw(page->drawing_area);
zathura_image_buffer_free(image_buffer);
g_static_mutex_unlock(&(page->lock)); g_static_mutex_unlock(&(page->lock));
gdk_threads_leave(); gdk_threads_leave();
return true; return true;
} }

View file

@ -16,7 +16,7 @@ struct render_thread_s
GThread* thread; /**> The thread object */ GThread* thread; /**> The thread object */
GMutex* lock; /**> Lock */ GMutex* lock; /**> Lock */
GCond* cond; /**> Condition */ GCond* cond; /**> Condition */
zathura_t* zathura; /**> Zathura object */ zathura_t* zathura; /**> Zathura object */
}; };
/** /**