Package org.jwildfire.transform

Source Code of org.jwildfire.transform.TextTransformer$ModeEditor

/*
  JWildfire - an image and animation processor written in Java
  Copyright (C) 1995-2011 Andreas Maschke

  This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
  General Public License as published by the Free Software Foundation; either version 2.1 of the
  License, or (at your option) any later version.
  This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with this software;
  if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.transform;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import org.jwildfire.base.Property;
import org.jwildfire.base.PropertyCategory;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.base.Tools;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;

import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;

public class TextTransformer extends Mesh2DTransformer {
  public enum FontStyle {
    PLAIN, BOLD, ITALIC
  }

  public enum Mode {
    NORMAL, OUTLINE
  }

  public enum HAlignment {
    CENTRE, LEFT, RIGHT, NONE
  }

  public enum VAlignment {
    CENTRE, TOP, BOTTOM, NONE
  }

  @Property(description = "1st row of text")
  private String text1;

  @Property(description = "2nd row of text")
  private String text2;

  @Property(description = "3rd row of text")
  private String text3;

  @Property(description = "4th row of text")
  private String text4;

  @Property(description = "5th row of text")
  private String text5;

  @Property(description = "6th row of text")
  private String text6;

  @Property(description = "7th row of text")
  private String text7;

  @Property(category = PropertyCategory.SECONDARY, description = "Horizontal alignment of the text", editorClass = HAlignmentEditor.class)
  private HAlignment hAlign = HAlignment.CENTRE;

  @Property(category = PropertyCategory.SECONDARY, description = "Vertical alignment of the text", editorClass = VAlignmentEditor.class)
  private VAlignment vAlign = VAlignment.CENTRE;

  @Property(description = "Name of the font", editorClass = FontNameEditor.class)
  private String fontName;

  @Property(description = "Size of the font")
  private int fontSize;

  @Property(description = "Offset to the base-line of the font")
  private int baseLineOffset = 0;

  @Property(description = "Style of the font", editorClass = FontStyleEditor.class, category = PropertyCategory.SECONDARY)
  private FontStyle fontStyle;

  @Property(description = "Text color")
  private Color color;

  @Property(description = "Text mode", editorClass = ModeEditor.class)
  private Mode mode;

  @Property(description = "Text position in x-direction (when no alignment")
  private int posX;

  @Property(description = "Text position in y-direction (when no alignment")
  private int posY;

  @PropertyMin(1)
  @Property(description = "Outline width (mode=OUTLINE)", category = PropertyCategory.SECONDARY)
  private int outlineWidth;

  @Property(description = "Enable antialiasing")
  private boolean antialiasing;

  private class TextRenderInfo {
    private Font font;
    int maxWidth = 0, maxHeight = 0, maxRow = 0;
    int yOffset = 0;
    int areaHeight;
  }

  private TextRenderInfo createTextRenderInfo(SimpleImage pImg, List<TextRow> pRows) {
    // create font and calculate the row sizes
    TextRenderInfo res = new TextRenderInfo();
    {
      Graphics g = pImg.getGraphics();
      {
        int fontStyle;
        switch (this.fontStyle) {
          case BOLD:
            fontStyle = Font.BOLD;
            break;
          case ITALIC:
            fontStyle = Font.ITALIC;
            break;
          default:
            fontStyle = Font.PLAIN;
            break;
        }
        res.font = new Font(this.fontName, fontStyle, this.fontSize);
      }
      g.setFont(res.font);
      FontMetrics fm = g.getFontMetrics();
      res.yOffset = fm.getMaxAscent();
      FontRenderContext frc = fm.getFontRenderContext();
      for (TextRow row : pRows) {
        Rectangle2D rect = res.font.getStringBounds(row.text, frc);
        row.width = (int) (rect.getWidth() + 0.5);
        row.height = (int) (rect.getHeight() + 0.5);
        if (this.mode == Mode.OUTLINE) {
          row.width += 2 * this.outlineWidth;
          row.height += 2 * this.outlineWidth;
        }
        row.height += baseLineOffset;
        if (row.width > res.maxWidth)
          res.maxWidth = row.width;
        if (row.height > res.maxHeight)
          res.maxHeight = row.height;
        if (row.row > res.maxRow)
          res.maxRow = row.row;
      }
    }
    res.areaHeight = (res.maxRow + 1) * res.maxHeight;
    return res;
  }

  public Dimension calculateTextSize() {
    SimpleImage img = new SimpleImage(320, 256);
    List<TextRow> rows = getRows();
    if ((rows == null) || (rows.size() < 1))
      return new Dimension(0, 0);
    TextRenderInfo renderInfo = createTextRenderInfo(img, rows);
    return new Dimension(renderInfo.maxWidth, renderInfo.areaHeight);
  }

  @Override
  protected void performPixelTransformation(WFImage pImg) {
    SimpleImage img = (SimpleImage) pImg;
    List<TextRow> rows = getRows();
    if ((rows == null) || (rows.size() < 1))
      return;

    // calculate the offsets
    // int areaWidth = maxWidth;
    TextRenderInfo renderInfo = createTextRenderInfo(img, rows);
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    for (TextRow row : rows) {
      switch (hAlign) {
        case CENTRE:
          row.left = (width - row.width) / 2;
          break;
        case LEFT:
          row.left = 0;
          break;
        case RIGHT:
          row.left = width - row.width;
          break;
        case NONE:
          row.left = posX;
      }
      switch (vAlign) {
        case CENTRE:
          row.top = (height - renderInfo.areaHeight) / 2 + row.row * renderInfo.maxHeight;
          break;
        case TOP:
          row.top = row.row * renderInfo.maxHeight;
          break;
        case BOTTOM:
          row.top = height - (renderInfo.maxRow + 1 - row.row) * renderInfo.maxHeight;
          break;
        case NONE:
          row.top = posY + row.row * renderInfo.maxHeight;
      }
      row.top += baseLineOffset;
    }

    // draw the text
    int offLeft, offRight;
    if (this.mode == Mode.OUTLINE) {
      offLeft = offRight = this.outlineWidth;
    }
    else {
      offLeft = offRight = 0;
    }
    switch (this.mode) {
      case NORMAL: {
        Graphics g = img.getGraphics();
        g.setFont(renderInfo.font);
        g.setColor(this.color);
        Graphics2D g2d = (Graphics2D) g;
        if (antialiasing) {
          g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
              RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
        for (TextRow row : rows) {
          g.drawString(row.text, offLeft + row.left, offRight + row.top + renderInfo.yOffset);
        }
      }
        break;
      case OUTLINE: {
        SimpleImage textImg = new SimpleImage(width, height);
        Graphics g = textImg.getGraphics();
        g.setFont(renderInfo.font);
        g.setColor(this.color);
        Graphics2D g2d = (Graphics2D) g;
        if (antialiasing) {
          g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
              RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
        for (TextRow row : rows) {
          g.drawString(row.text, offLeft + row.left, offRight + row.top + renderInfo.yOffset);
        }
        SimpleImage dilateImg = textImg.clone();
        {
          ErodeTransformer eT = new ErodeTransformer();
          eT.setMode(ErodeTransformer.Mode.DILATE);
          eT.setSize(2 * this.outlineWidth + 1);
          eT.setShape(ErodeTransformer.Shape.DISK);
          eT.transformImage(dilateImg);
        }
        {
          AddTransformer aT = new AddTransformer();
          aT.setMode(AddTransformer.Mode.SUBTRACT);
          aT.setForegroundImage(textImg);
          aT.transformImage(dilateImg);
        }
        {
          AlphaComposeTransformer cT = new AlphaComposeTransformer();
          cT.setForegroundImage(dilateImg);
          SimpleImage alphaImg = dilateImg.clone();
          new ColorToGrayTransformer().transformImage(alphaImg);
          cT.setAlphaChannelImage(alphaImg);
          cT.transformImage(img);
        }
      }
        break;
    }

    // apply the text mask to the image
    /*
    pImg.setBufferedImage(textImg.getBufferedImg(), textImg.getImageWidth(),
        textImg.getImageHeight());*/
  }

  private List<TextRow> getRows() {
    List<TextRow> res = new ArrayList<TextRow>();
    if ((text1 != null) && (text1.length() > 0))
      res.add(new TextRow(0, text1));
    if ((text2 != null) && (text2.length() > 0))
      res.add(new TextRow(1, text2));
    if ((text3 != null) && (text3.length() > 0))
      res.add(new TextRow(2, text3));
    if ((text4 != null) && (text4.length() > 0))
      res.add(new TextRow(3, text4));
    if ((text5 != null) && (text5.length() > 0))
      res.add(new TextRow(4, text5));
    if ((text6 != null) && (text6.length() > 0))
      res.add(new TextRow(5, text6));
    if ((text7 != null) && (text7.length() > 0))
      res.add(new TextRow(6, text7));
    return res;
  }

  private class TextRow {
    public int row;
    public String text;
    public int width;
    public int height;
    public int left;
    public int top;

    public TextRow(int pRow, String pText) {
      row = pRow;
      text = pText;
    }
  }

  @Override
  public void initDefaultParams(WFImage pImg) {
    text1 = Tools.APP_TITLE;
    text2 = "is";
    text3 = "cool :-)";
    fontName = "Arial";
    fontStyle = FontStyle.PLAIN;
    fontSize = 120;
    color = new Color(255, 0, 51);
    mode = Mode.NORMAL;
    outlineWidth = 3;
    antialiasing = true;
    hAlign = HAlignment.CENTRE;
    vAlign = VAlignment.CENTRE;
  }

  public static class FontStyleEditor extends ComboBoxPropertyEditor {
    public FontStyleEditor() {
      super();
      setAvailableValues(new FontStyle[] { FontStyle.PLAIN, FontStyle.BOLD, FontStyle.ITALIC });
    }
  }

  public static class ModeEditor extends ComboBoxPropertyEditor {
    public ModeEditor() {
      super();
      setAvailableValues(new Mode[] { Mode.NORMAL, Mode.OUTLINE });
    }
  }

  private static String[] availableFontNames = null;

  private static String[] getAvailableFontNames() {
    if (availableFontNames == null) {
      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
      availableFontNames = ge.getAvailableFontFamilyNames();
    }
    return availableFontNames;
  }

  public static class FontNameEditor extends ComboBoxPropertyEditor {
    public FontNameEditor() {
      super();
      setAvailableValues(getAvailableFontNames());
    }
  }

  public String getFontName() {
    return fontName;
  }

  public void setFontName(String fontName) {
    this.fontName = fontName;
  }

  public int getFontSize() {
    return fontSize;
  }

  public void setFontSize(int fontSize) {
    this.fontSize = fontSize;
  }

  public FontStyle getFontStyle() {
    return fontStyle;
  }

  public void setFontStyle(FontStyle fontStyle) {
    this.fontStyle = fontStyle;
  }

  public Color getColor() {
    return color;
  }

  public void setColor(Color color) {
    this.color = color;
  }

  public Mode getMode() {
    return mode;
  }

  public void setMode(Mode mode) {
    this.mode = mode;
  }

  public int getOutlineWidth() {
    return outlineWidth;
  }

  public void setOutlineWidth(int outlineWidth) {
    this.outlineWidth = outlineWidth;
  }

  public boolean isAntialiasing() {
    return antialiasing;
  }

  public void setAntialiasing(boolean antialiasing) {
    this.antialiasing = antialiasing;
  }

  public String getText1() {
    return text1;
  }

  public void setText1(String text1) {
    this.text1 = text1;
  }

  public String getText2() {
    return text2;
  }

  public void setText2(String text2) {
    this.text2 = text2;
  }

  public String getText3() {
    return text3;
  }

  public void setText3(String text3) {
    this.text3 = text3;
  }

  public String getText4() {
    return text4;
  }

  public void setText4(String text4) {
    this.text4 = text4;
  }

  public String getText5() {
    return text5;
  }

  public void setText5(String text5) {
    this.text5 = text5;
  }

  public String getText6() {
    return text6;
  }

  public void setText6(String text6) {
    this.text6 = text6;
  }

  public String getText7() {
    return text7;
  }

  public void setText7(String text7) {
    this.text7 = text7;
  }

  public static class HAlignmentEditor extends ComboBoxPropertyEditor {
    public HAlignmentEditor() {
      super();
      setAvailableValues(new HAlignment[] { HAlignment.CENTRE, HAlignment.LEFT, HAlignment.RIGHT, HAlignment.NONE });
    }
  }

  public static class VAlignmentEditor extends ComboBoxPropertyEditor {
    public VAlignmentEditor() {
      super();
      setAvailableValues(new VAlignment[] { VAlignment.CENTRE, VAlignment.TOP, VAlignment.BOTTOM, VAlignment.NONE });
    }
  }

  public HAlignment getHAlign() {
    return hAlign;
  }

  public void setHAlign(HAlignment hAlign) {
    this.hAlign = hAlign;
  }

  public VAlignment getVAlign() {
    return vAlign;
  }

  public void setVAlign(VAlignment vAlign) {
    this.vAlign = vAlign;
  }

  public int getBaseLineOffset() {
    return baseLineOffset;
  }

  public void setBaseLineOffset(int baseLineOffset) {
    this.baseLineOffset = baseLineOffset;
  }

  public int getPosX() {
    return posX;
  }

  public void setPosX(int posX) {
    this.posX = posX;
  }

  public int getPosY() {
    return posY;
  }

  public void setPosY(int posY) {
    this.posY = posY;
  }
}
TOP

Related Classes of org.jwildfire.transform.TextTransformer$ModeEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.