/** * Parse a color specified using the fop-rgb-named-color() function. * * @param value the function call * @return a color if possible * @throws PropertyException if the format is wrong. */ private static Color parseAsFopRgbNamedColor(FOUserAgent foUserAgent, String value) throws PropertyException { Color parsedColor; int poss = value.indexOf("("); int pose = value.indexOf(")"); if (poss != -1 && pose != -1) { String[] args = value.substring(poss + 1, pose).split(","); try { if (args.length != 6) { throw new PropertyException("rgb-named-color() function must have 6 arguments"); } // Set up fallback sRGB value Color sRGB = parseFallback(args, value); /* Get and verify ICC profile name */ String iccProfileName = args[3].trim(); if (iccProfileName == null || "".equals(iccProfileName)) { throw new PropertyException("ICC profile name missing"); } ICC_ColorSpace colorSpace = null; String iccProfileSrc; if (isPseudoProfile(iccProfileName)) { throw new IllegalArgumentException( "Pseudo-profiles are not allowed with fop-rgb-named-color()"); } else { /* Get and verify ICC profile source */ iccProfileSrc = args[4].trim(); if (iccProfileSrc == null || "".equals(iccProfileSrc)) { throw new PropertyException("ICC profile source missing"); } iccProfileSrc = unescapeString(iccProfileSrc); } // color name String colorName = unescapeString(args[5].trim()); /* Ask FOP factory to get ColorSpace for the specified ICC profile source */ if (foUserAgent != null && iccProfileSrc != null) { RenderingIntent renderingIntent = RenderingIntent.AUTO; // TODO connect to fo:color-profile/@rendering-intent colorSpace = (ICC_ColorSpace) foUserAgent .getColorSpaceCache() .get(iccProfileName, iccProfileSrc, renderingIntent); } if (colorSpace != null) { ICC_Profile profile = colorSpace.getProfile(); if (NamedColorProfileParser.isNamedColorProfile(profile)) { NamedColorProfileParser parser = new NamedColorProfileParser(); NamedColorProfile ncp = parser.parseProfile(profile, iccProfileName, iccProfileSrc); NamedColorSpace ncs = ncp.getNamedColor(colorName); if (ncs != null) { parsedColor = new ColorWithFallback(ncs, new float[] {1.0f}, 1.0f, null, sRGB); } else { log.warn( "Color '" + colorName + "' does not exist in named color profile: " + iccProfileSrc); parsedColor = sRGB; } } else { log.warn("ICC profile is no named color profile: " + iccProfileSrc); parsedColor = sRGB; } } else { // ICC profile could not be loaded - use rgb replacement values */ log.warn( "Color profile '" + iccProfileSrc + "' not found. Using sRGB replacement values."); parsedColor = sRGB; } } catch (IOException ioe) { // wrap in a PropertyException throw new PropertyException(ioe); } catch (RuntimeException re) { throw new PropertyException(re); // wrap in a PropertyException } } else { throw new PropertyException( "Unknown color format: " + value + ". Must be fop-rgb-named-color(r,g,b,NCNAME,src,color-name)"); } return parsedColor; }
/** * Parse a color specified using the fop-rgb-icc() function. * * @param value the function call * @return a color if possible * @throws PropertyException if the format is wrong. */ private static Color parseAsFopRgbIcc(FOUserAgent foUserAgent, String value) throws PropertyException { Color parsedColor; int poss = value.indexOf("("); int pose = value.indexOf(")"); if (poss != -1 && pose != -1) { String[] args = value.substring(poss + 1, pose).split(","); try { if (args.length < 5) { throw new PropertyException("Too few arguments for rgb-icc() function"); } // Set up fallback sRGB value Color sRGB = parseFallback(args, value); /* Get and verify ICC profile name */ String iccProfileName = args[3].trim(); if (iccProfileName == null || "".equals(iccProfileName)) { throw new PropertyException("ICC profile name missing"); } ColorSpace colorSpace = null; String iccProfileSrc = null; if (isPseudoProfile(iccProfileName)) { if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { colorSpace = ColorSpaces.getDeviceCMYKColorSpace(); } else if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { colorSpace = new NamedColorSpace(args[5], sRGB, SEPARATION_PSEUDO_PROFILE, null); } else { assert false : "Incomplete implementation"; } } else { /* Get and verify ICC profile source */ iccProfileSrc = args[4].trim(); if (iccProfileSrc == null || "".equals(iccProfileSrc)) { throw new PropertyException("ICC profile source missing"); } iccProfileSrc = unescapeString(iccProfileSrc); } /* ICC profile arguments */ int componentStart = 4; if (colorSpace instanceof NamedColorSpace) { componentStart++; } float[] iccComponents = new float[args.length - componentStart - 1]; for (int ix = componentStart; ++ix < args.length; ) { iccComponents[ix - componentStart - 1] = Float.parseFloat(args[ix].trim()); } if (colorSpace instanceof NamedColorSpace && iccComponents.length == 0) { iccComponents = new float[] {1.0f}; // full tint if not specified } /* Ask FOP factory to get ColorSpace for the specified ICC profile source */ if (foUserAgent != null && iccProfileSrc != null) { RenderingIntent renderingIntent = RenderingIntent.AUTO; // TODO connect to fo:color-profile/@rendering-intent colorSpace = foUserAgent.getColorSpaceCache().get(iccProfileName, iccProfileSrc, renderingIntent); } if (colorSpace != null) { // ColorSpace is available if (ColorSpaces.isDeviceColorSpace(colorSpace)) { // Device-specific colors are handled differently: // sRGB is the primary color with the CMYK as the alternative Color deviceColor = new Color(colorSpace, iccComponents, 1.0f); float[] rgbComps = sRGB.getRGBColorComponents(null); parsedColor = new ColorWithAlternatives( rgbComps[0], rgbComps[1], rgbComps[2], new Color[] {deviceColor}); } else { parsedColor = new ColorWithFallback(colorSpace, iccComponents, 1.0f, null, sRGB); } } else { // ICC profile could not be loaded - use rgb replacement values */ log.warn( "Color profile '" + iccProfileSrc + "' not found. Using sRGB replacement values."); parsedColor = sRGB; } } catch (RuntimeException re) { throw new PropertyException(re); } } else { throw new PropertyException( "Unknown color format: " + value + ". Must be fop-rgb-icc(r,g,b,NCNAME,src,....)"); } return parsedColor; }