package com.octo.captcha.component.image.textpaster; import com.octo.captcha.CaptchaException; import com.octo.captcha.component.image.color.ColorGenerator; import com.octo.captcha.component.image.textpaster.glyphsvisitor.GlyphsVisitors; import com.octo.captcha.component.image.textpaster.glyphsdecorator.GlyphsDecorator; import java.awt.image.BufferedImage; import java.awt.*; import java.awt.geom.Rectangle2D; import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.text.AttributedString; import java.text.AttributedCharacterIterator; /** * Use Glyphs to draw, much more powerfull and efficient than using AttributedString * * @author mag * @Date 6 mars 2008 */ public class GlyphsPaster extends AbstractTextPaster{ private GlyphsVisitors[] glyphVisitors; private GlyphsDecorator[] glyphsDecorators; public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength) { super(minAcceptedWordLength, maxAcceptedWordLength); } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, Color textColor) { super(minAcceptedWordLength, maxAcceptedWordLength, textColor); } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator); } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator, Boolean manageColorPerGlyph) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator, manageColorPerGlyph); } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, GlyphsVisitors[] glyphVisitors) { super(minAcceptedWordLength, maxAcceptedWordLength); this.glyphVisitors = glyphVisitors; } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, Color textColor, GlyphsVisitors[] glyphVisitors) { super(minAcceptedWordLength, maxAcceptedWordLength, textColor); this.glyphVisitors = glyphVisitors; } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator, GlyphsVisitors[] glyphVisitors) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator); this.glyphVisitors = glyphVisitors; } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator, GlyphsVisitors[] glyphVisitors, GlyphsDecorator[] glyphsDecorators) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator); this.glyphVisitors = glyphVisitors; this.glyphsDecorators = glyphsDecorators; } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator, Boolean manageColorPerGlyph, GlyphsVisitors[] glyphVisitors) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator, manageColorPerGlyph); this.glyphVisitors = glyphVisitors; } public GlyphsPaster(Integer minAcceptedWordLength, Integer maxAcceptedWordLength, ColorGenerator colorGenerator, Boolean manageColorPerGlyph, GlyphsVisitors[] glyphVisitors, GlyphsDecorator[] glyphsDecorators) { super(minAcceptedWordLength, maxAcceptedWordLength, colorGenerator, manageColorPerGlyph); this.glyphVisitors = glyphVisitors; this.glyphsDecorators = glyphsDecorators; } public BufferedImage pasteText(BufferedImage background, AttributedString attributedWord) throws CaptchaException { BufferedImage out = copyBackground(background); Graphics2D g2 = pasteBackgroundAndSetTextColor(out, background); customizeGraphicsRenderingHints(g2); //build glyphs AttributedCharacterIterator acit = attributedWord.getIterator(); Glyphs glyphs = new Glyphs(); for(int i = 0 ; i < acit.getEndIndex(); i++){ Font font = (Font) acit.getAttribute(TextAttribute.FONT); g2.setFont(font); final FontRenderContext frc = g2.getFontRenderContext(); glyphs.addGlyphVector(font.createGlyphVector(frc,new char[]{acit.current()})); acit.next(); } Rectangle2D backgroundBounds = new Rectangle2D.Float(0,0,background.getWidth(),background.getHeight()); //First decorate if (glyphVisitors != null) { //System.out.println("\n"+glyphs); for (int i = 0; i < glyphVisitors.length; i++) { //System.out.println(glyphVisitors[i]); glyphVisitors[i].visit(glyphs,backgroundBounds); //System.out.println(glyphs); } /* if(!backgroundBounds.contains(glyphs.getBounds())){ StringBuffer error =new StringBuffer("Invalid visitor configuration : " + "\nTrying to move glyphs out of background\n Visitors:"); for (int i = 0; i < glyphVisitors.length; i++) { error.append("\n"); error.append(glyphVisitors[i]); } error.append("\nResulting string bounds : "); error.append(glyphs.getBounds()); throw new CaptchaException(error.toString()); } */ } for(int i = 0 ; i < glyphs.size(); i++){ g2.drawGlyphVector(glyphs.get(i),0,0); if(isManageColorPerGlyph())g2.setColor(getColorGenerator().getNextColor()); } //and now decorate if (glyphsDecorators != null) { for (int i = 0; i < glyphsDecorators.length; i++) { glyphsDecorators[i].decorate(g2, glyphs, background); } } g2.dispose(); return out; } }