private ReturnType CopyPageMarks(PdfDictionary parentTree, PdfNumber arrayNumber, int newArrayNumber) { PdfArray pages = (PdfArray)GetDirectObject(parentTree.Get(PdfName.NUMS)); if (pages == null) { PdfArray kids = (PdfArray)GetDirectObject(parentTree.Get(PdfName.KIDS)); if (kids == null) { return(ReturnType.NOTFOUND); } int cur = kids.Size / 2; int begin = 0; while (true) { PdfDictionary kidTree = (PdfDictionary)GetDirectObject(kids.GetPdfObject(cur + begin)); switch (CopyPageMarks(kidTree, arrayNumber, newArrayNumber)) { case ReturnType.FOUND: return(ReturnType.FOUND); case ReturnType.ABOVE: begin += cur; cur /= 2; if (cur == 0) { cur = 1; } if (cur + begin == kids.Size) { return(ReturnType.ABOVE); } break; case ReturnType.BELOW: if (cur + begin == 0) { return(ReturnType.BELOW); } if (cur == 0) { return(ReturnType.NOTFOUND); } cur /= 2; break; default: return(ReturnType.NOTFOUND); } } } else { if (pages.Size == 0) { return(ReturnType.NOTFOUND); } return(FindAndCopyMarks(pages, arrayNumber.IntValue, newArrayNumber)); } }
private void NodeProcess(PdfDictionary struc, PdfIndirectReference reference) { PdfObject obj = struc.Get(PdfName.K); if (obj != null && obj.IsArray()) { PdfArray ar = (PdfArray)obj; for (int k = 0; k < ar.Size; ++k) { PdfDictionary dictionary = ar.GetAsDict(k); if (dictionary == null) { continue; } if (!PdfName.STRUCTELEM.Equals(dictionary.Get(PdfName.TYPE))) { continue; } if (ar.GetPdfObject(k) is PdfStructureElement) { PdfStructureElement e = (PdfStructureElement)dictionary; ar.Set(k, e.Reference); NodeProcess(e, e.Reference); } } } if (reference != null) { writer.AddToBody(struc, reference); } }
private static PdfArray GetDirectArray(PdfArray input) { PdfArray output = new PdfArray(); for (int i = 0; i < input.Size; ++i) { PdfObject value = GetDirectObject(input.GetPdfObject(i)); if (value == null) { continue; } if (value.IsArray()) { output.Add(GetDirectArray((PdfArray)value)); } else if (value.IsDictionary()) { output.Add(GetDirectDict((PdfDictionary)value)); } else { output.Add(value); } } return(output); }
private static void IterateItems(PdfDictionary dic, Dictionary <int, PdfObject> items) { PdfArray nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.NUMS)); if (nn != null) { for (int k = 0; k < nn.Size; ++k) { PdfNumber s = (PdfNumber)PdfReader.GetPdfObjectRelease(nn.GetPdfObject(k++)); items[s.IntValue] = nn.GetPdfObject(k); } } else if ((nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.KIDS))) != null) { for (int k = 0; k < nn.Size; ++k) { PdfDictionary kid = (PdfDictionary)PdfReader.GetPdfObjectRelease(nn.GetPdfObject(k)); IterateItems(kid, items); } } }
private static PdfString IterateItems(PdfDictionary dic, Dictionary <string, PdfObject> items, PdfString leftOverString) { PdfArray nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.NAMES)); if (nn != null) { for (int k = 0; k < nn.Size; ++k) { PdfString s; if (leftOverString == null) { s = (PdfString)PdfReader.GetPdfObjectRelease(nn.GetPdfObject(k++)); } else { // this is the leftover string from the previous loop s = leftOverString; leftOverString = null; } if (k < nn.Size) // could have a mistake int the pdf file { items[PdfEncodings.ConvertToString(s.GetBytes(), null)] = nn.GetPdfObject(k); } else { return(s); } } } else if ((nn = (PdfArray)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.KIDS))) != null) { for (int k = 0; k < nn.Size; ++k) { PdfDictionary kid = (PdfDictionary)PdfReader.GetPdfObjectRelease(nn.GetPdfObject(k)); leftOverString = IterateItems(kid, items, leftOverString); } } return(null); }
internal void BuildTree() { CreateNumTree(); PdfDictionary dicTree = PdfNumberTree.WriteTree(numTree, writer); if (dicTree != null) { Put(PdfName.PARENTTREE, writer.AddToBody(dicTree).IndirectReference); } if (classMap != null && classes.Count > 0) { foreach (KeyValuePair <PdfName, PdfObject> entry in classes) { PdfObject value = entry.Value; if (value.IsDictionary()) { classMap.Put(entry.Key, writer.AddToBody(value).IndirectReference); } else if (value.IsArray()) { PdfArray newArray = new PdfArray(); PdfArray array = (PdfArray)value; for (int i = 0; i < array.Size; ++i) { if (array.GetPdfObject(i).IsDictionary()) { newArray.Add(writer.AddToBody(array.GetAsDict(i)).IndirectReference); } } classMap.Put(entry.Key, newArray); } } Put(PdfName.CLASSMAP, writer.AddToBody(classMap).IndirectReference); } if (idTreeMap != null && idTreeMap.Count > 0) { PdfDictionary dic = PdfNameTree.WriteTree(idTreeMap, writer); this.Put(PdfName.IDTREE, dic); } NodeProcess(this, reference); }
/** Normalizes a <CODE>Rectangle</CODE> so that llx and lly are smaller than urx and ury. * @param box the original rectangle * @return a normalized <CODE>Rectangle</CODE> */ public static Rectangle GetNormalizedRectangle(PdfArray box) { float llx = ((PdfNumber)GetPdfObjectRelease(box.GetPdfObject(0))).FloatValue; float lly = ((PdfNumber)GetPdfObjectRelease(box.GetPdfObject(1))).FloatValue; float urx = ((PdfNumber)GetPdfObjectRelease(box.GetPdfObject(2))).FloatValue; float ury = ((PdfNumber)GetPdfObjectRelease(box.GetPdfObject(3))).FloatValue; return new Rectangle(Math.Min(llx, urx), Math.Min(lly, ury), Math.Max(llx, urx), Math.Max(lly, ury)); }
internal void AddClass(PdfObject obj) { obj = GetDirectObject(obj); if (obj.IsDictionary()) { PdfObject curClass = ((PdfDictionary)obj).Get(PdfName.C); if (curClass == null) { return; } if (curClass.IsArray()) { PdfArray array = (PdfArray)curClass; for (int i = 0; i < array.Size; ++i) { AddClass(array.GetPdfObject(i)); } } else if (curClass.IsName()) { AddClass(curClass); } } else if (obj.IsName()) { PdfName name = (PdfName)obj; if (sourceClassMap == null) { obj = GetDirectObject(structTreeRoot.Get(PdfName.CLASSMAP)); if (obj == null || !obj.IsDictionary()) { return; } sourceClassMap = (PdfDictionary)obj; } obj = GetDirectObject(sourceClassMap.Get(name)); if (obj == null) { return; } PdfObject put = structureTreeRoot.GetMappedClass(name); if (put != null) { if (!CompareObjects(put, obj)) { throw new BadPdfFormatException(MessageLocalization.GetComposedMessage("conflict.in.classmap", name)); } } else { if (obj.IsDictionary()) { structureTreeRoot.MapClass(name, GetDirectDict((PdfDictionary)obj)); } else if (obj.IsArray()) { structureTreeRoot.MapClass(name, GetDirectArray((PdfArray)obj)); } } } }
public static bool CompareObjects(PdfObject value1, PdfObject value2) { value2 = GetDirectObject(value2); if (value2 == null) { return(false); } if (value1.Type != value2.Type) { return(false); } if (value1.IsBoolean()) { if (value1 == value2) { return(true); } if (value2 is PdfBoolean) { return(((PdfBoolean)value1).BooleanValue == ((PdfBoolean)value2).BooleanValue); } return(false); } else if (value1.IsName()) { return(value1.Equals(value2)); } else if (value1.IsNumber()) { if (value1 == value2) { return(true); } if (value2 is PdfNumber) { return(((PdfNumber)value1).DoubleValue == ((PdfNumber)value2).DoubleValue); } return(false); } else if (value1.IsNull()) { if (value1 == value2) { return(true); } if (value2 is PdfNull) { return(true); } return(false); } else if (value1.IsString()) { if (value1 == value2) { return(true); } if (value2 is PdfString) { return((value2 == null && value1.ToString() == null) || value1.ToString() == value2.ToString()); } return(false); } if (value1.IsArray()) { PdfArray array1 = (PdfArray)value1; PdfArray array2 = (PdfArray)value2; if (array1.Size != array2.Size) { return(false); } for (int i = 0; i < array1.Size; ++i) { if (!CompareObjects(array1.GetPdfObject(i), array2.GetPdfObject(i))) { return(false); } } return(true); } if (value1.IsDictionary()) { PdfDictionary first = (PdfDictionary)value1; PdfDictionary second = (PdfDictionary)value2; if (first.Size != second.Size) { return(false); } foreach (PdfName name in first.hashMap.Keys) { if (!CompareObjects(first.Get(name), second.Get(name))) { return(false); } } return(true); } return(false); }
private ReturnType FindAndCopyMarks(PdfArray pages, int arrayNumber, int newArrayNumber) { if (pages.GetAsNumber(0).IntValue > arrayNumber) { return(ReturnType.BELOW); } if (pages.GetAsNumber(pages.Size - 2).IntValue < arrayNumber) { return(ReturnType.ABOVE); } int cur = pages.Size / 4; int begin = 0; int curNumber; while (true) { curNumber = pages.GetAsNumber((begin + cur) * 2).IntValue; if (curNumber == arrayNumber) { PdfObject obj = pages.GetPdfObject((begin + cur) * 2 + 1); PdfObject obj1 = obj; while (obj.IsIndirect()) { obj = PdfReader.GetPdfObjectRelease(obj); } //invalid Nums if (obj.IsArray()) { PdfObject firstNotNullKid = null; foreach (PdfObject numObj in (PdfArray)obj) { if (numObj.IsNull()) { if (nullReference == null) { nullReference = writer.AddToBody(new PdfNull()).IndirectReference; } structureTreeRoot.SetPageMark(newArrayNumber, nullReference); } else { PdfObject res = writer.CopyObject(numObj, true, false); if (firstNotNullKid == null) { firstNotNullKid = res; } structureTreeRoot.SetPageMark(newArrayNumber, (PdfIndirectReference)res); } } AttachStructTreeRootKids(firstNotNullKid); } else if (obj.IsDictionary()) { PdfDictionary k = GetKDict((PdfDictionary)obj); if (k == null) { return(ReturnType.NOTFOUND); } PdfObject res = writer.CopyObject(obj1, true, false); structureTreeRoot.SetAnnotationMark(newArrayNumber, (PdfIndirectReference)res); } else { return(ReturnType.NOTFOUND); } return(ReturnType.FOUND); } if (curNumber < arrayNumber) { begin += cur; cur /= 2; if (cur == 0) { cur = 1; } if (cur + begin == pages.Size) { return(ReturnType.NOTFOUND); } continue; } if (cur + begin == 0) { return(ReturnType.BELOW); } if (cur == 0) { return(ReturnType.NOTFOUND); } cur /= 2; } }
/** * Example. * TJ = [(h) 3 4 (q) 7 (w) (e)] * Result = {0:0, 1:7, 2:7, 3:0, 4:0} * * @return Map whose key is an ordinal number of the string in the TJ array and value * is the position adjustment. */ private IDictionary<int, float> StructureTJarray(PdfArray array) { IDictionary<int, float> structuredTJoperands = new Dictionary<int, float>(); if (array.Size == 0) { return structuredTJoperands; } int previousStrNum = 0; structuredTJoperands.Add(previousStrNum, 0f); for (int i = 0; i < array.Size; ++i) { PdfObject currentObj = array.GetPdfObject(i); if (currentObj is PdfString && ((PdfString) currentObj).ToUnicodeString().Length > 0) { ++previousStrNum; structuredTJoperands.Add(previousStrNum, 0f); } else { float oldOffset = structuredTJoperands[previousStrNum]; structuredTJoperands[previousStrNum] = oldOffset + ((PdfNumber) currentObj).FloatValue; } } return structuredTJoperands; }
private static PdfArray GetDirectArray(PdfArray input) { PdfArray output = new PdfArray(); for (int i = 0; i < input.Size; ++i) { PdfObject value = GetDirectObject(input.GetPdfObject(i)); if (value == null) continue; if (value.IsArray()) { output.Add(GetDirectArray((PdfArray)value)); } else if (value.IsDictionary()) { output.Add(GetDirectDict((PdfDictionary)value)); } else { output.Add(value); } } return output; }
private ReturnType FindAndCopyMarks(PdfArray pages, int arrayNumber, int newArrayNumber){ if (pages.GetAsNumber(0).IntValue > arrayNumber) return ReturnType.BELOW; if (pages.GetAsNumber(pages.Size - 2).IntValue < arrayNumber) return ReturnType.ABOVE; int cur = pages.Size/4; int begin = 0; int curNumber; while (true) { curNumber = pages.GetAsNumber((begin + cur)*2).IntValue; if (curNumber == arrayNumber) { PdfObject obj = pages.GetPdfObject((begin + cur)*2 + 1); PdfObject obj1 = obj; while (obj.IsIndirect()) obj = PdfReader.GetPdfObjectRelease(obj); //invalid Nums if (obj.IsArray()) { PdfObject firstNotNullKid = null; foreach (PdfObject numObj in (PdfArray) obj) { if (numObj.IsNull()) { if (nullReference == null) nullReference = writer.AddToBody(new PdfNull()).IndirectReference; structureTreeRoot.SetPageMark(newArrayNumber, nullReference); } else { PdfObject res = writer.CopyObject(numObj, true, false); if (firstNotNullKid == null) firstNotNullKid = res; structureTreeRoot.SetPageMark(newArrayNumber, (PdfIndirectReference) res); } } AttachStructTreeRootKids(firstNotNullKid); } else if (obj.IsDictionary()) { PdfDictionary k = GetKDict((PdfDictionary) obj); if (k == null) return ReturnType.NOTFOUND; PdfObject res = writer.CopyObject(obj1, true, false); structureTreeRoot.SetAnnotationMark(newArrayNumber, (PdfIndirectReference) res); } else { return ReturnType.NOTFOUND; } return ReturnType.FOUND; } if (curNumber < arrayNumber) { begin += cur; cur /= 2; if (cur == 0) cur = 1; if (cur + begin == pages.Size) return ReturnType.NOTFOUND; continue; } if (cur + begin == 0) return ReturnType.BELOW; if (cur == 0) return ReturnType.NOTFOUND; cur /= 2; } }
private void RemoveInactiveReferences(PdfArray array, HashSet2<RefKey> activeKeys) { for (int i = 0; i < array.Size; ++i) { PdfObject obj = array.GetPdfObject(i); if ((obj.Type == 0 && !activeKeys.Contains(new RefKey((PdfIndirectReference)obj))) || (obj.IsDictionary() && ContainsInactivePg((PdfDictionary)obj, activeKeys))) array.Remove(i--); } }