// origbbには,GhostscriptのsDevice=bboxで得られた値を入れておく。 // 空ページはdeleteemptypages = trueならば消されるが,falseならばダミーのページが挿入される. // ついでに塗る. // crop = falseならば塗ることしかしない. bool pdfcrop(string inputFileName, string outputFileName, bool use_bp, List<int> pages, List<BoundingBoxPair> origbb, bool drawback = true, bool deleteemptypages = false, bool crop = true, int version = -1) { var colorstr = ((double)Properties.Settings.Default.backgroundColor.R / 255).ToString() + " " + ((double)Properties.Settings.Default.backgroundColor.G / 255).ToString() + " " + ((double)Properties.Settings.Default.backgroundColor.B / 255).ToString(); System.Diagnostics.Debug.Assert(pages.Count == origbb.Count); var tmpfile = TempFilesDeleter.GetTempFileName(".tex", workingDir); if (tmpfile == null) return false; tempFilesDeleter.AddTeXFile(tmpfile); tempFilesDeleter.AddFile(outputFileName); var bbBox = new List<BoundingBox>(); for (int i = 0; i < pages.Count; ++i) { BoundingBoxPair bb; if (origbb[i] == null) { bb = readPDFBB(inputFileName, pages[i]); } else { bb = origbb[i]; } if (bb == null) return false; var rect = AddMargineToBoundingBox(bb.hiresbb, use_bp); if (rect.IsEmpty && !deleteemptypages) rect = new BoundingBox(0, 0, 10, 10);// dummy bbBox.Add(rect); } using (var fw = new StreamWriter(Path.Combine(workingDir, tmpfile))) { fw.WriteLine(@"\pdfoutput=1\relax"); if (version != -1) fw.WriteLine(@"\pdfminorversion=" + (version - 10).ToString() + @"\relax"); for (int i = 0; i < pages.Count; ++i) { var box = bbBox[i]; if (!box.IsEmpty) { var page = pages[i]; fw.WriteLine(@"\pdfximage page " + page.ToString() + " mediabox{" + inputFileName + @"}"); fw.Write(@"\setbox0=\hbox{"); if (drawback) { fw.Write(@"\pdfliteral{q " + colorstr + " rg n " + box.Left.ToString() + " " + box.Bottom.ToString() + " " + box.Width.ToString() + " " + box.Height.ToString() + " re f Q}"); } fw.WriteLine(@"\pdfrefximage\pdflastximage}\relax"); if (crop) { fw.WriteLine(@"\pdfhorigin=" + (-box.Left).ToString() + @"bp\relax"); fw.WriteLine(@"\pdfvorigin=" + box.Bottom.ToString() + @"bp\relax"); fw.WriteLine(@"\pdfpagewidth=" + (box.Right - box.Left).ToString() + @"bp\relax"); fw.WriteLine(@"\pdfpageheight=" + (box.Top - box.Bottom).ToString() + @"bp\relax"); fw.WriteLine(@"\ht0=\pdfpageheight\relax"); } else { fw.WriteLine(@"\pdfhorigin=0pt\relax"); fw.WriteLine(@"\pdfvorigin=0pt\relax"); fw.WriteLine(@"\pdfpagewidth=\wd0\relax"); fw.WriteLine(@"\pdfpageheight=\ht0\relax"); } fw.WriteLine(@"\shipout\box0\relax"); } } fw.WriteLine(@"\bye"); } using (var proc = GetProcess()) { proc.StartInfo.FileName = GetpdftexPath(); proc.StartInfo.Arguments = "-no-shell-escape -interaction=nonstopmode \"" + tmpfile + "\""; try { printCommandLine(proc); ReadOutputs(proc, Properties.Resources.EXEC_PDFTEX); } catch (Win32Exception) { if (controller_ != null) controller_.showPathError("pdftex.exe", String.Format(Properties.Resources.TEX_DISTRIBUTION,"pdftex")); return false; } catch (TimeoutException) { return false; } } if (File.Exists(Path.Combine(workingDir, Path.GetFileNameWithoutExtension(tmpfile) + ".pdf"))) { File.Delete(Path.Combine(workingDir, outputFileName)); File.Move(Path.Combine(workingDir, Path.GetFileNameWithoutExtension(tmpfile) + ".pdf"), Path.Combine(workingDir, outputFileName)); } else { if (controller_ != null) controller_.showGenerateError(); return false; } return true; }
void rewriteBB(string inputEpsFileName, Func<BoundingBox, BoundingBox> bb, Func<BoundingBox, BoundingBox> hiresbb) { Regex regexBB = new Regex(@"^\%\%(HiRes|)BoundingBox\: ([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)$"); byte[] inbuf; using (var fs = new FileStream(Path.Combine(workingDir, inputEpsFileName), FileMode.Open, FileAccess.Read)) { if (!fs.CanRead) return; inbuf = new byte[fs.Length]; fs.Read(inbuf, 0, (int)fs.Length); } var s = System.Text.UTF8Encoding.UTF8.GetString(inbuf); byte[] outbuf = new byte[inbuf.Length + 200]; byte[] tmpbuf; // 現在読んでいるinufの「行」の先頭 int inp = 0; // inbufの現在読んでいる場所 int q = 0; // outbufに書き込んだ量 int outp = 0; bool bbfound = false, hiresbbfound = false; while (q < inbuf.Length) { if (q == inbuf.Length - 1 || inbuf[q] == '\r' || inbuf[q] == '\n') { string line = System.Text.Encoding.ASCII.GetString(inbuf, inp, q - inp); Match match = regexBB.Match(line); if (match.Success) { BoundingBox bbinfile = new BoundingBox( System.Convert.ToDecimal(match.Groups[2].Value), System.Convert.ToDecimal(match.Groups[3].Value), System.Convert.ToDecimal(match.Groups[4].Value), System.Convert.ToDecimal(match.Groups[5].Value)); string HiRes = match.Groups[1].Value; if (HiRes == "") { bbfound = true; var newbb = bb(bbinfile); line = String.Format("%%BoundingBox: {0} {1} {2} {3}", (int)newbb.Left, (int)newbb.Bottom, (int)newbb.Right, (int)newbb.Top); } else { hiresbbfound = true; var newbb = hiresbb(bbinfile); line = String.Format("%%HiResBoundingBox: {0} {1} {2} {3}", newbb.Left, newbb.Bottom, newbb.Right, newbb.Top); } tmpbuf = System.Text.Encoding.ASCII.GetBytes(line); System.Array.Copy(tmpbuf, 0, outbuf, outp, tmpbuf.Length); outp += tmpbuf.Length; if (bbfound && hiresbbfound) { System.Array.Copy(inbuf, q, outbuf, outp, inbuf.Length - q); outp += inbuf.Length - q; break; } } else { System.Array.Copy(inbuf, inp, outbuf, outp, q - inp); outp += q - inp; } inp = q; while (q < inbuf.Length - 1 && (inbuf[q] == '\r' || inbuf[q] == '\n')) ++q; System.Array.Copy(inbuf, inp, outbuf, outp, q - inp); outp += q - inp; inp = q; if (q == inbuf.Length - 1) break; } else ++q; } using (FileStream wfs = new System.IO.FileStream(Path.Combine(workingDir, inputEpsFileName), FileMode.Create, FileAccess.Write)) { var ss = System.Text.UTF8Encoding.UTF8.GetString(outbuf, 0, outp); wfs.Write(outbuf, 0, outp); } }
BoundingBox AddMargineToBoundingBox(BoundingBox bb, bool use_bp) { decimal margindevide = use_bp ? 1 : Properties.Settings.Default.resolutionScale; return new BoundingBox( bb.Left - Properties.Settings.Default.leftMargin / margindevide, bb.Bottom - Properties.Settings.Default.bottomMargin / margindevide, bb.Right + Properties.Settings.Default.rightMargin / margindevide, bb.Top + Properties.Settings.Default.topMargin / margindevide); }
List<BoundingBoxPair> readPDFBB(string inputPDFFileName, int firstpage, int lastpage) { System.Diagnostics.Debug.Assert(lastpage >= firstpage); string arg; var gspath = setProcStartInfo(Properties.Settings.Default.gsPath, out arg); using (var proc = GetProcess()) { proc.StartInfo.FileName = gspath; proc.StartInfo.Arguments = arg + "-q -dBATCH -dNOPAUSE -sDEVICE=bbox "; /* if(Properties.Settings.Default.pagebox != "media") { var box = Properties.Settings.Default.pagebox; proc.StartInfo.Arguments += "-dUse" + Char.ToUpper(box[0]) + box.Substring(1) + "Box "; }*/ proc.StartInfo.Arguments += "-dFirstPage=" + firstpage.ToString() + " -dLastPage=" + lastpage.ToString() + " \"" + inputPDFFileName + "\""; var rv = new List<BoundingBoxPair>(); Regex regexBB = new Regex(@"^\%\%(HiRes)?BoundingBox\: ([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)$"); BoundingBox? bb = null; BoundingBox? hiresbb = null; Action<string> err_read = line => { if (controller_ != null) controller_.appendOutput(line + "\n"); var match = regexBB.Match(line); if (match.Success) { var currentbb = new BoundingBox( System.Convert.ToDecimal(match.Groups[2].Value), System.Convert.ToDecimal(match.Groups[3].Value), System.Convert.ToDecimal(match.Groups[4].Value), System.Convert.ToDecimal(match.Groups[5].Value)); if (match.Groups[1].Value == "HiRes") { hiresbb = currentbb; } else { bb = currentbb; } if (bb != null && hiresbb != null) { rv.Add(new BoundingBoxPair(bb.Value, hiresbb.Value)); bb = null; hiresbb = null; } } }; try { printCommandLine(proc); ReadOutputs(proc, Properties.Resources.GET_BOUNDINGBOX, s => { System.Diagnostics.Debug.WriteLine(s); }, err_read); if (controller_ != null) controller_.appendOutput("\n"); if (rv.Count != lastpage - firstpage + 1) return null; else return rv; } catch (Win32Exception) { if (controller_ != null) controller_.showPathError(gspath, "Ghostscript"); return null; } catch (TimeoutException) { return null; } } }
List<BoundingBoxPair> readPDFBox(string inputPDFFileName, List<int> pages, string boxname) { try { using (var mupdf = new MuPDF(Path.Combine(GetToolsPath(), "mudraw.exe"))) { if (controller_ != null) controller_.appendOutput("Getting the size of PDFBox...\n"); var rv = new List<BoundingBoxPair>(); var doc = mupdf.Execute<int>("open_document", Path.Combine(workingDir, inputPDFFileName)); if (doc == 0) return null; foreach (var p in pages) { if (abort) { if (controller_ != null) controller_.appendOutput(Properties.Resources.STOPCONVERTMSG + "\n"); return null; } int rotate = 0; BoundingBox box = new BoundingBox(), media = new BoundingBox(); const int repeatTimes = 10; for (int i = 1; i <= repeatTimes; ++i) { try { var page = mupdf.Execute<int>("load_page", doc, p - 1); media = mupdf.Execute< BoundingBox>("pdfbox_page", page, "media"); box = mupdf.Execute<BoundingBox>("pdfbox_page", page, boxname); rotate = mupdf.Execute<int>("rotate_page", page); break; } catch (Exception) { mupdf.ClearError(); if (i == repeatTimes) throw; } } BoundingBox bb; switch (rotate) { default: case 0: bb = new BoundingBox(box.Left - media.Left, box.Bottom - media.Bottom, box.Right - media.Left, box.Top - media.Bottom); break; case 90: bb = new BoundingBox(box.Bottom - media.Bottom, media.Right - box.Right, box.Top - media.Bottom, media.Right - box.Left); break; case 180: bb = new BoundingBox(media.Right - box.Right, media.Top - box.Top, media.Right - box.Left, media.Top - box.Bottom); break; case 270: bb = new BoundingBox(media.Top - box.Top, box.Left - media.Left, media.Top - box.Bottom, box.Right - media.Left); break; } if (controller_ != null) controller_.appendOutput(bb.ToString() + " (Page " + p + ")\n"); rv.Add(new BoundingBoxPair(bb.HiresBBToBB(), bb)); } if (controller_ != null) controller_.appendOutput("\n"); return rv; } } catch (Exception e) { if (controller_ != null) controller_.appendOutput(e.Message + "\n"); #if DEBUG System.Diagnostics.Debug.WriteLine(e.StackTrace); #endif return null; } }
private BoundingBoxPair readBB(string inputEpsFileName) { Regex regex = new Regex(@"^\%\%(HiRes)?BoundingBox\: ([-\d\.]+) ([-\d\.]+) ([-\d\.]+) ([-\d\.]+)$"); BoundingBox? bb = null; BoundingBox? hiresbb = null; using (StreamReader sr = new StreamReader(Path.Combine(workingDir, inputEpsFileName), Encoding.GetEncoding("shift_jis"))) { string line; while ((line = sr.ReadLine()) != null) { Match match = regex.Match(line); if (match.Success) { var cb = new BoundingBox( System.Convert.ToDecimal(match.Groups[2].Value), System.Convert.ToDecimal(match.Groups[3].Value), System.Convert.ToDecimal(match.Groups[4].Value), System.Convert.ToDecimal(match.Groups[5].Value)); if (match.Groups[1].Value == "HiRes") { hiresbb = cb; } else { bb = cb; } if (bb != null && hiresbb != null) break; } } } if (bb == null && hiresbb == null) return null; if (hiresbb == null) hiresbb = bb.Value; else if (bb == null) bb = hiresbb.Value.HiresBBToBB(); return new BoundingBoxPair(bb.Value, hiresbb.Value); }
public BoundingBoxPair(BoundingBox b, BoundingBox h) { bb = b; hiresbb = h; }