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); }
void pdfapp_inverthit(pdfapp_t *app) { fz_bbox hitbox, bbox; fz_matrix ctm; int i; if (app->hit < 0) return; hitbox = fz_empty_bbox; ctm = pdfapp_viewctm(app); for (i = app->hit; i < app->hit + app->hitlen; i++) { bbox = bboxcharat(app->page_text, i); if (fz_is_empty_rect(bbox)) { if (!fz_is_empty_rect(hitbox)) pdfapp_invert(app, fz_transform_bbox(ctm, hitbox)); hitbox = fz_empty_bbox; } else { hitbox = fz_union_bbox(hitbox, bbox); } } if (!fz_is_empty_rect(hitbox)) pdfapp_invert(app, fz_transform_bbox(ctm, hitbox)); }
static void fz_bbox_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha) { fz_bbox *result = dev->user; fz_bbox bbox = fz_round_rect(fz_bound_shade(shade, ctm)); *result = fz_union_bbox(*result, bbox); }
static void fz_bbox_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_bbox *result = dev->user; fz_bbox bbox = fz_round_rect(fz_bound_path(path, NULL, ctm)); *result = fz_union_bbox(*result, bbox); }
static void fz_bbox_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_bbox *result = dev->user; fz_bbox bbox = fz_round_rect(fz_bound_text(dev->ctx, text, ctm)); *result = fz_union_bbox(*result, bbox); }
static void fz_bbox_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_bbox *result = dev->user; fz_bbox bbox = fz_round_rect(fz_bound_path(path, stroke, ctm)); *result = fz_union_bbox(*result, bbox); }
static void fz_bbox_add_rect(fz_device *dev, fz_rect rect, int clip) { fz_bbox_data *data = dev->user; if (0 < data->top && data->top <= STACK_SIZE) rect = fz_intersect_rect(rect, data->stack[data->top-1]); if (!clip && data->top <= STACK_SIZE && !data->ignore) *data->result = fz_union_bbox(*data->result, fz_bbox_covering_rect(rect)); if (clip && ++data->top <= STACK_SIZE) data->stack[data->top-1] = rect; }
std::shared_ptr<std::vector<std::shared_ptr<RectFloat>>> MuPDFDoc::SearchText(const char* searchText) { fz_text_sheet *sheet = nullptr; fz_text_page *text = nullptr; fz_device *dev = nullptr; PageCache *pageCache = &m_pages[m_currentPage]; fz_var(sheet); fz_var(text); fz_var(dev); std::shared_ptr<std::vector<std::shared_ptr<RectFloat>>> hints(new std::vector<std::shared_ptr<RectFloat>>()); fz_try(m_context) { int hitCount = 0; fz_matrix ctm = CalcConvertMatrix(); fz_rect mbrect = fz_transform_rect(ctm, pageCache->mediaBox); sheet = fz_new_text_sheet(m_context); text = fz_new_text_page(m_context, mbrect); dev = fz_new_text_device(m_context, sheet, text); fz_run_page(m_document, pageCache->page, dev, ctm, nullptr); fz_free_device(dev); dev = nullptr; int len = TextLen(text); for (int pos = 0; pos < len; pos++) { fz_bbox rr = fz_empty_bbox; int n = Match(text, searchText, pos); for (int i = 0; i < n; i++) rr = fz_union_bbox(rr, BBoxCharAt(text, pos + i)); if (!fz_is_empty_bbox(rr) && hitCount < MAX_SEARCH_HITS) { hints->push_back(std::shared_ptr<RectFloat>(new RectFloat(rr.x0, rr.y0, rr.x1, rr.y1))); if (++hitCount >= MAX_SEARCH_HITS) break; } } } fz_always(m_context) { fz_free_text_page(m_context, text); fz_free_text_sheet(m_context, sheet); fz_free_device(dev); } fz_catch(m_context) { return std::shared_ptr<std::vector<std::shared_ptr<RectFloat>>>(nullptr); } return hints; }
int fz_highlight_selection(fz_context *ctx, fz_text_page *page, fz_bbox rect, fz_bbox *hit_bbox, int hit_max) { fz_bbox linebox, charbox; fz_text_block *block; fz_text_line *line; fz_text_span *span; int i, hit_count; int x0 = rect.x0; int x1 = rect.x1; int y0 = rect.y0; int y1 = rect.y1; hit_count = 0; for (block = page->blocks; block < page->blocks + page->len; block++) { for (line = block->lines; line < block->lines + block->len; line++) { linebox = fz_empty_bbox; for (span = line->spans; span < line->spans + line->len; span++) { for (i = 0; i < span->len; i++) { charbox = fz_bbox_covering_rect(span->text[i].bbox); if (charbox.x1 >= x0 && charbox.x0 <= x1 && charbox.y1 >= y0 && charbox.y0 <= y1) { if (charbox.y0 != linebox.y0 || fz_absi(charbox.x0 - linebox.x1) > 5) { if (!fz_is_empty_bbox(linebox) && hit_count < hit_max) hit_bbox[hit_count++] = linebox; linebox = charbox; } else { linebox = fz_union_bbox(linebox, charbox); } } } } if (!fz_is_empty_bbox(linebox) && hit_count < hit_max) hit_bbox[hit_count++] = linebox; } } return hit_count; }
int fz_search_text_page(fz_context *ctx, fz_text_page *text, char *needle, fz_bbox *hit_bbox, int hit_max) { int pos, len, i, n, hit_count; if (strlen(needle) == 0) return 0; hit_count = 0; len = textlen(text); for (pos = 0; pos < len; pos++) { n = match(text, needle, pos); if (n) { fz_bbox linebox = fz_empty_bbox; for (i = 0; i < n; i++) { fz_bbox charbox = bboxat(text, pos + i); if (!fz_is_empty_bbox(charbox)) { if (charbox.y0 != linebox.y0 || fz_absi(charbox.x0 - linebox.x1) > 5) { if (!fz_is_empty_bbox(linebox) && hit_count < hit_max) hit_bbox[hit_count++] = linebox; linebox = charbox; } else { linebox = fz_union_bbox(linebox, charbox); } } } if (!fz_is_empty_bbox(linebox) && hit_count < hit_max) hit_bbox[hit_count++] = linebox; } } return hit_count; }
JNIEXPORT jobjectArray JNICALL Java_com_artifex_mupdf_MuPDFCore_searchPage(JNIEnv * env, jobject thiz, jstring jtext) { jclass rectClass; jmethodID ctor; jobjectArray arr; jobject rect; fz_text_sheet *sheet = NULL; fz_text_page *text = NULL; fz_device *dev = NULL; float zoom; fz_matrix ctm; int pos; int len; int i, n; int hit_count = 0; const char *str; page_cache *pc = &pages[current]; rectClass = (*env)->FindClass(env, "android/graphics/RectF"); if (rectClass == NULL) return NULL; ctor = (*env)->GetMethodID(env, rectClass, "<init>", "(FFFF)V"); if (ctor == NULL) return NULL; str = (*env)->GetStringUTFChars(env, jtext, NULL); if (str == NULL) return NULL; fz_var(sheet); fz_var(text); fz_var(dev); fz_try(ctx) { fz_rect rect; if (hit_bbox == NULL) hit_bbox = fz_malloc_array(ctx, MAX_SEARCH_HITS, sizeof(*hit_bbox)); zoom = resolution / 72; ctm = fz_scale(zoom, zoom); rect = fz_transform_rect(ctm, pc->media_box); sheet = fz_new_text_sheet(ctx); text = fz_new_text_page(ctx, rect); dev = fz_new_text_device(ctx, sheet, text); fz_run_page(doc, pc->page, dev, ctm, NULL); fz_free_device(dev); dev = NULL; len = textlen(text); for (pos = 0; pos < len; pos++) { fz_bbox rr = fz_empty_bbox; n = match(text, str, pos); for (i = 0; i < n; i++) rr = fz_union_bbox(rr, bboxcharat(text, pos + i)); if (!fz_is_empty_bbox(rr) && hit_count < MAX_SEARCH_HITS) hit_bbox[hit_count++] = rr; } } fz_always(ctx) { fz_free_text_page(ctx, text); fz_free_text_sheet(ctx, sheet); fz_free_device(dev); } fz_catch(ctx) { jclass cls; (*env)->ReleaseStringUTFChars(env, jtext, str); cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); if (cls != NULL) (*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage"); (*env)->DeleteLocalRef(env, cls); return NULL; } (*env)->ReleaseStringUTFChars(env, jtext, str); arr = (*env)->NewObjectArray(env, hit_count, rectClass, NULL); if (arr == NULL) return NULL; for (i = 0; i < hit_count; i++) { rect = (*env)->NewObject(env, rectClass, ctor, (float) (hit_bbox[i].x0), (float) (hit_bbox[i].y0), (float) (hit_bbox[i].x1), (float) (hit_bbox[i].y1)); if (rect == NULL) return NULL; (*env)->SetObjectArrayElement(env, arr, i, rect); (*env)->DeleteLocalRef(env, rect); } return arr; }