static uchar * leo_strchr_codes_ansi(uchar *c1, uchar c2) { uchar *c; for (c = c1; *c; c++) if (stdLeoCompareChar(stdAnsiToAscii(*c), c2)) return c; return NULL; }
static void print_method(FILE *fp,RecVersions *res,char *s,int ansi) { int ii; fprintf(fp, "%s", s); if( !res->lnAltCnt ) { fprintf(fp,"-\n"); return; } fprintf(fp,"%c(%d)",ansi?stdAnsiToAscii(res->Alt[0].Code):res->Alt[0].Code,res->Alt[0].Prob); for(ii=1;ii<res->lnAltCnt;ii++) { fprintf(fp,",%c(%d)",ansi?stdAnsiToAscii(res->Alt[ii].Code):res->Alt[ii].Code,res->Alt[ii].Prob); } fprintf(fp,"\n"); return; }
int16_t rstr_cont_store(RecRaster *r,uchar let, uchar nLns,Rect16 *rect,uchar IsPrint, uchar Prob, uchar Valid, RecVersions *v,uchar control, uchar kegl,uchar column, uchar tabno) { int32_t num; uchar raster[4096],data[CTB_DATA_SIZE]= {0}; int32_t wb, k; Bool32 ret; RecVersions ver; if( !this_ctb.bas ) // || !cont_name[0] ) return 0; data[0]= CTB_OEM_CHARSET; data[1] = (uchar)r->lnPixWidth; data[2] = (uchar)r->lnPixHeight; data[3] = let; //stdAnsiToAscii(let); data[4] = 0; data[31] = nLns; data[32] = 0; data[5] = IsPrint; memcpy(&data[6],rect,sizeof(Rect16)); data[14] = Prob; data[15] = Valid; if( v ) { ver=*v; if( ver.lnAltCnt>4 ) ver.lnAltCnt=4; data[16]=(uchar)ver.lnAltCnt; for(k=0; k<ver.lnAltCnt; k++) { data[17+k*2]= stdAnsiToAscii(ver.Alt[k].Code); data[18+k*2]= ver.Alt[k].Prob; data[28+k] = ver.Alt[k].Method; } } data[25] = (uchar)line_number; // !!! can be great than 255 data[26] = 0;//leo_current_alpha_ndx; data[27] = control; if( datalen>34 ) data[34]=kegl; if( datalen>35 ) data[35]=column; if( datalen>36 ) data[36]=tabno; wb = ((r->lnPixWidth+63)/64)*8; memcpy( raster, r->Raster, wb*r->lnPixHeight); #ifdef _USE_CTB_ CTB_align1_lines(raster, r->lnPixWidth, r->lnPixHeight); ret = CTB_write( &this_ctb, -1, raster, data); if( !ret ) return -1; num = this_ctb.num; return (int16_t)num; // id_rast = last sequentaly saved raster+1 #else ret=-1; num=-1; return -1; #endif }
uchar leo_proport_penalty(uchar let,uchar prolet, int32_t w, int32_t h) { int32_t comSizes[4], prob[4], wid, hei, pr, pr1, prop, prp; uchar name; int32_t pmin=0, pmax=255; #ifdef NO_SIZES return 0; #endif if( !w || !h ) return 255; if( let ) { name = stdAnsiToAscii((uchar)let); if( memchr("№",let,1) ) name=let; pmin=letters_prop_table_rus[name].pmin; pmax=letters_prop_table_rus[name].pmax; if( LEO_GetLetStat((int32_t)let, comSizes,prob)>=0 && comSizes[0] && comSizes[2]) { // normal statistic && not empty hei = MIN(comSizes[0],comSizes[2]); wid = MAX(comSizes[1],comSizes[3]); pr = MIN(prob[0],prob[1]); // continued after all "else" } else { // statistic is not ready if( h>w ) pr= (64*w)/h ; else if( h==w ) pr=64 ; else if( h<w ) pr=128 - (64*h)/w ; if( pr>=pmin && pr<=pmax ) { if( pr<pmin+3 ) leo_narrow++; if( comSizes[0] && leo_alpha_type==ALPH_DIG && h*5<=comSizes[0]*4 ) return 50; return 0; } else { if( pr<=pmin/2 || pr>=pmax*3/2) return 255; if( prolet>230 && pr>pmin-5 && pr<pmin ) { leo_narrow_pen++; LEO_GetCommonStat(comSizes,prob); if( comSizes[0] ) { hei = comSizes[0]; wid = comSizes[2]; prop= MIN( prob[0], prob[2]); if( prop>64 && hei>wid) { prop= (64*wid)/hei ; if( abs(pr-prop)<5 ) return 0; } } } if( pr<pmin ) // было const 255,255-75 ,const 0, 60-255, const 255 { if( leo_narrow>5 && leo_narrow_pen>1 || leo_narrow>10 ) pr=(pmin+pr)/2; return 128*(256-(256*pr)/pmin)/256; //return 255-255*((2*256*pr)/pmin-256)/256; } if( pr>pmax ) // стало const 255, 255-0, const 0 ,0-255, const 255 return 10+255*2*((256*pr)/pmax-256)/256; } } } else { // no letter LEO_GetCommonStat(comSizes,prob); if( comSizes[0]==0 ) return 0; // empty stat if( comSizes[1]==0 ) { // all hei = comSizes[0]; wid = comSizes[2]; pr = MIN( prob[0], prob[2]); } else { // different Capital & Small hei = MIN(comSizes[0],comSizes[1]); pr = MIN( prob[0], prob[1]); wid = comSizes[2]; pr = MIN( pr, prob[2]); } } if( !hei || !wid ) return 0; if( hei>wid ) prop= (64*wid)/hei ; else if( hei==wid ) prop=64 ; else if( hei<wid ) prop=128 - (64*hei)/wid; if( h>w ) prp= (64*w)/h ; else if( h==w ) prp=64 ; else if( h<w ) prp=128 - (64*h)/w ; if( !let && prp<79 && prp>32 || (pmax!=255 && prp>=pmin && prp<=pmax )) return 0; if( !let && prp<96 && prp>32 ) if( prp<62 && prop>66 || prop<62 && prp>66 ) return 0; pr1 = ( abs( prp-prop )*100/prop ); if( pr1>100 ) pr1=100; if( h>=w && prp>=pmin && prp<=pmax || h<w &&pr1<45 && !( pmax && w>wid && w*100/wid>120 && prp>pmax) ) return 0; return (uchar)((pr1*255)/100); // large prop }
Bool32 RecogLEO(RecRaster *Rs,uchar Language,UniVersions *Us) { #ifdef _USE_LEO_ LeoFieldSetup fs={0}; RecObject ro={0}; LeoPageSetup ps={0}; char * alpha; uchar c, cw; int32_t i, up=-1; alpha = alpha_str; set_alphabet(alphabet1, alpha); LEOSetPlatform(586); fs.nStyle = LS_PRINT; memcpy(fs.AlphaTable,alphabet1,256); LEOSetupField(&fs); memset(&ro,0,sizeof(RecObject)); memcpy(&ro.recData.recRaster,Rs,REC_MAX_RASTER_SIZE); ps.nIdPage=-1; ro.recData.lwStatus=0; LEOSetupPage(&ps); LEORecogPrintChar(&ro); // memcpy(Vs,&ro.recResults,sizeof(RecVersions)); if( Us->lnAltCnt ) { c = Us->Alt[0].Liga ; if( is_upper(c) ) up=1; else if( is_lower(c) ) up=0; } Us->lnAltCnt=ro.recResults.lnAltCnt; Us->lnAltMax=REC_MAX_VERS; for(i=0;i<ro.recResults.lnAltCnt;i++) { c = stdAnsiToAscii( ro.recResults.Alt[i].Code); switch( up ) { case 1: // upper c=to_upper(c); break; case 0: // lower c=to_lower(c); break; default: break; } cw = stdAsciiToAnsi( c ); Us->Alt[i].Code[0]=cw; Us->Alt[i].Code[1]=0; Us->Alt[i].Liga=c; Us->Alt[i].Charset=CSTR_RUSSIAN_CHARSET; Us->Alt[i].Method =REC_METHOD_LEO; Us->Alt[i].Prob = ro.recResults.Alt[i].Prob ; } #endif return TRUE; }
int32_t TestFontClusters(void) { #ifdef _USE_LEO_ int32_t name; int i,j; int nClust; int porog=50; // test !!! int numInvalid; LeoFieldSetup fs={0}; RecRaster rec; RecObject ro={0}; LeoPageSetup ps={0}; ClustInfo cluInfo; uchar addLet,resLet; #ifdef _SAVE_INVALID_CLU_ FILE *fp; #endif curNumFile++; nClust=FONGetClustCount(); set_alphabet(alphabet1, alpha_str); #ifdef _SAVE_INVALID_CLU_ fp=fopen("clust.tst","at"); fprintf(fp,"file %d\n",curNumFile); #endif LEOSetPlatform(LEOGetCPU()); fs.nStyle = LS_PRINT; memcpy(fs.AlphaTable,alphabet1,256); LEOSetupField(&fs); for(i=0,numInvalid=0;i<nClust;i++) { cluInfo.let = 0; j=FONGetClustInfo(&cluInfo,i+1); if(j<=0) continue; if(cluInfo.attr & CTB_PRINT_ITALIC) continue; if(cluInfo.attr & CTB_PRINT_BOLD) continue; // now - test only russian ASCII letters if(cluInfo.let < 128 || cluInfo.let >= 176 && cluInfo.let < 224 || cluInfo.let > 240 ) continue; addLet=(cluInfo.let < 144 ? cluInfo.let +32 : cluInfo.let < 160 ? cluInfo.let +80 : cluInfo.let < 176 ? cluInfo.let -32 : cluInfo.let - 80 ); name=0; FONGetClusterAsBW(&name,i,porog,&rec); memset(&ro,0,sizeof(RecObject)); memcpy(&ro.recData.recRaster,&rec,sizeof(RecRaster)); ps.nIdPage=-1; ro.recData.lwStatus=0; LEOSetupPage(&ps); LEORecogPrintChar(&ro); // ничего хорошего по LEO ? if( ro.recResults.lnAltCnt <= 0 || ro.recResults.Alt[0].Prob < 150 ) continue; for(j=0;j<ro.recResults.lnAltCnt;j++) { resLet = stdAnsiToAscii(ro.recResults.Alt[j].Code); if( resLet == cluInfo.let || resLet == addLet ) break; } if(j==0) continue; { char *qq; resLet = stdAnsiToAscii(ro.recResults.Alt[0].Code); if( !is_lower(resLet) ) resLet = to_lower(resLet); if( (qq=strchr(hasNearSame,cluInfo.let)) && NearSame[qq-(char*)hasNearSame] == resLet ) continue; } // узналось как что-то иное ? // если совсем не распозналось - бывает ('»' в sten91) if( j >= ro.recResults.lnAltCnt || ro.recResults.Alt[j].Prob < 180 || ro.recResults.Alt[j].Prob < 220 && ro.recResults.Alt[j].Prob + 25 < ro.recResults.Alt[0].Prob ) { FonTestInfo testInfo[MAXCHECKALT]; // проверим resLet = stdAnsiToAscii(ro.recResults.Alt[0].Code); j=FONTestChar(&rec,resLet,testInfo,0); if( j <=0 || testInfo[0].prob <= 215 ) { resLet=(resLet < 144 ? resLet +32 : resLet < 160 ? resLet +80 : resLet < 176 ? resLet -32 : resLet - 80 ); j=FONTestChar(&rec,resLet,testInfo,0); } if( j > 0 && testInfo[0].prob > 215 ) { numInvalid++; FONSetClusterInvalid(i+1); #ifdef _SAVE_INVALID_CLU_ fprintf(fp," invalid %d (%c -> %c(%d))\n",i+1,cluInfo.let, stdAnsiToAscii(ro.recResults.Alt[0].Code), ro.recResults.Alt[0].Prob); #endif } } // end if j } // end clusters #ifdef _SAVE_INVALID_CLU_ fclose(fp); #endif return numInvalid; #else return 0; #endif }