public xObjects::XObject ToXObject( Document context ) { xObjects::FormXObject form; { form = new xObjects::FormXObject(context, Box); form.Resources = (Resources)(context.Equals(Document) ? Resources // Same document: reuses the existing resources. : Resources.Clone(context) // Alien document: clones the resources. ); // Body (contents). { IBuffer formBody = form.BaseDataObject.Body; PdfDataObject contentsDataObject = BaseDataObject.Resolve(PdfName.Contents); if (contentsDataObject is PdfStream) { formBody.Append(((PdfStream)contentsDataObject).Body); } else { foreach (PdfDirectObject contentStreamObject in (PdfArray)contentsDataObject) { formBody.Append(((PdfStream)contentStreamObject.Resolve()).Body); } } } } return(form); }
public virtual SKTypeface GetTypeface() { if (typeface != null) { return(typeface); } var fontDescription = GetFontDescription(); if (fontDescription != null) { if (fontDescription.Resolve(PdfName.FontFile) is PdfStream stream) { return(typeface = GetTypeface(fontDescription, stream)); } if (fontDescription.Resolve(PdfName.FontFile2) is PdfStream stream2) { return(typeface = GetTypeface(fontDescription, stream2)); } if (fontDescription.Resolve(PdfName.FontFile3) is PdfStream stream3) { return(typeface = GetTypeface(fontDescription, stream3)); } if (fontDescription.Resolve(PdfName.FontName) is PdfName fontName) { return(typeface = ParseName(fontName.StringValue, fontDescription)); } } else if (BaseDataObject.Resolve(PdfName.BaseFont) is PdfName baseFont) { return(typeface = ParseName(baseFont.StringValue, Dictionary)); } return(null); }
/** * <summary>Gets whether this is the first bead in its thread.</summary> */ public bool IsHead( ) { PdfDictionary thread = (PdfDictionary)BaseDataObject.Resolve(PdfName.T); return(thread != null && BaseObject.Equals(thread[PdfName.F])); }
private object GetEntry <T, TPdf>( PdfName key ) where TPdf : PdfAtomicObject <T> { TPdf entry = (TPdf)BaseDataObject.Resolve(key); return(entry == null ? null : entry.Value); }
protected override PdfDataObject GetDescriptorValue( PdfName key ) { PdfDictionary fontDescriptor = (PdfDictionary)BaseDataObject.Resolve(PdfName.FontDescriptor); return(fontDescriptor != null?fontDescriptor.Resolve(key) : null); }
protected override void OnLoad() { base.OnLoad(); if (BaseDataObject.Resolve(PdfName.Encoding) is PdfDictionary encodingDictionary && encodingDictionary.Values.Count > 0 && encodingDictionary.Resolve(PdfName.Differences) is PdfArray differencesObject) { var fontMapping = (GlyphMapping)null; if (BaseDataObject.Resolve(PdfName.BaseFont) is PdfName pdfName) { var name = Regex.Replace(pdfName.RawValue, @"[\/?:*""><|]+", "", RegexOptions.Compiled); if (GlyphMapping.IsExist(name)) { fontMapping = new GlyphMapping(name); } } byte[] charCodeData = new byte[1]; foreach (PdfDirectObject differenceObject in differencesObject) { if (differenceObject is PdfInteger pdfInteger) // Subsequence initial code. { charCodeData[0] = (byte)(((int)pdfInteger.Value) & 0xFF); } else // Character name. { ByteArray charCode = new ByteArray(charCodeData); string charName = (string)((PdfName)differenceObject).Value; if (charName.Equals(".notdef", StringComparison.Ordinal)) { codes.Remove(charCode); } else { int?code = GlyphMapping.DLFONT.NameToCode(charName) ?? fontMapping?.NameToCode(charName); if (code != null) { codes[charCode] = code.Value; } else { System.Diagnostics.Debug.WriteLine($" {charName}"); } } charCodeData[0]++; } } } }
protected override void OnLoad( ) { LoadEncoding(); // Glyph widths. if (glyphWidths == null) { glyphWidths = new Dictionary <int, int>(); PdfArray glyphWidthObjects = (PdfArray)BaseDataObject.Resolve(PdfName.Widths); if (glyphWidthObjects != null) { ByteArray charCode = new ByteArray( new byte[] { (byte)((PdfInteger)BaseDataObject[PdfName.FirstChar]).IntValue } ); foreach (PdfDirectObject glyphWidthObject in glyphWidthObjects) { int glyphWidth = ((IPdfNumber)glyphWidthObject).IntValue; if (glyphWidth > 0) { int code; if (codes.TryGetValue(charCode, out code)) { // [Zmiana] try { glyphWidths[glyphIndexes[code]] = glyphWidth; } catch (Exception) { } } } charCode.Data[0]++; } } } // Default glyph width. { IPdfNumber widthObject = (IPdfNumber)GetDescriptorValue(PdfName.AvgWidth); if (widthObject != null) { AverageWidth = widthObject.IntValue; } widthObject = (IPdfNumber)GetDescriptorValue(PdfName.MissingWidth); if (widthObject != null) { DefaultWidth = widthObject.IntValue; } } }
public PdfDictionary GetFontDescription() { if (BaseDataObject.Resolve(PdfName.FontDescriptor) is PdfDictionary fontDescription) { return(fontDescription); } if (BaseDataObject.Resolve(PdfName.DescendantFonts) is PdfArray array && array.Resolve(0) is PdfDictionary descendant && descendant.Resolve(PdfName.FontDescriptor) is PdfDictionary descendantDescription) { return(descendantDescription); } return(null); }
public virtual SKTypeface GetTypefaceByName() { var fontDescription = GetFontDescription(); if (fontDescription != null) { return(ParseName(fontDescription.Resolve(PdfName.FontName)?.ToString(), fontDescription)); } else if (BaseDataObject.Resolve(PdfName.BaseFont) is PdfName baseFont) { return(typeface = ParseName(baseFont.StringValue, Dictionary)); } return(null); }
protected override void LoadEncoding( ) { //FIXME: consolidate with Type1Font and TrueTypeFont! // Encoding. if (this.codes == null) { IDictionary <ByteArray, int> codes; PdfDataObject encodingObject = BaseDataObject.Resolve(PdfName.Encoding); if (encodingObject == null) // Native encoding. { codes = GetNativeEncoding(); } else if (encodingObject is PdfName) // Predefined encoding. { codes = Encoding.Get((PdfName)encodingObject).GetCodes(); } else // Custom encoding. { PdfDictionary encodingDictionary = (PdfDictionary)encodingObject; // 1. Base encoding. PdfName baseEncodingName = (PdfName)encodingDictionary[PdfName.BaseEncoding]; if (baseEncodingName == null) // Native base encoding. { codes = GetNativeEncoding(); } else // Predefined base encoding. { codes = Encoding.Get(baseEncodingName).GetCodes(); } // 2. Differences. LoadEncodingDifferences(encodingDictionary, codes); } this.codes = new BiDictionary <ByteArray, int>(codes); } // Glyph indexes. if (glyphIndexes == null) { glyphIndexes = new Dictionary <int, int>(); foreach (KeyValuePair <ByteArray, int> codeEntry in codes) { glyphIndexes[codeEntry.Value] = ConvertUtils.ByteArrayToInt(codeEntry.Key.Data); } } }
/** * <summary>Sets the usage application for the specified factors.</summary> * <param name="event">Situation in which this usage application should be used. May be * <see cref="PdfName.View">View</see>, <see cref="PdfName.Print">Print</see> or <see * cref="PdfName.Export">Export</see>.</param> * <param name="category">Layer usage entry to consider when managing the states of the layer. * </param> * <param name="layer">Layer which should have its state automatically managed based on its usage * information.</param> * <param name="retain">Whether this usage application has to be kept or removed.</param> */ internal void SetUsageApplication( PdfName @event, PdfName category, Layer layer, bool retain ) { bool matched = false; PdfArray usages = BaseDataObject.Resolve <PdfArray>(PdfName.AS); foreach (PdfDirectObject usage in usages) { PdfDictionary usageDictionary = (PdfDictionary)usage; if (usageDictionary[PdfName.Event].Equals(@event) && ((PdfArray)usageDictionary[PdfName.Category]).Contains(category)) { PdfArray usageLayers = usageDictionary.Resolve <PdfArray>(PdfName.OCGs); if (usageLayers.Contains(layer.BaseObject)) { if (!retain) { usageLayers.Remove(layer.BaseObject); } } else { if (retain) { usageLayers.Add(layer.BaseObject); } } matched = true; } } if (!matched && retain) { PdfDictionary usageDictionary = new PdfDictionary(); { usageDictionary[PdfName.Event] = @event; usageDictionary.Resolve <PdfArray>(PdfName.Category).Add(category); usageDictionary.Resolve <PdfArray>(PdfName.OCGs).Add(layer.BaseObject); } usages.Add(usageDictionary); } }
private void SetEntry <T, TPdf>( PdfName key, object value ) where TPdf : PdfAtomicObject <T>, new() { if (value == null) { BaseDataObject.Remove(key); } else { if (!BaseDataObject.ContainsKey(key)) { BaseDataObject[key] = new TPdf(); } ((TPdf)BaseDataObject.Resolve(key)).Value = value; } }
public override void RemoveAt(int index) { int baseIndex = GetBaseIndex(index); IUILayerNode removedItem = base[baseIndex]; base.RemoveAt(baseIndex); if (removedItem is Layer && baseIndex < base.Count) { /* * NOTE: Sublayers MUST be removed as well. */ if (BaseDataObject.Resolve(baseIndex) is PdfArray) { BaseDataObject.RemoveAt(baseIndex); } } }
public xObjects::XObject ToXObject( Document context ) { File contextFile = context.File; xObjects::FormXObject form = new xObjects::FormXObject(context); PdfStream formStream = form.BaseDataObject; // Header. { PdfDictionary formHeader = formStream.Header; // Bounding box. formHeader[PdfName.BBox] = (PdfDirectObject)GetInheritableAttribute(PdfName.MediaBox).Clone(contextFile); // Resources. { PdfDirectObject resourcesObject = GetInheritableAttribute(PdfName.Resources); // Same document? /* NOTE: Try to reuse the resource dictionary whenever possible. */ formHeader[PdfName.Resources] = (context.Equals(Document) ? resourcesObject : (PdfDirectObject)resourcesObject.Clone(contextFile)); } } // Body (contents). { IBuffer formBody = formStream.Body; PdfDataObject contentsDataObject = BaseDataObject.Resolve(PdfName.Contents); if (contentsDataObject is PdfStream) { formBody.Append(((PdfStream)contentsDataObject).Body); } else { foreach (PdfDirectObject contentStreamObject in (PdfArray)contentsDataObject) { formBody.Append(((PdfStream)File.Resolve(contentStreamObject)).Body); } } } return(form); }
protected override void OnLoad( ) { LoadEncoding(); // Glyph widths. if (glyphWidths == null) { glyphWidths = new Dictionary <int, int>(); PdfArray glyphWidthObjects = (PdfArray)BaseDataObject.Resolve(PdfName.Widths); if (glyphWidthObjects != null) { ByteArray charCode = new ByteArray( new byte[] { (byte)((PdfInteger)BaseDataObject[PdfName.FirstChar]).IntValue } ); foreach (PdfDirectObject glyphWidthObject in glyphWidthObjects) { int glyphWidth = ((IPdfNumber)glyphWidthObject).IntValue; if (glyphWidth > 0) { int code; if (codes.TryGetValue(charCode, out code)) { glyphWidths[glyphIndexes[code]] = glyphWidth; } } charCode.Data[0]++; } } } // Default glyph width. { PdfDictionary descriptor = Descriptor; if (descriptor != null) { IPdfNumber defaultGlyphWidthObject = (IPdfNumber)descriptor[PdfName.MissingWidth]; defaultGlyphWidth = (defaultGlyphWidthObject != null ? defaultGlyphWidthObject.IntValue : 0); } } }
/** * <summary>Loads font information from existing PDF font structure.</summary> */ protected void Load( ) { if (BaseDataObject.ContainsKey(PdfName.ToUnicode)) // To-Unicode explicit mapping. { PdfStream toUnicodeStream = (PdfStream)BaseDataObject.Resolve(PdfName.ToUnicode); CMapParser parser = new CMapParser(toUnicodeStream.Body); codes = new BiDictionary <ByteArray, int>(parser.Parse()); symbolic = false; } OnLoad(); // Maximum character code length. foreach (ByteArray charCode in codes.Keys) { if (charCode.Data.Length > charCodeMaxLength) { charCodeMaxLength = charCode.Data.Length; } } // Missing character substitute. if (defaultCode == UndefinedDefaultCode) { ICollection <int> codePoints = CodePoints; if (codePoints.Contains((int)'?')) { DefaultCode = '?'; } else if (codePoints.Contains((int)' ')) { DefaultCode = ' '; } else // PK 2017-03-08 - allow for encoding to fail, which should just result in a "?" or rectangle appearing instead of the correct character { DefaultCode = codePoints.FirstOrDefault(); } } }
/** * <summary>Loads font information from existing PDF font structure.</summary> */ protected void Load( ) { if (BaseDataObject.ContainsKey(PdfName.ToUnicode)) // To-Unicode explicit mapping. { PdfStream toUnicodeStream = (PdfStream)BaseDataObject.Resolve(PdfName.ToUnicode); CMapParser parser = new CMapParser(toUnicodeStream.Body); codes = new BiDictionary <ByteArray, int>(parser.Parse()); symbolic = false; } OnLoad(); // Maximum character code length. foreach (ByteArray charCode in codes.Keys) { if (charCode.Data.Length > charCodeMaxLength) { charCodeMaxLength = charCode.Data.Length; } } }
/** * <summary>Loads font information from existing PDF font structure.</summary> */ protected void Load( ) { if (BaseDataObject.ContainsKey(PdfName.ToUnicode)) // To-Unicode explicit mapping. { PdfStream toUnicodeStream = (PdfStream)BaseDataObject.Resolve(PdfName.ToUnicode); CMapParser parser = new CMapParser(toUnicodeStream.Body); codes = new BiDictionary <ByteArray, int>(parser.Parse()); symbolic = false; } OnLoad(); // Maximum character code length. foreach (ByteArray charCode in codes.Keys) { if (charCode.Data.Length > charCodeMaxLength) { charCodeMaxLength = charCode.Data.Length; } } // Missing character substitute. if (defaultCode == UndefinedDefaultCode) { ICollection <int> codePoints = CodePoints; if (codePoints.Contains((int)'?')) { DefaultCode = '?'; } else if (codePoints.Contains((int)' ')) { DefaultCode = ' '; } else { DefaultCode = codePoints.First(); } } }
protected void LoadEncoding( ) { // Mapping character codes... PdfDataObject encodingObject = BaseDataObject.Resolve(PdfName.Encoding); FlagsEnum flags = Flags; symbolic = (flags & FlagsEnum.Symbolic) != 0; if (this.codes == null) { IDictionary <ByteArray, int> codes; if (encodingObject is PdfDictionary) // Derived encoding. { PdfDictionary encodingDictionary = (PdfDictionary)encodingObject; // Base encoding. codes = GetBaseEncoding((PdfName)encodingDictionary[PdfName.BaseEncoding]); // Differences. PdfArray differencesObject = (PdfArray)encodingDictionary.Resolve(PdfName.Differences); if (differencesObject != null) { /* * NOTE: Each code is the first index in a sequence of character codes to be changed: the * first character name after a code associates that character to that code; subsequent * names replace consecutive code indices until the next code appears in the array. */ byte[] charCodeData = new byte[1]; foreach (PdfDirectObject differenceObject in differencesObject) { if (differenceObject is PdfInteger) // Subsequence initial code. { charCodeData[0] = (byte)(((int)((PdfInteger)differenceObject).Value) & 0xFF); } else // Character name. { ByteArray charCode = new ByteArray(charCodeData); string charName = (string)((PdfName)differenceObject).Value; if (charName.Equals(".notdef")) { codes.Remove(charCode); } else { int?code = GlyphMapping.NameToCode(charName); codes[charCode] = (code ?? charCodeData[0]); } charCodeData[0]++; } } } } else // Predefined encoding. { codes = GetBaseEncoding((PdfName)encodingObject); } this.codes = new BiDictionary <ByteArray, int>(codes); } // Purging unused character codes... { PdfArray glyphWidthObjects = (PdfArray)BaseDataObject.Resolve(PdfName.Widths); if (glyphWidthObjects != null) { ByteArray charCode = new ByteArray(new byte[] { (byte)((PdfInteger)BaseDataObject[PdfName.FirstChar]).IntValue }); foreach (PdfDirectObject glyphWidthObject in glyphWidthObjects) { // PK 2017-03-08 - Changed type from PdfInteger to IPdfNumber to avoid ClassCastException and allow for more granular font sizes if (((IPdfNumber)glyphWidthObject).IntValue == 0) { codes.Remove(charCode); } charCode.Data[0]++; } } } // Mapping glyph indices... glyphIndexes = new Dictionary <int, int>(); foreach (KeyValuePair <ByteArray, int> code in codes) { glyphIndexes[code.Value] = (int)code.Key.Data[0] & 0xFF; } }
protected void LoadEncoding( ) { PdfDataObject encodingObject = BaseDataObject.Resolve(PdfName.Encoding); // CMap [PDF:1.6:5.6.4]. IDictionary <ByteArray, int> cmap = CMap.Get(encodingObject); // 1. Unicode. if (codes == null) { codes = new BiDictionary <ByteArray, int>(); if (encodingObject is PdfName && !(encodingObject.Equals(PdfName.IdentityH) || encodingObject.Equals(PdfName.IdentityV))) { /* * NOTE: According to [PDF:1.6:5.9.1], the fallback method to retrieve * the character-code-to-Unicode mapping implies getting the UCS2 CMap * (Unicode value to CID) corresponding to the font's one (character code to CID); * CIDs are the bridge from character codes to Unicode values. */ BiDictionary <ByteArray, int> ucs2CMap; { PdfDictionary cidSystemInfo = (PdfDictionary)CIDFontDictionary.Resolve(PdfName.CIDSystemInfo); String registry = (String)((PdfTextString)cidSystemInfo[PdfName.Registry]).Value; String ordering = (String)((PdfTextString)cidSystemInfo[PdfName.Ordering]).Value; String ucs2CMapName = registry + "-" + ordering + "-" + "UCS2"; ucs2CMap = new BiDictionary <ByteArray, int>(CMap.Get(ucs2CMapName)); } if (ucs2CMap.Count > 0) { foreach (KeyValuePair <ByteArray, int> cmapEntry in cmap) { codes[cmapEntry.Key] = ConvertUtils.ByteArrayToInt(ucs2CMap.GetKey(cmapEntry.Value).Data); } } } if (codes.Count == 0) { /* * NOTE: In case no clue is available to determine the Unicode resolution map, * the font is considered symbolic and an identity map is synthesized instead. */ symbolic = true; foreach (KeyValuePair <ByteArray, int> cmapEntry in cmap) { codes[cmapEntry.Key] = ConvertUtils.ByteArrayToInt(cmapEntry.Key.Data); } } } // 2. Glyph indexes. /* * TODO: gids map for glyph indexes as glyphIndexes is used to map cids!!! */ // Character-code-to-CID mapping [PDF:1.6:5.6.4,5]. glyphIndexes = new Dictionary <int, int>(); foreach (KeyValuePair <ByteArray, int> cmapEntry in cmap) { if (!codes.ContainsKey(cmapEntry.Key)) { continue; } glyphIndexes[codes[cmapEntry.Key]] = cmapEntry.Value; } }
protected override void LoadEncoding( ) { OpenFontParser parser; { PdfDictionary descriptor = Descriptor; if(descriptor.ContainsKey(PdfName.FontFile2)) // Embedded TrueType font file (without 'glyf' table). { PdfStream fontFileStream = (PdfStream)descriptor.Resolve(PdfName.FontFile2); parser = new OpenFontParser(fontFileStream.Body); } else if(descriptor.ContainsKey(PdfName.FontFile3)) { PdfStream fontFileStream = (PdfStream)descriptor.Resolve(PdfName.FontFile3); PdfName fontFileSubtype = (PdfName)fontFileStream.Header[PdfName.Subtype]; if(fontFileSubtype.Equals(PdfName.OpenType)) // Embedded OpenFont/TrueType font file (with 'glyf' table). {parser = new OpenFontParser(fontFileStream.Body);} else // Unknown. throw new NotSupportedException("Unknown embedded font file format: " + fontFileSubtype); } else {parser = null;} } if(parser != null) // Embedded font file. { // Glyph indexes. glyphIndexes = parser.GlyphIndexes; if(codes != null && parser.Metrics.IsCustomEncoding) { /* NOTE: In case of symbolic font, glyph indices are natively mapped to character codes, so they must be remapped to Unicode whenever possible (i.e. when ToUnicode stream is available). */ Dictionary<int,int> unicodeGlyphIndexes = new Dictionary<int,int>(); foreach(KeyValuePair<int,int> glyphIndexEntry in glyphIndexes) { int code; if(!codes.TryGetValue(new ByteArray(new byte[]{(byte)(int)glyphIndexEntry.Key}),out code)) continue; unicodeGlyphIndexes[code] = glyphIndexEntry.Value; } glyphIndexes = unicodeGlyphIndexes; } } PdfDataObject encodingObject = BaseDataObject.Resolve(PdfName.Encoding); FlagsEnum flags = Flags; if((flags & FlagsEnum.Symbolic) != 0 || ((flags & FlagsEnum.Nonsymbolic) == 0 && encodingObject == null)) // Symbolic. { symbolic = true; if(glyphIndexes == null) { /* NOTE: In case no font file is available, we have to synthesize its metrics from existing entries. */ glyphIndexes = new Dictionary<int,int>(); PdfArray glyphWidthObjects = (PdfArray)BaseDataObject.Resolve(PdfName.Widths); if(glyphWidthObjects != null) { int code = ((PdfInteger)BaseDataObject[PdfName.FirstChar]).RawValue; foreach(PdfDirectObject glyphWidthObject in glyphWidthObjects) { if(((PdfInteger)glyphWidthObject).RawValue > 0) {glyphIndexes[code] = code;} code++; } } } if(this.codes == null) { Dictionary<ByteArray,int> codes = new Dictionary<ByteArray,int>(); foreach(KeyValuePair<int,int> glyphIndexEntry in glyphIndexes) { if(glyphIndexEntry.Value > 0) { int glyphCharCode = glyphIndexEntry.Key; byte[] charCode = new byte[]{(byte)glyphCharCode}; codes[new ByteArray(charCode)] = glyphCharCode; } } this.codes = new BiDictionary<ByteArray,int>(codes); } } else // Nonsymbolic. { symbolic = false; if(this.codes == null) { Dictionary<ByteArray,int> codes; if(encodingObject == null) // Default encoding. {codes = Encoding.Get(PdfName.StandardEncoding).GetCodes();} else if(encodingObject is PdfName) // Predefined encoding. {codes = Encoding.Get((PdfName)encodingObject).GetCodes();} else // Custom encoding. { PdfDictionary encodingDictionary = (PdfDictionary)encodingObject; // 1. Base encoding. PdfName baseEncodingName = (PdfName)encodingDictionary[PdfName.BaseEncoding]; if(baseEncodingName == null) // Default base encoding. {codes = Encoding.Get(PdfName.StandardEncoding).GetCodes();} else // Predefined base encoding. {codes = Encoding.Get(baseEncodingName).GetCodes();} // 2. Differences. LoadEncodingDifferences(encodingDictionary, codes); } this.codes = new BiDictionary<ByteArray,int>(codes); } if(glyphIndexes == null) { /* NOTE: In case no font file is available, we have to synthesize its metrics from existing entries. */ glyphIndexes = new Dictionary<int,int>(); PdfArray glyphWidthObjects = (PdfArray)BaseDataObject.Resolve(PdfName.Widths); if(glyphWidthObjects != null) { ByteArray charCode = new ByteArray( new byte[] {(byte)(int)((PdfInteger)BaseDataObject[PdfName.FirstChar]).RawValue} ); foreach(PdfDirectObject glyphWidthObject in glyphWidthObjects) { if(((PdfInteger)glyphWidthObject).RawValue > 0) { int code; if(codes.TryGetValue(charCode,out code)) {glyphIndexes[code] = (int)charCode.Data[0];} } charCode.Data[0]++; } } } } }
private DeviceColor GetColor( PdfName key ) { return(DeviceColor.Get((PdfArray)BaseDataObject.Resolve(key))); }