Example #1
0
fz_irect PDFDocument::GetBoundingBox(
    pdf_page* page_struct, const fz_matrix& m) {
  assert(page_struct != nullptr);
#if MUPDF_VERSION >= 10014
  return fz_round_rect(
      fz_transform_rect(pdf_bound_page(_fz_context, page_struct), m));
#else
  fz_rect bbox;
  fz_irect ibbox;
  return *fz_round_rect(
      &ibbox,
      fz_transform_rect(
          pdf_bound_page(_fz_context, _pdf_document, page_struct, &bbox), &m));
#endif
}
Example #2
0
void
fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax)
{
	if (xmin >= xmax || ymin >= ymax)
	{
		/* Invalid bbox supplied. It would be prohibitively slow to
		 * measure the true one, so make one up. */
		font->bbox.x0 = -1;
		font->bbox.y0 = -1;
		font->bbox.x1 = 2;
		font->bbox.y1 = 2;
	}
	else
	{
		font->bbox.x0 = xmin;
		font->bbox.y0 = ymin;
		font->bbox.x1 = xmax;
		font->bbox.y1 = ymax;
	}
	/* SumatraPDF: some fonts seem to use oversized bboxes (Ghostscript issue?) */
	if (xmax - xmin == 1000 && ymax - ymin == 1000)
	{
		fz_matrix ctm;
		fz_transform_rect(&font->bbox, fz_scale(&ctm, 0.001f, 0.001f));
	}
}
Example #3
0
void
pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_rect bbox)
{
	pdf_document *doc = annot->page->doc;
	fz_matrix page_ctm, inv_page_ctm;
	pdf_obj *quad_points;

	check_allowed_subtypes(ctx, annot, PDF_NAME(QuadPoints), quad_point_subtypes);

	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
	fz_invert_matrix(&inv_page_ctm, &page_ctm);

	quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME(QuadPoints));
	if (!pdf_is_array(ctx, quad_points))
	{
		quad_points = pdf_new_array(ctx, doc, 8);
		pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(QuadPoints), quad_points);
	}

	/* Contrary to the specification, the points within a QuadPoint are NOT ordered
	 * in a counterclockwise fashion. Experiments with Adobe's implementation
	 * indicates a cross-wise ordering is intended: ul, ur, ll, lr.
	 */
	fz_transform_rect(&bbox, &inv_page_ctm);
	pdf_array_push_real(ctx, quad_points, bbox.x0); /* ul */
	pdf_array_push_real(ctx, quad_points, bbox.y1);
	pdf_array_push_real(ctx, quad_points, bbox.x1); /* ur */
	pdf_array_push_real(ctx, quad_points, bbox.y1);
	pdf_array_push_real(ctx, quad_points, bbox.x0); /* ll */
	pdf_array_push_real(ctx, quad_points, bbox.y0);
	pdf_array_push_real(ctx, quad_points, bbox.x1); /* lr */
	pdf_array_push_real(ctx, quad_points, bbox.y0);

	pdf_dirty_annot(ctx, annot);
}
Example #4
0
HRESULT MuPDFDoc::GotoPage(int pageNumber)
{
	int index = FindPageInCache(pageNumber);
	if (index >= 0)
	{
		m_currentPage = index;
		return S_OK;
	}
	index = GetPageCacheIndex(pageNumber);
	m_currentPage = index;
	PageCache *pageCache = &m_pages[m_currentPage];
	ClearPageCache(pageCache);
	/* In the event of an error, ensure we give a non-empty page */
	pageCache->width = 100;
	pageCache->height = 100;
	pageCache->number = pageNumber;
	fz_try(m_context)
	{
		pageCache->page = fz_load_page(m_document, pageCache->number);
		pageCache->mediaBox = fz_bound_page(m_document, pageCache->page);
		// fz_bound_page determine the size of a page at 72 dpi.
		fz_matrix ctm = CalcConvertMatrix();
		fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, pageCache->mediaBox));
		pageCache->width = bbox.x1 - bbox.x0;
		pageCache->height = bbox.y1 - bbox.y0;
	}
	fz_catch(m_context)
	{
		return E_FAIL;
	}
	return S_OK;
}
Example #5
0
static void
fz_bbox_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
{
	fz_bbox *result = dev->user;
	fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect));
	*result = fz_union_bbox(*result, bbox);
}
Example #6
0
fz_pixmap *
fz_new_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, const fz_matrix *ctm, fz_colorspace *cs, int background)
{
	fz_rect rect;
	fz_irect irect;
	fz_pixmap *pix;
	fz_device *dev;

	fz_bound_display_list(ctx, list, &rect);
	fz_transform_rect(&rect, ctm);
	fz_round_rect(&irect, &rect);

	pix = fz_new_pixmap_with_bbox(ctx, cs, &irect);
	if (background)
		fz_clear_pixmap_with_value(ctx, pix, 0xFF);
	else
		fz_clear_pixmap(ctx, pix);

	fz_try(ctx)
	{
		dev = fz_new_draw_device(ctx, pix);
		fz_run_display_list(ctx, list, dev, ctm, NULL, NULL);
	}
	fz_always(ctx)
	{
		fz_drop_device(ctx, dev);
	}
	fz_catch(ctx)
	{
		fz_drop_pixmap(ctx, pix);
		fz_rethrow(ctx);
	}

	return pix;
}
Example #7
0
static void
fz_bbox_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_rect r = fz_unit_rect;
	fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 0);
}
Example #8
0
bool PdfCreator::AddImagePage(fz_image *image, float imgDpi)
{
    CrashIf(!ctx || !doc);
    if (!ctx || !doc) return false;

    pdf_page *page = nullptr;
    fz_device *dev = nullptr;
    fz_var(page);
    fz_var(dev);

    fz_try(ctx) {
        float zoom = imgDpi ? 72 / imgDpi : 1.0f;
        fz_matrix ctm = { image->w * zoom, 0, 0, image->h * zoom, 0, 0 };
        fz_rect bounds = fz_unit_rect;
        fz_transform_rect(&bounds, &ctm);
        page = pdf_create_page(doc, bounds, 72, 0);
        dev = pdf_page_write(doc, page);
        fz_fill_image(dev, image, &ctm, 1.0);
        fz_free_device(dev);
        dev = nullptr;
        pdf_insert_page(doc, page, INT_MAX);
    }
    fz_always(ctx) {
        fz_free_device(dev);
        pdf_free_page(doc, page);
    }
    fz_catch(ctx) {
        return false;
    }
    return true;
}
Example #9
0
void Mpdf::showPage()
{
    fz_page *page = fz_load_page(doc, currentPage - 1);

    fz_matrix transform;
    fz_rotate(&transform, 0);
    fz_pre_scale(&transform, currentZoom / 100.0f, currentZoom / 100.0f);

    fz_rect bounds;
    fz_bound_page(doc, page, &bounds);
    fz_transform_rect(&bounds, &transform);

    fz_irect bbox;
    fz_round_rect(&bbox, &bounds);
    fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, &bbox);
    fz_clear_pixmap_with_value(ctx, pix, 0xff);

    fz_device *dev = fz_new_draw_device(ctx, pix);
    fz_run_page(doc, page, dev, &transform, NULL);
    fz_free_device(dev);
    
    QString qpng = QString("%1.png").arg(currentPage);
    const char *ccpng = qpng.toStdString().c_str();
    char *cpng = new char[strlen(ccpng) + 1];
    strcpy(cpng, ccpng);
    
    fz_write_png(ctx, pix, cpng, 0);
    QPixmap qpix(qpng);
    pdfLabel->setPixmap(qpix);

    fz_drop_pixmap(ctx, pix);
    fz_free_page(doc, page);
}
Example #10
0
static void
fz_text_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *img, const fz_matrix *ctm,
		fz_colorspace *cspace, float *color, float alpha)
{
	fz_text_device *tdev = (fz_text_device*)dev;
	fz_text_page *page = tdev->page;
	fz_image_block *block;

	/* If the alpha is less than 50% then it's probably a watermark or
	 * effect or something. Skip it */
	if (alpha < 0.5)
		return;

	/* New block */
	if (page->len == page->cap)
	{
		int newcap = (page->cap ? page->cap*2 : 4);
		page->blocks = fz_resize_array(ctx, page->blocks, newcap, sizeof(*page->blocks));
		page->cap = newcap;
	}
	block = fz_malloc_struct(ctx, fz_image_block);
	page->blocks[page->len].type = FZ_PAGE_BLOCK_IMAGE;
	page->blocks[page->len].u.image = block;
	block->image = fz_keep_image(ctx, img);
	block->cspace = fz_keep_colorspace(ctx, cspace);
	if (cspace)
		memcpy(block->colors, color, sizeof(block->colors[0])*cspace->n);
	block->mat = *ctm;
	block->bbox.x0 = 0;
	block->bbox.y0 = 0;
	block->bbox.x1 = 1;
	block->bbox.y1 = 1;
	fz_transform_rect(&block->bbox, ctm);
	page->len++;
}
Example #11
0
static void
fz_draw_begin_tile(void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_pixmap *dest;
	fz_bbox bbox;

	/* area, view, xstep, ystep are in pattern space */
	/* ctm maps from pattern space to device space */

	if (dev->top == STACK_SIZE)
	{
		fz_warn("assert: too many buffers on stack");
		return;
	}

	bbox = fz_round_rect(fz_transform_rect(ctm, view));
	dest = fz_new_pixmap_with_rect(model, bbox);
	fz_clear_pixmap(dest);

	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].dest = dev->dest;
	dev->stack[dev->top].xstep = xstep;
	dev->stack[dev->top].ystep = ystep;
	dev->stack[dev->top].area = area;
	dev->stack[dev->top].ctm = ctm;
	dev->top++;

	dev->scissor = bbox;
	dev->dest = dest;
}
Example #12
0
/* Create transform to fit appearance stream to annotation Rect */
void
pdf_annot_transform(fz_context *ctx, pdf_annot *annot, fz_matrix *annot_ctm)
{
	fz_rect bbox, rect;
	fz_matrix matrix;
	float w, h, x, y;

	pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), &rect);
	pdf_xobject_bbox(ctx, annot->ap, &bbox);
	pdf_xobject_matrix(ctx, annot->ap, &matrix);

	fz_transform_rect(&bbox, &matrix);
	if (bbox.x1 == bbox.x0)
		w = 0;
	else
		w = (rect.x1 - rect.x0) / (bbox.x1 - bbox.x0);
	if (bbox.y1 == bbox.y0)
		h = 0;
	else
		h = (rect.y1 - rect.y0) / (bbox.y1 - bbox.y0);
	x = rect.x0 - bbox.x0;
	y = rect.y0 - bbox.y0;

	fz_pre_scale(fz_translate(annot_ctm, x, y), w, h);
}
Example #13
0
void
fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, const fz_rect *scissor)
{
	if (dev->error_depth)
	{
		dev->error_depth++;
		return;
	}

	fz_try(ctx)
	{
		if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
		{
			if (scissor == NULL)
			{
				fz_rect bbox = fz_unit_rect;
				fz_transform_rect(&bbox, ctm);
				push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_image_mask);
			}
			else
				push_clip_stack(ctx, dev, scissor, fz_device_container_stack_is_clip_image_mask);
		}
		if (dev->clip_image_mask)
			dev->clip_image_mask(ctx, dev, image, ctm, scissor);
	}
	fz_catch(ctx)
	{
		dev->error_depth = 1;
		strcpy(dev->errmess, fz_caught_message(ctx));
		/* Error swallowed */
	}
}
Example #14
0
static void
fz_bbox_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha)
{
	fz_rect *result = dev->user;
	fz_rect r = fz_unit_rect;
	fz_union_rect(result, fz_transform_rect(&r, ctm));
}
Example #15
0
fz_pixmap *
fz_new_pixmap_from_page_contents(fz_context *ctx, fz_page *page, const fz_matrix *ctm, fz_colorspace *cs)
{
	fz_rect rect;
	fz_irect irect;
	fz_pixmap *pix;
	fz_device *dev;

	fz_bound_page(ctx, page, &rect);
	fz_transform_rect(&rect, ctm);
	fz_round_rect(&irect, &rect);

	pix = fz_new_pixmap_with_bbox(ctx, cs, &irect);
	fz_clear_pixmap_with_value(ctx, pix, 0xFF);

	fz_try(ctx)
	{
		dev = fz_new_draw_device(ctx, pix);
		fz_run_page_contents(ctx, page, dev, ctm, NULL);
	}
	fz_always(ctx)
	{
		fz_drop_device(ctx, dev);
	}
	fz_catch(ctx)
	{
		fz_drop_pixmap(ctx, pix);
		fz_rethrow(ctx);
	}

	return pix;
}
Example #16
0
File: util.c Project: Enzime/mupdf
fz_pixmap *
fz_new_pixmap_from_annot(fz_context *ctx, fz_annot *annot, const fz_matrix *ctm, fz_colorspace *cs, int alpha)
{
	fz_rect rect;
	fz_irect irect;
	fz_pixmap *pix;
	fz_device *dev;

	fz_bound_annot(ctx, annot, &rect);
	fz_transform_rect(&rect, ctm);
	fz_round_rect(&irect, &rect);

	pix = fz_new_pixmap_with_bbox(ctx, cs, &irect, alpha);
	if (alpha)
		fz_clear_pixmap(ctx, pix);
	else
		fz_clear_pixmap_with_value(ctx, pix, 0xFF);

	fz_try(ctx)
	{
		dev = fz_new_draw_device(ctx, ctm, pix);
		fz_run_annot(ctx, annot, dev, &fz_identity, NULL);
	}
	fz_always(ctx)
	{
		fz_drop_device(ctx, dev);
	}
	fz_catch(ctx)
	{
		fz_drop_pixmap(ctx, pix);
		fz_rethrow(ctx);
	}

	return pix;
}
Example #17
0
int adjust_page_position(fz_context *ctx, pdf_document *doc, pdf_page *page, struct pos_info *pos)
{
	/* if page is rotated we must add this to the desired rotation of the page */
	pos->rotate = (pos->rotate + page->rotate) % 360;
	fz_matrix rotation_mtx; /* tranformation of the user-space due to the rotation */
	fz_rotate(&rotation_mtx, page->rotate);

	/* get the media-box (with rotation applied) */
	pdf_obj *media_box = juggler_lookup_inherited_page_item(ctx, doc, page->me, "MediaBox");
	if(!pdf_is_array(ctx, media_box) || pdf_array_len(ctx, media_box) != 4) 
		return(-1); /* the specification forces a valid media-box... */

	fz_rect media_rect;
	pdf_to_rect(ctx, media_box, &media_rect);
	fz_transform_rect(&media_rect, &rotation_mtx);

	/* get trim-box */
	pdf_obj *trim_box = juggler_lookup_inherited_page_item(ctx, doc, page->me, "TrimBox");
	if(trim_box == NULL)
		trim_box = media_box;
	if(!pdf_is_array(ctx, trim_box) || pdf_array_len(ctx, trim_box) != 4)
		return(-2);

	fz_rect trim_rect;
	pdf_to_rect(ctx, trim_box, &trim_rect);
	fz_transform_rect(&trim_rect, &rotation_mtx);
	// TODO: Take scale into account

	double available_width = pos->width;
	double available_height = pos->height;

	double page_width = trim_rect.x1 - trim_rect.x0;
	double page_height = trim_rect.y1 - trim_rect.y0;

	/* position the page in the middle of the destination area */
	pos->content_translate_x = 
		media_rect.x0 - trim_rect.x0 + (available_width - page_width) / 2;
	pos->content_translate_y = 
		media_rect.y0 - trim_rect.y0 + (available_height - page_height) / 2;

	
	/* if needed, clip the contents to the bleed-box */
	if(adjust_bleed_clipping(ctx, doc, page, pos) < 0)
		return(-2);

	return(0);
}
Example #18
0
static void
fz_bbox_begin_tile(fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm)
{
	fz_bbox_data *data = dev->user;
	fz_rect r = *area;
	fz_bbox_add_rect(dev, fz_transform_rect(&r, ctm), 0);
	data->ignore++;
}
Example #19
0
fz_irect PDFDocument::GetBoundingBox(
    pdf_page* page_struct, const fz_matrix& m) {
  assert(page_struct != nullptr);
  fz_rect bbox;
  fz_irect ibbox;
  return *fz_round_rect(&ibbox, fz_transform_rect(
      pdf_bound_page(_fz_context, _pdf_document, page_struct, &bbox), &m));
}
void
pdf_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect *rect)
{
	fz_matrix page_ctm;
	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);
	pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), rect);
	fz_transform_rect(rect, &page_ctm);
}
Example #21
0
JNIEXPORT jobjectArray JNICALL
Java_com_artifex_mupdf_MuPDFCore_getPageLinksInternal(JNIEnv * env, jobject thiz, int pageNumber)
{
	jclass       linkInfoClass;
	jmethodID    ctor;
	jobjectArray arr;
	jobject      linkInfo;
	fz_matrix    ctm;
	float        zoom;
	fz_link     *list;
	fz_link     *link;
	int          count;
	page_cache  *pc;

	linkInfoClass = (*env)->FindClass(env, "com/artifex/mupdf/LinkInfo");
	if (linkInfoClass == NULL) return NULL;
	ctor = (*env)->GetMethodID(env, linkInfoClass, "<init>", "(FFFFI)V");
	if (ctor == NULL) return NULL;

	Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(env, thiz, pageNumber);
	pc = &pages[current];
	if (pc->page == NULL || pc->number != pageNumber)
		return NULL;

	zoom = resolution / 72;
	ctm = fz_scale(zoom, zoom);

	list = fz_load_links(doc, pc->page);
	count = 0;
	for (link = list; link; link = link->next)
	{
		if (link->dest.kind == FZ_LINK_GOTO)
			count++ ;
	}

	arr = (*env)->NewObjectArray(env, count, linkInfoClass, NULL);
	if (arr == NULL) return NULL;

	count = 0;
	for (link = list; link; link = link->next)
	{
		if (link->dest.kind == FZ_LINK_GOTO)
		{
			fz_rect rect = fz_transform_rect(ctm, link->rect);

			linkInfo = (*env)->NewObject(env, linkInfoClass, ctor,
					(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
					link->dest.ld.gotor.page);
			if (linkInfo == NULL) return NULL;
			(*env)->SetObjectArrayElement(env, arr, count, linkInfo);
			(*env)->DeleteLocalRef(env, linkInfo);

			count ++;
		}
	}

	return arr;
}
Example #22
0
pdf_page *
pdf_create_page(pdf_document *doc, fz_rect mediabox, int res, int rotate)
{
	pdf_page *page = NULL;
	pdf_obj *pageobj;
	float userunit = 1;
	fz_context *ctx = doc->ctx;
	fz_matrix ctm, tmp;
	fz_rect realbox;

	page = fz_malloc_struct(ctx, pdf_page);

	fz_try(ctx)
	{
		page->resources = NULL;
		page->contents = NULL;
		page->transparency = 0;
		page->links = NULL;
		page->annots = NULL;
		page->me = pageobj = pdf_new_dict(doc, 4);

		pdf_dict_puts_drop(pageobj, "Type", pdf_new_name(doc, "Page"));

		page->mediabox.x0 = fz_min(mediabox.x0, mediabox.x1) * userunit;
		page->mediabox.y0 = fz_min(mediabox.y0, mediabox.y1) * userunit;
		page->mediabox.x1 = fz_max(mediabox.x0, mediabox.x1) * userunit;
		page->mediabox.y1 = fz_max(mediabox.y0, mediabox.y1) * userunit;
		pdf_dict_puts_drop(pageobj, "MediaBox", pdf_new_rect(doc, &page->mediabox));

		/* Snap page->rotate to 0, 90, 180 or 270 */
		if (page->rotate < 0)
			page->rotate = 360 - ((-page->rotate) % 360);
		if (page->rotate >= 360)
			page->rotate = page->rotate % 360;
		page->rotate = 90*((page->rotate + 45)/90);
		if (page->rotate > 360)
			page->rotate = 0;
		pdf_dict_puts_drop(pageobj, "Rotate", pdf_new_int(doc, page->rotate));

		fz_pre_rotate(fz_scale(&ctm, 1, -1), -page->rotate);
		realbox = page->mediabox;
		fz_transform_rect(&realbox, &ctm);
		fz_pre_scale(fz_translate(&tmp, -realbox.x0, -realbox.y0), userunit, userunit);
		fz_concat(&ctm, &ctm, &tmp);
		page->ctm = ctm;
		/* Do not create a Contents, as an empty Contents dict is not
		 * valid. See Bug 694712 */
	}
	fz_catch(ctx)
	{
		pdf_drop_obj(page->me);
		fz_free(ctx, page);
		fz_rethrow_message(ctx, "Failed to create page");
	}

	return page;
}
Example #23
0
static fz_rect *
fz_bound_mesh_type1(fz_context *ctx, fz_shade *shade, fz_rect *bbox)
{
	bbox->x0 = shade->u.f.domain[0][0];
	bbox->y0 = shade->u.f.domain[0][1];
	bbox->x1 = shade->u.f.domain[1][0];
	bbox->y1 = shade->u.f.domain[1][1];
	return fz_transform_rect(bbox, &shade->u.f.matrix);
}
Example #24
0
static void
fz_list_fill_image(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
	fz_display_node *node;
	node = fz_new_display_node(FZ_CMD_FILL_IMAGE, ctm, NULL, NULL, alpha);
	node->rect = fz_transform_rect(ctm, fz_unit_rect);
	node->item.image = fz_keep_pixmap(image);
	fz_append_display_node(user, node);
}
Example #25
0
static void
fz_list_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
	fz_display_node *node;
	node = fz_new_display_node(dev->ctx, FZ_CMD_FILL_IMAGE, ctm, NULL, NULL, alpha);
	node->rect = fz_transform_rect(ctm, fz_unit_rect);
	node->item.image = fz_keep_image(dev->ctx, image);
	fz_append_display_node(dev->user, node);
}
Example #26
0
static void
fz_draw_begin_tile(fz_context *ctx, void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_pixmap *dest;
	fz_bbox bbox;

	/* area, view, xstep, ystep are in pattern space */
	/* ctm maps from pattern space to device space */

	if (dev->top == dev->stack_max)
		fz_grow_stack(dev);

	if (dev->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_begin(ctx, dev);

	bbox = fz_round_rect(fz_transform_rect(ctm, view));
	/* We should never have a bbox that entirely covers our destination.
	 * If we do, then the check for only 1 tile being visible above has
	 * failed. */
	/* SumatraPDF: assertion intentionally disabled
	assert(bbox.x0 > dev->dest->x || bbox.x1 < dev->dest->x + dev->dest->w ||
		bbox.y0 > dev->dest->y || bbox.y1 < dev->dest->y + dev->dest->h);
	/* cf. http://bugs.ghostscript.com/show_bug.cgi?id=692418 */
	dest = fz_new_pixmap_with_limit(ctx, model, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0);
	if (dest)
	{
		dest->x = bbox.x0;
		dest->y = bbox.y0;
	}
	else
	{
		bbox.x1 = bbox.x0;
		bbox.y1 = bbox.y0;
		dest = fz_new_pixmap_with_rect(ctx, model, bbox);
	}
	/* FIXME: See note #1 */
	fz_clear_pixmap(dest);

	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].dest = dev->dest;
	dev->stack[dev->top].shape = dev->shape;
	/* FIXME: See note #1 */
	dev->stack[dev->top].blendmode = dev->blendmode | FZ_BLEND_ISOLATED;
	dev->stack[dev->top].xstep = xstep;
	dev->stack[dev->top].ystep = ystep;
	dev->stack[dev->top].area = area;
	dev->stack[dev->top].ctm = ctm;
#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "Tile begin\n");
#endif
	dev->top++;

	dev->scissor = bbox;
	dev->dest = dest;
}
Example #27
0
static void
fz_list_begin_page(fz_device *dev, const fz_rect *mediabox, const fz_matrix *ctm)
{
	fz_context *ctx = dev->ctx;
	fz_display_node *node = fz_new_display_node(ctx, FZ_CMD_BEGIN_PAGE, ctm, NULL, NULL, 0);
	node->rect = *mediabox;
	fz_transform_rect(&node->rect, ctm);
	fz_append_display_node(dev->user, node);
}
Example #28
0
static int
fz_bbox_begin_tile(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id)
{
	fz_bbox_device *bdev = (fz_bbox_device*)dev;
	fz_rect r = *area;
	fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 0);
	bdev->ignore++;
	return 0;
}
Example #29
0
static void
xps_draw_linear_gradient(fz_context *ctx, xps_document *doc, const fz_matrix *ctm, const fz_rect *area,
	struct stop *stops, int count,
	fz_xml *root, int spread)
{
	float x0, y0, x1, y1;
	int i, mi, ma;
	float dx, dy, x, y, k;
	fz_point p1, p2;
	fz_matrix inv;
	fz_rect local_area = *area;

	char *start_point_att = fz_xml_att(root, "StartPoint");
	char *end_point_att = fz_xml_att(root, "EndPoint");

	x0 = y0 = 0;
	x1 = y1 = 1;

	if (start_point_att)
		xps_parse_point(ctx, doc, start_point_att, &x0, &y0);
	if (end_point_att)
		xps_parse_point(ctx, doc, end_point_att, &x1, &y1);

	p1.x = x0; p1.y = y0; p2.x = x1; p2.y = y1;
	fz_transform_rect(&local_area, fz_invert_matrix(&inv, ctm));
	x = p2.x - p1.x; y = p2.y - p1.y;
	k = ((local_area.x0 - p1.x) * x + (local_area.y0 - p1.y) * y) / (x * x + y * y);
	mi = floorf(k); ma = ceilf(k);
	k = ((local_area.x1 - p1.x) * x + (local_area.y0 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	k = ((local_area.x0 - p1.x) * x + (local_area.y1 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	k = ((local_area.x1 - p1.x) * x + (local_area.y1 - p1.y) * y) / (x * x + y * y);
	mi = fz_mini(mi, floorf(k)); ma = fz_maxi(ma, ceilf(k));
	dx = x1 - x0; dy = y1 - y0;

	if (spread == SPREAD_REPEAT)
	{
		for (i = mi; i < ma; i++)
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + i * dx, y0 + i * dy, x1 + i * dx, y1 + i * dy);
	}
	else if (spread == SPREAD_REFLECT)
	{
		if ((mi % 2) != 0)
			mi--;
		for (i = mi; i < ma; i += 2)
		{
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + i * dx, y0 + i * dy, x1 + i * dx, y1 + i * dy);
			xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 0, x0 + (i + 2) * dx, y0 + (i + 2) * dy, x1 + i * dx, y1 + i * dy);
		}
	}
	else
	{
		xps_draw_one_linear_gradient(ctx, doc, ctm, stops, count, 1, x0, y0, x1, y1);
	}
}
Example #30
0
static void
fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
	fz_draw_device *dev = devp->user;
	fz_pixmap *dest = NULL;
	fz_pixmap *shape;
	fz_bbox bbox;
	fz_context *ctx = dev->ctx;
	fz_draw_state *state = &dev->stack[dev->top];
	fz_colorspace *model = state->dest->colorspace;

	/* area, view, xstep, ystep are in pattern space */
	/* ctm maps from pattern space to device space */

	if (state->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_begin(dev);

	state = push_stack(dev);
	bbox = fz_bbox_covering_rect(fz_transform_rect(ctm, view));
	/* We should never have a bbox that entirely covers our destination.
	 * If we do, then the check for only 1 tile being visible above has
	 * failed. Actually, this *can* fail due to the round_rect, at extreme
	 * resolutions, so disable this assert.
	 * assert(bbox.x0 > state->dest->x || bbox.x1 < state->dest->x + state->dest->w ||
	 *	bbox.y0 > state->dest->y || bbox.y1 < state->dest->y + state->dest->h);
	 */
	dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
	fz_clear_pixmap(ctx, dest);
	shape = state[0].shape;
	if (shape)
	{
		fz_var(shape);
		fz_try(ctx)
		{
			shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
			fz_clear_pixmap(ctx, shape);
		}
		fz_catch(ctx)
		{
			fz_drop_pixmap(ctx, dest);
			fz_rethrow(ctx);
		}
	}
	state[1].blendmode |= FZ_BLEND_ISOLATED;
	state[1].xstep = xstep;
	state[1].ystep = ystep;
	state[1].area = area;
	state[1].ctm = ctm;
#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top-1, "Tile begin\n");
#endif

	state[1].scissor = bbox;
	state[1].dest = dest;
	state[1].shape = shape;
}