Mercurial > hgrepos > Python2 > PyMuPDF
view mupdf-source/thirdparty/tesseract/src/textord/drawtord.cpp @ 38:8934ac156ef5
Allow to build with the PyPI package "clang" instead of "libclang".
1. It seems to be maintained.
2. In the FreeBSD base system there is no pre-built libclang.so. If you
need this library you have to install llvm from ports additionally.
2. On FreeBSD there is no pre-built wheel "libclang" with a packaged
libclang.so.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Tue, 23 Sep 2025 10:27:15 +0200 |
| parents | b50eed0cc0ef |
| children |
line wrap: on
line source
/********************************************************************** * File: drawtord.cpp (Formerly drawto.c) * Description: Draw things to do with textord. * Author: Ray Smith * * (C) Copyright 1992, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/ #ifdef HAVE_CONFIG_H # include "config_auto.h" #endif #include "drawtord.h" #include "pithsync.h" #include "topitch.h" namespace tesseract { #define TO_WIN_XPOS 0 // default window pos #define TO_WIN_YPOS 0 #define TO_WIN_NAME "Textord" // title of window BOOL_VAR(textord_show_fixed_cuts, false, "Draw fixed pitch cell boundaries"); ScrollView *to_win = nullptr; #ifndef GRAPHICS_DISABLED /********************************************************************** * create_to_win * * Create the to window used to show the fit. **********************************************************************/ ScrollView *create_to_win(ICOORD page_tr) { if (to_win != nullptr) { return to_win; } to_win = new ScrollView(TO_WIN_NAME, TO_WIN_XPOS, TO_WIN_YPOS, page_tr.x() + 1, page_tr.y() + 1, page_tr.x(), page_tr.y(), true); return to_win; } void close_to_win() { // to_win is leaked, but this enables the user to view the contents. if (to_win != nullptr) { to_win->Update(); } } /********************************************************************** * plot_box_list * * Draw a list of blobs. **********************************************************************/ void plot_box_list( // make gradients win ScrollView *win, // window to draw in BLOBNBOX_LIST *list, // blob list ScrollView::Color body_colour // colour to draw ) { BLOBNBOX_IT it = list; // iterator win->Pen(body_colour); win->Brush(ScrollView::NONE); for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { it.data()->bounding_box().plot(win); } } /********************************************************************** * plot_to_row * * Draw the blobs of a row in a given colour and draw the line fit. **********************************************************************/ void plot_to_row( // draw a row TO_ROW *row, // row to draw ScrollView::Color colour, // colour to draw in FCOORD rotation // rotation for line ) { FCOORD plot_pt; // point to plot // blobs BLOBNBOX_IT it = row->blob_list(); float left, right; // end of row if (it.empty()) { tprintf("No blobs in row at %g\n", row->parallel_c()); return; } left = it.data()->bounding_box().left(); it.move_to_last(); right = it.data()->bounding_box().right(); plot_blob_list(to_win, row->blob_list(), colour, ScrollView::BROWN); to_win->Pen(colour); plot_pt = FCOORD(left, row->line_m() * left + row->line_c()); plot_pt.rotate(rotation); to_win->SetCursor(plot_pt.x(), plot_pt.y()); plot_pt = FCOORD(right, row->line_m() * right + row->line_c()); plot_pt.rotate(rotation); to_win->DrawTo(plot_pt.x(), plot_pt.y()); } /********************************************************************** * plot_parallel_row * * Draw the blobs of a row in a given colour and draw the line fit. **********************************************************************/ void plot_parallel_row( // draw a row TO_ROW *row, // row to draw float gradient, // gradients of lines int32_t left, // edge of block ScrollView::Color colour, // colour to draw in FCOORD rotation // rotation for line ) { FCOORD plot_pt; // point to plot // blobs BLOBNBOX_IT it = row->blob_list(); auto fleft = static_cast<float>(left); // floating version float right; // end of row // left=it.data()->bounding_box().left(); it.move_to_last(); right = it.data()->bounding_box().right(); plot_blob_list(to_win, row->blob_list(), colour, ScrollView::BROWN); to_win->Pen(colour); plot_pt = FCOORD(fleft, gradient * left + row->max_y()); plot_pt.rotate(rotation); to_win->SetCursor(plot_pt.x(), plot_pt.y()); plot_pt = FCOORD(fleft, gradient * left + row->min_y()); plot_pt.rotate(rotation); to_win->DrawTo(plot_pt.x(), plot_pt.y()); plot_pt = FCOORD(fleft, gradient * left + row->parallel_c()); plot_pt.rotate(rotation); to_win->SetCursor(plot_pt.x(), plot_pt.y()); plot_pt = FCOORD(right, gradient * right + row->parallel_c()); plot_pt.rotate(rotation); to_win->DrawTo(plot_pt.x(), plot_pt.y()); } /********************************************************************** * draw_occupation * * Draw the row occupation with points above the threshold in white * and points below the threshold in black. **********************************************************************/ void draw_occupation( // draw projection int32_t xleft, // edge of block int32_t ybottom, // bottom of block int32_t min_y, // coordinate limits int32_t max_y, int32_t occupation[], // projection counts int32_t thresholds[] // for drop out ) { int32_t line_index; // pixel coord ScrollView::Color colour; // of histogram auto fleft = static_cast<float>(xleft); // float version colour = ScrollView::WHITE; to_win->Pen(colour); to_win->SetCursor(fleft, static_cast<float>(ybottom)); for (line_index = min_y; line_index <= max_y; line_index++) { if (occupation[line_index - min_y] < thresholds[line_index - min_y]) { if (colour != ScrollView::BLUE) { colour = ScrollView::BLUE; to_win->Pen(colour); } } else { if (colour != ScrollView::WHITE) { colour = ScrollView::WHITE; to_win->Pen(colour); } } to_win->DrawTo(fleft + occupation[line_index - min_y] / 10.0, static_cast<float>(line_index)); } colour = ScrollView::STEEL_BLUE; to_win->Pen(colour); to_win->SetCursor(fleft, static_cast<float>(ybottom)); for (line_index = min_y; line_index <= max_y; line_index++) { to_win->DrawTo(fleft + thresholds[line_index - min_y] / 10.0, static_cast<float>(line_index)); } } /********************************************************************** * draw_meanlines * * Draw the meanlines of the given block in the given colour. **********************************************************************/ void draw_meanlines( // draw a block TO_BLOCK *block, // block to draw float gradient, // gradients of lines int32_t left, // edge of block ScrollView::Color colour, // colour to draw in FCOORD rotation // rotation for line ) { FCOORD plot_pt; // point to plot // rows TO_ROW_IT row_it = block->get_rows(); TO_ROW *row; // current row BLOBNBOX_IT blob_it; // blobs float right; // end of row to_win->Pen(colour); for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) { row = row_it.data(); blob_it.set_to_list(row->blob_list()); blob_it.move_to_last(); right = blob_it.data()->bounding_box().right(); plot_pt = FCOORD(static_cast<float>(left), gradient * left + row->parallel_c() + row->xheight); plot_pt.rotate(rotation); to_win->SetCursor(plot_pt.x(), plot_pt.y()); plot_pt = FCOORD(right, gradient * right + row->parallel_c() + row->xheight); plot_pt.rotate(rotation); to_win->DrawTo(plot_pt.x(), plot_pt.y()); } } /********************************************************************** * plot_word_decisions * * Plot a row with words in different colours and fuzzy spaces * highlighted. **********************************************************************/ void plot_word_decisions( // draw words ScrollView *win, // window tro draw in int16_t pitch, // of block TO_ROW *row // row to draw ) { ScrollView::Color colour = ScrollView::MAGENTA; // current colour ScrollView::Color rect_colour; // fuzzy colour int32_t prev_x; // end of prev blob int16_t blob_count; // blobs in word BLOBNBOX *blob; // current blob TBOX blob_box; // bounding box // iterator BLOBNBOX_IT blob_it = row->blob_list(); BLOBNBOX_IT start_it = blob_it; // word start rect_colour = ScrollView::BLACK; prev_x = -INT16_MAX; blob_count = 0; for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) { blob = blob_it.data(); blob_box = blob->bounding_box(); if (!blob->joined_to_prev() && blob_box.left() - prev_x > row->max_nonspace) { if ((blob_box.left() - prev_x >= row->min_space || blob_box.left() - prev_x > row->space_threshold) && blob_count > 0) { if (pitch > 0 && textord_show_fixed_cuts) { plot_fp_cells(win, colour, &start_it, pitch, blob_count, &row->projection, row->projection_left, row->projection_right, row->xheight * textord_projection_scale); } blob_count = 0; start_it = blob_it; } if (colour == ScrollView::MAGENTA) { colour = ScrollView::RED; } else { colour = static_cast<ScrollView::Color>(colour + 1); } if (blob_box.left() - prev_x < row->min_space) { if (blob_box.left() - prev_x > row->space_threshold) { rect_colour = ScrollView::GOLDENROD; } else { rect_colour = ScrollView::CORAL; } // fill_color_index(win, rect_colour); win->Brush(rect_colour); win->Rectangle(prev_x, blob_box.bottom(), blob_box.left(), blob_box.top()); } } if (!blob->joined_to_prev()) { prev_x = blob_box.right(); } if (blob->cblob() != nullptr) { blob->cblob()->plot(win, colour, colour); } if (!blob->joined_to_prev() && blob->cblob() != nullptr) { blob_count++; } } if (pitch > 0 && textord_show_fixed_cuts && blob_count > 0) { plot_fp_cells(win, colour, &start_it, pitch, blob_count, &row->projection, row->projection_left, row->projection_right, row->xheight * textord_projection_scale); } } /********************************************************************** * plot_fp_cells * * Make a list of fixed pitch cuts and draw them. **********************************************************************/ void plot_fp_cells( // draw words ScrollView *win, // window tro draw in ScrollView::Color colour, // colour of lines BLOBNBOX_IT *blob_it, // blobs int16_t pitch, // of block int16_t blob_count, // no of real blobs STATS *projection, // vertical int16_t projection_left, // edges //scale factor int16_t projection_right, float projection_scale) { int16_t occupation; // occupied cells TBOX word_box; // bounding box FPSEGPT_LIST seg_list; // list of cuts FPSEGPT_IT seg_it; FPSEGPT *segpt; // current point if (pitsync_linear_version) { check_pitch_sync2(blob_it, blob_count, pitch, 2, projection, projection_left, projection_right, projection_scale, occupation, &seg_list, 0, 0); } else { check_pitch_sync(blob_it, blob_count, pitch, 2, projection, &seg_list); } word_box = blob_it->data()->bounding_box(); for (; blob_count > 0; blob_count--) { word_box += box_next(blob_it); } seg_it.set_to_list(&seg_list); for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) { segpt = seg_it.data(); if (segpt->faked) { colour = ScrollView::WHITE; win->Pen(colour); } else { win->Pen(colour); } win->Line(segpt->position(), word_box.bottom(), segpt->position(), word_box.top()); } } /********************************************************************** * plot_fp_cells2 * * Make a list of fixed pitch cuts and draw them. **********************************************************************/ void plot_fp_cells2( // draw words ScrollView *win, // window tro draw in ScrollView::Color colour, // colour of lines TO_ROW *row, // for location FPSEGPT_LIST *seg_list // segments to plot ) { TBOX word_box; // bounding box FPSEGPT_IT seg_it = seg_list; // blobs in row BLOBNBOX_IT blob_it = row->blob_list(); FPSEGPT *segpt; // current point word_box = blob_it.data()->bounding_box(); for (blob_it.mark_cycle_pt(); !blob_it.cycled_list();) { word_box += box_next(&blob_it); } for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) { segpt = seg_it.data(); if (segpt->faked) { colour = ScrollView::WHITE; win->Pen(colour); } else { win->Pen(colour); } win->Line(segpt->position(), word_box.bottom(), segpt->position(), word_box.top()); } } /********************************************************************** * plot_row_cells * * Make a list of fixed pitch cuts and draw them. **********************************************************************/ void plot_row_cells( // draw words ScrollView *win, // window tro draw in ScrollView::Color colour, // colour of lines TO_ROW *row, // for location float xshift, // amount of shift ICOORDELT_LIST *cells // cells to draw ) { TBOX word_box; // bounding box ICOORDELT_IT cell_it = cells; // blobs in row BLOBNBOX_IT blob_it = row->blob_list(); ICOORDELT *cell; // current cell word_box = blob_it.data()->bounding_box(); for (blob_it.mark_cycle_pt(); !blob_it.cycled_list();) { word_box += box_next(&blob_it); } win->Pen(colour); for (cell_it.mark_cycle_pt(); !cell_it.cycled_list(); cell_it.forward()) { cell = cell_it.data(); win->Line(cell->x() + xshift, word_box.bottom(), cell->x() + xshift, word_box.top()); } } #endif // !GRAPHICS_DISABLED } // namespace tesseract
