Exemple #1
0
void PDFDocument::Render(
    Document::PixelWriter* pw, int page, float zoom, int rotation) {
  assert((page >= 0) && (page < GetNumPages()));

  std::unique_lock<std::mutex> lock(_render_mutex);

  // 1. Init MuPDF structures.
  const fz_matrix& m = Transform(zoom, rotation);
  pdf_page* page_struct = GetPage(page);
  const fz_irect& bbox = GetBoundingBox(page_struct, m);
  fz_pixmap* pixmap = fz_new_pixmap_with_bbox(
      _fz_context, fz_device_rgb(_fz_context), FZ_OBJ(bbox), nullptr, 1);
  fz_device* dev = fz_new_draw_device(_fz_context, FZ_OBJ(fz_identity), pixmap);

  // 2. Render page.
  fz_clear_pixmap_with_value(_fz_context, pixmap, 0xff);
  pdf_run_page(
      _fz_context, _pdf_document, page_struct, dev, FZ_OBJ(m), nullptr);

  // 3. Write pixmap to buffer. The page is vertically divided into n equal
  // stripes, each copied to pw by one thread.
  assert(fz_pixmap_components(_fz_context, pixmap) == 4);
  uint8_t* buffer =
      reinterpret_cast<uint8_t*>(fz_pixmap_samples(_fz_context, pixmap));
  const int num_cols = fz_pixmap_width(_fz_context, pixmap);
  const int num_rows = fz_pixmap_height(_fz_context, pixmap);
  ExecuteInParallel([=](int num_threads, int i) {
    const int num_rows_per_thread = num_rows / num_threads;
    const int y_begin = i * num_rows_per_thread;
    const int y_end =
        (i == num_threads - 1) ? num_rows : (i + 1) * num_rows_per_thread;
    uint8_t* p = buffer + y_begin * num_cols * 4;
    for (int y = y_begin; y < y_end; ++y) {
      for (int x = 0; x < num_cols; ++x) {
        pw->Write(x, y, p[0], p[1], p[2]);
        p += 4;
      }
    }
  });

  // 4. Clean up.
  fz_close_device(_fz_context, dev);
  fz_drop_device(_fz_context, dev);
  fz_drop_pixmap(_fz_context, pixmap);
}
Exemple #2
0
static int bmpmupdf_pixmap_to_bmp(WILLUSBITMAP *bmp,fz_context *ctx,fz_pixmap *pixmap)

    {
	unsigned char *p;
	int ncomp,i,row,col;

    bmp->width=fz_pixmap_width(ctx,pixmap);
    bmp->height=fz_pixmap_height(ctx,pixmap);
    ncomp=fz_pixmap_components(ctx,pixmap);
    /* Has to be 8-bit or RGB */
	if (ncomp != 2 && ncomp != 4)
		return(-1);
    bmp->bpp=(ncomp==2) ? 8 : 24;
    bmp_alloc(bmp);
    if (ncomp==2)
        for (i=0;i<256;i++)
            bmp->red[i]=bmp->green[i]=bmp->blue[i]=i;
	p = fz_pixmap_samples(ctx,pixmap);
    if (ncomp==1)
        for (row=0;row<bmp->height;row++)
            {
            unsigned char *dest;
            dest=bmp_rowptr_from_top(bmp,row);
            memcpy(dest,p,bmp->width);
            p+=bmp->width;
            }
    else if (ncomp==2)
        for (row=0;row<bmp->height;row++)
            {
            unsigned char *dest;
            dest=bmp_rowptr_from_top(bmp,row);
            for (col=0;col<bmp->width;col++,dest++,p+=2)
                dest[0]=p[0];
            }
    else
        for (row=0;row<bmp->height;row++)
            {
            unsigned char *dest;
            dest=bmp_rowptr_from_top(bmp,row);
            for (col=0;col<bmp->width;col++,dest+=ncomp-1,p+=ncomp)
                memcpy(dest,p,ncomp-1);
            }
	return(0);
    }
Exemple #3
0
void winblit()
{
	int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
	int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
	int image_n = fz_pixmap_components(gapp.ctx, gapp.image);
	unsigned char *samples = fz_pixmap_samples(gapp.ctx, gapp.image);
	int x0 = gapp.panx;
	int y0 = gapp.pany;
	int x1 = gapp.panx + image_w;
	int y1 = gapp.pany + image_h;
	RECT r;

	if (gapp.image)
	{
		if (gapp.iscopying || justcopied)
		{
			pdfapp_invert(&gapp, &gapp.selr);
			justcopied = 1;
		}

		pdfapp_inverthit(&gapp);

		dibinf->bmiHeader.biWidth = image_w;
		dibinf->bmiHeader.biHeight = -image_h;
		dibinf->bmiHeader.biSizeImage = image_h * 4;

		if (image_n == 2)
		{
			int i = image_w * image_h;
			unsigned char *color = malloc(i*4);
			unsigned char *s = samples;
			unsigned char *d = color;
			for (; i > 0 ; i--)
			{
				d[2] = d[1] = d[0] = *s++;
				d[3] = *s++;
				d += 4;
			}
			SetDIBitsToDevice(hdc,
				gapp.panx, gapp.pany, image_w, image_h,
				0, 0, 0, image_h, color,
				dibinf, DIB_RGB_COLORS);
			free(color);
		}
		if (image_n == 4)
		{
			SetDIBitsToDevice(hdc,
				gapp.panx, gapp.pany, image_w, image_h,
				0, 0, 0, image_h, samples,
				dibinf, DIB_RGB_COLORS);
		}

		pdfapp_inverthit(&gapp);

		if (gapp.iscopying || justcopied)
		{
			pdfapp_invert(&gapp, &gapp.selr);
			justcopied = 1;
		}
	}

	/* Grey background */
	r.top = 0; r.bottom = gapp.winh;
	r.left = 0; r.right = x0;
	FillRect(hdc, &r, bgbrush);
	r.left = x1; r.right = gapp.winw;
	FillRect(hdc, &r, bgbrush);
	r.left = 0; r.right = gapp.winw;
	r.top = 0; r.bottom = y0;
	FillRect(hdc, &r, bgbrush);
	r.top = y1; r.bottom = gapp.winh;
	FillRect(hdc, &r, bgbrush);

	/* Drop shadow */
	r.left = x0 + 2;
	r.right = x1 + 2;
	r.top = y1;
	r.bottom = y1 + 2;
	FillRect(hdc, &r, shbrush);
	r.left = x1;
	r.right = x1 + 2;
	r.top = y0 + 2;
	r.bottom = y1;
	FillRect(hdc, &r, shbrush);

	winblitsearch();
}
Exemple #4
0
static void winblit(pdfapp_t *app)
{
	int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
	int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
	int image_n = fz_pixmap_components(gapp.ctx, gapp.image);
	unsigned char *image_samples = fz_pixmap_samples(gapp.ctx, gapp.image);
	int x0 = gapp.panx;
	int y0 = gapp.pany;
	int x1 = gapp.panx + image_w;
	int y1 = gapp.pany + image_h;

	XSetForeground(xdpy, xgc, xbgcolor.pixel);
	fillrect(0, 0, x0, gapp.winh);
	fillrect(x1, 0, gapp.winw - x1, gapp.winh);
	fillrect(0, 0, gapp.winw, y0);
	fillrect(0, y1, gapp.winw, gapp.winh - y1);

	XSetForeground(xdpy, xgc, xshcolor.pixel);
	fillrect(x0+2, y1, image_w, 2);
	fillrect(x1, y0+2, 2, image_h);

	if (gapp.iscopying || justcopied)
	{
		pdfapp_invert(&gapp, &gapp.selr);
		justcopied = 1;
	}

	pdfapp_inverthit(&gapp);

	if (image_n == 4)
		ximage_blit(xwin, xgc,
			x0, y0,
			image_samples,
			0, 0,
			image_w,
			image_h,
			image_w * image_n);
	else if (image_n == 2)
	{
		int i = image_w*image_h;
		unsigned char *color = malloc(i*4);
		if (color)
		{
			unsigned char *s = image_samples;
			unsigned char *d = color;
			for (; i > 0 ; i--)
			{
				d[2] = d[1] = d[0] = *s++;
				d[3] = *s++;
				d += 4;
			}
			ximage_blit(xwin, xgc,
				x0, y0,
				color,
				0, 0,
				image_w,
				image_h,
				image_w * 4);
			free(color);
		}
	}

	pdfapp_inverthit(&gapp);

	if (gapp.iscopying || justcopied)
	{
		pdfapp_invert(&gapp, &gapp.selr);
		justcopied = 1;
	}

	winblitsearch(app);

	if (showingpage)
	{
		char buf[42];
		snprintf(buf, sizeof buf, "Page %d/%d", gapp.pageno, gapp.pagecount);
		windrawstringxor(&gapp, 10, 20, buf);
	}
}
Exemple #5
0
QImage Pdf::page(int i)
      {
      fz_page* page = fz_load_page(doc, i);
      if (page == 0) {
            printf("cannot load page %d\n", i);
            return QImage();
            }
      static const float resolution = 300.0;
      const float zoom = resolution / 72.0;

      fz_rect bounds = fz_bound_page(doc, page);
      fz_matrix ctm  = fz_scale(zoom, zoom);
      fz_bbox bbox   = fz_round_rect(fz_transform_rect(ctm, bounds));
      fz_pixmap* pix = fz_new_pixmap_with_bbox(ctx, fz_device_gray, bbox);

      fz_clear_pixmap_with_value(ctx, pix, 255);
      fz_device* dev = fz_new_draw_device(ctx, pix);
      fz_run_page(doc, page, dev, ctm, NULL);
      fz_free_device(dev);
      dev = NULL;

      int w = fz_pixmap_width(ctx, pix);
      int h = fz_pixmap_height(ctx, pix);
      if (fz_pixmap_components(ctx, pix) != 2) {
            printf("omg: pixmap not bw? %d\n", fz_pixmap_components(ctx, pix));
            return QImage();
            }

      QImage image(w, h, QImage::Format_MonoLSB);
      QVector<QRgb> ct(2);
      ct[0] = qRgb(255, 255, 255);
      ct[1] = qRgb(0, 0, 0);
      image.setColorTable(ct);

      uchar* s   = fz_pixmap_samples(ctx, pix);
      int bytes  = w / 8;
      int bits   = w % 8;
      for (int line = 0; line < h; ++line) {
            uchar* d = image.scanLine(line);
            for (int col = 0; col < bytes; ++col) {
                  uchar data = 0;
                  for (int i = 0; i < 8; ++i) {
                        uchar v = *s;
                        s += 2;
                        data >>= 1;
                        if (v < 128) {            // convert grayscale to bw
                              data |= 0x80;
                              }
                        }
                  *d++ = data;
                  }
            uchar data = 0;
            for (int col = 0; col < bits; ++col) {
                  uchar v = *s;
                  s += 2;
                  data >>= 1;
                  if (v < 128)
                        data |= 0x80;
                  }
            }
      fz_drop_pixmap(ctx, pix);
      return image;
      }
Exemple #6
0
cairo_surface_t*
pdf_page_image_get_cairo(zathura_page_t* page, void* data,
    zathura_image_t* image, zathura_error_t* error)
{
  mupdf_page_t* mupdf_page = data;

  if (page == NULL || mupdf_page == NULL || image == NULL || image->data == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  fz_image* mupdf_image = (fz_image*) image->data;

  fz_pixmap* pixmap = NULL;
  cairo_surface_t* surface = NULL;

  pixmap = fz_get_pixmap_from_image(mupdf_page->ctx, mupdf_image, NULL, NULL, 0, 0);
  if (pixmap == NULL) {
    goto error_free;
  }

  surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, mupdf_image->w, mupdf_image->h);
  if (surface == NULL) {
    goto error_free;
  }

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

  unsigned char* s = fz_pixmap_samples(mupdf_page->ctx, pixmap);
  unsigned int n   = fz_pixmap_components(mupdf_page->ctx, pixmap);

  const int height = fz_pixmap_height(mupdf_page->ctx, pixmap);
  const int width  = fz_pixmap_width(mupdf_page->ctx, pixmap);
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      guchar* p = surface_data + y * rowstride + x * 4;

      // RGB
      if (n == 4) {
        p[0] = s[2];
        p[1] = s[1];
        p[2] = s[0];
      // Gray-scale or mask
      } else {
        p[0] = s[0];
        p[1] = s[0];
        p[2] = s[0];
      }
      s += n;
    }
  }

  fz_drop_pixmap(mupdf_page->ctx, pixmap);

  return surface;

error_free:

  if (pixmap != NULL) {
    fz_drop_pixmap(mupdf_page->ctx, pixmap);
  }

  if (surface != NULL) {
    cairo_surface_destroy(surface);
  }

error_ret:

  return NULL;
}