View Javadoc

1   /*
2    * JCaptcha, the open source java framework for captcha definition and integration
3    * Copyright (c)  2007 jcaptcha.net. All Rights Reserved.
4    * See the LICENSE.txt file distributed with this package.
5    */
6   package com.octo.captcha.component.image.textpaster;
7   
8   import com.octo.captcha.CaptchaException;
9   import com.octo.captcha.component.image.color.ColorGenerator;
10  
11  import java.awt.*;
12  import java.awt.font.TextAttribute;
13  import java.awt.geom.Rectangle2D;
14  import java.awt.image.BufferedImage;
15  import java.text.AttributedCharacterIterator;
16  import java.text.AttributedString;
17  import java.util.HashMap;
18  import java.util.Map;
19  
20  /***
21   * A <code>TextPaster</code> that pasts the characters on the background image, turned around a random angle from the
22   * center of the character and past at a random y position.
23   *
24   * @author Martijn van Groningen
25   * @since Nov 11, 2007
26   *
27   *
28    * @deprecated 
29   */
30  public class NonLinearRandomAngleTextPaster extends AbstractTextPaster {
31  
32      private Map renderingHints = new HashMap();
33  
34      public NonLinearRandomAngleTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength,
35                                            Color textColor) {
36          super(minAcceptedWordLength, maxAcceptedWordLength, textColor);
37      }
38  
39      public NonLinearRandomAngleTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength,
40                                            ColorGenerator colorGenerator) {
41          super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator);
42      }
43  
44      public NonLinearRandomAngleTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength,
45                                            ColorGenerator colorGenerator, Boolean manageColorPerGlyph) {
46          super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator, manageColorPerGlyph);
47      }
48  
49      /***
50       * @see com.octo.captcha.component.image.textpaster.AbstractTextPaster#pasteText(java.awt.image.BufferedImage, java.text.AttributedString)
51       */
52      public BufferedImage pasteText(final BufferedImage background, final AttributedString attributedWord) throws CaptchaException {
53          BufferedImage out = copyBackground(background);
54          Graphics2D g2d = pasteBackgroundAndSetTextColor(out, background);
55          g2d.setRenderingHints(renderingHints);
56          g2d.translate(10, background.getHeight() / 2);
57  
58          AttributedCharacterIterator iterator = attributedWord.getIterator();
59          while (iterator.getIndex() != iterator.getEndIndex()) {
60              AttributedString character = new AttributedString(String.valueOf(iterator.current()));
61              character.addAttribute(TextAttribute.FONT, iterator.getAttribute(TextAttribute.FONT));
62              pasteCharacter(g2d, character);
63              iterator.next();
64          }
65  
66          g2d.dispose();
67          return out;
68      }
69  
70      /***
71       * Draws a certain character on the <code>BufferedImage</code> with a random angle and y pos.
72       * If the characters angle is greater then 90 degrees and lower then 270 degrees, the bottom
73       * of the character will be underlined.
74       *
75       * @param g2d       The graphics of the <code>BufferedImage</code>
76       * @param character The character to be drawn
77       */
78      protected void pasteCharacter(Graphics2D g2d, AttributedString character) {
79          Font font = (Font) character.getIterator().getAttribute(TextAttribute.FONT);
80          Rectangle2D rectangle = g2d.getFontMetrics(font).getStringBounds(String.valueOf(character.getIterator().current()), g2d);
81          double angle = getRandomAngle();
82          int maxTranslatedY = (int) g2d.getTransform().getTranslateY();
83          double y = myRandom.nextBoolean() ? myRandom.nextInt(maxTranslatedY) : -myRandom.nextInt(maxTranslatedY - (int) rectangle.getHeight());
84  
85          g2d.setFont(font);
86          g2d.translate(0, y);
87          if ((angle >= Math.PI / 2 || angle <= -(Math.PI / 2))) {
88              character.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL);
89          }
90  
91          g2d.rotate(angle, rectangle.getX() + (rectangle.getWidth() / 2), rectangle.getY() + (rectangle.getHeight() / 2));
92          g2d.drawString(character.getIterator(), 0, 0);
93          g2d.rotate(-angle, rectangle.getX() + (rectangle.getWidth() / 2), rectangle.getY() + (rectangle.getHeight() / 2));
94          g2d.translate(rectangle.getHeight(), -y);
95      }
96  
97      /***
98       * Returns a random angle between 0 and 360 degrees in radians (inclusive).
99       *
100      * @return a random angle between 0 and 360 degrees in radians
101      */
102     protected double getRandomAngle() {
103         double number = myRandom.nextDouble() * myRandom.nextInt(10) + 1;
104         double angle = Math.PI / number;
105         return myRandom.nextBoolean() ? angle : -angle;
106     }
107 
108     /***
109      * Adds <code>RenderingHints</code> for the drawing of the characters.
110      *
111      * @param key   The RenderingHints Key
112      * @param value The RenderingHints value
113      */
114     public void addRenderingHints(RenderingHints.Key key, Object value) {
115         renderingHints.put(key, value);
116     }
117 }