Package ket.display.box

Source Code of ket.display.box.BoxWord

/*
* Copyright (C) 2011  Alasdair C. Hamilton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package ket.display.box;

import geom.Offset;
import geom.Position;

import java.awt.*;
import java.awt.geom.*;
import java.util.Vector;

import ket.math.*;
import ket.display.ColourScheme;



/*
* handle display of a letter, symbol or word
*/
public class BoxWord extends Box {
  Font font;
  final String text;
  double ascent;
  //- Position topLeft = null;
  //- Offset actualSize = null;
  Vector<Integer> cumulativeWidths = null;
  //double decent; // not yet used

  /*
   * If HORIZONTAL_STRETCH or VERTICAL_STRETCH is set then this factor
   * describes how the font should be scaled horizontally.
   */
  double xFactor;

  /*
   * If HORIZONTAL_STRETCH or VERTICAL_STRETCH is set then this factor
   * describes how the font should be scaled vertically.
   */
  double yFactor;

  @Override
  public Box cloneBox() {
    return new BoxWord(getArgument(), text, getSettings());
  }

  public BoxWord(Argument argument, String text, long settings) {
    super(argument, settings);
    this.text = text;
    this.font = null;
    this.ascent = 0.0;
    this.xFactor = 1.0;
    this.yFactor = 1.0;
  }

  /*
   * Change the font to a given size and style.
   */
  @Override
  protected void fontSetup(int parentFontSize) {
    super.fontSetup(parentFontSize);
    int style = 0;
    if (hasProperty(BOLD_FONT)) {
      style |= Font.BOLD;
    } else if (hasProperty(PLAIN_FONT)) {
      style |= Font.PLAIN;
    } else {
      style |= Font.ITALIC;
    }
    font = new Font(//! Font.DIALOG,
      "Times New Roman",
      style,
      fontSize);
    boolean invalid = false;
    for (int i=0; i<text.length(); i++) {
      int codePoint = text.codePointAt(i);
      if ( ! font.canDisplay(codePoint) ) {
        invalid = true;
      }
    }
    if (invalid) {
      font = new Font(
        Font.DIALOG,
        style,
        (int) (TEXT_SCALE_FACTOR*fontSize));
    }
  }

  /*
   * Use the font to determine the size of the text.
   */
  @Override
  protected void calcMinimumSize() {
    FontMetrics fontMetrics = getFontMetrics(font);
    int width = fontMetrics.stringWidth(text);
    int decent = fontMetrics.getDescent();
    ascent = fontMetrics.getAscent();
    innerRectangle = new Offset(width, decent+ascent);
  }

  private int getFontProperty() {
    if (hasProperty(BOLD_FONT)) {
      return Font.BOLD;
    } else if (hasProperty(PLAIN_FONT)) {
      return Font.PLAIN;
    } else {
      return Font.ITALIC;
    }
  }

  @Override
  public void setupOuterRectangle(Offset actualSize) {
    FontMetrics fontMetrics = getFontMetrics(font);
    cumulativeWidths = new Vector<Integer>();
    if (hasProperty(HORIZONTAL_STRETCH) || hasProperty(VERTICAL_STRETCH)) {
      int oldAscent = fontMetrics.getAscent();
      int oldDescent = fontMetrics.getDescent();
      int oldWidth = fontMetrics.stringWidth(text);
      for (int fontSize=SMALLEST_FONT_SIZE-1; fontSize<=LARGEST_FONT_SIZE; fontSize++) {
        font = new Font("Times New Roman", getFontProperty(), fontSize);
        fontMetrics = getFontMetrics(font);
        ascent = fontMetrics.getAscent();
        int newDescent = fontMetrics.getDescent();
        int newWidth = fontMetrics.stringWidth(text);

        if (hasProperty(HORIZONTAL_STRETCH) && hasProperty(VERTICAL_STRETCH)) {
          xFactor = newWidth / (double) oldWidth;
          yFactor = (ascent+newDescent) / (double) (oldAscent+oldDescent);
        } else if (hasProperty(HORIZONTAL_STRETCH)) {
          xFactor = actualSize.width / (double) oldWidth;
          yFactor = (ascent+newDescent) / (double) (oldAscent+oldDescent);
        } else if (hasProperty(VERTICAL_STRETCH)) {
          xFactor = newWidth / (double) oldWidth;
          yFactor = actualSize.height / (double) (oldAscent+oldDescent);
        }

        // TODO: In the case of horizontal and vertical
        // stretches, this box should expand in size, but this
        // is currently beyond the scope of this inheritance
        // hierarchy.
        if (hasProperty(PRESERVE_ASPECT_RATIO)) {
          xFactor = Math.min(xFactor, yFactor);
          yFactor = xFactor;
        }

        if (xFactor>=1 && yFactor>=1) {
          break;
        }
      }
    }
    // Record cumulative widths of the string.
    for (int q=1; q<text.length(); q++) {
      int width = fontMetrics.stringWidth(text.substring(0, q));
      cumulativeWidths.add(width);
    }
    // Use the actual size to appropriately lay out the component. 
    super.setupOuterRectangle(actualSize);
 

  public int getIndex(Position p) {
    if (topLeft==null || cumulativeWidths==null) {
      return -1;
    }
    int boxIndent = (int) getXPosition(topLeft);
    for (int q=1; q<cumulativeWidths.size(); q++) {
      boolean bounded = 0<=p.x && p.x<boxIndent+cumulativeWidths.get(q)//? boxIndent
      if (bounded) {
        return q;
      }
    }
    return -1;
  }

  @Override
  public void draw(Graphics2D g2D, Position topLeft, ColourScheme colourScheme) {
    this.topLeft = topLeft;
    double x = getXPosition(topLeft);
    double y = getYPosition(topLeft);
    if (hasProperty(HORIZONTAL_STRETCH) || hasProperty(VERTICAL_STRETCH)) {
      g2D.setFont(font);
      AffineTransform originalTransformation = g2D.getTransform();
      g2D.translate(x, y);
      g2D.scale(xFactor, yFactor);
      g2D.drawString(text, 0, (float) ascent);
      g2D.setTransform(originalTransformation);
    } else {
      g2D.setFont(font);
      g2D.drawString(text, (float) x, (float) (y + ascent));
    }
  }

  public String getText() {
    return text;
  }

  public String toString() {
    return "BoxWord('" + text + "'; font:" + font + ", ascent:" + ascent +
      " | " + super.toString();
  }

  @Override
  public boolean withinInnerRectangle(Position p) {
    if (getText().trim().equals("")) return false;
    return super.withinInnerRectangle(p);
  }

}
  
TOP

Related Classes of ket.display.box.BoxWord

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.