PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Mon May 13, 2024 9:14 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: changing text color
PostPosted: Thu Jul 29, 2010 1:13 pm 
Offline

Joined: Sat Dec 12, 2009 8:10 pm
Posts: 2
If I open an exsisting pdf document, can I change the color of part of the text, chosen by me?


Top
 Profile  
Reply with quote  
 Post subject: Re: changing text color
PostPosted: Fri Aug 06, 2010 3:31 pm 
Offline

Joined: Tue Jun 08, 2010 6:12 pm
Posts: 13
I found a way to do this, but it isn't easy (if you find an easier way please post your solution). What I found is that you'll have to read the text directly from the PdfPage's stream. You then search through the stream line by line looking for the op codes that draw the text and set its color. You will then change the parameters for text's color op code. To find the op codes you are looking for you'll have to look them up from either the PDFSharp source code or the Adobe PDF Spec.

My requirement was to create a program to convert all the RGB vector data in a PDF to CMYK using predefined conversion values. Here is some prototype code I wrote to accomplish this. You might can change it to work for just text:

private void ConvertDocToCMYK()
{
PdfDocument rgbdoc = PdfReader.Open("C:\\pdf\\NebraskaDOR(rgb).pdf", PdfDocumentOpenMode.Modify);
PdfPage rgbpage = rgbdoc.Pages[0];

//get all the internal objects from the pdf
PdfObject[] obj = rgbdoc.Internals.GetAllObjects();

//loop through all of those objects looking for streams
for (int i = 0; i < obj.Length; i++)
{
PdfDictionary dict = (PdfDictionary)obj[i];

//if the object doesn't contain a stream then just skip it
if (dict.Stream != null)
{
//there should also not be a subtype if this stream contains vector data???
object subType = dict.Elements["/Subtype"];
if (subType == null)
{
PdfDictionary.PdfStream stream = dict.Stream;

//decode the stream
bool pass = stream.TryUnfilter();
string temp = stream.ToString();

//look for the op-codes and change values
ParseString(ref temp);

//re encode the dtream
byte[] b = PdfDictionary.PdfStream.RawEncode(temp);

PdfInteger integer = new PdfInteger(b.Length);

//set the old stream to null, do we need to dispose of this some how???
dict.Stream = null;
//set the length of the new stream
dict.Elements["/Length"] = integer;
//create the new stream
dict.CreateStream(b);

//delete the old dictionary from the page
rgbdoc.Internals.RemoveObject(obj[i]);
//add the dictionary we just created
rgbdoc.Internals.AddObject(dict);

}
}
}

rgbdoc.Options.ColorMode = PdfColorMode.Cmyk;
rgbdoc.Save("C:\\pdf\\testconvert.pdf");
}

private void ParseString(ref string stream)
{
string temp;
string r, g, b, c, m, y, k;
int beginIndex, endIndex, lineIndex;
int rBeginIndex, rEndIndex, gBeginIndex, gEndIndex, bBeginIndex, bEndIndex;

//rg is the op code for drawing in RGB, find all instances of this and change to CMYK
while (stream.Contains(" rg"))
{
endIndex = stream.IndexOf(" rg") + 3;

bEndIndex = endIndex - 3;

temp = stream.Substring(0, bEndIndex);

bBeginIndex = temp.LastIndexOf(" ");

b = temp.Substring(bBeginIndex, bEndIndex - bBeginIndex);

gEndIndex = bBeginIndex;
temp = temp.Substring(0, gEndIndex);

gBeginIndex = temp.LastIndexOf(" ");

g = temp.Substring(gBeginIndex, gEndIndex - gBeginIndex);

rEndIndex = gBeginIndex;
temp = temp.Substring(0, rEndIndex);

rBeginIndex = temp.LastIndexOf(" ");
lineIndex = temp.LastIndexOf("\n") + 1;

if (rBeginIndex < lineIndex)
rBeginIndex = lineIndex;

r = temp.Substring(rBeginIndex, rEndIndex - rBeginIndex);

beginIndex = rBeginIndex;

ConvertRGBToCMYK(r, g, b, out c, out m, out y, out k);

stream = stream.Remove(beginIndex, endIndex - beginIndex);

stream = stream.Insert(beginIndex, c + " " + m + " " + y + " " + k + " k");
}

//also check for the capitalized version
while (stream.Contains(" RG"))
{
endIndex = stream.IndexOf(" RG") + 3;

bEndIndex = endIndex - 3;

temp = stream.Substring(0, bEndIndex);

bBeginIndex = temp.LastIndexOf(" ");

b = temp.Substring(bBeginIndex, bEndIndex - bBeginIndex);

gEndIndex = bBeginIndex;
temp = temp.Substring(0, gEndIndex);

gBeginIndex = temp.LastIndexOf(" ");

g = temp.Substring(gBeginIndex, gEndIndex - gBeginIndex);

rEndIndex = gBeginIndex;
temp = temp.Substring(0, rEndIndex);

rBeginIndex = temp.LastIndexOf(" ");
lineIndex = temp.LastIndexOf("\n") + 1;

if (rBeginIndex < lineIndex)
rBeginIndex = lineIndex;

r = temp.Substring(rBeginIndex, rEndIndex - rBeginIndex);

beginIndex = rBeginIndex;

ConvertRGBToCMYK(r, g, b, out c, out m, out y, out k);

stream = stream.Remove(beginIndex, endIndex - beginIndex);

stream = stream.Insert(beginIndex, c + " " + m + " " + y + " " + k + " K");
}

}

This may be over kill for what you are trying to do. Maybe somebody else will chime in with a much easier way of changing the color of just the text.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: Baidu [Spider], Google [Bot] and 74 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group