예제 #1
0
/*---------------------------------------------------------------
  spec_pairs "ст", "сл" и др.
----------------------------------------------------------------*/
static void spec_pairs()
{
  struct cut_elm *cut;
  int16_t i,ip; //текущее и предыдущее сечения
  SVERS *vers;                   //текущая версия
  uchar let,letp;                 //текущая и предыдущая буквы
  struct cut_elm *cuts;
  int16_t is,x0;  //правая граница "с"
  int16_t m_row;                     //средняя базовая линия

  det_snap(LC, "special pairs");

  i=ncut-1;
  letp=0;
  ip=i;
  while (i>0)
    {
     cut=cut_list+i;
	 vers=&cut->versm;
	 let=vers->vers[0].let;
     if (dust(vers))
       {
        cuts=cut_list+cut->px;  //левый край dust'а
        if (cuts->dh != 0 &&      //dust отрезан слева
            addij(LC,r,cut_list,vers_list,ncut,cuts->px,i,0)==0 &&
            cut->versm.vers[0].prob > cuts->versm.vers[0].prob
           ) ;                     //приклеили
          else
            if (cut->dh != 0)       //dust отрезан справа
              addij(LC,r,cut_list,vers_list,ncut,i,ip,0);
       }
      else
        if ( cut->dh != 0 && strchr("кКтТуУ",let) &&
		    !is_russian_baltic_conflict(let) && // 17.07.2001 E.P.
			!is_russian_turkish_conflict(let)&&	// 21.05.2002 E.P.
		     (letp==(uchar)'г' || letp==(uchar)'Г')
		   )
          {
           int16_t  j,il=cut->px;
           int16_t x0=cut->x-((cut_list[ip].x-cut->x)>>1);
           uchar *letr=&cut_list[ip].versm.vers[0].let;
           for (j=i-1,cuts=cut-1; j>il && cuts->x >= x0; j--,cuts--)
             {
              if (addij(LC,r,cut_list,vers_list,ncut,il,j,0)>1)
				 break;
//              if (cut_list[j].versm.vers[0].prob<trs2)
//			       break;
              if (addij(LC,r,cut_list,vers_list,ncut,j,ip,0)>1)
				 continue;
              if ( (*letr==(uchar)'т' || *letr==(uchar)'Т')  &&
					!is_russian_baltic_conflict(*letr) && // 17.07.2001 E.P.
					!is_russian_turkish_conflict(*letr)	// 21.05.2002 E.P.
				 )
				 break;
             }
          }
         else
            {
             if (cut->dh != 0 &&
예제 #2
0
int16_t erection_incline_word_set(cell *b, cell *e)
{
cell  *c                  ;
int32_t  inc                 ;

if( (inc=get_incline_of_word(b,e))==0 )
  {
  for( c=b; c!=e; c=c->next)
    {
    c->pos_inc=erect_no;
    c->stick_inc = NO_INCLINE;
    c->save_stick_inc = NO_INCLINE;
    }
  return 0;
  }

for( c=b; c!=e; c=c->next)
  {
  // rotate cell images
  if( c->stick_inc!=NO_INCLINE && (((long)c->stick_inc*c->h)/204l)>16 &&
      ( (c->flg==c_f_bad) && c->stick_inc<max_incline ||
      c->nvers>0 && (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars)) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	  ||
       erect_solid_stick(c))) )
    c->save_stick_inc=c->stick_inc;
  else
    c->save_stick_inc=(uchar)inc;
  c->pos_inc=erect_no;
  c->stick_inc = NO_INCLINE;
  }

return (int16_t)inc;
}
예제 #3
0
Bool    test_incline_of_word(cell *b,cell *e,int32_t inc)
{
//Bool    ret=TRUE;
cell  * c;
int16_t     i,wn, up,let;
for(up=let=i=0, c=b; c!=e; c=c->next, i++)
    {
    if( c->flg&(c_f_let|c_f_bad) )
        {
        let++;
        if( c->stick_inc!=NO_INCLINE && (((long)c->stick_inc*c->h)/204l)>16 &&
          ( (c->flg==c_f_bad) && c->stick_inc<max_incline ||
          c->nvers>0 && (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars)) &&
			!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
			!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
		  ||
          erect_solid_stick(c))) )
            wn=erect_cell_width (c, (int16_t)(c->stick_inc));
        else
            wn=erect_cell_width(c, (int16_t)(inc));
        if( wn>c->w+1 )
            {
            up++;
            }
        }
    }
return !(up*2>let&&let>2);
}
예제 #4
0
void criteries()
 {
 cell *c;

 if (!line_number || current_fragment!=curr_frag)
  {
  dist_point_of_i_1=dist_point_of_i_2=dist_point_of_i_3=
  dist_point_of_i_b=0;
  curr_frag=current_fragment;
  }

 c=cell_f();
 while ((c=c->nextl)->nextl != NULL)
 {
  criteria(c);
 if(language == PUMA_LANG_RUSSIAN )
  {
  r_criteria(c,NULL);
  if( c->nvers>0 && memchr("’вѓЈ",c->vers[0].let,4) &&
      !is_russian_baltic_conflict(c->vers[0].let)&& // 17.07.2001 E.P.
	  !is_russian_turkish_conflict(c->vers[0].let) 	// 21.05.2002 E.P.
	)
    stick_center_study(c,NULL,1);
  }
 }
 }
예제 #5
0
파일: iot.cpp 프로젝트: nctan/quneiform
/********************************************************
 *							*
 * 		 Special programs for Й			*
 *							*
 ********************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "func.h"
#include "struct.h"
#include "linear.h"
#include "linutil.h"
#include "ligas.h"
#include "func.h"
#include "minmax.h"

extern uchar p2_active;
// Discrim й by base lines                              *
static int16_t rec_ii(cell*c,cell*cap);
static int16_t rec_ii_halo(cell * c);

static uchar iot_pen_lc[]= { 120,60,10,0,0 };
static uchar iot_pen_uc[]= { 140,10,0 ,0,0 };

int16_t cut_by_pos_ii(s_glue * const gl,uchar let)
{
    B_LINES bl;
    int16_t pen=0,upper=32000,dis,i;


    get_b_lines(gl->celist[0],&bl);
    for(i=0; i < gl->ncell; i++)
        upper = MIN(upper,gl->celist[i]->row);

    if(let==(uchar)'\xa9' /* й */ &&
            !is_russian_turkish_conflict(let) // 21.05.2002 E.P.
      ) {
        if((dis=upper-bl.b2) <= 0) { // letter upper than bbs2
            dis = abs(dis);
            if(dis < 5) pen = iot_pen_lc[dis];
        }
        else pen = 160; // letter lower than bbs2
        if( gl->ncell==1 && (gl->celist[0]->recsource == c_rs_ev ||
                             gl->celist[0]->recsource == (c_rs_ev|c_rs_deskr) ))// events brought vers
            if((Ns1+Ns2)>0 && bl.b2-bl.b1>6) {
                dis=upper-bl.b1;
                pen +=  dis<3 ? 60 : 0;
            }
    }
    if(let==(uchar)'\x89' /* Й */) { // Capital iot
        if((dis=upper-bl.b1) <= 0 ) { // letter upper than bbs1
            dis = abs(dis);
            if(dis < 5) pen = iot_pen_uc[dis];
        }
        else pen = 160; // letter lower than bbs1
    }
    return pen;
}

// Go by string and recog '\xa9' /* й */
void proc_ii(void)
{
    cell * c,*cap;
    uchar let;
    int16_t ndust;
    c = cell_f();
    while((c=c->nextLetter()) != NULL ) {
        if( !c->hasCellFlag(c_f_let + c_f_bad))
            continue;
        let = c->vers[0].let;
        ndust=0;
        //if( !memchr("иИнНпыў",let,7) ||
        if( !memchr("\xA8\x88\xAD\x8D\xAF\xEB\xF7",let,7) ||
                is_russian_baltic_conflict(let)	// 17.07.2001 E.P.
          )
            continue;

        cap = c;
        while((cap=cap->next)!=NULL && cap != c->nextLetter()) {
            if(cap->isDust()) {
                ndust++;
                switch(rec_ii(c,cap)) {
                case    1:
                    goto next_let;
                case   -1:
                    return;
                case    0:
                    break;
                }
            }
        }

        cap = c;

        while((cap=cap->prev)!=NULL && cap != c->previousLetter()) {
            if(cap->isDust()) {
                ndust++;
                //if(rec_ii(c,cap))goto next_let;
                switch( rec_ii(c,cap))
                {
                case    1:
                    goto next_let;
                case   -1:
                    return;
                case    0:
                    break;
                }
            }
        }
        if( ndust > 1)
            rec_ii_halo(c); // many dusts, try all together

next_let:
        ;
    } // while by letters
}
예제 #6
0
void analysis_words(void)
{
    int16_t   left,right,flag=0,flag_qual;
    cell  *WB,*WE,*cl;
    char  snap[380],*buf=snap;

    left=right=0;
    WB=clbeg;
    WE=clend;

    //AK! add crashguard
    while( (WB->flg & c_f_dust) || (WB->flg & c_f_fict) ||
            (WB->flg & c_f_punct) )
    {
        if ((WB->next == cell_l() || WB->next == NULL) )
            return;
        WB=WB->next;
    }

    //AK! add c/g
    while( (WE->flg & c_f_dust) || (WB->flg & c_f_fict) ||
            (WB->flg & c_f_punct))
    {
        if ((WE->prev == cell_f() || WE->prev == NULL))
            return;
        WE=WE->prev;
    }

    if(WB==WE) return;
    /*  ---------------- LEFT -----------------------------*/
    if(WB->vers[0].let==left_quocket) left=100;
    else if((WB->flg & c_f_bad)                                                 ||
            (memchr("¢э™",WB->vers[0].let,6) &&
             !is_russian_baltic_conflict(WB->vers[0].let) &&	// 17.07.2001 E.P.
             !is_russian_turkish_conflict(WB->vers[0].let)&& // 21.05.2002 E.P.
             WB->vers[0].prob < MAX_PROB) ||
            (memchr("Cc",WB->vers[0].let,2)     && WB->vers[0].prob < MIN_PROB) ||
            (memchr("u",WB->vers[0].let,1)      && WB->vers[0].prob <=SMAX_PROB &&
             WB->h <= ok_K_hgt)                                                 ||
            (WB->vers[0].let== r_cu_u           && WB->vers[0].prob < MID_PROB) ||
            (memchr("ae",WB->vers[0].let,2)     && WB->vers[0].prob < MAX_PROB)
           )
    {
        if(WB->vers[0].prob<MIN_PROB && (WB->h>>1)*3 <= (WB->nextl)->h)
            flag_qual=1;
        else  flag_qual=0;
        if(WB->vers[0].let=='1') flag_qual=0;
        left=check_shevron(WB,flag_qual);
    }
예제 #7
0
int16_t get_baton_inc(cell *c)
 {
 int16_t n, inc=0;
 STICK *res,*r;
 uchar let;

if( c->nvers<1 )
    return 0;

 let = decode_ASCII_to_[c->vers[0].let][0];
 n=sticks_in_letter(c,0,&res);
 r=res;

 if (n>=0)
    {
    switch( let )
        {
        case    (uchar)'ѕ':
        case    (uchar)'п':
			if (is_russian_baltic_conflict(let))	// 17.07.2001 E.P.
				{inc=1;break;}

            if( n==2 && abs(r[1].incl-r[0].incl)<50 )
                inc=r[1].incl;
            break;
        case    (uchar)'„':
        case    (uchar)'ч':
            if( n==2 && abs(r[1].incl-r[0].incl)<50 )
                inc=r[1].incl;
            else if( n==1  )
                inc=r[0].incl;
            break;
        case    (uchar)'“':
        case    (uchar)'т':
            if( n==1  )
                inc=r[0].incl;
            break;
        default:
            inc=1;
            break;
        }
    }
 else
      return 0;

 return inc;
 }
예제 #8
0
/*---------------------------------------------------------------------
  r2l процесс последовательного отрезания букв справа на интервале
      (ib2,ie2) (или (ib1,ie2), если справа буква из списка);
      заканчивается, если весь интервал хорошо разрезался или очередная
      граница совпала с вершиной оптимального пути слева;
      вычисляет новые значения ie1, ie2, ir;
---------------------------------------------------------------------*/
static char r2l(int16_t *ir, int16_t *ie2, int16_t *ie1, int16_t mode)
{
  int16_t i,x0;
  uchar let;
  seg_vers *cur_vers;
  struct cut_elm *cut;
  char cc;
  int16_t ie2p;   //предыдущая ie2
  struct cut_elm *cutb;  //граница при движении по связным компонентам
  int16_t pmax;       //наилучший результат
  int16_t set;        //индекс множества точек разрезания
  int16_t ie0;
  int16_t wmin,wmax;  //допустимая ширина буквы: мин. и макс.

  ie2p=*ie1;  *ir=ibc=*ie2;  cutb=cut_list+ibc;
  while (ibc > 0)
  {
    if (connect_)
    {
    //выбираем компоненту, добавляя узкие куски, лежащие недалеко
      x0=cut_list[*ie2].x;
      for (i=ibc-1,cut=cutb-1; i>=0; i--,cut--)
      {
        if (cut->dh != 0)  continue;
        if (cut->rv.v3 > minp)  break;   //широкий просвет
        if (cutb->x-cut->x > sym_width &&
            x0-cutb->x > sym_width)  break;
        ibc=i; cutb=cut;                 //кандидат на конец
      }
      if (i<0)  { i++; cut++; }
      if (cutb->x-cut->x <= sym_width || x0-cutb->x <= sym_width)
        { ibc=i;  cutb=cut; }
    }
    else
      ibc=0;

    //режем
    *ir=*ie2;
    while (*ir > ibc)
    {
      version *vers0;
      char *ilet;
      int16_t ie1p=*ie1;
      if (ib2<*ie2 && ibc<=ib2 && cut_list[*ie2].x-cut_list[ib2].x <= w2)
      {
        ie0=*ie2;
        if ((addij(LC,r,cut_list,vers_list,ncut,ib2,ie0,0) & (2+4+8)) == 0)
          if (cut_list[*ie2].versm.vers[0].prob>trs2)
            { *ie1=*ir=ib2;  goto accept; }
      }
      pmax=-1;
      wmin=w1;  wmax=w2;
      for (set=1; set<=3; set++)
      {
        ie0=*ie2;                                   //пробуем следующую
        cc=rcut_out(ibc,ie0,ie0,wmin,wmax,set,trs2,ir,&pmax,mode);
        if (cc)  { *ie1=*ir; goto accept; }
      }
      wmin=minw; wmax=h2;
      for (set=1; set<=4; set++)
      {
        ie0=*ie2;
        cc=rcut_out(ibc,ie0,ie0,wmin,wmax,set,trs2,ir,&pmax,mode);
                                                    //пробуем следующую
        if (cc)  { *ie1=*ir; goto accept; }
        if (*ie1 != *ie2)
        {                 //справа буква может быть частью более широкой
          ie0=*ie1;
          cc=rcut_out(ibc,*ie2,ie0,minw,h2,set,trs2,ir,&pmax,mode);
                                                  //расширяем предыдущую
          if (cc) { *ie1=*ie2; goto accept; }
        }
      }
      if (*ie2<ie2p)
      {
        ie0=*ie2;
        cc=radjust_cut(ibc,ir,&ie0,ie2p,minw,&pmax,mode);
        if (cc) { *ie1=*ir; goto accept; }
      }
      return 0;

accept:
      *ie2=*ir; ie2p=ie0; let=0;
      if (cur_vers=find_vers(*ir,ie0,vers_list))
      {
        vers0=&cur_vers->vers.vers[0];  let=vers0->let;
        if (let=='-')
          *ie1=ie1p;
        else
          if ( (let==(uchar)'т' || strchr(sticks_right_to_bad,let) ) &&
			   !is_russian_baltic_conflict(let) &&	// 17.07.2001 E.P.
			   !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
			 )
            *ie1=ie0;
          else
            if ( (ilet=strchr(letters_right_to_bad,let))!=0 &&
			    !is_russian_baltic_conflict(let) // 17.07.2001 E.P.
			   )
              if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad])
                *ie1=ie0;          //может быть частью буквы
      }

      if (debug_on)
#ifndef MY_DEBUG
        if (det_trace)
#endif
        {
          sprintf(snap_text,"keep: (%d,%d) %c",*ir,ie0,let);
          show_and_wait(snap_text);
        }
      if (ib2>=*ie2)
        if (ib2==*ie2 || on_path(*ie2,ib2,cut_list))  return 1;
    }
  }
  return 1;
}
예제 #9
0
/*---------------------------------------------------------------------
  l2r процесс последовательного отрезания букв слева на интервале
      (*b2,ie2) (или (*b1,ie2), если слева буква из списка);
      заканчивается, если весь интервал хорошо разрезался или очередная
      граница совпала с вершиной оптимального пути справа;
      вычисляет новые значения ib1, ib2, il;
---------------------------------------------------------------------*/
static char l2r(int16_t *ib1, int16_t *ib2, int16_t *il)
{
  int16_t i,x0;
  uchar let;
  struct cut_elm *cut;
  char cc;
  int16_t ib2p;       //предыдущая ib2
  struct cut_elm *cute;//граница при движении по связным компонентам
  int16_t pmax;       //наилучший результат
  int16_t set;               //индекс множества точек разрезания
  int16_t ib0;
  int16_t wmin,wmax;  //допустимая ширина буквы: мин. и макс.

  ib2p=*ib1;  *il=iec=*ib2;  cute=cut_list+iec;
  while (iec < iemax)
  {
    if (connect_)
    {
    //выбираем компоненту, добавляя узкие куски, лежащие недалеко
      x0=cut_list[*ib2].x;
      for (i=iec+1,cut=cute+1; i<=iemax; i++,cut++)
      {
        if (cut->dh != 0)  continue;
        if (cut->rv.v3 > minp)  break;   //широкий просвет
        if (cut->x-cute->x > sym_width &&
            cute->x-x0 > sym_width)  break;
        iec=i; cute=cut;                 //кандидат на конец
      }
      if (i>iemax)  { i--; cut--; }
      if (cut->x-cute->x <= sym_width || cute->x-x0 <= sym_width)
        { iec=i; cute=cut; }
    }
    else
      iec=iemax;

    //режем
    *il=*ib2;
    while (*il<iec)
    {
      version *vers0;
      char *ilet;
      int16_t ib1p=*ib1;
      if (*ib2<ie2 && ie2<=iec && cut_list[ie2].x-cut_list[*ib2].x <= w2)
      {
        ib0=*ib2;
        if ((addij(LC,r,cut_list,vers_list,ncut,ib0,ie2,0) & (2+4+8)) == 0)
          if (cut_list[ie2].versm.vers[0].prob>trs2)
            { *ib1=*il=ie2;  goto accept; }
      }
      pmax=-1;
      wmin=w1;  wmax=w2;
      for (set=1; set<=3; set++)
      {
        ib0=*ib2;                                   //пробуем следующую
        cc=lcut_out(ib0,*ib2,iec,wmin,wmax,set,trs2,il,&pmax);
        if (cc)  { *ib1=*il; goto accept; }
      }
      wmin=minw; wmax=h2;
      for (set=1; set<=4; set++)
      {
        ib0=*ib2;
        cc=lcut_out(ib0,*ib2,iec,wmin,wmax,set,trs2,il,&pmax);
                                                    //пробуем следующую
        if (cc)  { *ib1=*il; goto accept; }
        if (*ib1 != *ib2)
        {             //слева буква может быть частью более широкой
          ib0=*ib1;
          cc=lcut_out(ib0,*ib2,iec,minw,h2,set,trs2,il,&pmax);
                                                    //расширяем предыдущую
          if (cc) { *ib1=*ib2; goto accept; }
        }
      }
      if (*ib2>ib2p)
      {
        ib0=*ib2;
        cc=ladjust_cut(ib2p,&ib0,il,iec,minw,&pmax);
        if (cc) { *ib1=*il; goto accept; }
      }
      return 0;

accept:
      *ib2=*il; ib2p=ib0; let=0;
      vers0=&cut_list[*il].versm.vers[0];  let=vers0->let;
      if (let=='-')
        *ib1=ib1p;
      else
        if ( (let==(uchar)'т' || let==(uchar)'ш' || let==(uchar)'Ш' ||
              strchr(sticks_left_to_bad,let)
			 ) &&
			 !is_russian_baltic_conflict(let) &&// 17.07.2001 E.P.
			 !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
		   )
          *ib1=ib0;
        else
          if ( (ilet=strchr(letters_left_to_bad,let))!=0 &&
			  !is_russian_baltic_conflict(let)	// 17.07.2001 E.P.
			  )
            if (vers0->prob < prob_left_to_bad[(uchar*)ilet-letters_left_to_bad])
              *ib1=ib0;            //может быть частью буквы

      if (debug_on)
#ifndef MY_DEBUG
        if (det_trace)
#endif
        {
          sprintf(snap_text,"keep: (%d,%d) %c",ib0,*il,let);
          show_and_wait(snap_text);
        }
      if (*ib2>=ie2)
        if (*ib2==ie2 || on_path(*ib2,iemax,cut_list))
		  return 1;
      if ( (let==(uchar)'ь' || let==(uchar)'Ь') &&
		  !is_russian_baltic_conflict(let) 	// 17.07.2001 E.P.
		 )
      {
        fl_b=1; return 0;
      }
    }
  }
  return 1;
}
예제 #10
0
/*------------------------------------------------------------------
  dp_pass0  линейный проход в растре r на множестве ncut
            точек cut_list; vers_list - результаты для отдельных
            сегментов; LC - cell слева от растра
------------------------------------------------------------------*/
void dp_pass0(cell *CP, raster *rp, struct cut_elm *cutp,
              seg_vers **versp, int16_t n)
{
  int16_t i,j,x;
  int16_t i1,i2;
  uchar let;
  int16_t cc;
  struct cut_elm *cut;
  SVERS *vers;
  int16_t pass;
//  seg_vers *cur_vers;

  if ((ncut=n)<2)  return;
  LC=CP; r=rp; cut_list=cutp; vers_list=versp;
  iemax=ncut-1;  right_dust=0;  fl_b=0;  connect_=1;
  ie1=iemax;  vers=&cut_list[ie1].versm;
  ie2=ir=(let(vers) || dust(vers)) ? ie1-1 : ie1;
  ib1=ib2=0;      vers=&cut_list[1].versm;
  if (let(vers))  ib2=1;
  else
    if (cut_list->gvarm & c_cg_cutdone)  ib2=on_path(0,ie2,cut_list);
  iec=ib2;  ibc=ie2;
  w1=sym_width-(sym_width>>2);  w2=sym_width+(sym_width>>2);  h2=r->h<<1;
  cut=cut_list+ie1;
/*
//отщепляем правые dust'ы
  if (dust(&cut->versm) && cut->duflm==0)
  {
    right_dust=1;  iemax--;  cut--;
//    if (dust(&cut->versm) && cut->duflm==0)  iemax--;
    ir=ie1=ie2=iemax;
  }
*/
//крайние хорошие распознаем с сопутствующими dust'ами
  if (ie1 != ie2 && cut->duflm)
    addij(LC,r,cut_list,vers_list,ncut,ie2,ie1,0);
  if (ib1 != ib2)
  {
    cut=cut_list+ib2;
    if (cut->duflm)
		addij(LC,r,cut_list,vers_list,ncut,ib1,ib2,0);
    if ((let=cut->versm.vers[0].let)==(uchar)'ь' &&
			!is_russian_baltic_conflict(let) ||		// 17.07.2001 E.P.
			let==(uchar)'Ь'
	   )
      fl_b=1;
  }

  if (ib2>=ie2)
  {
    addij(LC,r,cut_list,vers_list,ncut,ib1,ie1,0);
    goto test_right_dust;
  }

  do
  {
    if (!fl_b && iec != iemax)
    {
#ifndef MY_DEBUG
    if (det_trace)
#endif
      cg_show_rast(LC,r,"left to right",cut_list); //растр - на экран

      cc=l2r(&ib1,&ib2,&il);
      if (cc)  goto finish;

      if (il<iemax && iec>il &&
          (cut=cut_list+il)->dh==0 &&
          (x=cut->x-cut_list->x) < h2 && x > sym_width>>1 &&
          cut->versm.vers[0].prob>=190 &&
          !not_connect_sect(0,il,cut_list))
      {                 //оставим, как есть, и попробуем дальше
        i1=i2=il;
        cc=l2r(&i1,&i2,&i);
        if (cc)         //дальше - хорошо, вернемся к подозрительному участку
        {
  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"right side reached, return %d-%d",0,il);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
          ib1=i1;  ib2=i2;  i1=i2=il;  il=i;
          cc=r2l(&i,&i2,&i1,0);
          goto finish;
        }
      }
    }
    if (ibc != 0 && abs(cut_list[ie2].x-cut_list[ib2].x)>minw)
    {
    //слева не вышло, пробуем справа налево

  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"left: reliable=%d advance=%d; try right",ib2,il);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }

      cc=r2l(&ir,&ie2,&ie1,2);
      if (cc)  goto finish;

      if (ir>0 && ibc<ir &&
          (cut=cut_list+ir)->dh==0 &&
          (x=cut_list[iemax].x-cut->x) < h2 && x > sym_width>>1 &&
          cut_list[iemax].versm.vers[0].prob>=190 &&
          !not_connect_sect(ir,iemax,cut_list))
      {                 //оставим, как есть, и попробуем дальше
        i1=i2=ie2;
        cc=r2l(&i,&i2,&i1,2);
        if (cc)         //дальше - хорошо, вернемся к подозрительному участку
        {
  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"left side reached, return %d-%d",ir,iemax);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
          ie1=i1;  ie2=i2;  i1=i2=ir;  ir=i;
          cc=l2r(&i1,&i2,&i);
          goto finish;
        }
      }
    }
    if (abs(cut_list[ie2].x-cut_list[ib2].x)<=minw)
    {
      j=on_path(ie2,iemax,cut_list);
      if (j==0)  break;
      if (ib2==0)  addij(LC,r,cut_list,vers_list,ncut,0,j,0);
      else         one_cut(cut_list[ib2].px,ib2,ie2,j);
      goto test_right_dust;
    }

    if (il==ie2 && (iec>il || iec==iemax) &&
        ir==ib2 && (ibc<ir || ibc==0)     &&
        cut_list[ie2].versm.vers[0].prob>MINlet)
      goto finish;
    if (il==ie2 && (iec>il || iec==iemax) || ir==ib2 && (ibc<ir || ibc==0))
      if (cut_list[ie2].versm.vers[0].prob>=190)  goto finish;
    if (il==ir)
    {
      version *vers0;
      char *ilet;
      if (connect_ && cut_list[il].dh==0)
      {
        addij(LC,r,cut_list,vers_list,ncut,ib2,ie2,0);
        if (cut_list[ie2].versm.vers[0].prob>trs2)  goto finish;
      }
      if (ir != ie2 && cut_list[ie2].x-cut_list[ir].x > w2)
      {
        i1=i2=ir;
        if ( l2r(&i1,&i2,&i) || i>0 && on_path(i,iemax,cut_list) &&
             cut_list[i].versm.vers[0].prob>=190)
        {
          j=on_path(ir,iemax,cut_list);
          vers0=&cut_list[j].versm.vers[0];
          if ( (let=vers0->let)==(uchar)'т' &&
			  !is_russian_baltic_conflict(let) && 	// 17.07.2001 E.P.
			  !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
			  )
            ie1=j;
          else
            if ( (ilet=strchr(letters_right_to_bad,let))!=0 &&
			    !is_russian_baltic_conflict(let) // 17.07.2001 E.P.
			   )
              if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad])
                ie1=j;          //может быть частью буквы
          ie2=ir;
        }
      }
      if (il != ib2 && cut_list[il].x-cut_list[ib2].x > w2)
      {
        i2=il;  i1 = (ie2==il) ? ie1 : i2;
        if (r2l(&i,&i2,&i1,0) || on_path(i,ib2,cut_list) &&
            cut_list[i2].versm.vers[0].prob>=190)
        {
          cut=cut_list+il;
          vers0=&cut->versm.vers[0];
          if ((let=vers0->let)==(uchar)'т' &&
			  !is_russian_baltic_conflict(let) && 	// 17.07.2001 E.P.
			  !is_russian_turkish_conflict(let) 	// 21.05.2002 E.P.
			  )
            ib1=cut->px;
          else
            if ( (ilet=strchr(letters_right_to_bad,let)) !=0 &&
			    !is_russian_baltic_conflict(let) // 17.07.2001 E.P.
			   )
              if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad])
                ie1=cut->px;          //может быть частью буквы
          ib2=il;
        }
      }
      if (ib2==ie2)  goto finish;
    }
//    if (il>ir)  break;
//    if (iec==iemax || ibc==0 || iec<ibc)  break;
    if (iec==iemax && ibc==0)  break;
    connect_ = 1-connect_;
  }
  while (!connect_);

  if (right_dust)
    if (glue_right_dust())
    {
      spec_pairs();  return;
    }

  if (debug_on)
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"right: reliable=%d advance=%d; ",ie2,ir);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }

  //не сошлись, запускаем ДП между ними

  if (ie1-ib1 <= 2)
    if (!good_path(cut_list,ncut))  { ib1=ib2=0; ie2=ie1=ncut-1; }

DP:
  if (ie1-ib1 <= 2)
  {
    spec_pairs();  return;
  }

  il=ib1; ir=ie1;

  for (pass=1; pass<=4; pass++)
  {
    dp_bound(cut_list,vers_list,pass,&il,&ir);
    if (ir<=il)
    {
      if (ib1 != 0 || ie1 != ncut-1)  spec_pairs();   //неполное ДП
      return;
    }
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
    for ( i=il+1; i<=ir; i++ )
    {
      if ( !ben_cut(cut_list+i) )  //разрешен на данном проходе
      {
        snap_newpoint(i);
        for (j=i-1; j>=il; j--)
          if ( !ben_cut(cut_list+j) )
            if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8)  break                                                               ;
      }                                                     //8-широк                                                               ий
    }
  }  //pass

  if (ib1==0 && ie1==ncut-1)  return;   //полное ДП - больше нечего делать

  if (good_path(cut_list,ncut))  { spec_pairs();  return; }

//ДП по всему участку

  il=0;  ir=ncut-1;
  for (pass=1; pass<=4; pass++)
  {
    dp_bound(cut_list,vers_list,pass,&il,&ir);
    if (ir<=il)  return;
    if (il>=ib1 && ir<=ie1)  return; //на этом интервале уже считали
/*
    {
      struct cut_elm *cute=cut_list+ir;
      for (cut=cut_list+(il+1); cut<cute; cut++)
        if ((cut->var & 0x7F)==40)  break;
      if (cut==cute)  return;  //новых точек не будет
    }
*/
#ifndef MY_DEBUG
    if (det_trace)
#endif
    {
      sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass);
      cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран
    }
    for ( i=il+1; i<=ir; i++ )
    {
      if ( !ben_cut(cut_list+i) )  //разрешен на данном проходе
      {
        snap_newpoint(i);
        for (j=i-1; j>=il; j--)
          if ( !ben_cut(cut_list+j) )
            if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8)  break                                                               ;
      }                                                     //8-широк                                                               ий
    }
  }  //pass
  return;

test_right_dust:
  if (right_dust)  glue_right_dust();
  if (!good_path(cut_list,ncut))  { ib1=ib2=0; ie2=ie1=ncut-1; goto DP; }
  spec_pairs();
  return;

finish:
  if (right_dust)  glue_right_dust();
  spec_pairs();
  return;
}
예제 #11
0
// erecting all letters with sticks and bad symbols
Bool setup_incline_word(cell *b, cell *e, Bool calc)
{
cell *c , *cs;
int16_t  inc, ninc, nall;

if( calc )
  {
  memset(hist,0,sizeof(hist));
  memset(extr,0,sizeof(extr));
  }
for( nall=ninc=0, c=b; c!=e; c = c->next,nall++)
    {
    if( !(c->pos_inc&erect_rot) )
      {
      c->pos_inc=erect_no;
      c->right=0;
      if( (c->flg&c_f_let) && // for inclinables images
          (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars) ) &&
			!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
			!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
		  ||
           erect_solid_stick(c))  ||
          (c->flg&c_f_bad) )  // or  bad symbols
        {
        if( erector(c, 1, 0, 1, 0)==2 )  // set incline in c->stick_inc
            {

            }
        inc=0;
        if( c->stick_inc!=NO_INCLINE )
          inc = c->stick_inc;
        if( inc>=0 )
          {
          if( calc  )
            {
            hist[ inc/16 ]++;
            }
          ninc++;
          cs = c;
          }
        }
      }
    }

if( calc )
  {
  num_extr = 0;
  if( hist[0]+1==ninc && hist[16]==1 )
    return FALSE;
  if( !(hist[0]*3>ninc*2) && ninc>9) //10 )
    { // binarize if few nonIncline images & many incline images
    for(inc=0;inc<128;inc++)
      if( hist[ inc ]>=ninc/4 && num_extr<sizeof( extr ) )
        extr[ num_extr++ ] = (uchar)inc;
    }
  if( num_extr )
    max_incline = MAX((extr[ num_extr-1 ]+1)*16,512);
  else
    max_incline = 512;
  if( !num_extr )
    {
    for( c=b; c!=e; c = c->next)
        {
        if( c->stick_inc<300 ||
            c->stick_inc<400 && get_baton_inc(c)==0 )
            {
            if( calc  )
                hist[ c->stick_inc/16 ]--;
            ninc--;
            if( !local_pass )
                c->stick_inc=0;
            }
        }
    }

  if( num_extr )
    {
    for( c=b; c!=e; c = c->next)
    if( !(c->pos_inc&erect_rot) )
      {
      if( (c->flg&c_f_let) && // for inclinables images
        memchr(aux_inc_chars,c->vers[0].let,sizeof(aux_inc_chars)) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
		)
      {
      inc = 0;
      erector(c, 1, 0, 1, 1);  // set incline in c->stick_inc
      if( c->stick_inc!=NO_INCLINE )
        {
        inc = c->stick_inc;
        ninc++;
        }
      if( !mode_incline(inc) && inc<300 )
        {  // non characteristical incline
        c->pos_inc=erect_no;
        c->right=0;
        }
      }
    }
    }
  line_incline = ( ninc*2>nall );
  }
else // calc==0 : study one word
  if( ninc==0 )
    return FALSE;
return TRUE;
}
예제 #12
0
//
// rotate word cells
//
int16_t erection_incline_word(cell *b, cell *e, int16_t base_3, int16_t n_call)
{
cell  *c, *tmp, *cnext                  ;
int32_t  inc,    i                         ;
int16_t   shave=(erection_enable==2)        ;
version save_versions[VERS_IN_CELL]     ;
int16_t   save_nvers                        ;

if( (inc=get_incline_of_word(b,e))==0 )
  return 0;
if( 1&&!test_incline_of_word(b,e,inc) )
    return 0;

for(i=0, c=b; c!=e; c=c->next, i++)
  {
  tmp = c->prev; // left cell
  cnext=c->next; // right cell
  if( local_pass )
    {
    if( c->pos_inc&erect_rot )
        continue;
    if( c->stick_inc!=NO_INCLINE && (((long)c->stick_inc*c->h)/204l)>16 &&
      ( (c->flg==c_f_bad) && c->stick_inc<max_incline ||
      c->nvers>0 && (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars)) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	  ||
      erect_solid_stick(c))) )
        c->save_stick_inc = c->stick_inc;
    else
        c->save_stick_inc = (int16_t)inc;
    c->pos_inc = erect_rest;
    continue;
    }
  // rotate cell images
  if( c->stick_inc!=NO_INCLINE && (((long)c->stick_inc*c->h)/204l)>16 &&
      ( (c->flg==c_f_bad) && c->stick_inc<max_incline ||
      c->nvers>0 && (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars)) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	  ||
      erect_solid_stick(c))) )
    c=erect_cell_value (c, c->stick_inc, shave , TRUE);
  else
    c=erect_cell_value (c, (int16_t)inc, shave , TRUE);

  for(tmp = tmp->next;tmp!=cnext;tmp=tmp->next)
    {    // shift cell boxes
    erect_rotate_bl(tmp,base_3,inc,-1);//(int16_t)(line_scale?(base_3>>line_scale):base_3),inc,-1);
    v2_pidx_crit(tmp);
    if( (save_nvers = c->nvers)>0 )
        memcpy(save_versions,c->vers,VERS_IN_CELL*sizeof(version));
    // recognizing corrected images
    if( (tmp->flg&(c_f_bad|c_f_let)) && !local_pass)
      {
      if(n_call==0  )
        {
        if( tmp->nvers>0 &&
			memchr(disable_rerecog,tmp->vers[0].let,sizeof(disable_rerecog) ) &&
				!is_russian_baltic_conflict(tmp->vers[0].let)&&// 17.07.2001 E.P.
				!is_russian_turkish_conflict(tmp->vers[0].let)   // 21.05.2002 E.P.
			||
            tmp->nvers<1 )
          {
          short_recog_cell( tmp );
          levcut(tmp,1);
          add_versions(tmp, save_versions, save_nvers);
          } // end of spec letters for 1 pass
        }
      else
        {
        s_glue GL={0};

        GL.celist[0]   = tmp;
        GL.maxlist[0]  = tmp;
        GL.complist[0] = tmp->env;
        GL.maxlist[1]  = GL.celist[1]=NULL;
        GL.complist[1] = NULL;
        GL.ncell       = 1;
        GL.row         = tmp->row;
        GL.col         = tmp->col;
        GL.width       = tmp->w;
        GL.height      = tmp->h;

        if(crecell(tmp,&GL,3)>=0)
          dmBOX(tmp,&GL);
        } // end of spec letters for 2 pass
      } // end of if letter
    } // end of cykl tmp
  }

return (int16_t)inc;
}
예제 #13
0
// calculate average incline in word
int16_t get_incline_of_word(cell *b, cell *e)
{
cell *c                       ;
int32_t  inc, inc1, n1           ;
int16_t   i, n, mn, all, zeromn   ;
int16_t   inc_list[MAX_LEN_WORD]  ;
int16_t   norm_list[MAX_LEN_WORD] ;
int16_t   zero, in, zerall        ;
#define MAX_INCLINE 55

memset(inc_list,0,sizeof(inc_list));
for(n1=inc1=inc=0,zerall=zero=zeromn=all=mn=i=n=0,c=b; c!=e; c=c->next)
  {
  if( (c->flg&(c_f_let|c_f_bad)) &&
      c->stick_inc!=NO_INCLINE &&
      c->stick_inc>1 &&
      (memchr(incline_main, c->vers[0].let, sizeof(incline_main)) &&
		!is_russian_baltic_conflict(c->vers[0].let)	&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let)// 21.05.2002 E.P.
	  ||
       c->stick_inc<max_incline)  &&
      c->nvers>0 &&
       ( (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars) ) &&
			!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
			!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	   ||
       erect_solid_stick(c) ) ||
        memchr(aux_inc_chars,c->vers[0].let,sizeof(aux_inc_chars) ) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
		)
	)
    {
    inc += c->stick_inc;
    norm_list[n] = c->stick_inc;
    n++;
    if( c->nvers>0 &&
        memchr(incline_main,c->vers[0].let,sizeof(incline_main)) &&
		!is_russian_baltic_conflict(c->vers[0].let)	&& // 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let)&&// 21.05.2002 E.P.
        no_bad_alias(c)
	  )
      mn++;
    if( (c->flg&c_f_bad)&&mode_incline(c->stick_inc) )
      mn++;
    }
  else if( (c->flg&c_f_bad) && mode_incline(c->stick_inc) )
    inc_list[i++] = c->stick_inc;

  if( c->stick_inc==0 )
    zerall++;
  if( (c->flg&c_f_let) &&
      c->stick_inc==0 )
    {
    if( c->nvers && memchr(incline_main,c->vers[0].let,sizeof(incline_main)) &&
			!is_russian_baltic_conflict(c->vers[0].let)&& // 17.07.2001 E.P.
			!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	  )
        zeromn++;
    else if(   c->nvers && '|'==c->vers[0].let && c->h>16 )
        zeromn++;
    }

  if( (c->flg&c_f_let) &&      c->stick_inc==0 &&      c->nvers>0 &&
    (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars) ) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	||
       erect_solid_stick(c)) )
    zero++;

  if((c->flg&c_f_let) && c->stick_inc!=NO_INCLINE && c->stick_inc>1 &&
     c->nvers>0 && (memchr(incline_chars,c->vers[0].let,sizeof(incline_chars) ) &&
		!is_russian_baltic_conflict(c->vers[0].let)&&// 17.07.2001 E.P.
		!is_russian_turkish_conflict(c->vers[0].let) // 21.05.2002 E.P.
	 ||
       erect_solid_stick(c)) )
    {
    inc1 += c->stick_inc;
    n1++;
    }
  if( (c->flg&c_f_let) )  all++;
  }

if( n==0 )
  {
  if( i )
    return ( represent_inc(inc_list,i, 64) );
  else if(n1>0 && n1*2>all && line_incline )
    {
    inc1 /= n1;
    if( inc1<300 ) inc1=0;
    return (uchar)inc1;
    }
  else
    return 0;
  }
else
  {
  if( (in=represent_inc(norm_list,n, 64))!=0 &&
       num_inc_in_list(norm_list,n)>2 )
    inc = in;
  else
    inc /= n;
  }


// delete incline for small statistic
if( inc<100 )
  inc = 0; // too small incline

if( mn==0 && ( num_extr==0 && n*5<all*3 || all==1 ))
  inc = 0; // too few inclineable images

if( mn==1 && num_extr==0 && nIncline>=MAX_INCLINE && inc-nIncline<=256 )
  inc = 0; // too few inclineable images  & large line incline

if( inc<300 &&  // small incline
    (zeromn>1 || hist[0]>5) &&  // exist zero inc in word or line
    (num_extr==0||num_extr==2 && extr[0]==0&&extr[1]<=16) && // non inc line
    (nIncline>=MAX_INCLINE && inc-nIncline<=256 ||  // large line incline
     zero>2 && mn<2) )           // many zero inc in word  & 1 inc
  inc = 0;

if( inc<350 && mn==0 && all<4 && zeromn>0 )
    inc=0;
if( mn==1 && zeromn>1 )          // many zero inc in word  & 1 inc
  inc = 0;

if( mn==1 && zeromn>=1 && nIncline>=MAX_INCLINE )
  inc = 0;

if( zeromn && zerall>MAX(all/3,2) && num_extr==0 && inc>max_incline )
  inc = 0;

if( inc>700 && mn<2 && !num_extr ) // big incline & too few inclineables letsx
  inc = 0;

// set new inc during bad letter with good incline
if( inc==0 && all<2 && num_extr )
  {
  int16_t num, ii;
  inc1 = represent_inc(inc_list,i, 64);
  for(num=ii=0;ii<i;ii++)
    if(inc_list[ii]==inc1) num++;
  if( num==i )
    inc = inc1;
  }

return (int16_t)inc;
}