Skip to content

Commit 19c5404

Browse files
authored
Merge branch 'release/26.3.0' into examples/9f94b342-parse-pdf
2 parents 000a9de + b9a1c77 commit 19c5404

2,289 files changed

Lines changed: 85003 additions & 65815 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/validate-pr.yml

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,76 @@ jobs:
6060
dotnet restore .build-template/ --verbosity quiet
6161
echo "Template ready with Aspose.PDF ${{ steps.version.outputs.nuget_version }}"
6262
63-
# ── Find .cs files changed in this PR ──
64-
# Use merge-base (three-dot diff) so we only see files the PR itself
65-
# changed — not files brought in from the base branch when the PR is
66-
# updated via "Update branch" (which merges base into head).
63+
# ── Find .cs files to validate ──
64+
# We apply up to three filters to avoid re-running CI on files that
65+
# didn't actually change:
66+
# 1. PR-owned filter (merge-base): only files the PR itself added
67+
# or modified vs the base branch — skips files that came in via
68+
# "Update branch" merges from the base.
69+
# 2. Incremental filter: if HEAD is a merge commit (i.e. the user
70+
# clicked "Update branch"), only validate files that changed in
71+
# the merge itself (HEAD^1..HEAD). If the merge introduced no
72+
# new changes to PR-owned .cs files, skip the build entirely.
73+
# 3. Environment tripwire: if the merge touched csproj, workflow,
74+
# index.json, or global.json, force a full revalidation because
75+
# the build environment may have changed.
6776
- name: Get changed .cs files
6877
id: changed
6978
run: |
7079
BASE="${{ github.event.pull_request.base.sha }}"
7180
HEAD="${{ github.event.pull_request.head.sha }}"
7281
MERGE_BASE=$(git merge-base "$BASE" "$HEAD")
73-
echo "PR base: $BASE"
74-
echo "PR head: $HEAD"
82+
echo "PR base: $BASE"
83+
echo "PR head: $HEAD"
7584
echo "Merge base: $MERGE_BASE"
76-
FILES=$(git diff --name-only "$MERGE_BASE" "$HEAD" -- '*.cs' | grep '\.cs$' || true)
85+
86+
# ── Filter 1: files the PR itself changed ──
87+
PR_FILES=$(git diff --name-only "$MERGE_BASE" "$HEAD" -- '*.cs' | grep '\.cs$' || true)
88+
89+
# ── Is HEAD a merge commit (i.e. "Update branch" was clicked)? ──
90+
IS_MERGE=false
91+
if git rev-parse --verify HEAD^2 >/dev/null 2>&1; then
92+
IS_MERGE=true
93+
echo "HEAD is a merge commit (Update branch was used)"
94+
fi
95+
96+
# ── Filter 3: environment tripwire (forces full revalidate) ──
97+
FORCE_FULL=false
98+
if [ "$IS_MERGE" = "true" ]; then
99+
ENV_DIFF=$(git diff --name-only HEAD^1 HEAD -- \
100+
'index.json' \
101+
'.github/workflows/validate-pr.yml' \
102+
'**/*.csproj' \
103+
'global.json' 2>/dev/null || true)
104+
if [ -n "$ENV_DIFF" ]; then
105+
FORCE_FULL=true
106+
echo "Environment changed in merge — forcing full revalidation:"
107+
echo "$ENV_DIFF"
108+
fi
109+
fi
110+
111+
# ── Filter 2: incremental (only files touched by the merge) ──
112+
if [ "$IS_MERGE" = "true" ] && [ "$FORCE_FULL" = "false" ]; then
113+
RECENT_FILES=$(git diff --name-only HEAD^1 HEAD -- '*.cs' | grep '\.cs$' || true)
114+
if [ -z "$RECENT_FILES" ]; then
115+
echo "Merge did not touch any .cs files — skipping validation."
116+
echo "has_cs=false" >> "$GITHUB_OUTPUT"
117+
exit 0
118+
fi
119+
# Intersect PR-owned files with files touched by the merge
120+
FILES=$(comm -12 \
121+
<(printf '%s\n' "$PR_FILES" | sort -u) \
122+
<(printf '%s\n' "$RECENT_FILES" | sort -u))
123+
if [ -z "$FILES" ]; then
124+
echo "Merge touched .cs files but none were PR-owned — skipping validation."
125+
echo "has_cs=false" >> "$GITHUB_OUTPUT"
126+
exit 0
127+
fi
128+
echo "Incremental mode: validating only files touched by the merge"
129+
else
130+
FILES="$PR_FILES"
131+
fi
132+
77133
if [ -z "$FILES" ]; then
78134
echo "No .cs files changed in this PR"
79135
echo "has_cs=false" >> "$GITHUB_OUTPUT"

facades-annotations/add-annotation-verbose-logging.cs

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.IO;
3+
using Aspose.Pdf;
4+
using Aspose.Pdf.Facades;
5+
using Aspose.Pdf.Annotations;
6+
7+
class Program
8+
{
9+
static void Main()
10+
{
11+
const string inputPath = "input.pdf";
12+
const string outputPath = "output_modified.pdf";
13+
14+
if (!File.Exists(inputPath))
15+
{
16+
Console.Error.WriteLine($"File not found: {inputPath}");
17+
return;
18+
}
19+
20+
// Load the PDF document (lifecycle rule: use using for deterministic disposal)
21+
using (Document doc = new Document(inputPath))
22+
{
23+
// Prepare a concrete annotation (TextAnnotation) using the (Page, Rectangle) constructor
24+
// This is required because TextAnnotation does not expose a public parameter‑less constructor.
25+
Page firstPage = doc.Pages[1];
26+
Aspose.Pdf.Rectangle rect = new Aspose.Pdf.Rectangle(100, 500, 300, 550);
27+
TextAnnotation customAnnot = new TextAnnotation(firstPage, rect)
28+
{
29+
Title = "Custom Flag",
30+
Contents = "Annotation with custom flags",
31+
Color = Aspose.Pdf.Color.Yellow,
32+
// Combine desired flags (e.g., Print and Locked)
33+
Flags = AnnotationFlags.Print | AnnotationFlags.Locked
34+
};
35+
36+
// Initialize the annotation editor facade
37+
using (PdfAnnotationEditor editor = new PdfAnnotationEditor())
38+
{
39+
// Bind the document to the editor
40+
editor.BindPdf(doc);
41+
42+
// Modify annotations on the desired page range (1‑based indexing)
43+
int startPage = 1;
44+
int endPage = doc.Pages.Count;
45+
editor.ModifyAnnotations(startPage, endPage, customAnnot);
46+
47+
// Save the modified PDF (lifecycle rule: use provided Save method)
48+
editor.Save(outputPath);
49+
}
50+
}
51+
52+
Console.WriteLine($"Modified PDF saved to '{outputPath}'.");
53+
}
54+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System;
2+
using System.IO;
3+
using Aspose.Pdf;
4+
using Aspose.Pdf.Annotations;
5+
using Aspose.Pdf.Facades;
6+
7+
class Program
8+
{
9+
static void Main()
10+
{
11+
const string inputPath = "input.pdf";
12+
const string outputPath = "output_custom_meta.pdf";
13+
14+
if (!File.Exists(inputPath))
15+
{
16+
Console.Error.WriteLine($"File not found: {inputPath}");
17+
return;
18+
}
19+
20+
// Load the PDF document
21+
using (Document doc = new Document(inputPath))
22+
{
23+
// -----------------------------------------------------------------
24+
// 1. Add a sample annotation (TextAnnotation) to demonstrate custom
25+
// metadata injection.
26+
// -----------------------------------------------------------------
27+
Page page = doc.Pages[1];
28+
// Fully qualified rectangle to avoid ambiguity with System.Drawing
29+
Aspose.Pdf.Rectangle rect = new Aspose.Pdf.Rectangle(100, 500, 300, 550);
30+
TextAnnotation txtAnn = new TextAnnotation(page, rect)
31+
{
32+
Title = "Sample Note",
33+
Contents = "This annotation will carry custom metadata.",
34+
Color = Aspose.Pdf.Color.Yellow,
35+
Open = true
36+
};
37+
page.Annotations.Add(txtAnn);
38+
39+
// -----------------------------------------------------------------
40+
// 2. Use PdfAnnotationEditor (Facades API) to modify the annotation.
41+
// Since the Facades API only supports a limited set of fields,
42+
// we embed custom key/value pairs into the 'Subject' property as
43+
// a JSON string. This effectively extends the annotation dictionary.
44+
// -----------------------------------------------------------------
45+
using (PdfAnnotationEditor editor = new PdfAnnotationEditor())
46+
{
47+
// Bind the same document instance to the editor
48+
editor.BindPdf(doc);
49+
50+
// Prepare custom metadata (key/value) as JSON
51+
string customMetaJson = "{\"CustomKey\":\"CustomValue\",\"Author\":\"John Doe\"}";
52+
53+
// Modify annotations on page 1 (page indexes are 1‑based)
54+
// Parameters: startPage, endPage, Annotation object with modified fields
55+
// Only the fields listed in ModifyAnnotations are respected.
56+
// We set the Subject field to carry our custom metadata.
57+
txtAnn.Subject = customMetaJson; // Subject will hold the JSON payload
58+
59+
// Apply the modification
60+
editor.ModifyAnnotations(1, 1, txtAnn);
61+
}
62+
63+
// -----------------------------------------------------------------
64+
// 3. (Optional) Add a document‑level custom property using PdfFileInfo.
65+
// This demonstrates how to store additional metadata at the file level.
66+
// -----------------------------------------------------------------
67+
using (PdfFileInfo fileInfo = new PdfFileInfo())
68+
{
69+
fileInfo.BindPdf(doc);
70+
fileInfo.SetMetaInfo("DocumentCustomKey", "DocumentCustomValue");
71+
// No need to call SaveNewInfo; the changes are persisted when the
72+
// underlying Document is saved.
73+
}
74+
75+
// Save the modified PDF
76+
doc.Save(outputPath);
77+
}
78+
79+
Console.WriteLine($"PDF saved with custom annotation metadata to '{outputPath}'.");
80+
}
81+
}

0 commit comments

Comments
 (0)