123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Text;
- namespace FastReport.RichTextParser
- {
- internal class RTF_Picture : RTF_CommonRichElement
- {
- internal Picture picture = new Picture();
- internal long metamapmode;
- public RTF_Picture()
- {
- picture.scalex = 100;
- picture.scaley = 100;
- subdata_counter = 1;
- }
- internal override RichObject RichObject
- {
- get
- {
- RichObject rich = new RichObject();
- rich.type = RichObject.Type.Picture;
- rich.picture = picture;
- rich.size = picture.size;
- return rich;
- }
- }
- private enum State { PictHeader, BlipImage, BlipMetafile };
- private State state = State.PictHeader;
- int subdata_counter;
- internal void CreateImage(Stream stream)
- {
- switch (state)
- {
- case State.PictHeader:
- throw new NotImplementedException("Image format not supported (yet)");
- case State.BlipImage:
- picture.image = Bitmap.FromStream(stream);
- picture.width = picture.image.Width;
- picture.height = picture.image.Height;
- break;
- case State.BlipMetafile:
- #if true
- //picture.image = new Metafile(stream);
- picture.image = new Bitmap(stream);
- if (metamapmode == 8)
- {
- picture.width = picture.image.Width;
- picture.height = picture.image.Height;
- if (picture.desired_height != 0)
- picture.height = Twips2Pixels(picture.desired_height);
- if (picture.desired_width != 0)
- picture.height = Twips2Pixels(picture.desired_width);
- }
- #elif false
- using (var fileStream = File.Create("my.wmf"))
- {
- stream.Seek(0, SeekOrigin.Begin);
- stream.CopyTo(fileStream);
- }
- #else
- picture.image = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
- using (Graphics graphics = Graphics.FromImage(picture.image))
- {
- graphics.FillEllipse(Brushes.Brown, new Rectangle(new Point(0, 0), picture.image.Size));
- }
- #endif
- break;
- }
- }
- private byte CharToHex(char ch)
- {
- if (char.IsDigit(ch))
- return (byte)(ch - '0');
- if (ch >= 'A' && ch <= 'F')
- return (byte)(10 + ch - 'A');
- if (ch >= 'a' && ch <= 'f')
- return (byte)(10 + ch - 'a');
- return 0;
- }
- internal bool ParseBlip(RTF_Parser parser, RTF_Header header)
- {
- int i, j;
- int len = parser.Text.Length;
- byte h = 0, l;
- byte[] raw_pict = new byte[len >> 1];
- for (i = j = 0; i < len; i++)
- {
- if ((i & 1) == 0)
- {
- h = CharToHex(parser.Text[i]);
- }
- else
- {
- l = CharToHex(parser.Text[i]);
- raw_pict[j++] = (byte)((h << 4) | l);
- }
- }
- try
- {
- CreateImage(new MemoryStream(raw_pict));
- }
- catch (Exception e)
- {
- if (picture.desired_height != 0)
- picture.height = Twips2Pixels(picture.desired_height);
- if (picture.desired_width != 0)
- picture.width = Twips2Pixels(picture.desired_width);
- picture.image = new Bitmap(picture.width, picture.height);
- Graphics g = Graphics.FromImage(picture.image);
- g.DrawString("Unable load bitmap", new Font(FontFamily.GenericMonospace, 10), new SolidBrush(Color.Red), 5, 5); ;
- g.DrawString(e.Message, new Font(FontFamily.GenericMonospace, 8), new SolidBrush(Color.Red), 5, 20); ;
- }
- return false;
- }
- internal override bool Parse(RTF_Parser parser, RTF_Header header)
- {
- if (parser.Status == ParserStatus.OpenBlock)
- {
- subdata_counter++;
- picture.horizontalAlign = parser.current_paragraph_format.align;
- }
- if (parser.Status == ParserStatus.CloseBlock)
- // if (parser.Status == ParserStatus.OpenBlock)
- {
- subdata_counter--;
- }
- switch (parser.Control)
- {
- case "picw":
- picture.width = (int)parser.Number;
- break;
- case "pich":
- picture.height = (int)parser.Number;
- break;
- case "picscalex":
- picture.scalex = (int)parser.Number;
- break;
- case "picscaley":
- picture.scaley = (int)parser.Number;
- break;
- case "pngblip":
- state = State.BlipImage;
- break;
- case "jpegblip":
- state = State.BlipImage;
- break;
- case "piccropt":
- picture.crop_top = Twips2Pixels(parser.Number);
- break;
- case "piccropl":
- picture.crop_left = Twips2Pixels(parser.Number);
- break;
- case "piccropb":
- picture.crop_bottom = Twips2Pixels(parser.Number);
- break;
- case "piccropr":
- picture.crop_right = Twips2Pixels(parser.Number);
- break;
- case "picprop":
- picture.picprop = true;
- break;
- case "picwgoal":
- case "picwGoal":
- picture.desired_width = (int) parser.Number;
- break;
- case "pichgoal":
- case "pichGoal":
- picture.desired_height = (int)parser.Number;
- break;
- case "wmetafile":
- state = State.BlipMetafile;
- metamapmode = parser.Number;
- break;
- case "emfblip":
- state = State.BlipMetafile;
- metamapmode = parser.Number;
- break;
- case "bliptag":
- picture.tag = (int)parser.Number;
- break;
- case "blipupi":
- picture.units_per_inch = (int)parser.Number;
- break;
- case "blipuid":
- ;
- break;
- case "":
- if (parser.Status == ParserStatus.CloseBlock)
- {
- if (parser.Text.Length != 0)
- {
- if(subdata_counter <= 0)
- return ParseBlip(parser, header);
- }
- }
- break;
- case "sp":
- // Word-2007 shape property
- break;
- case "sn":
- // Word-2007 shape property name
- break;
- case "sv":
- // Word-2007 shape property value
- break;
- default:
- #if DEBUG_RTF
- throw new NotImplementedException(parser.Control);
- #else
- break;
- #endif
- }
- return true;
- }
- }
- }
|