加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[iTextSharp学习笔记]了解DirectContent

(2011-08-25 20:54:20)
标签:

itextsharp

csharp

dotnet

杂谈

分类: 好好学习

本章将学习如何使用直接向页面数据流写入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


    第1个图形:橙色、无边框。

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函数与之对应。否则,将会抛出IllegalPdfSyntaxException异常。

在本章中,绝对位置(absolute position)使用的座标系的原点为页面的左下角

 

文本状态(text state

文本状态是图形状态的一个子集。其实,文本也能视为一种图形,字体告诉计算机如何将文字“画”出来。默认情况下,“画”出文字没有边框,使用指定的颜色填充。如果想绘出文字的边框,可以使用SetTextRenderingMode函数改变文字呈现(text-rendering)模式。SetFontAndSize函数设置字体和大小,SetTextMatrix设置text matrix,ShowText绘制文字。

 

绘图的一些函数

MoveTo、LineTo、Circle、Ellipse、Arc。

 

iTextSharp中,Rectangle、Cirlce、LineTo等函数并不实际绘制出图形,Stroke、FillStroke等函数才实际完成绘图操作。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有