private void OpenPsFile(string path)
{
_tokenizer = new DSCTokenizer(path);
this.FirstPageNumber = 1;
DSCToken token = null;
// loop through all DSC comments based on keyword
while ((token = _tokenizer.GetNextDSCKeywordToken()) != null)
{
switch (token.Text)
{
case DSC_PAGES: // %%Pages: <numpages> | (atend)
{
token = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace | DSCTokenEnding.LineEnd);
// check if we need to ignore this comment because it's set at the end of the file
if (!string.IsNullOrWhiteSpace(token.Text) && token.Text != "(atend)" && !token.Text.StartsWith("%"))
{
// we got it, memorize it
this.LastPageNumber = int.Parse(token.Text);
}
break;
}
case DSC_BOUNDINGBOX: // { %%BoundingBox: <llx> <lly> <urx> <ury> } | (atend)
{
try
{
DSCToken llx = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace | DSCTokenEnding.LineEnd);
if (!string.IsNullOrWhiteSpace(llx.Text) && llx.Text != "(atend)" && !llx.Text.StartsWith("%"))
{
DSCToken lly = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace);
DSCToken urx = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace);
DSCToken ury = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace | DSCTokenEnding.LineEnd);
this.BoundingBox = new GhostscriptRectangle(
float.Parse(llx.Text, System.Globalization.CultureInfo.InvariantCulture),
float.Parse(lly.Text, System.Globalization.CultureInfo.InvariantCulture),
float.Parse(urx.Text, System.Globalization.CultureInfo.InvariantCulture),
float.Parse(ury.Text, System.Globalization.CultureInfo.InvariantCulture));
}
}
catch { }
break;
}
case DSC_PAGE: // %%Page: <label> <ordinal>
{
// label can be anything, we need to get oridinal which is the last
// value of the line
DSCToken pageNumberToken;
// loop through each comment value
while ((pageNumberToken = _tokenizer.GetNextDSCValueToken(DSCTokenEnding.Whitespace | DSCTokenEnding.LineEnd)) != null)
{
// check if this is the last comment value in this line
if (pageNumberToken.Ending == DSCTokenEnding.LineEnd)
{
// we got it, add this comment keyword to the page list
_pageTokens.Add(int.Parse(pageNumberToken.Text), token);
break;
}
}
break;
}
case DSC_TRAILER: // %%Trailer (no keywords)
{
// if the postscript is well formatted, we should get this one
// save this comment so we can know the position when the last page is ending
_lastPageEnding = token;
break;
}
case DSC_EOF: // %%EOF (no keywords)
{
// check if we already know where the last page is ending
if (_lastPageEnding == null)
{
// we don't know, use start of the %%EOF comment as the last page ending position
_lastPageEnding = token;
}
break;
}
}
}
// check if we didn't find %%Trailer or %%EOF comment
if (_lastPageEnding == null)
{
// it seems that the last page goes to the end of the file, set the last page ending
// position to the complete file size value
_lastPageEnding = new DSCToken();
_lastPageEnding.StartPosition = _tokenizer.FileSize;
}
// we did'n find %%Pages comment, set the last page number to 1
if (this.LastPageNumber == 0)
{
this.LastPageNumber = 1;
}
// check if we didn't find any %%Page comment
if (_pageTokens.Count == 0)
{
// create dummy one that will point to the first byte in the file
_pageTokens.Add(1, new DSCToken() { StartPosition = 0 });
}
// hpd = Header, Procedure definitions, Document setup
// start position of the first %%Page: comment is te hpd size
int hpdSize = (int)_pageTokens[1].StartPosition;
// get the hpd text
string hpdContent = _tokenizer.ReadContent(0, hpdSize);
// process header, procedure definitions and document setup
if (string.IsNullOrWhiteSpace(hpdContent))
{
hpdContent = "%!PS-Adobe-3.0";
}
this.Execute(hpdContent);
}