Ejemplo n.º 1
0
void
zathura_document_get_cell_size(zathura_document_t* document,
                               unsigned int* height, unsigned int* width)
{
  g_return_if_fail(document != NULL && height != NULL && width != NULL);

  unsigned int number_of_pages =
    zathura_document_get_number_of_pages(document);
  *width = 0;
  *height = 0;

  /* Get the size of each cell of the table/grid, assuming it is homogeneous
   * (i.e. each cell has the same dimensions. */
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(document, page_id);
    if (page == NULL)
      continue;

    unsigned int page_width = 0, page_height = 0;
    page_calc_height_width(page, &page_height, &page_width, true);

    if (*width < page_width)
      *width = page_width;
    if (*height < page_height)
      *height = page_height;
  }
}
Ejemplo n.º 2
0
void
zathura_document_get_cell_size(zathura_document_t* document,
                               unsigned int* height, unsigned int* width)
{
  g_return_if_fail(document != NULL && height != NULL && width != NULL);

  page_calc_height_width(document, document->cell_height, document->cell_width,
                         height, width, true);
}
Ejemplo n.º 3
0
void
render_all(zathura_t* zathura)
{
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

  /* unmark all pages */
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
    unsigned int page_height = 0, page_width = 0;
    page_calc_height_width(page, &page_height, &page_width, true);

    GtkWidget* widget = zathura_page_get_widget(zathura, page);
    gtk_widget_set_size_request(widget, page_width, page_height);
    gtk_widget_queue_resize(widget);
  }
}
Ejemplo n.º 4
0
static bool
render(zathura_t* zathura, zathura_page_t* page)
{
  if (zathura == NULL || page == NULL || zathura->sync.render_thread->about_to_close == true) {
    return false;
  }

  /* create cairo surface */
  unsigned int page_width  = 0;
  unsigned int page_height = 0;
  page_calc_height_width(page, &page_height, &page_width, false);

  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);

  if (surface == NULL) {
    return false;
  }

  cairo_t* cairo = cairo_create(surface);

  if (cairo == NULL) {
    cairo_surface_destroy(surface);
    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);

  double scale = zathura_document_get_scale(zathura->document);
  if (fabs(scale - 1.0f) > FLT_EPSILON) {
    cairo_scale(cairo, scale, scale);
  }

  render_lock(zathura->sync.render_thread);
  if (zathura_page_render(page, cairo, false) != ZATHURA_ERROR_OK) {
    render_unlock(zathura->sync.render_thread);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);
    return false;
  }

  render_unlock(zathura->sync.render_thread);
  cairo_restore(cairo);
  cairo_destroy(cairo);

  const int rowstride  = cairo_image_surface_get_stride(surface);
  unsigned char* image = cairo_image_surface_get_data(surface);

  /* recolor */
  /* uses a representation of a rgb color as follows:
     - a lightness scalar (between 0,1), which is a weighted average of r, g, b,
     - a hue vector, which indicates a radian direction from the grey axis, inside the equal lightness plane.
     - a saturation scalar between 0,1. It is 0 when grey, 1 when the color is in the boundary of the rgb cube.
  */
  if (zathura->global.recolor == true) {
    /* RGB weights for computing lightness. Must sum to one */
    double a[] = {0.30, 0.59, 0.11};

    double l1, l2, l, s, u, t;
    double h[3];
    double rgb1[3], rgb2[3], rgb[3];

    color2double(&zathura->ui.colors.recolor_dark_color, rgb1);
    color2double(&zathura->ui.colors.recolor_light_color, rgb2);

    l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]);
    l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]);

    for (unsigned int y = 0; y < page_height; y++) {
      unsigned char* data = image + y * rowstride;

      for (unsigned int x = 0; x < page_width; x++) {
        /* Careful. data color components blue, green, red. */
        rgb[0] = (double) data[2] / 256.;
        rgb[1] = (double) data[1] / 256.;
        rgb[2] = (double) data[0] / 256.;

        /* compute h, s, l data   */
        l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2];

        h[0] = rgb[0] - l;
        h[1] = rgb[1] - l;
        h[2] = rgb[2] - l;

        /* u is the maximum possible saturation for given h and l. s is a rescaled saturation between 0 and 1 */
        u = colorumax(h, l, 0, 1);
        if (u == 0) {
          s = 0;
        } else {
          s = 1/u;
        }

        /* Interpolates lightness between light and dark colors. white goes to light, and black goes to dark. */
        t = l;
        l = t * (l2 - l1) + l1;

        if (zathura->global.recolor_keep_hue == true) {
          /* adjusting lightness keeping hue of current color. white and black go to grays of same ligtness
             as light and dark colors. */
          u = colorumax(h, l, l1, l2);
          data[2] = (unsigned char)round(255.*(l + s*u * h[0]));
          data[1] = (unsigned char)round(255.*(l + s*u * h[1]));
          data[0] = (unsigned char)round(255.*(l + s*u * h[2]));
        } else {
          /* Linear interpolation between dark and light with color ligtness as a parameter */
          data[2] = (unsigned char)round(255.*(t * (rgb2[0] - rgb1[0]) + rgb1[0]));
          data[1] = (unsigned char)round(255.*(t * (rgb2[1] - rgb1[1]) + rgb1[1]));
          data[0] = (unsigned char)round(255.*(t * (rgb2[2] - rgb1[2]) + rgb1[2]));
        }

        data += 4;
      }
    }
  }

  if (zathura->sync.render_thread->about_to_close == false) {
    /* update the widget */
    gdk_threads_enter();
    GtkWidget* widget = zathura_page_get_widget(zathura, page);
    zathura_page_widget_update_surface(ZATHURA_PAGE(widget), surface);
    gdk_threads_leave();
  } else {
    cairo_surface_destroy(surface);
  }

  return true;
}