void * renderer(void *data) { int pagenumber = ((struct data *) data)->pagenumber; fz_context *ctx = ((struct data *) data)->ctx; fz_display_list *list = ((struct data *) data)->list; fz_bbox bbox = ((struct data *) data)->bbox; fz_pixmap *pix = ((struct data *) data)->pix; fprintf(stderr, "thread at page %d loading!\n", pagenumber); // The context pointer is pointing to the main thread's // context, so here we create a new context based on it for // use in this thread. ctx = fz_clone_context(ctx); // Next we run the display list through the draw device which // will render the request area of the page to the pixmap. fprintf(stderr, "thread at page %d rendering!\n", pagenumber); fz_device *dev = fz_new_draw_device(ctx, pix); fz_run_display_list(list, dev, fz_identity, bbox, NULL); fz_free_device(dev); // This threads context is freed. fz_free_context(ctx); fprintf(stderr, "thread at page %d done!\n", pagenumber); return data; }
/* Render thread entry */ static void *render_thread(void *t) { SDL_Event my_event; struct least_thread *self = t; my_event.type = LEAST_PAGE_COMPLETE; my_event.user.data1 = t; self->context = fz_clone_context(self->context); if (!self->context) { fprintf(stderr, "In render thread %d: fz_clone_context returned NULL\n", self->id); abort(); } printf("Render thread %d up and running.\n", self->id); pthread_mutex_lock(&self->mutex); /* Wait for first command */ pthread_cond_wait(&self->cond, &self->mutex); while (self->keep_running) { printf("Thread %d: Rendering page %d\n", self->id, self->pagenum); /* Render a page */ self->pixmap = page_to_pixmap(self->context, doc, self->pagenum); if (!self->pixmap) { fprintf(stderr, "In render thread %d: " "page_to_pixmap returned NULL\n", self->id); abort(); } /* Push completed page to event queue */ SDL_PushEvent(&my_event); pthread_cond_wait(&self->cond, &self->mutex); } pthread_mutex_unlock(&self->mutex); /* Cleanup */ fz_free_context(self->context); return NULL; }
/** * Perform MuPDF native operations on a given MuOfficeLib * instance. * * The function is called with a fz_context value that can * be safely used (i.e. the context is cloned/dropped * appropriately around the call). The function should signal * errors by fz_throw-ing. * * @param mu the MuOfficeLib instance. * @param fn the function to call to run the operations. * @param arg Opaque data pointer. * * @return error indication - 0 for success */ MuError MuOfficeLib_run(MuOfficeLib *mu, void (*fn)(fz_context *ctx, void *arg), void *arg) { fz_context *ctx; MuError err = MuError_OK; if (mu == NULL) return MuError_BadNull; if (fn == NULL) return err; ctx = fz_clone_context(mu->ctx); if (ctx == NULL) return MuError_OOM; fz_try(ctx) fn(ctx, arg); fz_catch(ctx) err = MuError_Generic; fz_drop_context(ctx); return err; }
Object ^ MuPdf::Sharp::Fitz::Context::Clone() { return gcnew Context(fz_clone_context(m_pCtx)); }
HRESULT MuPDFDoc::Renderer(Data *data, int part, int numParts) { if (m_cts->abort == 1) return S_OK; int pagenumber = data->pagenumber; fz_context *ctx = data->ctx; fz_display_list *list = data->list; fz_display_list *annotList = data->annotList; fz_rect rect = data->rect; fz_pixmap *pix = data->pix; fz_device *dev = nullptr; int width = data->width; int height = data->height / numParts; // The context pointer is pointing to the main thread's // context, so here we create a new context based on it for // use in this thread. ctx = fz_clone_context(ctx); fz_try(ctx) { if (part == 1 && numParts == 2) { rect.y1 = rect.y1/2; } if (part == 2 && numParts == 2) { rect.y0 = rect.y1/2; } fz_matrix ctm = CalcConvertMatrix(); fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, rect)); /* 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, rect)); dev = fz_new_draw_device(ctx, pix); if (list) fz_run_display_list(list, dev, ctm, bbox, *&m_cts); if (m_cts->abort == 1) break; if (annotList) fz_run_display_list(annotList, dev, ctm, bbox, *&m_cts); } fz_always(ctx) { if (dev) { fz_free_device(dev); dev = nullptr; } if (pix) { fz_drop_pixmap(m_context, pix); } } fz_catch(ctx) { return E_FAIL; } fz_free_context(ctx); return S_OK; }