[iTextSharp学习笔记]了解DirectContent

标签:
itextsharpcsharpdotnet杂谈 |
分类: 好好学习 |
本章将学习如何使用直接向页面数据流写入PDF语法的低等级操作(low-level operation)来添加内容。我们会见识ColumnText的威力,它能帮助我们在指定的PDF文档位置上添加基本块。
什么是direct content
Document类的Add操作会自动将图片布置到文档的图片层,而图片层总是在文字层之下的。
direct content层
BaseFont msyhBaseFont = BaseFont.CreateFont(@"C:\windows\fonts\msyh.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font mshyFont = new Font(msyhBaseFont, 18, Font.NORMAL, BaseColor.BLUE);
Document document = new Document(PageSize.B5);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(@"F:\DirectContent.pdf", FileMode.Create));
document.Open();
Paragraph content = new Paragraph("使用低等级操作", mshyFont);
content.Alignment = Element.ALIGN_CENTER;
document.Add(content);
Image image = Image.GetInstance(@"F:\gold.jpg");
Console.WriteLine("ScaledWidth: {0}, ScaledHeight: {1} of the Image.", image.ScaledWidth, image.ScaledHeight);
image.SetAbsolutePosition((PageSize.B5.Width - image.ScaledWidth) / 2, (PageSize.B5.Height - image.ScaledHeight) / 2);
document.Add(image);
document.NewPage();
PdfContentByte over = writer.DirectContent;
over.SaveState();
float sinus = (float)Math.Sin(Math.PI / 60);
float cosinus = (float)Math.Cos(Math.PI / 60);
over.BeginText();
over.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
over.SetLineWidth(1.5f);
over.SetRGBColorStroke(0xFF, 0x00, 0x00);
over.SetRGBColorFill(0xFF, 0xFF, 0xFF);
over.SetFontAndSize(msyhBaseFont, 36);
over.SetTextMatrix(cosinus, sinus, -sinus, cosinus, 50, 324);
over.ShowText("SOLD OUT");
over.EndText();
over.RestoreState();
document.Add(content);
document.Add(image);
PdfContentByte under = writer.DirectContentUnder;
under.SaveState();
under.SetRGBColorFill(0xFF, 0xD7, 0x00);
under.Rectangle(5, 5, PageSize.B5.Width - 10, PageSize.B5.Height - 10);
under.Fill();
under.RestoreState();
document.Close();
上面代码中,演示了使用高等级操作(high-level)和低等级操作(low-level)向PDF文档中添加内容的方式。iText可以直接向包装在PdfContentByte对象中的ByteBuffer中写入PDF语法。当一页写满时,iText会将缓冲区(buffer)中的内容按照特定的顺序写入PDF文件。每一个缓冲区可以视为一个单独的层。
在上面的例子中,PDF文档分为四层:最高层和最低用于direct content,中间2层用于高等级(high-level)对象。
页面初始化时会自动创建2个PdfContentByte对象:
1.用于文本的PdfContentByte对象:可写入Chunk、Phrase、Paragraph等对象的内容。
2.用于图像的PdfContentByte对象:可写入Chunk、Image的背景、PdfPCell的边框等内容。
中间2层对应的PdfContentByte不能直接访问,它们由iText来管理。但最高层和最低层的PdfContentByte可以操作:
最高层:用于文本和图像,通过PdfWriter.GetDirectContent函数获得该对象。
最低层:用于文本和图像,通过PdfWriter.GetDirectContentUnder函数获得该对象。
在iText术语中,向这两层添加内容称为writing to the direct content或者low-level access,其过程就是在PdfContentByte对象上执行low-level操作。正如上面代码,首先更改对象的状态(state),在指定的位置画线、形状或添加文本。
图形和文本状态(graphics state and text state)
图形状态(graphics state)
Document document = new Document(PageSize.B8.Rotate());
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(@"F:\GraphicsState.pdf", FileMode.Create));
document.Open();
PdfContentByte canvas = writer.DirectContent;
canvas.SetRGBColorFill(0xFF, 0x45, 0x00);
canvas.Rectangle(10, 10, 60, 60);
canvas.Fill();
canvas.SaveState();
canvas.SetLineWidth(3);
canvas.SetRGBColorFill(0x8B, 0x00, 0x00);
canvas.Rectangle(40, 20, 60, 60);
canvas.FillStroke();
canvas.SaveState();
canvas.ConcatCTM(1, 0, 0.1f, 1, 0, 0);
canvas.SetRGBColorStroke(0xff, 0x45, 0x00);
canvas.SetRGBColorFill(0xff, 0xd7, 0x00);
canvas.Rectangle(70, 30, 60, 60);
canvas.FillStroke();
canvas.RestoreState();
canvas.Rectangle(100, 40, 60, 60);
canvas.Stroke();
canvas.RestoreState();
canvas.Rectangle(130, 50, 60, 60);
canvas.FillStroke();
document.Close();
http://s12/bmiddle/88ac4b5fgab54002cab1b&690
canvas.SetRGBColorFill(0xFF, 0x45, 0x00);
canvas.Rectangle(10, 10, 60, 60);
canvas.Fill();
使用SetRGBColorFill设置填充色,使用Rectangle设置位置和大小,使用Fill填充。
第2个图形:默认颜色(黑色)线条,深红色填充,在绘制该图形前使用了SetLineWidth将线条粗细设为了3,然后调用FillStroke绘制图形。
第3个图形:该图形线条宽度依然保持3,但颜色设置为了桔黄色,填充色设置为金色,但图形不再为正方形,因为使用ConcatCTM函数改变了current transformation matrix(CTM)。
第4个图形:由于在绘制第4个图形前使用了RestoreState函数,因此绘制第3个图形时的设置都取消了,图形状态回到了绘制第2个图形时的设置。在绘制第4个图形时,由于使用的是Stroke函数而不是FillStroke,因此只绘制了边框而没有填充。
第5个图形:图形状态恢复到了绘制第1个图形时的状态。
图形状态相当于一个栈(stack),SaveState为进栈、RestoreState为出栈。SaveState和RestoreState函数在代码中应该成对出现,如果想使用RestoreState恢复图形状态,则必须首先使用了SaveState保存了图形状态;如果使用了SaveState保存了图形状态,则后面必须有一个RestoreState函数与之对应。否则,将会抛出IllegalPdfSyntaxExceptio
在本章中,绝对位置(absolute position)使用的座标系的原点为页面的左下角。
文本状态(text state)
文本状态是图形状态的一个子集。其实,文本也能视为一种图形,字体告诉计算机如何将文字“画”出来。默认情况下,“画”出文字没有边框,使用指定的颜色填充。如果想绘出文字的边框,可以使用SetTextRenderingMode函数改变文字呈现(text-rendering)模式。SetFontAndSize函数设置字体和大小,SetTextMatrix设置text matrix,ShowText绘制文字。
绘图的一些函数
MoveTo、LineTo、Circle、Ellipse、Arc。
iTextSharp中,Rectangle、Cirlce、LineTo等函数并不实际绘制出图形,Stroke、FillStroke等函数才实际完成绘图操作。