📄 topitch.cpp
字号:
block->max_nonspace = (INT32) ceil (block->xheight * textord_words_default_nonspace); block->fixed_pitch = 0.0f; block->space_size = (float) block->min_space; block->kern_size = (float) block->max_nonspace; block->pr_nonsp = block->xheight * words_default_prop_nonspace; block->pr_space = block->pr_nonsp * textord_spacesize_ratioprop; if (!block->get_rows ()->empty ()) { ASSERT_HOST (block->xheight > 0); if (textord_repeat_extraction) find_repeated_chars(block, textord_show_initial_words &&testing_on);#ifndef GRAPHICS_DISABLED if (textord_show_initial_words && testing_on) overlap_picture_ops(TRUE);#endif compute_rows_pitch(block, block_index, textord_debug_pitch_test &&testing_on); }}/********************************************************************** * compute_rows_pitch * * Decide whether each row is fixed pitch individually. **********************************************************************/BOOL8 compute_rows_pitch( //find line stats TO_BLOCK *block, //block to do INT32 block_index, //block number BOOL8 testing_on //correct orientation ) { INT32 maxwidth; //of spaces TO_ROW *row; //current row INT32 row_index; //row number. float lower, upper; //cluster thresholds TO_ROW_IT row_it = block->get_rows (); row_index = 1; for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); ASSERT_HOST (row->xheight > 0); row->compute_vertical_projection (); maxwidth = (INT32) ceil (row->xheight * textord_words_maxspace); if (row_pitch_stats (row, maxwidth, testing_on) && find_row_pitch (row, maxwidth, textord_dotmatrix_gap + 1, block, block_index, row_index, testing_on)) { if (row->fixed_pitch == 0) { lower = row->pr_nonsp; upper = row->pr_space; row->space_size = upper; row->kern_size = lower; } } else { row->fixed_pitch = 0.0f; //insufficient data row->pitch_decision = PITCH_DUNNO; } row_index++; } return FALSE;}/********************************************************************** * try_doc_fixed * * Attempt to call the entire document fixed pitch. **********************************************************************/BOOL8 try_doc_fixed( //determine pitch ICOORD page_tr, //top right TO_BLOCK_LIST *port_blocks, //input list float gradient //page skew ) { INT16 master_x; //uniform shifts INT16 pitch; //median pitch. int x; //profile coord int prop_blocks; //correct counts int fixed_blocks; int total_row_count; //total in page //iterator TO_BLOCK_IT block_it = port_blocks; TO_BLOCK *block; //current block; TO_ROW_IT row_it; //row iterator TO_ROW *row; //current row INT16 projection_left; //edges INT16 projection_right; INT16 row_left; //edges of row INT16 row_right; ICOORDELT_LIST *master_cells; //cells for page float master_y; //uniform shifts float shift_factor; //page skew correction float row_shift; //shift for row float final_pitch; //output pitch float row_y; //baseline STATS projection; //entire page STATS pitches (0, MAX_ALLOWED_PITCH); //for median float sp_sd; //space sd INT16 mid_cuts; //no of cheap cuts float pitch_sd; //sync rating if (block_it.empty () // || block_it.data()==block_it.data_relative(1) || !textord_blockndoc_fixed) return FALSE; shift_factor = gradient / (gradient * gradient + 1); row_it.set_to_list (block_it.data ()->get_rows ()); master_x = row_it.data ()->projection_left; master_y = row_it.data ()->baseline.y (master_x); projection_left = MAX_INT16; projection_right = -MAX_INT16; prop_blocks = 0; fixed_blocks = 0; total_row_count = 0; for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); if (block->block->text_region () != NULL) { if (block->block->text_region ()->is_prop ()) prop_blocks++; else fixed_blocks++; } row_it.set_to_list (block->get_rows ()); for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); total_row_count++; if (row->fixed_pitch > 0) pitches.add ((INT32) (row->fixed_pitch), 1); //find median row_y = row->baseline.y (master_x); row_left = (INT16) (row->projection_left - shift_factor * (master_y - row_y)); row_right = (INT16) (row->projection_right - shift_factor * (master_y - row_y)); if (row_left < projection_left) projection_left = row_left; if (row_right > projection_right) projection_right = row_right; } } if (pitches.get_total () == 0) return FALSE; projection.set_range (projection_left, projection_right); for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); row_it.set_to_list (block->get_rows ()); for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); row_y = row->baseline.y (master_x); row_left = (INT16) (row->projection_left - shift_factor * (master_y - row_y)); for (x = row->projection_left; x < row->projection_right; x++, row_left++) { projection.add (row_left, row->projection.pile_count (x)); } } } row_it.set_to_list (block_it.data ()->get_rows ()); row = row_it.data ();#ifndef GRAPHICS_DISABLED if (textord_show_page_cuts && to_win != NO_WINDOW) projection.plot (to_win, projection_left, row->intercept (), 1.0f, -1.0f, CORAL);#endif final_pitch = pitches.ile (0.5); pitch = (INT16) final_pitch; pitch_sd = tune_row_pitch (row, &projection, projection_left, projection_right, pitch * 0.75, final_pitch, sp_sd, mid_cuts, &row->char_cells, FALSE); if (textord_debug_pitch_metric) tprintf ("try_doc:props=%d:fixed=%d:pitch=%d:final_pitch=%g:pitch_sd=%g:sp_sd=%g:sd/trc=%g:sd/p=%g:sd/trc/p=%g\n", prop_blocks, fixed_blocks, pitch, final_pitch, pitch_sd, sp_sd, pitch_sd / total_row_count, pitch_sd / pitch, pitch_sd / total_row_count / pitch);#ifndef GRAPHICS_DISABLED if (textord_show_page_cuts && to_win != NO_WINDOW) { master_cells = &row->char_cells; for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); row_it.set_to_list (block->get_rows ()); for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); row_y = row->baseline.y (master_x); row_shift = shift_factor * (master_y - row_y); plot_row_cells(to_win, GOLDENROD, row, row_shift, master_cells); } } }#endif row->char_cells.clear (); return FALSE;}/********************************************************************** * try_block_fixed * * Try to call the entire block fixed. **********************************************************************/BOOL8 try_block_fixed( //find line stats TO_BLOCK *block, //block to do INT32 block_index //block number ) { return FALSE;}/********************************************************************** * try_rows_fixed * * Decide whether each row is fixed pitch individually. **********************************************************************/BOOL8 try_rows_fixed( //find line stats TO_BLOCK *block, //block to do INT32 block_index, //block number BOOL8 testing_on //correct orientation ) { INT32 maxwidth; //of spaces TO_ROW *row; //current row INT32 row_index; //row number. INT32 def_fixed = 0; //counters INT32 def_prop = 0; INT32 maybe_fixed = 0; INT32 maybe_prop = 0; INT32 dunno = 0; INT32 corr_fixed = 0; INT32 corr_prop = 0; float lower, upper; //cluster thresholds TO_ROW_IT row_it = block->get_rows (); row_index = 1; for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) { row = row_it.data (); ASSERT_HOST (row->xheight > 0); maxwidth = (INT32) ceil (row->xheight * textord_words_maxspace); if (row->fixed_pitch > 0 && fixed_pitch_row (row, block_index)) { if (row->fixed_pitch == 0) { lower = row->pr_nonsp; upper = row->pr_space; row->space_size = upper; row->kern_size = lower; } } row_index++; } count_block_votes(block, def_fixed, def_prop, maybe_fixed, maybe_prop, corr_fixed, corr_prop, dunno); if (testing_on && (textord_debug_pitch_test || textord_blocksall_prop || textord_blocksall_fixed)) { tprintf ("Initially:"); print_block_counts(block, block_index); } if (def_fixed > def_prop * textord_words_veto_power) block->pitch_decision = PITCH_DEF_FIXED; else if (def_prop > def_fixed * textord_words_veto_power) block->pitch_decision = PITCH_DEF_PROP; else if (def_fixed > 0 || def_prop > 0) block->pitch_decision = PITCH_DUNNO; else if (maybe_fixed > maybe_prop * textord_words_veto_power) block->pitch_decision = PITCH_MAYBE_FIXED; else if (maybe_prop > maybe_fixed * textord_words_veto_power) block->pitch_decision = PITCH_MAYBE_PROP; else block->pitch_decision = PITCH_DUNNO; return FALSE;}/********************************************************************** * print_block_counts * * Count up how many rows have what decision and print the results. **********************************************************************/void print_block_counts( //find line stats TO_BLOCK *block, //block to do INT32 block_index //block number ) { INT32 def_fixed = 0; //counters INT32 def_prop = 0; INT32 maybe_fixed = 0; INT32 maybe_prop = 0; INT32 dunno = 0; INT32 corr_fixed = 0; INT32 corr_prop = 0; count_block_votes(block, def_fixed, def_prop, maybe_fixed, maybe_prop, corr_fixed, corr_prop, dunno); tprintf ("Block %d has (%d,%d,%d)", block_index, def_fixed, maybe_fixed, corr_fixed); if ((textord_blocksall_prop || block->block->text_region () != NULL && block->block->text_region ()->is_prop ()) && (def_fixed || maybe_fixed || corr_fixed)) tprintf (" (Wrongly)"); tprintf (" fixed, (%d,%d,%d)", def_prop, maybe_prop, corr_prop); if ((textord_blocksall_fixed || block->block->text_region () != NULL && !block->block->text_region ()->is_prop ()) && (def_prop || maybe_prop || corr_prop)) tprintf (" (Wrongly)"); tprintf (" prop, %d dunno\n", dunno);}/********************************************************************** * count_block_votes * * Count the number of rows in the block with each kind of pitch_decision. **********************************************************************/void count_block_votes( //find line stats TO_BLOCK *block, //block to do INT32 &def_fixed, //add to counts INT32 &def_prop, INT32 &maybe_fixed, INT32 &maybe_prop, INT32 &corr_fixed,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -