/************************************************************************ * * ColorConverter.java * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Copyright: 2002-2008 by Henrik Just * * All Rights Reserved. * * Version 1.0 (2008-11-23) * */ package writer2latex.latex; import writer2latex.latex.util.BeforeAfter; import writer2latex.latex.util.Context; import writer2latex.office.OfficeReader; import writer2latex.office.StyleWithProperties; import writer2latex.office.XMLString; import writer2latex.util.Misc; /** This class converts color */ public class ColorConverter extends ConverterHelper { private static final int RED = 0; private static final int GREEN = 1; private static final int BLUE = 2; private boolean bUseColor; /** <p>Constructs a new <code>CharStyleConverter</code>.</p> */ public ColorConverter(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette) { super(ofr,config,palette); // We use color if requested in the configuration, however ignoring // all formatting overrides this bUseColor = config.useColor() && config.formatting()>LaTeXConfig.IGNORE_ALL; } public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) { if (bUseColor) { pack.append("\\usepackage{color}").nl(); } } public void setNormalColor(String sColor, LaTeXDocumentPortion ldp) { if (bUseColor && sColor!=null) { ldp.append("\\renewcommand\\normalcolor{\\color") .append(color(sColor)).append("}").nl(); } } public void applyNormalColor(BeforeAfter ba) { if (bUseColor) { ba.add("\\normalcolor",""); } } /** <p>Apply foreground color.</p> * @param style the OOo style to read attributesfrom * @param bDecl true if declaration form is required * @param bInherit true if inherited properties should be used * @param ba the <code>BeforeAfter</code> to add LaTeX code to. * @param context the current context */ public void applyColor(StyleWithProperties style, boolean bDecl, boolean bInherit, BeforeAfter ba, Context context) { // Note: if bDecl is true, nothing will be put in the "after" part of ba. if (bUseColor && style!=null) { String sColor = style.getProperty(XMLString.FO_COLOR,bInherit); if (sColor!=null) { if (!sColor.equals(context.getFontColor())) { // Convert color if it differs from the current font color context.setFontColor(sColor); applyColor(sColor, bDecl, ba, context); } } else { // No color; maybe automatic color? String sAutomatic = style.getProperty(XMLString.STYLE_USE_WINDOW_FONT_COLOR,bInherit); if (sAutomatic==null && bInherit) { // We may need to inherit this property from the default style StyleWithProperties defaultStyle = ofr.getDefaultParStyle(); if (defaultStyle!=null) { sAutomatic = defaultStyle.getProperty(XMLString.STYLE_USE_WINDOW_FONT_COLOR,bInherit); } } if ("true".equals(sAutomatic)) { // Automatic color based on background if (context.getBgColor()!=null) { applyAutomaticColor(ba,bDecl,context); } } } } } /** <p>Apply a specific foreground color.</p> * @param sColor the rgb color to use * @param bDecl true if declaration form is required * @param ba the <code>BeforeAfter</code> to add LaTeX code to. */ public void applyColor(String sColor, boolean bDecl, BeforeAfter ba, Context context) { // Note: if bDecl is true, nothing will be put in the "after" part of ba. if (bUseColor && sColor!=null) { // If there's a background color, allow all colors String s = context.getBgColor()!=null ? fullcolor(sColor) : color(sColor); if (s!=null) { if (bDecl) { ba.add("\\color"+s,""); } else { ba.add("\\textcolor"+s+"{","}"); } } } } public void applyBgColor(String sCommand, String sColor, BeforeAfter ba, Context context) { // Note: Will only fill "before" part of ba if (sColor!=null && !"transparent".equals(sColor)) { String s = fullcolor(sColor); if (bUseColor && s!=null) { context.setBgColor(sColor); ba.add(sCommand+s,""); } } } public void applyAutomaticColor(BeforeAfter ba, boolean bDecl, Context context) { String s = automaticcolor(context.getBgColor()); if (s!=null) { if (bDecl) { ba.add("\\color"+s,""); } else { ba.add("\\textcolor"+s+"{","}"); } } } private static final String automaticcolor(String sBgColor) { if (sBgColor!=null && sBgColor.length()==7) { float[] rgb = getRgb(sBgColor); if (rgb[RED]+rgb[GREEN]+rgb[BLUE]<0.6) { // Dark background return "{white}"; } } return "{black}"; } private static final String color(String sColor){ if ("#000000".equalsIgnoreCase(sColor)) { return "{black}"; } else if ("#ff0000".equalsIgnoreCase(sColor)) { return "{red}"; } else if ("#00ff00".equalsIgnoreCase(sColor)) { return "{green}"; } else if ("#0000ff".equalsIgnoreCase(sColor)) { return "{blue}"; } else if ("#ffff00".equalsIgnoreCase(sColor)) { return "{yellow}"; } else if ("#ff00ff".equalsIgnoreCase(sColor)) { return "{magenta}"; } else if ("#00ffff".equalsIgnoreCase(sColor)) { return "{cyan}"; } //no white, since we don't have background colors: //else if ("#ffffff".equalsIgnoreCase(sColor)) { return "{white}"; } else { if (sColor==null || sColor.length()!=7) return null; float[] rgb = getRgb(sColor); // avoid very bright colors (since we don't have background colors): if (rgb[RED]+rgb[GREEN]+rgb[BLUE]>2.7) { return "{black}"; } else { return "[rgb]{"+rgb[RED]+","+rgb[GREEN]+","+rgb[BLUE]+"}"; } } } private static final String fullcolor(String sColor){ if ("#000000".equalsIgnoreCase(sColor)) { return "{black}"; } else if ("#ff0000".equalsIgnoreCase(sColor)) { return "{red}"; } else if ("#00ff00".equalsIgnoreCase(sColor)) { return "{green}"; } else if ("#0000ff".equalsIgnoreCase(sColor)) { return "{blue}"; } else if ("#ffff00".equalsIgnoreCase(sColor)) { return "{yellow}"; } else if ("#ff00ff".equalsIgnoreCase(sColor)) { return "{magenta}"; } else if ("#00ffff".equalsIgnoreCase(sColor)) { return "{cyan}"; } else if ("#ffffff".equalsIgnoreCase(sColor)) { return "{white}"; } else { // This could mean transparent: if (sColor==null || sColor.length()!=7) return null; float[] rgb = getRgb(sColor); return "[rgb]{"+rgb[RED]+","+rgb[GREEN]+","+rgb[BLUE]+"}"; } } private static final float[] getRgb(String sColor) { float[] rgb = new float[3]; rgb[RED] = (float)Misc.getIntegerFromHex(sColor.substring(1,3),0)/255; rgb[GREEN] = (float)Misc.getIntegerFromHex(sColor.substring(3,5),0)/255; rgb[BLUE] = (float)Misc.getIntegerFromHex(sColor.substring(5,7),0)/255; return rgb; } }