/**
   * Create string representation of a fop-rgb-icc (or fop-rgb-named-color) function call from the
   * given color.
   *
   * @param color the color to turn into a function call
   * @return the string representing the internal fop-rgb-icc() or fop-rgb-named-color() function
   *     call
   */
  private static String toFunctionCall(ColorWithAlternatives color) {
    ColorSpace cs = color.getColorSpace();
    if (cs.isCS_sRGB() && !color.hasAlternativeColors()) {
      return toRGBFunctionCall(color);
    }
    if (cs instanceof CIELabColorSpace) {
      return toCIELabFunctionCall(color);
    }

    Color specColor = color;
    if (color.hasAlternativeColors()) {
      Color alt = color.getAlternativeColors()[0];
      if (ColorSpaces.isDeviceColorSpace(alt.getColorSpace())) {
        cs = alt.getColorSpace();
        specColor = alt;
      }
    }
    ColorSpaceOrigin origin = ColorSpaces.getColorSpaceOrigin(cs);
    String functionName;

    Color fallbackColor = getsRGBFallback(color);
    float[] rgb = fallbackColor.getColorComponents(null);
    assert rgb.length == 3;
    StringBuffer sb = new StringBuffer(40);
    sb.append("(");
    sb.append(rgb[0]).append(",");
    sb.append(rgb[1]).append(",");
    sb.append(rgb[2]).append(",");
    String profileName = origin.getProfileName();
    sb.append(profileName).append(",");
    if (origin.getProfileURI() != null) {
      sb.append("\"").append(origin.getProfileURI()).append("\"");
    }

    if (cs instanceof NamedColorSpace) {
      NamedColorSpace ncs = (NamedColorSpace) cs;
      if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(profileName)) {
        functionName = "fop-rgb-icc";
      } else {
        functionName = "fop-rgb-named-color";
      }
      sb.append(",").append(ncs.getColorName());
    } else {
      functionName = "fop-rgb-icc";
      float[] colorComponents = specColor.getColorComponents(null);
      for (float colorComponent : colorComponents) {
        sb.append(",");
        sb.append(colorComponent);
      }
    }
    sb.append(")");
    return functionName + sb.toString();
  }
 private static Color getsRGBFallback(ColorWithAlternatives color) {
   Color fallbackColor;
   if (color instanceof ColorWithFallback) {
     fallbackColor = ((ColorWithFallback) color).getFallbackColor();
     if (!fallbackColor.getColorSpace().isCS_sRGB()) {
       fallbackColor = toSRGBColor(fallbackColor);
     }
   } else {
     fallbackColor = toSRGBColor(color);
   }
   return fallbackColor;
 }
 /**
  * Set the non stroking color, specified as RGB.
  *
  * @param color The color to set.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setNonStrokingColor(Color color) throws IOException {
   ColorSpace colorSpace = color.getColorSpace();
   if (colorSpace.getType() == ColorSpace.TYPE_RGB) {
     setNonStrokingColor(color.getRed(), color.getGreen(), color.getBlue());
   } else if (colorSpace.getType() == ColorSpace.TYPE_GRAY) {
     color.getColorComponents(colorComponents);
     setNonStrokingColor(colorComponents[0]);
   } else if (colorSpace.getType() == ColorSpace.TYPE_CMYK) {
     color.getColorComponents(colorComponents);
     setNonStrokingColor(
         colorComponents[0], colorComponents[2], colorComponents[2], colorComponents[3]);
   } else {
     throw new IOException("Error: unknown colorspace:" + colorSpace);
   }
 }
 /**
  * Creates a re-parsable string representation of the given color.
  *
  * <p>First, the color will be converted into the sRGB colorspace. It will then be printed as
  * #rrggbb, or as #rrrggbbaa if an alpha value is present.
  *
  * @param color the color to represent.
  * @return a re-parsable string representadion.
  */
 public static String colorToString(Color color) {
   ColorSpace cs = color.getColorSpace();
   if (color instanceof ColorWithAlternatives) {
     return toFunctionCall((ColorWithAlternatives) color);
   } else if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
     StringBuffer sbuf = new StringBuffer(24);
     float[] cmyk = color.getColorComponents(null);
     sbuf.append("cmyk(")
         .append(cmyk[0])
         .append(",")
         .append(cmyk[1])
         .append(",")
         .append(cmyk[2])
         .append(",")
         .append(cmyk[3])
         .append(")");
     return sbuf.toString();
   } else {
     return toRGBFunctionCall(color);
   }
 }