| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.afp; |
| |
| import java.awt.geom.AffineTransform; |
| |
| import org.apache.fop.fo.Constants; |
| import org.apache.fop.render.intermediate.BorderPainter; |
| import org.apache.fop.util.ColorUtil; |
| |
| /** |
| * Handles the drawing of borders/lines in AFP |
| */ |
| public class AFPBorderPainter extends AbstractAFPPainter { |
| |
| /** |
| * Main constructor |
| * |
| * @param paintingState the AFP painting state converter |
| * @param dataStream the AFP datastream |
| */ |
| public AFPBorderPainter(AFPPaintingState paintingState, DataStream dataStream) { |
| super(paintingState, dataStream); |
| } |
| |
| /** {@inheritDoc} */ |
| public void paint(PaintingInfo paintInfo) { |
| BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo; |
| float w = borderPaintInfo.getX2() - borderPaintInfo.getX1(); |
| float h = borderPaintInfo.getY2() - borderPaintInfo.getY1(); |
| if ((w < 0) || (h < 0)) { |
| log.error("Negative extent received. Border won't be painted."); |
| return; |
| } |
| |
| int pageWidth = dataStream.getCurrentPage().getWidth(); |
| int pageHeight = dataStream.getCurrentPage().getHeight(); |
| AFPUnitConverter unitConv = paintingState.getUnitConverter(); |
| AffineTransform at = paintingState.getData().getTransform(); |
| |
| float x1 = unitConv.pt2units(borderPaintInfo.getX1()); |
| float y1 = unitConv.pt2units(borderPaintInfo.getY1()); |
| float x2 = unitConv.pt2units(borderPaintInfo.getX2()); |
| float y2 = unitConv.pt2units(borderPaintInfo.getY2()); |
| |
| switch (paintingState.getRotation()) { |
| case 90: |
| x1 += at.getTranslateY(); |
| y1 += (float) (pageWidth - at.getTranslateX()); |
| x2 += at.getTranslateY(); |
| y2 += (float) (pageWidth - at.getTranslateX()); |
| break; |
| case 180: |
| x1 += (float) (pageWidth - at.getTranslateX()); |
| y1 += (float) (pageHeight - at.getTranslateY()); |
| x2 += (float) (pageWidth - at.getTranslateX()); |
| y2 += (float) (pageHeight - at.getTranslateY()); |
| break; |
| case 270: |
| x1 = (float) (pageHeight - at.getTranslateY()); |
| y1 += (float) at.getTranslateX(); |
| x2 += x1; |
| y2 += (float) at.getTranslateX(); |
| break; |
| case 0: |
| default: |
| x1 += at.getTranslateX(); |
| y1 += at.getTranslateY(); |
| x2 += at.getTranslateX(); |
| y2 += at.getTranslateY(); |
| break; |
| } |
| |
| AFPLineDataInfo lineDataInfo = new AFPLineDataInfo(); |
| lineDataInfo.setColor(borderPaintInfo.getColor()); |
| lineDataInfo.setRotation(paintingState.getRotation()); |
| lineDataInfo.setX1(Math.round(x1)); |
| lineDataInfo.setY1(Math.round(y1)); |
| float thickness; |
| if (borderPaintInfo.isHorizontal()) { |
| thickness = y2 - y1; |
| } else { |
| thickness = x2 - x1; |
| } |
| lineDataInfo.setThickness(Math.round(thickness)); |
| |
| // handle border-*-style |
| switch (borderPaintInfo.getStyle()) { |
| case Constants.EN_DOUBLE: |
| int thickness3 = (int)Math.floor(thickness / 3f); |
| lineDataInfo.setThickness(thickness3); |
| if (borderPaintInfo.isHorizontal()) { |
| lineDataInfo.setX2(Math.round(x2)); |
| lineDataInfo.setY2(lineDataInfo.getY1()); |
| dataStream.createLine(lineDataInfo); |
| int distance = thickness3 * 2; |
| lineDataInfo = new AFPLineDataInfo(lineDataInfo); |
| lineDataInfo.setY1(lineDataInfo.getY1() + distance); |
| lineDataInfo.setY2(lineDataInfo.getY2() + distance); |
| dataStream.createLine(lineDataInfo); |
| } else { |
| lineDataInfo.setX2(lineDataInfo.getX1()); |
| lineDataInfo.setY2(Math.round(y2)); |
| dataStream.createLine(lineDataInfo); |
| int distance = thickness3 * 2; |
| lineDataInfo = new AFPLineDataInfo(lineDataInfo); |
| lineDataInfo.setX1(lineDataInfo.getX1() + distance); |
| lineDataInfo.setX2(lineDataInfo.getX2() + distance); |
| dataStream.createLine(lineDataInfo); |
| } |
| break; |
| case Constants.EN_DASHED: |
| if (borderPaintInfo.isHorizontal()) { |
| int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(w, h)); |
| lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth); |
| lineDataInfo.setY2(lineDataInfo.getY1()); |
| int ex2 = Math.round(x2); |
| int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth); |
| while (lineDataInfo.getX2() <= ex2) { |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setX1(lineDataInfo.getX2() + spaceWidth); |
| lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth); |
| } |
| } else { |
| int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(h, w)); |
| lineDataInfo.setX2(lineDataInfo.getX1()); |
| lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth); |
| int ey2 = Math.round(y2); |
| int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth); |
| while (lineDataInfo.getY2() <= ey2) { |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setY1(lineDataInfo.getY2() + spaceWidth); |
| lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth); |
| } |
| } |
| break; |
| case Constants.EN_DOTTED: |
| if (borderPaintInfo.isHorizontal()) { |
| lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness()); |
| lineDataInfo.setY2(lineDataInfo.getY1()); |
| int ex2 = Math.round(x2); |
| while (lineDataInfo.getX1() + lineDataInfo.getThickness() < ex2) { |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setX1(lineDataInfo.getX1() + 3 * lineDataInfo.getThickness()); |
| lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness()); |
| } |
| } else { |
| lineDataInfo.setX2(lineDataInfo.getX1()); |
| lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness()); |
| int ey2 = Math.round(y2); |
| while (lineDataInfo.getY1() + lineDataInfo.getThickness() < ey2) { |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setY1(lineDataInfo.getY1() + 3 * lineDataInfo.getThickness()); |
| lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness()); |
| } |
| } |
| break; |
| case Constants.EN_GROOVE: |
| case Constants.EN_RIDGE: |
| //TODO |
| int yNew; |
| lineDataInfo.setX2(Math.round(x2)); |
| float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f); |
| float h3 = (y2 - y1) / 3; |
| lineDataInfo.setColor( |
| ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor)); |
| lineDataInfo.setThickness(Math.round(h3)); |
| yNew = Math.round(y1); |
| lineDataInfo.setY1(yNew); |
| lineDataInfo.setY2(yNew); |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setColor(borderPaintInfo.getColor()); |
| yNew = Math.round(y1 + h3); |
| lineDataInfo.setY1(yNew); |
| lineDataInfo.setY2(yNew); |
| dataStream.createLine(lineDataInfo); |
| lineDataInfo.setColor(ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor)); |
| yNew = Math.round(y1 + h3 + h3); |
| lineDataInfo.setY1(yNew); |
| lineDataInfo.setY2(yNew); |
| dataStream.createLine(lineDataInfo); |
| break; |
| case Constants.EN_HIDDEN: |
| break; |
| case Constants.EN_INSET: |
| case Constants.EN_OUTSET: |
| case Constants.EN_SOLID: |
| default: |
| if (borderPaintInfo.isHorizontal()) { |
| lineDataInfo.setX2(Math.round(x2)); |
| lineDataInfo.setY2(lineDataInfo.getY1()); |
| } else { |
| lineDataInfo.setX2(lineDataInfo.getX1()); |
| lineDataInfo.setY2(Math.round(y2)); |
| } |
| dataStream.createLine(lineDataInfo); |
| } |
| } |
| |
| } |