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 |