Package org.pentaho.reporting.engine.classic.core.modules.output.table.base

Source Code of org.pentaho.reporting.engine.classic.core.modules.output.table.base.TableLayoutProducer

/*
* 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 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.modules.output.table.base;

import org.pentaho.reporting.engine.classic.core.layout.model.BlockRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.LayoutNodeTypes;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderableReplacedContentBox;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorFeature;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorMetaData;
import org.pentaho.reporting.engine.classic.core.layout.process.IterateSimpleStructureProcessStep;

public class TableLayoutProducer extends IterateSimpleStructureProcessStep
{
  private SheetLayout layout;
  private long pageOffset;
  private boolean headerProcessed;
  private long contentOffset;
  private long effectiveHeaderSize;
  private long pageEndPosition;

  private boolean unalignedPagebands;
  private boolean processWatermark;

  public TableLayoutProducer(final OutputProcessorMetaData metaData)
  {
    initialize(metaData);
    this.layout = new SheetLayout(metaData);
  }

  private void initialize(final OutputProcessorMetaData metaData)
  {
    if (metaData == null)
    {
      throw new NullPointerException();
    }
    this.processWatermark = metaData.isFeatureSupported(OutputProcessorFeature.WATERMARK_SECTION);
    this.unalignedPagebands = metaData.isFeatureSupported(OutputProcessorFeature.UNALIGNED_PAGEBANDS);
  }

  public TableLayoutProducer(final OutputProcessorMetaData metaData,
                             final SheetLayout sheetLayout)
  {
    initialize(metaData);
    this.layout = sheetLayout;
  }

  public boolean isProcessWatermark()
  {
    return processWatermark;
  }

  public void setProcessWatermark(final boolean processWatermark)
  {
    this.processWatermark = processWatermark;
  }

  public SheetLayout getLayout()
  {
    return layout;
  }

  public void update(final LogicalPageBox logicalPage,
                     final boolean iterativeUpdate)
  {
    if (unalignedPagebands == false)
    {
      // The page-header and footer area are aligned/shifted within the logical pagebox so that all areas
      // share a common coordinate system. This also implies, that the whole logical page is aligned content.
      pageOffset = 0;
      effectiveHeaderSize = 0;
      pageEndPosition = logicalPage.getPageEnd();
      //Log.debug ("Content Processing " + pageOffset + " -> " + pageEnd);
      if (startBox(logicalPage))
      {
        if (headerProcessed == false)
        {
          if (processWatermark)
          {
            startProcessing(logicalPage.getWatermarkArea());
          }
          final BlockRenderBox headerArea = logicalPage.getHeaderArea();
          startProcessing(headerArea);
          headerProcessed = true;
        }

        processBoxChilds(logicalPage);
        if (iterativeUpdate == false)
        {
          final BlockRenderBox repeatFooterBox = logicalPage.getRepeatFooterArea();
          startProcessing(repeatFooterBox);

          final BlockRenderBox pageFooterBox = logicalPage.getFooterArea();
          startProcessing(pageFooterBox);
        }
      }
      finishBox(logicalPage);
    }
    else
    {
      // The page-header and footer area are not aligned/shifted within the logical pagebox.
      // All areas have their own coordinate system starting at (0,0). We apply a manual shift here
      // so that we dont have to modify the nodes (which invalidates the cache, and therefore is ugly)
      effectiveHeaderSize = 0;
      pageOffset = logicalPage.getPageOffset();
      pageEndPosition = (logicalPage.getPageEnd());
      if (startBox(logicalPage))
      {
        if (headerProcessed == false)
        {
          pageOffset = 0;
          contentOffset = 0;
          effectiveHeaderSize = 0;

          if (processWatermark)
          {
            final BlockRenderBox watermarkArea = logicalPage.getWatermarkArea();
            pageEndPosition = watermarkArea.getHeight();
            startProcessing(watermarkArea);
          }

          final BlockRenderBox headerArea = logicalPage.getHeaderArea();
          pageEndPosition = headerArea.getHeight();
          startProcessing(headerArea);
          contentOffset = headerArea.getHeight();
          headerProcessed = true;
        }

        pageOffset = logicalPage.getPageOffset();
        pageEndPosition = logicalPage.getPageEnd();
        effectiveHeaderSize = contentOffset;
        processBoxChilds(logicalPage);

        if (iterativeUpdate == false)
        {
          pageOffset = 0;
          final BlockRenderBox repeatFooterArea = logicalPage.getRepeatFooterArea();
          final long repeatFooterOffset = contentOffset + (logicalPage.getPageEnd() - logicalPage.getPageOffset());
          final long repeatFooterPageEnd = repeatFooterOffset + repeatFooterArea.getHeight();
          effectiveHeaderSize = repeatFooterOffset;
          pageEndPosition = repeatFooterPageEnd;
          startProcessing(repeatFooterArea);

          final BlockRenderBox footerArea = logicalPage.getFooterArea();
          final long footerPageEnd = repeatFooterPageEnd + footerArea.getHeight();
          effectiveHeaderSize = repeatFooterPageEnd;
          pageEndPosition = footerPageEnd;
          startProcessing(footerArea);
        }
      }
      finishBox(logicalPage);
    }

    // try to remove as many nodes as you can ..
    logicalPage.setProcessedTableOffset(logicalPage.getPageEnd());
  }

  protected boolean startBox(final RenderBox box)
  {
    if (box.isVisible() == false)
    {
      return false;
    }

    if (box.getLayoutNodeType() == LayoutNodeTypes.TYPE_BOX_CONTENT)
    {
      processRenderableContent((RenderableReplacedContentBox) box);
      return false;
    }

    return startBoxInternal(box);
  }

  private boolean startBoxInternal(final RenderBox box)
  {

    final long height = box.getHeight();
//
//    DebugLog.log ("Processing Box " + pageOffset + " " + effectiveHeaderSize + " " + box.getY() + " " + height);
//    DebugLog.log ("Processing Box " + box);

    if (height > 0)
    {
      if ((box.getY() + height) <= pageOffset)
      {
        return false;
      }
      if (box.getY() >= pageEndPosition)
      {
        return false;
      }
    }
    else
    {
      // zero height boxes are always a bit tricky ..
      if ((box.getY() + height) < pageOffset)
      {
        return false;
      }
      if (box.getY() > pageEndPosition)
      {
        return false;
      }
    }

    if (box.isOpen() == false &&
        box.isFinishedTable() == false &&
        box.isCommited())
    {
      if (layout.add(box, pageOffset, effectiveHeaderSize, pageEndPosition))
      {
        return false;
      }
      box.setFinishedTable(true);
      return true;
    }

    return true;
  }

  protected void processRenderableContent(final RenderableReplacedContentBox box)
  {
    if (box.isOpen() == false &&
        box.isFinishedTable() == false &&
        box.isCommited())
    {
      startBoxInternal(box);
      layout.addRenderableContent(box, pageOffset, effectiveHeaderSize, pageEndPosition);
    }
  }

  protected void processBoxChilds(final RenderBox box)
  {
    if (box.getLayoutNodeType() == LayoutNodeTypes.TYPE_BOX_PARAGRAPH)
    {
      // not needed. Keep this method empty so that the paragraph childs are *not* processed.
      return;
    }
    super.processBoxChilds(box);
  }

  public void pageCompleted()
  {
    layout.pageCompleted();
    headerProcessed = false;
  }

  /**
   * A designtime support method to compute a sheet layout for the given section. A new sheetlayout is created
   * on each call.
   *
   * @param box the section that should be processed.
   * @return the computed sheet layout.
   */
  public void computeDesigntimeConflicts(final RenderBox box)
  {
    clear();
    pageEndPosition = box.getHeight();

    startProcessing(box);
  }

  public void clear()
  {
    this.layout.clear();

    effectiveHeaderSize = 0;
    pageOffset = 0;
    pageEndPosition = 0;
    contentOffset = 0;
    headerProcessed = false;
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.output.table.base.TableLayoutProducer

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.