1
2
3
4
5
6
7 package com.octo.captcha.component.image.textpaster;
8
9 import com.octo.captcha.CaptchaException;
10 import com.octo.captcha.component.image.color.ColorGenerator;
11 import com.octo.captcha.component.image.color.SingleColorGenerator;
12
13 import java.awt.*;
14 import java.awt.image.BufferedImage;
15 import java.security.SecureRandom;
16 import java.util.Random;
17 import java.text.AttributedString;
18
19 /***
20 * <p/>
21 * Base class for Test pasters. Sub classes must implement the pasteText(BufferedImage background, AttributedString
22 * attributedWord) method that return an image containing the pasted string.</br> use constructor to specify your paster
23 * properties. This base class use two Integers, maxAcceptedWordLength and minAcceptedWordLength by wich are the length
24 * boundaries for the implementation. By default minAcceptedWordLength = 6 and maxAcceptedWordLength = 20 </p>
25 *
26 * @author <a href="mailto:mag@jcaptcha.net">Marc-Antoine Garrigue </a>
27 * @version 1.0
28 */
29 public abstract class AbstractTextPaster implements TextPaster {
30 /***
31 * Comment for <code>myRandom</code>
32 */
33 public Random myRandom = new SecureRandom();
34
35 /***
36 * Max length of a word
37 */
38 private int max = 20;
39
40 /***
41 * Min length of a word
42 */
43 private int min = 6;
44
45 /***
46 * ColorGenerator for the text paster
47 */
48 private ColorGenerator colorGenerator = new SingleColorGenerator(Color.black);
49
50 /***
51 * If false (default) color is set for the whole test, otherwise each glyph can have its owne color
52 */
53 private boolean manageColorPerGlyph = false;
54
55 /***
56 * Default constructor with just min and max length of a word
57 *
58 * @param minAcceptedWordLength Max length of a word
59 * @param maxAcceptedWordLength Min length of a word
60 */
61 AbstractTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength) {
62 this.max = maxAcceptedWordLength != null ? maxAcceptedWordLength.intValue() : this.max;
63 this.min = minAcceptedWordLength != null && minAcceptedWordLength.intValue() <= this.max ? minAcceptedWordLength
64 .intValue()
65 : Math.min(this.min, this.max - 1);
66 }
67
68 /***
69 * Default constructor with unique color of text
70 *
71 * @param minAcceptedWordLength Max length of a word
72 * @param maxAcceptedWordLength Min length of a word
73 * @param textColor Unique color of text
74 */
75 AbstractTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, Color textColor) {
76 this(minAcceptedWordLength, maxAcceptedWordLength);
77
78 if (textColor != null) {
79 this.colorGenerator = new SingleColorGenerator(textColor);
80 }
81 }
82
83 /***
84 * Default Constructor with a color generator for the text
85 */
86 AbstractTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength,
87 ColorGenerator colorGenerator) {
88 this(minAcceptedWordLength, maxAcceptedWordLength);
89 if (colorGenerator == null) {
90 throw new CaptchaException("ColorGenerator is null");
91 }
92 this.colorGenerator = colorGenerator;
93 }
94
95 /***
96 * Default Constructor with a color generator for the text, and color is managed per glyph, each glyph can have a
97 * new color
98 *
99 * @param manageColorPerGlyph Boolean to set if each glyph can have a new color from the color generator
100 */
101 AbstractTextPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength,
102 ColorGenerator colorGenerator, Boolean manageColorPerGlyph) {
103 this(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator);
104 this.manageColorPerGlyph = manageColorPerGlyph != null ? manageColorPerGlyph.booleanValue() : this.manageColorPerGlyph;
105 }
106
107 /***
108 * @return the max word length accepted by this word2image service
109 * @deprecated misspelled, use {@link #getMaxAcceptedWordLength()} instead
110 */
111 public int getMaxAcceptedWordLenght() {
112 return max;
113 }
114
115 /***
116 * @return the min word length accepted by this word2image service
117 * @deprecated misspelled, use {@link #getMinAcceptedWordLength()} instead
118 */
119 public int getMinAcceptedWordLenght() {
120 return min;
121 }
122
123 /***
124 * @return the max word length accepted by this word2image service
125 */
126 public int getMaxAcceptedWordLength() {
127 return max;
128 }
129
130 /***
131 * @return the min word length accepted by this word2image service
132 */
133 public int getMinAcceptedWordLength() {
134 return min;
135 }
136
137
138 /***
139 * @return the color generator
140 */
141 protected ColorGenerator getColorGenerator() {
142 return colorGenerator;
143 }
144
145 /***
146 * @return the copy of the background
147 */
148 BufferedImage copyBackground(final BufferedImage background) {
149 BufferedImage out = new BufferedImage(background.getWidth(), background.getHeight(),
150 background.getType());
151 return out;
152 }
153
154 /***
155 * @param out
156 * @param background
157 * @return a graphic2D
158 */
159 Graphics2D pasteBackgroundAndSetTextColor(BufferedImage out, final BufferedImage background) {
160 Graphics2D pie = (Graphics2D) out.getGraphics();
161
162 pie.drawImage(background, 0, 0, out.getWidth(), out.getHeight(), null);
163
164 pie.setColor(colorGenerator.getNextColor());
165 return pie;
166 }
167
168
169 void customizeGraphicsRenderingHints(Graphics2D g2){
170 g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
171 RenderingHints.VALUE_FRACTIONALMETRICS_ON);
172 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
173 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
174 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
175 }
176
177 /***
178 * @return true if this component manage color per glyph
179 */
180 public boolean isManageColorPerGlyph() {
181 return manageColorPerGlyph;
182 }
183
184 /***
185 * @param colorGenerator
186 */
187 public void setColorGenerator(ColorGenerator colorGenerator) {
188 this.colorGenerator = colorGenerator;
189 }
190
191
192 }