How do I find the list the spot colors (separations) in a PDF document?

Q: I'd like to obtain a piece of code to list the spot colors
(separations) in the pdf document and how to enable/disable them for
the rendering.
---------------
A: Attached is a trimmed down version of ElementReaderAdv sample
project (in C++; C#, JAVA is very similar) that shows how to print out
the colorants for all Separations (Separation color spaces in a PDF
document).

how to enable/disable them for the rendering.

Unfortunately PDFDraw calls does not have direct controls for this at
the moment, so you would need to manually separate content based on
color information (this can be done along the lines of ElementEdit
sample project - http://www.pdftron.com/pdfnet/samplecode.html#ElementEdit)
then render each separation page using PDFDraw (in grayscale mode).

#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <PDF/ElementReader.h>
#include <PDF/Element.h>

#include <iostream>
#include <assert.h>

using namespace std;

using namespace pdftron;
using namespace PDF;
using namespace SDF;
using namespace Common;
using namespace Filters;

void ProcessElements(ElementReader& reader);

void ProcessPath(ElementReader& reader, Element path)
{
  GState gs = path.GetGState();

  // Set Path State 0 (stroke, fill, fill-rule)
-----------------------------------
  if (path.IsStroked())
  {
    //cout << "Stroke path" << endl;

    if (gs.GetStrokeColorSpace().GetType() == ColorSpace::e_pattern)
    {
      // cout << "Path has associated pattern" << endl;
    }
    else
    {
      // Get stroke color (you can use PDFNet color conversion
facilities)
      // ColorPt rgb;
      ColorSpace cs = gs.GetStrokeColorSpace();
      if (cs.GetType() == ColorSpace::e_separation) {
        cout << cs.GetSDFObj().GetAt(1).GetName() << endl;
      }
    }
  }
  else
  {
    // Do not stroke path
  }

  if (path.IsFilled())
  {
    //cout << "Fill path" << endl;

    if (gs.GetFillColorSpace().GetType() == ColorSpace::e_pattern)
    {
      // cout << "Path has associated pattern" << endl;
    }
    else
    {
      ColorSpace cs = gs.GetFillColorSpace();
      if (cs.GetType() == ColorSpace::e_separation) {
        cout << cs.GetSDFObj().GetAt(1).GetName() << endl;
      }
    }
  }
  else
  {
    // Do not fill path
  }
}

void ProcessText(ElementReader& page_reader)
{
  // Begin text element
  //cout << "Begin Text Block:" << endl;

  Element element;
  while ((element = page_reader.Next()) != NULL)
  {
    switch (element.GetType())
    {
    case Element::e_text_end:
      // Finish the text block
      //cout << "End Text Block." << endl;
      return;

    case Element::e_text:
      {
        GState gs = element.GetGState();
        GState::TextRenderingMode tr = gs.GetTextRenderMode();

        bool is_stroked = (tr == GState::e_fill_stroke_text ||
          tr == GState::e_fill_stroke_clip_text ||
          tr == GState::e_fill_stroke_text ||
          tr == GState::e_stroke_text);

        if (is_stroked) {
          if (gs.GetStrokeColorSpace().GetType() == ColorSpace::e_pattern)
{}
          else
          {
            ColorSpace cs = gs.GetStrokeColorSpace();
            if (cs.GetType() == ColorSpace::e_separation) {
              cout << cs.GetSDFObj().GetAt(1).GetName() << endl;
            }
          }
        }

        bool is_filled = (tr == GState::e_fill_clip_text ||
          tr == GState::e_fill_stroke_clip_text ||
          tr == GState::e_fill_stroke_text ||
          tr == GState::e_fill_text);

        if (is_filled) {
          if (gs.GetFillColorSpace().GetType() == ColorSpace::e_pattern) {}
          else
          {
            ColorSpace cs = gs.GetFillColorSpace();
            if (cs.GetType() == ColorSpace::e_separation) {
              cout << cs.GetSDFObj().GetAt(1).GetName() << endl;
            }
          }
        }
      }
      break;
    }
  }
}

void ProcessImage(Element image)
{
  //bool image_mask = image.IsImageMask();
  //bool interpolate = image.IsImageInterpolate();
  //int width = image.GetImageWidth();
  //int height = image.GetImageHeight();

  ColorSpace cs = image.GetImageColorSpace();
  if (cs.GetSDFObj()!=NULL && cs.GetType() == ColorSpace::e_separation)
{
    cout << cs.GetSDFObj().GetAt(1).GetName() << endl;
  }
}

void ProcessElements(ElementReader& reader)
{
  Element element;
  while ((element = reader.Next()) != NULL) // Read page contents
  {
    switch (element.GetType())
    {
    case Element::e_path: // Process path data...
      {
        ProcessPath(reader, element);
      }
      break;
    case Element::e_text_begin: // Process text block...
      {
        ProcessText(reader);
      }
      break;
    case Element::e_form: // Process form XObjects
      {
        reader.FormBegin();
        ProcessElements(reader);
        reader.End();
      }
      break;
    case Element::e_image: // Process Images
      {
        ProcessImage(element);
      }
      break;
    }
  }
}

int main(int argc, char *argv[])
{
  int ret = 0;
  PDFNet::Initialize();

  // Relative path to the folder containing test files.
  string input_path = "../../TestFiles/";
  // string output_path = "../../TestFiles/Output/";

  try // Extract text data from all pages in the document
  {
    PDFDoc doc((input_path + "newsletter.pdf").c_str());
    doc.InitSecurityHandler();

    int pgnum = doc.GetPageCount();
    PageIterator page_begin = doc.GetPageIterator();

    ElementReader page_reader;

    PageIterator itr;
    for (itr = page_begin; itr.HasNext(); itr.Next()) // Read every
page
    {
      cout << "Page " << itr.Current().GetIndex() <<
"----------------------------------------" << endl;
      page_reader.Begin(itr.Current());
      ProcessElements(page_reader);
      page_reader.End();
    }

    cout << "Done." << endl;
  }
  catch(Exception& e)
  {
    cout << e << endl;
    ret = 1;
  }
  catch(...)
  {
    cout << "Unknown Exception" << endl;
    ret = 1;
  }

  PDFNet::Terminate();
  return ret;
}