├── .gitignore ├── src ├── test │ ├── resources │ │ ├── error01.jpg │ │ ├── error02.jpg │ │ ├── Bertrand1-figure.png │ │ ├── Bertrand1-figure-withres.png │ │ ├── test.svg │ │ ├── test01.html │ │ ├── test02.html │ │ └── LongSpanAndParagraph.html │ └── java │ │ └── net │ │ └── sf │ │ └── mcf2pdf │ │ └── util │ │ └── ImageUtilTest.java └── main │ ├── resources │ ├── linux-x86-64 │ │ └── libwebp.so │ ├── win32-x86-64 │ │ └── libwebp.dll │ └── log4j.properties │ ├── java │ └── net │ │ └── sf │ │ └── mcf2pdf │ │ ├── mcfelements │ │ ├── McfCorners.java │ │ ├── McfCorner.java │ │ ├── McfBundlesize.java │ │ ├── McfBorder.java │ │ ├── McfPosition.java │ │ ├── McfCutout.java │ │ ├── McfClipart.java │ │ ├── McfImageBackground.java │ │ ├── McfAreaContent.java │ │ ├── McfText.java │ │ ├── McfBackground.java │ │ ├── impl │ │ │ ├── AbstractMcfAreaContentImpl.java │ │ │ ├── McfCornersImpl.java │ │ │ ├── McfBundlesizeImpl.java │ │ │ ├── McfImageBackgroundImpl.java │ │ │ ├── McfCutoutImpl.java │ │ │ ├── McfClipartImpl.java │ │ │ ├── McfBorderImpl.java │ │ │ ├── McfCornerImpl.java │ │ │ ├── McfTextImpl.java │ │ │ ├── McfPageImpl.java │ │ │ ├── McfPositionImpl.java │ │ │ ├── McfBackgroundImpl.java │ │ │ ├── McfFotobookImpl.java │ │ │ ├── McfPageNumImpl.java │ │ │ ├── McfImageImpl.java │ │ │ └── McfAreaImpl.java │ │ ├── McfPageNum.java │ │ ├── McfImage.java │ │ ├── util │ │ │ ├── webp │ │ │ │ ├── WebpLib.java │ │ │ │ └── Webp.java │ │ │ ├── DigesterUtil.java │ │ │ ├── McfFileUtil.java │ │ │ ├── XslFoDocumentBuilder.java │ │ │ ├── ClpInputStream.java │ │ │ ├── PdfUtil.java │ │ │ └── FadingComposite.java │ │ ├── McfFotobook.java │ │ ├── McfPage.java │ │ ├── DigesterConfigurator.java │ │ ├── McfArea.java │ │ └── FotobookBuilder.java │ │ ├── mcfconfig │ │ ├── Template.java │ │ ├── Fotoarea.java │ │ ├── Clipart.java │ │ ├── Decoration.java │ │ └── Fading.java │ │ ├── mcfglobals │ │ ├── McfFotoFrame.java │ │ ├── McfAlbumType.java │ │ ├── impl │ │ │ ├── McfProductCatalogueImpl.java │ │ │ └── McfAlbumTypeImpl.java │ │ ├── McfProductCatalogue.java │ │ └── McfResourceScanner.java │ │ ├── pagebuild │ │ ├── AbstractPageBuilder.java │ │ ├── PageImageBackground.java │ │ ├── PageBuilder.java │ │ ├── FormattedText.java │ │ ├── PageBinding.java │ │ ├── SVGPageBuilder.java │ │ ├── PageClipart.java │ │ ├── BitmapPageBuilder.java │ │ ├── PageNum.java │ │ ├── PageDrawable.java │ │ ├── FormattedTextParagraph.java │ │ ├── PageBackground.java │ │ ├── PageRenderContext.java │ │ └── PageImage.java │ │ └── Main.java │ └── assembly │ ├── licenseText.properties │ ├── mcf2pdf │ ├── src.xml │ ├── mcf2pdf.bat │ ├── classpath.unix │ ├── classpath.win │ ├── classpath-filter.win │ ├── zip.xml │ └── tgz.xml ├── .settings ├── org.eclipse.m2e.core.prefs ├── org.eclipse.core.resources.prefs └── org.eclipse.jdt.core.prefs ├── .project ├── .classpath ├── mcf2pdf.iml ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | target 5 | .idea 6 | *.pdf -------------------------------------------------------------------------------- /src/test/resources/error01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/test/resources/error01.jpg -------------------------------------------------------------------------------- /src/test/resources/error02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/test/resources/error02.jpg -------------------------------------------------------------------------------- /src/test/resources/Bertrand1-figure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/test/resources/Bertrand1-figure.png -------------------------------------------------------------------------------- /src/main/resources/linux-x86-64/libwebp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/main/resources/linux-x86-64/libwebp.so -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /src/main/resources/win32-x86-64/libwebp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/main/resources/win32-x86-64/libwebp.dll -------------------------------------------------------------------------------- /src/test/resources/Bertrand1-figure-withres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbodziony/mcf2pdf/HEAD/src/test/resources/Bertrand1-figure-withres.png -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfCorners.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | import java.util.List; 4 | 5 | public interface McfCorners { 6 | public List getCorners(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfCorner.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | public interface McfCorner { 4 | 5 | public int getLength(); 6 | public String getShape(); 7 | public String getWhere(); 8 | } 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding//src/test/resources=UTF-8 6 | encoding/=UTF-8 7 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfBundlesize.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | public interface McfBundlesize { 4 | 5 | public McfPage getPage(); 6 | 7 | public int getHeight(); 8 | 9 | public int getWidth(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfBorder.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | import java.awt.Color; 4 | 5 | public interface McfBorder { 6 | 7 | public Color getColor(); 8 | 9 | public float getOffset(); 10 | 11 | public float getWidth(); 12 | 13 | public boolean isEnabled(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfPosition.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | public interface McfPosition { 4 | 5 | public float getLeft(); 6 | 7 | public float getTop(); 8 | 9 | public float getHeight(); 10 | 11 | public float getWidth(); 12 | 13 | public float getRotation(); 14 | 15 | public int getZPosition(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/assembly/licenseText.properties: -------------------------------------------------------------------------------- 1 | licenseText=This file is part of mcf2pdf.\n * Copyright (c) 2011 Florian Albrecht.\n * \n * mcf2pdf is distributed under the Terms and Conditions of the\n * Common Development and Distribution License (CDDL), version 1.0\n * A copy of the license text is bundled with this software,\n * and can be accessed here:\n * http://www.opensource.org/licenses/CDDL-1.0 -------------------------------------------------------------------------------- /src/test/resources/test.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, console 2 | 3 | log4j.appender.console=org.apache.log4j.ConsoleAppender 4 | 5 | log4j.appender.console.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.console.layout.ConversionPattern=[%-5p] %C %m%n 7 | 8 | log4j.logger.org.apache=ERROR 9 | log4j.logger.org.apache.commons.digester3.Digester=OFF 10 | log4j.logger.net.sf.mcf2pdf.mcfelements.impl.DigesterConfiguratorImpl$1=ERROR 11 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfCutout.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfCutout { 10 | 11 | public float getScale(); 12 | 13 | public float getLeft(); 14 | 15 | public float getTop(); 16 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfconfig/Template.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfconfig; 2 | 3 | public class Template { 4 | private String name; 5 | private String filename; 6 | 7 | public String getName() { 8 | return name; 9 | } 10 | public void setName(String name) { 11 | this.name = name; 12 | } 13 | public String getFilename() { 14 | return filename; 15 | } 16 | public void setFilename(String filename) { 17 | this.filename = filename; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfClipart.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfClipart extends McfAreaContent { 10 | 11 | public String getUniqueName(); 12 | public String getDesignElementId(); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfImageBackground.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfImageBackground extends McfImage { 10 | 11 | public final static String RIGHT_OR_BOTTOM = "RIGHT_OR_BOTTOM"; 12 | 13 | public String getBackgroundPosition(); 14 | 15 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfAreaContent.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfAreaContent { 10 | 11 | public static enum ContentType { 12 | IMAGE, IMAGEBACKGROUND, CLIPART, TEXT, POSITION 13 | } 14 | 15 | public McfArea getArea(); 16 | 17 | public ContentType getContentType(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfText.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfText extends McfAreaContent { 10 | 11 | public boolean isSpineText(); 12 | 13 | public String getHtmlContent(); 14 | 15 | public float getVerticalIndentMargin(); 16 | 17 | public float getIndentMargin(); 18 | 19 | public int getBackgroundColorAlpha(); 20 | 21 | } -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | mcf2pdf 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfBackground.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfBackground { 10 | 11 | public McfPage getPage(); 12 | 13 | public String getTemplateName(); 14 | 15 | public String getDesignElementId(); 16 | public int getType(); 17 | 18 | public int getLayout(); 19 | 20 | public int getHue(); 21 | 22 | public int getRotation(); 23 | 24 | public int getFading(); 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/McfFotoFrame.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfglobals; 2 | 3 | import java.io.File; 4 | 5 | import net.sf.mcf2pdf.mcfconfig.Fading; 6 | 7 | public class McfFotoFrame { 8 | private File clipart; 9 | private File fading; 10 | private Fading config; 11 | 12 | public McfFotoFrame(File clipart, File fading, Fading config) { 13 | this.clipart = clipart; 14 | this.fading = fading; 15 | this.config = config; 16 | } 17 | 18 | public File getClipart() { 19 | return clipart; 20 | } 21 | 22 | public File getFading() { 23 | return fading; 24 | } 25 | 26 | public Fading getConfig() { 27 | return config; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/AbstractMcfAreaContentImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfArea; 7 | import net.sf.mcf2pdf.mcfelements.McfAreaContent; 8 | 9 | public abstract class AbstractMcfAreaContentImpl implements McfAreaContent { 10 | 11 | private McfArea area; 12 | 13 | public McfArea getArea() { 14 | return area; 15 | } 16 | 17 | public void setArea(McfArea area) { 18 | this.area = area; 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/test01.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 |
10 |

11 | Line01 12 | Line02 13 | Line03 14 | Line04 15 |

16 |
19 | 20 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfconfig/Fotoarea.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfconfig; 2 | 3 | public class Fotoarea { 4 | private double x; 5 | private double y; 6 | private double width; 7 | private double height; 8 | 9 | public double getX() { 10 | return x; 11 | } 12 | public void setX(double x) { 13 | this.x = x; 14 | } 15 | public double getY() { 16 | return y; 17 | } 18 | public void setY(double y) { 19 | this.y = y; 20 | } 21 | public double getWidth() { 22 | return width; 23 | } 24 | public void setWidth(double width) { 25 | this.width = width; 26 | } 27 | public double getHeight() { 28 | return height; 29 | } 30 | public void setHeight(double height) { 31 | this.height = height; 32 | } 33 | } -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 12 | org.eclipse.jdt.core.compiler.source=1.6 13 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/AbstractPageBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.util.List; 7 | import java.util.Vector; 8 | 9 | public abstract class AbstractPageBuilder implements PageBuilder { 10 | 11 | private List pageContents = new Vector(); 12 | 13 | @Override 14 | public void addDrawable(PageDrawable drawable) { 15 | pageContents.add(drawable); 16 | } 17 | 18 | protected final List getDrawables() { 19 | return pageContents; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfPageNum.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements; 2 | 3 | import java.awt.Color; 4 | 5 | public interface McfPageNum { 6 | 7 | public McfFotobook getFotobook(); 8 | 9 | public String getTextString(); 10 | 11 | public int getPosition(); 12 | 13 | public int getVerticalMargin(); 14 | 15 | public int getHorizontalMargin(); 16 | 17 | public Color getTextColor(); 18 | 19 | public Color getBgColor(); 20 | 21 | public float getFontSize(); 22 | 23 | public int getFontBold(); 24 | 25 | public boolean getFBold(); 26 | 27 | public int getFontItalics(); 28 | 29 | public boolean getFItalics(); 30 | 31 | public String getFontFamily(); 32 | 33 | public int getFormat(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfCornersImpl.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.impl; 2 | 3 | import java.util.List; 4 | import java.util.Vector; 5 | 6 | import org.apache.commons.logging.Log; 7 | import org.apache.commons.logging.LogFactory; 8 | 9 | import net.sf.mcf2pdf.mcfelements.McfCorner; 10 | import net.sf.mcf2pdf.mcfelements.McfCorners; 11 | 12 | public class McfCornersImpl implements McfCorners { 13 | 14 | private final static Log log = LogFactory.getLog(McfCornersImpl.class); 15 | private List corners = new Vector(); 16 | 17 | @Override 18 | public List getCorners() { 19 | return corners; 20 | } 21 | 22 | public void addCorner(McfCorner corner) { 23 | log.debug("add corner"); 24 | corners.add(corner); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/McfAlbumType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfglobals; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfAlbumType { 10 | 11 | public String getName(); 12 | 13 | public int getSafetyMargin(); 14 | 15 | public int getBleedMargin(); 16 | 17 | public int getNormalPageHorizontalClamp(); 18 | 19 | public int getUsableWidth(); 20 | 21 | public int getUsableHeight(); 22 | 23 | public int getBleedMarginCover(); 24 | 25 | public int getCoverExtraVertical(); 26 | 27 | public int getCoverExtraHorizontal(); 28 | 29 | public int getSpineWidth(int normalPageCount); 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfImage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | /** 7 | * TODO comment 8 | */ 9 | public interface McfImage extends McfAreaContent { 10 | 11 | public String getParentChildRelationshipNature(); 12 | 13 | public float getScale(); 14 | 15 | public int getUseABK(); 16 | 17 | public float getLeft(); 18 | 19 | public float getTop(); 20 | 21 | public String getFileNameMaster(); 22 | 23 | public String getSafeContainerLocation(); 24 | 25 | public String getFileName(); 26 | 27 | public String getFadingFile(); 28 | 29 | public String getPassepartoutDesignElementId(); 30 | 31 | } -------------------------------------------------------------------------------- /src/main/assembly/mcf2pdf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Startup Script for mcf2pdf program. 4 | # 5 | 6 | # Adjust these variables to your local installation of the MCF software 7 | #MCF_INSTALL_DIR= 8 | 9 | # This is the default value of the software 10 | MCF_TEMP_DIR=~/.mcf 11 | 12 | # 13 | # Java Options. You can adjust the amount of reserved memory (RAM) here. 14 | # 15 | MCF2PDF_JAVA_OPTS="-Xms64M -Xmx4G" 16 | 17 | 18 | 19 | # check if this file has to be adjusted! 20 | if [ "$MCF_INSTALL_DIR" == "" ] 21 | then 22 | echo "The installation directory of the MCF software has not been set! Please edit the file $0 with a text editor first." 23 | exit 3 24 | fi 25 | 26 | java $MCF2PDF_JAVA_OPTS -classpath "${classpath}:$MCF_INSTALL_DIR:mcf2pdf-${project.version}.jar" net.sf.mcf2pdf.Main -i "$MCF_INSTALL_DIR" -t "$MCF_TEMP_DIR" "$@" 27 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/webp/WebpLib.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.util.webp; 2 | 3 | import com.sun.jna.Library; 4 | import com.sun.jna.Pointer; 5 | 6 | /** 7 | * JNA interface with all required methods to be dynamically linked and accessed 8 | * from the shared WebP library. Derived from https://code.woboq.org/qt5/qtimageformats/src/3rdparty/libwebp/src/webp/decode.h.html 10 | * 11 | * @author Florian Albrecht 12 | * 13 | */ 14 | public interface WebpLib extends Library { 15 | 16 | int WebPGetInfo(byte[] data, int data_size, int[] width, int[] height); 17 | 18 | Pointer WebPDecodeRGBAInto(byte[] data, int data_size, byte[] output_buffer, int output_buffer_size, 19 | int output_stride); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfBundlesizeImpl.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.impl; 2 | 3 | import net.sf.mcf2pdf.mcfelements.McfBundlesize; 4 | import net.sf.mcf2pdf.mcfelements.McfPage; 5 | 6 | public class McfBundlesizeImpl implements McfBundlesize { 7 | 8 | private McfPage page; 9 | private int height; 10 | private int width; 11 | 12 | @Override 13 | public McfPage getPage() { 14 | return page; 15 | } 16 | 17 | public void setPage(McfPage page) { 18 | this.page = page; 19 | } 20 | 21 | @Override 22 | public int getHeight() { 23 | return height; 24 | } 25 | 26 | public void setHeight(int height) { 27 | this.height = height; 28 | } 29 | 30 | @Override 31 | public int getWidth() { 32 | return width; 33 | } 34 | 35 | public void setWidth(int width) { 36 | this.width = width; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfImageBackgroundImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfImageBackground; 7 | 8 | public class McfImageBackgroundImpl extends McfImageImpl implements McfImageBackground { 9 | 10 | private String backgroundPosition; 11 | 12 | @Override 13 | public ContentType getContentType() { 14 | return ContentType.IMAGEBACKGROUND; 15 | } 16 | 17 | public String getBackgroundPosition() { 18 | return backgroundPosition; 19 | } 20 | 21 | public void setBackgroundPosition(String backgroundPosition) { 22 | this.backgroundPosition = backgroundPosition; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfFotobook.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | import java.io.File; 7 | import java.util.List; 8 | 9 | /** 10 | * TODO comment 11 | */ 12 | public interface McfFotobook { 13 | 14 | public File getFile(); 15 | 16 | public List getPages(); 17 | 18 | public McfPageNum getPageNum(); 19 | 20 | public int getProductType(); 21 | 22 | public String getProductName(); 23 | 24 | public String getVersion(); 25 | 26 | public String getCreatedWithHPSVersion(); 27 | 28 | public String getProgramVersion(); 29 | 30 | public String getImageDir(); 31 | 32 | public int getNormalPages(); 33 | 34 | public int getTotalPages(); 35 | 36 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfCutoutImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfCutout; 7 | 8 | public class McfCutoutImpl implements McfCutout { 9 | 10 | private float scale; 11 | 12 | private float left; 13 | 14 | private float top; 15 | 16 | public float getScale() { 17 | return scale; 18 | } 19 | 20 | public void setScale(float scale) { 21 | this.scale = scale; 22 | } 23 | 24 | public float getLeft() { 25 | return left; 26 | } 27 | 28 | public void setLeft(float left) { 29 | this.left = left; 30 | } 31 | 32 | public float getTop() { 33 | return top; 34 | } 35 | 36 | public void setTop(float top) { 37 | this.top = top; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfconfig/Clipart.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfconfig; 2 | 3 | public class Clipart { 4 | private String file; 5 | private String designElementType; 6 | private String designElementId; 7 | 8 | 9 | private double ratio; 10 | 11 | public String getFile() { 12 | return file; 13 | } 14 | public void setFile(String file) { 15 | this.file = file; 16 | } 17 | public String getDesignElementType() { 18 | return designElementType; 19 | } 20 | public void setDesignElementType(String designElementType) { 21 | this.designElementType = designElementType; 22 | } 23 | public double getRatio() { 24 | return ratio; 25 | } 26 | public void setRatio(double ratio) { 27 | this.ratio = ratio; 28 | } 29 | public String getDesignElementId() { 30 | return designElementId; 31 | } 32 | 33 | public void setDesignElementId(String designElementId) { 34 | this.designElementId = designElementId; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfPage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | import java.util.List; 7 | import java.util.regex.Pattern; 8 | 9 | /** 10 | * TODO comment 11 | */ 12 | public interface McfPage { 13 | 14 | public final static Pattern FULLCOVER = Pattern.compile("FULLCOVER|fullcover"); 15 | 16 | public final static Pattern CONTENT = Pattern.compile("CONTENT|normalpage"); 17 | 18 | public final static Pattern EMPTY = Pattern.compile("EMPTY|emptypage"); 19 | 20 | public final static Pattern SPINE = Pattern.compile("SPINE|spine"); 21 | 22 | public McfFotobook getFotobook(); 23 | 24 | public McfBundlesize getBundlesize(); 25 | 26 | public List getAreas(); 27 | 28 | public List getBackgrounds(); 29 | 30 | public int getPageNr(); 31 | 32 | public String getType(); 33 | 34 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfClipartImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfClipart; 7 | 8 | public class McfClipartImpl extends AbstractMcfAreaContentImpl implements McfClipart { 9 | 10 | private String uniqueName; 11 | private String designElementId; 12 | 13 | 14 | 15 | @Override 16 | public ContentType getContentType() { 17 | return ContentType.CLIPART; 18 | } 19 | 20 | public String getUniqueName() { 21 | return uniqueName; 22 | } 23 | 24 | @Override 25 | public String getDesignElementId() { 26 | return designElementId; 27 | } 28 | 29 | public void setDesignElementId(String designElementId) { 30 | this.designElementId = designElementId; 31 | } 32 | 33 | public void setUniqueName(String uniqueName) { 34 | this.uniqueName = uniqueName; 35 | } 36 | 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/assembly/src.xml: -------------------------------------------------------------------------------- 1 | 4 | src 5 | 6 | tar.gz 7 | 8 | true 9 | 10 | 11 | src 12 | src 13 | true 14 | 15 | 16 | / 17 | 18 | README 19 | LICENSE 20 | 21 | true 22 | 23 | 24 | / 25 | 26 | pom.xml 27 | 28 | false 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfconfig/Decoration.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfconfig; 2 | 3 | public class Decoration { 4 | private Fading fading; 5 | 6 | public Clipart getClipart() { 7 | return clipart; 8 | } 9 | 10 | public void setClipart(Clipart clipart) { 11 | this.clipart = clipart; 12 | } 13 | 14 | // new for cliparts 15 | private Clipart clipart; 16 | 17 | public void setId(String id) { 18 | this.id = id; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public void setDesignElementId(String designElementId) { 26 | this.designElementId = designElementId; 27 | } 28 | 29 | private String id; 30 | 31 | public String getId() { 32 | return id; 33 | } 34 | 35 | public String getType() { 36 | return type; 37 | } 38 | 39 | public String getDesignElementId() { 40 | return designElementId; 41 | } 42 | 43 | private String type; 44 | private String designElementId; 45 | 46 | public Fading getFading() { 47 | return fading; 48 | } 49 | public void setFading(Fading fading) { 50 | this.fading = fading; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfBorderImpl.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.impl; 2 | 3 | import java.awt.Color; 4 | 5 | import net.sf.mcf2pdf.mcfelements.McfBorder; 6 | 7 | public class McfBorderImpl implements McfBorder { 8 | 9 | private Color color; 10 | 11 | private float offset; 12 | 13 | private float width; 14 | 15 | private boolean enabled; 16 | 17 | @Override 18 | public Color getColor() { 19 | return color; 20 | } 21 | 22 | public void setColor(Color color) { 23 | this.color = color; 24 | } 25 | 26 | @Override 27 | public float getOffset() { 28 | return offset; 29 | } 30 | 31 | public void setOffset(float offset) { 32 | this.offset = offset; 33 | } 34 | 35 | @Override 36 | public float getWidth() { 37 | return width; 38 | } 39 | 40 | public void setWidth(float width) { 41 | this.width = width; 42 | } 43 | 44 | @Override 45 | public boolean isEnabled() { 46 | return enabled; 47 | } 48 | 49 | public void setEnabled(boolean enabled) { 50 | this.enabled = enabled; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/impl/McfProductCatalogueImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfglobals.impl; 5 | 6 | import java.util.List; 7 | import java.util.Vector; 8 | 9 | import net.sf.mcf2pdf.mcfglobals.McfAlbumType; 10 | import net.sf.mcf2pdf.mcfglobals.McfProductCatalogue; 11 | 12 | 13 | public class McfProductCatalogueImpl extends McfProductCatalogue { 14 | 15 | private List albumTypes = new Vector(); 16 | 17 | public McfProductCatalogueImpl() { 18 | } 19 | 20 | public void addAlbumType(McfAlbumType albumType) { 21 | albumTypes.add(albumType); 22 | } 23 | 24 | @Override 25 | public McfAlbumType getAlbumType(String name) { 26 | for (McfAlbumType a : albumTypes) { 27 | if (name.equals(a.getName())) 28 | return a; 29 | } 30 | 31 | return null; 32 | } 33 | 34 | @Override 35 | public boolean isEmpty() { 36 | return albumTypes.isEmpty(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/assembly/mcf2pdf.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM 3 | REM Startup Script for mcf2pdf program. 4 | REM 5 | 6 | REM 7 | REM Adjust these variables to your local installation of the MCF software 8 | REM A common value is: C:\Program Files\cewe-fotobuch 9 | REM 10 | SET MCF_INSTALL_DIR= 11 | 12 | REM 13 | REM Enter here the location for temporary files of the MCF software. Refer to 14 | REM the options dialog in the software for this information. 15 | REM 16 | SET MCF_TEMP_DIR= 17 | 18 | REM 19 | REM Java Options. You can adjust reserved memory (RAM) here 20 | REM 21 | SET MCF2PDF_JAVA_OPTS=-Xms64M -Xmx4G 22 | 23 | 24 | 25 | 26 | 27 | REM check if this file has to be adjusted! 28 | if "%MCF_INSTALL_DIR%" == "" GOTO echo_adjust 29 | if "%MCF_TEMP_DIR%" == "" GOTO echo_adjust 30 | 31 | java %MCF2PDF_JAVA_OPTS% -classpath "${windowsClasspath};%MCF_INSTALL_DIR%;mcf2pdf-${project.version}.jar" net.sf.mcf2pdf.Main -i "%MCF_INSTALL_DIR%" -t "%MCF_TEMP_DIR%" %1 %2 %3 %4 %5 %6 %7 %8 %9 32 | 33 | GOTO end 34 | 35 | :echo_adjust 36 | ECHO The installation and/or temporary directory of the MCF software has not been set! Please edit the file mcf2pdf.bat with a text editor first. 37 | 38 | :end 39 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/DigesterUtil.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.util; 5 | 6 | import java.util.List; 7 | 8 | import org.apache.commons.digester3.Digester; 9 | import org.apache.commons.digester3.SetPropertiesRule; 10 | 11 | /** 12 | * TODO comment 13 | */ 14 | public final class DigesterUtil { 15 | 16 | private DigesterUtil() { 17 | } 18 | 19 | public static void addSetProperties(Digester digester, String pattern, 20 | List specialAttributes) { 21 | String[] attrNames = new String[specialAttributes.size()]; 22 | String[] propNames = new String[specialAttributes.size()]; 23 | 24 | for (int i = 0; i < specialAttributes.size(); i++) { 25 | attrNames[i] = specialAttributes.get(i)[0]; 26 | propNames[i] = specialAttributes.get(i)[1]; 27 | } 28 | 29 | SetPropertiesRule rule = new SetPropertiesRule(attrNames, propNames); 30 | rule.setIgnoreMissingProperty(true); 31 | digester.addRule(pattern, rule); 32 | } 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/assembly/classpath.unix: -------------------------------------------------------------------------------- 1 | classpath=lib/jdom-1.1.jar:lib/fop-2.9.jar:lib/fop-util-2.9.jar:lib/fop-events-2.9.jar:lib/qdox-1.12.jar:lib/commons-io-2.11.0.jar:lib/fop-core-2.9.jar:lib/batik-anim-1.17.jar:lib/batik-css-1.17.jar:lib/batik-dom-1.17.jar:lib/batik-ext-1.17.jar:lib/batik-parser-1.17.jar:lib/batik-shared-resources-1.17.jar:lib/batik-svg-dom-1.17.jar:lib/batik-util-1.17.jar:lib/batik-constants-1.17.jar:lib/batik-i18n-1.17.jar:lib/batik-awt-util-1.17.jar:lib/batik-bridge-1.17.jar:lib/batik-script-1.17.jar:lib/batik-xml-1.17.jar:lib/batik-extension-1.17.jar:lib/batik-gvt-1.17.jar:lib/batik-transcoder-1.17.jar:lib/batik-svggen-1.17.jar:lib/batik-codec-1.17.jar:lib/fontbox-2.0.27.jar:lib/batik-all-1.16.jar:lib/xml-apis-1.4.01.jar:lib/xml-apis-ext-1.3.04.jar:lib/xmlgraphics-commons-2.7.jar:lib/commons-digester3-3.1.jar:lib/commons-logging-1.1.1.jar:lib/commons-beanutils-1.8.3.jar:lib/commons-cli-1.2.jar:lib/log4j-1.2.9.jar:lib/jempbox-1.6.0.jar:lib/metadata-extractor-2.18.0.jar:lib/xmpcore-6.1.11.jar:lib/pngj-2.1.0.jar:lib/jna-4.1.0.jar:lib/jna-platform-4.1.0.jar:lib/junit-4.11.jar:lib/hamcrest-core-1.3.jar:lib/imageio-batik-3.9.4.jar:lib/common-lang-3.9.4.jar:lib/common-io-3.9.4.jar:lib/common-image-3.9.4.jar:lib/imageio-core-3.9.4.jar:lib/imageio-tiff-3.9.4.jar:lib/imageio-metadata-3.9.4.jar:lib/jsoup-1.10.2.jar -------------------------------------------------------------------------------- /src/main/assembly/classpath.win: -------------------------------------------------------------------------------- 1 | classpath=lib\\jdom-1.1.jar;lib\\fop-2.9.jar;lib\\fop-util-2.9.jar;lib\\fop-events-2.9.jar;lib\\qdox-1.12.jar;lib\\commons-io-2.11.0.jar;lib\\fop-core-2.9.jar;lib\\batik-anim-1.17.jar;lib\\batik-css-1.17.jar;lib\\batik-dom-1.17.jar;lib\\batik-ext-1.17.jar;lib\\batik-parser-1.17.jar;lib\\batik-shared-resources-1.17.jar;lib\\batik-svg-dom-1.17.jar;lib\\batik-util-1.17.jar;lib\\batik-constants-1.17.jar;lib\\batik-i18n-1.17.jar;lib\\batik-awt-util-1.17.jar;lib\\batik-bridge-1.17.jar;lib\\batik-script-1.17.jar;lib\\batik-xml-1.17.jar;lib\\batik-extension-1.17.jar;lib\\batik-gvt-1.17.jar;lib\\batik-transcoder-1.17.jar;lib\\batik-svggen-1.17.jar;lib\\batik-codec-1.17.jar;lib\\fontbox-2.0.27.jar;lib\\batik-all-1.16.jar;lib\\xml-apis-1.4.01.jar;lib\\xml-apis-ext-1.3.04.jar;lib\\xmlgraphics-commons-2.7.jar;lib\\commons-digester3-3.1.jar;lib\\commons-logging-1.1.1.jar;lib\\commons-beanutils-1.8.3.jar;lib\\commons-cli-1.2.jar;lib\\log4j-1.2.9.jar;lib\\jempbox-1.6.0.jar;lib\\metadata-extractor-2.18.0.jar;lib\\xmpcore-6.1.11.jar;lib\\pngj-2.1.0.jar;lib\\jna-4.1.0.jar;lib\\jna-platform-4.1.0.jar;lib\\junit-4.11.jar;lib\\hamcrest-core-1.3.jar;lib\\imageio-batik-3.9.4.jar;lib\\common-lang-3.9.4.jar;lib\\common-io-3.9.4.jar;lib\\common-image-3.9.4.jar;lib\\imageio-core-3.9.4.jar;lib\\imageio-tiff-3.9.4.jar;lib\\imageio-metadata-3.9.4.jar;lib\\jsoup-1.10.2.jar -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageImageBackground.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Point; 7 | import java.awt.image.BufferedImage; 8 | import java.io.IOException; 9 | 10 | import net.sf.mcf2pdf.mcfelements.McfImageBackground; 11 | import net.sf.mcf2pdf.mcfglobals.McfAlbumType; 12 | 13 | 14 | /** 15 | * TODO comment 16 | */ 17 | public class PageImageBackground extends PageImage { 18 | 19 | private McfImageBackground image; 20 | 21 | public PageImageBackground(McfImageBackground image) { 22 | super(image); 23 | this.image = image; 24 | } 25 | 26 | @Override 27 | public BufferedImage renderAsBitmap(PageRenderContext context, 28 | Point drawOffsetPixels, int widthPX, int heightPX) throws IOException { 29 | BufferedImage img = super.renderAsBitmap(context, drawOffsetPixels, widthPX, heightPX); 30 | if (McfImageBackground.RIGHT_OR_BOTTOM.equals(image.getBackgroundPosition())) { 31 | McfAlbumType albumType = context.getAlbumType(); 32 | drawOffsetPixels.x += context.toPixel(albumType.getUsableWidth() / 10.0f + 33 | albumType.getBleedMargin() / 10.0f); 34 | } 35 | return img; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/assembly/classpath-filter.win: -------------------------------------------------------------------------------- 1 | windowsClasspath=lib\\jdom-1.1.jar;lib\\fop-2.9.jar;lib\\fop-util-2.9.jar;lib\\fop-events-2.9.jar;lib\\qdox-1.12.jar;lib\\commons-io-2.11.0.jar;lib\\fop-core-2.9.jar;lib\\batik-anim-1.17.jar;lib\\batik-css-1.17.jar;lib\\batik-dom-1.17.jar;lib\\batik-ext-1.17.jar;lib\\batik-parser-1.17.jar;lib\\batik-shared-resources-1.17.jar;lib\\batik-svg-dom-1.17.jar;lib\\batik-util-1.17.jar;lib\\batik-constants-1.17.jar;lib\\batik-i18n-1.17.jar;lib\\batik-awt-util-1.17.jar;lib\\batik-bridge-1.17.jar;lib\\batik-script-1.17.jar;lib\\batik-xml-1.17.jar;lib\\batik-extension-1.17.jar;lib\\batik-gvt-1.17.jar;lib\\batik-transcoder-1.17.jar;lib\\batik-svggen-1.17.jar;lib\\batik-codec-1.17.jar;lib\\fontbox-2.0.27.jar;lib\\batik-all-1.16.jar;lib\\xml-apis-1.4.01.jar;lib\\xml-apis-ext-1.3.04.jar;lib\\xmlgraphics-commons-2.7.jar;lib\\commons-digester3-3.1.jar;lib\\commons-logging-1.1.1.jar;lib\\commons-beanutils-1.8.3.jar;lib\\commons-cli-1.2.jar;lib\\log4j-1.2.9.jar;lib\\jempbox-1.6.0.jar;lib\\metadata-extractor-2.18.0.jar;lib\\xmpcore-6.1.11.jar;lib\\pngj-2.1.0.jar;lib\\jna-4.1.0.jar;lib\\jna-platform-4.1.0.jar;lib\\junit-4.11.jar;lib\\hamcrest-core-1.3.jar;lib\\imageio-batik-3.9.4.jar;lib\\common-lang-3.9.4.jar;lib\\common-io-3.9.4.jar;lib\\common-image-3.9.4.jar;lib\\imageio-core-3.9.4.jar;lib\\imageio-tiff-3.9.4.jar;lib\\imageio-metadata-3.9.4.jar;lib\\jsoup-1.10.2.jar -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfCornerImpl.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.impl; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfCorner; 7 | 8 | public class McfCornerImpl implements McfCorner { 9 | 10 | private final static Log log = LogFactory.getLog(McfCornerImpl.class); 11 | int length = 0; 12 | private String shape = null; 13 | private String where = null; 14 | 15 | @Override 16 | public int getLength() { 17 | return this.length; 18 | } 19 | 20 | public void setLength( int l ) { 21 | log.debug("setLength"); 22 | this.length = l; 23 | } 24 | 25 | @Override 26 | public String getShape() { 27 | return this.shape; 28 | } 29 | 30 | public void setShape(String text) { 31 | log.debug("setShape"); 32 | } 33 | 34 | @Override 35 | public String getWhere() { 36 | return this.where; 37 | } 38 | 39 | public void setWhere(String text) { 40 | log.debug("setWhere"); 41 | this.where = text; 42 | /* 43 | if ("bottom-left".equals(text)) { 44 | 45 | position = where.bottom_left; 46 | } else if ("bottom-right".equals(text)) { 47 | position = where.bottom_right; 48 | } else if ("top-left".equals(text)) { 49 | position = where.top_left; 50 | } else if ("top-right".equals(text)) { 51 | position = where.top_right; 52 | } else { 53 | System.out.println("unknown where: " + text); 54 | } 55 | */ 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfconfig/Fading.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfconfig; 2 | 3 | public class Fading { 4 | private String file; 5 | private String designElementType; 6 | private String designElementId; 7 | 8 | 9 | private double ratio; 10 | private double keepAspectRatio; 11 | private Clipart clipart; 12 | private Fotoarea fotoarea; 13 | 14 | public String getFile() { 15 | return file; 16 | } 17 | public void setFile(String file) { 18 | this.file = file; 19 | } 20 | public String getDesignElementType() { 21 | return designElementType; 22 | } 23 | public void setDesignElementType(String designElementType) { 24 | this.designElementType = designElementType; 25 | } 26 | public double getRatio() { 27 | return ratio; 28 | } 29 | public void setRatio(double ratio) { 30 | this.ratio = ratio; 31 | } 32 | public double getKeepAspectRatio() { 33 | return keepAspectRatio; 34 | } 35 | public void setKeepAspectRatio(double keepAspectRatio) { 36 | this.keepAspectRatio = keepAspectRatio; 37 | } 38 | public Clipart getClipart() { 39 | return clipart; 40 | } 41 | public void setClipart(Clipart clipart) { 42 | this.clipart = clipart; 43 | } 44 | public Fotoarea getFotoarea() { 45 | return fotoarea; 46 | } 47 | public void setFotoarea(Fotoarea fotoarea) { 48 | this.fotoarea = fotoarea; 49 | } 50 | 51 | public String getDesignElementId() { 52 | return designElementId; 53 | } 54 | 55 | public void setDesignElementId(String designElementId) { 56 | this.designElementId = designElementId; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.io.IOException; 7 | 8 | import net.sf.mcf2pdf.mcfelements.util.XslFoDocumentBuilder; 9 | 10 | 11 | /** 12 | * Interface for page builders. A page builder is responsible for rendering a 13 | * "single" page (single from its point of view. In the context of mcf2pdf, one 14 | * page will always reflect two pages, but this is not managed by the PageBuilder). 15 | * The page builder can receive any number of PageDrawables which 16 | * must be rendered to the page, preserving their Z ordering. The page must then 17 | * be added to a given XslFoDocumentBuilder. 18 | * 19 | */ 20 | public interface PageBuilder { 21 | 22 | /** 23 | * Adds a single drawable to the page. 24 | * 25 | * @param drawable Drawable to add. 26 | */ 27 | public void addDrawable(PageDrawable drawable); 28 | 29 | /** 30 | * Adds this page to the given document builder. Normally, now the rendering 31 | * of all drawables is performed, and then one "page" object is added to the 32 | * builder. 33 | * 34 | * @param docBuilder Document Builder to add a page element to. 35 | * 36 | * @throws IOException If any I/O related problem occurs, e.g. when reading 37 | * an image file during rendering. 38 | */ 39 | public void addToDocumentBuilder(XslFoDocumentBuilder docBuilder) throws IOException; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/assembly/zip.xml: -------------------------------------------------------------------------------- 1 | 4 | bin-windows 5 | 6 | zip 7 | 8 | true 9 | 10 | 11 | lib 12 | false 13 | false 14 | runtime 15 | 16 | 17 | 18 | 19 | 20 | lib 21 | lib 22 | 23 | 24 | / 25 | 26 | README 27 | LICENSE 28 | 29 | 644 30 | true 31 | 32 | 33 | src/main/assembly 34 | / 35 | true 36 | windows 37 | 38 | mcf2pdf.bat 39 | 40 | 41 | 42 | ${project.build.directory} 43 | / 44 | 45 | ${project.name}-${project.version}.jar 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/DigesterConfigurator.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import org.apache.commons.digester3.Digester; 10 | 11 | /** 12 | * Interface for objects being able to configure a Digester object to 13 | * be ready to parse the given MCF file. 14 | */ 15 | public interface DigesterConfigurator { 16 | 17 | /** 18 | * Configures the given Digester to parse the given MCF file and create 19 | * an MCF DOM with an McfFotobook as root object.
20 | * As the root McfFotobook object has a getFile() 21 | * method, this property must somehow be set on the root object. A normal way 22 | * would be to provide a setter for this property in the used McfFotobook 23 | * implementing class. This property is then set by the FotobookBuilder 24 | * on the resulting McfFotobook object after parsing the MCF file, 25 | * using BeanUtils API.
26 | * If, for some reason, your chosen DOM implementation does not offer such a 27 | * setter for the file property, you can use the File object here to somehow 28 | * inject it into your root object class. 29 | * 30 | * @param digester Digester object to configure. 31 | * @param mcfFile MCF file which is going to be parsed. 32 | * 33 | * @throws IOException If any I/O related problem occurs, e.g. when analysing 34 | * the file is required but fails. 35 | */ 36 | public void configureDigester(Digester digester, File mcfFile) throws IOException; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/McfArea.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | import java.awt.Color; 7 | import java.util.regex.Pattern; 8 | 9 | /** 10 | * TODO comment 11 | */ 12 | public interface McfArea { 13 | 14 | public final static Pattern IMAGEBACKGROUNDAREA = Pattern.compile("IMAGEBACKGROUNDAREA", Pattern.CASE_INSENSITIVE); 15 | 16 | public final static Pattern IMAGEAREA = Pattern.compile("IMAGEAREA", Pattern.CASE_INSENSITIVE); 17 | 18 | public final static Pattern TEXTAREA = Pattern.compile("FREETEXTAREA|textarea"); 19 | 20 | public final static Pattern CLIPARTAREA = Pattern.compile("CLIPARTAREA", Pattern.CASE_INSENSITIVE); 21 | 22 | public final static Pattern SPINETEXTAREA = Pattern.compile("SPINETEXTAREA", Pattern.CASE_INSENSITIVE); 23 | 24 | 25 | public McfPage getPage(); 26 | 27 | public float getLeft(); 28 | 29 | public float getTop(); 30 | 31 | public float getHeight(); 32 | 33 | public float getWidth(); 34 | 35 | public float getRotation(); 36 | 37 | public int getZPosition(); 38 | 39 | public String getAreaType(); 40 | 41 | public boolean isBorderEnabled(); 42 | 43 | public float getBorderSize(); 44 | 45 | public Color getBorderColor(); 46 | 47 | public boolean isShadowEnabled(); 48 | 49 | public int getShadowAngle(); 50 | 51 | public int getShadowIntensity(); 52 | 53 | public float getShadowDistance(); 54 | 55 | public Color getBackgroundColor(); 56 | 57 | public McfAreaContent getContent(); 58 | 59 | public McfBorder getBorder(); 60 | 61 | public McfCorners getCorners(); 62 | 63 | public McfPosition getPosition(); 64 | 65 | } -------------------------------------------------------------------------------- /src/main/assembly/tgz.xml: -------------------------------------------------------------------------------- 1 | 4 | bin-linux 5 | 6 | tar.gz 7 | 8 | true 9 | 10 | 11 | lib 12 | false 13 | false 14 | runtime 15 | 16 | 17 | 18 | 19 | 20 | lib 21 | lib 22 | *.jar 23 | 644 24 | 25 | 26 | / 27 | 28 | README 29 | LICENSE 30 | 31 | 644 32 | true 33 | 34 | 35 | src/main/assembly 36 | / 37 | true 38 | 39 | mcf2pdf 40 | 41 | 750 42 | 43 | 44 | ${project.build.directory} 45 | / 46 | 644 47 | 48 | ${project.name}-${project.version}.jar 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfTextImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfText; 7 | 8 | public class McfTextImpl extends AbstractMcfAreaContentImpl implements McfText { 9 | 10 | private boolean isSpineText; 11 | 12 | private String htmlContent; 13 | 14 | private float verticalIndentMargin; 15 | 16 | private float indentMargin; 17 | 18 | private int backgroundColorAlpha; 19 | 20 | 21 | @Override 22 | public ContentType getContentType() { 23 | return ContentType.TEXT; 24 | } 25 | 26 | @Override 27 | public boolean isSpineText() { 28 | return isSpineText; 29 | } 30 | 31 | public void setSpineText(boolean isSpineText) { 32 | this.isSpineText = isSpineText; 33 | } 34 | 35 | @Override 36 | public String getHtmlContent() { 37 | return htmlContent; 38 | } 39 | 40 | public void setHtmlContent(String htmlContent) { 41 | this.htmlContent = htmlContent; 42 | } 43 | 44 | @Override 45 | public float getVerticalIndentMargin() { 46 | return verticalIndentMargin; 47 | } 48 | 49 | public void setVerticalIndentMargin(float verticalIndentMargin) { 50 | this.verticalIndentMargin = verticalIndentMargin; 51 | } 52 | 53 | @Override 54 | public float getIndentMargin() { 55 | return indentMargin; 56 | } 57 | 58 | public void setIndentMargin(float indentMargin) { 59 | this.indentMargin = indentMargin; 60 | } 61 | 62 | @Override 63 | public int getBackgroundColorAlpha() { 64 | return backgroundColorAlpha; 65 | } 66 | 67 | public void setBackgroundColorAlpha(int backgroundColorAlpha) { 68 | this.backgroundColorAlpha = backgroundColorAlpha; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/net/sf/mcf2pdf/util/ImageUtilTest.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.util; 2 | 3 | import java.io.File; 4 | import java.awt.image.BufferedImage; 5 | import org.junit.Assert; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | import javax.imageio.IIOException; 9 | 10 | import net.sf.mcf2pdf.mcfelements.util.ImageUtil; 11 | 12 | public class ImageUtilTest { 13 | 14 | @Test 15 | @Ignore("Currently disabled as no longer used by CEWE?!") 16 | public void testPngWithRes() throws Exception { 17 | float[] res = ImageUtil.getImageResolution(new File("./src/test/resources/Bertrand1-figure-withres.png")); 18 | Assert.assertEquals(72.009f, res[0], 0.01f); 19 | Assert.assertEquals(72.009f, res[1], 0.01f); 20 | } 21 | 22 | @Test 23 | public void testPngWithoutRes() throws Exception { 24 | float[] res = ImageUtil.getImageResolution(new File("./src/test/resources/Bertrand1-figure.png")); 25 | Assert.assertEquals(180.0f, res[0], 0.01f); 26 | Assert.assertEquals(180.0f, res[1], 0.01f); 27 | } 28 | 29 | @Test(expected = IIOException.class) 30 | public void testJpgIssueUnsupportedSOFile() throws Exception { 31 | BufferedImage res = ImageUtil.readImage(new File("./src/test/resources/error01.jpg")); 32 | Assert.assertNotNull(res); 33 | } 34 | 35 | @Ignore("Will be working if changed to imageio by twelvemonkeys") 36 | @Test 37 | public void testJpgIssueUnsupportedSOFSecondfile() throws Exception { 38 | BufferedImage res = ImageUtil.readImage(new File("./src/test/resources/error02.jpg")); 39 | Assert.assertNotNull(res); 40 | } 41 | 42 | //@Ignore("Will be working if changed to imageio by twelvemonkeys") 43 | @Test 44 | public void testSVGShouldwork() throws Exception { 45 | BufferedImage res = ImageUtil.readImage(new File("./src/test/resources/test.svg")); 46 | Assert.assertNotNull(res); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfPageImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Vector; 9 | 10 | import net.sf.mcf2pdf.mcfelements.*; 11 | 12 | 13 | public class McfPageImpl implements McfPage { 14 | 15 | private McfFotobook fotobook; 16 | 17 | private McfBundlesize bundlesize; 18 | 19 | private int pageNr; 20 | 21 | private String type; 22 | 23 | private List areas = new Vector(); 24 | 25 | private List backgrounds = new Vector(); 26 | 27 | public void addArea(McfArea area) { 28 | areas.add(area); 29 | } 30 | 31 | public List getAreas() { 32 | return Collections.unmodifiableList(areas); 33 | } 34 | 35 | public void addBackground(McfBackground bg) { 36 | backgrounds.add(bg); 37 | } 38 | 39 | public List getBackgrounds() { 40 | return Collections.unmodifiableList(backgrounds); 41 | } 42 | 43 | public McfFotobook getFotobook() { 44 | return fotobook; 45 | } 46 | 47 | public void setFotobook(McfFotobook fotobook) { 48 | this.fotobook = fotobook; 49 | } 50 | 51 | public int getPageNr() { 52 | return pageNr; 53 | } 54 | 55 | public void setPageNr(int pageNr) { 56 | this.pageNr = pageNr; 57 | } 58 | 59 | public String getType() { 60 | return type; 61 | } 62 | 63 | public void setType(String type) { 64 | this.type = type; 65 | } 66 | 67 | @Override 68 | public McfBundlesize getBundlesize() { 69 | return bundlesize; 70 | } 71 | 72 | public void setBundlesize(McfBundlesize bundlesize) { 73 | this.bundlesize = bundlesize; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfPositionImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfPosition; 7 | import org.apache.commons.logging.Log; 8 | import org.apache.commons.logging.LogFactory; 9 | 10 | public class McfPositionImpl extends AbstractMcfAreaContentImpl implements McfPosition { 11 | private final static Log log = LogFactory.getLog(McfPositionImpl.class); 12 | 13 | private float left; 14 | 15 | private float top; 16 | 17 | private float width; 18 | 19 | private float height; 20 | 21 | private float rotation; 22 | 23 | private int zPosition; 24 | 25 | @Override 26 | public ContentType getContentType() { 27 | return ContentType.POSITION; 28 | } 29 | 30 | @Override 31 | public float getLeft() { 32 | return left; 33 | } 34 | 35 | public void setLeft(float left) { 36 | this.left = left; 37 | } 38 | 39 | @Override 40 | public float getTop() { 41 | return top; 42 | } 43 | 44 | public void setTop(float top) { 45 | this.top = top; 46 | } 47 | 48 | @Override 49 | public float getWidth() { 50 | return width; 51 | } 52 | 53 | public void setWidth(float width) { 54 | this.width = width; 55 | } 56 | 57 | @Override 58 | public float getHeight() { 59 | return height; 60 | } 61 | 62 | public void setHeight(float height) { 63 | this.height = height; 64 | } 65 | 66 | @Override 67 | public float getRotation() { 68 | return rotation; 69 | } 70 | 71 | public void setRotation(float rotation) { 72 | this.rotation = rotation; 73 | } 74 | 75 | @Override 76 | public int getZPosition() { 77 | return zPosition; 78 | } 79 | 80 | public void setZPosition(int zPosition) { 81 | this.zPosition = zPosition; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfBackgroundImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfBackground; 7 | import net.sf.mcf2pdf.mcfelements.McfPage; 8 | 9 | public class McfBackgroundImpl implements McfBackground { 10 | 11 | private McfPage page; 12 | 13 | private String templateName; 14 | 15 | private String designElementId; 16 | private int type; 17 | 18 | private int layout; 19 | 20 | private int Hue; 21 | private int Fading; 22 | private int Rotation; 23 | 24 | public McfPage getPage() { 25 | return page; 26 | } 27 | 28 | public void setPage(McfPage page) { 29 | this.page = page; 30 | } 31 | 32 | public String getTemplateName() { 33 | return templateName; 34 | } 35 | 36 | public void setTemplateName(String templateName) { 37 | this.templateName = templateName; 38 | } 39 | 40 | public int getType() { 41 | return type; 42 | } 43 | 44 | public void setType(int type) { 45 | this.type = type; 46 | } 47 | 48 | public int getLayout() { 49 | return layout; 50 | } 51 | 52 | @Override 53 | public int getHue() { 54 | return Hue; 55 | } 56 | 57 | public void setHue(int hue) {this.Hue = hue;}; 58 | 59 | public void setRotation(int rotation) {this.Rotation = rotation;}; 60 | 61 | public void setFading(int fading) {this.Fading = fading;}; 62 | 63 | @Override 64 | public int getRotation() { 65 | return Rotation; 66 | } 67 | 68 | @Override 69 | public int getFading() { 70 | return Fading; 71 | } 72 | 73 | public void setLayout(int layout) { 74 | this.layout = layout; 75 | } 76 | 77 | public void setDesignElementId(String designElementId) { 78 | this.designElementId = designElementId; 79 | } 80 | @Override 81 | public String getDesignElementId() { 82 | return designElementId; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/FormattedText.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Color; 7 | 8 | public class FormattedText { 9 | 10 | private String text; 11 | 12 | private boolean bold; 13 | private boolean italic; 14 | private boolean underline; 15 | 16 | private Color textColor; 17 | 18 | private String fontFamily; 19 | private float fontSize; 20 | 21 | private int margintop; 22 | private int marginleft; 23 | private int marginbottom; 24 | private int marginright; 25 | 26 | public FormattedText(String text, boolean bold, boolean italic, 27 | boolean underline, Color textColor, String fontFamily, float fontSize, 28 | int margintop,int marginright,int marginbottom,int marginleft) { 29 | this.text = text; 30 | this.bold = bold; 31 | this.italic = italic; 32 | this.underline = underline; 33 | this.textColor = textColor; 34 | this.fontFamily = fontFamily; 35 | this.fontSize = fontSize; 36 | this.margintop =margintop; 37 | this.marginright =marginright; 38 | this.marginbottom = marginbottom; 39 | this.marginleft = marginleft; 40 | } 41 | 42 | public String getText() { 43 | return text; 44 | } 45 | 46 | public boolean isBold() { 47 | return bold; 48 | } 49 | 50 | public boolean isItalic() { 51 | return italic; 52 | } 53 | 54 | public boolean isUnderline() { 55 | return underline; 56 | } 57 | 58 | public Color getTextColor() { 59 | return textColor; 60 | } 61 | 62 | public String getFontFamily() { 63 | return fontFamily; 64 | } 65 | 66 | public float getFontSize() { 67 | return fontSize; 68 | } 69 | 70 | public int getMargintop() { return margintop;} 71 | 72 | public int getMarginleft() { return marginleft;} 73 | 74 | public int getMarginbottom() {return marginbottom;} 75 | 76 | public int getMarginright() {return marginright;} 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageBinding.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Graphics2D; 7 | import java.awt.Point; 8 | import java.awt.RenderingHints; 9 | import java.awt.image.BufferedImage; 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.io.Writer; 13 | 14 | import net.sf.mcf2pdf.mcfelements.util.ImageUtil; 15 | 16 | public class PageBinding implements PageDrawable { 17 | 18 | private BufferedImage bindingImg; 19 | 20 | public PageBinding(File fBindingImg) throws IOException { 21 | bindingImg = ImageUtil.readImage(fBindingImg); 22 | } 23 | 24 | @Override 25 | public boolean isVectorGraphic() { 26 | return false; 27 | } 28 | 29 | @Override 30 | public void renderAsSvgElement(Writer writer, PageRenderContext context) throws IOException { 31 | throw new UnsupportedOperationException(); 32 | } 33 | 34 | @Override 35 | public BufferedImage renderAsBitmap(PageRenderContext context, 36 | Point drawOffsetPixels, int widthPX, int heightPX) throws IOException { 37 | context.getLog().debug("Rendering page binding"); 38 | 39 | int width = Math.round(widthPX / 16.0f); 40 | 41 | BufferedImage img = new BufferedImage(width, heightPX, BufferedImage.TYPE_INT_ARGB); 42 | Graphics2D g2d = img.createGraphics(); 43 | g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); 44 | 45 | g2d.drawImage(bindingImg, 0, 0, width, heightPX, 0, 0, bindingImg.getWidth(), bindingImg.getHeight(), null); 46 | g2d.dispose(); 47 | 48 | drawOffsetPixels.x = Math.round((widthPX - width) / 2.0f); 49 | drawOffsetPixels.y = 0; 50 | 51 | return img; 52 | } 53 | 54 | @Override 55 | public int getZPosition() { 56 | // always on top! 57 | return 10000; 58 | } 59 | 60 | @Override 61 | public float getLeftMM() { 62 | return 0; 63 | } 64 | 65 | @Override 66 | public float getTopMM() { 67 | return 0; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/McfFileUtil.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.util; 5 | 6 | import java.io.File; 7 | import java.io.FileNotFoundException; 8 | 9 | import net.sf.mcf2pdf.mcfelements.McfFotobook; 10 | 11 | 12 | /** 13 | * Utility class for File related "hacks" in the context of the mcf2pdf project. 14 | */ 15 | public final class McfFileUtil { 16 | 17 | private McfFileUtil() { 18 | } 19 | 20 | /** 21 | * Tries some locations to find the given image file: 22 | *
  • First, it searches for the images directory within the 23 | * directory where the fotobook is stored, and if found, searches there for 24 | * the given file.
  • 25 | *
  • If not found, it is checked if the image dir exists in the CURRENT 26 | * working directory, and if exists, it is searched for the file.
  • 27 | *
  • As a last try, the given file is searched directly from where the 28 | * fotobook is stored (this is required for some older mcf files).
  • 29 | *
    30 | * 31 | * @param fileName File name to search. Should be the filename 32 | * property of an image or imagebackground tag. 33 | * @param fotobook The fotobook to use for search. 34 | * 35 | * @return The file, if found. 36 | * 37 | * @throws FileNotFoundException If the file could not be found. 38 | */ 39 | public static File getImageFile(String fileName, McfFotobook fotobook) throws FileNotFoundException { 40 | if (fileName.startsWith("safecontainer:")) { 41 | // Version 4.x 42 | fileName = fileName.substring(14); 43 | } 44 | File f = new File(new File(fotobook.getFile().getParentFile(), fotobook.getImageDir()), fileName); 45 | if (f.isFile()) 46 | return f; 47 | 48 | f = new File(new File(fotobook.getImageDir()), fileName); 49 | if (f.isFile()) 50 | return f; 51 | 52 | f = new File(fotobook.getFile().getParentFile(), fileName); 53 | if (f.isFile()) 54 | return f; 55 | 56 | throw new FileNotFoundException(fileName); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/SVGPageBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.pagebuild; 9 | 10 | import java.awt.Dimension; 11 | import java.io.File; 12 | import java.io.IOException; 13 | 14 | import net.sf.mcf2pdf.mcfelements.util.XslFoDocumentBuilder; 15 | 16 | import org.apache.batik.dom.GenericDOMImplementation; 17 | import org.apache.batik.svggen.*; 18 | import org.w3c.dom.DOMImplementation; 19 | import org.w3c.dom.Document; 20 | 21 | 22 | /** 23 | * Vector based renderer for pages. Yet to be implemented. 24 | */ 25 | public class SVGPageBuilder extends AbstractPageBuilder { 26 | 27 | private float widthMM; 28 | 29 | private float heightMM; 30 | 31 | private PageRenderContext context; 32 | 33 | private File tempImageDir; 34 | 35 | public SVGPageBuilder(float widthMM, float heightMM, PageRenderContext context, 36 | File tempImageDir) throws IOException { 37 | this.widthMM = widthMM; 38 | this.heightMM = heightMM; 39 | this.context = context; 40 | this.tempImageDir = tempImageDir; 41 | } 42 | 43 | @Override 44 | public void addToDocumentBuilder(XslFoDocumentBuilder docBuilder) 45 | throws IOException { 46 | // Get a DOMImplementation. 47 | DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); 48 | 49 | // Create an instance of org.w3c.dom.Document. 50 | String svgNS = "http://www.w3.org/2000/svg"; 51 | Document document = domImpl.createDocument(svgNS, "svg", null); 52 | 53 | SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document); 54 | DefaultImageHandler ihandler = new ImageHandlerJPEGEncoder(tempImageDir.getAbsolutePath(), null); 55 | ctx.setImageHandler(ihandler); 56 | 57 | // Create an instance of the SVG Generator. 58 | SVGGraphics2D graphics = new SVGGraphics2D(ctx, false); 59 | graphics.setSVGCanvasSize(new Dimension(context.toPixel(widthMM), context.toPixel(heightMM))); 60 | 61 | 62 | // TODO render all drawables to canvas 63 | 64 | 65 | graphics.dispose(); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/FotobookBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import net.sf.mcf2pdf.mcfelements.impl.DigesterConfiguratorImpl; 10 | 11 | import org.apache.commons.beanutils.BeanUtils; 12 | import org.apache.commons.digester3.Digester; 13 | import org.xml.sax.SAXException; 14 | 15 | 16 | /** 17 | * Entry point to create an MCF DOM from a given MCF input file. 18 | */ 19 | public final class FotobookBuilder { 20 | 21 | private DigesterConfigurator configurator; 22 | 23 | /** 24 | * Creates a new MCF DOM builder with default settings. 25 | */ 26 | public FotobookBuilder() { 27 | this(new DigesterConfiguratorImpl()); 28 | } 29 | 30 | /** 31 | * Creates a new MCF DOM builder which uses the given configurator to configure 32 | * the XML Digester to use. This way, you can use your own API or add some 33 | * preprocessing to the parsing process. 34 | * 35 | * @param configurator Configurator to use to configure the internal Digester 36 | * object. 37 | */ 38 | public FotobookBuilder(DigesterConfigurator configurator) { 39 | this.configurator = configurator; 40 | } 41 | 42 | /** 43 | * Reads the given MCF input file and creates an MCF DOM reflecting the 44 | * relevant parts of the content. 45 | * 46 | * @param file MCF input file. 47 | * 48 | * @return A Fotobook object reflecting the contents of the file. 49 | * 50 | * @throws IOException If any I/O related problem occurs reading the file. 51 | * @throws SAXException If any XML related problem occurs reading the file. 52 | */ 53 | public McfFotobook readFotobook(File file) throws IOException, SAXException { 54 | Digester digester = new Digester(); 55 | configurator.configureDigester(digester, file); 56 | McfFotobook fb = digester.parse(file); 57 | 58 | // try to set file on it 59 | try { 60 | BeanUtils.setProperty(fb, "file", file); 61 | } 62 | catch (Exception e) { 63 | // ignore - digester configurator will (hopefully) do it anyhow 64 | } 65 | 66 | // if this is thrown, your McfFotobook implementation has no setFile(), 67 | // and your configurator has also not set it. 68 | if (!file.equals(fb.getFile())) 69 | throw new IllegalStateException("File could not be set on photobook. Please check used DigesterConfigurator."); 70 | 71 | return fb; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageClipart.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Point; 7 | import java.awt.image.BufferedImage; 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.Writer; 11 | 12 | import net.sf.mcf2pdf.mcfelements.McfClipart; 13 | import net.sf.mcf2pdf.mcfelements.util.ImageUtil; 14 | 15 | 16 | /** 17 | * TODO comment 18 | */ 19 | public class PageClipart implements PageDrawable { 20 | 21 | private McfClipart clipart; 22 | 23 | public PageClipart(McfClipart clipart) { 24 | this.clipart = clipart; 25 | } 26 | 27 | @Override 28 | public float getLeftMM() { 29 | return clipart.getArea().getLeft() / 10.0f; 30 | } 31 | 32 | @Override 33 | public float getTopMM() { 34 | return clipart.getArea().getTop() / 10.0f; 35 | } 36 | 37 | @Override 38 | public boolean isVectorGraphic() { 39 | return true; 40 | } 41 | 42 | @Override 43 | public void renderAsSvgElement(Writer writer, PageRenderContext context) throws IOException { 44 | // TODO Auto-generated method stub 45 | 46 | } 47 | 48 | @Override 49 | public BufferedImage renderAsBitmap(PageRenderContext context, 50 | Point drawOffsetPixels, int widthPX, int heightPX) throws IOException { 51 | File f = null; 52 | if(clipart.getDesignElementId() == null) { 53 | f = context.getClipart(clipart.getUniqueName()); 54 | } else { 55 | f = context.getClipartViaDesignElementId(clipart.getDesignElementId()); 56 | } 57 | if (f == null) { 58 | if(clipart.getDesignElementId() == null) 59 | context.getLog().warn("Clipart not found: " + clipart.getUniqueName()); 60 | else 61 | context.getLog().warn("Clipart designElementId not found: " + clipart.getDesignElementId()); 62 | return null; 63 | } 64 | context.getLog().debug("Rendering clipart " + f); 65 | 66 | int widthPixel = context.toPixel(clipart.getArea().getWidth() / 10.0f); 67 | int heightPixel = context.toPixel(clipart.getArea().getHeight() / 10.0f); 68 | 69 | drawOffsetPixels.x = drawOffsetPixels.y = 0; 70 | BufferedImage loadedClip = ImageUtil.loadClpFile(f, widthPixel, heightPixel); 71 | // apply rotation 72 | if (clipart.getArea().getRotation() != 0) { 73 | loadedClip = ImageUtil.rotateImage(loadedClip, (float)Math.toRadians(clipart.getArea().getRotation()), drawOffsetPixels); 74 | } 75 | return loadedClip; 76 | } 77 | 78 | @Override 79 | public int getZPosition() { 80 | return clipart.getArea().getZPosition(); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfFotobookImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import java.io.File; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import java.util.Vector; 10 | 11 | import net.sf.mcf2pdf.mcfelements.McfFotobook; 12 | import net.sf.mcf2pdf.mcfelements.McfPage; 13 | import net.sf.mcf2pdf.mcfelements.McfPageNum; 14 | 15 | 16 | public class McfFotobookImpl implements McfFotobook { 17 | 18 | public File file; 19 | 20 | private int productType; 21 | 22 | private String productName; 23 | 24 | private String version; 25 | 26 | private String createdWithHPSVersion; 27 | 28 | private String programVersion; 29 | 30 | private String imageDir; 31 | 32 | private int normalPages; 33 | 34 | private int totalPages; 35 | 36 | private McfPageNum pageNumbering; 37 | 38 | private List pages = new Vector(); 39 | 40 | public void addPage(McfPage page) { 41 | pages.add(page); 42 | } 43 | 44 | public List getPages() { 45 | return Collections.unmodifiableList(pages); 46 | } 47 | 48 | public void addPageNum(McfPageNum pageNumbering) { 49 | this.pageNumbering = pageNumbering; 50 | } 51 | 52 | public McfPageNum getPageNum() { 53 | return pageNumbering; 54 | } 55 | 56 | public int getProductType() { 57 | return productType; 58 | } 59 | 60 | public void setProductType(int productType) { 61 | this.productType = productType; 62 | } 63 | 64 | public String getProductName() { 65 | return productName; 66 | } 67 | 68 | public void setProductName(String productName) { 69 | this.productName = productName; 70 | } 71 | 72 | public String getVersion() { 73 | return version; 74 | } 75 | 76 | public void setVersion(String version) { 77 | this.version = version; 78 | } 79 | 80 | public String getCreatedWithHPSVersion() { 81 | return createdWithHPSVersion; 82 | } 83 | 84 | public void setCreatedWithHPSVersion(String createdWithHPSVersion) { 85 | this.createdWithHPSVersion = createdWithHPSVersion; 86 | } 87 | 88 | public String getProgramVersion() { 89 | return programVersion; 90 | } 91 | 92 | public void setProgramVersion(String programVersion) { 93 | this.programVersion = programVersion; 94 | } 95 | 96 | public String getImageDir() { 97 | return imageDir; 98 | } 99 | 100 | public void setImageDir(String imageDir) { 101 | this.imageDir = imageDir; 102 | } 103 | 104 | public int getNormalPages() { 105 | return normalPages; 106 | } 107 | 108 | public void setNormalPages(int normalPages) { 109 | this.normalPages = normalPages; 110 | } 111 | 112 | public int getTotalPages() { 113 | return totalPages; 114 | } 115 | 116 | public void setTotalPages(int totalPages) { 117 | this.totalPages = totalPages; 118 | } 119 | 120 | public File getFile() { 121 | return file; 122 | } 123 | 124 | public void setFile(File file) { 125 | this.file = file; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfPageNumImpl.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.impl; 2 | 3 | import java.awt.Color; 4 | 5 | import net.sf.mcf2pdf.mcfelements.McfFotobook; 6 | import net.sf.mcf2pdf.mcfelements.McfPageNum; 7 | 8 | public class McfPageNumImpl implements McfPageNum { 9 | 10 | private McfFotobook fotobook; 11 | private String textString; 12 | private int position; 13 | private int verticalMargin; 14 | private int horizontalMargin; 15 | private Color textColor; 16 | private Color bgColor; 17 | private float fontSize; 18 | private int fontBold; 19 | private int fontItalics; 20 | private String fontFamily; 21 | private int format; 22 | 23 | public void setFotobook(McfFotobook fotobook) { 24 | this.fotobook = fotobook; 25 | } 26 | 27 | @Override 28 | public McfFotobook getFotobook() { 29 | return fotobook; 30 | } 31 | 32 | public void setTextString(String text) { 33 | this.textString = text; 34 | } 35 | 36 | @Override 37 | public String getTextString() { 38 | return textString; 39 | } 40 | 41 | public void setPosition(int position) { 42 | this.position = position; 43 | } 44 | 45 | @Override 46 | public int getPosition() { 47 | return position; 48 | } 49 | 50 | public void setVerticalMargin(int verticalMargin) { 51 | this.verticalMargin = verticalMargin; 52 | } 53 | 54 | @Override 55 | public int getVerticalMargin() { 56 | return verticalMargin; 57 | } 58 | 59 | public void setHorizontalMargin(int horizontalMargin) { 60 | this.horizontalMargin = horizontalMargin; 61 | } 62 | 63 | @Override 64 | public int getHorizontalMargin() { 65 | return horizontalMargin; 66 | } 67 | 68 | public void setTextColor(Color textColor) { 69 | this.textColor = textColor; 70 | } 71 | 72 | @Override 73 | public Color getTextColor() { 74 | return textColor; 75 | } 76 | 77 | public void setBgColor(Color bgColor) { 78 | this.bgColor = bgColor; 79 | } 80 | 81 | @Override 82 | public Color getBgColor() { 83 | return bgColor; 84 | } 85 | 86 | public void setFontSize(float fontSize) { 87 | this.fontSize = fontSize; 88 | } 89 | 90 | @Override 91 | public float getFontSize() { 92 | return fontSize; 93 | } 94 | 95 | public void setFontBold(int fontBold) { 96 | this.fontBold = fontBold; 97 | } 98 | 99 | @Override 100 | public int getFontBold() { 101 | return fontBold; 102 | } 103 | 104 | @Override 105 | public boolean getFBold() { 106 | return (fontBold == 1) ? true : false; 107 | } 108 | 109 | public void setFontItalics(int fontItalics) { 110 | this.fontItalics = fontItalics; 111 | } 112 | 113 | @Override 114 | public int getFontItalics() { 115 | return fontItalics; 116 | } 117 | 118 | @Override 119 | public boolean getFItalics() { 120 | return (fontItalics == 1) ? true : false; 121 | } 122 | 123 | public void setFontFamily(String fontFamily) { 124 | this.fontFamily = fontFamily; 125 | } 126 | 127 | @Override 128 | public String getFontFamily() { 129 | return fontFamily; 130 | } 131 | 132 | public void setFormat(int format) { 133 | this.format = format; 134 | } 135 | 136 | @Override 137 | public int getFormat() { 138 | return format; 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/webp/Webp.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.mcfelements.util.webp; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.awt.image.DataBufferByte; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.IOException; 8 | 9 | import org.apache.commons.io.IOUtils; 10 | 11 | import com.sun.jna.Native; 12 | import com.sun.jna.Platform; 13 | 14 | /** 15 | * Utility class to load the dynamic library for the WebP file format from the 16 | * CEWE installation directory, and for convenient WebP image loading using that 17 | * library. 18 | * 19 | * @author Florian Albrecht 20 | * 21 | * @see WebpLib 22 | * 23 | */ 24 | public final class Webp { 25 | 26 | private Webp() { 27 | } 28 | 29 | /** 30 | * Loads the WebP library. Under Windows, the library must be named 31 | * libwebp.dll, under Linux and Mac OS X, a 32 | * libwebp.so is expected. For Windows and Linux, the shared 33 | * library is included in the mcf2pdf package. 34 | * 35 | * @return The loaded WebP library, as a dynamic Java JNA proxy. 36 | * 37 | * @throws IOException 38 | * If the library cannot be found. 39 | */ 40 | public static WebpLib loadLibrary() throws IOException { 41 | String libName = Platform.isWindows() ? "libwebp.dll" : "libwebp.so"; 42 | return (WebpLib) Native.loadLibrary(libName, WebpLib.class); 43 | } 44 | 45 | /** 46 | * Uses the Qt5 library functions to read the given WebP image file into a 47 | * {@link BufferedImage}. 48 | * 49 | * @param webpImageFile 50 | * WebP image file to read. 51 | * @param library 52 | * Qt5 library to use. Must have been retrieved using 53 | * {@link #loadLibrary(File)}. 54 | * @return The loaded WebP image, as a {@link BufferedImage}. 55 | * @throws IOException 56 | * If the image could not be loaded. 57 | */ 58 | public static BufferedImage loadWebPImage(File webpImageFile, WebpLib library) throws IOException { 59 | int[] aw = new int[1]; 60 | int[] ah = new int[1]; 61 | 62 | FileInputStream fis = new FileInputStream(webpImageFile); 63 | byte[] rawData; 64 | try { 65 | rawData = IOUtils.toByteArray(fis); 66 | } finally { 67 | IOUtils.closeQuietly(fis); 68 | } 69 | 70 | library.WebPGetInfo(rawData, rawData.length, aw, ah); 71 | int width = aw[0]; 72 | int height = ah[0]; 73 | 74 | if (width == 0 || height == 0 || width > 10000 || height > 10000) { 75 | throw new IOException("Invalid WebP file"); 76 | } 77 | 78 | // allocate BufferedImage including byte buffer 79 | BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); 80 | DataBufferByte dbb = (DataBufferByte) img.getRaster().getDataBuffer(); 81 | byte[] target = dbb.getData(); 82 | 83 | if (library.WebPDecodeRGBAInto(rawData, rawData.length, target, target.length, width * 4) == null) { 84 | throw new IOException("Could not read WebP file"); 85 | } 86 | 87 | // bring bytes into correct order (RGBA -> ABGR) 88 | for (int i = 0; i < target.length; i += 4) { 89 | byte r = target[i]; 90 | byte g = target[i + 1]; 91 | byte b = target[i + 2]; 92 | byte a = target[i + 3]; 93 | target[i] = a; 94 | target[i + 1] = b; 95 | target[i + 2] = g; 96 | target[i + 3] = r; 97 | } 98 | 99 | return img; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/impl/McfAlbumTypeImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfglobals.impl; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | import net.sf.mcf2pdf.mcfglobals.McfAlbumType; 14 | 15 | 16 | public class McfAlbumTypeImpl implements McfAlbumType { 17 | 18 | private String name; 19 | 20 | private int safetyMargin; 21 | 22 | private int bleedMargin; 23 | 24 | private int normalPageHorizontalClamp; 25 | 26 | private int usableWidth; 27 | 28 | private int usableHeight; 29 | 30 | private int bleedMarginCover; 31 | 32 | private int coverExtraVertical; 33 | 34 | private int coverExtraHorizontal; 35 | 36 | private Map spineWidths = new HashMap(); 37 | 38 | @Override 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | @Override 44 | public int getSafetyMargin() { 45 | return safetyMargin; 46 | } 47 | 48 | @Override 49 | public int getBleedMargin() { 50 | return bleedMargin; 51 | } 52 | 53 | 54 | @Override 55 | public int getNormalPageHorizontalClamp() { 56 | return normalPageHorizontalClamp; 57 | } 58 | 59 | @Override 60 | public int getUsableWidth() { 61 | return usableWidth; 62 | } 63 | 64 | @Override 65 | public int getUsableHeight() { 66 | return usableHeight; 67 | } 68 | 69 | @Override 70 | public int getBleedMarginCover() { 71 | return bleedMarginCover; 72 | } 73 | 74 | @Override 75 | public int getCoverExtraVertical() { 76 | return coverExtraVertical; 77 | } 78 | 79 | @Override 80 | public int getCoverExtraHorizontal() { 81 | return coverExtraHorizontal; 82 | } 83 | 84 | @Override 85 | public int getSpineWidth(int normalPageCount) { 86 | Integer key = Integer.valueOf(normalPageCount); 87 | if (!spineWidths.containsKey(key)) 88 | return 0; 89 | 90 | return spineWidths.get(key).intValue(); 91 | } 92 | 93 | public void setName(String name) { 94 | this.name = name; 95 | } 96 | 97 | public void setSafetyMargin(int safetyMargin) { 98 | this.safetyMargin = safetyMargin; 99 | } 100 | 101 | public void setBleedMargin(int bleedMargin) { 102 | this.bleedMargin = bleedMargin; 103 | } 104 | 105 | public void setNormalPageHorizontalClamp(int normalPageHorizontalClamp) { 106 | this.normalPageHorizontalClamp = normalPageHorizontalClamp; 107 | } 108 | 109 | public void setUsableWidth(int usableWidth) { 110 | this.usableWidth = usableWidth; 111 | } 112 | 113 | public void setUsableHeight(int usableHeight) { 114 | this.usableHeight = usableHeight; 115 | } 116 | 117 | public void setBleedMarginCover(int bleedMarginCover) { 118 | this.bleedMarginCover = bleedMarginCover; 119 | } 120 | 121 | public void setCoverExtraVertical(int coverExtraVertical) { 122 | this.coverExtraVertical = coverExtraVertical; 123 | } 124 | 125 | public void setCoverExtraHorizontal(int coverExtraHorizontal) { 126 | this.coverExtraHorizontal = coverExtraHorizontal; 127 | } 128 | 129 | public void addSpine(int pageCount, int width) { 130 | spineWidths.put(pageCount, width); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/BitmapPageBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.pagebuild; 9 | 10 | import java.awt.Color; 11 | import java.awt.Graphics2D; 12 | import java.awt.Point; 13 | import java.awt.image.BufferedImage; 14 | import java.io.File; 15 | import java.io.FileNotFoundException; 16 | import java.io.IOException; 17 | import java.util.Collections; 18 | import java.util.Comparator; 19 | import java.util.List; 20 | import java.util.Vector; 21 | 22 | import javax.imageio.ImageIO; 23 | 24 | import net.sf.mcf2pdf.mcfelements.util.XslFoDocumentBuilder; 25 | 26 | import org.jdom.Namespace; 27 | 28 | 29 | 30 | public class BitmapPageBuilder extends AbstractPageBuilder { 31 | 32 | private File tempImageDir; 33 | 34 | private PageRenderContext context; 35 | 36 | private int widthPX; 37 | 38 | private int heightPX; 39 | 40 | private static final Comparator zComp = new Comparator() { 41 | @Override 42 | public int compare(PageDrawable p1, PageDrawable p2) { 43 | return p1.getZPosition() - p2.getZPosition(); 44 | } 45 | }; 46 | 47 | public BitmapPageBuilder(int widthPX, int heightPX, 48 | PageRenderContext context, File tempImageDir) throws IOException { 49 | this.widthPX = widthPX; 50 | this.heightPX = heightPX; 51 | this.context = context; 52 | this.tempImageDir = tempImageDir; 53 | } 54 | 55 | @Override 56 | public void addToDocumentBuilder(XslFoDocumentBuilder docBuilder) 57 | throws IOException { 58 | // render drawables onto image, regardless of type 59 | List pageContents = new Vector(getDrawables()); 60 | Collections.sort(pageContents, zComp); 61 | 62 | context.getLog().debug("Creating full page image from page elements"); 63 | 64 | BufferedImage img = new BufferedImage(widthPX, heightPX, BufferedImage.TYPE_INT_ARGB); 65 | Graphics2D g2d = img.createGraphics(); 66 | g2d.setColor(Color.white); 67 | g2d.fillRect(0, 0, img.getWidth(), img.getHeight()); 68 | 69 | for (PageDrawable pd : pageContents) { 70 | int left = context.toPixel(pd.getLeftMM()); 71 | int top = context.toPixel(pd.getTopMM()); 72 | 73 | Point offset = new Point(); 74 | try { 75 | BufferedImage pdImg = pd.renderAsBitmap(context, offset, widthPX, heightPX); 76 | if (pdImg != null) 77 | g2d.drawImage(pdImg, left + offset.x, top + offset.y, null); 78 | } 79 | catch (FileNotFoundException e) { 80 | // ignore 81 | // throw e; 82 | } 83 | } 84 | 85 | docBuilder.addPageElement(createImgFoElement(img, docBuilder.getNamespace())); 86 | g2d.dispose(); 87 | } 88 | 89 | private String createImgFoElement(BufferedImage img, Namespace xslFoNs) throws IOException { 90 | // save bitmap to file 91 | File f; 92 | int i = 1; 93 | do { 94 | f = new File(tempImageDir, (i++) + ".jpg"); 95 | } 96 | while (f.isFile()); 97 | 98 | BufferedImage imgPlain = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB); 99 | Graphics2D g2d = imgPlain.createGraphics(); 100 | g2d.drawImage(img, 0, 0, null); 101 | g2d.dispose(); 102 | 103 | ImageIO.write(imgPlain, "jpeg", f); 104 | String src = f.getAbsolutePath(); 105 | f.deleteOnExit(); 106 | 107 | return src; 108 | } 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageNum.java: -------------------------------------------------------------------------------- 1 | package net.sf.mcf2pdf.pagebuild; 2 | 3 | import java.awt.Color; 4 | import java.awt.FontMetrics; 5 | import java.awt.Graphics2D; 6 | import java.awt.Point; 7 | import java.awt.image.BufferedImage; 8 | import java.io.IOException; 9 | import java.io.Writer; 10 | 11 | import net.sf.mcf2pdf.mcfelements.McfFotobook; 12 | import net.sf.mcf2pdf.mcfelements.McfPage; 13 | import net.sf.mcf2pdf.mcfelements.McfPageNum; 14 | 15 | 16 | 17 | public class PageNum implements PageDrawable { 18 | 19 | private McfPageNum pageNum; 20 | private McfPage page; 21 | private String side; 22 | 23 | private int leftPX = -1; 24 | private int topPX = -1; 25 | private int pageWidth; 26 | private int pageHeight; 27 | 28 | public PageNum(McfFotobook book, McfPage page, String side, int pageWidth, int pageHeight) { 29 | this.pageNum = book.getPageNum(); 30 | this.page = page; 31 | this.side = side; 32 | this.pageWidth = pageWidth; 33 | this.pageHeight = pageHeight; 34 | 35 | setPosition(); 36 | 37 | FormattedTextParagraph para = new FormattedTextParagraph(); 38 | para.addText(createFormattedText()); 39 | } 40 | 41 | @Override 42 | public int getZPosition() { 43 | return 100000; 44 | } 45 | 46 | @Override 47 | public float getLeftMM() { 48 | // TODO Auto-generated method stub 49 | return 0; 50 | } 51 | 52 | @Override 53 | public float getTopMM() { 54 | // TODO Auto-generated method stub 55 | return 0; 56 | } 57 | 58 | private void setPosition() { 59 | int offsetXCenter = (side.equals("right")) ? Math.round(pageWidth / 2.0f) : 0; 60 | int offsetXOutside = (side.equals("right")) ? (pageWidth - 2 * pageNum.getHorizontalMargin()) : 0; 61 | switch (pageNum.getPosition()) { 62 | case 2: // top center 63 | topPX = pageNum.getVerticalMargin(); 64 | leftPX = Math.round(pageWidth / 4.0f) + offsetXCenter; 65 | break; 66 | case 1: // top outside 67 | topPX = pageNum.getVerticalMargin(); 68 | leftPX = pageNum.getHorizontalMargin() + offsetXOutside; 69 | break; 70 | case 5: // bottom center 71 | topPX = pageHeight - pageNum.getVerticalMargin(); 72 | leftPX = Math.round(pageWidth / 4.0f) + offsetXCenter; 73 | break; 74 | case 4: // bottom outside 75 | topPX = pageHeight - pageNum.getVerticalMargin(); 76 | leftPX = pageNum.getHorizontalMargin() + offsetXOutside; 77 | break; 78 | } 79 | } 80 | 81 | private FormattedText createFormattedText() { 82 | String text = pageNum.getTextString().replaceAll("%", Integer.toString(page.getPageNr())); 83 | Boolean bold = pageNum.getFBold(); 84 | Boolean italics = pageNum.getFItalics(); 85 | Color textColor = pageNum.getTextColor(); 86 | String fontFamily = pageNum.getFontFamily(); 87 | Float fontSize = pageNum.getFontSize(); 88 | // TODO check margins for Pagenum 89 | return new FormattedText(text, bold, italics, false, textColor, fontFamily, fontSize, 90 | 0,0,0,0); 91 | } 92 | 93 | @Override 94 | public boolean isVectorGraphic() { 95 | return true; 96 | } 97 | 98 | @Override 99 | public void renderAsSvgElement(Writer writer, PageRenderContext context) throws IOException { 100 | // TODO Auto-generated method stub 101 | } 102 | 103 | @Override 104 | public BufferedImage renderAsBitmap(PageRenderContext context, Point drawOffsetPixels, int widthPX, int heightPX) 105 | throws IOException { 106 | context.getLog().debug("Rendering pageNumber"); 107 | 108 | 109 | BufferedImage tempImg = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); 110 | Graphics2D tempGraphics = tempImg.createGraphics(); 111 | 112 | FontMetrics fm = tempGraphics.getFontMetrics(); 113 | 114 | return null; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/XslFoDocumentBuilder.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfelements.util; 9 | 10 | import org.jdom.Document; 11 | import org.jdom.Element; 12 | import org.jdom.Namespace; 13 | 14 | /** 15 | * A builder for XSL-FO documents. This builder provides a simple way 16 | * to build a flow of pages, and internally maintains a DOM with the according 17 | * XSL-FO elements. When finished with adding content, call createDocument() 18 | * to receive the DOM object. 19 | */ 20 | public class XslFoDocumentBuilder { 21 | 22 | private Document document; 23 | 24 | private Element flow; 25 | 26 | private static final Namespace ns = Namespace.getNamespace("fo", "http://www.w3.org/1999/XSL/Format"); 27 | 28 | protected static final String EMPTY_DTD = ""; 29 | 30 | public XslFoDocumentBuilder() { 31 | document = new Document(); 32 | 33 | // create root element 34 | Element e = new Element("root", ns); 35 | 36 | document.addContent(e); 37 | } 38 | 39 | public void addPageMaster(String name, int widthPX, int heightPX) { 40 | Element m = new Element("simple-page-master", ns); 41 | m.setAttribute("master-name", name); 42 | m.setAttribute("page-width", widthPX + "px"); 43 | m.setAttribute("page-height", heightPX + "px"); 44 | 45 | Element body = new Element("region-body", ns); 46 | m.addContent(body); 47 | 48 | // insert into master set, if present 49 | Element ms = document.getRootElement().getChild("layout-master-set", ns); 50 | if (ms == null) { 51 | ms = new Element("layout-master-set", ns); 52 | document.getRootElement().addContent(ms); 53 | } 54 | 55 | ms.addContent(m); 56 | } 57 | 58 | public void startFlow(String masterName) { 59 | if (flow != null) 60 | throw new IllegalStateException("Please call endFlow() first before starting a new flow!"); 61 | 62 | Element ps = new Element("page-sequence", ns); 63 | ps.setAttribute("master-reference", masterName); 64 | Element f = new Element("flow", ns); 65 | f.setAttribute("flow-name", "xsl-region-body"); 66 | ps.addContent(f); 67 | document.getRootElement().addContent(ps); 68 | flow = f; 69 | } 70 | 71 | public void endFlow() { 72 | flow = null; 73 | } 74 | 75 | public void newPage() { 76 | if (flow == null) 77 | throw new IllegalStateException("Please call startFlow() first"); 78 | 79 | Element e = new Element("block", ns); 80 | e.setAttribute("break-after", "page"); 81 | e.setAttribute("padding", "0px"); 82 | e.setAttribute("margin", "0px"); 83 | e.setAttribute("border-width", "0px"); 84 | flow.addContent(e); 85 | } 86 | 87 | public Document createDocument() { 88 | return (Document)document.clone(); 89 | } 90 | 91 | public Namespace getNamespace() { 92 | return ns; 93 | } 94 | 95 | public void addPageElement(String imgSource) { 96 | if (flow == null) 97 | throw new IllegalStateException("Please call startFlow() first"); 98 | 99 | // create block container 100 | Element bc = new Element("block-container",ns); 101 | bc.setAttribute("background-image", "file:///"+imgSource); 102 | bc.setAttribute("width", "100%"); 103 | bc.setAttribute("height", "100%"); 104 | bc.addContent(new Element("block", ns)); 105 | 106 | flow.addContent(bc); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfImageImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import net.sf.mcf2pdf.mcfelements.McfCutout; 7 | import net.sf.mcf2pdf.mcfelements.McfImage; 8 | 9 | public class McfImageImpl extends AbstractMcfAreaContentImpl implements McfImage { 10 | 11 | private String parentChildRelationshipNature; 12 | 13 | private float scale; 14 | 15 | private int useABK; 16 | 17 | private float left; 18 | 19 | private float top; 20 | 21 | private String fileNameMaster; 22 | 23 | private String safeContainerLocation; 24 | 25 | private String fileName; 26 | 27 | private String fadingFile; 28 | 29 | private String passepartoutDesignElementId; 30 | 31 | private McfCutout cutout; 32 | 33 | @Override 34 | public ContentType getContentType() { 35 | return ContentType.IMAGE; 36 | } 37 | 38 | public String getParentChildRelationshipNature() { 39 | return parentChildRelationshipNature; 40 | } 41 | 42 | public void setParentChildRelationshipNature( 43 | String parentChildRelationshipNature) { 44 | this.parentChildRelationshipNature = parentChildRelationshipNature; 45 | } 46 | 47 | public float getScale() { 48 | // Version 4.x 49 | if (this.cutout != null) { 50 | return this.cutout.getScale(); 51 | } 52 | return scale; 53 | } 54 | 55 | public void setScale(float scale) { 56 | this.scale = scale; 57 | } 58 | 59 | public int getUseABK() { 60 | return useABK; 61 | } 62 | 63 | public void setUseABK(int useABK) { 64 | this.useABK = useABK; 65 | } 66 | 67 | public float getLeft() { 68 | // Version 4.x 69 | if (this.cutout != null) { 70 | return this.cutout.getLeft()/this.cutout.getScale(); 71 | } 72 | return left; 73 | } 74 | 75 | public void setLeft(float left) { 76 | this.left = left; 77 | } 78 | 79 | public float getTop() { 80 | // Version 4.x 81 | if (this.cutout != null) { 82 | // log.debug("top from cutout: " + this.cutout.getTop()); 83 | return this.cutout.getTop()/this.cutout.getScale(); 84 | } 85 | return top; 86 | } 87 | 88 | public void setTop(float top) { 89 | this.top = top; 90 | } 91 | 92 | public String getFileNameMaster() { 93 | return fileNameMaster; 94 | } 95 | 96 | public void setFileNameMaster(String fileNameMaster) { 97 | this.fileNameMaster = fileNameMaster; 98 | } 99 | 100 | public String getSafeContainerLocation() { 101 | return safeContainerLocation; 102 | } 103 | 104 | public void setSafeContainerLocation(String safeContainerLocation) { 105 | this.safeContainerLocation = safeContainerLocation; 106 | } 107 | 108 | public String getFileName() { 109 | return fileName; 110 | } 111 | 112 | public void setFileName(String fileName) { 113 | this.fileName = fileName; 114 | } 115 | 116 | public String getFadingFile() { 117 | // Version 6/7 ... 118 | if (this.cutout != null) { 119 | return passepartoutDesignElementId; 120 | } 121 | if(this.passepartoutDesignElementId != null) { 122 | return passepartoutDesignElementId; 123 | } 124 | return fadingFile; 125 | } 126 | 127 | @Override 128 | public String getPassepartoutDesignElementId() { 129 | return passepartoutDesignElementId; 130 | } 131 | 132 | public void setPassepartoutDesignElementId(String passepartoutDesignElementId) { 133 | this.passepartoutDesignElementId = passepartoutDesignElementId; 134 | } 135 | 136 | public void setFadingFile(String fadingFile) { 137 | this.fadingFile = fadingFile; 138 | } 139 | 140 | public McfCutout getCutout() { 141 | return cutout; 142 | } 143 | 144 | public void setCutout(McfCutout cutout) { 145 | // log.debug("cutout.top: " + cutout.getTop()); 146 | this.cutout = cutout; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/ClpInputStream.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfelements.util; 9 | 10 | import java.io.*; 11 | import java.nio.ByteBuffer; 12 | import java.nio.charset.Charset; 13 | 14 | /** 15 | * InputStream filter for the ugly CLP format.
    16 | * This format is a somewhat "obfuscated" SVG file. Every character of the SVG 17 | * file is written as hexadecimal representation of the byte value of that 18 | * character, and from time to time, random characters which cannot be interpreted 19 | * as hexadecimal are inserted. The first character is always an "a" which 20 | * also has to be ignored (although this would be a valid hexadecimal character).
    21 | * This class is not optimized for speed. It is kept as simple as possible, as 22 | * CLP files tend to be rather small. 23 | */ 24 | public class ClpInputStream extends FilterInputStream { 25 | 26 | private boolean firstByte = true; 27 | 28 | public ClpInputStream(InputStream in) { 29 | super(in); 30 | } 31 | 32 | @Override 33 | public int read() throws IOException { 34 | if (firstByte) { 35 | // first byte has to be ignored and must be "a" 36 | int b = in.read(); 37 | if (b == -1) 38 | return -1; // okay - empty stream 39 | if (b != 0x61) 40 | throw new IOException("CLP data must start with byte 0x61"); 41 | firstByte = false; 42 | } 43 | 44 | // read two bytes, interpret them as a string and convert that string 45 | // to a hexadecimal number. Ignore non-hexadecimal characters. 46 | int i1 = readValidCharacter(); 47 | if (i1 == -1) 48 | return -1; 49 | int i2 = readValidCharacter(); 50 | if (i2 == -1) 51 | throw new EOFException("Unexpected end of CLP data"); 52 | 53 | char c1 = (char)i1; 54 | char c2 = (char)i2; 55 | String s = new StringBuilder().append(c1).append(c2).toString(); 56 | 57 | try { 58 | return Integer.valueOf(s, 16).intValue(); 59 | } 60 | catch (NumberFormatException nfe) { 61 | // should not occur due to checks in readValidCharacter() 62 | throw new IOException("Invalid character sequence found: " + s); 63 | } 64 | } 65 | 66 | @Override 67 | public int read(byte[] b, int off, int len) throws IOException { 68 | // fallback to simple read() 69 | // TODO replace with an optimized version 70 | 71 | int cnt = 0; 72 | for (int i = 0; i < len; i++) { 73 | int n = read(); 74 | if (n == -1) 75 | return (cnt == 0 ? -1 : cnt); 76 | b[off + i] = (byte)n; 77 | cnt++; 78 | } 79 | 80 | return cnt == 0 ? -1 : cnt; 81 | } 82 | 83 | @Override 84 | public boolean markSupported() { 85 | return false; 86 | } 87 | 88 | @Override 89 | public int read(byte[] b) throws IOException { 90 | return read(b, 0, b.length); 91 | } 92 | 93 | private static Charset CS_ISO = Charset.forName("ISO-8859-1"); 94 | 95 | private int readValidCharacter() throws IOException { 96 | String s; 97 | char c; 98 | do { 99 | int b = in.read(); 100 | if (b == -1) 101 | return -1; 102 | ByteBuffer bb = ByteBuffer.wrap(new byte[] { (byte)b }); 103 | c = CS_ISO.decode(bb).charAt(0); 104 | s = "" + c; 105 | if (!s.matches("[0-9a-zA-Z]")) 106 | throw new IOException("Unexpected character found in CLP data: " + s); 107 | } 108 | while (!s.matches("[0-9a-fA-F]")); 109 | return c; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/PdfUtil.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfelements.util; 9 | 10 | import java.io.*; 11 | 12 | import javax.xml.transform.Result; 13 | import javax.xml.transform.Source; 14 | import javax.xml.transform.Transformer; 15 | import javax.xml.transform.TransformerException; 16 | import javax.xml.transform.TransformerFactory; 17 | import javax.xml.transform.sax.SAXResult; 18 | import javax.xml.transform.stream.StreamSource; 19 | 20 | import org.apache.commons.logging.Log; 21 | import org.apache.commons.logging.LogFactory; 22 | import org.apache.fop.apps.FOPException; 23 | import org.apache.fop.apps.FOUserAgent; 24 | import org.apache.fop.apps.Fop; 25 | import org.apache.fop.apps.FopFactory; 26 | import org.apache.fop.apps.FormattingResults; 27 | import org.apache.fop.apps.MimeConstants; 28 | import org.apache.fop.apps.PageSequenceResults; 29 | 30 | /** 31 | * Utility class for working with PDFs. 32 | */ 33 | public class PdfUtil { 34 | 35 | private final static Log log = LogFactory.getLog(PdfUtil.class); 36 | 37 | /** 38 | * Converts an FO file to a PDF file using Apache FOP. 39 | * 40 | * @param fo the FO file 41 | * @param pdf the target PDF file 42 | * @param dpi the DPI resolution to use for bitmaps in the PDF 43 | * @throws IOException In case of an I/O problem 44 | * @throws FOPException In case of a FOP problem 45 | * @throws TransformerException In case of XML transformer problem 46 | */ 47 | @SuppressWarnings("rawtypes") 48 | public static void convertFO2PDF(InputStream fo, OutputStream pdf, int dpi) throws IOException, 49 | FOPException, TransformerException { 50 | 51 | //FopFactory fopFactory = FopFactory.newInstance(); 52 | FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); 53 | 54 | FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 55 | // configure foUserAgent as desired 56 | foUserAgent.setTargetResolution(dpi); 57 | 58 | 59 | // Setup output stream. Note: Using BufferedOutputStream 60 | // for performance reasons (helpful with FileOutputStreams). 61 | OutputStream out = new BufferedOutputStream(pdf); 62 | 63 | // Construct fop with desired output format 64 | Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); 65 | 66 | // Setup JAXP using identity transformer 67 | TransformerFactory factory = TransformerFactory.newInstance(); 68 | Transformer transformer = factory.newTransformer(); // identity 69 | // transformer 70 | 71 | // Setup input stream 72 | Source src = new StreamSource(fo); 73 | 74 | // Resulting SAX events (the generated FO) must be piped through to FOP 75 | Result res = new SAXResult(fop.getDefaultHandler()); 76 | 77 | // Start XSLT transformation and FOP processing 78 | transformer.transform(src, res); 79 | 80 | // Result processing 81 | FormattingResults foResults = fop.getResults(); 82 | java.util.List pageSequences = foResults.getPageSequences(); 83 | for (java.util.Iterator it = pageSequences.iterator(); it.hasNext();) { 84 | PageSequenceResults pageSequenceResults = (PageSequenceResults)it 85 | .next(); 86 | log.debug("PageSequence " 87 | + (String.valueOf(pageSequenceResults.getID()).length() > 0 ? pageSequenceResults 88 | .getID() : "") + " generated " 89 | + pageSequenceResults.getPageCount() + " pages."); 90 | } 91 | log.info("Generated " + foResults.getPageCount() + " PDF pages in total."); 92 | out.flush(); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/McfProductCatalogue.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfglobals; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.util.List; 13 | import java.util.Vector; 14 | 15 | import net.sf.mcf2pdf.mcfelements.util.DigesterUtil; 16 | import net.sf.mcf2pdf.mcfglobals.impl.McfAlbumTypeImpl; 17 | import net.sf.mcf2pdf.mcfglobals.impl.McfProductCatalogueImpl; 18 | 19 | import org.apache.commons.digester3.Digester; 20 | import org.xml.sax.SAXException; 21 | 22 | /** 23 | * TODO comment 24 | */ 25 | public abstract class McfProductCatalogue { 26 | 27 | public static enum CatalogueVersion { 28 | PRE_V6, V6; 29 | } 30 | 31 | public abstract McfAlbumType getAlbumType(String name); 32 | 33 | public abstract boolean isEmpty(); 34 | 35 | public static McfProductCatalogue read(InputStream in, CatalogueVersion version) throws IOException, SAXException { 36 | if (version == CatalogueVersion.V6) { 37 | return readV6(in); 38 | } 39 | 40 | // PRE_V6 41 | Digester digester = new Digester(); 42 | digester.addObjectCreate("fotobookdefinitions", McfProductCatalogueImpl.class); 43 | digester.addObjectCreate("fotobookdefinitions/album", McfAlbumTypeImpl.class); 44 | DigesterUtil.addSetProperties(digester, "fotobookdefinitions/album", getAlbumSpecialAttributes()); 45 | DigesterUtil.addSetProperties(digester, "fotobookdefinitions/album/usablesize", getUsableSizeAttributes()); 46 | digester.addCallMethod("fotobookdefinitions/album/spines/spine", "addSpine", 2, 47 | new String[] { Integer.class.getName(), Integer.class.getName() }); 48 | digester.addCallParam("fotobookdefinitions/album/spines/spine", 0, "pages"); 49 | digester.addCallParam("fotobookdefinitions/album/spines/spine", 1, "width"); 50 | digester.addSetNext("fotobookdefinitions/album", "addAlbumType"); 51 | 52 | return digester.parse(in); 53 | } 54 | 55 | private static McfProductCatalogue readV6(InputStream in) throws IOException, SAXException { 56 | Digester digester = new Digester(); 57 | digester.addObjectCreate("description", McfProductCatalogueImpl.class); 58 | digester.addObjectCreate("description/product", McfAlbumTypeImpl.class); 59 | DigesterUtil.addSetProperties(digester, "description/product", getAlbumSpecialAttributes()); 60 | DigesterUtil.addSetProperties(digester, "description/product/usablesize", getUsableSizeAttributes()); 61 | digester.addCallMethod("description/product/spines/spine", "addSpine", 2, 62 | new String[] { Integer.class.getName(), Integer.class.getName() }); 63 | digester.addCallParam("description/product/spines/spine", 0, "pages"); 64 | digester.addCallParam("description/product/spines/spine", 1, "width"); 65 | digester.addSetNext("description/product", "addAlbumType"); 66 | 67 | return digester.parse(in); 68 | } 69 | 70 | private static List getAlbumSpecialAttributes() { 71 | List result = new Vector(); 72 | result.add(new String[] { "safetymargin", "safetyMargin" }); 73 | result.add(new String[] { "bleedmargin", "bleedMargin" }); 74 | result.add(new String[] { "normalpagehorizontalclamp", "normalPageHorizontalClamp" }); 75 | result.add(new String[] { "coverextrahorizontal", "coverExtraHorizontal" }); 76 | result.add(new String[] { "coverextravertical", "coverExtraVertical" }); 77 | result.add(new String[] { "bleedmargincover", "bleedMarginCover" }); 78 | return result; 79 | } 80 | 81 | private static List getUsableSizeAttributes() { 82 | List result = new Vector(); 83 | result.add(new String[] { "width", "usableWidth" }); 84 | result.add(new String[] { "height", "usableHeight" }); 85 | return result; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/util/FadingComposite.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | * All rights reserved. This file is made available under the terms of the 4 | * Common Development and Distribution License (CDDL) v1.0 which accompanies 5 | * this distribution, and is available at 6 | * http://www.opensource.org/licenses/cddl1.txt 7 | *******************************************************************************/ 8 | package net.sf.mcf2pdf.mcfelements.util; 9 | 10 | import java.awt.Composite; 11 | import java.awt.CompositeContext; 12 | import java.awt.RenderingHints; 13 | import java.awt.image.*; 14 | 15 | /** 16 | * Performs the "fading" of a rendered image with a mask image. 17 | * In MCF, the mask images have to be applied as follows: 18 | *
      19 | *
    • transparent areas have to be also transparent on target image
    • 20 | *
    • black areas are "opaque" areas of the target image
    • 21 | *
    • greyscale areas have to get an alpha value on the target image, 22 | * according to the greyscale degree.
    • 23 | *
    24 | */ 25 | public final class FadingComposite implements Composite { 26 | 27 | public static final FadingComposite INSTANCE = new FadingComposite(); 28 | 29 | private FadingComposite() { 30 | } 31 | 32 | 33 | private static boolean validateColorModel(ColorModel cm) { 34 | if (cm instanceof DirectColorModel 35 | && cm.getTransferType() == DataBuffer.TYPE_INT) { 36 | DirectColorModel directCM = (DirectColorModel)cm; 37 | 38 | return directCM.getRedMask() == 0x00FF0000 39 | && directCM.getGreenMask() == 0x0000FF00 40 | && directCM.getBlueMask() == 0x000000FF 41 | && directCM.getAlphaMask() == 0xFF000000; 42 | } 43 | 44 | return false; 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | public CompositeContext createContext(ColorModel srcColorModel, 51 | ColorModel dstColorModel, RenderingHints hints) { 52 | if (!validateColorModel(srcColorModel) 53 | || !validateColorModel(dstColorModel)) { 54 | throw new RasterFormatException("Color models are not compatible"); 55 | } 56 | 57 | return new FadingContext(this); 58 | } 59 | 60 | private static final class FadingContext implements CompositeContext { 61 | 62 | private FadingContext(FadingComposite composite) { 63 | } 64 | 65 | public void dispose() { 66 | } 67 | 68 | public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { 69 | int width = Math.min(src.getWidth(), dstIn.getWidth()); 70 | int height = Math.min(src.getHeight(), dstIn.getHeight()); 71 | 72 | int[] result = new int[4]; 73 | int[] srcPixel = new int[4]; 74 | int[] dstPixel = new int[4]; 75 | int[] srcPixels = new int[width]; 76 | int[] dstPixels = new int[width]; 77 | 78 | for (int y = 0; y < height; y++) { 79 | src.getDataElements(0, y, width, 1, srcPixels); 80 | dstIn.getDataElements(0, y, width, 1, dstPixels); 81 | for (int x = 0; x < width; x++) { 82 | // pixels are stored as INT_ARGB 83 | // our arrays are [R, G, B, A] 84 | int pixel = srcPixels[x]; 85 | srcPixel[0] = (pixel >> 16) & 0xFF; 86 | srcPixel[1] = (pixel >> 8) & 0xFF; 87 | srcPixel[2] = (pixel) & 0xFF; 88 | srcPixel[3] = (pixel >> 24) & 0xFF; 89 | 90 | pixel = dstPixels[x]; 91 | dstPixel[0] = (pixel >> 16) & 0xFF; 92 | dstPixel[1] = (pixel >> 8) & 0xFF; 93 | dstPixel[2] = (pixel) & 0xFF; 94 | dstPixel[3] = (pixel >> 24) & 0xFF; 95 | 96 | process(srcPixel, dstPixel, result); 97 | // copy back to dstPixels 98 | dstPixels[x] = ((result[3] & 0xFF) << 24) | ((result[0] & 0xFF) << 16) | 99 | ((result[1] & 0xFF) << 8) | (result[2] & 0xFF); 100 | } 101 | dstOut.setDataElements(0, y, width, 1, dstPixels); 102 | } 103 | } 104 | 105 | // The core "fading" logic 106 | private void process(int[] src, int[] dst, int[] result) { 107 | // use colors from dst, calculate alpha from src color 108 | result[0] = dst[0]; 109 | result[1] = dst[1]; 110 | result[2] = dst[2]; 111 | 112 | if (src[3] != 255) { 113 | result[3] = src[3]; 114 | } 115 | else { 116 | int alpha = 255 - (int)Math.round((src[0] + src[1] + src[2]) / 3.0); 117 | result[3] = Math.max(alpha, 0); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageDrawable.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Point; 7 | import java.awt.image.BufferedImage; 8 | import java.io.IOException; 9 | import java.io.Writer; 10 | 11 | /** 12 | * The interface for objects which can be drawn by PageBuilders. 13 | * Every PageDrawable must be able to render itself as a bitmap. 14 | * Optionally, it can also be able to create an SVG element displaying its contents. 15 | */ 16 | public interface PageDrawable { 17 | 18 | /** 19 | * Indicates if this object supports rendering as an SVG element. This would 20 | * enable vector based PageBuilders to achieve better quality in 21 | * the output results. 22 | * 23 | * @return true if a call to renderAsSvgElement() is 24 | * valid, false otherwise. 25 | * 26 | * @see #renderAsSvgElement(Writer, PageRenderContext) 27 | */ 28 | public boolean isVectorGraphic(); 29 | 30 | /** 31 | * Renders this drawble as an SVG element. A typical implementation would create 32 | * a <g> element with a z-index and left-top position 33 | * calculated as "pixel position" (using the given Page Render Context), 34 | * and optionally a transformation to size the contents according to the 35 | * parameters of the underlying MCF element (e.g. scaling a clipart).
    36 | * If isVectorGraphic() for this object returns false, 37 | * this method is free to (and should) throw an UnsupportedOperationException. 38 | * 39 | * @param writer Writer to write the SVG element and content to. 40 | * @param context Current Page Render Context. 41 | * @throws IOException If any I/O related problem occurs, e.g. reading a 42 | * clipart file. 43 | */ 44 | public void renderAsSvgElement(Writer writer, PageRenderContext context) throws IOException; 45 | 46 | /** 47 | * Renders this drawable as a bitmap according to the settings of the given 48 | * Page Render Context. If attributions (border, shadow...) require a pixel-based 49 | * drawing starting on another point than the point given by getLeftMM() 50 | * and getRightMM(), the parameter drawOffsetPixels 51 | * must be filled with the required drawing offset (in pixels). 52 | * 53 | * @param context Current Page Render Context. 54 | * @param drawOffsetPixels Receives the required drawing offset, relative to 55 | * the position indicated by getLeftMM() and getRightMM(), 56 | * translated in pixels (using the Page Render Context). 57 | * 58 | * @return The rendered bitmap. 59 | * 60 | * @throws IOException If any I/O related problem occurs, e.g. reading an 61 | * image file. 62 | */ 63 | public BufferedImage renderAsBitmap(PageRenderContext context, Point drawOffsetPixels, int widthPX, int heightPX) throws IOException; 64 | 65 | /** 66 | * Returns the Z position of this drawable. This is mostly indicated by the 67 | * underlying MCF elements (by their area).
    68 | * This value is only used for bitmap based rendering; SVG elements rendered 69 | * by renderAsSvgElement() must provide their own z-index attribute. 70 | * 71 | * @return The Z Position of this drawable. The higher the value, the later 72 | * will this drawable be drawn when the page is rendered. 73 | */ 74 | public int getZPosition(); 75 | 76 | /** 77 | * Returns the x-position of this drawable, relative to the left border of the 78 | * current double page. This is mostly indicated by the underlying MCF elements (by their area).
    79 | * This value is only used for bitmap based rendering; SVG elements rendered 80 | * by renderAsSvgElement() must provide their own position attributes. 81 | * 82 | * @return The x-Position of this drawable, in millimeters. 83 | */ 84 | public float getLeftMM(); 85 | 86 | /** 87 | * Returns the y-position of this drawable, relative to the top border of the 88 | * current double page. This is mostly indicated by the underlying MCF elements (by their area).
    89 | * This value is only used for bitmap based rendering; SVG elements rendered 90 | * by renderAsSvgElement() must provide their own position attributes. 91 | * 92 | * @return The y-Position of this drawable, in millimeters. 93 | */ 94 | public float getTopMM(); 95 | 96 | } 97 | -------------------------------------------------------------------------------- /mcf2pdf.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/FormattedTextParagraph.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Font; 7 | import java.awt.FontMetrics; 8 | import java.awt.Graphics2D; 9 | import java.awt.GraphicsEnvironment; 10 | import java.awt.font.TextAttribute; 11 | import java.awt.geom.AffineTransform; 12 | import java.text.AttributedCharacterIterator; 13 | import java.text.AttributedString; 14 | import java.util.Collections; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.Vector; 19 | 20 | public class FormattedTextParagraph { 21 | 22 | public static enum Alignment { 23 | LEFT, CENTER, RIGHT, JUSTIFY 24 | } 25 | 26 | private Alignment alignment = Alignment.LEFT; 27 | 28 | private List texts = new Vector(); 29 | 30 | public FormattedTextParagraph() { 31 | } 32 | 33 | public FormattedTextParagraph createEmptyCopy() { 34 | FormattedTextParagraph result = new FormattedTextParagraph(); 35 | result.alignment = alignment; 36 | return result; 37 | } 38 | 39 | public void addText(FormattedText text) { 40 | // if we contain an empty start text, remove that now! 41 | if (texts.size() == 1 && texts.get(0).getText().length() == 0) 42 | texts.remove(0); 43 | texts.add(text); 44 | } 45 | 46 | public List getTexts() { 47 | return Collections.unmodifiableList(texts); 48 | } 49 | 50 | public void setAlignment(Alignment alignment) { 51 | this.alignment = alignment; 52 | } 53 | 54 | public Alignment getAlignment() { 55 | return alignment; 56 | } 57 | 58 | public AttributedCharacterIterator getCharacterIterator(PageRenderContext context) { 59 | // build whole string 60 | StringBuilder sb = new StringBuilder(); 61 | for (FormattedText text : texts) { 62 | sb.append(text.getText()); 63 | } 64 | AttributedString string = new AttributedString(sb.toString()); 65 | 66 | // apply formats 67 | int start = 0; 68 | for (FormattedText text : texts) { 69 | Map map = new HashMap(); 70 | 71 | // use font created by text (could be a loaded font!) 72 | Font font = createFont(text, context); 73 | 74 | // default attributes (could also be applied to the whole string) 75 | map.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); 76 | 77 | map.put(TextAttribute.WEIGHT, text.isBold() ? 78 | TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR); 79 | map.put(TextAttribute.POSTURE, text.isItalic() ? 80 | TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR); 81 | map.put(TextAttribute.UNDERLINE, text.isUnderline() ? 82 | TextAttribute.UNDERLINE_ON : Integer.valueOf(-1)); 83 | 84 | map.put(TextAttribute.FOREGROUND, text.getTextColor()); 85 | 86 | float fontSizeInch = text.getFontSize() / 72.0f; 87 | 88 | map.put(TextAttribute.SIZE, fontSizeInch * context.getTargetDpi()); 89 | Font fontOriginal = font; 90 | font = font.deriveFont(map); 91 | if (map.get(TextAttribute.WEIGHT) == TextAttribute.WEIGHT_BOLD && font.getFontName().equals(fontOriginal.getFontName())) { 92 | AffineTransform afT = new AffineTransform(); 93 | afT.setToScale(context.getSX(), 1); 94 | font = font.deriveFont(afT); 95 | } 96 | map.put(TextAttribute.FONT, font); 97 | 98 | if (text.getText().length() > 0) { 99 | string.addAttributes(map, start, start + text.getText().length()); 100 | } 101 | start += text.getText().length(); 102 | } 103 | 104 | return string.getIterator(); 105 | } 106 | 107 | public boolean isEmpty() { 108 | if (texts.isEmpty()) 109 | return true; 110 | 111 | for (FormattedText t : texts) { 112 | if (t.getText().length() > 0) 113 | return false; 114 | } 115 | 116 | return true; 117 | } 118 | 119 | public float getMarginTop() { 120 | if (texts.isEmpty()) 121 | return 0; 122 | for (FormattedText t : texts) { 123 | if (t.getMargintop() > 0) 124 | return t.getMargintop(); 125 | else 126 | return 0; 127 | } 128 | return 0; 129 | } 130 | 131 | public float getMarginBottom() { 132 | if (texts.isEmpty()) 133 | return 0; 134 | for (FormattedText t : texts) { 135 | if (t.getMarginbottom() > 0) 136 | return t.getMarginbottom(); 137 | else 138 | return 0; 139 | } 140 | return 0; 141 | } 142 | 143 | 144 | public int getEmptyHeight(Graphics2D graphics, PageRenderContext context) { 145 | if (texts.isEmpty()) 146 | return 0; 147 | 148 | FormattedText ft = texts.get(0); 149 | float fontSizeInch = ft.getFontSize() / 72.0f; 150 | Font font = createFont(ft, context).deriveFont(fontSizeInch * context.getTargetDpi()); 151 | 152 | FontMetrics fm = graphics.getFontMetrics(font); 153 | return fm.getHeight(); 154 | } 155 | 156 | // return bottom / top 157 | //public 158 | 159 | private Font createFont(FormattedText text, PageRenderContext context) { 160 | Font font = null; 161 | for (Font f : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) { 162 | if (f.getFamily().equals(text.getFontFamily())) { 163 | // we just assume that first match to family is best match 164 | font = f; 165 | break; 166 | } 167 | } 168 | 169 | if (font == null) { 170 | font = context.getFont(text.getFontFamily()); 171 | if (font == null) 172 | return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()[0]; 173 | } 174 | 175 | return font; 176 | } 177 | 178 | 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfelements/impl/McfAreaImpl.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfelements.impl; 5 | 6 | import java.awt.Color; 7 | 8 | import net.sf.mcf2pdf.mcfelements.*; 9 | 10 | 11 | public class McfAreaImpl implements McfArea { 12 | 13 | private McfPage page; 14 | 15 | private float left; 16 | 17 | private float top; 18 | 19 | private float width; 20 | 21 | private float height; 22 | 23 | private float rotation; 24 | 25 | private int zPosition; 26 | 27 | private String areaType; 28 | 29 | private boolean borderEnabled; 30 | 31 | private float borderSize; 32 | 33 | private Color borderColor; 34 | 35 | private boolean shadowEnabled; 36 | 37 | private int shadowAngle; 38 | 39 | private int shadowIntensity; 40 | 41 | private float shadowDistance; 42 | 43 | private Color backgroundColor; 44 | 45 | private McfAreaContent content; 46 | 47 | private McfPosition position; 48 | 49 | private McfBorder border; 50 | 51 | public void setzPosition(int zPosition) { 52 | this.zPosition = zPosition; 53 | } 54 | 55 | public void setCorner(McfCorners corner) { 56 | this.corner = corner; 57 | } 58 | 59 | private McfCorners corner; 60 | 61 | @Override 62 | public McfPage getPage() { 63 | return page; 64 | } 65 | 66 | public void setPage(McfPage page) { 67 | this.page = page; 68 | } 69 | 70 | @Override 71 | public float getLeft() { 72 | // Version 4.x 73 | if (this.position != null) { 74 | return this.position.getLeft(); 75 | } 76 | return left; 77 | } 78 | 79 | public void setLeft(float left) { 80 | this.left = left; 81 | } 82 | 83 | @Override 84 | public float getTop() { 85 | // Version 4.x 86 | if (this.position != null) { 87 | return this.position.getTop(); 88 | } 89 | return top; 90 | } 91 | 92 | public void setTop(float top) { 93 | this.top = top; 94 | } 95 | 96 | @Override 97 | public float getWidth() { 98 | // Version 4.x 99 | if (this.position != null) { 100 | return this.position.getWidth(); 101 | } 102 | return width; 103 | } 104 | 105 | public void setWidth(float width) { 106 | this.width = width; 107 | } 108 | 109 | @Override 110 | public float getHeight() { 111 | // Version 4.x 112 | if (this.position != null) { 113 | return this.position.getHeight(); 114 | } 115 | return height; 116 | } 117 | 118 | public void setHeight(float height) { 119 | this.height = height; 120 | } 121 | 122 | @Override 123 | public float getRotation() { 124 | // Version 4.x 125 | if (this.position != null) { 126 | return this.position.getRotation(); 127 | } 128 | return rotation; 129 | } 130 | 131 | public void setRotation(float rotation) { 132 | this.rotation = rotation; 133 | } 134 | 135 | @Override 136 | public int getZPosition() { 137 | // Version 4.x 138 | if (this.position != null) { 139 | return this.position.getZPosition(); 140 | } 141 | return zPosition; 142 | } 143 | 144 | public void setZposition(int zPosition) { 145 | this.zPosition = zPosition; 146 | } 147 | 148 | @Override 149 | public String getAreaType() { 150 | return areaType; 151 | } 152 | 153 | public void setAreaType(String areaType) { 154 | this.areaType = areaType; 155 | } 156 | 157 | @Override 158 | public boolean isBorderEnabled() { 159 | return borderEnabled; 160 | } 161 | 162 | public void setBorderEnabled(boolean borderEnabled) { 163 | this.borderEnabled = borderEnabled; 164 | } 165 | 166 | @Override 167 | public float getBorderSize() { 168 | return borderSize; 169 | } 170 | 171 | public void setBorderSize(float borderSize) { 172 | this.borderSize = borderSize; 173 | } 174 | 175 | @Override 176 | public Color getBorderColor() { 177 | return borderColor; 178 | } 179 | 180 | public void setBorderColor(Color borderColor) { 181 | this.borderColor = borderColor; 182 | } 183 | 184 | @Override 185 | public boolean isShadowEnabled() { 186 | return shadowEnabled; 187 | } 188 | 189 | public void setShadowEnabled(boolean shadowEnabled) { 190 | this.shadowEnabled = shadowEnabled; 191 | } 192 | 193 | @Override 194 | public int getShadowAngle() { 195 | return shadowAngle; 196 | } 197 | 198 | public void setShadowAngle(int shadowAngle) { 199 | this.shadowAngle = shadowAngle; 200 | } 201 | 202 | @Override 203 | public int getShadowIntensity() { 204 | return shadowIntensity; 205 | } 206 | 207 | public void setShadowIntensity(int shadowIntensity) { 208 | this.shadowIntensity = shadowIntensity; 209 | } 210 | 211 | @Override 212 | public float getShadowDistance() { 213 | return shadowDistance; 214 | } 215 | 216 | public void setShadowDistance(float shadowDistance) { 217 | this.shadowDistance = shadowDistance; 218 | } 219 | 220 | @Override 221 | public Color getBackgroundColor() { 222 | return backgroundColor; 223 | } 224 | 225 | public void setBackgroundColor(Color backgroundColor) { 226 | this.backgroundColor = backgroundColor; 227 | } 228 | 229 | @Override 230 | public McfAreaContent getContent() { 231 | return content; 232 | } 233 | 234 | public void setContent(McfAreaContent content) { 235 | this.content = content; 236 | } 237 | 238 | public McfBorder getBorder() { 239 | return border; 240 | } 241 | 242 | @Override 243 | public McfCorners getCorners() { 244 | return corner; 245 | } 246 | 247 | public void setBorder(McfBorder border) { 248 | this.border = border; 249 | } 250 | 251 | @Override 252 | public McfPosition getPosition() { 253 | return position; 254 | } 255 | 256 | public void setPosition(McfPosition position) { 257 | this.position = position; 258 | } 259 | 260 | } 261 | -------------------------------------------------------------------------------- /src/test/resources/test02.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 89 | 90 |
    10 |

    11 | 01 SPAN 12 |

    13 |

    14 |

    15 |

    16 | 02 SPAN 17 |

    18 |

    19 | 20 | LINE03 21 | LINE04 22 | 23 |

    24 |

    25 |
    26 |

    27 |

    28 | 03 SPAN 29 |

    30 |

    31 | LINE05 32 | LINE06 33 | LINE07 34 | LINE08 35 |

    36 |

    37 |
    38 |

    39 |

    40 | 04 SPAN 41 |

    42 |

    43 | 05 SPAN 44 |

    45 |

    46 |
    47 |

    48 |

    49 | 06 SPAN 50 |

    51 |

    52 | 07 SPAN 53 |

    54 |

    55 |
    56 |

    57 |

    58 | 08 SPAN 59 |

    60 |

    61 | 09 SPAN 62 |

    63 |

    64 |
    65 |

    66 |

    67 | 10 SPAN 68 |

    69 |

    70 | 11 SPAN 71 |

    72 |

    73 |
    74 |

    75 |

    76 | 12 SPAN 77 |

    78 |

    79 | 13 SPAN 80 | LINE14 81 |

    82 |

    83 | 15 SPAN 84 |

    85 |

    86 |
    87 |

    88 |
    91 | 92 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageBackground.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.*; 7 | import java.awt.image.BufferedImage; 8 | import java.awt.image.WritableRaster; 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.io.Writer; 12 | import java.util.List; 13 | 14 | import net.sf.mcf2pdf.mcfelements.McfBackground; 15 | import net.sf.mcf2pdf.mcfelements.util.ImageUtil; 16 | 17 | 18 | public class PageBackground implements PageDrawable { 19 | 20 | private List leftBg; 21 | 22 | private List rightBg; 23 | 24 | public PageBackground(List leftBg, 25 | List rightBg) { 26 | this.leftBg = leftBg; 27 | this.rightBg = rightBg; 28 | } 29 | 30 | @Override 31 | public boolean isVectorGraphic() { 32 | return false; 33 | } 34 | 35 | @Override 36 | public void renderAsSvgElement(Writer writer, PageRenderContext context) throws IOException { 37 | throw new UnsupportedOperationException(); 38 | } 39 | 40 | @Override 41 | public BufferedImage renderAsBitmap(PageRenderContext context, 42 | Point drawOffsetPixels, int widthPX, int heightPX) throws IOException { 43 | File fLeft = extractBackground(leftBg, context); 44 | File fRight = extractBackground(rightBg, context); 45 | 46 | BufferedImage img = new BufferedImage(widthPX, heightPX, BufferedImage.TYPE_INT_ARGB); 47 | Graphics2D g2d = img.createGraphics(); 48 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 49 | g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 50 | 51 | if (fLeft != null && fLeft.equals(fRight)) { 52 | // draw the background image on whole page 53 | int hue = extractHueFromBackGround(leftBg); 54 | drawBackground(fLeft, g2d, 0, 0, img.getWidth(), img.getHeight(),hue); 55 | } 56 | else { 57 | // process background parts separate 58 | if (fLeft != null) { 59 | int hueleft = extractHueFromBackGround(leftBg); 60 | drawBackground(fLeft, g2d, 0, 0, img.getWidth() / 2, img.getHeight(), hueleft); 61 | } 62 | if (fRight != null) { 63 | int hueright = extractHueFromBackGround(rightBg); 64 | drawBackground(fRight, g2d, img.getWidth() / 2, 0, img.getWidth() / 2, img.getHeight(), hueright); 65 | } 66 | } 67 | 68 | g2d.dispose(); 69 | return img; 70 | } 71 | 72 | private void drawBackground(File f, Graphics2D g2d, int x, int y, int width, int height, int hue) throws IOException { 73 | BufferedImage img = ImageUtil.readImage(f); 74 | if (img == null) { 75 | throw new IOException("Could not read image file: " + f.getAbsolutePath()); 76 | } 77 | /// aply hue 270 78 | BufferedImage applied=null; 79 | if(f.getName().equalsIgnoreCase("6898.webp")) { 80 | applied=applyHue(img, hue/360.0f); 81 | } else 82 | applied = img; 83 | float tgtRatio = width / (float)height; 84 | 85 | float imgRatio = img.getWidth() / (float)img.getHeight(); 86 | float scale; 87 | boolean xVar; 88 | 89 | if (imgRatio > tgtRatio) { 90 | // scale image Y to target Y 91 | scale = height / (float)img.getHeight(); 92 | xVar = true; 93 | } 94 | else { 95 | // scale image X to target X 96 | scale = width / (float)img.getWidth(); 97 | xVar = false; 98 | } 99 | 100 | int sx = (int)(xVar ? ((img.getWidth() - (width / scale)) / 2) : 0); 101 | int sy = (int)(xVar ? 0 : ((img.getHeight() - (height / scale)) / 2)); 102 | 103 | int sw = (int)(width / scale); 104 | int sh = (int)(height / scale); 105 | 106 | g2d.drawImage(applied, x, y, x + width, y + height, sx, sy, sx + sw, sy + sh, null); 107 | } 108 | 109 | private BufferedImage applyHue(BufferedImage image, float hue) { 110 | int width = image.getWidth(); 111 | int height = image.getHeight(); 112 | WritableRaster raster = image.getRaster(); 113 | BufferedImage res = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 114 | WritableRaster resRast = res.getRaster(); 115 | 116 | for (int xx = 0; xx < width; xx++) { 117 | for (int yy = 0; yy < height; yy++) { 118 | //Color color = new Color(Color.HSBtoRGB(hue, 0.7f, 0.7f)); 119 | int RGB=image.getRGB(xx,yy); 120 | //int[] pixels = raster.getPixel(xx, yy, (int[]) null); 121 | int R = (RGB >> 16) & 0xff; 122 | int G = (RGB >> 8) & 0xff; 123 | int B = (RGB) & 0xff; 124 | float HSV[]=new float[3]; 125 | Color.RGBtoHSB(R,G,B,HSV); 126 | //pixels[0] = color.getRed(); 127 | //pixels[1] = color.getGreen(); 128 | //pixels[2] = color.getBlue(); 129 | //float newhue = (hue)%1.0f; 130 | //float newsat = HSV[1]; 131 | float newsat = (float) Math.sqrt(HSV[1]*100)/100; 132 | res.setRGB(xx,yy,Color.getHSBColor(hue,newsat,HSV[2]).getRGB()); 133 | //resRast.setPixel(xx, yy, pixels); 134 | } 135 | } 136 | return res; 137 | } 138 | 139 | private File extractBackground(List bgs, 140 | PageRenderContext context) throws IOException { 141 | for (McfBackground bg : bgs) { 142 | String tn = bg.getTemplateName(); 143 | String designElementId = bg.getDesignElementId(); 144 | if (designElementId != null) { 145 | tn = designElementId; 146 | } else { 147 | if (tn == null || !tn.matches("[a-zA-Z0-9_]+,normal(,.*)?")) 148 | continue; 149 | if(designElementId == null) 150 | tn = tn.substring(0, tn.indexOf(",")); 151 | } 152 | File f = context.getBackgroundImage(tn); 153 | if (f == null) { 154 | f = context.getBackgroundColor(tn); 155 | } 156 | if (f == null) 157 | context.getLog().warn("Background not found for page " + bg.getPage().getPageNr() + ": " + tn); 158 | else 159 | return f; 160 | } 161 | 162 | return null; 163 | } 164 | 165 | private int extractHueFromBackGround(List bgs) { 166 | int hue=0; 167 | for (McfBackground bg : bgs) { 168 | if(bg.getHue()>0) { 169 | hue=bg.getHue(); 170 | }; 171 | } 172 | 173 | return hue; 174 | } 175 | 176 | @Override 177 | public int getZPosition() { 178 | return 0; 179 | } 180 | 181 | @Override 182 | public float getLeftMM() { 183 | return 0; 184 | } 185 | 186 | @Override 187 | public float getTopMM() { 188 | return 0; 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /src/test/resources/LongSpanAndParagraph.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

    8 | firstSpan 9 |

    10 |

    11 |
    12 |

    13 |

    14 | asdasd asdasda asd asda asd asd asd, 15 |

    16 |

    17 | asdasd asdasdasd asdasd 18 |

    19 |

    20 | asdasda asda sdasd asd asda sda sdasd. 21 |

    22 |

    23 | asdasd asdasdasda dsa 24 | 25 |

    26 |

    27 | asdadsasdasdasdasdasd. asdasdadsasd asd asd asda ds 28 |

    29 |

    30 | asdasdasd asd asd. asdasdasda sda sasd asd 31 |

    32 |

    33 | asdasd a s. asdasdasdasdasdasdasdasdasdadsasdadadasdas dasdadsadasasasdasasaaaae 34 |

    35 |

    36 | asdasdasd asd asd asd asd asd asd asd asd asd asd. 37 |

    38 |

    39 | asdasdasdasdasdasdasdadasdasdasda asda sd asd asd asd asda sads as a asd adadsad 40 |

    41 |

    42 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 43 |

    44 |

    45 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 46 |

    47 |

    48 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 49 |

    50 |

    51 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 52 |

    53 |

    54 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a . 55 |

    56 |

    57 | asasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 58 |

    59 |

    60 | asasdasdasda ad asd as asd aasd ads asd asad 61 |

    62 |

    63 | asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a. asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aa. aasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aas asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a 64 |

    65 |

    66 | asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a. aa ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aa. aasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aas asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a . 67 |

    68 |

    69 | asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a.. 70 |

    71 |

    72 | asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a., asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aasdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a.. 73 |

    74 |

    75 | asdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as a.j. sdasdasda ad asd as asd aasd ads asd asad sas a aa sas asdasdasd aa ad a sdas as aasdasdasda 76 |

    77 |

    78 | lastSpan 79 |

    80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mcf2pdf Converter for Mein CEWE Fotobuch (My CEWE Photobook) files to PDF 2 | 3 | Latest Release: Version **0.7.4** 4 | 5 | 6 | Initial Author: Florian Albrecht 7 | Current developer : rbodziony 8 | 9 | Downloads can be found [here](https://github.com/rbodziony/mcf2pdf/releases). Please read the **installation instructions** below carefully, **otherwise the software will definitely not work for you.** You have been warned. 10 | 11 | ## What is mcf2pdf? What not? 12 | 13 | This program enables you to convert photobooks created with the Mein CEWE 14 | Fotobuch or My CEWE Photobook software (in short, MCF software) to PDF files. 15 | These files then can be used to have a quick and rough impression on how the 16 | photobook is going to look after printing. 17 | 18 | **Calendars and anything else than BOOKS are NOT (yet) supported by this software!** 19 | **(Do not ask me WHEN they will be supported - you will be ignored)** 20 | 21 | The generated PDFs are NOT, and will never be, a 100% representation of the 22 | designed photobook. Also, they do NOT include bleed margins (especially not for 23 | the cover pages) and such things, and they use the RGB color model, not the CMYK 24 | model used for professional printings. Therefore, you should not use the 25 | generated PDFs for any "real" print jobs - you will be really disappointed about 26 | the results. 27 | 28 | I just developed this program for personal use. So, there will be many features 29 | of MCF files not yet supported by this software. This can result in empty or 30 | strange looking PDFs, or even in program crashes. Notice that this program is 31 | in BETA stage and is not guaranteed to work for ANY of your MCF files. However, 32 | if you notice any strange output, feel free to issue a ticket in the GitHub 33 | bugtracker. If possible, include a screenshot of the MCF software which shows how 34 | the page should look, and then a screenshot of the PDF how it looks after 35 | conversion. Also, including the whole .mcf file would help (don't panic, the .mcf 36 | files do not include any pictures by theirselves, but TEXT inserted into the 37 | photobook can be seen in the .mcf file). 38 | 39 | If you are interested in extending the software, feel free to fork the project 40 | and start developing! Most important classes are commented. If you create Pull 41 | Requests in the main project, I can review them and include them in the software. 42 | 43 | ## Installation and configuration 44 | 45 | Installation is quite easy. Just download and extract the archive 46 | (mcf2pdf-x.y.z-bin-windows.zip or mcf2pdf-x.y.z-bin-linux.tar.gz). 47 | 48 | To run mcf2pdf, you will have to **adjust the startup script by hand**, as the 49 | program cannot yet automatically determine where the MCF software is installed. 50 | 51 | Some notes about the structure of the MCF software first: The installation 52 | locations of the software consist of two components. One component is the 53 | "real" installation directory, like `C:\Program Files\Mein CEWE Fotobuch` under 54 | Windows, or perhaps `/home/myuser/cewe-fotobuch` under Linux. Here the binaries 55 | of the software are located as well as the shipped background images, fonts, 56 | cliparts etc. 57 | The other component is the "temporary" directory of the MCF software which can 58 | be set from within the software. Here everything you download from within the 59 | program (e.g. new background images, cliparts, themes...) will be stored. 60 | 61 | As files from both locations could be used in your photobook (.mcf) files, you 62 | have to "tell" mcf2pdf about both. This is done by editing the startup script 63 | (mcf2pdf.bat under Windows, mcf2pdf under Linux) with any text editor you like 64 | (Windows: right-click the file and select "Edit"). 65 | 66 | Look for the line starting with <SET> MCF_INSTALL_DIR= (SET only in the .bat 67 | version). After the =, insert the complete path to the "real" MCF software 68 | installation location, e.g. "C:\Program Files\Mein CEWE Fotobuch". Notice that 69 | you MUST include the path in double quotes if it contains spaces!! 70 | 71 | Next, look for the line starting with <SET> MCF_TEMP_DIR= (SET only in the 72 | .bat version). The same, insert now the TEMPORARY location of the software. If 73 | unsure, startup the MCF software, open any file, select "Options", "Directories" 74 | (second item in the Options dialog), and copy the temporary directory listed 75 | there. 76 | 77 | When finished, save the startup script. 78 | 79 | ## Converting files 80 | 81 | After correct configuration (see above), conversion of MCF files now is rather 82 | simple. Just open a command line (Windows: Win+R, then enter "cmd"), change to 83 | the directory where you extracted the mcf2pdf program (if you do not know what 84 | this means, google for "cd change directory"), and type "mcf2pdf <my MCF file> 85 | <my new PDF file>". For example: 86 | 87 | mcf2pdf "C:\Documents and Settings\myuser\My Documents\USA 2011.mcf" output.pdf 88 | 89 | Notice the double quotes due to the spaces in the path to the MCF file! 90 | 91 | If this seems to complicated, you can COPY the .mcf file AND the images folder 92 | of it (e.g. "USA 2011.mcf Files") to the directory where mcf2pdf is located, 93 | and then just enter 94 | 95 | mcf2pdf "USA 2011.mcf" output.pdf 96 | 97 | The program will start converting the file and inform you when this is finished. 98 | Notice that the program is NOT optimized for speed in any way... It can take 99 | a long time. 100 | 101 | For advanced settings, enter "mcf2pdf -h". This will give you information on 102 | how to adjust the output DPI setting and much more. 103 | 104 | ## Troubleshooting 105 | 106 | As stated above, mcf2pdf is BETA and does not yet implement very much of the 107 | MCF software features. Please refer to chapter 1 on how to file a "bug". 108 | 109 | If you get any error like "Unrecognized command: java", please make sure that 110 | a Java Runtime (1.6.0 or newer) is installed and the Java Executable is on your 111 | PATH. Ask Google if you do not know what this means. 112 | 113 | If you get an error like "Java Heap Space" or OutOfMemoryException, 114 | there is not enough memory for the page rendering. Adjust the startup 115 | script (see chapter 2) to set higher memory levels for Java. You can find memory 116 | settings in the line containing `MCF2PDF_JAVA_OPTS=...`. 117 | Increase the option `-Xmx4G` e.g. to 8G. 118 | 119 | ## Legal Stuff (Disclaimer) 120 | 121 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 122 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 123 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 124 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 125 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 126 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 127 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 128 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 129 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 130 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 131 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/pagebuild/PageRenderContext.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.pagebuild; 5 | 6 | import java.awt.Font; 7 | import java.io.File; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | import org.apache.commons.logging.Log; 12 | import org.apache.commons.logging.LogFactory; 13 | 14 | import net.sf.mcf2pdf.mcfconfig.Fading; 15 | import net.sf.mcf2pdf.mcfelements.util.ImageUtil; 16 | import net.sf.mcf2pdf.mcfglobals.McfAlbumType; 17 | import net.sf.mcf2pdf.mcfglobals.McfFotoFrame; 18 | import net.sf.mcf2pdf.mcfglobals.McfResourceScanner; 19 | 20 | 21 | /** 22 | * The context for page based rendering. The context offers information about 23 | * the output DPI settings and the album type in use, and provides methods to 24 | * retrieve referenced resources. Also, a log object can be retrieved to log 25 | * rendering related messages. 26 | */ 27 | public final class PageRenderContext { 28 | 29 | private final static Log log = LogFactory.getLog(PageRenderContext.class); 30 | 31 | private double sx; 32 | 33 | private int targetDpi; 34 | 35 | private McfResourceScanner resources; 36 | 37 | private McfAlbumType albumType; 38 | 39 | public PageRenderContext(int targetDpi, double sx, McfResourceScanner resources, 40 | McfAlbumType albumType) { 41 | this.targetDpi = targetDpi; 42 | this.sx = sx; 43 | this.resources = resources; 44 | this.albumType = albumType; 45 | } 46 | 47 | /** 48 | * Returns a log object which can be used to log rendering related messages. 49 | * 50 | * @return A log object which can be used to log rendering related messages. 51 | */ 52 | public Log getLog() { 53 | return log; 54 | } 55 | 56 | /** 57 | * Returns the scaling factor for fonts that don't natively support bold text. 58 | * 59 | * @return the scaling factor for fonts that don't natively support bold text. 60 | */ 61 | public double getSX() { 62 | return sx; 63 | } 64 | 65 | /** 66 | * Returns the target DPI setting. 67 | * 68 | * @return The target DPI setting. 69 | */ 70 | public int getTargetDpi() { 71 | return targetDpi; 72 | } 73 | 74 | /** 75 | * Returns the album type in use for the current MCF file. The album type 76 | * contains information about page sizes etc. 77 | * 78 | * @return The album type in use for the current MCF file. 79 | */ 80 | public McfAlbumType getAlbumType() { 81 | return albumType; 82 | } 83 | 84 | /** 85 | * Returns the image file containing the "binding" image, if any. This is taken 86 | * from the installation directory of the MCF software. 87 | * 88 | * @return The image file containing the "binding" image, if any. 89 | */ 90 | public File getBinding() { 91 | return resources.getBinding(); 92 | } 93 | 94 | private static final Pattern PATTERN_FADING = Pattern.compile("fading_(.+)\\.svg", Pattern.CASE_INSENSITIVE); 95 | private static final Pattern PATTERN_CLIPART = Pattern.compile("clipart_(.+)\\.svg", Pattern.CASE_INSENSITIVE); 96 | private static final Pattern PATTERN_FOTOFRAME = 97 | Pattern.compile("Schmuckrahmen_fading_(.+).mask\\.svg_clipart_(.+).clip\\.svg", Pattern.CASE_INSENSITIVE); 98 | 99 | /** 100 | * Returns the "fading" (mask) file for the given referenced file name 101 | * (should end with .svg). The installation and the temporary directories 102 | * of the MCF software are searched for an according CLP file. 103 | * 104 | * @param fileName SVG file name, something like fading_foo.svg. 105 | * 106 | * @return The CLP file containing the vector mask, or null if not found. 107 | */ 108 | public File getFading(String fileName) { 109 | Matcher m = PATTERN_FADING.matcher(fileName); 110 | if (!m.matches()) 111 | return null; 112 | 113 | return resources.getClip(m.group(1)); 114 | } 115 | 116 | /** 117 | * Returns the clipart file for the given referenced file name (should end with 118 | * .svg). The installation and the temporary directories of the MCF software 119 | * are searched for an according CLP file. 120 | * 121 | * @param fileName SVG file name, something like clipart_foo.svg. 122 | * 123 | * @return The CLP file containing the vector graphic, or null if not found. 124 | */ 125 | public File getClipart(String fileName) { 126 | if (fileName == null ) return null; 127 | Matcher m = PATTERN_CLIPART.matcher(fileName); 128 | if (!m.matches()) 129 | return null; 130 | 131 | return resources.getClip(m.group(1)); 132 | } 133 | 134 | public File getClipartViaDesignElementId(String designElementId) { 135 | if (designElementId == null ) return null; 136 | Fading config = resources.getDecoration(designElementId); 137 | File clipart = null; 138 | if(config != null) { 139 | clipart = resources.getClip(config.getClipart().getFile().split("\\.")[0]); 140 | } 141 | return clipart; 142 | } 143 | 144 | /** 145 | * Returns the background image for the given ID (usually a number). The 146 | * installation and the temporary directories of the MCF software are searched 147 | * for an according JPEG file. 148 | * 149 | * @param id ID of the background image (a number). 150 | * 151 | * @return The JPEG file containing the image, or null if not found. 152 | */ 153 | public File getBackgroundImage(String id) { 154 | return resources.getImage(id); 155 | } 156 | 157 | /** 158 | * Return the background image for given color name eg. 'Schwarz'. 159 | * 160 | * @param name Name of the color 161 | * @return The JPEG file containing the image, or null if not found. 162 | */ 163 | public File getBackgroundColor(String name) { 164 | // FIXME this is a workaround. ID should be derived from 165 | // element. 166 | if ("Weiss".equals(name)) { 167 | name = "Weiß"; 168 | } 169 | return resources.getColorImage(name); 170 | } 171 | 172 | /** 173 | * Converts the given millimeter value to pixels, using the DPI setting of this 174 | * context. 175 | * 176 | * @param mm millimeter value. 177 | * 178 | * @return Pixel value, according to the current DPI settings. 179 | */ 180 | public int toPixel(float mm) { 181 | return Math.round(mm * (targetDpi / ImageUtil.MM_PER_INCH)); 182 | } 183 | 184 | /** 185 | * Returns the font with the given name, if such a font is present in the 186 | * MCF software. The installation and the temporary directories of the MCF 187 | * software are searched for an according TTF file. 188 | * 189 | * @param fontFamily Family name of the font. 190 | * 191 | * @return A loaded Font object, or null if this font is not 192 | * present in the MCF software. 193 | */ 194 | public Font getFont(String fontFamily) { 195 | return resources.getFont(fontFamily); 196 | } 197 | 198 | /** 199 | * Returns fotoframe used for photo, consists of: 200 | *
      201 | *
    • Mask / fading file
    • 202 | *
    • Clipart
    • 203 | *
    • Config file describing transformations for mask, clipart and photo
    • 204 | *
    205 | * 206 | * @param fileName Name of the fotoframe, eg. 207 | * Schmuckrahmen_fading_6220-DECO-CC-mask.svg_clipart_6220-DECO-CC-clip.svg 208 | * @return 209 | */ 210 | public McfFotoFrame getFotoFrame(String fileName) { 211 | Matcher m = PATTERN_FOTOFRAME.matcher(fileName); 212 | if (!m.matches()) { 213 | return null; 214 | } 215 | if (!m.group(1).equals(m.group(2))) { 216 | log.warn("Unsupported fotoframe config: " + fileName); 217 | return null; 218 | } 219 | 220 | String fotoframeName = m.group(1); 221 | Fading config = resources.getDecoration(fotoframeName); 222 | File fading = resources.getClip(fotoframeName + "-mask"); 223 | File clipart = resources.getClip(fotoframeName + "-clip"); 224 | 225 | if (fading == null || clipart == null || config == null) { 226 | log.warn("Could not get required resources for fotoframe: " + fotoframeName); 227 | return null; 228 | } 229 | return new McfFotoFrame(clipart, fading, config); 230 | } 231 | 232 | public McfFotoFrame getFotoFrameViaDesignElementID(String passepartoutDesignElementId) { 233 | 234 | //String fotoframeName = m.group(1); 235 | Fading config = resources.getDecoration(passepartoutDesignElementId); 236 | // fix getting fadding and clippart 237 | File fading = resources.getClip(config.getFile().split("\\.")[0]); 238 | File clipart = null; 239 | if(config.getClipart()!=null) { 240 | clipart = resources.getClip(config.getClipart().getFile().split("\\.")[0]); 241 | } 242 | if (config == null) { 243 | log.warn("Could not get required resources for fotoframe: via passepartoutDesignElementId= " + passepartoutDesignElementId); 244 | return null; 245 | } 246 | return new McfFotoFrame(clipart, fading, config); 247 | } 248 | 249 | 250 | } 251 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/Main.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | 12 | import org.apache.commons.cli.CommandLine; 13 | import org.apache.commons.cli.CommandLineParser; 14 | import org.apache.commons.cli.HelpFormatter; 15 | import org.apache.commons.cli.Option; 16 | import org.apache.commons.cli.OptionBuilder; 17 | import org.apache.commons.cli.Options; 18 | import org.apache.commons.cli.ParseException; 19 | import org.apache.commons.cli.PosixParser; 20 | import org.apache.commons.io.output.ByteArrayOutputStream; 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | import org.apache.log4j.Level; 24 | import org.apache.log4j.Logger; 25 | import org.apache.log4j.PropertyConfigurator; 26 | 27 | import net.sf.mcf2pdf.mcfelements.util.PdfUtil; 28 | 29 | 30 | /** 31 | * Main entry point of the mcf2pdf application. Creates an 32 | * Mcf2FoConverter object with the settings passed on command line, 33 | * and renders the given input file to XSL-FO. If PDF output is requested 34 | * (the default), the XSL-FO is converted to PDF using Apache FOP. The result 35 | * (PDF or XSL-FO) is then written to given output file, which can be STDOUT 36 | * when a dash (-) is passed. 37 | */ 38 | public class Main { 39 | 40 | @SuppressWarnings("static-access") 41 | public static void main(String[] args) { 42 | Options options = new Options(); 43 | 44 | Option o = OptionBuilder.hasArg().isRequired().withDescription("Installation location of My CEWE Photobook. REQUIRED.").create('i'); 45 | options.addOption(o); 46 | options.addOption("h", false, "Prints this help and exits."); 47 | options.addOption("t", true, "Location of MCF temporary files."); 48 | options.addOption("c", true, "Location of MCF (hps dir) additional files."); 49 | options.addOption("w", true, "Location for temporary images generated during conversion."); 50 | options.addOption("r", true, "Sets the resolution to use for page rendering, in DPI. Default is 150."); 51 | options.addOption("n", true, "Sets the page number to render up to. Default renders all pages."); 52 | options.addOption("b", false, "Prevents rendering of binding between double pages."); 53 | options.addOption("p", false, "Enable page numbering"); 54 | options.addOption("s", true, "Set scaling for fonts which don't support bold text nativly. Default is 0.82."); 55 | options.addOption("x", false, "Generates only XSL-FO content instead of PDF content."); 56 | options.addOption("q", false, "Quiet mode - only errors are logged."); 57 | options.addOption("d", false, "Enables debugging logging output."); 58 | 59 | CommandLine cl; 60 | try { 61 | CommandLineParser parser = new PosixParser(); 62 | cl = parser.parse(options, args); 63 | } 64 | catch (ParseException pe) { 65 | printUsage(options, pe); 66 | System.exit(3); 67 | return; 68 | } 69 | 70 | if (cl.hasOption("h")) { 71 | printUsage(options, null); 72 | return; 73 | } 74 | 75 | if (cl.getArgs().length != 2) { 76 | printUsage(options, new ParseException("INFILE and OUTFILE must be specified. Arguments were: " + cl.getArgList())); 77 | System.exit(3); 78 | return; 79 | } 80 | 81 | File installDir = new File(cl.getOptionValue("i")); 82 | if (!installDir.isDirectory()) { 83 | printUsage(options, new ParseException("Specified installation directory does not exist.")); 84 | System.exit(3); 85 | return; 86 | } 87 | File hpsDirPath=null; 88 | if (cl.hasOption("c")) { 89 | hpsDirPath = new File(cl.getOptionValue("c")); 90 | if (!hpsDirPath.isDirectory()) { 91 | printUsage(options, new ParseException("Specified hps directory does not exist.")); 92 | System.exit(3); 93 | return; 94 | } 95 | } 96 | 97 | File tempDir = null; 98 | String sTempDir = cl.getOptionValue("t"); 99 | if (sTempDir == null) { 100 | tempDir = new File(new File(System.getProperty("user.home")), ".mcf"); 101 | if (!tempDir.isDirectory()) { 102 | printUsage(options, new ParseException("MCF temporary location not specified and default location " + tempDir + " does not exist.")); 103 | System.exit(3); 104 | return; 105 | } 106 | } 107 | else { 108 | tempDir = new File(sTempDir); 109 | if (!tempDir.isDirectory()) { 110 | printUsage(options, new ParseException("Specified temporary location does not exist.")); 111 | System.exit(3); 112 | return; 113 | } 114 | } 115 | 116 | File mcfFile = new File(cl.getArgs()[0]); 117 | if (!mcfFile.isFile()) { 118 | printUsage(options, new ParseException("MCF input file does not exist.")); 119 | System.exit(3); 120 | return; 121 | } 122 | mcfFile = mcfFile.getAbsoluteFile(); 123 | 124 | File tempImages = new File(new File(System.getProperty("user.home")), ".mcf2pdf"); 125 | if (cl.hasOption("w")) { 126 | tempImages = new File(cl.getOptionValue("w")); 127 | if (!tempImages.mkdirs() && !tempImages.isDirectory()) { 128 | printUsage(options, new ParseException("Specified working dir does not exist and could not be created.")); 129 | System.exit(3); 130 | return; 131 | } 132 | } 133 | 134 | int dpi = 150; 135 | if (cl.hasOption("r")) { 136 | try { 137 | dpi = Integer.valueOf(cl.getOptionValue("r")).intValue(); 138 | if (dpi < 30 || dpi > 600) 139 | throw new IllegalArgumentException(); 140 | } 141 | catch (Exception e) { 142 | printUsage(options, new ParseException("Parameter for option -r must be an integer between 30 and 600.")); 143 | } 144 | } 145 | 146 | int maxPageNo = -1; 147 | if (cl.hasOption("n")) { 148 | try { 149 | maxPageNo = Integer.valueOf(cl.getOptionValue("n")).intValue(); 150 | if (maxPageNo < 0) 151 | throw new IllegalArgumentException(); 152 | } 153 | catch (Exception e) { 154 | printUsage(options, new ParseException("Parameter for option -n must be an integer >= 0.")); 155 | } 156 | } 157 | 158 | boolean binding = true; 159 | if (cl.hasOption("b")) { 160 | binding = false; 161 | } 162 | 163 | boolean pageNum = false; 164 | if (cl.hasOption("p")) { 165 | pageNum = true; 166 | } 167 | double sx = 0.82d; 168 | if (cl.hasOption("s")) { 169 | try { 170 | sx = Double.valueOf(cl.getOptionValue("s")).doubleValue(); 171 | } catch (Exception e) { 172 | printUsage(options, new ParseException("Parameter for option -s must be a double value.")); 173 | } 174 | } 175 | 176 | OutputStream finalOut; 177 | if (cl.getArgs()[1].equals("-")) 178 | finalOut = System.out; 179 | else { 180 | try { 181 | finalOut = new FileOutputStream(cl.getArgs()[1]); 182 | } 183 | catch (IOException e) { 184 | printUsage(options, new ParseException("Output file could not be created.")); 185 | System.exit(3); 186 | return; 187 | } 188 | } 189 | 190 | // configure logging, if no system property is present 191 | if (System.getProperty("log4j.configuration") == null) { 192 | PropertyConfigurator.configure(Main.class.getClassLoader().getResource("log4j.properties")); 193 | 194 | Logger.getRootLogger().setLevel(Level.INFO); 195 | if (cl.hasOption("q")) 196 | Logger.getRootLogger().setLevel(Level.ERROR); 197 | if (cl.hasOption("d")) 198 | Logger.getRootLogger().setLevel(Level.DEBUG); 199 | } 200 | 201 | // start conversion to XSL-FO 202 | // if -x is specified, this is the only thing we do 203 | OutputStream xslFoOut; 204 | if (cl.hasOption("x")) 205 | xslFoOut = finalOut; 206 | else 207 | xslFoOut = new ByteArrayOutputStream(); 208 | 209 | Log log = LogFactory.getLog(Main.class); 210 | 211 | try { 212 | new Mcf2FoConverter(installDir, tempDir, tempImages,hpsDirPath).convert( 213 | mcfFile, xslFoOut, dpi, binding, pageNum, maxPageNo,sx); 214 | xslFoOut.flush(); 215 | 216 | if (!cl.hasOption("x")) { 217 | // convert to PDF 218 | log.debug("Converting XSL-FO data to PDF"); 219 | byte[] data = ((ByteArrayOutputStream)xslFoOut).toByteArray(); 220 | PdfUtil.convertFO2PDF(new ByteArrayInputStream(data), finalOut, dpi); 221 | finalOut.flush(); 222 | } 223 | } 224 | catch (Exception e) { 225 | log.error("An exception has occured", e); 226 | System.exit(1); 227 | return; 228 | } 229 | finally { 230 | if (finalOut instanceof FileOutputStream) { 231 | try { finalOut.close(); } catch (Exception e) { } 232 | } 233 | } 234 | } 235 | 236 | private static void printUsage(Options options, ParseException pe) { 237 | if (pe != null) 238 | System.err.println("ERROR: " + pe.getMessage()); 239 | System.out.println(); 240 | System.out.println("mcf2pdf My CEWE Photobook to PDF converter"); 241 | HelpFormatter hf = new HelpFormatter(); 242 | hf.printHelp("mcf2pdf INFILE OUTFILE", "Options are:", options, 243 | "If -t is not specified, /.mcf is used.\n" + 244 | "If -w is not specified, /.mcf2pdf is created and used.\n" + 245 | "If you specify a dash (-) as OUTFILE, resulting content will be written to STDOUT. Notice that, in that case, temporary image files will be kept in specified image working directory. Notice also that you should add option -q in this case to avoid logging output."); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | de.florian-albrecht.tools 4 | mcf2pdf 5 | 0.7.4-SNAPSHOT 6 | mcf2pdf 7 | mcf2pdf enables you to convert photobooks generated with the My CEWE Photobook software to PDF files for preview. 8 | 9 | 10 | UTF-8 11 | github 12 | 1.16 13 | 2.9 14 | 15 | 16 | 17 | scm:git:https://github.com/rbodziony/mcf2pdf.git 18 | https://github.com/rbodziony/mcf2pdf.git 19 | scm:git:https://github.com/rbodziony/mcf2pdf.git 20 | HEAD 21 | 22 | 23 | 24 | 25 | rbodziony 26 | +1 27 | 28 | 29 | 30 | 31 | 32 | org.jdom 33 | jdom 34 | 1.1 35 | 36 | 37 | 38 | org.apache.xmlgraphics 39 | fop 40 | ${fop.version} 41 | 42 | 43 | org.apache.xmlgraphics 44 | batik-all 45 | ${batik.version} 46 | 47 | 48 | 49 | org.apache.commons 50 | commons-digester3 51 | 3.1 52 | 53 | 54 | commons-logging 55 | commons-logging 56 | 1.1.1 57 | 58 | 59 | commons-beanutils 60 | commons-beanutils 61 | 1.8.3 62 | 63 | 64 | commons-cli 65 | commons-cli 66 | 1.2 67 | 68 | 69 | log4j 70 | log4j 71 | 1.2.9 72 | true 73 | 74 | 75 | org.apache.pdfbox 76 | jempbox 77 | 1.6.0 78 | 79 | 80 | 81 | com.drewnoakes 82 | metadata-extractor 83 | 2.18.0 84 | 85 | 86 | ar.com.hjg 87 | pngj 88 | 2.1.0 89 | 90 | 91 | 92 | net.java.dev.jna 93 | jna 94 | 4.1.0 95 | 96 | 97 | net.java.dev.jna 98 | jna-platform 99 | 4.1.0 100 | 101 | 102 | 103 | junit 104 | junit 105 | 4.11 106 | test 107 | 108 | 109 | 110 | 111 | com.twelvemonkeys.imageio 112 | imageio-batik 113 | 3.9.4 114 | 115 | 116 | com.twelvemonkeys.imageio 117 | imageio-core 118 | 3.9.4 119 | 120 | 121 | 122 | com.twelvemonkeys.imageio 123 | imageio-tiff 124 | 3.9.4 125 | 126 | 127 | 128 | org.jsoup 129 | jsoup 130 | 1.10.2 131 | 132 | 133 | 134 | 135 | 136 | 137 | src/main/assembly/classpath-filter.win 138 | src/main/assembly/classpath.unix 139 | src/main/assembly/licenseText.properties 140 | 141 | 142 | 143 | 144 | org.apache.maven.plugins 145 | maven-compiler-plugin 146 | 2.3.2 147 | 148 | 1.8 149 | 1.8 150 | 151 | 152 | 153 | 154 | org.apache.maven.plugins 155 | maven-release-plugin 156 | 2.5.3 157 | 158 | 159 | 160 | org.apache.maven.plugins 161 | maven-dependency-plugin 162 | 2.4 163 | 164 | 165 | prepare-classpath-win 166 | 167 | build-classpath 168 | 169 | generate-sources 170 | 171 | ; 172 | \\ 173 | lib 174 | src/main/assembly/classpath.win 175 | true 176 | 177 | 178 | 179 | prepare-classpath-unix 180 | 181 | build-classpath 182 | 183 | generate-sources 184 | 185 | : 186 | / 187 | lib 188 | src/main/assembly/classpath.unix 189 | true 190 | 191 | 192 | 193 | 194 | 195 | 196 | com.google.code.maven-replacer-plugin 197 | maven-replacer-plugin 198 | 1.4.0 199 | 200 | 201 | generate-sources 202 | 203 | replace 204 | 205 | 206 | 207 | 208 | src/main/assembly/classpath.win 209 | 210 | 211 | classpath= 212 | windowsClasspath= 213 | 214 | 215 | src/main/assembly/classpath-filter.win 216 | 217 | 218 | 219 | 220 | 221 | org.apache.maven.plugins 222 | maven-assembly-plugin 223 | 2.2.2 224 | 225 | 226 | package-assembly 227 | 228 | single 229 | 230 | package 231 | 232 | 233 | 234 | 235 | src/main/assembly/tgz.xml 236 | src/main/assembly/zip.xml 237 | src/main/assembly/src.xml 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | org.eclipse.m2e 247 | lifecycle-mapping 248 | 1.0.0 249 | 250 | 251 | 252 | 253 | 254 | 255 | com.google.code.maven-replacer-plugin 256 | 257 | 258 | maven-replacer-plugin 259 | 260 | 261 | [1.4.0,) 262 | 263 | 264 | replace 265 | 266 | 267 | 268 | 269 | false 270 | 271 | 272 | 273 | 274 | 275 | 276 | org.apache.maven.plugins 277 | 278 | 279 | maven-dependency-plugin 280 | 281 | 282 | [2.4,) 283 | 284 | 285 | build-classpath 286 | 287 | 288 | 289 | 290 | false 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /src/main/java/net/sf/mcf2pdf/mcfglobals/McfResourceScanner.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * ${licenseText} 3 | *******************************************************************************/ 4 | package net.sf.mcf2pdf.mcfglobals; 5 | 6 | import java.awt.Font; 7 | import java.awt.FontFormatException; 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.util.ArrayList; 12 | import java.util.Collections; 13 | import java.util.HashMap; 14 | import java.util.LinkedList; 15 | import java.util.List; 16 | import java.util.Locale; 17 | import java.util.Map; 18 | 19 | import org.apache.commons.digester3.Digester; 20 | import org.apache.commons.io.IOUtils; 21 | import org.apache.commons.logging.Log; 22 | import org.apache.commons.logging.LogFactory; 23 | 24 | import net.sf.mcf2pdf.mcfconfig.Decoration; 25 | import net.sf.mcf2pdf.mcfconfig.Fading; 26 | import net.sf.mcf2pdf.mcfconfig.Template; 27 | import net.sf.mcf2pdf.mcfelements.impl.DigesterConfiguratorImpl; 28 | 29 | /** 30 | * "Dirty little helper" which scans installation directory and temporary 31 | * directory of fotobook software for background images, cliparts, fonts, 32 | * and masks (fadings). As there is no (known) usable TOC for these, we just 33 | * take what we find. 34 | */ 35 | public class McfResourceScanner { 36 | 37 | private final static Log log = LogFactory.getLog(McfResourceScanner.class); 38 | 39 | private List scanDirs = new ArrayList(); 40 | 41 | private Map foundImages = new HashMap(); 42 | 43 | private Map foundClips = new HashMap(); 44 | 45 | private Map foundFonts = new HashMap(); 46 | 47 | private Map foundColors = new HashMap(); 48 | 49 | private Map foundDecorations = new HashMap(); 50 | 51 | private Map foundedDesignelementIDs = new HashMap(); 52 | private File foundBinding; 53 | 54 | public McfResourceScanner(List scanDirs) { 55 | this.scanDirs.addAll(scanDirs); 56 | } 57 | 58 | public void scan() throws IOException { 59 | for (File f : scanDirs) { 60 | scanDirectory(f); 61 | } 62 | log.debug("finished scanning "); 63 | } 64 | 65 | private void scanDirectory(File dir) throws IOException { 66 | if (!dir.isDirectory()) 67 | return; 68 | 69 | for (File f : dir.listFiles()) { 70 | log.debug("checking "+f.getAbsolutePath()); 71 | if (f.isDirectory()) 72 | scanDirectory(f); 73 | else { 74 | String nm = f.getName().toLowerCase(Locale.US); 75 | log.debug("nm="+nm); 76 | String path = f.getAbsolutePath(); 77 | log.debug("nm="+nm); 78 | log.debug("path="+path); 79 | if (nm.matches(".+\\.(jp(e?)g|webp|bmp)")) { 80 | String id = nm.substring(0, nm.indexOf(".")); 81 | foundImages.put(id, f); 82 | } 83 | else if (nm.matches(".+\\.(clp|svg)")) { 84 | String id = f.getName().substring(0, nm.lastIndexOf(".")); 85 | foundClips.put(id, f); 86 | } 87 | else if (nm.equals("1_color_backgrounds.xml")) { 88 | log.debug("Processing 1-color backgrounds " + f.getAbsolutePath()); 89 | List