1
2
3
4
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 }