Package org.pentaho.reporting.engine.classic.core.modules.output.table.html.helper

Source Code of org.pentaho.reporting.engine.classic.core.modules.output.table.html.helper.DefaultStyleBuilderFactory

/*
* 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) 2006 - 2013 Pentaho Corporation..  All rights reserved.
*/

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

import java.awt.Color;
import java.text.NumberFormat;

import org.pentaho.reporting.engine.classic.core.ElementAlignment;
import org.pentaho.reporting.engine.classic.core.layout.model.Border;
import org.pentaho.reporting.engine.classic.core.layout.model.BorderCorner;
import org.pentaho.reporting.engine.classic.core.layout.model.BorderEdge;
import org.pentaho.reporting.engine.classic.core.layout.model.context.BoxDefinition;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.CellBackground;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.util.HtmlColors;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.util.HtmlEncoderUtil;
import org.pentaho.reporting.engine.classic.core.style.ElementStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.StyleSheet;
import org.pentaho.reporting.engine.classic.core.style.TextStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.WhitespaceCollapse;
import org.pentaho.reporting.engine.classic.core.util.geom.StrictGeomUtility;
import org.pentaho.reporting.libraries.base.config.Configuration;

@SuppressWarnings("HardCodedStringLiteral")
public class DefaultStyleBuilderFactory implements StyleBuilderFactory
{
  private boolean safariLengthFix;
  private boolean useWhitespacePreWrap;
  private boolean enableRoundBorderCorner;

  public DefaultStyleBuilderFactory()
  {
  }

  public boolean isSafariLengthFix()
  {
    return safariLengthFix;
  }

  public boolean isUseWhitespacePreWrap()
  {
    return useWhitespacePreWrap;
  }

  public boolean isEnableRoundBorderCorner()
  {
    return enableRoundBorderCorner;
  }

  public StyleBuilder produceTextStyle(StyleBuilder styleBuilder,
                                       final StyleSheet styleSheet,
                                       final BoxDefinition boxDefinition,
                                       final boolean includeBorder,
                                       final StyleBuilder.StyleCarrier[] parentElementStyle)
  {
    if (styleSheet == null)
    {
      throw new NullPointerException();
    }
    if (styleBuilder == null)
    {
      styleBuilder = new DefaultStyleBuilder(this);
    }
    else
    {
      styleBuilder.clear();
    }

    final FilterStyleBuilder filterStyleBuilder = new FilterStyleBuilder(styleBuilder, parentElementStyle);
    final NumberFormat pointConverter = filterStyleBuilder.getPointConverter();
    final Color textColor = (Color) styleSheet.getStyleProperty(ElementStyleKeys.PAINT);
    final Color backgroundColor = (Color) styleSheet.getStyleProperty(ElementStyleKeys.BACKGROUND_COLOR);
    if (backgroundColor != null)
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.BACKGROUND_COLOR, HtmlColors.getColorString(backgroundColor));
    }

    if (includeBorder)
    {
      processBorder(styleSheet, boxDefinition, filterStyleBuilder, pointConverter);
    }
    if (textColor != null)
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.COLOR, HtmlColors.getColorString(textColor));
    }

    processFontStyle(styleSheet, filterStyleBuilder, pointConverter);
    processTextDecoration(styleSheet, filterStyleBuilder);

    final ElementAlignment align = (ElementAlignment) styleSheet.getStyleProperty(ElementStyleKeys.ALIGNMENT);
    filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.TEXT_ALIGN, translateHorizontalAlignment(align));

    final double wordSpacing = styleSheet.getDoubleStyleProperty(TextStyleKeys.WORD_SPACING, 0);
    filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.WORD_SPACING, pointConverter.format
        (fixLengthForSafari(wordSpacing)), "pt");

    final double minLetterSpacing = styleSheet.getDoubleStyleProperty(TextStyleKeys.X_MIN_LETTER_SPACING, 0);
    final double maxLetterSpacing = styleSheet.getDoubleStyleProperty(TextStyleKeys.X_MAX_LETTER_SPACING, 0);
    filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.LETTER_SPACING, pointConverter.format
        (fixLengthForSafari(Math.min(minLetterSpacing, maxLetterSpacing))), "pt");

    processWhiteSpaceCollapse(styleSheet, filterStyleBuilder);

    return styleBuilder;
  }

  private void processWhiteSpaceCollapse(final StyleSheet styleSheet, final FilterStyleBuilder filterStyleBuilder)
  {
    final WhitespaceCollapse wsCollapse = (WhitespaceCollapse)
        styleSheet.getStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE);
    if (WhitespaceCollapse.PRESERVE.equals(wsCollapse))
    {
      if (useWhitespacePreWrap)
      {
        // this style does not work for IE6 and IE7, but heck, in that case they just behave as if normal mode is
        // selected. In that case multiple spaces are collapsed into a single space.
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.WHITE_SPACE, "pre-wrap");
      }
      else
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.WHITE_SPACE, "pre");
      }
    }
    else if (WhitespaceCollapse.PRESERVE_BREAKS.equals(wsCollapse))
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.WHITE_SPACE, "nowrap");
    }
    else
    {
      // discard is handled on the layouter level already;
      // collapse is the normal way of handling whitespaces in the engine.
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.WHITE_SPACE, "normal");
    }
  }

  private void processFontStyle(final StyleSheet styleSheet,
                                final FilterStyleBuilder filterStyleBuilder,
                                final NumberFormat pointConverter)
  {
    filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.FONT_FAMILY, translateFontFamily(styleSheet));
    filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.FONT_SIZE, pointConverter.format
        (fixLengthForSafari(styleSheet.getDoubleStyleProperty(TextStyleKeys.FONTSIZE, 0))), "pt");
    if (styleSheet.getBooleanStyleProperty(TextStyleKeys.BOLD))
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.FONT_WEIGHT, "bold");
    }
    else
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.FONT_WEIGHT, "normal");
    }

    if (styleSheet.getBooleanStyleProperty(TextStyleKeys.ITALIC))
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.FONT_STYLE, "italic");
    }
    else
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.FONT_STYLE, "normal");
    }
  }

  private void processTextDecoration(final StyleSheet styleSheet, final FilterStyleBuilder filterStyleBuilder)
  {
    final boolean underlined = styleSheet.getBooleanStyleProperty(TextStyleKeys.UNDERLINED);
    final boolean strikeThrough = styleSheet.getBooleanStyleProperty(TextStyleKeys.STRIKETHROUGH);
    if (underlined && strikeThrough)
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.TEXT_DECORATION, "underline line-through");
    }
    else if (strikeThrough)
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.TEXT_DECORATION, "line-through");
    }
    if (underlined)
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.TEXT_DECORATION, "underline");
    }
    else
    {
      filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.TEXT_DECORATION, "none");
    }
  }

  private void processBorder(final StyleSheet styleSheet,
                             final BoxDefinition boxDefinition,
                             final FilterStyleBuilder filterStyleBuilder,
                             final NumberFormat pointConverter)
  {
    final Border border = boxDefinition.getBorder();
    final BorderEdge top = border.getTop();
    final BorderEdge left = border.getLeft();
    final BorderEdge bottom = border.getBottom();
    final BorderEdge right = border.getRight();
    if (top.equals(left) &&
        top.equals(right) &&
        top.equals(bottom))
    {
      if (BorderEdge.EMPTY.equals(top) == false)
      {
        filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER, filterStyleBuilder.printEdgeAsCSS(top));
      }
    }
    else
    {
      if (top != null && BorderEdge.EMPTY.equals(top) == false)
      {
        filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_TOP, filterStyleBuilder.printEdgeAsCSS(top));
      }
      if (left != null && BorderEdge.EMPTY.equals(left) == false)
      {
        filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_LEFT, filterStyleBuilder.printEdgeAsCSS(left));
      }
      if (bottom != null && BorderEdge.EMPTY.equals(bottom) == false)
      {
        filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM, filterStyleBuilder.printEdgeAsCSS(bottom));
      }
      if (right != null && BorderEdge.EMPTY.equals(right) == false)
      {
        filterStyleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_RIGHT, filterStyleBuilder.printEdgeAsCSS(right));
      }
    }
    if (enableRoundBorderCorner)
    {
      final double blW = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_BOTTOM_LEFT_RADIUS_WIDTH, 0));
      final double blH = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_BOTTOM_LEFT_RADIUS_HEIGHT, 0));
      if (blW > 0 && blH > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_BOTTOM_LEFT,
            pointConverter.format(fixLengthForSafari(blW)) + "pt " +
                pointConverter.format(fixLengthForSafari(blH)) + "pt");
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM_LEFT_RADIUS,
            pointConverter.format(fixLengthForSafari(blW)) + "pt " +
                pointConverter.format(fixLengthForSafari(blH)) + "pt");
      }

      final double brW = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_BOTTOM_RIGHT_RADIUS_WIDTH, 0));
      final double brH = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_BOTTOM_RIGHT_RADIUS_HEIGHT, 0));
      if (brW > 0 && brH > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_BOTTOM_RIGHT,
            pointConverter.format(fixLengthForSafari(brW)) + "pt " +
                pointConverter.format(fixLengthForSafari(brH)) + "pt");
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM_RIGHT_RADIUS,
            pointConverter.format(fixLengthForSafari(brW)) + "pt " +
                pointConverter.format(fixLengthForSafari(brH)) + "pt");
      }

      final double tlW = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_TOP_LEFT_RADIUS_WIDTH, 0));
      final double tlH = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_TOP_LEFT_RADIUS_HEIGHT, 0));
      if (tlW > 0 && tlH > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_TOP_LEFT,
            pointConverter.format(fixLengthForSafari(tlW)) + "pt " +
                pointConverter.format(fixLengthForSafari(tlH)) + "pt");
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_TOP_LEFT_RADIUS,
            pointConverter.format(fixLengthForSafari(tlW)) + "pt " +
                pointConverter.format(fixLengthForSafari(tlH)) + "pt");
      }

      final double trW = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_TOP_RIGHT_RADIUS_WIDTH, 0));
      final double trH = Math.max(0, styleSheet.getDoubleStyleProperty(ElementStyleKeys.BORDER_TOP_RIGHT_RADIUS_HEIGHT, 0));
      if (trW > 0 && trH > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_TOP_RIGHT,
            pointConverter.format(fixLengthForSafari(trW)) + "pt " +
                pointConverter.format(fixLengthForSafari(trH)) + "pt");
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_TOP_RIGHT_RADIUS,
            pointConverter.format(fixLengthForSafari(trW)) + "pt " +
                pointConverter.format(fixLengthForSafari(trH)) + "pt");
      }
    }

    final long paddingTop = boxDefinition.getPaddingTop();
    final long paddingLeft = boxDefinition.getPaddingLeft();
    final long paddingBottom = boxDefinition.getPaddingBottom();
    final long paddingRight = boxDefinition.getPaddingRight();
    if (paddingTop == paddingLeft && paddingTop == paddingRight && paddingTop == paddingBottom)
    {
      if (paddingTop > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.PADDING, pointConverter.format
            (fixLengthForSafari(StrictGeomUtility.toExternalValue(paddingTop))), "pt");
      }
    }
    else
    {
      if (paddingTop > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.PADDING_TOP, pointConverter.format
            (fixLengthForSafari(StrictGeomUtility.toExternalValue(paddingTop))), "pt");
      }
      if (paddingLeft > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.PADDING_LEFT, pointConverter.format
            (fixLengthForSafari(StrictGeomUtility.toExternalValue(paddingLeft))), "pt");
      }
      if (paddingBottom > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.PADDING_BOTTOM, pointConverter.format
            (fixLengthForSafari(StrictGeomUtility.toExternalValue(paddingBottom))), "pt");
      }
      if (paddingRight > 0)
      {
        filterStyleBuilder.append(DefaultStyleBuilder.CSSKeys.PADDING_RIGHT, pointConverter.format
            (fixLengthForSafari(StrictGeomUtility.toExternalValue(paddingRight))), "pt");
      }
    }
  }


  private static String translateFontFamily(final StyleSheet box)
  {
    final String family = (String) box.getStyleProperty(TextStyleKeys.FONT);
    if ("Serif".equalsIgnoreCase(family))
    {
      return "serif";
    }
    else if ("Sans-serif".equalsIgnoreCase(family) || "SanSerif".equalsIgnoreCase(
        family) || "SansSerif".equalsIgnoreCase(family) ||
        "Dialog".equalsIgnoreCase(family) || "DialogInput".equalsIgnoreCase(family))
    {
      return "sans-serif";
    }
    else if ("Monospaced".equalsIgnoreCase(family))
    {
      return "monospace";
    }
    else
    {
      return '\"' + HtmlEncoderUtil.encodeCSS(family) + '\"';
    }
  }

  public double fixLengthForSafari(final double border)
  {
    if (safariLengthFix == false)
    {
      return border;
    }
    if (border == 0)
    {
      return 0;
    }
    return Math.max(1, Math.round(border));
  }


  /**
   * Translates the JFreeReport horizontal element alignment into a HTML alignment constant.
   *
   * @param ea the element alignment
   * @return the translated alignment name.
   */
  public static String translateHorizontalAlignment(final ElementAlignment ea)
  {
    if (ElementAlignment.JUSTIFY.equals(ea))
    {
      return "justify";
    }
    if (ElementAlignment.RIGHT.equals(ea))
    {
      return "right";
    }
    if (ElementAlignment.CENTER.equals(ea))
    {
      return "center";
    }
    return "left";
  }


  public void configure(final Configuration configuration)
  {
    safariLengthFix = ("true".equals(configuration.getConfigProperty
        ("org.pentaho.reporting.engine.classic.core.modules.output.table.html.SafariLengthHack")));
    useWhitespacePreWrap = ("true".equals(configuration.getConfigProperty
        ("org.pentaho.reporting.engine.classic.core.modules.output.table.html.UseWhitespacePreWrap")));
    enableRoundBorderCorner = ("true".equals(configuration.getConfigProperty
        ("org.pentaho.reporting.engine.classic.core.modules.output.table.html.EnableRoundBorderCorner")));
  }


  public StyleBuilder createCellStyle(StyleBuilder styleBuilder,
                                      final CellBackground background,
                                      final StyleBuilder.CSSKeys[] extraStyleKeys,
                                      final String[] extraStyleValues)
  {
    return createCellStyle(styleBuilder, null, null, background, extraStyleKeys, extraStyleValues);
  }

  public StyleBuilder createCellStyle(StyleBuilder styleBuilder,
                                      final StyleSheet styleSheet,
                                      final BoxDefinition boxDefinition,
                                      final CellBackground background,
                                      final StyleBuilder.CSSKeys[] extraStyleKeys,
                                      final String[] extraStyleValues)
  {
    if (styleBuilder == null)
    {
      throw new NullPointerException();
    }
    if (styleSheet == null)
    {
      styleBuilder.clear();
    }
    else
    {
      styleBuilder = produceTextStyle(styleBuilder, styleSheet, boxDefinition, true, null);
    }

    // Add the extra styles
    if (extraStyleKeys != null
        && extraStyleValues != null
        && extraStyleKeys.length == extraStyleValues.length)
    {
      for (int i = 0; i < extraStyleKeys.length; ++i)
      {
        styleBuilder.append(extraStyleKeys[i], extraStyleValues[i], false);
      }
    }

    if (background != null)
    {
      final Color colorValue = (background.getBackgroundColor());
      if (colorValue != null)
      {
        styleBuilder.append(DefaultStyleBuilder.CSSKeys.BACKGROUND_COLOR, HtmlColors.getColorString(colorValue));
      }

      final BorderEdge topEdge = background.getTop();
      final BorderEdge leftEdge = background.getLeft();
      final BorderEdge bottomEdge = background.getBottom();
      final BorderEdge rightEdge = background.getRight();
      if (topEdge.equals(leftEdge) &&
          topEdge.equals(rightEdge) &&
          topEdge.equals(bottomEdge))
      {
        if (BorderEdge.EMPTY.equals(topEdge) == false)
        {
          styleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER, styleBuilder.printEdgeAsCSS(topEdge));
        }
      }
      else
      {
        if (BorderEdge.EMPTY.equals(topEdge) == false)
        {
          styleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_TOP, styleBuilder.printEdgeAsCSS(topEdge));
        }
        if (BorderEdge.EMPTY.equals(leftEdge) == false)
        {
          styleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_LEFT, styleBuilder.printEdgeAsCSS(leftEdge));
        }
        if (BorderEdge.EMPTY.equals(bottomEdge) == false)
        {
          styleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM, styleBuilder.printEdgeAsCSS(bottomEdge));
        }
        if (BorderEdge.EMPTY.equals(rightEdge) == false)
        {
          styleBuilder.appendRaw(DefaultStyleBuilder.CSSKeys.BORDER_RIGHT, styleBuilder.printEdgeAsCSS(rightEdge));
        }
      }

      if (isEnableRoundBorderCorner())
      {
        final BorderCorner topLeft = background.getTopLeft();
        if (BorderCorner.EMPTY.equals(topLeft) == false)
        {
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_TOP_LEFT, styleBuilder.printCornerAsCSS(topLeft));
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_TOP_LEFT_RADIUS, styleBuilder.printCornerAsCSS(topLeft));
        }

        final BorderCorner topRight = background.getTopRight();
        if (BorderCorner.EMPTY.equals(topRight) == false)
        {
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_TOP_RIGHT, styleBuilder.printCornerAsCSS(topRight));
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_TOP_RIGHT_RADIUS, styleBuilder.printCornerAsCSS(topRight));
        }

        final BorderCorner bottomLeft = background.getBottomLeft();
        if (BorderCorner.EMPTY.equals(bottomLeft) == false)
        {
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_BOTTOM_LEFT, styleBuilder.printCornerAsCSS(bottomLeft));
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM_LEFT_RADIUS, styleBuilder.printCornerAsCSS(bottomLeft));
        }

        final BorderCorner bottomRight = background.getBottomRight();
        if (BorderCorner.EMPTY.equals(bottomRight) == false)
        {
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.MOZ_BORDER_RADIUS_BOTTOM_RIGHT, styleBuilder.printCornerAsCSS(bottomRight));
          styleBuilder.append(DefaultStyleBuilder.CSSKeys.BORDER_BOTTOM_RIGHT_RADIUS, styleBuilder.printCornerAsCSS(bottomRight));
        }
      }
    }
    return styleBuilder;
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.modules.output.table.html.helper.DefaultStyleBuilderFactory

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.