How can I modify text color under a given rectangle?

Q:

I would like to edit PDF page by chanding text color under a given
rectangle (in our case we would like to change text color under an
annotation object).

Unlike the article 'How to search and highlight text using PDFNet?' in
this Knowledge Base I would like to modify page content and not create
highlight annotations or similar.

Now, how can I change the color for text covered with link
annotation?
----
A:

You would need to edit the page content by changing the text color on
all text elements covered with link annotation. As a starting point
you may want to take a look at ElementEdit sample project (http://
www.pdftron.com/net/samplecode.html#ElementEdit). In this sample, the
text color is changed from black to blue (for all text on the page).

The code can be extended to modify text color only if the bounding box
of a text run (element.GetBox()) occurs within the area covered by the
link annotation (annot.GetRect()).

Things are a bit more complicated if you need to change color only on
parts of a word/text string. In this case you would need to break the
text run into one or more text runs (using ElementBuilder) and then
write new elements instead of the old element. You would need to
'break' a single text element into two or more runs with different
properties (e.g. fill color) depending on whether they lie under the
annotation rectangle. The last article in the Knowledge Base (http://
groups.google.com/group/pdfnet-sdk/topics) details couple of
approaches that can be used to determine a bounding box for each
character in a text element. If a text run partially intersects
annotation bbox, this information could be used to determine which
characters should be marked (i.e. colored) as being in the highlight
region.

The following is a sample implementation showing how to change the
text color under a given rectangle:

using System;
using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

namespace ElementEditTestCS
{
/// <summary>
/// The sample code shows how to edit the page display list and how
to modify graphics state
/// attributes on existing Elements. In particular the sample program
changes text color to
/// under a given annotation rectangle.
/// </summary>
class ElementEditTest
{
  [STAThread]
  static void Main(string[] args)
  {
   PDFNet.Initialize();
   PDFNet.SetResourcesPath("../../../../../resources");

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

   try
   {

Console.WriteLine("-------------------------------------------------");

    // Open the test file
    Console.WriteLine("Opening the input file...");
    PDFDoc doc = new PDFDoc(input_path + "newsletter.pdf");
    doc.InitSecurityHandler();

    Page page = doc.PageBegin().Current();

    Element element = null;
    ElementReader reader = new ElementReader();
    ElementWriter writer = new ElementWriter();
    ElementBuilder _eb = new ElementBuilder();

    reader.Begin(page);
    Page new_page = doc.PageCreate(new Rect(0, 0, page.GetPageWidth(),
page.GetPageHeight()));
    doc.PageInsert(doc.PageBegin().Next(), new_page);
    writer.Begin(new_page);

    // The color of modified text - green.
    ColorPt textColor = new ColorPt(0, 1, 0);

    // For test purposes change color under the first annotation on
the page.
    int num_annots = page.GetNumAnnots();
    for (int a = 0; a < num_annots; a++)
    {
     Annot anot = page.GetAnnot(a);
     new_page.AnnotPushBack(anot);
    }

    Rect sel_rect;
    if (num_annots > 0) sel_rect = new_page.GetAnnot(0).GetRect();
    else sel_rect = new Rect(100, 400, 300, 500); // if there are no
annotations use an explicit selection rectangle.

    Rect bbox = new Rect();
    while ((element = reader.Next()) != null)
    {
     if (element.GetType() == Element.Type.e_text)
     {
      ColorPt cpt = element.GetGState().GetFillColor();
      element.GetBBox(bbox);

      if (bbox.x2 <= sel_rect.x1 || bbox.x1 >= sel_rect.x2 || bbox.y1

= sel_rect.y2 || bbox.y2 <= sel_rect.y1)

      {
       writer.WriteElement(element);
      }
      else if (bbox.x2 <= sel_rect.x2 && bbox.x1 >= sel_rect.x1 &&
bbox.y1 >= sel_rect.y1 && bbox.y2 <= sel_rect.y2)
      {
       GState gs = element.GetGState();
       gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
       gs.SetFillColor(textColor);
       writer.WriteElement(element);
       gs.SetFillColor(cpt);
      }
      else
      {
       GState gs = element.GetGState();
       pdftron.PDF.Font font = gs.GetFont();
       double font_sz = gs.GetFontSize();
       Rect bbox1 = font.GetBBox();
       double bbox_height = bbox1.y2 - bbox1.y1;
       double decent = font_sz * bbox1.y1 / bbox_height;
       double ascent = font_sz * bbox1.y2 / bbox_height;
       double horiz_scale = gs.GetHorizontalScale() / 100.0;
       Matrix2D tmtx = element.GetTextMatrix();
       Matrix2D mtx = element.GetCTM() * tmtx;
       CharIterator itr = element.CharBegin(), end =
element.CharEnd();

       for (; itr != end; itr.Next())
       {
        Rect gbox = GetGlyphBBox(itr, font, horiz_scale, font_sz,
ascent, decent);
        gbox = GetBBoxTransfRect(gbox, mtx);

        Element new_element = _eb.CreateTextRun(new String((char)
(itr.Current().char_code), 1), font, font_sz);

        if (element.HasTextMatrix() && itr == element.CharBegin())
        {
         new_element.SetTextMatrix(element.GetTextMatrix());
        }

        new_element.SetPosAdjustment(element.GetPosAdjustment());
        GState ngs = new_element.GetGState();
        ngs.SetBlackGenFunct(gs.GetBlackGenFunct());
        ngs.SetBlendMode(gs.GetBlendMode());
        ngs.SetCharSpacing(gs.GetCharSpacing());
        ngs.SetDashPattern(gs.GetDashes(), gs.GetPhase());
        ngs.SetFillColorSpace(gs.GetFillColorSpace());
        ngs.SetFillOpacity(gs.GetFillOpacity());
        ngs.SetFlatness(gs.GetFlatness());
        ngs.SetHalftone(gs.GetHalftone());
        ngs.SetHorizontalScale(gs.GetHorizontalScale());
        ngs.SetLeading(gs.GetLeading());
        ngs.SetLineCap(gs.GetLineCap());
        ngs.SetLineJoin(gs.GetLineJoin());
        ngs.SetLineWidth(gs.GetLineWidth());
        ngs.SetMiterLimit(gs.GetMiterLimit());
        ngs.SetRenderingIntent(gs.GetRenderingIntent());
        ngs.SetSmoothnessTolerance(gs.GetSmoothnessTolerance());
        ngs.SetSoftMask(gs.GetSoftMask());
        ngs.SetStrokeColor(gs.GetStrokeColor());
        ngs.SetStrokeColorSpace(gs.GetStrokeColorSpace());
        ngs.SetStrokeOpacity(gs.GetStrokeOpacity());
        ngs.SetTextKnockout(gs.IsTextKnockout());
        ngs.SetTextRenderMode(gs.GetTextRenderMode());
        ngs.SetTextRise(gs.GetTextRise());
        ngs.SetUCRFunct(gs.GetUCRFunct());
        ngs.SetWordSpacing(gs.GetWordSpacing());

        if (gbox.IntersectRect(gbox, sel_rect))
        {
         ngs.SetFillColor(textColor);
        }
        else
        {
         ngs.SetFillColor(cpt);
        }

        writer.WriteElement(new_element);
        gs.SetFillColor(cpt);
       }
      }
     }
     else
     {
      writer.WriteElement(element);
     }
    }

    writer.End();
    reader.End();
    doc.PageRemove(doc.PageFind(1));

    doc.Save(output_path + "newsletter_edited.pdf",
Doc.SaveOptions.e_remove_unused);
    doc.Close();
    Console.WriteLine("Done. Result saved in
newsletter_edited.pdf...");
   }
   catch (PDFNetException e)
   {
    Console.WriteLine(e.Message);
   }

   PDFNet.Terminate();
  }

  static Rect GetGlyphBBox(CharIterator itr, pdftron.PDF.Font font,
double horiz_scale, double font_sz , double ascent, double descent)
  {
   Rect out_bbox = new Rect();
   out_bbox.x1 = itr.Current().x;
   out_bbox.y1 = itr.Current().y;

   double dx = 0;
   if (font.IsSimple())
   {
    dx = font.GetWidth(itr.Current().char_code) / 1000.0;
    dx *= horiz_scale * font_sz;

    out_bbox.x2 = out_bbox.x1 + dx;
    out_bbox.y1 = itr.Current().y + descent;
    out_bbox.y2 = itr.Current().y + ascent;
   }
   else
   {
    int cid = font.MapToCID(itr.Current().char_code);
    dx = font.GetWidth(cid) / 1000.0;
    dx *= horiz_scale * font_sz;

    out_bbox.x2 = out_bbox.x1 + dx;
    out_bbox.y1 = itr.Current().y + descent;
    out_bbox.y2 = itr.Current().y + ascent;
   }

   return out_bbox;
  }

  static Rect GetBBoxTransfRect(Rect inn, Matrix2D mtx)
  {
   double p1x = inn.x1, p1y = inn.y1, p2x = inn.x2, p2y = inn.y1, p3x
= inn.x2, p3y = inn.y2, p4x = inn.x1, p4y = inn.y2;
   mtx.Mult(ref p1x, ref p1y);
   mtx.Mult(ref p2x, ref p2y);
   mtx.Mult(ref p3x, ref p3y);
   mtx.Mult(ref p4x, ref p4y);

   return new Rect(Math.Min(Math.Min(Math.Min(p1x, p2x), p3x), p4x),
      Math.Min(Math.Min(Math.Min(p1y, p2y), p3y), p4y),
      Math.Max(Math.Max(Math.Max(p1x, p2x), p3x), p4x),
      Math.Max(Math.Max(Math.Max(p1y, p2y), p3y), p4y));
  }
}
}

A:
The following is a bit cleaned up version of the above code that
changes text color under a given rectangle:

using System;
using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

namespace ElementEditTestCS
{
/// <summary>
/// The sample code shows how to edit the page display list and how
to modify graphics state
/// attributes on existing Elements. In particular the sample program
changes text color to
/// under a given annotation rectangle.
/// </summary>
class ElementEditTest
{
  [STAThread]
  static void Main(string[] args)
  {
   PDFNet.Initialize();
   PDFNet.SetResourcesPath("../../../../../resources");

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

   try
   {

Console.WriteLine("-------------------------------------------------");

    // Open the test file
    Console.WriteLine("Opening the input file...");
    PDFDoc doc = new PDFDoc(input_path + "1.pdf");
    doc.InitSecurityHandler();

    Page page = doc.PageBegin().Current();

    Element element = null;
    ElementReader reader = new ElementReader();
    ElementWriter writer = new ElementWriter();
    ElementBuilder _eb = new ElementBuilder();

    reader.Begin(page);
    Page new_page = doc.PageCreate(new Rect(0, 0, page.GetPageWidth(),
page.GetPageHeight()));
    doc.PageInsert(doc.PageBegin().Next(), new_page);
    writer.Begin(new_page);

    // The color of modified text - green.
    ColorPt textColor = new ColorPt(0, 1, 0);

    // For test purposes change color under the first annotation on
the page.
    int num_annots = page.GetNumAnnots();
    for (int a = 0; a < num_annots; a++)
    {
     Annot anot = page.GetAnnot(a);
     new_page.AnnotPushBack(anot);
    }

    Rect sel_rect;
    if (num_annots > 0) sel_rect = new_page.GetAnnot(0).GetRect();
    else sel_rect = new Rect(100, 400, 300, 500); // if there are no
annotations use an explicit selection rectangle.

    Rect bbox = new Rect();
    while ((element = reader.Next()) != null)
    {
     if (element.GetType() == Element.Type.e_text)
     {
      ColorPt cpt = element.GetGState().GetFillColor();
      ColorSpace cs = element.GetGState().GetFillColorSpace();
      element.GetBBox(bbox);

      if (bbox.x2 <= sel_rect.x1 || bbox.x1 >= sel_rect.x2 || bbox.y1

= sel_rect.y2 || bbox.y2 <= sel_rect.y1)

      {
       writer.WriteElement(element);
      }
      else if (bbox.x2 <= sel_rect.x2 && bbox.x1 >= sel_rect.x1 &&
bbox.y1 >= sel_rect.y1 && bbox.y2 <= sel_rect.y2)
      {
       GState gs = element.GetGState();
       gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
       gs.SetFillColor(textColor);
       writer.WriteElement(element);
       gs.SetFillColorSpace(cs);
       gs.SetFillColor(cpt);
      }
      else
      {
       GState gs = element.GetGState();
       pdftron.PDF.Font font = gs.GetFont();
       double font_sz = gs.GetFontSize();
       Rect bbox1 = font.GetBBox();
       double bbox_height = bbox1.y2 - bbox1.y1;
       double decent = font_sz * bbox1.y1 / bbox_height;
       double ascent = font_sz * bbox1.y2 / bbox_height;
       double horiz_scale = gs.GetHorizontalScale() / 100.0;
       Matrix2D tmtx = element.GetTextMatrix();
       Matrix2D mtx = element.GetCTM() * tmtx;
       CharIterator itr = element.CharBegin(), end =
element.CharEnd();

       for (; itr != end; itr.Next())
       {
        Rect gbox = GetGlyphBBox(itr, font, horiz_scale, font_sz,
ascent, decent);
        gbox = GetBBoxTransfRect(gbox, mtx);

        Element new_element = _eb.CreateTextRun(new String((char)
(itr.Current().char_code), 1), font, font_sz);

        if (element.HasTextMatrix() && itr == element.CharBegin())
        {
         new_element.SetTextMatrix(element.GetTextMatrix());
        }

        new_element.SetPosAdjustment(element.GetPosAdjustment());
        GState ngs = new_element.GetGState();
        ngs.SetBlackGenFunct(gs.GetBlackGenFunct());
        ngs.SetBlendMode(gs.GetBlendMode());
        ngs.SetCharSpacing(gs.GetCharSpacing());
        ngs.SetDashPattern(gs.GetDashes(), gs.GetPhase());
        ngs.SetFillColorSpace(gs.GetFillColorSpace());
        ngs.SetFillOpacity(gs.GetFillOpacity());
        ngs.SetFlatness(gs.GetFlatness());
        ngs.SetHalftone(gs.GetHalftone());
        ngs.SetHorizontalScale(gs.GetHorizontalScale());
        ngs.SetLeading(gs.GetLeading());
        ngs.SetLineCap(gs.GetLineCap());
        ngs.SetLineJoin(gs.GetLineJoin());
        ngs.SetLineWidth(gs.GetLineWidth());
        ngs.SetMiterLimit(gs.GetMiterLimit());
        ngs.SetRenderingIntent(gs.GetRenderingIntent());
        ngs.SetSmoothnessTolerance(gs.GetSmoothnessTolerance());
        ngs.SetSoftMask(gs.GetSoftMask());
        ngs.SetStrokeColor(gs.GetStrokeColor());
        ngs.SetStrokeColorSpace(gs.GetStrokeColorSpace());
        ngs.SetStrokeOpacity(gs.GetStrokeOpacity());
        ngs.SetTextKnockout(gs.IsTextKnockout());
        ngs.SetTextRenderMode(gs.GetTextRenderMode());
        ngs.SetTextRise(gs.GetTextRise());
        ngs.SetUCRFunct(gs.GetUCRFunct());
        ngs.SetWordSpacing(gs.GetWordSpacing());

        if (gbox.IntersectRect(gbox, sel_rect))
        {
         ngs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
         ngs.SetFillColor(textColor);
        }
        else
        {
         ngs.SetFillColor(cpt);
        }

        writer.WriteElement(new_element);
        gs.SetFillColorSpace(cs);
        gs.SetFillColor(cpt);
       }
      }
     }
     else
     {
      writer.WriteElement(element);
     }
    }

    writer.End();
    reader.End();
    doc.PageRemove(doc.PageFind(1));

    doc.Save(output_path + "newsletter_edited.pdf",
Doc.SaveOptions.e_remove_unused);
    doc.Close();
    Console.WriteLine("Done. Result saved in
newsletter_edited.pdf...");
   }
   catch (PDFNetException e)
   {
    Console.WriteLine(e.Message);
   }

   PDFNet.Terminate();
  }

  static Rect GetGlyphBBox(CharIterator itr, pdftron.PDF.Font font,
double horiz_scale, double font_sz , double ascent, double descent)
  {
   Rect out_bbox = new Rect();
   out_bbox.x1 = itr.Current().x;
   out_bbox.y1 = itr.Current().y;

   double dx = 0;
   if (font.IsSimple())
   {
    dx = font.GetWidth(itr.Current().char_code) / 1000.0;
    dx *= horiz_scale * font_sz;

    out_bbox.x2 = out_bbox.x1 + dx;
    out_bbox.y1 = itr.Current().y + descent;
    out_bbox.y2 = itr.Current().y + ascent;
   }
   else
   {
    int cid = font.MapToCID(itr.Current().char_code);
    dx = font.GetWidth(cid) / 1000.0;
    dx *= horiz_scale * font_sz;

    out_bbox.x2 = out_bbox.x1 + dx;
    out_bbox.y1 = itr.Current().y + descent;
    out_bbox.y2 = itr.Current().y + ascent;
   }

   return out_bbox;
  }

  static Rect GetBBoxTransfRect(Rect inn, Matrix2D mtx)
  {
   double p1x = inn.x1, p1y = inn.y1, p2x = inn.x2, p2y = inn.y1, p3x
= inn.x2, p3y = inn.y2, p4x = inn.x1, p4y = inn.y2;
   mtx.Mult(ref p1x, ref p1y);
   mtx.Mult(ref p2x, ref p2y);
   mtx.Mult(ref p3x, ref p3y);
   mtx.Mult(ref p4x, ref p4y);

   return new Rect(Math.Min(Math.Min(Math.Min(p1x, p2x), p3x), p4x),
      Math.Min(Math.Min(Math.Min(p1y, p2y), p3y), p4y),
      Math.Max(Math.Max(Math.Max(p1x, p2x), p3x), p4x),
      Math.Max(Math.Max(Math.Max(p1y, p2y), p3y), p4y));
  }
}
}

Updated code, for latest API, and now handles all GState changes. Also attached, same code. You can replace the ElementEditTest sample code with this file.

`

//
// Copyright (c) 2001-2016 by PDFTron Systems Inc. All Rights Reserved.
//

using System;
using System.Collections.Generic;

using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

using XSet = System.Collections.Generic.List<int>;

namespace ElementEditTestCS
{
/// <summary>
/// The sample code shows how to edit the page display list and how to modify graphics state
/// attributes on existing Elements. In particular the sample program strips all images from
/// the page, changes path fill color to red, and changes text fill color to blue.
/// </summary>
class ElementEditTest
{
private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();

static Rect GetGlyphBBox(CharIterator itr, pdftron.PDF.Font font,
double horiz_scale, double font_sz, double ascent, double descent)
{
Rect out_bbox = new Rect();
out_bbox.x1 = itr.Current().x;
out_bbox.y1 = itr.Current().y;

double dx = 0;
if (font.IsSimple())
{
dx = font.GetWidth(itr.Current().char_code) / 1000.0;
dx *= horiz_scale * font_sz;

out_bbox.x2 = out_bbox.x1 + dx;
out_bbox.y1 = itr.Current().y + descent;
out_bbox.y2 = itr.Current().y + ascent;
}
else
{
int cid = font.MapToCID(itr.Current().char_code);
dx = font.GetWidth(cid) / 1000.0;
dx *= horiz_scale * font_sz;

out_bbox.x2 = out_bbox.x1 + dx;
out_bbox.y1 = itr.Current().y + descent;
out_bbox.y2 = itr.Current().y + ascent;
}

return out_bbox;
}

static Rect GetBBoxTransfRect(Rect inn, Matrix2D mtx)
{
double p1x = inn.x1, p1y = inn.y1, p2x = inn.x2, p2y = inn.y1, p3x
= inn.x2, p3y = inn.y2, p4x = inn.x1, p4y = inn.y2;
mtx.Mult(ref p1x, ref p1y);
mtx.Mult(ref p2x, ref p2y);
mtx.Mult(ref p3x, ref p3y);
mtx.Mult(ref p4x, ref p4y);

return new Rect(Math.Min(Math.Min(Math.Min(p1x, p2x), p3x), p4x),
Math.Min(Math.Min(Math.Min(p1y, p2y), p3y), p4y),
Math.Max(Math.Max(Math.Max(p1x, p2x), p3x), p4x),
Math.Max(Math.Max(Math.Max(p1y, p2y), p3y), p4y));
}

static void ProcessElements(ElementReader reader, ElementWriter writer, XSet visited)
{
Rect sel_rect = new Rect(124.338000, 481.582000, 515.442000, 527.214000);
ColorPt textColor = new ColorPt(1.0, 0.0, 0.0);
Rect bbox = new Rect();

ElementBuilder builder = new ElementBuilder();

Element element;
while ((element = reader.Next()) != null) // Read page contents
{
switch (element.GetType())
{
case Element.Type.e_text:
{
ColorPt cpt = element.GetGState().GetFillColor();
element.GetBBox(bbox);

if (bbox.x2 <= sel_rect.x1 || bbox.x1 >= sel_rect.x2 || bbox.y1
>= sel_rect.y2 || bbox.y2 <= sel_rect.y1)
{
writer.WriteElement(element);
}
else if (bbox.x2 <= sel_rect.x2 && bbox.x1 >= sel_rect.x1 &&
bbox.y1 >= sel_rect.y1 && bbox.y2 <= sel_rect.y2)
{
GState gs = element.GetGState();
gs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
gs.SetFillColor(textColor);
writer.WriteElement(element);
gs.SetFillColor(cpt);
}
else
{
GState gs = element.GetGState();
pdftron.PDF.Font font = gs.GetFont();
double font_sz = gs.GetFontSize();
Rect bbox1 = font.GetBBox();
double bbox_height = bbox1.y2 - bbox1.y1;
double decent = font_sz * bbox1.y1 / bbox_height;
double ascent = font_sz * bbox1.y2 / bbox_height;
double horiz_scale = gs.GetHorizontalScale() / 100.0;
Matrix2D tmtx = element.GetTextMatrix();
Matrix2D mtx = element.GetCTM() * tmtx;

for (CharIterator itr = element.GetCharIterator(); itr.HasNext(); itr.Next())
{
{
Rect gbox = GetGlyphBBox(itr, font, horiz_scale, font_sz, ascent, decent);
gbox = GetBBoxTransfRect(gbox, mtx);

Element new_element = builder.CreateTextRun(new String((char)(itr.Current().char_code), 1), font, font_sz);

if (element.HasTextMatrix() && itr == element.GetCharIterator())
{
new_element.SetTextMatrix(element.GetTextMatrix());
}

new_element.SetPosAdjustment(element.GetPosAdjustment());
GState ngs = new_element.GetGState();

int i = 0;

for (GSChangesIterator gsitr = reader.GetChangesIterator(); gsitr.HasNext(); gsitr.Next())
{
GState.GStateAttribute st = gsitr.Current();
switch (gsitr.Current())
{
case GState.GStateAttribute.e_halftone:
ngs.SetHalftone(gs.GetHalftone());
break;
case GState.GStateAttribute.e_UCR_funct:
ngs.SetUCRFunct(gs.GetUCRFunct());
break;
case GState.GStateAttribute.e_BG_funct:
ngs.SetBlackGenFunct(gs.GetBlackGenFunct());
break;
case GState.GStateAttribute.e_transfer_funct:
ngs.SetTransferFunct(gs.GetTransferFunct());
break;
case GState.GStateAttribute.e_overprint_mode:
ngs.SetOverprintMode(gs.GetOverprintMode());
break;
case GState.GStateAttribute.e_fill_overprint:
ngs.SetFillOverprint(gs.GetFillOverprint());
break;
case GState.GStateAttribute.e_stroke_overprint:
ngs.SetStrokeOverprint(gs.GetStrokeOverprint());
break;
case GState.GStateAttribute.e_auto_stoke_adjust:
ngs.SetAutoStrokeAdjust(gs.GetAutoStrokeAdjust());
break;
case GState.GStateAttribute.e_smoothnes:
ngs.SetSmoothnessTolerance(gs.GetSmoothnessTolerance());
break;
case GState.GStateAttribute.e_soft_mask:
ngs.SetSoftMask(gs.GetSoftMask());
break;
case GState.GStateAttribute.e_alpha_is_shape:
ngs.SetAISFlag(gs.GetAISFlag());
break;
case GState.GStateAttribute.e_opacity_stroke:
ngs.SetStrokeOpacity(gs.GetStrokeOpacity());
break;
case GState.GStateAttribute.e_opacity_fill:
ngs.SetFillOpacity(gs.GetFillOpacity());
break;
case GState.GStateAttribute.e_blend_mode:
ngs.SetBlendMode(gs.GetBlendMode());
break;
case GState.GStateAttribute.e_text_pos_offset:
//ngs.Settext_pos_offset(gs.Gettext_pos_offset());
break;
case GState.GStateAttribute.e_text_knockout:
ngs.SetTextKnockout(gs.IsTextKnockout());
break;
case GState.GStateAttribute.e_text_rise:
ngs.SetTextRise(gs.GetTextRise());
break;
case GState.GStateAttribute.e_text_render_mode:
ngs.SetTextRenderMode(gs.GetTextRenderMode());
break;
case GState.GStateAttribute.e_font_size:
ngs.SetFont(gs.GetFont(), gs.GetFontSize());
break;
case GState.GStateAttribute.e_font:
ngs.SetFont(gs.GetFont(), gs.GetFontSize());
break;
case GState.GStateAttribute.e_leading:
ngs.SetLeading(gs.GetLeading());
break;
case GState.GStateAttribute.e_horizontal_scale:
ngs.SetHorizontalScale(gs.GetHorizontalScale());
break;
case GState.GStateAttribute.e_word_spacing:
ngs.SetWordSpacing(gs.GetWordSpacing());
break;
case GState.GStateAttribute.e_char_spacing:
ngs.SetCharSpacing(gs.GetCharSpacing());
break;
case GState.GStateAttribute.e_dash_pattern:
ngs.SetDashPattern(gs.GetDashes(), gs.GetPhase());
break;
case GState.GStateAttribute.e_miter_limit:
ngs.SetMiterLimit(gs.GetMiterLimit());
break;
case GState.GStateAttribute.e_flatness:
ngs.SetFlatness(gs.GetFlatness());
break;
case GState.GStateAttribute.e_line_join:
ngs.SetLineJoin(gs.GetLineJoin());
break;
case GState.GStateAttribute.e_line_cap:
ngs.SetLineCap(gs.GetLineCap());
break;
case GState.GStateAttribute.e_line_width:
ngs.SetLineWidth(gs.GetLineWidth());
break;
case GState.GStateAttribute.e_fill_color:
ngs.SetFillColor(gs.GetFillColor());
break;
case GState.GStateAttribute.e_fill_cs:
ngs.SetFillColorSpace(gs.GetFillColorSpace());
break;
case GState.GStateAttribute.e_stroke_color:
ngs.SetStrokeColor(gs.GetStrokeColor());
break;
case GState.GStateAttribute.e_stroke_cs:
ngs.SetStrokeColorSpace(gs.GetStrokeColorSpace());
break;
case GState.GStateAttribute.e_rendering_intent:
ngs.SetRenderingIntent(gs.GetRenderingIntent());
break;
case GState.GStateAttribute.e_transform:
ngs.SetTransform(gs.GetTransform());
break;
}
}

ngs.SetFillColorSpace(ColorSpace.CreateDeviceRGB());

if (gbox.IntersectRect(gbox, sel_rect))
{
ngs.SetFillColor(textColor);
}
else
{
ngs.SetFillColor(cpt);
}

writer.WriteElement(new_element);
gs.SetFillColor(cpt);
}
}
}
break;
}
case Element.Type.e_form:
{
writer.WriteElement(element); // write Form XObject reference to current stream

Obj form_obj = element.GetXObject();
if (!visited.Contains(form_obj.GetObjNum())) // if this XObject has not been processed
{
// recursively process the Form XObject
visited.Add(form_obj.GetObjNum());
ElementWriter new_writer = new ElementWriter();

reader.FormBegin();
new_writer.Begin(form_obj, true);
ProcessElements(reader, new_writer, visited);
new_writer.End();
reader.End();
}
break;
}
default:
writer.WriteElement(element);
break;
}
}
}

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
PDFNet.Initialize();

// Relative path to the folder containing test files.
string input_path = "../../../../TestFiles/";
string output_path = "../../../../TestFiles/Output/";
string input_filename = "newsletter.pdf";
string output_filename = "newsletter_edited.pdf";

try
{
Console.WriteLine("Opening the input file...");
using (PDFDoc doc = new PDFDoc(@"D:\work\PDFNet_alpha\CWrap\Samples\TestFiles\newsletter.pdf"))
{
doc.InitSecurityHandler();

ElementWriter writer = new ElementWriter();
ElementReader reader = new ElementReader();
XSet visited = new XSet();

PageIterator itr = doc.GetPageIterator();

while (itr.HasNext())
{
Page page = itr.Current();
visited.Add(page.GetSDFObj().GetObjNum());

reader.Begin(page);
writer.Begin(page, ElementWriter.WriteMode.e_replacement, false);
ProcessElements(reader, writer, visited);
writer.End();
reader.End();

itr.Next();
break;
}

doc.Save(@"D:\work\PDFNet_alpha\CWrap\Samples\TestFiles\newsletter_out_04.pdf", SDFDoc.SaveOptions.e_remove_unused);
Console.WriteLine("Done. Result saved in {0}...", output_filename);
}
}
catch (PDFNetException e)
{
Console.WriteLine(e.Message);
}

}
}
}

ElementEditTest.cs (17.7 KB)