Package org.pentaho.reporting.engine.classic.core.layout.model

Source Code of org.pentaho.reporting.engine.classic.core.layout.model.RenderableText

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2001 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.layout.model;

import org.pentaho.reporting.engine.classic.core.ReportAttributeMap;
import org.pentaho.reporting.engine.classic.core.layout.model.context.NodeLayoutProperties;
import org.pentaho.reporting.engine.classic.core.layout.text.ExtendedBaselineInfo;
import org.pentaho.reporting.engine.classic.core.layout.text.Glyph;
import org.pentaho.reporting.engine.classic.core.layout.text.GlyphList;
import org.pentaho.reporting.engine.classic.core.metadata.ElementType;
import org.pentaho.reporting.engine.classic.core.style.StyleSheet;
import org.pentaho.reporting.engine.classic.core.util.InstanceID;
import org.pentaho.reporting.libraries.fonts.encoding.CodePointBuffer;
import org.pentaho.reporting.libraries.fonts.text.Spacing;
import org.pentaho.reporting.libraries.fonts.text.breaks.BreakOpportunityProducer;


/**
* The renderable text is a text chunk, enriched with layouting information, such as break opportunities, character
* sizes, kerning information and spacing information.
* <p/>
* Text is given as codepoints. Break opportunities are given as integer values, where zero forbids breaking, and higher
* values denote better breaks. Spacing and glyph sizes and kerning is given in micro-points; Spacing is the 'added'
* space between codepoints if text-justification is enabled.
* <p/>
* The text is computed as grapheme clusters; this means that several unicode codepoints may result in a single
* /virtual/ glyph/codepoint/character. (Example: 'A' + accent symbols). If the font supports Lithurges, these lithurges
* may also be represented as a single grapheme cluster (and thus behave unbreakable).
* <p/>
* Grapheme clusters with more than one unicode char have the size of that char added to the first codepoint, all
* subsequence codepoints of the same cluster have a size/kerning/etc of zero and are unbreakable.
* <p/>
* This text chunk is perfectly suitable for horizontal text, going either from left-to-right or right-to-left.
* (Breaking mixed text is up to the textfactory).
*
* @author Thomas Morgner
*/
public final class RenderableText extends RenderNode
{
  private GlyphList glyphs;
  private int offset;
  private int length;
  private boolean ltr;
  private int script;

  private long minimumWidth;
  private long preferredWidth;
  private boolean forceLinebreak;
  private ExtendedBaselineInfo baselineInfo;
  private boolean normalTextSpacing;

  public RenderableText(final StyleSheet layoutContext,
                        final ElementType elementType,
                        final InstanceID instanceID,
                        final ReportAttributeMap attributes,
                        final ExtendedBaselineInfo baselineInfo,
                        final GlyphList glyphs,
                        final int offset,
                        final int length,
                        final int script,
                        final boolean forceLinebreak)
  {
    super(elementType, attributes, new NodeLayoutProperties(layoutContext, instanceID));
    initialize(glyphs, offset, length, baselineInfo, script, forceLinebreak);
  }

  protected void initialize(final GlyphList glyphs,
                            final int offset,
                            final int length,
                            final ExtendedBaselineInfo baselineInfo,
                            final int script, final boolean forceLinebreak)
  {
    if (glyphs == null)
    {
      throw new NullPointerException();
    }
    if (forceLinebreak == false && length == 0)
    {
      throw new IllegalArgumentException("Do not create zero-length renderable text!");
    }
    if (glyphs.getSize() < (offset + length))
    {
      throw new IllegalArgumentException();
    }

    this.baselineInfo = baselineInfo;
    this.ltr = true; // this depends on the script value
    this.script = script;

    this.glyphs = glyphs;
    this.offset = offset;
    this.length = length;
    this.forceLinebreak = forceLinebreak;

    normalTextSpacing = true;
    long wordMinChunkWidth = 0;

//    long heightAbove = 0;
//    long heightBelow = 0;
    long minimumChunkWidth = 0;

    long realCharTotal = 0;
    long spacerMin = 0;
    long spacerMax = 0;
    long spacerOpt = 0;

    final int lastPos = Math.min(glyphs.getSize(), offset + length);
    for (int i = offset; i < lastPos; i++)
    {
      final Glyph glyph = glyphs.getGlyph(i);
      //      heightAbove = Math.max(glyph.getBaseLine(), heightAbove);
      //      heightBelow = Math.max(glyph.getHeight() - glyph.getBaseLine(), heightBelow);
      final int kerning = glyph.getKerning();
      final int width = glyph.getWidth();
      final int realCharSpace = width - kerning;
      realCharTotal += realCharSpace;
      if (i == (lastPos - 1))
      {
        wordMinChunkWidth += realCharSpace;
      }
      else
      {
        final Spacing spacing = glyph.getSpacing();
        spacerMax += spacing.getMaximum();
        spacerMin += spacing.getMinimum();
        spacerOpt += spacing.getOptimum();
        if (normalTextSpacing == true &&
            Spacing.EMPTY_SPACING.equals(spacing) == false)
        {
          normalTextSpacing = false;
        }

        wordMinChunkWidth += spacing.getMinimum() + realCharSpace;
      }

      if (glyph.getBreakWeight() > BreakOpportunityProducer.BREAK_CHAR)
      {
        minimumChunkWidth = Math.max(minimumChunkWidth, wordMinChunkWidth);
        wordMinChunkWidth = 0;

        // Paranoid sanity checks: The word- and linebreaks should have been
        // replaced by other definitions in the text factory.
        if (glyph.getBreakWeight() == BreakOpportunityProducer.BREAK_LINE)
        {
          throw new IllegalStateException("A renderable text cannot and must " +
              "not contain linebreaks.");
        }
      }
    }

    final long wordMinWidth = spacerMin + realCharTotal;
    final long wordPrefWidth = spacerOpt + realCharTotal;
    final long wordMaxWidth = spacerMax + realCharTotal;

    minimumChunkWidth = Math.max(minimumChunkWidth, wordMinChunkWidth);
    minimumWidth = wordMinWidth;
    preferredWidth = wordPrefWidth;

    setMaximumBoxWidth(wordMaxWidth);
    setMinimumChunkWidth(minimumChunkWidth);
  }

  public int getNodeType()
  {
    return LayoutNodeTypes.TYPE_NODE_TEXT;
  }

  public boolean isNormalTextSpacing()
  {
    return normalTextSpacing;
  }

  public boolean isForceLinebreak()
  {
    return forceLinebreak;
  }

  public boolean isLtr()
  {
    return ltr;
  }

  public GlyphList getGlyphs()
  {
    return glyphs;
  }

  public int getOffset()
  {
    return offset;
  }

  public int getLength()
  {
    return length;
  }

  public String getRawText()
  {
    final GlyphList gs = getGlyphs();
    return gs.getText(offset, length, new CodePointBuffer(length));
  }

  public boolean isEmpty()
  {
    return length == 0 && forceLinebreak == false;
  }

  public boolean isDiscardable()
  {
    if (forceLinebreak)
    {
      return false;
    }

    return glyphs.getSize() == 0;
  }

  /**
   * Returns the baseline info for the given node. This can be null, if the node does not have any baseline info.
   *
   * @return
   */
  public ExtendedBaselineInfo getBaselineInfo()
  {
    return baselineInfo;
  }

  public int getScript()
  {
    return script;
  }

  public long getMinimumWidth()
  {
    return minimumWidth;
  }

  public long getPreferredWidth()
  {
    return preferredWidth;
  }

  public String toString()
  {
    return "RenderableText={glyphs=" + glyphs + "'}";
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.layout.model.RenderableText

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.