/** * <summary>Creates a new form within the specified document context.</summary> * <param name="context">Document where to place this form.</param> * <param name="box">Form box.</param> */ public FormXObject( Document context, drawing::RectangleF box ) : base(context) { BaseDataObject.Header[PdfName.Subtype] = PdfName.Form; Box = box; }
public Screen( Page page, drawing::RectangleF box, String text, Rendition rendition ) : base(page, PdfName.Screen, box, text) { Render render = new Render(this, Render.OperationEnum.PlayResume, rendition); { // Adding preview and play/pause control... /* * NOTE: Mouse-related actions don't work when the player is active; therefore, in order to let * the user control the rendering of the media clip (play/pause) just by mouse-clicking on the * player, we can only rely on the player's focus event. Furthermore, as the player's focus can * only be altered setting it on another widget, we have to define an ancillary field on the * same page (so convoluted!). */ string playerReference = "__player" + ((PdfReference)render.BaseObject).ObjectNumber; Document.Form.Fields.Add(new TextField(playerReference, new Widget(page, new drawing::RectangleF(box.X, box.Y, 0, 0)), "")); // Ancillary field. render.Script = RenderScript.Replace(PlayerPlaceholder, playerReference); } Actions.OnPageOpen = render; if (rendition is MediaRendition) { PdfObjectWrapper data = ((MediaRendition)rendition).Clip.Data; if (data is FileSpecification) { // Adding fallback annotation... /* * NOTE: In case of viewers which don't support video rendering, this annotation gently * degrades to a file attachment that can be opened on the same location of the corresponding * screen annotation. */ FileAttachment attachment = new FileAttachment(page, box, text, (FileSpecification)data); BaseDataObject[PdfName.T] = PdfString.Get(((FileSpecification)data).Path); // Force empty appearance to ensure no default icon is drawn on the canvas! attachment.BaseDataObject[PdfName.AP] = new PdfDictionary(new PdfName[] { PdfName.D, PdfName.R, PdfName.N }, new PdfDirectObject[] { new PdfDictionary(), new PdfDictionary(), new PdfDictionary() }); } } }
public Screen( Page page, drawing::RectangleF box, String text, String mediaPath, String mimeType ) : this( page, box, text, new MediaRendition( new MediaClipData( FileSpecification.Get( EmbeddedFile.Get(page.Document, mediaPath), System.IO.Path.GetFileName(mediaPath) ), mimeType ) ) ) { }
/** * <summary>Executes scanning on this operation.</summary> * <param name="state">Graphics state context.</param> * <param name="textScanner">Scanner to be notified about text contents. * In case it's null, the operation is applied to the graphics state context.</param> */ public void Scan( ContentScanner.GraphicsState state, IScanner textScanner ) { /* * TODO: I really dislike this solution -- it's a temporary hack until the event-driven * parsing mechanism is implemented... */ /* * TODO: support to vertical writing mode. */ double contextHeight = state.Scanner.ContextSize.Height; // PK - 2017-09-15 - state.Font can be null, which throws an exception below, so fall back on standard Courier Font font = state.Font ?? new StandardType1Font(((Page)state.Scanner.RootLevel.ContentContext).Document, StandardType1Font.FamilyEnum.Courier, false, false); double fontSize = state.FontSize; double scaledFactor = Font.GetScalingFactor(fontSize) * state.Scale; bool wordSpaceSupported = !(font is CompositeFont); double wordSpace = wordSpaceSupported ? state.WordSpace * state.Scale : 0; double charSpace = state.CharSpace * state.Scale; Matrix ctm = state.Ctm.Clone(); Matrix tm = state.Tm; if (this is ShowTextToNextLine) { ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this; double? newWordSpace = showTextToNextLine.WordSpace; if (newWordSpace != null) { if (textScanner == null) { state.WordSpace = newWordSpace.Value; } if (wordSpaceSupported) { wordSpace = newWordSpace.Value * state.Scale; } } double?newCharSpace = showTextToNextLine.CharSpace; if (newCharSpace != null) { if (textScanner == null) { state.CharSpace = newCharSpace.Value; } charSpace = newCharSpace.Value * state.Scale; } tm = state.Tlm.Clone(); tm.Multiply(new Matrix(1, 0, 0, 1, 0, (float)-state.Lead)); } else { tm = state.Tm.Clone(); } foreach (object textElement in Value) { if (textElement is byte[]) // Text string. { string textString = font.Decode((byte[])textElement); foreach (char textChar in textString) { double charWidth = font.GetWidth(textChar) * scaledFactor; if (textScanner != null) { /* * NOTE: The text rendering matrix is recomputed before each glyph is painted * during a text-showing operation. */ Matrix trm = ctm.Clone(); trm.Multiply(tm); double charHeight = font.GetHeight(textChar, fontSize); drawing::RectangleF charBox = new drawing::RectangleF( trm.Elements[4], (float)(contextHeight - trm.Elements[5] - font.GetAscent(fontSize) * trm.Elements[3]), (float)charWidth * trm.Elements[0], (float)charHeight * trm.Elements[3] ); textScanner.ScanChar(textChar, charBox); } /* * NOTE: After the glyph is painted, the text matrix is updated * according to the glyph displacement and any applicable spacing parameter. */ tm.Translate((float)(charWidth + charSpace + (textChar == ' ' ? wordSpace : 0)), 0); } } else // Text position adjustment. { tm.Translate((float)(-Convert.ToSingle(textElement) * scaledFactor), 0); } } if (textScanner == null) { state.Tm = tm; if (this is ShowTextToNextLine) { state.Tlm = tm.Clone(); } } }
/** <summary>Executes scanning on this operation.</summary> <param name="state">Graphics state context.</param> <param name="textScanner">Scanner to be notified about text contents. In case it's null, the operation is applied to the graphics state context.</param> */ public void Scan( ContentScanner.GraphicsState state, IScanner textScanner ) { /* TODO: I really dislike this solution -- it's a temporary hack until the event-driven parsing mechanism is implemented... */ /* TODO: support to vertical writing mode. */ IContentContext context = state.Scanner.ContentContext; double contextHeight = context.Box.Height; Font font = state.Font; double fontSize = state.FontSize; double scale = state.Scale / 100; double scaledFactor = Font.GetScalingFactor(fontSize) * scale; double wordSpace = state.WordSpace * scale; double charSpace = state.CharSpace * scale; Matrix ctm = state.Ctm.Clone(); Matrix tm = state.Tm; if(this is ShowTextToNextLine) { ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this; double? newWordSpace = showTextToNextLine.WordSpace; if(newWordSpace != null) { if(textScanner == null) {state.WordSpace = newWordSpace.Value;} wordSpace = newWordSpace.Value * scale; } double? newCharSpace = showTextToNextLine.CharSpace; if(newCharSpace != null) { if(textScanner == null) {state.CharSpace = newCharSpace.Value;} charSpace = newCharSpace.Value * scale; } tm = state.Tlm.Clone(); tm.Translate(0, (float)state.Lead); } else {tm = state.Tm.Clone();} foreach(object textElement in Value) { if(textElement is byte[]) // Text string. { string textString = font.Decode((byte[])textElement); foreach(char textChar in textString) { double charWidth = font.GetWidth(textChar) * scaledFactor; if(textScanner != null) { /* NOTE: The text rendering matrix is recomputed before each glyph is painted during a text-showing operation. */ Matrix trm = ctm.Clone(); trm.Multiply(tm); double charHeight = font.GetHeight(textChar,fontSize); drawing::RectangleF charBox = new drawing::RectangleF( trm.Elements[4], (float)(contextHeight - trm.Elements[5] - font.GetAscent(fontSize) * trm.Elements[3]), (float)charWidth * trm.Elements[0], (float)charHeight * trm.Elements[3] ); textScanner.ScanChar(textChar,charBox); } /* NOTE: After the glyph is painted, the text matrix is updated according to the glyph displacement and any applicable spacing parameter. */ tm.Translate((float)(charWidth + charSpace + (textChar == ' ' ? wordSpace : 0)), 0); } } else // Text position adjustment. {tm.Translate((float)(-Convert.ToSingle(textElement) * scaledFactor), 0);} } if(textScanner == null) { state.Tm = tm; if(this is ShowTextToNextLine) {state.Tlm = tm.Clone();} } }
/** * <summary>Executes scanning on this operation.</summary> * <param name="state">Graphics state context.</param> * <param name="textScanner">Scanner to be notified about text contents. * In case it's null, the operation is applied to the graphics state context.</param> */ public void Scan( ContentScanner.GraphicsState state, IScanner textScanner ) { /* * TODO: I really dislike this solution -- it's a temporary hack until the event-driven * parsing mechanism is implemented... */ /* * TODO: support to vertical writing mode. */ IContentContext context = state.Scanner.ContentContext; float contextHeight = context.Box.Height; Font font = state.Font; float fontSize = state.FontSize; float scale = state.Scale / 100; float scaledFactor = Font.GetScalingFactor(fontSize) * scale; float wordSpace = state.WordSpace * scale; float charSpace = state.CharSpace * scale; Matrix ctm = state.Ctm.Clone(); Matrix tm = state.Tm; if (this is ShowTextToNextLine) { ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this; float?newWordSpace = showTextToNextLine.WordSpace; if (newWordSpace != null) { if (textScanner == null) { state.WordSpace = newWordSpace.Value; } wordSpace = newWordSpace.Value * scale; } float?newCharSpace = showTextToNextLine.CharSpace; if (newCharSpace != null) { if (textScanner == null) { state.CharSpace = newCharSpace.Value; } charSpace = newCharSpace.Value * scale; } tm = state.Tlm.Clone(); tm.Translate(0, state.Lead); } else { tm = state.Tm.Clone(); } foreach (object textElement in Value) { if (textElement is byte[]) // Text string. { string textString = font.Decode((byte[])textElement); foreach (char textChar in textString) { float charWidth = font.GetWidth(textChar) * scaledFactor; if (textScanner != null) { /* * NOTE: The text rendering matrix is recomputed before each glyph is painted * during a text-showing operation. */ Matrix trm = ctm.Clone(); trm.Multiply(tm); float charHeight = font.GetHeight(textChar, fontSize); drawing::RectangleF charBox = new drawing::RectangleF( trm.Elements[4], contextHeight - trm.Elements[5] - font.GetAscent(fontSize) * tm.Elements[3], charWidth * tm.Elements[0], charHeight * tm.Elements[3] ); textScanner.ScanChar(textChar, charBox); } /* * NOTE: After the glyph is painted, the text matrix is updated * according to the glyph displacement and any applicable spacing parameter. */ tm.Translate(charWidth + charSpace + (textChar == ' ' ? wordSpace : 0), 0); } } else // Text position adjustment. { tm.Translate(-Convert.ToSingle(textElement) * scaledFactor, 0); } } if (textScanner == null) { state.Tm = tm; if (this is ShowTextToNextLine) { state.Tlm = tm.Clone(); } } }