/* ----------------------------------------------------------------- */ /// /// GetSize /// /// <summary> /// ページサイズを取得します。 /// </summary> /// /// <remarks> /// PDFium は回転後のサイズを返しますが、Page オブジェクトでは /// 回転前の情報として格納します。そのため、場合によって幅と /// 高さの情報を反転しています。 /// </remarks> /// /* ----------------------------------------------------------------- */ private SizeF GetPageSize(IntPtr handle, int degree) { var w = (float)PdfiumApi.FPDF_GetPageWidth(handle); var h = (float)PdfiumApi.FPDF_GetPageHeight(handle); return((degree != 90 && degree != 270) ? new SizeF(w, h) : new SizeF(h, w)); }
/* ----------------------------------------------------------------- */ /// /// GetPageRotation /// /// <summary> /// ページの回転角度を取得します。 /// </summary> /// /* ----------------------------------------------------------------- */ private int GetPageRotation(IntPtr handle) { var dest = PdfiumApi.FPDFPage_GetRotation(handle); return(dest == 1 ? 90 : dest == 2 ? 180 : dest == 3 ? 270 : 0); }
/* ----------------------------------------------------------------- */ /// /// Create /// /// <summary> /// Creates a PdfFile object from the specified arguments. /// </summary> /// /* ----------------------------------------------------------------- */ private PdfFile Create(string password, bool fullaccess) { var dest = IO.GetPdfFile(Source, password); dest.Count = Invoke(e => PdfiumApi.FPDF_GetPageCount(e)); dest.FullAccess = fullaccess; return(dest); }
/* ----------------------------------------------------------------- */ /// /// GetText /// /// <summary> /// Gets the metadata corresponding to the specified name. /// </summary> /// /* ----------------------------------------------------------------- */ private static string GetText(PdfiumReader core, string name) { var size = core.Invoke(e => PdfiumApi.FPDF_GetMetaText(e, name, null, 0)); if (size <= 2) { return(string.Empty); } var buffer = new byte[size]; core.Invoke(e => PdfiumApi.FPDF_GetMetaText(e, name, buffer, size)); return(Encoding.Unicode.GetString(buffer, 0, (int)(size - 2))); }
/* ----------------------------------------------------------------- */ /// /// Create /// /// <summary> /// Creates a new instance of the Encryption class with the /// specified arguments. /// </summary> /// /// <param name="core">PDFium object.</param> /// <param name="password">Password</param> /// /// <returns>Encryption object.</returns> /// /// <remarks> /// 現在 FPDF_GetDocPermissions の結果で諸々の判定を行っているが /// 最終的には OwnerPassword で開いた状態でもオリジナルの /// Permission を取得する事を目指す。それに伴って、各種操作も /// 修正する必要がある。 /// </remarks> /// /* ----------------------------------------------------------------- */ public static Encryption Create(PdfiumReader core, string password) { var method = core.Invoke(e => PdfiumApi.FPDF_GetSecurityHandlerRevision(e)); var permission = (uint)core.Invoke(e => PdfiumApi.FPDF_GetDocPermissions(e)); var restrict = permission != 0xfffffffc; return(method == -1 ? new Encryption() : new Encryption { Enabled = true, OwnerPassword = restrict ? string.Empty : password, OpenWithPassword = restrict, UserPassword = restrict ? password : string.Empty, Method = CreateMethod(method), Permission = new Permission(permission), }); }
/* ----------------------------------------------------------------- */ /// /// Dispose /// /// <summary> /// Releases the unmanaged resources used by the PdfiumReader /// and optionally releases the managed resources. /// </summary> /// /// <param name="disposing"> /// true to release both managed and unmanaged resources; /// false to release only unmanaged resources. /// </param> /// /* ----------------------------------------------------------------- */ private void Dispose(bool disposing) { if (_disposed) { return; } _disposed = true; lock (_lock) { if (_core != IntPtr.Zero) { PdfiumApi.FPDF_CloseDocument(_core); _core = IntPtr.Zero; } } if (disposing) { _stream?.Dispose(); } }
/* ----------------------------------------------------------------- */ /// /// Load /// /// <summary> /// Loads the PDF document. /// </summary> /// /// <param name="password">Password.</param> /// /* ----------------------------------------------------------------- */ private void Load(string password) { var core = PdfiumApi.FPDF_LoadCustomDocument( new FileAccess { Length = (uint)_stream.Length, GetBlock = Marshal.GetFunctionPointerForDelegate(_delegate), Parameter = IntPtr.Zero, }, password ); if (core == IntPtr.Zero) { throw GetLastError(); } _core = core; Encryption = EncryptionFactory.Create(this, password); File = Create(password, !Encryption.OpenWithPassword); Pages = new ReadOnlyPageList(this, File); Metadata = MetadataFactory.Create(this); }
/* ----------------------------------------------------------------- */ /// /// Render /// /// <summary> /// Executes the rendering with the specified arguments. /// </summary> /// /* ----------------------------------------------------------------- */ private static void Render(IntPtr core, Graphics dest, Page page, PointF point, SizeF size, int flags) { if (core == IntPtr.Zero) { return; } var n = 5; var hp = PdfiumApi.FPDF_LoadPage(core, page.Number - 1, n); if (hp == IntPtr.Zero) { throw new LoadException(LoadStatus.PageError); } var hdc = dest.GetHdc(); try { PdfiumApi.FPDF_RenderPage( hdc, hp, (int)point.X, (int)point.Y, (int)size.Width, (int)size.Height, GetRotation(page.Delta), flags, n ); } finally { dest.ReleaseHdc(hdc); PdfiumApi.FPDF_ClosePage(hp); } }
/* ----------------------------------------------------------------- */ /// /// GetPage /// /// <summary> /// Page オブジェクトを取得します。 /// </summary> /// /// <param name="index"> /// 最初のページを "ゼロ" とするインデックス /// </param> /// /* ----------------------------------------------------------------- */ private Page GetPage(int index) { var page = _core.Invoke(e => PdfiumApi.FPDF_LoadPage(e, index, 5)); if (page == IntPtr.Zero) { throw _core.GetLastError(); } try { var degree = GetPageRotation(page); var size = GetPageSize(page, degree); return(new Page( File, // File index + 1, // Number size, // Size new Angle(degree), // Rotation new PointF(72.0f, 72.0f) // Resolution )); } finally { PdfiumApi.FPDF_ClosePage(page); } }