View Javadoc

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         // super.decorate(gv, backroundBounds);
24  
25          //evaluate overlapPixel
26  
27          for (int i = 1; i < gv.size(); i++) {
28              //System.out.println("I "+i);
29              //first position the shapes near the preceding one
30               gv.translate(i, getSidingPosition(gv, i), 0);
31  
32              //then evaluate if there is a real overlap
33              if (mayGlyphsOverlapAtIndex(gv, i)) {
34                  //ok overlap is possible, try to reach
35                  double realPossibleOverlap = getMaximumPossibleOverlap(gv, i);
36                  double currentOverlapWidth = intersectAndGetOverlapWidth(gv, i);
37                  double currentOverlapStatus = currentOverlapWidth - realPossibleOverlap;
38                  double bestReacheadOverlapStatus = Math.abs(currentOverlapStatus);
39                 // System.out.println("Real possible "+realPossibleOverlap);
40                  boolean stillOk=true;
41                 // System.out.println("bestReacheadOverlapStatus : "+bestReacheadOverlapStatus);
42                  while (Math.abs(currentOverlapStatus) >= overlapPixels/10&&stillOk) {
43                      double step = currentOverlapStatus/2;
44                      //System.out.println("translated "+ step);
45                      gv.translate(i, step, 0);
46                      currentOverlapWidth = intersectAndGetOverlapWidth(gv, i);
47                      currentOverlapStatus = currentOverlapWidth-realPossibleOverlap;
48                      //System.out.println("bestReacheadOverlapStatus : "+bestReacheadOverlapStatus);
49                      //System.out.println("currentOverlapStatus : "+currentOverlapStatus);
50  
51  
52                      //we already reach the best overlap
53                      if(Math.abs(currentOverlapStatus)>=bestReacheadOverlapStatus&&(currentOverlapWidth!=0||gv.getMaxX(i-1)-gv.getMinX(i)>gv.getBoundsWidth(i-1))){
54                          //System.out.println("BREAK");
55                          //tranlsate back
56                          if(currentOverlapWidth==0){
57                              //back to siding
58                              gv.translate(i, getSidingPosition(gv, i), 0);
59                              //System.out.println("no overlap");
60                          }else{
61                              //back on step
62                              gv.translate(i, -step, 0);
63                             // System.out.println("best reached");
64                          }
65                         // System.out.println("currentOverlapStatus : "+(intersectAndGetOverlapWidth(gv, i)-realPossibleOverlap));
66                          stillOk=false;
67                      }
68                      bestReacheadOverlapStatus = Math.min(Math.abs(currentOverlapStatus),bestReacheadOverlapStatus);
69                  }
70              //System.out.println("bestReacheadOverlapStatus : "+bestReacheadOverlapStatus);
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 }