void pdfapp_invert(pdfapp_t *app, const fz_rect *rect) { fz_irect b; fz_invert_pixmap_rect(app->ctx, app->image, fz_round_rect(&b, rect)); }
HRESULT MuPDFDoc::UpdatePage(int pageNumber, unsigned char *bitmap, int x, int y, int width, int height, bool invert) { int index = FindPageInCache(pageNumber); if (index < 0) { //TODO: get rid of this side effect!!! HRESULT result = GotoPage(pageNumber); if (FAILED(result)) { return result; } return DrawPage(bitmap, x, y, width, height, invert); } fz_device *dev = nullptr; fz_pixmap *pixmap = nullptr; fz_var(dev); fz_var(pixmap); PageCache *pageCache = &m_pages[m_currentPage]; fz_try(m_context) { fz_interactive *idoc = fz_interact(m_document); // Call fz_update_page now to ensure future calls yield the // changes from the current state if (idoc) fz_update_page(idoc, pageCache->page); if (!pageCache->pageList) { /* Render to list */ pageCache->pageList = fz_new_display_list(m_context); dev = fz_new_list_device(m_context, pageCache->pageList); fz_run_page_contents(m_document, pageCache->page, dev, fz_identity, nullptr); } if (!pageCache->annotList) { if (dev) { fz_free_device(dev); dev = nullptr; } pageCache->annotList = fz_new_display_list(m_context); dev = fz_new_list_device(m_context, pageCache->annotList); for (fz_annot *annot = fz_first_annot(m_document, pageCache->page); annot; annot = fz_next_annot(m_document, annot)) fz_run_annot(m_document, pageCache->page, annot, dev, fz_identity, nullptr); } fz_bbox rect; rect.x0 = x; rect.y0 = y; rect.x1 = x + width; rect.y1 = y + height; pixmap = fz_new_pixmap_with_bbox_and_data(m_context, fz_device_bgr, rect, bitmap); // fz_matrix ctm = CalcConvertMatrix(); fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, pageCache->mediaBox)); /* Now, adjust ctm so that it would give the correct page width * heights. */ float xscale = (float)width/(float)(bbox.x1-bbox.x0); float yscale = (float)height/(float)(bbox.y1-bbox.y0); ctm = fz_concat(ctm, fz_scale(xscale, yscale)); bbox = fz_round_rect(fz_transform_rect(ctm, pageCache->mediaBox)); if (dev) { fz_free_device(dev); dev = nullptr; } fz_annot *annot; while (idoc && (annot = fz_poll_changed_annot(idoc, pageCache->page))) { fz_bbox abox = fz_round_rect(fz_transform_rect(ctm, fz_bound_annot(m_document, annot))); abox = fz_intersect_bbox(abox, rect); if (!fz_is_empty_bbox(abox)) { fz_clear_pixmap_rect_with_value(m_context, pixmap, 0xff, abox); dev = fz_new_draw_device_with_bbox(m_context, pixmap, abox); if (pageCache->pageList) fz_run_display_list(pageCache->pageList, dev, ctm, abox, nullptr); if (pageCache->annotList) fz_run_display_list(pageCache->annotList, dev, ctm, abox, nullptr); fz_free_device(dev); dev = nullptr; if (invert) fz_invert_pixmap_rect(pixmap, abox); } } } fz_always(m_context) { if (dev) { fz_free_device(dev); dev = nullptr; } if (pixmap) { fz_drop_pixmap(m_context, pixmap); } } fz_catch(m_context) { return E_FAIL; } return S_OK; }