isbn 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. data/{README → README.md} +5 -11
  2. data/Rakefile +20 -14
  3. data/isbn.gemspec +23 -0
  4. data/lib/isbn.rb +2 -0
  5. data/test/isbn_spec.rb +1 -1
  6. metadata +29 -316
  7. data/VERSION +0 -1
  8. data/src/gocr-0.48/.cvsignore +0 -6
  9. data/src/gocr-0.48/AUTHORS +0 -7
  10. data/src/gocr-0.48/BUGS +0 -55
  11. data/src/gocr-0.48/CREDITS +0 -17
  12. data/src/gocr-0.48/HISTORY +0 -243
  13. data/src/gocr-0.48/INSTALL +0 -83
  14. data/src/gocr-0.48/Makefile +0 -193
  15. data/src/gocr-0.48/Makefile.in +0 -193
  16. data/src/gocr-0.48/README +0 -165
  17. data/src/gocr-0.48/READMEde.txt +0 -80
  18. data/src/gocr-0.48/REMARK.txt +0 -18
  19. data/src/gocr-0.48/REVIEW +0 -538
  20. data/src/gocr-0.48/TODO +0 -65
  21. data/src/gocr-0.48/bin/.cvsignore +0 -2
  22. data/src/gocr-0.48/bin/create_db +0 -38
  23. data/src/gocr-0.48/bin/gocr.tcl +0 -527
  24. data/src/gocr-0.48/bin/gocr_chk.sh +0 -44
  25. data/src/gocr-0.48/configure +0 -4689
  26. data/src/gocr-0.48/configure.in +0 -71
  27. data/src/gocr-0.48/doc/.#Makefile.1.6 +0 -39
  28. data/src/gocr-0.48/doc/.cvsignore +0 -2
  29. data/src/gocr-0.48/doc/Makefile +0 -39
  30. data/src/gocr-0.48/doc/Makefile.in +0 -39
  31. data/src/gocr-0.48/doc/example.dtd +0 -53
  32. data/src/gocr-0.48/doc/example.xml +0 -21
  33. data/src/gocr-0.48/doc/examples.txt +0 -67
  34. data/src/gocr-0.48/doc/gocr.html +0 -578
  35. data/src/gocr-0.48/doc/unicode.txt +0 -57
  36. data/src/gocr-0.48/examples/.#Makefile.1.22 +0 -166
  37. data/src/gocr-0.48/examples/4x6.png +0 -0
  38. data/src/gocr-0.48/examples/4x6.txt +0 -2
  39. data/src/gocr-0.48/examples/5x7.png +0 -0
  40. data/src/gocr-0.48/examples/5x7.png.txt +0 -2
  41. data/src/gocr-0.48/examples/5x8.png +0 -0
  42. data/src/gocr-0.48/examples/5x8.png.txt +0 -2
  43. data/src/gocr-0.48/examples/Makefile +0 -166
  44. data/src/gocr-0.48/examples/color.fig +0 -20
  45. data/src/gocr-0.48/examples/ex.fig +0 -16
  46. data/src/gocr-0.48/examples/font.tex +0 -22
  47. data/src/gocr-0.48/examples/font1.tex +0 -46
  48. data/src/gocr-0.48/examples/font2.fig +0 -27
  49. data/src/gocr-0.48/examples/font_nw.tex +0 -24
  50. data/src/gocr-0.48/examples/handwrt1.jpg +0 -0
  51. data/src/gocr-0.48/examples/handwrt1.txt +0 -10
  52. data/src/gocr-0.48/examples/inverse.fig +0 -20
  53. data/src/gocr-0.48/examples/matrix.jpg +0 -0
  54. data/src/gocr-0.48/examples/ocr-a-subset.png +0 -0
  55. data/src/gocr-0.48/examples/ocr-a-subset.png.txt +0 -4
  56. data/src/gocr-0.48/examples/ocr-a.png +0 -0
  57. data/src/gocr-0.48/examples/ocr-a.txt +0 -6
  58. data/src/gocr-0.48/examples/ocr-b.png +0 -0
  59. data/src/gocr-0.48/examples/ocr-b.png.txt +0 -4
  60. data/src/gocr-0.48/examples/polish.tex +0 -28
  61. data/src/gocr-0.48/examples/rotate45.fig +0 -14
  62. data/src/gocr-0.48/examples/score +0 -36
  63. data/src/gocr-0.48/examples/text.tex +0 -28
  64. data/src/gocr-0.48/gpl.html +0 -537
  65. data/src/gocr-0.48/include/.cvsignore +0 -2
  66. data/src/gocr-0.48/include/config.h +0 -36
  67. data/src/gocr-0.48/include/config.h.in +0 -36
  68. data/src/gocr-0.48/include/version.h +0 -2
  69. data/src/gocr-0.48/install-sh +0 -3
  70. data/src/gocr-0.48/make.bat +0 -57
  71. data/src/gocr-0.48/man/.cvsignore +0 -2
  72. data/src/gocr-0.48/man/Makefile +0 -29
  73. data/src/gocr-0.48/man/Makefile.in +0 -29
  74. data/src/gocr-0.48/man/man1/gocr.1 +0 -166
  75. data/src/gocr-0.48/src/.cvsignore +0 -4
  76. data/src/gocr-0.48/src/Makefile +0 -132
  77. data/src/gocr-0.48/src/Makefile.in +0 -132
  78. data/src/gocr-0.48/src/amiga.h +0 -31
  79. data/src/gocr-0.48/src/barcode.c +0 -846
  80. data/src/gocr-0.48/src/barcode.c.orig +0 -593
  81. data/src/gocr-0.48/src/barcode.h +0 -11
  82. data/src/gocr-0.48/src/box.c +0 -372
  83. data/src/gocr-0.48/src/database.c +0 -462
  84. data/src/gocr-0.48/src/detect.c +0 -943
  85. data/src/gocr-0.48/src/gocr.c +0 -373
  86. data/src/gocr-0.48/src/gocr.h +0 -288
  87. data/src/gocr-0.48/src/jconv.c +0 -168
  88. data/src/gocr-0.48/src/job.c +0 -84
  89. data/src/gocr-0.48/src/lines.c +0 -350
  90. data/src/gocr-0.48/src/list.c +0 -334
  91. data/src/gocr-0.48/src/list.h +0 -90
  92. data/src/gocr-0.48/src/ocr0.c +0 -6756
  93. data/src/gocr-0.48/src/ocr0.h +0 -63
  94. data/src/gocr-0.48/src/ocr0n.c +0 -1475
  95. data/src/gocr-0.48/src/ocr1.c +0 -85
  96. data/src/gocr-0.48/src/ocr1.h +0 -3
  97. data/src/gocr-0.48/src/otsu.c +0 -289
  98. data/src/gocr-0.48/src/otsu.h +0 -23
  99. data/src/gocr-0.48/src/output.c +0 -289
  100. data/src/gocr-0.48/src/output.h +0 -37
  101. data/src/gocr-0.48/src/pcx.c +0 -153
  102. data/src/gocr-0.48/src/pcx.h +0 -9
  103. data/src/gocr-0.48/src/pgm2asc.c +0 -2893
  104. data/src/gocr-0.48/src/pgm2asc.h +0 -105
  105. data/src/gocr-0.48/src/pixel.c +0 -537
  106. data/src/gocr-0.48/src/pnm.c +0 -533
  107. data/src/gocr-0.48/src/pnm.h +0 -35
  108. data/src/gocr-0.48/src/progress.c +0 -87
  109. data/src/gocr-0.48/src/progress.h +0 -42
  110. data/src/gocr-0.48/src/remove.c +0 -703
  111. data/src/gocr-0.48/src/tga.c +0 -87
  112. data/src/gocr-0.48/src/tga.h +0 -6
  113. data/src/gocr-0.48/src/unicode.c +0 -1314
  114. data/src/gocr-0.48/src/unicode.h +0 -1257
  115. data/src/jpeg-7/Makefile.am +0 -133
  116. data/src/jpeg-7/Makefile.in +0 -1089
  117. data/src/jpeg-7/README +0 -322
  118. data/src/jpeg-7/aclocal.m4 +0 -8990
  119. data/src/jpeg-7/ansi2knr.1 +0 -36
  120. data/src/jpeg-7/ansi2knr.c +0 -739
  121. data/src/jpeg-7/cderror.h +0 -132
  122. data/src/jpeg-7/cdjpeg.c +0 -181
  123. data/src/jpeg-7/cdjpeg.h +0 -187
  124. data/src/jpeg-7/change.log +0 -270
  125. data/src/jpeg-7/cjpeg.1 +0 -325
  126. data/src/jpeg-7/cjpeg.c +0 -616
  127. data/src/jpeg-7/ckconfig.c +0 -402
  128. data/src/jpeg-7/coderules.txt +0 -118
  129. data/src/jpeg-7/config.guess +0 -1561
  130. data/src/jpeg-7/config.sub +0 -1686
  131. data/src/jpeg-7/configure +0 -17139
  132. data/src/jpeg-7/configure.ac +0 -317
  133. data/src/jpeg-7/depcomp +0 -630
  134. data/src/jpeg-7/djpeg.1 +0 -251
  135. data/src/jpeg-7/djpeg.c +0 -617
  136. data/src/jpeg-7/example.c +0 -433
  137. data/src/jpeg-7/filelist.txt +0 -215
  138. data/src/jpeg-7/install-sh +0 -520
  139. data/src/jpeg-7/install.txt +0 -1097
  140. data/src/jpeg-7/jaricom.c +0 -148
  141. data/src/jpeg-7/jcapimin.c +0 -282
  142. data/src/jpeg-7/jcapistd.c +0 -161
  143. data/src/jpeg-7/jcarith.c +0 -921
  144. data/src/jpeg-7/jccoefct.c +0 -453
  145. data/src/jpeg-7/jccolor.c +0 -459
  146. data/src/jpeg-7/jcdctmgr.c +0 -482
  147. data/src/jpeg-7/jchuff.c +0 -1612
  148. data/src/jpeg-7/jcinit.c +0 -65
  149. data/src/jpeg-7/jcmainct.c +0 -293
  150. data/src/jpeg-7/jcmarker.c +0 -667
  151. data/src/jpeg-7/jcmaster.c +0 -770
  152. data/src/jpeg-7/jcomapi.c +0 -106
  153. data/src/jpeg-7/jconfig.bcc +0 -48
  154. data/src/jpeg-7/jconfig.cfg +0 -45
  155. data/src/jpeg-7/jconfig.dj +0 -38
  156. data/src/jpeg-7/jconfig.mac +0 -43
  157. data/src/jpeg-7/jconfig.manx +0 -43
  158. data/src/jpeg-7/jconfig.mc6 +0 -52
  159. data/src/jpeg-7/jconfig.sas +0 -43
  160. data/src/jpeg-7/jconfig.st +0 -42
  161. data/src/jpeg-7/jconfig.txt +0 -155
  162. data/src/jpeg-7/jconfig.vc +0 -45
  163. data/src/jpeg-7/jconfig.vms +0 -37
  164. data/src/jpeg-7/jconfig.wat +0 -38
  165. data/src/jpeg-7/jcparam.c +0 -632
  166. data/src/jpeg-7/jcprepct.c +0 -358
  167. data/src/jpeg-7/jcsample.c +0 -545
  168. data/src/jpeg-7/jctrans.c +0 -381
  169. data/src/jpeg-7/jdapimin.c +0 -396
  170. data/src/jpeg-7/jdapistd.c +0 -275
  171. data/src/jpeg-7/jdarith.c +0 -762
  172. data/src/jpeg-7/jdatadst.c +0 -151
  173. data/src/jpeg-7/jdatasrc.c +0 -212
  174. data/src/jpeg-7/jdcoefct.c +0 -736
  175. data/src/jpeg-7/jdcolor.c +0 -396
  176. data/src/jpeg-7/jdct.h +0 -393
  177. data/src/jpeg-7/jddctmgr.c +0 -382
  178. data/src/jpeg-7/jdhuff.c +0 -1309
  179. data/src/jpeg-7/jdinput.c +0 -384
  180. data/src/jpeg-7/jdmainct.c +0 -512
  181. data/src/jpeg-7/jdmarker.c +0 -1360
  182. data/src/jpeg-7/jdmaster.c +0 -663
  183. data/src/jpeg-7/jdmerge.c +0 -400
  184. data/src/jpeg-7/jdpostct.c +0 -290
  185. data/src/jpeg-7/jdsample.c +0 -361
  186. data/src/jpeg-7/jdtrans.c +0 -136
  187. data/src/jpeg-7/jerror.c +0 -252
  188. data/src/jpeg-7/jerror.h +0 -304
  189. data/src/jpeg-7/jfdctflt.c +0 -174
  190. data/src/jpeg-7/jfdctfst.c +0 -230
  191. data/src/jpeg-7/jfdctint.c +0 -4348
  192. data/src/jpeg-7/jidctflt.c +0 -242
  193. data/src/jpeg-7/jidctfst.c +0 -368
  194. data/src/jpeg-7/jidctint.c +0 -5137
  195. data/src/jpeg-7/jinclude.h +0 -91
  196. data/src/jpeg-7/jmemansi.c +0 -167
  197. data/src/jpeg-7/jmemdos.c +0 -638
  198. data/src/jpeg-7/jmemdosa.asm +0 -379
  199. data/src/jpeg-7/jmemmac.c +0 -289
  200. data/src/jpeg-7/jmemmgr.c +0 -1118
  201. data/src/jpeg-7/jmemname.c +0 -276
  202. data/src/jpeg-7/jmemnobs.c +0 -109
  203. data/src/jpeg-7/jmemsys.h +0 -198
  204. data/src/jpeg-7/jmorecfg.h +0 -369
  205. data/src/jpeg-7/jpegint.h +0 -395
  206. data/src/jpeg-7/jpeglib.h +0 -1135
  207. data/src/jpeg-7/jpegtran.1 +0 -272
  208. data/src/jpeg-7/jpegtran.c +0 -546
  209. data/src/jpeg-7/jquant1.c +0 -856
  210. data/src/jpeg-7/jquant2.c +0 -1310
  211. data/src/jpeg-7/jutils.c +0 -179
  212. data/src/jpeg-7/jversion.h +0 -14
  213. data/src/jpeg-7/libjpeg.map +0 -4
  214. data/src/jpeg-7/libjpeg.txt +0 -3067
  215. data/src/jpeg-7/ltmain.sh +0 -8406
  216. data/src/jpeg-7/makcjpeg.st +0 -36
  217. data/src/jpeg-7/makdjpeg.st +0 -36
  218. data/src/jpeg-7/makeadsw.vc6 +0 -77
  219. data/src/jpeg-7/makeasln.vc9 +0 -33
  220. data/src/jpeg-7/makecdep.vc6 +0 -82
  221. data/src/jpeg-7/makecdsp.vc6 +0 -130
  222. data/src/jpeg-7/makecmak.vc6 +0 -159
  223. data/src/jpeg-7/makecvcp.vc9 +0 -186
  224. data/src/jpeg-7/makeddep.vc6 +0 -82
  225. data/src/jpeg-7/makeddsp.vc6 +0 -130
  226. data/src/jpeg-7/makedmak.vc6 +0 -159
  227. data/src/jpeg-7/makedvcp.vc9 +0 -186
  228. data/src/jpeg-7/makefile.ansi +0 -220
  229. data/src/jpeg-7/makefile.bcc +0 -291
  230. data/src/jpeg-7/makefile.dj +0 -226
  231. data/src/jpeg-7/makefile.manx +0 -220
  232. data/src/jpeg-7/makefile.mc6 +0 -255
  233. data/src/jpeg-7/makefile.mms +0 -224
  234. data/src/jpeg-7/makefile.sas +0 -258
  235. data/src/jpeg-7/makefile.unix +0 -234
  236. data/src/jpeg-7/makefile.vc +0 -217
  237. data/src/jpeg-7/makefile.vms +0 -142
  238. data/src/jpeg-7/makefile.wat +0 -239
  239. data/src/jpeg-7/makejdep.vc6 +0 -423
  240. data/src/jpeg-7/makejdsp.vc6 +0 -285
  241. data/src/jpeg-7/makejdsw.vc6 +0 -29
  242. data/src/jpeg-7/makejmak.vc6 +0 -425
  243. data/src/jpeg-7/makejsln.vc9 +0 -17
  244. data/src/jpeg-7/makejvcp.vc9 +0 -328
  245. data/src/jpeg-7/makeproj.mac +0 -213
  246. data/src/jpeg-7/makerdep.vc6 +0 -6
  247. data/src/jpeg-7/makerdsp.vc6 +0 -78
  248. data/src/jpeg-7/makermak.vc6 +0 -110
  249. data/src/jpeg-7/makervcp.vc9 +0 -133
  250. data/src/jpeg-7/maketdep.vc6 +0 -43
  251. data/src/jpeg-7/maketdsp.vc6 +0 -122
  252. data/src/jpeg-7/maketmak.vc6 +0 -131
  253. data/src/jpeg-7/maketvcp.vc9 +0 -178
  254. data/src/jpeg-7/makewdep.vc6 +0 -6
  255. data/src/jpeg-7/makewdsp.vc6 +0 -78
  256. data/src/jpeg-7/makewmak.vc6 +0 -110
  257. data/src/jpeg-7/makewvcp.vc9 +0 -133
  258. data/src/jpeg-7/makljpeg.st +0 -68
  259. data/src/jpeg-7/maktjpeg.st +0 -30
  260. data/src/jpeg-7/makvms.opt +0 -4
  261. data/src/jpeg-7/missing +0 -376
  262. data/src/jpeg-7/rdbmp.c +0 -439
  263. data/src/jpeg-7/rdcolmap.c +0 -253
  264. data/src/jpeg-7/rdgif.c +0 -38
  265. data/src/jpeg-7/rdjpgcom.1 +0 -63
  266. data/src/jpeg-7/rdjpgcom.c +0 -515
  267. data/src/jpeg-7/rdppm.c +0 -459
  268. data/src/jpeg-7/rdrle.c +0 -387
  269. data/src/jpeg-7/rdswitch.c +0 -365
  270. data/src/jpeg-7/rdtarga.c +0 -500
  271. data/src/jpeg-7/structure.txt +0 -945
  272. data/src/jpeg-7/testimg.bmp +0 -0
  273. data/src/jpeg-7/testimg.jpg +0 -0
  274. data/src/jpeg-7/testimg.ppm +0 -4
  275. data/src/jpeg-7/testimgp.jpg +0 -0
  276. data/src/jpeg-7/testorig.jpg +0 -0
  277. data/src/jpeg-7/testprog.jpg +0 -0
  278. data/src/jpeg-7/transupp.c +0 -1533
  279. data/src/jpeg-7/transupp.h +0 -205
  280. data/src/jpeg-7/usage.txt +0 -605
  281. data/src/jpeg-7/wizard.txt +0 -211
  282. data/src/jpeg-7/wrbmp.c +0 -442
  283. data/src/jpeg-7/wrgif.c +0 -399
  284. data/src/jpeg-7/wrjpgcom.1 +0 -103
  285. data/src/jpeg-7/wrjpgcom.c +0 -583
  286. data/src/jpeg-7/wrppm.c +0 -269
  287. data/src/jpeg-7/wrrle.c +0 -305
  288. data/src/jpeg-7/wrtarga.c +0 -253
@@ -1,63 +0,0 @@
1
- #ifndef _OCR0_H
2
- #define _OCR0_H
3
- #include "pgm2asc.h"
4
-
5
- /* ----------------------------------------------------------------
6
- - functions with thousand of lines make the compilation very slow
7
- therefore the ocr0-function is splitted in subfunctions
8
- - shared data used often in ocr0-subroutines are stored
9
- in ocr0_shared structure.
10
- * ------------------------------------------------------------ */
11
-
12
- typedef struct ocr0_shared { /* shared variables and properties */
13
-
14
- struct box *box1; /* box in whole image */
15
- pix *bp; /* extracted temporarly box, cleaned */
16
- int cs; /* global threshold value (gray level) */
17
-
18
- /* ToDo: or MACROS: X0 = box1->x0 */
19
- int x0, x1, y0, y1; /* box coordinates related to box1 */
20
- int dx, dy; /* size of box */
21
- int hchar, gchar; /* relation to m1..m4 */
22
- int aa[4][4]; /* corner points, see xX (x,y,dist^2,vector_idx) v0.41 */
23
- holes_t holes; /* list of holes (max MAX_HOLES) */
24
-
25
- } ocr0_shared_t;
26
-
27
- /* tests for umlaut */
28
- int testumlaut(struct box *box1, int cs, int m, wchar_t *modifier);
29
- /* detect chars */
30
- wchar_t ocr0(struct box *box1, pix *b, int cs);
31
- /* detect numbers */
32
- wchar_t ocr0n(ocr0_shared_t *sdata);
33
-
34
- static inline int sq(int x) { return x*x; } /* square */
35
-
36
- /*
37
- * go from vector j1 to vector j2 and measure maximum deviation of
38
- * the steps from the line connecting j1 and j2
39
- * return the squared maximum distance
40
- * in units of the box size times 1024
41
- */
42
- int line_deviation( struct box *box1, int j1, int j2 );
43
-
44
- /*
45
- * search vectors between j1 and j2 for nearest point a to point r
46
- * example:
47
- *
48
- * r-> $$...$$ $ - mark vectors
49
- * @@$..@@ @ - black pixels
50
- * @@$..@@ . - white pixels
51
- * @@@@.$@
52
- * a-> @@$@$@@
53
- * @$.@@@@
54
- * @@..$@@
55
- * @@..$@@
56
- * j1 --> $$...$$ <-- j2
57
- *
58
- * ToDo: vector aa[5] = {rx,ry,x,y,d^2,idx} statt rx,ry?
59
- * j1 and j2 must be in the same frame
60
- * return aa?
61
- */
62
- int nearest_frame_vector( struct box *box1, int j1, int j2, int rx, int ry);
63
- #endif
@@ -1,1475 +0,0 @@
1
- /* ocr-engine numbers only */
2
- /*
3
- This is a Optical-Character-Recognition program
4
- Copyright (C) 2000-2009 Joerg Schulenburg
5
-
6
- This program is free software; you can redistribute it and/or
7
- modify it under the terms of the GNU General Public License
8
- as published by the Free Software Foundation; either version 2
9
- of the License, or (at your option) any later version.
10
-
11
- This program is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with this program; if not, write to the Free Software
18
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
-
20
- see README for EMAIL-address
21
-
22
- OCR engine (c) Joerg Schulenburg
23
- first engine: rule based --- numbers 0..9
24
-
25
- */
26
-
27
- #include <stdlib.h>
28
- #include <stdio.h>
29
- /* #include "pgm2asc.h" */
30
- #include "ocr0.h"
31
- #include "ocr1.h"
32
- #include "amiga.h"
33
- #include "pnm.h"
34
- #include "gocr.h"
35
-
36
- /* only for debugging and development */
37
- #define IFV if(JOB->cfg.verbose&4)
38
- #define MM {IFV fprintf(stderr,"\nDBG %c L%04d (%d,%d): ",(char)c_ask,__LINE__,box1->x0,box1->y0);}
39
-
40
- /* the old debug mode (0.40) was only for a special char, for another char
41
- * code must be recompiled with C_ASK='char'
42
- * new debug mode (0.41) explains why char is declined or accepted as ABC...
43
- * the output can be filtered by external scripts
44
- * ToDo: we could reduce output to filter string
45
- */
46
- #ifndef DO_DEBUG /* can be defined outside */
47
- #define DO_DEBUG 0 /* 0 is the default */
48
- #endif
49
-
50
- /* this macro is for debugging output: "if char is declined, why?" */
51
- #if DO_DEBUG /* 0=Work mode, 1=debugging mode */
52
- // Setac: output, that char is choosen with a probability
53
- // Break: output, why the char is not choosen
54
- // MSG: debugging functions for char C_ASK, mostly messages
55
- // DBG: definitions usefull only for debugging
56
- #define Setac(box1,ac,ad) { MM;IFV fprintf(stderr,"setac %d",ad);setac(box1,ac,ad); }
57
- #define Break { MM;IFV fprintf(stderr,"break"); break; }
58
- #define MSG(x) { MM;IFV x }
59
- #define DBG(x) x
60
- #else
61
- #define Setac(box1,ac,ad) setac(box1,ac,ad)
62
- #define Break break
63
- #define MSG(x)
64
- #define DBG(x)
65
- #endif
66
-
67
- /* extern "C"{ */
68
-
69
- // OCR engine ;)
70
- wchar_t ocr0n(ocr0_shared_t *sdata){
71
- struct box *box1=sdata->box1;
72
- pix *bp=sdata->bp;
73
- int d,x,y,x0=box1->x0,x1=box1->x1,y0=box1->y0,y1=box1->y1;
74
- int dx=x1-x0+1,dy=y1-y0+1,cs=sdata->cs; // size
75
- int xa,xb,ya,yb, /* tmp-vars */
76
- i1,i2,i3,i4,i,j;
77
- int (*aa)[4]=sdata->aa; /* corner-points, (x,y,dist^2,vector_idx) */
78
- wchar_t bc=UNKNOWN; // best char
79
- int ad=0; // propability 0..100
80
- int hchar=sdata->hchar; // char is higher than 'e'
81
- int gchar=sdata->gchar; // char has ink lower than m3
82
- int dots=box1->dots;
83
- // --- test 5 near S ---------------------------------------------------
84
- for(ad=d=100;dx>2 && dy>4;){ // min 3x4
85
- DBG( char c_ask='5'; )
86
- if (sdata->holes.num > 1) Break; /* be tolerant */
87
- if( num_cross( dx/2, dx/2,0,dy-1,bp,cs)!=3
88
- && num_cross(5*dx/8,3*dx/8,0,dy-1,bp,cs)!=3 ) Break;
89
-
90
- i1=loop(bp,dx-1,dy-1,dx,cs,0,LE);
91
- i2=loop(bp,dx-1,dy-2,dx,cs,0,LE);
92
- if (i2-i1 >= dx/4) Break; // ~{ 5x7font
93
-
94
- // get the upper and lower hole koords, y around dy/4 ???
95
- x=5*dx/8;
96
- y =loop(bp,x,0,dy,cs,0,DO); if(y>dy/8) Break;
97
- y +=loop(bp,x,y,dy,cs,1,DO); if(y>dy/4) Break;
98
- i1 =loop(bp,x,y,dy,cs,0,DO)+y; if(i1>5*dy/8) Break;
99
- i3=y=(y+i1)/2; // upper end can be shifted to the right for italic
100
- x =loop(bp,0,y,dx,cs,0,RI); if(x>4*dx/8) Break;
101
- x +=loop(bp,x,y,dx,cs,1,RI); if(x>5*dx/8) Break;
102
- i1 =loop(bp,x,y,dx,cs,0,RI); i1=(i1+2*x)/2; // upper center (i1,i3)
103
- y=11*dy/16;
104
- x =loop(bp,dx-1 ,y,dx,cs,0,LE); if(x>dx/4) Break;
105
- x +=loop(bp,dx-1-x,y,dx,cs,1,LE); if(x>dx/2) Break;
106
- i2 =loop(bp,dx-1-x,y,dx,cs,0,LE); i2=dx-1-(i2+2*x)/2; // lower center x
107
-
108
- MSG( fprintf(stderr,"i1,i3=%d,%d i2=%d (upper+lower center)",i1,i3,i2);)
109
-
110
- y =loop(bp,i1,0,dy,cs,0,DO);
111
- y +=loop(bp,i1,y,dy,cs,1,DO);
112
- y =(3*y+i3)/4;
113
- if( num_cross( i1, dx-1, y, y,bp,cs)>0 ){ /* S or serif5 ? */
114
- y =loop(bp,i1 ,i3,dy,cs,0,DO);
115
- i =loop(bp,i1-1,i3,dy,cs,0,DO);
116
- if (y>i ) ad=99*ad/100; /* looks like S */
117
- y =loop(bp,i1 ,i3,dy,cs,0,UP);
118
- i =loop(bp,i1+1,i3,dy,cs,0,UP);
119
- if (i<y ) ad=99*ad/100; /* looks like S */
120
- x =loop(bp,dx-1,0,dx,cs,0,LE);
121
- i =loop(bp,dx-1,1,dx,cs,0,LE);
122
- if (x>i ) ad=99*ad/100; /* looks like S */
123
- if( num_cross( 0, dx/2, dy-1, dy-1,bp,cs)>1
124
- && num_cross( dx/2,dx-1, 0, 0,bp,cs)>1 ) ad=98*ad/100; /* serifs */
125
- if (loop(bp,0,dy-1,dx,cs,0,RI)==0) ad=98*ad/100; /* S or 7segment */
126
- ad=99*ad/100;
127
- }
128
-
129
- for(y=dy/5;y<3*dy/4;y++) // right gap?
130
- if( num_cross(i1,dx-1,y,y,bp,cs)==0 ) break;
131
- if( y==3*dy/4 ) Break;
132
-
133
- for(y=dy/4;y<=11*dy/16;y++) // left gap?
134
- if( num_cross(0,i2,y,y,bp,cs)==0 ) break;
135
- if( y>11*dy/16 ) Break;
136
-
137
- // if( num_hole( x0, x1, y0, y1, box1->p,cs,NULL) > 0 ) break;
138
- if (sdata->holes.num>0) Break;
139
-
140
- // sS5 \sl z left upper v-bow ?
141
- for(x=dx,i=y=dy/4;y<dy/2;y++){
142
- j=loop(bp,0,y,dx,cs,0,RI); if(j<x) { x=j; i=y; }
143
- } y=i;
144
- i1=loop(bp,0, dy/16 ,dx,cs,0,RI);
145
- i2=loop(bp,0,(y+dy/16)/2 ,dx,cs,0,RI);
146
- i =loop(bp,0,(y+dy/16)/2+1,dx,cs,0,RI); if( i>i2 ) i2=i;
147
- i3=loop(bp,0, y ,dx,cs,0,RI);
148
- i =loop(bp,0, y-1,dx,cs,0,RI); if( i<i3 ) i3=i;
149
- if( 2*i2+1+dx/16 < i1+i3 ) Break;
150
-
151
- if( dy>=20 && dx<16 ) /* tall S */
152
- if( loop(bp,0, dy/5 ,dx,cs,0,RI)
153
- ==loop(bp,0, dy/4 ,dx,cs,0,RI)
154
- &&
155
- loop(bp,0, dy/10 ,dx,cs,0,RI)
156
- >loop(bp,0, dy/4 ,dx,cs,0,RI)
157
- &&
158
- loop(bp,0, 1 ,dx,cs,0,RI)
159
- >loop(bp,0, dy/4 ,dx,cs,0,RI)+1
160
- &&
161
- loop(bp,dx-1, 0 ,dx,cs,0,LE)
162
- >loop(bp,dx-1, 1 ,dx,cs,0,LE) ) Break;
163
-
164
- if( dy>=30 && dx>15 ) /* large S */
165
- if( loop(bp,dx/4,3*dy/10,dy,cs,1,DO)>0 ) // check start
166
- if( loop(bp,dx-2,3*dy/4 ,dy,cs,1,UP)>0 ) // check end
167
- if( num_cross(dx/4,dx-2,3*dy/10,3*dy/4,bp,cs)==1 ) Break; // connected?
168
- MSG(fprintf(stderr,"~S ad=%d",ad);)
169
-
170
- // small fat s is very similar to rounded serif 5
171
- // but has a fat diagonal arrea (Oct08 JS)
172
- if ( num_cross(dx/8,dx-1-dx/8,3*dy/10,3*dy/4,bp,cs)==1 ) ad=98*ad/100;
173
- MSG(fprintf(stderr,"~S ad=%d",ad);)
174
-
175
- if( dy>17 && dx>9 ) /* S */
176
- if( loop(bp, 0,dy/2 ,dx,cs,0,RI)<dx/2
177
- || loop(bp, 0,dy/2-1 ,dx,cs,0,RI)<dx/2 )
178
- if( loop(bp,dx/4,3*dy/10,dy,cs,1,DO)>0 ) // check start
179
- if( loop(bp,dx-2,2*dy/3 ,dy,cs,1,UP)>0 ) // check end
180
- if( loop(bp, 0, dy/16,dx,cs,0,RI)
181
- >= loop(bp,dx-1, dy-1-dy/16,dx,cs,0,LE) ) ad=ad*98/100;
182
- MSG(fprintf(stderr,"~S ad=%d",ad);)
183
- if( loop(bp,3*dx/4 , 0,dy,cs,1,DO) // ToDo: improve!
184
- < loop(bp, dx/4 ,dy-1,dy,cs,1,UP)
185
- && loop(bp,3*dx/4-1, 0,dy,cs,0,DO)
186
- < loop(bp, dx/4+1,dy-1,dy,cs,0,UP) ) ad=ad*98/100;
187
- MSG(fprintf(stderr,"~S ad=%d",ad);)
188
-
189
- if ( gchar) ad=99*ad/100;
190
- if (!hchar) ad=99*ad/100;
191
- Setac(box1,(wchar_t)'5',ad);
192
- if (ad==100) return '5';
193
- break;
194
-
195
- }
196
- // --- test 1 ---------------------------------------------------
197
- for(ad=d=100;dy>4 && dy>dx && 2*dy>box1->m3-box1->m2;){ // min 3x4
198
- DBG( char c_ask='1'; )
199
- if( dots==1 ) Break;
200
- if (sdata->holes.num > 1) Break; /* be tolerant */
201
-
202
- if( num_cross(0, dx-1, 0 , 0 ,bp,cs) != 1
203
- && num_cross(0, dx-1, 1 , 1 ,bp,cs) != 1 ) Break;
204
- if( num_cross(0, dx-1,dy/2,dy/2,bp,cs) != 1 ) Break;
205
- if( num_cross(0, dx-1,dy-1,dy-1,bp,cs) != 1
206
- && num_cross(0, dx-1,dy-2,dy-2,bp,cs) != 1 ) Break;
207
- /* 5x7 micr ocr-a
208
-
209
- ooo @@@..
210
- .$. ooo ..@..
211
- $@. oo ..@..
212
- .$. oo ..@..
213
- .@. ooooo ..@.@
214
- .$. ooooo ..@.@
215
- $@$ ooooo @@@@@
216
-
217
- */
218
- i4=0; // human font
219
- if( num_cross(0, dx-1,3*dy/4,3*dy/4,bp,cs) != 2 ) { // except ocr-a
220
- for( y=1; y<dy/2; y++ ){
221
- if( num_cross(0, dx-1, y , y ,bp,cs) == 2 ) break;
222
- } if (y>=dy/2) ad=98*ad/100;
223
- for( i=dy/8,y=7*dy/16;y<dy-1 && i;y++ ){
224
- if( num_cross(0, dx-1, y , y ,bp,cs) != 1 ) i--;
225
- } if( dy>8 && !i ) Break;
226
- } else { // ocr-a-1
227
- i= loop(bp,dx/2,0,dy,cs,0,DO);
228
- if (loop(bp,dx/2,i,dy,cs,1,DO)<dy-1) Break;
229
- i= loop(bp,dx -1,dy-1-dy/16,dx,cs,0,LE);
230
- if (loop(bp,dx-i-1,dy-1-dy/16,dx,cs,1,LE)<dx-1) Break;
231
- i= loop(bp,0,dy/16,dx,cs,0,RI);
232
- if (loop(bp,i,dy/16,dx,cs,1,RI)<dx/2) Break;
233
- i4=1;
234
- MSG(fprintf(stderr,"ocr-a-1 detected ad= %d", ad);)
235
- }
236
-
237
- if( num_cross(0, dx-1, 0 , 0 ,bp,cs) > 1
238
- && num_cross(0, dx-1, 1 , 1 ,bp,cs) > 1 ) Break; // ~/it_7
239
-
240
- // calculate upper and lower mass center (without lower serif)
241
-
242
- x =loop(bp,0,7*dy/8-1,dx,cs,0,RI); i2=x;
243
- x+=loop(bp,x,7*dy/8-1,dx,cs,1,RI)-1; i2=(i2+x)/2;
244
-
245
- i1=loop(bp,dx-1 ,1+0* dy/4,dx,cs,0,LE); i1=dx-1-i1-(x-i2)/2;
246
-
247
- x =(i1-i2+4)/8; i1+=x; i2-=x;
248
-
249
- if( get_line2(i1,0,i2,dy-1,bp,cs,100)<95 ) { // dont work for ocr-a-1
250
- i1=loop(bp,dx-1 ,1+0* dy/4,dx,cs,0,LE); i1=dx-1-i1;
251
- if( get_line2(i1,0,i2,dy-1,bp,cs,100)<95 ) Break;
252
- }
253
- // upper and lower width
254
- x =loop(bp,(i1+i2)/2,dy/2,dx,cs,1,RI); i=x; i3=0;
255
- for(y=0;y<7*dy/8;y++)
256
- if( loop(bp,i1+y*(i2-i1)/dy, y,dx,cs,1,RI)-i > 1+dx/8 ) break;
257
- if(y<7*dy/8) ad=98*ad/100; // serif or ocr-a-1 ?
258
- if(y<6*dy/8) ad=99*ad/100; /* MICR E-13B font Jan07 */
259
- if(y<4*dy/8) Break;
260
- MSG(fprintf(stderr,"i12 %d %d ad= %d", i1,i2,ad);)
261
- // out_x(box1); printf(" i12=%d %d\n",i1,i2);
262
- x =loop(bp,i2,dy-1,dx,cs,1,LE); j=x;
263
- x =loop(bp,i2,dy-2,dx,cs,1,LE); if(x>j)j=x; i=j;
264
- x =loop(bp,i2,dy-1,dx,cs,1,RI); j=x;
265
- x =loop(bp,i2,dy-2,dx,cs,1,RI); if(x>j)j=x;
266
- if(abs(i-j)>1+dx/8) i3|=1;
267
- if(i3) Break;
268
- // out_x(box1);printf(" 11 i=%d j=%d i2=%d dx=%d\n",i,j,i1,dx);
269
- // get most left upper point (i,j)
270
- for(i=dx,j=y=0;y<7*dy/16;y++){
271
- x =loop(bp,0,y,dx,cs,0,RI); if(x<i) { i=x;j=y; }
272
- }
273
- if ( i1-i<7*dx/16 ) ad=ad*98/100;
274
- if ( i1-i<6*dx/16 ) ad=ad*98/100; // 4*dx/8 => 7*dx/16 MICR E-13B font
275
- if ( i1-i<4*dx/16 ) Break;
276
- MSG(fprintf(stderr,"i12 %d %d ad= %d", i1,i2,ad);)
277
- x =loop(bp,0,dy/2,dx,cs,0,RI); // right distance
278
- j =loop(bp,x,dy/2,dx,cs,1,RI); // thickness
279
- if( j>x+(dy+16)/32 ) ad=98*ad/100; // ~l but MICR E-13B font
280
- x =loop(bp,0,0,dx,cs,0,RI); // straight line ???
281
- j =loop(bp,0,1,dx,cs,0,RI); if( j>x ) Break; // ~l
282
- if( x==j ) j =loop(bp,0,dy/8,dx,cs,0,RI); if( j>x && !i4) Break;
283
- if( x==j ) if(loop(bp,0,dy/4,dx,cs,0,RI)>x) { // ~l
284
- // check micr-1 first before taken as 'l'
285
- if (loop(bp,dx-1,dy/8,dx,cs,0,LE)<=dx/4
286
- && loop(bp, 0,3*dy/4,dx,cs,1,RI)< dx-1) ad=97*ad/100;
287
- }
288
- MSG(fprintf(stderr,"1l check ad= %d", ad);)
289
- x=j;
290
- // j =loop(bp,0,2,dx,cs,0,RI); if( j>=x ) Break; x=j; // ~l
291
- // j =loop(bp,0, 0,dx,cs,0,DO); if( !j ) Break; // ~7
292
- if( !hchar ) // ~ right part of n
293
- /* look for upper right side, not going from nw to se */
294
- if( loop(bp,dx-1, 1,dx,cs,0,LE)-dy/6
295
- > loop(bp,dx-1,dy/4,dx,cs,0,LE)
296
- // failes on small fonts with 1 point spaces between chars
297
- // also do not know what the purpose of this line was (JS Oct08)
298
- // || get_bw(x1+1,x1+2,y0,y0+dy/8,box1->p,cs,1)==1
299
- ) Break; // Mai00
300
- if( loop(bp,dx-1,3*dy/4,dx,cs,0,LE) > dx/2
301
- && get_bw(x1-dx/4,x1,y1-1,y1,box1->p,cs,1)==1 ) Break; // ~z Jun00
302
-
303
- i=loop(bp, dx/8,0,dy,cs,0,DO);
304
- for (y=dy,x=dx/2;x<3*dx/4;x++){ /* get upper end y */
305
- j=loop(bp,x,0,dy,cs,0,DO); if (j<y) { y=j; }
306
- }
307
- if(y<dy/2 && y+dy/16>=i) ad=98*ad/100; // ~\tt l ??? ocr-a_1
308
- MSG(fprintf(stderr,"1l check i= %d y= %d ad= %d", i, y, ad);)
309
-
310
- if( loop(bp, 0, dy/8,dx,cs,0,RI)
311
- -(dx-loop(bp,dx-1,7*dy/8,dx,cs,0,LE)) > dx/4 ) Break; // ~/
312
-
313
- i= loop(bp, 0, 0,dy,cs,0,DO); // horizontal line?
314
- if(dy>=12 && i>dy/8 && i<dy/2){
315
- if( loop(bp,dx-1,3*dy/16,dx,cs,0,LE)-dx/8
316
- >loop(bp,dx-1, i,dx,cs,0,LE)
317
- || loop(bp,dx-1,3*dy/16,dx,cs,0,LE)-dx/8
318
- >loop(bp,dx-1, i+1,dx,cs,0,LE) ) Break; // ~t,~f
319
- i= loop(bp, 0,dy-1-dy/32,dx,cs,0,RI);
320
- x= loop(bp, 0,dy-2-dy/32,dx,cs,0,RI); if (i<x) x=i;
321
- if( x-loop(bp, 0, 3*dy/4,dx,cs,0,RI)>dx/8
322
- && loop(bp,dx-1, 3*dy/4,dx,cs,0,LE)-dx/8
323
- >loop(bp,dx-1,dy-1-dy/32,dx,cs,0,LE) ) Break; // ~t
324
- if( loop(bp, 0,i-1,dx,cs,0,RI)>1 && dx<6) {
325
- ad=99*ad/100;
326
- if ( loop(bp,dx-1,i-1,dx,cs,0,LE)>1 ) Break; // ~t
327
- }
328
- }
329
-
330
- if (dx>8){
331
- if (loop(bp,0,3*dy/4,dx,cs,0,RI)-
332
- loop(bp,0,dy/2-1,dx,cs,0,RI)>dx/4) ad=95*ad/100; // ~3
333
- if (loop(bp,dx-1,dy/2-1,dx,cs,0,LE)-
334
- loop(bp,dx-1,3*dy/4,dx,cs,0,LE)>dx/8) ad=99*ad/100; // ~3 ocr-a?
335
- if (loop(bp,dx-1, dy/16,dx,cs,0,LE)-
336
- loop(bp,dx-1, dy/4,dx,cs,0,LE)>dx/8) ad=95*ad/100; // ~23
337
- MSG(fprintf(stderr,"23 check ad= %d", ad);)
338
- }
339
- /* font 5x9 "2" recognized as "1" */
340
- i=loop(bp,dx-1-dx/8,dy-1,dy,cs,0,UP);
341
- if (i<=dy/4) {
342
- i+=loop(bp,dx-1-dx/8,dy-1-i,dy,cs,1,UP);
343
- if (i<=dy/4) {
344
- i=loop(bp,dx-1-dx/8,dy-1-i,dy,cs,0,LE);
345
- if (2*i>=dx && loop(bp,dx/4,0,dy,cs,0,DO)<dy/2) {
346
- if (dx<17) ad=98*ad/100;
347
- if (dx<9) ad=97*ad/100;
348
- MSG(fprintf(stderr,"5x9 2 check ad= %d", ad);)
349
- }
350
- }
351
- }
352
-
353
- // looking for ###
354
- // ..# pattern (its important, we dont want perp. lines as 1)
355
- // ToDo: better check that we have exact one on top
356
- for (i2=0,i=dx,y=0;y<dy/2;y++) {
357
- j=loop(bp,0,y,dx,cs,0,RI); if (j<i) i=j;
358
- if (j>i+dx/8) { break; }
359
- } if (y>=dy/2) ad=95*ad/100; // Feb07 care plates, right black border
360
- MSG(fprintf(stderr,"ad= %d", ad);)
361
-
362
- if (sdata->holes.num > 0) Break; // mini holes should be filtered
363
- if (!box1->m3 && ad>98) ad=98; else {
364
- if (!hchar) ad=99*ad/100;
365
- if (box1->y0>box1->m2) ad=98*ad/100;
366
- if (box1->y1<(1*box1->m2+3*box1->m3)/4) ad=98*ad/100;
367
- if (box1->y1-box1->y0<(box1->m3-box1->m1)/2) ad=98*ad/100;
368
- if ( gchar) ad=99*ad/100;
369
- }
370
-
371
- Setac(box1,(wchar_t)'1',ad);
372
- break;
373
- }
374
- // --- test 2 old pixelbased - remove! -----------------------------
375
- #ifdef Old_pixel_based
376
- for(ad=d=100;dx>2 && dy>4;){ // min 3x4
377
- DBG( char c_ask='2'; )
378
- if (sdata->holes.num > 1) Break; /* be tolerant */
379
- if( get_bw(x0+dx/2, x0+dx/2 , y1-dy/5, y1 ,box1->p,cs,1) != 1 ) Break;
380
- if( get_bw(x0+dx/2, x0+dx/2 , y0 , y0+dy/5,box1->p,cs,1) != 1 ) Break;
381
- if( get_bw(x0+dx/8, x1-dx/3 , y1-dy/3, y1-dy/3,box1->p,cs,1) != 1 ) Break;
382
-
383
- if( get_bw(x1-dx/3, x1 , y0+dy/3 , y0+dy/3,box1->p,cs,1) != 1 ) Break;
384
- if( get_bw(x0 , x0+dx/ 8, y1-dy/16, y1 ,box1->p,cs,1) != 1 ) Break;
385
- if( num_cross(x0, x1-dx/8, y0+dy/2, y0+dy/2,box1->p,cs) != 1 ) Break;
386
- if( get_bw(x0, x0+dx/9 , y0 , y0 ,box1->p,cs,1) == 1
387
- && get_bw(x0, x0+dx/2 ,y0+3*dy/16,y0+3*dy/16,box1->p,cs,1) == 1 ) Break;
388
- if( get_bw(x0, x0+dx/9 , y0 , y0 ,box1->p,cs,1)
389
- != get_bw(x1-dx/9, x1 , y0 , y0 ,box1->p,cs,1) )
390
- { if (dx<6 && dy<9) ad=99*ad/100; else Break; }
391
- // out_x(box1);
392
-
393
- for( x=x0+dx/4;x<x1-dx/6;x++ ) // C
394
- if( num_cross( x, x, y0, y0+dy/2,box1->p,cs) == 2 ) break;
395
- if( x>=x1-dx/6 ) Break;
396
-
397
- for( x=x0+dx/4;x<x1-dx/6;x++ ) // C, but acr-a
398
- if( num_cross( x, x, y0+3*dy/8,y1,box1->p,cs) == 2 ) break;
399
- if( x>=x1-dx/6 ) Break;
400
-
401
- for(i=1,y=y0;y<y0+dy/2;y++ )
402
- if( num_cross( x0, x1, y, y,box1->p,cs) == 2 ) i=0;
403
- if( i ) ad=99*ad/100; // ToDo: ocr-a-2 should have 100%
404
-
405
- for(i=1,y=y0+dy/5;y<y0+3*dy/4;y++ )
406
- if( get_bw( x0, x0+dx/3, y, y,box1->p,cs,1) == 0 ) i=0;
407
- if( i ) Break;
408
-
409
- x=x1-dx/3,y=y1; /* center bottom */
410
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y1-dy/5 ) Break;
411
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,ST,UP); if( y<y1-dy/4 ) ad=99*ad/100;
412
- if( y<y1-dy/3 ) Break;
413
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y0+dy/3 ) Break; y++;
414
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,RI,ST);
415
- if( x<x1 ){ x--; // hmm thick font and serifs
416
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y0+dy/2 ) Break; y++;
417
- turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,RI,ST);
418
- if( x<x1 ) Break;
419
- }
420
-
421
- // test ob rechte Kante ansteigend
422
- for(x=0,y=dy/18;y<=dy/3;y++){ // rechts abfallende Kante/Rund?
423
- i=loop(box1->p,x1,y0+y,dx,cs,0,LE); // use p (not b) for broken chars
424
- if( i<x ) break; // rund
425
- if( i>x ) x=i;
426
- }
427
- if (y>dy/3 ) Break; // z
428
-
429
- // hole is only allowed in beauty fonts
430
- // if( num_hole( x0, x1, y0, y1,box1->p,cs,NULL) > 0 ) // there is no hole
431
- // if( num_hole( x0, x0+dx/2, y0, y0+dy/2,box1->p,cs,NULL) == 0 ) // except in some beauty fonts
432
- if (sdata->holes.num>0)
433
- if (sdata->holes.hole[0].x1 >= dx/2 || sdata->holes.hole[0].y1 >= dy/2)
434
- Break;
435
-
436
- if (loop(bp,dx-1, 0,dx,cs,0,LE)
437
- <loop(bp,dx-1,dy/4,dx,cs,0,LE)-dx/8) Break; // 5x7,5x8 z Jul09
438
- i1=loop(bp,dx-1-dx/16,0,dy,cs,0,DO); // Jul00
439
- i2=loop(bp, dx/ 2,0,dy,cs,0,DO); if( i2+dy/32>=i1 ) Break; // ~z
440
- i1=loop(bp,dx-1,dy-3*dy/16,dx,cs,0,LE);
441
- i2=loop(bp, 0,dy-3*dy/16,dx,cs,0,RI); if( i2>i1 ) ad=98*ad/100; // ~i
442
- if (dots) ad=98*ad/100; // i
443
- if (loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/4) ad=96*ad/100; // \it i
444
-
445
- if ((!hchar) && box1->m4!=0) ad=80*ad/100;
446
- Setac(box1,(wchar_t)'2',ad);
447
- if (ad==100) return '2';
448
- break;
449
- }
450
- #endif
451
- // --- test 2 new edge based v0.44 --------------------------------------
452
- for(ad=d=100;dx>2 && dy>4;){ // min 3x4
453
- // rewritten for vectors 0.42
454
- int ld, i1, i2, i3, i4, i5, i6, i7; // line derivation + corners
455
- DBG( wchar_t c_ask='2'; )
456
- if (sdata->holes.num > 0) Break; /* no hole */
457
- /* half distance to the center */
458
- d=2*sq(128/4);
459
- /* now we check for the lower ends, must be near to the corner */
460
- if (aa[1][2]>d/4) Break; /* [2] = distance, ~7... */
461
- if (aa[2][2]>d/2) Break; /* [2] = distance, ~r... */
462
- if (aa[0][2]>d/1) Break; /* [2] = distance, ~d... */
463
- if (aa[3][2]>d/1) Break; /* [2] = distance, ~bhk... */
464
- /* searching for 4 notches between neighbouring ends */
465
-
466
- /*
467
- type A B
468
-
469
- 1OOO OO
470
- 2 1 2 <- 6
471
- 7-> OOOO O
472
- O O <- 5
473
- 3OO4 3OO4
474
- */
475
-
476
- // ToDo: replace by vector code (get point on line at dy/4)
477
- if (loop(bp,dx-1, 0,dx,cs,0,LE)
478
- <loop(bp,dx-1,dy/4,dx,cs,0,LE)-dx/8) Break; // 5x7,5x8 z Jul09
479
-
480
- /* get a point on the inner low left side of the J */
481
- i =box1->num_frame_vectors[0] - 1;
482
- /* rightmost point on upper left side */
483
- i2=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1+dx, y0+dy/4);
484
- /* upper leftmost vector */
485
- i1=nearest_frame_vector(box1, aa[0][3], i2, x0-dx, (y0+y1)/2);
486
- i3=aa[1][3];
487
- /* low leftmost vector */
488
- i5=nearest_frame_vector(box1, aa[2][3], aa[3][3], x0, y1);
489
- /* low mostright vector */
490
- i4=nearest_frame_vector(box1, aa[1][3], i5, x1+dx, y1);
491
- /* next local max_x-point after i5 */
492
- i6=i5;
493
- for (i=i5;i!=aa[0][3];i=(i+1)%box1->num_frame_vectors[0]) {
494
- if (box1->frame_vector[ i][0]
495
- >box1->frame_vector[i6][0]) i6=i; // get next maximum
496
- if (box1->frame_vector[ i][0]<x0+dx/3
497
- && box1->frame_vector[ i][1]<y0+dy/3
498
- && box1->frame_vector[i6][0]>x0+dx/2) break; // 5
499
- }
500
- /* which type? ToDo: have a more sure algorithm */
501
- i7=nearest_frame_vector(box1, i2, i3, x0-dx/8, (y0+y1)/2);
502
- if (box1->frame_vector[i7][0]<=x0+ dx/4
503
- && box1->frame_vector[i7][1]<=y0+2*dy/3) {
504
- MSG(fprintf(stderr,"7-segment-type");)
505
- } else { /* regular-book-type */
506
- MSG( fprintf(stderr,"upper bow not z-like? ad %d", ad); )
507
- if (aa[3][0]>=x1-dx/8 // x of upper right point
508
- && aa[3][1]< y0+dy/8) ad=99*ad/100; // y of upper right point
509
- if (aa[0][0]<=x0+dx/8 // x of upper left point
510
- && aa[0][1]< y0+dy/8) ad=99*ad/100; // y of upper left point
511
- if (aa[3][2]<=aa[1][2]) ad=97*ad/100; // dist to (maxx,0) <= (0,maxy)
512
- }
513
- // ToDo: output no=(x,y)
514
- MSG( fprintf(stderr,"i1-7 %d %d %d %d %d %d %d ad %d",
515
- i1,i2,i3,i4,i5,i6,i7,ad); )
516
- if (i5==i6) Break; // ~+
517
-
518
- if (box1->frame_vector[i5][1]
519
- -box1->frame_vector[i6][1]<dy/4) Break; // ~5
520
- if (box1->frame_vector[i1][1]>y0+dy/2) Break; // not to low
521
- if (box1->frame_vector[i1][0]>x0+dx/8+dx/16) Break; // slanted ?
522
- if (box1->frame_vector[i2][1]>(y0+ y1)/2) Break;
523
- if (box1->frame_vector[i2][1]>(5*y0+3*y1)/8) ad=99*ad/100;
524
- MSG( fprintf(stderr,"ad %d", ad); )
525
- if (box1->frame_vector[i2][0]<(x0+x1+1)/2) Break; // fat tiny fonts?
526
- if (box1->frame_vector[i2][0]<(x0+2*x1)/3) ad=99*ad/100;
527
- MSG( fprintf(stderr,"ad %d", ad); )
528
- if (box1->frame_vector[i3][0]>(3*x0+x1)/4) Break;
529
- if (box1->frame_vector[i3][0]>(7*x0+x1)/8) ad=99*ad/100;
530
- MSG( fprintf(stderr,"ad %d", ad); )
531
- /* check lowest left point */
532
- if (box1->frame_vector[i3][1]<(y0+3*y1)/4) Break;
533
- if (box1->frame_vector[i3][1]<(y0+7*y1)/8) ad=99*ad/100;
534
- MSG( fprintf(stderr,"ad %d", ad); )
535
- /* check lower leftmost point from right side */
536
- if (box1->frame_vector[i5][0]>(x0+2*x1)/3) Break;
537
- if (box1->frame_vector[i5][0]>(x0+ x1)/2) ad=98*ad/100;
538
- if (box1->frame_vector[i5][0]>(2*x0+2+x1)/3) ad=99*ad/100; /* 9x10 2 */
539
- MSG( fprintf(stderr,"ad %d", ad); )
540
- if (box1->frame_vector[i5][1]<(3*y0+5*y1)/8) Break;
541
- if (box1->frame_vector[i5][1]<(y0+3*y1)/4) ad=99*ad/100;
542
- MSG( fprintf(stderr,"ad %d", ad); )
543
- if (box1->frame_vector[i6][1]>(y0+2*y1)/3) Break;
544
- if (box1->frame_vector[i6][1]>(y0+ y1)/2) ad=99*ad/100;
545
- MSG( fprintf(stderr,"ad %d", ad); )
546
- if (box1->frame_vector[i6][0]<(x0+3*x1)/4) Break;
547
- if (box1->frame_vector[i6][0]<(x0+7*x1)/8) ad=99*ad/100;
548
-
549
- /* check for zZ */
550
-
551
- /* check if lower left and right points are joined directly */
552
- ld=line_deviation(box1, i3, i4);
553
- MSG(fprintf(stderr,"i1-i2 %d %d dist= %d/%d",i1,i2,ld,2*sq(1024/4));)
554
- if (ld >2*sq(1024/4)) Break;
555
- if (ld > sq(1024/4)) ad=99*ad/100;
556
-
557
- if (box1->m3) {
558
- if(!hchar){ ad=99*ad/100; }
559
- if( gchar){ ad=99*ad/100; }
560
- } else { if (ad==100) ad=99; } /* not 100% sure */
561
- Setac(box1,'2',ad);
562
- if (ad==100) return '2';
563
- break;
564
- }
565
- // --- test 3 -------
566
- for(ad=d=100;dx>3 && dy>4;){ // dy<=dx nicht perfekt! besser mittleres
567
- // min-suchen fuer m
568
- int i1, i2, i3, i4, i5, i6, i7, i8; // line derivation + corners
569
- DBG( char c_ask='3'; )
570
- if (sdata->holes.num > 1) Break; /* be tolerant */
571
- if (sdata->holes.num > 0) ad=98*ad/100; /* be tolerant */
572
- if (4*dx<dy) ad=98*ad/100; // to tall 1:2 - 1:3 is usual
573
- // --- vector based code ---
574
- /* half distance to the center */
575
- d=2*sq(128/4);
576
- /* now we check for the lower ends, must be near to the corner */
577
- if (aa[1][2]>d/1) Break; /* [2] = distance, ~7... */
578
- if (aa[2][2]>d/1) Break; /* [2] = distance, ~r... */
579
- if (aa[0][2]>d/1) Break; /* [2] = distance, ~d... */
580
- if (aa[3][2]>d/1) Break; /* [2] = distance, ~bhk... */
581
- /*
582
- type A B C
583
-
584
- 1OO8 1OO 1OO8
585
- O 8 2 <- 7,8
586
- 2 2 7
587
- 1-5-> 3OO7 37 3OO
588
- 4 4 4
589
- O 6 6 <- 6
590
- 5OO6 5OO 5OO
591
- */
592
- /* rightmost point on upper left side */
593
- i2=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1, y0+3*dy/16);
594
- /* rightmost point on lower left side */
595
- i4=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1, y1-dy/4);
596
- /* leftmost point on middle left side */
597
- i3=nearest_frame_vector(box1, i2, i4, x0, y0+dy/2);
598
- /* upper leftmost vector */
599
- i1=nearest_frame_vector(box1, aa[0][3], i2, x0-dx, (y0+y1)/2);
600
- i5=aa[1][3]; // points to vector point in point list
601
- i6=aa[2][3];
602
- i8=aa[3][3];
603
- /* leftmost point on middle right side */
604
- i7=nearest_frame_vector(box1, i6, i8, x0 , y0+dy/2);
605
- /* which type? ToDo: have a more sure algorithm */
606
- if (box1->frame_vector[i7][0]>=x1- dx/4
607
- && box1->frame_vector[i6][0]>=x1- dx/8 // ToDo: ...
608
- && box1->frame_vector[i6][1]>=y1- dy/8) {
609
- MSG(fprintf(stderr,"7-segment-type");)
610
- } else { /* regular-book-type */
611
- }
612
- // ToDo: output no=(x,y)
613
- MSG(fprintf(stderr,"i1-8 %d %d %d %d %d %d %d %d",i1,i2,i3,i4,i5,i6,i7,i8);)
614
- // if (i5==i6) Break; // ~+
615
-
616
- // i2 = upper left gap ) , i3 = middle left <
617
- if (box1->frame_vector[i2][0]
618
- -box1->frame_vector[i3][0]<dx/4) Break; // video samples
619
- if (box1->frame_vector[i4][0]
620
- -box1->frame_vector[i3][0]<dx/4) Break; // video samples
621
- if (box1->frame_vector[i4][0]
622
- -box1->frame_vector[i5][0]<dx/2) Break; // video samples
623
- if (box1->frame_vector[i2][0]
624
- -box1->frame_vector[i1][0]<dx/2) Break; // video samples
625
- if (box1->frame_vector[i1][1]>y0+dy/2) Break; // not to low
626
- if (box1->frame_vector[i1][0]>x0+dx/4+dx/16) Break; // slanted?
627
- if (box1->frame_vector[i5][1]<y1-dy/2) Break; // not to high
628
- if (box1->frame_vector[i5][0]>x0+dx/4) Break;
629
- // ToDo ....
630
-
631
- // --- pixel based old code ---
632
- // if( get_bw(x0+dx/2,x0+dx/2,y0,y0+dy/4,box1->p,cs,1) == 0 ) Break; // ~4
633
- // if( get_bw(x0+dx/2,x0+dx/2,y1-dy/8,y1,box1->p,cs,1) == 0 ) Break; // ~4
634
- // if( num_cross(x0+dx/2,x0+dx/2,y0 ,y1,box1->p,cs) < 2 ) Break;
635
- // if( num_cross(x0+dx/4,x0+dx/4,y1-dy/2,y1,box1->p,cs) == 0 ) Break;
636
- if( get_bw(dx/2,dx/2, 0,dy/6,bp,cs,1) == 0 ) Break; // ~4
637
- if( get_bw(dx/2,dx-1, dy/6,dy/6,bp,cs,1) == 0 ) Break; // ~j
638
- if( get_bw(dx/2,dx/2,dy-1-dy/8,dy-1,bp,cs,1) == 0 ) Break; // ~4
639
- if( num_cross(dx/2,dx/2,0 ,dy-1,bp,cs) < 2 // normal
640
- && num_cross(dx/3,dx/3,0 ,dy-1,bp,cs) < 2 ) Break; // fat LCD
641
- if( num_cross(dx/4,dx/4,dy-1-dy/2,dy-1,bp,cs) == 0 ) Break;
642
- if( loop(bp,dx/2, 0 ,dy,cs,0,DO)>dy/4 ) Break;
643
- if( loop(bp,dx/2, dy-1,dy,cs,0,UP)>dy/4 ) Break;
644
- if( loop(bp,dx-1, dy/3,dy,cs,0,LE)>dy/4 /* 3 with upper bow */
645
- && loop(bp,dx-1, dy/8,dy,cs,0,LE)>dy/4 /* 3 with horizontal line */
646
- && loop(bp,dx/4, dy/8,dy,cs,1,RI)<dy/2 ) Break;
647
- if( loop(bp,dx-1,2*dy/3,dy,cs,0,LE)>dy/4 ) Break;
648
- if( loop(bp,dx-1,3*dy/4,dy,cs,0,LE)>dy/2 ) Break; // ~2 Feb06
649
- if( loop(bp,dx-1,7*dy/8,dy,cs,0,LE)>dy/2 ) Break; // ~2 Feb06
650
- // search upper right half circle (may fail on 4x5 font)
651
- for( i3=x=0,i1=y=dy/5;y<dy/2;y++ ){
652
- i=loop(bp,0,y,dx,cs,0,RI);
653
- if (i>x) { i3=x=i; i1=y; }
654
- } i3--;
655
- if( loop(bp,i3,i1,1,cs,0,UP)==1 ) { // find hidden gap in tiny fonts
656
- i1--; i3+=loop(bp,i3,i1,dx,cs,0,RI)-1;
657
- }
658
- if (i3<dx/3 && i3+1+loop(bp,i3+1,i1,dx,cs,1,RI)<3*dx/4) Break;
659
- if (loop(bp,dx-1,i1,dx,cs,0,LE)>1+dx/8) ad=ad*99/100; // ~1 with a pixel
660
- // search lower right half circle
661
- for( i4=x=0,i2=y=dy-1-dy/8;y>=dy/2;y-- ){
662
- i=loop(bp,0,y,dx,cs,0,RI);
663
- if( i>x ) { i4=x=i;i2=y; }
664
- } i4--; if(i4<dx/3 && i4+1+loop(bp,i4+1,i2,dx,cs,1,RI)<3*dx/4) Break;
665
- if (loop(bp,dx-1,i2,dx,cs,0,LE)>1+dx/8) ad=ad*99/100; // ~1 with a pixel
666
-
667
- for( x=xa=0,ya=y=dy/4;y<3*dy/4;y++ ){ // right gap, not on LCD-font
668
- i=loop(bp,dx-1,y,dx,cs,0,LE);
669
- if (i>=xa) { xa=i;ya=y;x=xa+loop(bp,dx-1-xa,y,dx,cs,1,LE); }
670
- } if (dy>3*dx) if (xa<2 && x-xa<dx/2) Break; // ~]
671
- if (xa>1+dx/8 // noLCD
672
- && xa<=loop(bp,dx-1,i2,dx,cs,0,LE)) ad=ad*99/100; // ~1 with a pixel
673
- if (xa>1+dx/8 // noLCD
674
- && xa<=loop(bp,dx-1,i1,dx,cs,0,LE)) ad=ad*99/100; // ~1 with a pixel
675
-
676
- // upper left gap = (i3,i1)
677
- // lower left gap = (i4,i2)
678
- MSG(fprintf(stderr,"left white gaps (%d,%d) (%d,%d)",i3,i1,i4,i2);)
679
- if( get_bw(i3,i3,i1,i2 ,bp,cs,1) != 1 ) Break; // no hor. middle line?
680
- if( get_bw(i4,i4,i1,i2 ,bp,cs,1) != 1 ) Break;
681
- if( get_bw(i3,i3,0 ,i1 ,bp,cs,1) != 1 ) Break; // no upper bow?
682
- if( get_bw(i4,i4,i2,dy-1,bp,cs,1) != 1 ) Break; // no lower bow?
683
- // hole is only allowed in beauty fonts
684
- // if( num_hole( x0, x1, y0, y1,box1->p,cs,NULL) > 0 ) // there is no hole
685
- // if( num_hole( x0, x0+dx/2, y0, y0+dy/2,box1->p,cs,NULL) == 0 ) // except in some beauty fonts
686
- if (sdata->holes.num>0)
687
- if (sdata->holes.hole[0].x1 >= dx/2 || sdata->holes.hole[0].y1 >= dy/2)
688
- Break;
689
- Setac(box1,(wchar_t)'3',ad);
690
- if (ad==100) return '3';
691
- break;
692
- }
693
- // --- test 4 --------------------------------------------------- 25Nov06
694
- for(ad=d=100;dy>3 && dx>2;){ // min 3x4 ~<gA',
695
- // rewritten for vectors 0.42
696
- int ld, i1, i2, i3, i4, i5, i6, i7; // line derivation + corners
697
- DBG( wchar_t c_ask='4'; )
698
- if (sdata->holes.num > 1) Break; /* no or one hole */
699
- /* half distance to the center */
700
- d=2*sq(128/4); /* 2048 */
701
- /* now we check for the lower left end, must be far away */
702
- /* lowest is 144 for 9x10 screen font (Apr2009) */
703
- if (aa[1][2]<d/16) { /* Apr09: d/8=256 to d/16=128 */
704
- MSG( fprintf(stderr," low-left-dist= %d < max= %d", aa[1][2], d); )
705
- Break; /* [2] = distance, ~ABDEF... */
706
- }
707
- /* searching for 4 notches between neighbouring ends */
708
-
709
- /*
710
- type A B C D
711
-
712
- 1 5 1 1 1
713
- O O O O5 O5
714
- 2OO3 O 5 O O O O <- 7 6
715
- O 2O3O 2OO3 2OO3O
716
- 4 4 4 4
717
-
718
- y4-y3 should be significant (bigger y3-y6)?
719
- */
720
-
721
- /* Warning: aa0 can be left upper or left lower point for type B */
722
- /* get a point on the inner low left side of the J */
723
- i =box1->num_frame_vectors[0] - 1;
724
- /* leftmost upper point */
725
- i1=nearest_frame_vector(box1, 0, i, x0, y0-dy);
726
- /* lowest from leftmost vector can be very low (20/23) */
727
- i2=nearest_frame_vector(box1, 0, i, x0-2*dx, (y0+7*y1)/8);
728
- /* lowest vector */
729
- i4=nearest_frame_vector(box1, 0, i, (x0+2*x1)/3, y1+dy);
730
- /* right center crossing point */
731
- i3=nearest_frame_vector(box1, i2, i4, x1, (3*y0+y1)/4);
732
- /* get a point on the outer right side below top serif */
733
- /* next local max_y-point after i4 */
734
- i5=i4;
735
- for (i=i4;i!=i2;i=(i+1)%box1->num_frame_vectors[0]) {
736
- if (box1->frame_vector[ i][1]
737
- <box1->frame_vector[i5][1]) i5=i; // get next maximum
738
- if (box1->frame_vector[ i][1]
739
- >box1->frame_vector[i5][1]+1) break; // break after maximum
740
- if (box1->frame_vector[ i][0]<x0+dx/4) break; // type A B
741
- }
742
- if (box1->num_frames>1) { // type C D
743
- i = box1->num_frame_vectors[0] - 1; // end outer loop
744
- j = box1->num_frame_vectors[1] - 1; // end inner loop
745
- if (box1->num_frames>2) { // see font2.png, 2nd one pixel hole
746
- j = box1->num_frame_vectors[2] - 1; // end inner loop
747
- ad=99*ad/100; // little bit unsure
748
- }
749
- i6=nearest_frame_vector(box1, i+1, j, x1, y1);
750
- i7=nearest_frame_vector(box1, i+1, j, x0, y1);
751
- if (box1->frame_vector[i1][0]
752
- -box1->frame_vector[i2][0]<dx/4+1) ad=96*ad/100; // ~4x6q
753
- i =nearest_frame_vector(box1, i+1, j, x0, y0); // top left
754
- MSG(fprintf(stderr,"triangle type top-left i=%d",i);)
755
- if (box1->frame_vector[i ][0]-x0<dx/4+1
756
- && box1->frame_vector[i ][1]-y0<dy/4+1
757
- && dx>7) ad=97*ad/100; // q
758
-
759
- } else { // type A B
760
- i6=nearest_frame_vector(box1, i5, i1, (x0+3*x1)/4, y1-dy/8);
761
- i7=nearest_frame_vector(box1, i5, i1, x0 , y1-dy/8);
762
- MSG(fprintf(stderr,"open type");)
763
- if (box1->frame_vector[i6][1]-y0>3*dy/4
764
- || box1->frame_vector[i7][1]-y0>3*dy/4) ad=96*ad/100; // ~uU
765
- }
766
- // ToDo: output no=(x,y)
767
- MSG(fprintf(stderr,"i1-7 %d %d %d %d %d %d %d",i1,i2,i3,i4,i5,i6,i7);)
768
- if (i5==i6) Break; // ~+
769
-
770
- if (box1->frame_vector[i1][1]>y0+dy/8) Break; // not to low
771
- if (box1->frame_vector[i2][1]
772
- -box1->frame_vector[i1][1]<dy/2) Break;
773
- if (box1->frame_vector[i3][0]
774
- -box1->frame_vector[i2][0]<dx/4) Break;
775
- if (abs(box1->frame_vector[i3][1]
776
- -box1->frame_vector[i2][1])>dy/4) Break;
777
- if (box1->frame_vector[i2][0]>x0+dx/8) Break;
778
- if (box1->frame_vector[i2][1]>y1-dy/8) Break;
779
- if (box1->frame_vector[i4][1]
780
- -box1->frame_vector[i2][1]<dy/8) Break;
781
- if (box1->frame_vector[i4][1]
782
- -box1->frame_vector[i2][1]<dy/6) ad=99*ad/100;
783
- /* min. distance of the horizontal bar to the ground */
784
- /* y4-y3 should be significant (bigger y3-y6)? */
785
- if (box1->frame_vector[i4][1]
786
- -box1->frame_vector[i3][1]<1+dy/16) Break;
787
- if ((box1->frame_vector[i4][1]
788
- -box1->frame_vector[i3][1])*2<=
789
- (box1->frame_vector[i3][1]
790
- -box1->frame_vector[i6][1])) Break; // 090728 gas_meter (flat-ulike)
791
- if ((box1->frame_vector[i4][1]
792
- -box1->frame_vector[i3][1])<
793
- (box1->frame_vector[i3][1]
794
- -box1->frame_vector[i6][1])) ad=99*ad/100;
795
- if (box1->frame_vector[i4][1]
796
- -box1->frame_vector[i3][1]<dy/6) ad=99*ad/100; /* tall chars */
797
- if (box1->frame_vector[i4][1]
798
- -box1->frame_vector[i3][1]<dy/8) ad=99*ad/100;
799
- if (box1->frame_vector[i4][1]<y1-1-dy/8) Break;
800
- if (box1->frame_vector[i3][0]<x0+dx/4) Break;
801
- if (box1->frame_vector[i3][0]<x0+dx/2) ad=98*ad/100;
802
- /* on very tall chars the i3 point can be near to the groundline */
803
- if (box1->frame_vector[i3][1]>y1-1) Break;
804
- if (box1->frame_vector[i3][1]>y1-dy/16) Break;
805
- if (box1->frame_vector[i3][1]>=y1) Break; // ~5x5#
806
- if (box1->frame_vector[i5][0]<x0+dx/3) Break;
807
- /* upper end of right vertical line */
808
- if (box1->frame_vector[i5][1]>y0+2*dy/3) Break;
809
- if (box1->frame_vector[i6][1]
810
- -box1->frame_vector[i5][1]<1+dy/16) Break;
811
- if (box1->frame_vector[i6][0]<x0+dx/3) Break;
812
- if (box1->frame_vector[i7][0]>x0+dx/2) Break;
813
- if (box1->frame_vector[i7][0]>x0+dx/3) ad=ad*99/100;
814
- if (box1->frame_vector[i6][1]<y0+dy/3) Break;
815
- if (box1->frame_vector[i6][0]<x0+dx/2) ad=96*ad/100; // ~ 42
816
- if (box1->frame_vector[i6][0]<aa[2][0]-dx/2
817
- && aa[2][1]>=y1-1-dy/8) ad=96*ad/100; // ~ 42
818
- if (box1->frame_vector[i7][1]<y0+dy/3) Break;
819
- if (abs(box1->frame_vector[i3][1]
820
- -box1->frame_vector[i2][1])>dy/4) Break;
821
-
822
- /* check if upper left and lower left points are joined directly */
823
- ld=line_deviation(box1, i1, i2);
824
- MSG(fprintf(stderr," i1-i2 %d %d dist= %d/%d",i1,i2,ld,2*sq(1024/4));)
825
- if (ld >2*sq(1024/4)) Break;
826
- /* check if lower right and upper right points are joined directly */
827
- ld=line_deviation(box1, i2, i3);
828
- MSG(fprintf(stderr," i2-i3 %d %d dist= %d/%d",i2,i3,ld,2*sq(1024/4));)
829
- if (ld > sq(1024/4)) Break;
830
- /* check if lower right and upper right points are joined directly */
831
- ld=line_deviation(box1, i3, i4);
832
- MSG(fprintf(stderr," i3-i4 %d %d dist= %d/%d",i3,i4,ld,2*sq(1024/4));)
833
- if (ld > sq(1024/4)) Break;
834
- /* check if lower right and upper right points are joined directly */
835
- ld=line_deviation(box1, i6, i7);
836
- MSG(fprintf(stderr," i6-i7 %d %d dist= %d/%d",i6,i7,ld,2*sq(1024/4));)
837
- if (ld >2*sq(1024/4)) Break;
838
-
839
- // 4 exists as gchar and ~gchar
840
- if(!hchar){ ad=99*ad/100; }
841
- Setac(box1,'4',ad);
842
- break;
843
- }
844
- #ifdef Old_pixel_based
845
- // --- old test 4 pixelbased ------- remove!
846
- for(ad=d=100;dx>3 && dy>5;){ // dy>dx, min 4x6 font
847
- DBG( char c_ask='4'; )
848
- if (sdata->holes.num > 2) Break; /* be tolerant */
849
- if (sdata->holes.num > 1) ad=97*ad/100;
850
- // upper raising or vertical line
851
- if( loop(bp,0 ,3*dy/16,dx,cs,0,RI)
852
- < loop(bp,0 ,2*dy/4 ,dx,cs,0,RI)-dx/8 ) Break;
853
- // search for a vertical line on lower end
854
- for (y=0;y<dy/4;y++)
855
- if( loop(bp,0 ,dy-1-y,dx,cs,0,RI)
856
- + loop(bp,dx-1,dy-1-y,dx,cs,0,LE) >= dx/2 ) break;
857
- if (y>=dy/4) Break;
858
- if( loop(bp,0 ,dy-1-dy/8,dx,cs,0,RI) < dx/4 ) Break;
859
- // --- follow line from (1,0) to (0,.7)
860
- y=0; x=loop(bp,0,0,dx,cs,0,RI);
861
- if (x<=dx/4) { // ocr-a-4
862
- i=loop(bp,0,dy/4,dx,cs,0,RI); if (i>dx/4) Break;
863
- i=loop(bp,i,dy/4,dx,cs,1,RI); if (i>dx/2) Break;
864
- j=loop(bp,i,dy/4,dy,cs,0,DO)+dy/4; if (j>7*dy/8) Break;
865
- }
866
- turmite(bp,&x,&y,0,dx-1,0,dy-1,cs,DO,LE); if( x>=0 ) Break;
867
-
868
- y=loop(bp,0,0,dy,cs,0,DO);
869
- if( (y+loop(bp,0,y,dy,cs,1,DO)) < dy/2 ) Break;
870
- if( get_bw(x0 , x0+3*dx/8, y1-dy/7, y1-dy/7,box1->p,cs,1) == 1 ) Break;
871
- if( get_bw(x0+dx/2, x1 , y1-dy/3, y1-dy/3,box1->p,cs,1) != 1 ) Break;
872
- if( get_bw(x0+dx/2, x0+dx/2, y0+dy/3, y1-dy/5,box1->p,cs,1) != 1 ) Break;
873
- i=loop(bp,bp->x-1, bp->y/4,dx,cs,0,LE);
874
- if( i > loop(bp,bp->x-1,2*bp->y/4,dx,cs,0,LE)+1
875
- && i > loop(bp,bp->x-1,3*bp->y/8,dx,cs,0,LE)+1 ) Break;
876
- if (loop(bp,0,0,dx,cs,0,RI)>dx/4) {
877
- for(i=dx/8+1,x=0;x<dx && i;x++){
878
- if( num_cross(x ,x ,0 ,dy-1, bp,cs) == 2 ) i--;
879
- } if( i ) Break;
880
- }
881
- for(i=dy/6+1,y=dy/4;y<dy && i;y++){
882
- if( num_cross(0 ,dx-1,y ,y , bp,cs) == 2 ) i--;
883
- } if( dy>15 && i ) Break;
884
- for(i=dy/10+1,y=dy-1-dy/4;y<dy && i;y++){
885
- if( num_cross(0 ,dx-1,y ,y , bp,cs) == 1 )
886
- if( num_cross(dx/2,dx-1,y ,y , bp,cs) == 1 ) i--;
887
- } if( i ) Break;
888
- // i4 = num_hole ( x0, x1, y0, y1,box1->p,cs,NULL);
889
- // ToDo:
890
- // - get start and endpoint of left edge of left vert. line
891
- // and check if that is an streight line
892
- // - check the right edge of the inner hole (if there) too
893
- i4 = sdata->holes.num;
894
- if (sdata->holes.num >0) { // ~q
895
- i = loop(bp,0,dy/16,dx,cs,0,RI);
896
- if (i < dx/3) Break;
897
- if (i < dx/2) ad=98*ad/100; // hole?
898
- if ( loop(bp, 0,dy-1,dy,cs,0,UP)
899
- -loop(bp,dx/8+1,dy-1,dy,cs,0,UP)>dy/16) ad=97*ad/100;
900
- }
901
- // thickness of left vertical line
902
- for (j=y=0;y<dy/6;y++) {
903
- i=loop(bp,dx-1 ,y,dx,cs,0,LE);
904
- i=loop(bp,dx-1-i,y,dx,cs,1,LE); if (i>j) j=i;
905
- }
906
- if (j>=dx/2) ad=98*ad/100; // ~q handwritten a (or very thinn 4)
907
- // ToDo: check y of masscenter of the hole q4
908
-
909
- if( i4 ) if( dx > 15 )
910
- if( loop(bp, dx/2, 0,dy,cs,0,DO)<dy/16
911
- && loop(bp, dx/4, 0,dy,cs,0,DO)<dy/8
912
- && loop(bp,3*dx/4, 0,dy,cs,0,DO)<dy/8
913
- && loop(bp, dx/4,dy-1,dy,cs,0,UP)<dy/8
914
- && loop(bp, dx/2,dy-1,dy,cs,0,UP)<dy/8
915
- && loop(bp,3*dx/4,dy-1,dy,cs,0,UP)<dy/4 ) Break; // ~9
916
-
917
- i =loop(bp,dx-1 ,dy-1,dx,cs,0,LE); // ~9
918
- i+=loop(bp,dx-1-i,dy-1,dx,cs,1,LE);
919
- if( i>3*dx/4
920
- && i-loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE)>dx/4 ) Break;
921
-
922
- i =loop(bp,dx-1-dx/4,dy-1,dx,cs,0,UP);
923
- if (i> dy/2) ad=97*ad/100;
924
- if (i>3*dy/4) ad=97*ad/100; /* handwritten n */
925
-
926
- if( num_cross(0 ,dx-1,dy/16 ,dy/16 , bp,cs) == 2 // ~9
927
- && loop(bp,dx-1,dy/16 ,dx,cs,0,LE)>
928
- loop(bp,dx-1,dy/16+1+dy/32,dx,cs,0,LE) ) Break;
929
- if ( !hchar) ad=99*ad/100;
930
- if (gchar && !hchar) ad=98*ad/100; // ~q
931
- Setac(box1,(wchar_t)'4',ad);
932
- if (ad>99) bc='4';
933
- break;
934
- }
935
- #endif
936
- // --- test 6 ------- ocr-a-6 looks like a b :(
937
- for(ad=d=100;dx>3 && dy>4;){ // dy>dx
938
- DBG( char c_ask='6'; )
939
- if (sdata->holes.num > 2) Break; /* be tolerant */
940
- if( loop(bp, 0, dy/4,dx,cs,0,RI)>dx/2 // ocr-a=6
941
- && loop(bp,dx-1, 0,dy,cs,0,DO)>dy/4 ) Break; // italic-6
942
- if( loop(bp, 0, dy/2,dx,cs,0,RI)>dx/4 ) Break;
943
- if( loop(bp, 0,3*dy/4,dx,cs,0,RI)>dx/4 ) Break;
944
- if( loop(bp,dx-1,3*dy/4,dx,cs,0,LE)>dx/2 ) Break;
945
- if( num_cross(x0+ dx/2,x0+ dx/2,y0 ,y1 ,box1->p,cs) != 3
946
- && num_cross(x0+5*dx/8,x0+5*dx/8,y0 ,y1 ,box1->p,cs) != 3 ) {
947
- if( num_cross(x0+ dx/2,x0+ dx/2,y0+dy/4,y1 ,box1->p,cs) != 2
948
- && num_cross(x0+5*dx/8,x0+5*dx/8,y0+dy/4,y1 ,box1->p,cs) != 2 ) Break;
949
- // here we have the problem to decide between ocr-a-6 and b
950
- if ( loop(box1->p,(x0+x1)/2,y0,dy,cs,0,DO)<dy/2 ) Break;
951
- ad=99*ad/100;
952
- } else {
953
- if (loop(box1->p,x0+dx/2,y0,dx,cs,0,DO)>dy/8
954
- && loop(box1->p,x1-dx/4,y0,dx,cs,0,DO)>dy/8 ) Break;
955
- }
956
- if( num_cross(x0 ,x1 ,y1-dy/4,y1-dy/4,box1->p,cs) != 2 ) Break;
957
- for( y=y0+dy/6;y<y0+dy/2;y++ ){
958
- x =loop(box1->p,x1 ,y ,dx,cs,0,LE); if( x>dx/2 ) break;
959
- x+=loop(box1->p,x1-x+1,y-1,dx,cs,0,LE); if( x>dx/2 ) break;
960
- } if( y>=y0+dy/2 ) Break;
961
- if (loop(box1->p,x0,y1-dy/3,dx,cs,0,RI)>dx/4 ) Break;
962
- if (loop(box1->p,x1,y1-dy/3,dx,cs,0,LE)>dx/4 ) Break;
963
-
964
- if (sdata->holes.num != 1) Break;
965
- if (sdata->holes.hole[0].y1 < dy/2) ad=95*ad/100; // whats good for?
966
- if (sdata->holes.hole[0].y0 < dy/4) Break;
967
- MSG( fprintf(stderr,"hole[0].x0,x1 %d %d", sdata->holes.hole[0].x0,
968
- sdata->holes.hole[0].x1); )
969
- if (sdata->holes.hole[0].x0<1
970
- && dx-1-sdata->holes.hole[0].x1>2) ad=ad*99/100; // melted serif sS ?
971
- if (loop(box1->p,x0,y0+dy/2,dx,cs,0,RI)>0
972
- && loop(box1->p,x0,y0+dy/4,dx,cs,0,RI)==0
973
- && loop(box1->p,x0,y1-dy/4,dx,cs,0,RI)==0) ad=97*ad/100; // molten serif sS
974
- // if( num_hole ( x0, x1, y0, y0+dy/2,box1->p,cs,NULL) > 0 ) ad=95*ad/100;
975
- // if( num_hole ( x0, x1, y0+dy/4, y1,box1->p,cs,NULL) != 1 ) Break;
976
- // if( num_hole ( x0, x1, y0 , y1,box1->p,cs,NULL) != 1 ) Break;
977
- // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
978
- /* check left vertical bow */
979
- i1=loop(bp,0,dy/8 ,dx,cs,0,RI);
980
- i3=loop(bp,0,dy-1-dy/8,dx,cs,0,RI);
981
- i2=loop(bp,0,dy/2 ,dx,cs,0,RI);
982
- if(i1+i3-2*i2<-2-dx/16 && i1+i2+i3>0) Break; // convex from left
983
- if(i1+i3-2*i2<1 && i1+i2+i3>0) ad=99*ad/100; // 7-segment-font
984
- for( x=dx,y=0;y<dy/4;y++ ){ // ~ b (serife?)
985
- i1=loop(bp, 0,y,dx,cs,0,RI);
986
- i2=loop(bp,i1,y,dx,cs,1,RI);
987
- if (i2+i1>dx/2 && i2>dx/4) break; /* its a 6 (example: 7-segment) */
988
- if (i1<x) x=i1; else if (i1>x) break; /* may be serifen b */
989
- } if (y<dy/4 && i1+i2<=dx/2) Break;
990
- // ~& (with open upper loop)
991
- for( i=0,y=dy/2;y<dy;y++){
992
- if( num_cross(dx/2,dx-1,y,y,bp,cs) > 1 ) i++; if( i>dy/8 ) break;
993
- } if( y<dy ) Break;
994
- if ( gchar) ad=99*ad/100;
995
- if (!hchar) ad=98*ad/100;
996
- if ( box1->dots ) ad=98*ad/100;
997
- Setac(box1,(wchar_t)'6',ad);
998
- bc='6';
999
- break;
1000
- }
1001
- // --- test 7 ---------------------------------------------------
1002
- for(ad=d=100;dx>2 && dy>4;){ // dx>1 dy>2*dx
1003
- DBG( char c_ask='7'; )
1004
- if (sdata->holes.num > 1) Break; /* be tolerant */
1005
- if( loop(bp,dx/2,0,dy,cs,0,DO)>dy/8 ) Break;
1006
- if( num_cross(0,dx-1,3*dy/4,3*dy/4,bp,cs) != 1 ) Break; // preselect
1007
- for( yb=xb=y=0;y<dy/2;y++){ // upper h-line and gap
1008
- j=loop(bp,0,y,dx,cs,0,RI);if(xb>0 && j>dx/4) break; // gap after h-line
1009
- j=loop(bp,j,y,dx,cs,1,RI);if(j>xb){ xb=j;yb=y; } // h-line
1010
- } if( xb<dx/4 || y==dy/2 ) Break;
1011
- j=loop(bp,0,dy/2,dx,cs,0,RI);
1012
- j=loop(bp,j,dy/2,dx,cs,1,RI); if(xb<2*j) Break; // minimum thickness
1013
- for(x=0,y+=dy/16;y<dy;y++){ // one v-line?
1014
- if( num_cross(0,dx-1,y,y,bp,cs) != 1 ) break;
1015
- j=loop(bp,dx-1,y,dx,cs,0,LE); if( j<x ) break; if( j-1>x ) x=j-1;
1016
- } if( y<dy || x<dx/3 ) {
1017
- MSG( fprintf(stderr,"xy= %d %d",x,y); )
1018
- Break;
1019
- }
1020
- j =loop(bp,dx-1,0,dy,cs,0,DO); // ~T
1021
- j+=loop(bp,dx-1,j,dy,cs,1,DO)+dy/16;
1022
- i =loop(bp,dx-1,j,dx,cs,0,LE); if(j<dy/2) {
1023
- if (i>j) Break;
1024
- j=loop(bp, 0,j,dx,cs,0,RI);
1025
- if(j>dx/4 && j<=i+dx/16) Break; // tall T
1026
- }
1027
-
1028
- MSG( fprintf(stderr,"7: ad= %d",ad); )
1029
- if( loop(bp, 0,3*dy/8,dx,cs,0,RI)
1030
- <=loop(bp,dx-1,3*dy/8,dx,cs,0,LE)+dx/8 ) ad=ad*98/100; // l
1031
- MSG( fprintf(stderr,"7: ad= %d",ad); )
1032
- if( num_cross(0,dx-1,dy/4,dy/4,bp,cs) == 1
1033
- && loop(bp,0,dy/4,dx,cs,0,RI) < dx/2 ) ad=ad*96/100; // J
1034
- MSG( fprintf(stderr,"7: ad= %d",ad); )
1035
-
1036
- if (box1->m3 && dy<box1->m3-box1->m2) ad=99*ad/100; // too small
1037
- if (box1->m3 && 2*dy<box1->m3-box1->m2) ad=96*ad/100; // too small
1038
- if (dy>3*dx) ad=99*ad/100; // )
1039
- if ( gchar) ad=99*ad/100; // J
1040
- if (!hchar) ad=99*ad/100;
1041
- Setac(box1,(wchar_t)'7',ad);
1042
- break;
1043
- }
1044
- // --- test 8 ---------------------------------------------------
1045
- // last change: May15th,2000 JS
1046
- for(ad=d=100;dx>2 && dy>4;){ // or we need large height
1047
- DBG( char c_ask='8'; )
1048
- if (sdata->holes.num != 2) Break;
1049
- if( num_cross(x0,x1,y0 +dy/4,y0 +dy/4,box1->p,cs) != 2 ) Break; // ~gr (glued)
1050
- if( num_cross(x0,x1,y1 -dy/4,y1 -dy/4,box1->p,cs) != 2
1051
- && num_cross(x0,x1,y1-3*dy/8,y1-3*dy/8,box1->p,cs) != 2 ) Break;
1052
- if( get_bw(x0,x0+dx/4,y1-dy/4,y1-dy/4,box1->p,cs,1) == 0 ) Break; // ~9
1053
- if( get_bw(x0,x0+dx/2,y0+dy/4,y0+dy/4,box1->p,cs,1) == 0 ) Break;
1054
- if( get_bw(x0+dx/2,x0+dx/2,y0+dy/4,y1-dy/4,box1->p,cs,1) == 0 ) Break; // ~0
1055
- // MSG( printf(" x0 y0 %d %d\n",x0,y0); )
1056
- for( i2=i1=x=0,i=y=y0+dy/3;y<=y1-dy/3;y++){ // check left middle nick
1057
- j=loop(box1->p,x0,y,dx,cs,0,RI);
1058
- if (j>x || (abs(j-x)<=dx/8 /* care about MICR E-13B font */
1059
- && (i1=loop(box1->p,x0+j,y,dx,cs,1,RI))>dx/2)) {
1060
- if (j>x) x=j; i=y; if (i1>i2) i2=i1; }
1061
- } if(i>=y1-dy/3 || (x<dx/8 && i2<=dx/2) || x>dx/2) Break; // no gB
1062
- if (x< dx/4) ad=99*ad/100; // no B
1063
- if (x<=dx/8) ad=98*ad/100; // no B
1064
- j = loop(box1->p,x1,y1- dy/4,dx,cs,0,LE);
1065
- if( j>loop(box1->p,x1,y1- dy/5,dx,cs,0,LE)
1066
- && j>loop(box1->p,x1,y1-2*dy/5,dx,cs,0,LE) ) Break; // &
1067
- // check for upper hole
1068
- for (j=0;j<sdata->holes.num;j++) {
1069
- if (sdata->holes.hole[j].y1 < i-y0+1 ) break;
1070
- if (sdata->holes.hole[j].y1 < i-y0+dy/8) break;
1071
- } if (j==sdata->holes.num) Break; // not found
1072
- // if( num_hole(x0,x1,y0,i+1 ,box1->p,cs,NULL)!=1 )
1073
- // if( num_hole(x0,x1,y0,i+dy/8,box1->p,cs,NULL)!=1 ) Break; // upper hole
1074
- // check for lower hole
1075
- for (j=0;j<sdata->holes.num;j++) {
1076
- if (sdata->holes.hole[j].y0 > i-y0-1 ) break;
1077
- } if (j==sdata->holes.num) Break; // not found
1078
- // if( num_hole(x0,x1,i-1,y1,box1->p,cs,NULL)!=1 ) Break;
1079
- i1=i; // left middle nick
1080
- /* find the middle right nick */
1081
- for( x=0,i2=i=y=y0+dy/3;y<=y1-dy/3;y++){
1082
- j=loop(box1->p,x1,y,dx,cs,0,LE); if( j>=x ) i2=y;
1083
- /* we care also for 7-segment and unusual fonts */
1084
- if (j>x || (abs(j-x)<=(dx+4)/8
1085
- && loop(box1->p,x1-j,y,dx,cs,1,LE)>dx/2)){
1086
- if (j>x) x=j; i=y; }
1087
- // MSG(fprintf(stderr," yjix %d %d %d %d %d %d",y-y0,j,i-y0,x,loop(box1->p,x1-j,y,dx,cs,1,LE),dx/2);)
1088
- }
1089
- if( i>y0+dy/2+dy/10 ) Break;
1090
- // if( x<dx/8 ) Break;
1091
- if( x>dx/2 ) Break;
1092
- MSG(fprintf(stderr,"center bar at y= %d %d x=%d+%d i1=%d",i-y0,i2-y0,x,j,i1);)
1093
- if( num_cross(x0,x1, i , i ,box1->p,cs) != 1
1094
- && num_cross(x0,x1, i+1 , i+1 ,box1->p,cs) != 1
1095
- && num_cross(x0,x1,(i+i2)/2,(i+i2)/2,box1->p,cs) != 1 ) Break; // no g
1096
- if(abs(i1-i)>(dy+5)/10) ad=99*ad/100; // y-distance right-left-nick
1097
- if(abs(i1-i)>(dy+4)/8) ad=99*ad/100; // y-distance right-left-nick
1098
- if(abs(i1-i)>(dy+2)/4) Break;
1099
- // ~B ff
1100
- for(i=dx,y=0;y<dy/8+2;y++){
1101
- j=loop(bp,0,y,dx,cs,0,RI); if( j<i ) i=j; if( j>i+dx/16 ) break;
1102
- } if( y<dy/8+2 ) Break;
1103
- for(i=dx,y=0;y<dy/8+2;y++){
1104
- j=loop(bp,0,dy-1-y,dx,cs,0,RI);
1105
- if( j<i ) i=j; if( j>i+dx/16 ) break;
1106
- } if( y<dy/8+2 ) Break;
1107
- if( dy>16 && num_cross(0,dx-1,dy-1,dy-1,bp,cs) > 1
1108
- && loop(bp,0,dy-1,dx,cs,0,RI) <dx/8+1 ) Break; // no fat serif S
1109
- for( i=0,y=dy/2;y<dy;y++){
1110
- if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; if( i>dy/8 ) break;
1111
- } if( y<dy ) Break;
1112
- if ( loop(bp,dx-1,0,dx,cs,0,LE)==0 ) ad=99*ad/100;
1113
- if (num_cross( 0,dx-1,dy-1,dy-1,bp,cs) > 1) ad=98*ad/100; // &
1114
- if (num_cross(dx-1,dx-1,dy/2,dy-1,bp,cs) > 1) ad=98*ad/100; // &
1115
- if (num_cross( 0,dx-1, 0, 0,bp,cs) > 1) ad=98*ad/100;
1116
- if (dy>15)
1117
- if (num_cross( 0,dx-1, 1, 1,bp,cs) > 1) ad=98*ad/100;
1118
- /* if m1..4 is unsure ignore hchar and gchar ~ga */
1119
- if (!hchar) {
1120
- if ((box1->m2-box1->y0)*8>=dy) ad=98*ad/100;
1121
- else ad=99*ad/100;
1122
- }
1123
- if ( gchar
1124
- && (box1->y1-box1->m3)*8>=dy) ad=99*ad/100;
1125
- Setac(box1,(wchar_t)'8',ad);
1126
- break;
1127
- }
1128
- // --- test 9 \it g ---------------------------------------------------
1129
- /*
1130
- *
1131
- * lcd micr round
1132
- * ooo ooo ooo
1133
- * o o o o o o
1134
- * ooo ooo ooo
1135
- * o o o
1136
- * ooo o o
1137
- */
1138
- for(ad=d=100;dx>2 && dy>4;){ // dx>1 dy>2*dx
1139
- DBG( char c_ask='9'; )
1140
- if (sdata->holes.num > 1) Break;
1141
- if( num_cross(x0+ dx/2,x0+ dx/2,y0,y1-dy/4,box1->p,cs) != 2 // pre select
1142
- && num_cross(x0+ dx/2,x0+ dx/2,y0, y1,box1->p,cs) != 3 // pre select
1143
- && num_cross(x0+3*dx/8,x0+3*dx/8,y0,y1,box1->p,cs) != 3
1144
- && num_cross(x0+ dx/4,x1 -dx/4,y0,y1,box1->p,cs) != 3 ) Break;
1145
- if( num_cross(x0+ dx/2,x0 +dx/2,y0,y0+dy/4,box1->p,cs) < 1 ) Break;
1146
- if( num_cross(x0+ dx/2,x1, y0+dy/2 ,y0+dy/2,box1->p,cs) < 1 ) Break;
1147
- if( num_cross(x0,x1, y0+ dy/4 ,y0+ dy/4,box1->p,cs) != 2
1148
- && num_cross(x0,x1, y0+3*dy/8 ,y0+3*dy/8,box1->p,cs) != 2 ) Break;
1149
- if( num_cross(x1-dx/8,x1,y0+dy/4,y0+dy/4,box1->p,cs) == 0) ad=ad*97/100; // ~4
1150
- for( x=0,i=y=y0+dy/2;y<=y1-dy/4;y++){ // find notch (suche kerbe)
1151
- j=loop(box1->p,x0,y,dx,cs,0,RI);
1152
- if( j>x ) { x=j; i=y; }
1153
- } if (x<1 || x<dx/8) Break; y=i;
1154
- // fprintf(stderr," debug 9: %d %d\n",x,i-y0);
1155
- if( x<dx/2 ) { /* big bow? */
1156
- j=loop(box1->p,x0+x-1,y,dy/8+1,cs,0,DO)/2; y=i=y+j;
1157
- j=loop(box1->p,x0+x-1,y,dx/2 ,cs,0,RI); x+=j;
1158
- if (x<dx/2) Break;
1159
- }
1160
- // check for the right lower bow
1161
- MSG( fprintf(stderr,"bow-y0= %d",i-y0); )
1162
- if (dx>5)
1163
- if( num_cross(x0+dx/2,x1,i,y1 ,box1->p,cs) != 1 /* fails on 5x8 */
1164
- && num_cross(x0+dx/2,x1,i,y1-dy/8,box1->p,cs) != 1 ) Break;
1165
- if( num_cross(x0+dx/2,x0+dx/2,i,y1,box1->p,cs) > 1 ) Break;
1166
- if( num_cross(x0+dx/2,x1 ,i, i,box1->p,cs) != 1 ) Break;
1167
-
1168
- if (sdata->holes.num < 1) { /* happens for 5x7 font */
1169
- if (dx<8) ad=98*ad/100; else Break; }
1170
- else {
1171
- if (sdata->holes.hole[0].y1 >= i+1) Break;
1172
- if (sdata->holes.hole[0].y0 > i-1) Break;
1173
- if (sdata->holes.num > 1)
1174
- if (sdata->holes.hole[1].y0 > i-1) Break;
1175
- // if( num_hole(x0,x1,y0,i+1,box1->p,cs,NULL)!=1 ) Break;
1176
- // if( num_hole(x0,x1,i-1,y1,box1->p,cs,NULL)!=0 ) Break;
1177
- }
1178
- if( loop(box1->p,x0,y1 ,dy,cs,0,RI)>dx/3 &&
1179
- loop(box1->p,x0,y1-1,dy,cs,0,RI)>dx/3
1180
- && (box1->m3==0 || (box1->m3!=0 && (!hchar || gchar)))) ad=98*ad/100; // no q OR ocr-a-9
1181
- for( x=0,i=y=y0+dy/3;y<=y1-dy/3;y++){ // suche kerbe
1182
- j=loop(box1->p,x1,y,dx,cs,0,LE);
1183
- if( j>x ) { x=j; i=y; }
1184
- } if( x>dx/2 ) Break; // no g
1185
- i1=loop(bp,dx-1,dy/8 ,dx,cs,0,LE); if(i1>dx/2) Break;
1186
- i3=loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE);
1187
- i2=loop(bp,dx-1,dy/2 ,dx,cs,0,LE); if(i1+i3-2*i2<-1-dx/16) Break; // konvex
1188
- i1=loop(bp,dx-1,dy/4 ,dx,cs,0,LE); if(i1>dx/2) Break;
1189
- i3=loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE);
1190
- for(y=dy/4;y<dy-1-dy/4;y++){ // may fail on type=round
1191
- i2=loop(bp,dx-1,y,dx,cs,0,LE);
1192
- // konvex from right ~g ~3 Jul09
1193
- if(i2>i1+(i3-i1)*(2*y-dy/2)/dy+dx/16) break;
1194
- // MSG(fprintf(stderr," y i2 %d %d %d",y,i2,i1+(i3-i1)*(2*y-dy/2)/dy);)
1195
- } if(y<dy-1-dy/4) Break;
1196
- x=loop(bp,dx -1,6*dy/8,dx,cs,0,LE); if(x>0){
1197
- x--; // robust
1198
- y=loop(bp,dx-x-1, dy-1,dy,cs,0,UP);
1199
- if(y<dy/8) Break; // ~q (serif!)
1200
- }
1201
- // check for agglutinated serif y
1202
- if (dy>=16 && dx>9
1203
- && loop(bp, 0,dy/ 4,dx,cs,0,RI)
1204
- -loop(bp, 0,dy/16,dx,cs,0,RI)>dx/6
1205
- && loop(bp,dx-1,dy/ 4,dx,cs,0,LE)
1206
- -loop(bp,dx-1,dy/16,dx,cs,0,LE)>dx/6) Break; // ~ serif yY
1207
-
1208
- if (box1->m3) {
1209
- if ( gchar) ad=99*ad/100; /* unsure (italic g)? */
1210
- if (box1->m2 && (!gchar) && y1 > box1->m3){
1211
- ad=99*ad/100;
1212
- if (box1->m4-box1->m3<3) ad=99*ad/100;
1213
- // if (!hchar) ad = 99*ad/100;
1214
- }
1215
- if (!hchar) ad=99*ad/100; /* unsure */
1216
- } else { if (ad==100) ad=99; } /* not 100% sure */
1217
- Setac(box1,(wchar_t)'9',ad);
1218
- break;
1219
- }
1220
- // 0 is same as O !?
1221
- // --- test 0 (with one big hole in it ) -----------------------------
1222
- for(d=ad=100;dx>2 && dy>3;){ // min 3x4
1223
- DBG( char c_ask='0'; )
1224
- if (sdata->holes.num > 1) Break; /* be tolerant */
1225
- if( get_bw(x0 , x0+dx/3,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1226
- if( get_bw(x1-dx/3 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1227
- /* could be an O, unless we find a dot in the center */
1228
- if( get_bw(x0 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 3 ) ad=99;
1229
- if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/3 , y1,box1->p,cs,1) != 1 ) Break;
1230
- if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/3,box1->p,cs,1) != 1 ) Break;
1231
- /* accept 0 with dot in center, accept \/0 too ... */
1232
- if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 0 ) Break;
1233
-
1234
- if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 2 ) Break;
1235
- if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1236
- if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1237
- if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1238
- if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1239
- if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1240
- if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1241
- if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1242
- if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1243
- // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 1 ) Break;
1244
- if (sdata->holes.num != 1) Break;
1245
-
1246
- i= loop(bp,0 ,0 ,x1-x0,cs,0,RI)-
1247
- loop(bp,0 ,2 ,x1-x0,cs,0,RI);
1248
- if (i<0) Break;
1249
- if (i==0) {
1250
- if (loop(bp,dx-1,0 ,x1-x0,cs,0,LE)>
1251
- loop(bp,dx-1,2 ,x1-x0,cs,0,LE) ) ad=98*ad/100;
1252
- ad=99*ad/100; /* LCD-type? */
1253
- }
1254
-
1255
- x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1256
- for (y=dy-1-dy/3;y<dy;y++){
1257
- i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1258
- if (i<x-dx/16-1) break; if (i>x) x=i;
1259
- }
1260
- if( y<dy ) Break;
1261
-
1262
- // ~D (but ocr-a-font)
1263
- i= loop(bp, 0, dy/16,dx,cs,0,RI)
1264
- + loop(bp, 0,dy-1-dy/16,dx,cs,0,RI)
1265
- - 2*loop(bp, 0, dy/2 ,dx,cs,0,RI);
1266
- j= loop(bp,dx-1, dy/16,dx,cs,0,LE)
1267
- + loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)
1268
- <= 2*loop(bp,dx-1, dy/2 ,dx,cs,0,LE);
1269
- if (i<-dx/8 || i+dx/8<j) Break; // not konvex
1270
-
1271
- if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1272
- if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1273
- if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1274
- if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1275
- if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1276
- && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1277
- && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1278
- || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) {
1279
- if (dx<32) ad=ad*99/100; else Break; // ~D
1280
- }
1281
-
1282
- // search lowest inner white point
1283
- for(y=dy,j=x=0;x<dx;x++) {
1284
- i =loop(bp,x,dy-1 ,y1-y0,cs,0,UP);
1285
- i+=loop(bp,x,dy-1-i,y1-y0,cs,1,UP);
1286
- if (i<=y) { y=i; j=x; }
1287
- } i=y;
1288
- // italic a
1289
- for(y=dy-1-i;y<dy-1;y++)
1290
- if( num_cross(j,dx-1,y,y,bp,cs) > 1 ) ad=99*ad/100; // ~a \it a
1291
-
1292
- if (loop(bp, 0, 0,x1-x0,cs,0,RI)>=dx/8) { // round, notLCD
1293
- if (loop(bp,dx-1,dy-1,x1-x0,cs,0,LE)<dx/8) ad=98*ad/100; // \it a
1294
- if (loop(bp,dx-1, 0,x1-x0,cs,0,LE)<dx/8) ad=98*ad/100; // \it a
1295
- }
1296
-
1297
- if (abs(loop(bp,dx/2, 0,dy,cs,0,DO)
1298
- -loop(bp,dx/2,dy-1,dy,cs,0,UP))>dy/8
1299
- || num_cross(0,dx-1, 0, 0,bp,cs) > 1
1300
- || num_cross(0,dx-1,dy-1,dy-1,bp,cs) > 1
1301
- ) ad=98*ad/100; // ~bq
1302
-
1303
- if (box1->m3) {
1304
- if (!hchar) ad=98*ad/100; else // ~o
1305
- if ( gchar) ad=99*ad/100; // wrong line detection?
1306
- } else { if (ad==100) ad=99; } /* not 100% sure */
1307
- if (ad>99) ad=99; /* we can never be sure having a O,
1308
- let context correction decide, see below! */
1309
- Setac(box1,(wchar_t)'0',ad);
1310
- break;
1311
- }
1312
- // --- test 0 with a straight line in it -------------------
1313
- for(ad=100;dx>4 && dy>5;){ /* v0.3.1+ */
1314
- DBG( char c_ask='0'; )
1315
- if (sdata->holes.num > 3) Break; /* be tolerant */
1316
- if (sdata->holes.num < 1) Break;
1317
- if (sdata->holes.num != 2) ad=95*ad/100;
1318
- if( get_bw(x0 , x0+dx/2,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1319
- if( get_bw(x1-dx/2 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1320
- if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/2 , y1,box1->p,cs,1) != 1 ) Break;
1321
- if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1322
- if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 1 ) Break;
1323
- // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
1324
- if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 3 ) Break;
1325
- if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1326
- if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1327
- if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1328
- if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1329
- if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1330
- if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1331
- if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1332
- if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1333
- // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 2 ) Break;
1334
- if (sdata->holes.num != 2) ad=85*ad/100;
1335
-
1336
- if( loop(bp,0 , 0,x1-x0,cs,0,RI)<=
1337
- loop(bp,0 , 2+dy/32,x1-x0,cs,0,RI) ) Break;
1338
- x= loop(bp,0 ,dy/2 ,x1-x0,cs,0,RI);
1339
- i= loop(bp,0 ,dy/2-1,x1-x0,cs,0,RI); if (i>x) x=i;
1340
- i= loop(bp,0 ,dy/2-2,x1-x0,cs,0,RI); if (i>x && dy>8) x=i;
1341
- if( loop(bp,0 , dy/4,x1-x0,cs,0,RI)<x ) Break; // ~8
1342
- x= loop(bp,dx-1,dy/2 ,x1-x0,cs,0,LE);
1343
- i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x) x=i;
1344
- i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x && dy>8) x=i;
1345
- if( loop(bp,dx-1,3*dy/4,x1-x0,cs,0,LE)<x) Break; // ~8
1346
-
1347
- x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1348
- for( y=dy-1-dy/3;y<dy;y++ ){
1349
- i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1350
- if (i<x-dx/16) break;
1351
- if (i>x) x=i;
1352
- }
1353
- if( y<dy ) Break;
1354
-
1355
- /* test for straight line */
1356
- y =loop(bp,dx/2,dy-1 ,y1-y0,cs,0,UP); if(y>dy/4) Break;
1357
- y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,1,UP); if(y>dy/3) Break; if (y>dy/4) ad=ad*99/100;
1358
- y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,0,UP); if(3*y>2*dy) Break;
1359
- x =loop(bp,dx/2,dy-y,dx/2,cs,0,RI); if(x==0) Break;
1360
- // MM; fprintf(stderr," y=%d x=%d\n",y-1,x);
1361
- if( loop(bp,dx/2+x-1-dx/16,dy-y,y1-y0,cs,0,UP)==0 ) Break;
1362
- // $
1363
- for(i=0,y=dy/4;y<dy-dy/4-1;y++)
1364
- if( loop(bp, 0,y,dx-1,cs,0,RI) > dx/4
1365
- || loop(bp,dx-1,y,dx-1,cs,0,LE) > dx/4 ) break;
1366
- if( y<dy-dy/4-1 ) Break;
1367
-
1368
- // ~D
1369
- if( loop(bp,0, dy/16,dx,cs,0,RI)
1370
- + loop(bp,0,dy-1-dy/16,dx,cs,0,RI)
1371
- <= 2*loop(bp,0, dy/2 ,dx,cs,0,RI)+dx/8 ) Break; // not konvex
1372
-
1373
- if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1374
- if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1375
- if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1376
- if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1377
- if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1378
- && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1379
- && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1380
- || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) Break; // ~D
1381
-
1382
- /* 5x9 font "9" is like "0" */
1383
- if (dx<16)
1384
- if ( num_cross(x0,x0,y0,y1,box1->p,cs) != 1 ) ad=98*ad/100;
1385
-
1386
- // italic a
1387
- for(i=0,y=6*dy/8;y<dy-dy/16;y++)
1388
- if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; else i--;
1389
- if(i>0) ad=ad*98/100; // ~'a' \it a
1390
- if( !hchar ) ad=90*ad/100;
1391
- Setac(box1,(wchar_t)'0',ad);
1392
- break;
1393
- }
1394
- // --- test 0 with a straight dot in it -------------------
1395
- for(ad=100;dx>4 && dy>5;){ /* v0.46+ */
1396
- DBG( char c_ask='0'; )
1397
- if (sdata->holes.num != 1) Break; /* do not be tolerant */
1398
- if (sdata->box1->num_frames != 2) ad=85*ad/100;
1399
- if( get_bw(x0 , x0+dx/2,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1400
- if( get_bw(x1-dx/2 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1401
- if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/2 , y1,box1->p,cs,1) != 1 ) Break;
1402
- if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1403
- if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 1 ) Break;
1404
- // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
1405
- if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 3 ) Break;
1406
- if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1407
- if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1408
- if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1409
- if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1410
- if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1411
- if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1412
- if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1413
- if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1414
- // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 2 ) Break;
1415
-
1416
- if( loop(bp,0 , 0,x1-x0,cs,0,RI)<=
1417
- loop(bp,0 , 2+dy/32,x1-x0,cs,0,RI) ) Break;
1418
- x= loop(bp,0 ,dy/2 ,x1-x0,cs,0,RI);
1419
- i= loop(bp,0 ,dy/2-1,x1-x0,cs,0,RI); if (i>x) x=i;
1420
- i= loop(bp,0 ,dy/2-2,x1-x0,cs,0,RI); if (i>x && dy>8) x=i;
1421
- if( loop(bp,0 , dy/4,x1-x0,cs,0,RI)<x ) Break; // ~8
1422
- x= loop(bp,dx-1,dy/2 ,x1-x0,cs,0,LE);
1423
- i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x) x=i;
1424
- i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x && dy>8) x=i;
1425
- if( loop(bp,dx-1,3*dy/4,x1-x0,cs,0,LE)<x) Break; // ~8
1426
-
1427
- x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1428
- for( y=dy-1-dy/3;y<dy;y++ ){
1429
- i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1430
- if (i<x-dx/16) break;
1431
- if (i>x) x=i;
1432
- }
1433
- if( y<dy ) Break;
1434
-
1435
- /* test for straight line */
1436
- y =loop(bp,dx/2,dy-1 ,y1-y0,cs,0,UP); if(y>dy/4) Break;
1437
- y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,1,UP); if(y>dy/3) Break; if (y>dy/4) ad=ad*99/100;
1438
- y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,0,UP); if(3*y>2*dy) Break;
1439
- x =loop(bp,dx/2,dy-y,dx/2,cs,0,RI); if(x==0) Break;
1440
- // MM; fprintf(stderr," y=%d x=%d\n",y-1,x);
1441
- if( loop(bp,dx/2+x-1-dx/16,dy-y,y1-y0,cs,0,UP)==0 ) Break;
1442
- // $
1443
- for(i=0,y=dy/4;y<dy-dy/4-1;y++)
1444
- if( loop(bp, 0,y,dx-1,cs,0,RI) > dx/4
1445
- || loop(bp,dx-1,y,dx-1,cs,0,LE) > dx/4 ) break;
1446
- if( y<dy-dy/4-1 ) Break;
1447
-
1448
- // ~D
1449
- if( loop(bp,0, dy/16,dx,cs,0,RI)
1450
- + loop(bp,0,dy-1-dy/16,dx,cs,0,RI)
1451
- <= 2*loop(bp,0, dy/2 ,dx,cs,0,RI)+dx/8 ) Break; // not konvex
1452
-
1453
- if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1454
- if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1455
- if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1456
- if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1457
- if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1458
- && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1459
- && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1460
- || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) Break; // ~D
1461
-
1462
- /* 5x9 font "9" is like "0" */
1463
- if (dx<16)
1464
- if ( num_cross(x0,x0,y0,y1,box1->p,cs) != 1 ) ad=98*ad/100;
1465
-
1466
- // italic a
1467
- for(i=0,y=6*dy/8;y<dy-dy/16;y++)
1468
- if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; else i--;
1469
- if(i>0) ad=ad*98/100; // ~'a' \it a
1470
- if( !hchar ) ad=90*ad/100;
1471
- Setac(box1,(wchar_t)'0',ad);
1472
- break;
1473
- }
1474
- return box1->c;
1475
- }