package tzatziki.pdf.support; import com.google.common.base.Optional; import com.google.common.collect.Maps; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Font; import gutenberg.itext.Colors; import gutenberg.itext.FontCopier; import gutenberg.itext.FontModifier; import gutenberg.itext.HeaderFooter; import gutenberg.itext.ITextContext; import gutenberg.itext.Styles; import gutenberg.itext.support.FirstPageRenderer; import gutenberg.util.KeyValues; import gutenberg.util.Margin; import gutenberg.util.SimpleKeyValues; import gutenberg.util.VariableResolver; import tzatziki.pdf.Settings; import tzatziki.pdf.emitter.DefaultPdfEmitters; import tzatziki.pdf.emitter.FeatureEmitter; import tzatziki.pdf.emitter.ScenarioEmitter; import java.util.Map; import static com.itextpdf.text.Font.*; import static gutenberg.itext.Colors.DARK_RED; import static gutenberg.itext.Styles.CODE_FONT; import static tzatziki.pdf.Settings.EMPHASIZE_COLOR; import static tzatziki.pdf.emitter.StepsEmitter.*; import static tzatziki.pdf.emitter.TagsEmitter.TAG_FONT; /** * @author <a href="http://twitter.com/aloyer">@aloyer</a> */ public class Configuration { public static final Object TITLE = "title"; public static final Object SUB_TITLE = "sub-title"; public static final Object HEADER_TITLE = "header-title"; private KeyValues keyValues = new SimpleKeyValues(); private Map<Object, FontModifier> fontModifiers = Maps.newHashMap(); private Map<Object, BaseColor> colors = Maps.newHashMap(); private Margin documentMargin; private StylesPostProcessor stylesPostProcessor; public Configuration() { displayFeatureUri(true); displayFeatureTags(true); displayScenarioTags(true); } public Configuration stylesPostProcessor(StylesPostProcessor stylesPostProcessor) { this.stylesPostProcessor = stylesPostProcessor; return this; } public Configuration declareProperty(Object key, Object value) { keyValues.declare(key, value); return this; } public Configuration displayFeatureUri(boolean displayFeatureUri) { return declareProperty(FeatureEmitter.DISPLAY_URI, displayFeatureUri); } public Configuration displayFeatureTags(boolean displayFeatureTags) { return declareProperty(FeatureEmitter.DISPLAY_TAGS, displayFeatureTags); } public Configuration displayScenarioTags(boolean displayScenarioTags) { return declareProperty(ScenarioEmitter.DISPLAY_TAGS, displayScenarioTags); } public Configuration adjustFont(Object key, FontModifier modifier) { fontModifiers.put(key, modifier); return this; } public Configuration defineColor(Object key, BaseColor color) { colors.put(key, color); return this; } public Configuration usingDocumentMargin(Margin documentMargin) { this.documentMargin = documentMargin; return this; } public void configureContext(ITextContext iTextContext) { configureEmitters(iTextContext); configureProperties(iTextContext); configureVariableResolver(iTextContext); Styles styles = ensureStylesIsDefined(iTextContext); configureStyles(styles); } protected void configureVariableResolver(ITextContext iTextContext) { VariableResolver variableResolver = iTextContext.variableResolver(); for (Map.Entry<Object, Object> entry : keyValues.asMap().entrySet()) { variableResolver.declare( String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); } } protected Styles ensureStylesIsDefined(ITextContext iTextContext) { KeyValues kvs = iTextContext.keyValues(); Optional<Styles> stylesOpt = kvs.getNullable(Styles.class); if (!stylesOpt.isPresent()) { Styles styles = new Styles(); kvs.declare(Styles.class, styles); return styles; } return stylesOpt.get(); } protected void configureProperties(ITextContext iTextContext) { KeyValues kvs = iTextContext.keyValues(); kvs.delegateTo(this.keyValues); } protected void configureStyles(Styles styles) { configureColors(styles); configureFonts(styles); configureFontModifiers(styles); if (stylesPostProcessor != null) stylesPostProcessor.postProcess(styles); } private void configureFontModifiers(Styles styles) { for (Map.Entry<Object, FontModifier> entry : fontModifiers.entrySet()) { styles.registerFontModifier(entry.getKey(), entry.getValue()); } } private void configureFonts(Styles styles) { Font metaFont = new FontCopier(styles.defaultFont()).style(NORMAL).size(8).color(DARK_RED).get(); styles.registerFont(Settings.META_FONT, metaFont); BaseColor emphasizedColor = styles.getColor(EMPHASIZE_COLOR).or(DARK_RED); BaseColor primaryColor = styles.getColor(Settings.PRIMARY_COLOR).or(DARK_RED); styles.registerFont(STEP_KEYWORD_FONT, styles.getFontOrDefault(CODE_FONT, BOLD, emphasizedColor)); styles.registerFont(STEP_PHRASE_FONT, styles.getFontOrDefault(CODE_FONT, NORMAL, styles.defaultColor())); styles.registerFont(STEP_PARAMETER_FONT, styles.getFontOrDefault(CODE_FONT, NORMAL, emphasizedColor)); styles.registerFont(STEP_DOCSTRING, styles.getFontOrDefault(CODE_FONT, NORMAL, emphasizedColor)); styles.registerFont(STEP_TABLE_CELL, styles.getFontOrDefault(CODE_FONT, NORMAL, styles.defaultColor())); styles.registerFont(STEP_TABLE_CELL_HEADER, styles.getFontOrDefault(CODE_FONT, BOLDITALIC, styles.defaultColor())); styles.registerFont(TAG_FONT, metaFont); styles.registerFont(FirstPageRenderer.FIRST_PAGE_TITLE_FONT, new FontCopier(styles.defaultFont()).style(NORMAL).size(32).color(primaryColor).get()); styles.registerFont(FirstPageRenderer.FIRST_PAGE_SUBJECT_FONT, new FontCopier(styles.defaultFont()).style(NORMAL).size(18).color(emphasizedColor).get()); styles.registerFont(HeaderFooter.HEADER_FONT, new FontCopier(styles.defaultFont()).noBold().size(10f).get()); styles.registerFont(HeaderFooter.FOOTER_FONT, new FontCopier(styles.defaultFont()).noBold().size(10f).get()); } private void configureColors(Styles styles) { styles.registerColor(Settings.PRIMARY_COLOR, DARK_RED); styles.registerColor(EMPHASIZE_COLOR, Colors.GRAY); styles.registerColor(HeaderFooter.HEADER_LINE_COLOR, DARK_RED); for (Map.Entry<Object, BaseColor> entry : colors.entrySet()) { styles.registerColor(entry.getKey(), entry.getValue()); } } protected void configureEmitters(ITextContext iTextContext) { new DefaultPdfEmitters().registerDefaults(iTextContext); } public Margin getDocumentMargin() { return documentMargin; } }