Rect やら BBox やら Matrix やら出てきて、どれをどうするのか、良く分かりません。
得られた知見:
- 外観辞書のXObjectの原点は、左下(0,0)原点で描いた方が後で管理しやすい。
- 掛ける物。
- Matrix の行列
- Rectに合うように、BBoxの幅高さを拡大縮小する行列
- Rect のオフセットと、BBox のオフセットを足す行列
- 外観辞書のXObjectは、同じスタンプを押す等で、使いまわしされます。
[ a b c d e f ]↑に対して、↓のようになります。
| a b | | c d | | e f |
| a b |
| x y 1 | * | c d |
| e f |
class AltPdfCopy : PdfCopy {
public AltPdfCopy(Document document, Stream os)
: base(document, os) {
}
protected override PdfDictionary CopyDictionary(PdfDictionary __inp, bool keepStruct, bool directRootKids) {
var newd = base.CopyDictionary(__inp, keepStruct, directRootKids);
...
return newd;
}
}
protected override PdfDictionary CopyDictionary(PdfDictionary __inp, bool keepStruct, bool directRootKids) {
var newd = base.CopyDictionary(__inp, keepStruct, directRootKids);
if (newd.GetAsName(PdfName.TYPE) == PdfName.FONTDESCRIPTOR) {
PdfName FontName = newd.GetAsName(PdfName.FONTNAME);
String a = enc.GetString(FontName.GetBytes());
if (Regex.IsMatch(a, "/[A-Z]{6}\\+")) {
newd.Put(PdfName.FONTNAME, new PdfName(enc.GetBytes("/" + a.Substring(1 + 6 + 1))));
IsMod |= true;
}
}
...
}
/// <summary>
/// CreateStampAnnotation
/// </summary>
/// <remarks>
/// How to compute width and height in pt.:
///
/// ```cs
/// var w = image.Width * 72f / image.DpiX;
/// var h = image.Height * 72f / image.DpiY;
/// ```
///
/// How to use:
///
/// ```cs
/// pdfStamper.AddAnnotation(CreateStampAnnotation(...), 1);
/// ```
/// </remarks>
/// <param name="writer">pdfStamper.Writer or such.</param>
/// <param name="annotContents">The body part of annotation tooltip.</param>
/// <param name="stampHintName">Such as "Approved" suitable for file name.</param>
/// <param name="stampAuthor">The bolded headline part of annotation tooltip suitable for author or title.</param>
/// <param name="stampTitle">The invisible title can be confirmed at annotation property.</param>
public static PdfAnnotation CreateStampAnnotation(
PdfWriter writer,
string annotContents,
string stampHintName,
string stampAuthor,
string stampTitle,
iTextSharp.text.Image image,
iTextSharp.text.Rectangle rect,
int annotFlags = PdfAnnotation.FLAGS_PRINT
)
{
var annot = PdfAnnotation.CreateStamp(writer, rect, annotContents, stampHintName);
{
{
// "/N" is a normal appearance should be stored in appearance dictionary.
var N = PdfAppearance.CreateAppearance(writer, image.Width, image.Height);
image.SetAbsolutePosition(0, 0);
N.AddImage(image);
new PdfStream(N.ToPdf(N.PdfWriter));
annot.SetAppearance(PdfName.N, N);
}
if (stampAuthor != null)
{
annot.Title = stampAuthor;
}
annot.Name = Guid.NewGuid().ToString();
annot.Flags = annotFlags;
if (stampTitle != null)
{
annot.Put(new PdfName("Subj"), new PdfString(stampTitle, PdfString.TEXT_UNICODE));
}
}
return annot;
}
var a = PdfAnnotation.CreateSquareCircle(wr1, pi.GetPDFRect(tx.Bounds), "", true);
a.Put(PdfName.IC, pi.GetPdfArray(tx.Fore));//interior color
a.Flags = PdfAnnotation.FLAGS_PRINT;
{
PdfDictionary objAP = new PdfDictionary();
{
PdfContentByte wr = new PdfContentByte(wr1);
var bcFore = pi.GetBaseColor(tx.Fore);
bcFore = new BaseColor(bcFore.R, bcFore.G, bcFore.B, (int)(255 * 0.3));
var rc1 = pi.GetPDFRect(tx.Bounds);
//PdfGState gs1 = new PdfGState();
//gs1.FillOpacity = 0.3f;
wr.SaveState();
//wr.SetGState(gs1);
wr.InternalBuffer.Append(" /GS1 gs ");
wr.SetColorFill(bcFore);
wr.SetLineWidth(0);
wr.Rectangle(rc1.Left, rc1.Bottom, rc1.Width, rc1.Height);
wr.Fill();
wr.RestoreState();
var bbox = pi.GetPDFRect(tx.Bounds);
PdfStream objN = new PdfStream(wr.ToPdf(wr.PdfWriter));
wr.Reset();
objN.Put(PdfName.TYPE, PdfName.XOBJECT);
objN.Put(PdfName.SUBTYPE, PdfName.FORM);
objN.Put(PdfName.FORMTYPE, new PdfNumber(1));
objN.Put(PdfName.BBOX, new PdfArray(new float[] { bbox.Left, bbox.Bottom, bbox.Right, bbox.Top }));
{
PdfDictionary objRes = new PdfDictionary();
{
PdfArray objProcSet = new PdfArray();
{
objProcSet.Add(PdfName.PDF);
}
objRes.Put(PdfName.PROCSET, objProcSet);
}
{
PdfDictionary objExtGState = new PdfDictionary();
{
PdfDictionary objGS1 = new PdfDictionary();
objGS1.Put(PdfName.ca, new PdfNumber(0.3f));
objExtGState.Put(new PdfName("GS1"), objGS1);
}
objRes.Put(PdfName.EXTGSTATE, objExtGState);
}
objN.Put(PdfName.RESOURCES, objRes);
}
objAP.Put(PdfName.N, wr1.AddToBody(objN).IndirectReference);
}
a.Flags = PdfAnnotation.FLAGS_PRINT;
a.Put(PdfName.AP, objAP);
a.Put(PdfName.CA, new PdfNumber(0.3f));
}
wr1.AddAnnotation(a);
+-----------------+ | | 4 | | V | | +---------+ 3 | |-->| |<--| | 1 +---------+ | | A | | 2 | | +-----------------+
+y A | | +------------B | | | | | | | | | | A------------+ | 0-------------------------> +x
(0, 0) +--------------+ → +x | | | A3 Landscape | | | +--------------+ (3309, 2339) ↓ +y
(0, 842.357361) ↑ +y +--------------+ (1191.68909, 842.357361) | | | A3 Landscape | | | +--------------+ → +x (1191.68909, 0) (0, 0)
| General graphics state | |
|---|---|
| w | Set the line width |
| J | Set the line cap style |
| j | Set the line join style |
| M | Set the miter limit |
| d | Set the line dash pattern (dashArray dashPhase) |
| ri | Set the colur rendering intent |
| i | Set the flatness tolerance |
| gs | Set the specified parameters (dictName) |
| gs Graphics state parameter dictionary | |
| LW | The line width |
| LC | The line cap style |
| LJ | The line joint style |
| ML | The miter limit |
| D | The line dash pattern |
| RI | The name of the rendering intent. |
| OP | whether to apply overprint; both or only stroking |
| op | whether to apply overprint for painting operations |
| OPM | The overprint mode |
| Font | An array of the form [font size] |
| BG | The black-generation function |
| BG2 | Same as BG, function or name |
| UCR | The undercolor-removal function |
| UCR2 | Same as UCR, function or name |
| TR | The transfer function |
| TR2 | Same as TR, function, array, or name |
| HT | The halftone dictionary or stream |
| FL | The flatness tolerance |
| SM | The smoothness tolerance |
| SA | apply automatic stroke adjustment |
| BM | The current blend mode |
| SMask | The current soft mask |
| CA | The current stroking alpha constant |
| ca | Same as CA; non-stroking operationg |
| AIS | The alpha source flag |
| TK | The text knockout flag |
| Special graphics state | |
| q | Save the current graphics state |
| Q | Restore the graphics state |
| cm | Modify the current transformation matrix (CTM) by concatenating the specified matrix (a b c d e f) |
| Path construction | |
| m | Begin a new subpath (x y) |
| l | Append a straight line segment (x y) |
| c | Append a cubic Bezier curve (x1 y1 x2 y2 x3 y3) |
| v | Append a cubic Bezier curve (x2 y2 x3 y3) |
| y | Append a cubic Bezier curve (x1 y1 x3 y3) |
| h | Close the current subpath |
| re | Append a rectangle (x y width height) |
| Path painting | |
| S | Stroke the path |
| s | Close and stroke the path |
| f | Fill the path |
| F | Equivalent to f; compatibility |
| f* | Fill the path |
| B | Fill and then stroke the path; winding |
| B* | Fill and then stroke the path; even-odd |
| b | Close, fill and then stroke the path; winding |
| b* | Close, fill and then stroke the path; even-odd |
| n | End the path object |
| Clipping paths | |
| W | Modify yhe current clipping path; winding |
| W* | Modify the current clipping path; even-odd |
| Text objects | |
| BT | Begin a text object |
| ET | End a text object |
| Text state | |
| Tc | Set the character spacing (charSpace) |
| Tw | Set the word spacing (wordSpace) |
| Tz | Set the horz scaling (scale) |
| TL | Set the text leading (leading) |
| Tf | Set the text font (font size) |
| Tr | Set the rendering mode (render) |
| Ts | Set the text rise (rise) |
| Text positioning | |
| Td | Move to the start of the next line (tx ty) |
| TD | Move to the start of the next line rel (tx ty) |
| Tm | Set the text matrix (a b c d e f) |
| T* | Move to the start of the next line |
| Text showing | |
| Tj | Show a text string (string) |
| TJ | Show one or more text strings (array) |
| ' | Move to the next line and show a text string (string) |
| " | Move to the next line and show a text string (aw ac string) |
| Type 3 fonts | |
| d0 | Set width info for the glyph (wx wy) |
| d1 | Set width and bbox info for the glypj (wx wy llx lly urx ury) |
| Color | |
| CS | Set the current colour space (name) |
| cs | Same as CS; non-stroking operations |
| SC | Set the colour to use for stroking (c1...cn) |
| SCN | Same as SC; supports Pattern,Separation,DeviceN and ICCBased (c1...cn; c1...cn name) |
| sc | Same as SC; for non-stroking operations (c1...cn) |
| scn | same as SCN; for non-stroking operations (c1...cn; c1...cn names) |
| G | Set the stroking colour space to DeviceGray (gray) |
| g | Same as G; for non-stroking operations (gray) |
| RG | Set the stroking colour space to DeviceRGB (r g b) |
| rg | Same as RG; for non-stroking operations |
| K | Set the stroking colour space to DeviceCMYK (c m y k) |
| k | Same as K; for non-stroking operations |
| Shading patterns | |
| sh | Paint the shape and colour shading (name) |
| Inline images | |
| BI | Begin an inline image object |
| ID | Begin the image data for an inline image object |
| EI | End an inline image object |
| XObjects | |
| Do | Invoke named XObject (name) |
| Marked content | |
| MP | Desginate a marked-content point (tag) |
| DP | Designate a marked-content point (tag properties) |
| BMC | Begin a marked-content sequence (tag) |
| BDC | Begin a marked-content sequence (tag properties) |
| EMC | End a marked-content sequence |
| Compatibility | |
| BX | Begin compatibility section |
| EX | End compatibility section |