Package limelight.ui.model.text

Source Code of limelight.ui.model.text.Lineator

//- Copyright © 2008-2011 8th Light, Inc. All Rights Reserved.
//- Limelight and all included source files are distributed under terms of the MIT License.

package limelight.ui.model.text;

import limelight.ui.model.TextPanel;
import limelight.ui.text.TypedLayout;

import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;

public class Lineator
{
  public static void parseTextForMultipleLayouts(TextModel model, ArrayList<TypedLayout> lines)
  {
    String text = model.getDisplayableText();
    AttributedString attrString = new AttributedString(text);
    attrString.addAttribute(TextAttribute.FONT, model.getFont());
    AttributedCharacterIterator iterator = attrString.getIterator();

    ArrayList<Integer> newLineCharIndices = findNewLineCharIndices(text);

    LineBreakMeasurer breaker = new LineBreakMeasurer(iterator, TextPanel.getRenderContext());
    int lastCharIndex = 0, newLineCharIndex = 0;
    while(breaker.getPosition() < iterator.getEndIndex())
    {
      lastCharIndex = addNewLayoutForTheNextLine(text, model, lines, breaker, lastCharIndex, newLineCharIndex, newLineCharIndices);
      if(layoutEndedOnNewLineChar(lastCharIndex, newLineCharIndex, newLineCharIndices))
        newLineCharIndex++;
    }
    addBlankLayoutIfLastLineIsEmpty(text, model, lines);
  }

  private static void addBlankLayoutIfLastLineIsEmpty(String text, TextModel model, ArrayList<TypedLayout> lines)
  {
    if(text.length() > 0 && isTheVeryLastCharANewLineChar(text))
      lines.add(model.createLayout(""));
  }

  private static int addNewLayoutForTheNextLine(String text, TextModel model, ArrayList<TypedLayout> lines, LineBreakMeasurer breaker, int lastCharIndex, int newLineCharIndex, ArrayList<Integer> newLineCharIndices)
  {
    int firstCharIndex = lastCharIndex;
    lastCharIndex = firstCharIndex + getNextLayout(model, breaker, newLineCharIndex, newLineCharIndices).getCharacterCount();
    String layoutText = text.substring(firstCharIndex, lastCharIndex);
    lines.add(model.createLayout(layoutText));
    return lastCharIndex;
  }

  private static boolean layoutEndedOnNewLineChar(int lastCharIndex, int returnCharIndex, ArrayList<Integer> newLineCharIndices)
  {
    return thereAreMoreReturnCharacters(returnCharIndex, newLineCharIndices) && lastCharIndex == newLineCharIndices.get(returnCharIndex) + 1;
  }

  private static TextLayout getNextLayout(TextModel model, LineBreakMeasurer breaker, int returnCharIndex, ArrayList<Integer> newLineCharIndices)
  {
    TextLayout layout;
    if(thereAreMoreReturnCharacters(returnCharIndex, newLineCharIndices))
      layout = breaker.nextLayout(model.getContainer().getWidth(), newLineCharIndices.get(returnCharIndex) + 1, false);
    else
      layout = breaker.nextLayout(model.getContainer().getWidth());
    return layout;
  }

  private static boolean isTheVeryLastCharANewLineChar(String text)
  {
    return text.endsWith("\n") || text.endsWith("\r\n");
  }

  private static boolean thereAreMoreReturnCharacters(int returnCharIndex, ArrayList<Integer> newLineCharIndices)
  {
    return newLineCharIndices != null && returnCharIndex < newLineCharIndices.size();
  }

  public static ArrayList<Integer> findNewLineCharIndices(String text)
  {
    ArrayList<Integer> indices = new ArrayList<Integer>();
    for(int i = 0; i < text.length(); i++)
    {
      if(text.charAt(i) == '\n')
        indices.add(i);
      else if(text.charAt(i) == '\r' && text.length() > (i+1) && text.charAt(i+1) == '\n')
      {
        indices.add(i+1);
        i++;
      }
    }
    return indices;
  }
}
TOP

Related Classes of limelight.ui.model.text.Lineator

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.