1 package com.octo.captcha.component.image.textpaster.glyphsvisitor;
2
3 import com.octo.captcha.component.image.textpaster.Glyphs;
4
5 import java.awt.geom.Rectangle2D;
6 import java.awt.geom.Area;
7
8 /***
9 * @author mag
10 * @Date 7 mars 2008
11 */
12 public class OverlapGlyphsUsingShapeVisitor extends OverlapGlyphsVisitor {
13 private double overlapPixels ;
14
15
16
17 public OverlapGlyphsUsingShapeVisitor(double overlapPixels) {
18 super(0);
19 this.overlapPixels = overlapPixels;
20 }
21
22 public void visit(Glyphs gv, Rectangle2D backroundBounds) {
23
24
25
26
27 for (int i = 1; i < gv.size(); i++) {
28
29
30 gv.translate(i, getSidingPosition(gv, i), 0);
31
32
33 if (mayGlyphsOverlapAtIndex(gv, i)) {
34
35 double realPossibleOverlap = getMaximumPossibleOverlap(gv, i);
36 double currentOverlapWidth = intersectAndGetOverlapWidth(gv, i);
37 double currentOverlapStatus = currentOverlapWidth - realPossibleOverlap;
38 double bestReacheadOverlapStatus = Math.abs(currentOverlapStatus);
39
40 boolean stillOk=true;
41
42 while (Math.abs(currentOverlapStatus) >= overlapPixels/10&&stillOk) {
43 double step = currentOverlapStatus/2;
44
45 gv.translate(i, step, 0);
46 currentOverlapWidth = intersectAndGetOverlapWidth(gv, i);
47 currentOverlapStatus = currentOverlapWidth-realPossibleOverlap;
48
49
50
51
52
53 if(Math.abs(currentOverlapStatus)>=bestReacheadOverlapStatus&&(currentOverlapWidth!=0||gv.getMaxX(i-1)-gv.getMinX(i)>gv.getBoundsWidth(i-1))){
54
55
56 if(currentOverlapWidth==0){
57
58 gv.translate(i, getSidingPosition(gv, i), 0);
59
60 }else{
61
62 gv.translate(i, -step, 0);
63
64 }
65
66 stillOk=false;
67 }
68 bestReacheadOverlapStatus = Math.min(Math.abs(currentOverlapStatus),bestReacheadOverlapStatus);
69 }
70
71 }else{
72 System.out.println("NOT POSSIBLE");
73 }
74
75 }
76 }
77
78 private double getSidingPosition(Glyphs gv, int i) {
79 return gv.getBoundsX(i-1)+gv.getBoundsWidth(i-1)-gv.getBoundsX(i)
80 -Math.abs(gv.getRSB(i-1))
81 -Math.abs(gv.getLSB(i));
82 }
83
84 private double intersectAndGetOverlapWidth(Glyphs gv, int i) {
85 return getIntesection(gv, i).getBounds2D().getWidth();
86 }
87
88 private Area getIntesection(Glyphs gv, int index) {
89 Area intersect = new Area(gv.getOutline(index - 1));
90 intersect.intersect(new Area(gv.getOutline(index)));
91 return intersect;
92 }
93
94 private double getMaximumPossibleOverlap(Glyphs gv, int index) {
95 return Math.min(Math.min(overlapPixels, gv.getBoundsWidth(index)), gv.getBoundsWidth(index - 1));
96 }
97
98 private boolean mayGlyphsOverlapAtIndex(Glyphs gv, int index) {
99
100 return gv.getMinY(index-1)> gv.getMaxY(index)||gv.getMinY(index)>gv.getMaxY(index-1);
101
102 }
103 }