How do I obtain correct opacity and blendmodes for PDF elements in a form XObject?

Q:

I’m trying to read PDF and was running ito some problems with opacity and blendmodes

gs.GetFillOpacity() returns always “1.0” for me
same for gs.GetStrokeOpacity()
gs.GetBlendMode() returns always “1”

i tried with one of your samples “ElementReaderAdvTest” and get also there only 1.0 for opacity and 1 for blend-modes

i have another pdf-file where i can read the correct opacity, just not in this file (it was created with Adobe Illustrator)

A:

The file you sent contains a transparency group (the form XObject is also a transparency group) that contains both paths. (see section 11.4 in the PDF specification for an in-depth description of transparency groups) Since the transparency is applied to the entire group in this case the transparency you are seeing will not be available when you process the path elements. To handle this case correctly the best approach is to identify and process transparency groups in a different manner. For example this code will identify a transparency group:

bool IsTransparencyGroup(Obj obj, bool& isolated, bool& knockout)

{

Obj grp = obj.FindObj(“Group”);

Obj grp_subtype = grp ? grp.FindObj(“S”) : 0;

if (grp_subtype && grp_subtype.IsName() && strcmp(grp_subtype.GetName(), “Transparency”)==0)

{

if (SDF::Obj is = grp.FindObj(“I”)) {

if (is.IsBool()) isolated = is.GetBool();

}

if (SDF::Obj kn = grp.FindObj(“K”)) {

if (kn.IsBool()) knockout = kn.GetBool();

}

return true;

}

return false;

}

You will then probably want to change the form processing code to check whether the object is a transparency group and process it accordingly. For example:

case Element::e_form: // Process form XObjects

{

bool group,isolated, knockout;

if(group=IsTransparencyGroup(reader.GetXObject(),isolated,knockout))

{

// additional processing for transparency group etc.

// for example if you were to render PDF you would need to

// render the group into a separate buffer and then blend

// it back to the main buffer.

}

reader.FormBegin();

ProcessElements(reader);

reader.End();

}

break;