David PHAM-VAN

Rename classes to satisfy Dart conventions

... ... @@ -10,21 +10,21 @@ images and text using TrueType fonts.
The coordinate system is using the internal Pdf system:
* (0.0, 0.0) is bottom-left
* 1.0 is defined as 1 / 72.0 inch
* you can use the constants for centimeters, milimeters and inch defined in PDFPageFormat
* you can use the constants for centimeters, milimeters and inch defined in PdfPageFormat
Example:
```dart
final pdf = new PDFDocument();
final page = new PDFPage(pdf, pageFormat: PDFPageFormat.letter);
final pdf = new PdfDocument();
final page = new PdfPage(pdf, pageFormat: PdfPageFormat.letter);
final g = page.getGraphics();
final font = new PDFFont(pdf);
final font = new PdfFont(pdf);
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0, 30.0, 100.0, 50.0);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 5.0 * PDFPageFormat.mm, 300.0);
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 5.0 * PdfPageFormat.mm, 300.0);
var file = new File('file.pdf');
file.writeAsBytesSync(pdf.save());
... ... @@ -34,7 +34,7 @@ To load an image it is possible to use the dart library [image](https://pub.dart
```dart
Image image = decodeImage(new Io.File('test.webp').readAsBytesSync());
PDFImage image = new PDFImage(
PdfImage image = new PdfImage(
pdf,
image: img.data.buffer.asUint8List(),
width: img.width,
... ... @@ -45,9 +45,9 @@ g.drawImage(image, 100.0, 100.0, 80.0);
To use a TrueType font:
```dart
PDFTTFFont ttf = new PDFTTFFont(
PdfTtfFont ttf = new PdfTtfFont(
pdf,
(new File("open-sans.ttf").readAsBytesSync() as Uint8List).buffer.asByteData());
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(ttf, 20.0, "Dart is awesome", 50.0, 30.0);
```
... ...
... ... @@ -3,20 +3,20 @@ import 'dart:io';
import 'package:pdf/pdf.dart';
void main() {
final pdf = new PDFDocument(deflate: zlib.encode);
final page = new PDFPage(pdf, pageFormat: PDFPageFormat.letter);
final pdf = new PdfDocument(deflate: zlib.encode);
final page = new PdfPage(pdf, pageFormat: PdfPageFormat.letter);
final g = page.getGraphics();
final font = new PDFFont(pdf);
final font = new PdfFont(pdf);
final top = page.pageFormat.height;
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.drawRect(50.0 * PDFPageFormat.mm, top - 80.0 * PDFPageFormat.mm,
100.0 * PDFPageFormat.mm, 50.0 * PDFPageFormat.mm);
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0 * PdfPageFormat.mm, top - 80.0 * PdfPageFormat.mm,
100.0 * PdfPageFormat.mm, 50.0 * PdfPageFormat.mm);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 10.0 * PDFPageFormat.mm,
top - 10.0 * PDFPageFormat.mm);
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 10.0 * PdfPageFormat.mm,
top - 10.0 * PdfPageFormat.mm);
var file = new File('example.pdf');
file.writeAsBytesSync(pdf.save());
... ...
... ... @@ -30,6 +30,7 @@ part 'src/ascii85.dart';
part 'src/border.dart';
part 'src/catalog.dart';
part 'src/color.dart';
part 'src/compatibility.dart';
part 'src/document.dart';
part 'src/font.dart';
part 'src/font_descriptor.dart';
... ...
... ... @@ -18,128 +18,75 @@
part of pdf;
class PDFAnnot extends PDFObject {
/// Solid border. The border is drawn as a solid line.
static const SOLID = 0;
/// The border is drawn with a dashed line.
static const DASHED = 1;
/// The border is drawn in a beveled style (faux three-dimensional) such
/// that it looks as if it is pushed out of the page (opposite of INSET)
static const BEVELED = 2;
/// The border is drawn in an inset style (faux three-dimensional) such
/// that it looks as if it is inset into the page (opposite of BEVELED)
static const INSET = 3;
/// The border is drawn as a line on the bottom of the annotation rectangle
static const UNDERLINED = 4;
class PdfAnnot extends PdfObject {
/// The subtype of the outline, ie text, note, etc
final String subtype;
/// The size of the annotation
final double l, b, r, t;
final PdfRect srcRect;
/// The text of a text annotation
final String s;
/// flag used to indicate that the destination should fit the screen
static const FULL_PAGE = -9999.0;
/// Link to the Destination page
PDFObject dest;
final PdfObject dest;
/// If fl!=FULL_PAGE then this is the region of the destination page shown.
/// If destRect is null then this is the region of the destination page shown.
/// Otherwise they are ignored.
final double fl, fb, fr, ft;
final PdfRect destRect;
/// the border for this annotation
PDFBorder border;
PdfBorder border;
PDFAnnot(PDFPage pdfPage,
PdfAnnot(PdfPage pdfPage,
{String type,
this.s,
this.l,
this.b,
this.r,
this.t,
this.srcRect,
this.subtype,
this.dest,
this.fl,
this.fb,
this.fr,
this.ft})
this.destRect})
: super(pdfPage.pdfDocument, type) {
pdfPage.annotations.add(this);
}
/// This is used to create an annotation.
/// @param s Subtype for this annotation
/// @param l Left coordinate
/// @param b Bottom coordinate
/// @param r Right coordinate
/// @param t Top coordinate
factory PDFAnnot.annotation(
PDFPage pdfPage, String s, double l, double b, double r, double t) =>
new PDFAnnot(pdfPage, type: "/Annot", s: s, l: l, b: b, r: r, t: t);
/// @param rect coordinates
factory PdfAnnot.annotation(PdfPage pdfPage, String s, PdfRect rect) =>
new PdfAnnot(pdfPage, type: "/Annot", s: s, srcRect: rect);
/// Creates a text annotation
/// @param l Left coordinate
/// @param b Bottom coordinate
/// @param r Right coordinate
/// @param t Top coordinate
/// @param rect coordinates
/// @param s Text for this annotation
factory PDFAnnot.text(
PDFPage pdfPage, double l, double b, double r, double t, String s) =>
new PDFAnnot(pdfPage, type: "/Text", l: l, b: b, r: r, t: t, s: s);
factory PdfAnnot.text(PdfPage pdfPage, PdfRect rect, String s) =>
new PdfAnnot(pdfPage, type: "/Text", srcRect: rect, s: s);
/// Creates a link annotation
/// @param l Left coordinate
/// @param b Bottom coordinate
/// @param r Right coordinate
/// @param t Top coordinate
/// @param srcRect coordinates
/// @param dest Destination for this link. The page will fit the display.
/// @param fl Left coordinate
/// @param fb Bottom coordinate
/// @param fr Right coordinate
/// @param ft Top coordinate
/// <br><br>Rectangle describing what part of the page to be displayed
/// @param destRect Rectangle describing what part of the page to be displayed
/// (must be in User Coordinates)
factory PDFAnnot.link(PDFPage pdfPage, double l, double b, double r, double t,
PDFObject dest,
[double fl = FULL_PAGE,
double fb = FULL_PAGE,
double fr = FULL_PAGE,
double ft = FULL_PAGE]) =>
new PDFAnnot(pdfPage,
type: "/Link",
l: l,
b: b,
r: r,
t: t,
dest: dest,
fl: fl,
fb: fb,
fr: fr,
ft: ft);
factory PdfAnnot.link(PdfPage pdfPage, PdfRect srcRect, PdfObject dest,
[PdfRect destRect]) =>
new PdfAnnot(pdfPage,
type: "/Link", srcRect: srcRect, dest: dest, destRect: destRect);
/// Sets the border for the annotation. By default, no border is defined.
///
/// <p>If the style is DASHED, then this method uses PDF's default dash
/// If the style is dashed, then this method uses Pdf's default dash
/// scheme {3}
///
/// <p>Important: the annotation must have been added to the document before
/// Important: the annotation must have been added to the document before
/// this is used. If the annotation was created using the methods in
/// PDFPage, then the annotation is already in the document.
/// [PdfPage], then the annotation is already in the document.
///
/// @param style Border style SOLID, DASHED, BEVELED, INSET or UNDERLINED.
/// @param style Border style solid, dashed, beveled, inset or underlined.
/// @param width Width of the border
/// @param dash Array of lengths, used for drawing the dashes. If this
/// is null, then the default of {3} is used.
void setBorder(double width, {int style = 0, List<double> dash}) {
border = new PDFBorder(pdfDocument, width, style: style, dash: dash);
void setBorder(double width,
{PdfBorderStyle style = PdfBorderStyle.solid, List<double> dash}) {
border = new PdfBorder(pdfDocument, width, style: style, dash: dash);
}
/// Output the annotation
... ... @@ -149,28 +96,30 @@ class PDFAnnot extends PDFObject {
void prepare() {
super.prepare();
params["/Subtype"] = PDFStream.string(subtype);
params["/Rect"] = PDFStream.string("[$l $b $r $t]");
params["/Subtype"] = PdfStream.string(subtype);
params["/Rect"] = PdfStream.string(
"[${srcRect.l} ${srcRect.b} ${srcRect.r} ${srcRect.t}]");
// handle the border
if (border == null) {
params["/Border"] = PDFStream.string("[0 0 0]");
params["/Border"] = PdfStream.string("[0 0 0]");
} else {
params["/BS"] = border.ref();
}
// Now the annotation subtypes
if (subtype == "/Text") {
params["/Contents"] = PDFStream.string(s);
params["/Contents"] = PdfStream.string(s);
} else if (subtype == "/Link") {
var dests = new List<PDFStream>();
var dests = new List<PdfStream>();
dests.add(dest.ref());
if (fl == FULL_PAGE)
dests.add(PDFStream.string("/Fit"));
if (destRect == null)
dests.add(PdfStream.string("/Fit"));
else {
dests.add(PDFStream.string("/FitR $fl $fb $fr $ft"));
dests.add(PdfStream.string(
"/FitR ${destRect.l} ${destRect.b} ${destRect.r} ${destRect.t}"));
}
params["/Dest"] = PDFStream.array(dests);
params["/Dest"] = PdfStream.array(dests);
}
}
}
... ...
... ... @@ -18,13 +18,13 @@
part of pdf;
class PDFArrayObject extends PDFObject {
class PdfArrayObject extends PdfObject {
final List<String> values;
PDFArrayObject(PDFDocument pdfDocument, this.values) : super(pdfDocument);
PdfArrayObject(PdfDocument pdfDocument, this.values) : super(pdfDocument);
@override
void writeContent(PDFStream os) {
void writeContent(PdfStream os) {
super.writeContent(os);
os.putStringArray(values);
... ...
... ... @@ -18,9 +18,28 @@
part of pdf;
class PDFBorder extends PDFObject {
enum PdfBorderStyle {
/// Solid border. The border is drawn as a solid line.
solid,
/// The border is drawn with a dashed line.
dashed,
/// The border is drawn in a beveled style (faux three-dimensional) such
/// that it looks as if it is pushed out of the page (opposite of INSET)
beveled,
/// The border is drawn in an inset style (faux three-dimensional) such
/// that it looks as if it is inset into the page (opposite of BEVELED)
inset,
/// The border is drawn as a line on the bottom of the annotation rectangle
underlined
}
class PdfBorder extends PdfObject {
/// The style of the border
final int style;
final PdfBorderStyle style;
/// The width of the border
final double width;
... ... @@ -28,29 +47,31 @@ class PDFBorder extends PDFObject {
/// This array allows the definition of a dotted line for the border
final List<double> dash;
/// Creates a border using the predefined styles in PDFAnnot.
/// <p>Note: Do not use PDFAnnot.DASHED with this method.
/// Creates a border using the predefined styles in [PdfAnnot].
/// Note: Do not use [PdfAnnot.dashed] with this method.
/// Use the other constructor.
///
/// @param width The width of the border
/// @param style The style of the border
/// @param dash The line pattern definition
/// @see PDFAnnot
PDFBorder(PDFDocument pdfDocument, this.width, {this.style = 0, this.dash})
/// @see [PdfAnnot]
PdfBorder(PdfDocument pdfDocument, this.width,
{this.style = PdfBorderStyle.solid, this.dash})
: super(pdfDocument);
/// @param os OutputStream to send the object to
@override
void writeContent(PDFStream os) {
void writeContent(PdfStream os) {
super.writeContent(os);
var data = new List<PDFStream>();
data.add(PDFStream.string("/S"));
data.add(PDFStream.string("/" + "SDBIU".substring(style, style + 1)));
data.add(PDFStream.string("/W $width"));
var data = new List<PdfStream>();
data.add(PdfStream.string("/S"));
data.add(PdfStream.string(
"/" + "SDBIU".substring(style.index, style.index + 1)));
data.add(PdfStream.string("/W $width"));
if (dash != null) {
data.add(PDFStream.string("/D"));
data.add(PDFStream.array(dash.map((double d) => PDFStream.num(d))));
data.add(PdfStream.string("/D"));
data.add(PdfStream.array(dash.map((double d) => PdfStream.num(d))));
}
os.putArray(data);
}
... ...
... ... @@ -18,23 +18,22 @@
part of pdf;
class PDFCatalog extends PDFObject {
class PdfCatalog extends PdfObject {
/// The pages of the document
final PDFPageList pdfPageList;
final PdfPageList pdfPageList;
/// The outlines of the document
PDFOutline outlines;
PdfOutline outlines;
/// The initial page mode
final PDFPageMode pageMode;
final PdfPageMode pageMode;
/// This constructs a PDF Catalog object
/// This constructs a Pdf Catalog object
///
/// @param pdfPageList The PDFPageList object that's the root
/// of the documents page tree
/// @param pdfPageList The [PdfPageList] object that's the root of the documents page tree
/// @param pagemode How the document should appear when opened.
/// Allowed values are USENONE, USEOUTLINES, USETHUMBS or FULLSCREEN.
PDFCatalog(PDFDocument pdfDocument, this.pdfPageList, this.pageMode)
/// Allowed values are usenone, useoutlines, usethumbs or fullscreen.
PdfCatalog(PdfDocument pdfDocument, this.pdfPageList, this.pageMode)
: super(pdfDocument, "/Catalog");
/// @param os OutputStream to send the object to
... ... @@ -51,6 +50,6 @@ class PDFCatalog extends PDFObject {
// the /PageMode setting
params["/PageMode"] =
PDFStream.string(PDFDocument._PDF_PAGE_MODES[pageMode.index]);
PdfStream.string(PdfDocument._PdfPageModes[pageMode.index]);
}
}
... ...
... ... @@ -18,26 +18,26 @@
part of pdf;
class PDFColor {
class PdfColor {
final double a;
final double r;
final double g;
final double b;
static var black = new PDFColor(0.0, 0.0, 0.0);
static var black = new PdfColor(0.0, 0.0, 0.0);
PDFColor(this.r, this.g, this.b, [this.a = 1.0]);
const PdfColor(this.r, this.g, this.b, [this.a = 1.0]);
factory PDFColor.fromInt(int color) {
return new PDFColor(
factory PdfColor.fromInt(int color) {
return new PdfColor(
(color >> 16 & 0xff) / 255.0,
(color >> 8 & 0xff) / 255.0,
(color & 0xff) / 255.0,
(color >> 24 & 0xff) / 255.0);
}
factory PDFColor.fromHex(String color) {
return new PDFColor(
factory PdfColor.fromHex(String color) {
return new PdfColor(
(int.parse(color.substring(0, 1), radix: 16) >> 16 & 0xff) / 255.0,
(int.parse(color.substring(2, 3), radix: 16) >> 8 & 0xff) / 255.0,
(int.parse(color.substring(4, 5), radix: 16) & 0xff) / 255.0,
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
part of pdf;
@deprecated
class PDFAnnot extends PdfAnnot {
static const SOLID = PdfBorderStyle.solid;
static const DASHED = PdfBorderStyle.dashed;
static const BEVELED = PdfBorderStyle.beveled;
static const INSET = PdfBorderStyle.inset;
static const UNDERLINED = PdfBorderStyle.underlined;
static const FULL_PAGE = -9999.0;
PDFAnnot(PdfPage pdfPage,
{String type,
String s,
double l,
double b,
double r,
double t,
String subtype,
PdfObject dest,
double fl,
double fb,
double fr,
double ft})
: super(pdfPage,
type: type,
s: s,
srcRect: PdfRect.fromLTRB(l, t, r, b),
subtype: subtype,
dest: dest,
destRect: PdfRect.fromLTRB(fl, ft, fr, fb));
factory PDFAnnot.annotation(
PdfPage pdfPage, String s, double l, double b, double r, double t) =>
new PDFAnnot(pdfPage, type: "/Annot", s: s, l: l, b: b, r: r, t: t);
factory PDFAnnot.text(
PdfPage pdfPage, double l, double b, double r, double t, String s) =>
new PDFAnnot(pdfPage, type: "/Text", l: l, b: b, r: r, t: t, s: s);
factory PDFAnnot.link(PdfPage pdfPage, double l, double b, double r, double t,
PdfObject dest,
[double fl = FULL_PAGE,
double fb = FULL_PAGE,
double fr = FULL_PAGE,
double ft = FULL_PAGE]) =>
new PDFAnnot(pdfPage,
type: "/Link",
l: l,
b: b,
r: r,
t: t,
dest: dest,
fl: fl,
fb: fb,
fr: fr,
ft: ft);
}
@deprecated
class PDFArrayObject extends PdfArrayObject {
PDFArrayObject(PdfDocument pdfDocument, List<String> values)
: super(pdfDocument, values);
}
@deprecated
class PDFBorder extends PdfBorder {
PDFBorder(PdfDocument pdfDocument, double width,
{int style, List<double> dash})
: super(pdfDocument, width,
style: PdfBorderStyle.values[style], dash: dash);
}
@deprecated
class PDFCatalog extends PdfCatalog {
PDFCatalog(
PdfDocument pdfDocument, PdfPageList pdfPageList, PdfPageMode pageMode)
: super(pdfDocument, pdfPageList, pageMode);
}
@deprecated
class PDFDocument extends PdfDocument {
PDFDocument(
{PdfPageMode pageMode = PdfPageMode.none, DeflateCallback deflate})
: super(pageMode: pageMode, deflate: deflate);
}
@deprecated
class PDFColor extends PdfColor {
PDFColor(double r, double g, double b, [double a = 1.0]) : super(r, g, b, a);
factory PDFColor.fromInt(int color) {
final c = PdfColor.fromInt(color);
return PDFColor(c.r, c.g, c.b, c.a);
}
factory PDFColor.fromHex(String color) {
final c = PdfColor.fromHex(color);
return PDFColor(c.r, c.g, c.b, c.a);
}
}
@deprecated
class PDFFontDescriptor extends PdfFontDescriptor {
PDFFontDescriptor(PdfTtfFont ttfFont, PdfObjectStream file)
: super(ttfFont, file);
}
@deprecated
class PDFFont extends PdfFont {
PDFFont(PdfDocument pdfDocument,
{String subtype = "/Type1", String baseFont = "/Helvetica"})
: super(pdfDocument, subtype: subtype, baseFont: baseFont);
}
@deprecated
class PDFFormXObject extends PdfFormXObject {
PDFFormXObject(PdfDocument pdfDocument) : super(pdfDocument);
}
@deprecated
class PDFGraphics extends PdfGraphics {
PDFGraphics(PdfPage page, PdfStream buf) : super(page, buf);
}
@deprecated
class PDFImage extends PdfImage {
PDFImage(PdfDocument pdfDocument,
{@required Uint8List image,
@required int width,
@required int height,
bool alpha = true,
bool alphaChannel = false})
: super(pdfDocument,
image: image,
width: width,
height: height,
alpha: alpha,
alphaChannel: alphaChannel);
}
@deprecated
class PDFInfo extends PdfInfo {
PDFInfo(PdfDocument pdfDocument,
{String title,
String author,
String creator,
String subject,
String keywords})
: super(pdfDocument,
title: title,
author: author,
creator: creator,
subject: subject,
keywords: keywords);
}
@deprecated
class PDFObjectStream extends PdfObjectStream {
PDFObjectStream(PdfDocument pdfDocument, {String type, bool isBinary = false})
: super(pdfDocument, type: type, isBinary: isBinary);
}
@deprecated
class PDFObject extends PdfObject {
PDFObject(PdfDocument pdfDocument, [String type]) : super(pdfDocument, type);
}
@deprecated
class PDFOutline extends PdfOutline {
@deprecated
static const PdfOutlineMode FITPAGE = PdfOutlineMode.fitpage;
@deprecated
static const PdfOutlineMode FITRECT = PdfOutlineMode.fitrect;
PDFOutline(PdfDocument pdfDocument,
{String title, PdfPage dest, double l, double b, double r, double t})
: super(pdfDocument,
title: title, dest: dest, rect: PdfRect.fromLTRB(l, t, r, b));
}
@deprecated
class PDFOutput extends PdfOutput {
PDFOutput(PdfStream os) : super(os);
}
@deprecated
class PDFPageFormat extends PdfPageFormat {
static const a4 = PdfPageFormat.a4;
static const a3 = PdfPageFormat.a3;
static const a5 = PdfPageFormat.a5;
static const letter = PdfPageFormat.letter;
static const legal = PdfPageFormat.legal;
static const point = PdfPageFormat.point;
static const inch = PdfPageFormat.inch;
static const cm = PdfPageFormat.cm;
static const mm = PdfPageFormat.mm;
static const A4 = a4;
static const A3 = a3;
static const A5 = a5;
static const LETTER = letter;
static const LEGAL = legal;
static const PT = point;
static const IN = inch;
static const CM = cm;
static const MM = mm;
const PDFPageFormat(double width, double height) : super(width, height);
}
@deprecated
class PDFPageList extends PdfPageList {
PDFPageList(PdfDocument pdfDocument) : super(pdfDocument);
}
@deprecated
class PDFPage extends PdfPage {
PDFPage(PdfDocument pdfDocument, {PdfPageFormat pageFormat})
: super(pdfDocument, pageFormat: pageFormat);
/// Returns the page's PageFormat.
/// @return PageFormat describing the page size in device units (72dpi)
/// use pageFormat
@deprecated
PdfPageFormat getPageFormat() {
return pageFormat;
}
/// Gets the dimensions of the page.
/// @return a Dimension object containing the width and height of the page.
/// use pageFormat.dimension
@deprecated
PdfPoint getDimension() => new PdfPoint(pageFormat.width, pageFormat.height);
/// This method adds a text note to the document.
/// @param note Text of the note
/// @param x Coordinate of note
/// @param y Coordinate of note
/// @param w Width of the note
/// @param h Height of the note
/// @return Returns the annotation, so other settings can be changed.
@deprecated
PdfAnnot addNote(String note, double x, y, w, h) {
var xy1 = cxy(x, y + h);
var xy2 = cxy(x + w, y);
PdfAnnot ob = new PdfAnnot.text(
this, PdfRect.fromLTRB(xy1.x, xy1.y, xy2.x, xy2.y), note);
return ob;
}
/// Adds a hyperlink to the document.
/// @param x Coordinate of active area
/// @param y Coordinate of active area
/// @param w Width of the active area
/// @param h Height of the active area
/// @param dest Page that will be displayed when the link is activated. When
/// displayed, the zoom factor will be changed to fit the display.
/// @param vx Coordinate of view area
/// @param vy Coordinate of view area
/// @param vw Width of the view area
/// @param vh Height of the view area
/// @return Returns the annotation, so other settings can be changed.
@deprecated
PdfAnnot addLink(double x, y, w, h, PdfObject dest,
[double vx = PDFAnnot.FULL_PAGE,
vy = PDFAnnot.FULL_PAGE,
vw = PDFAnnot.FULL_PAGE,
vh = PDFAnnot.FULL_PAGE]) {
var xy1 = cxy(x, y + h);
var xy2 = cxy(x + w, y);
var xy3 = cxy(vx, vy + vh);
var xy4 = cxy(vx + vw, vy);
PdfAnnot ob = new PdfAnnot.link(
this,
PdfRect.fromLTRB(xy1.x, xy1.y, xy2.x, xy2.y),
dest,
PdfRect.fromLTRB(xy3.x, xy3.y, xy4.x, xy4.y));
return ob;
}
/// This method attaches an outline to the current page being generated. When
/// selected, the outline displays the top of the page.
/// @param title Outline title to attach
/// @param x Left coordinate of region
/// @param y Bottom coordinate of region
/// @param w Width of region
/// @param h Height coordinate of region
/// @return [PdfOutline] object created, for addSubOutline if required.
@deprecated
PdfOutline addOutline(String title,
{double x, double y, double w, double h}) {
PdfPoint xy1 = cxy(x, y + h);
PdfPoint xy2 = cxy(x + w, y);
PdfOutline outline = new PdfOutline(pdfDocument,
title: title,
dest: this,
rect: PdfRect.fromLTRB(xy1.x, xy2.y, xy2.x, xy1.y));
pdfDocument.outline.outlines.add(outline);
return outline;
}
/// This utility method converts the y coordinate to User space
/// within the page.
/// @param x Coordinate in User space
/// @param y Coordinate in User space
/// @return y Coordinate in User space
@deprecated
double cy(double x, double y) => cxy(x, y).y;
/// This utility method converts the x coordinate to User space
/// within the page.
/// @param x Coordinate in User space
/// @param y Coordinate in User space
/// @return x Coordinate in User space
@deprecated
double cx(double x, double y) => cxy(x, y).x;
/// This utility method converts the coordinates to User space
/// within the page.
/// @param x Coordinate in User space
/// @param y Coordinate in User space
/// @return array containing the x & y Coordinate in User space
@deprecated
PdfPoint cxy(double x, double y) => new PdfPoint(x, pageFormat.height - y);
}
@deprecated
class PDFPoint extends PdfPoint {
@deprecated
double get w => x;
@deprecated
double get h => y;
PDFPoint(double w, double h) : super(w, h);
}
@deprecated
class PDFRect extends PdfRect {
const PDFRect(double x, double y, double w, double h) : super(x, y, w, h);
}
@deprecated
class PDFStream extends PdfStream {}
@deprecated
class TTFParser extends TtfParser {
TTFParser(ByteData bytes) : super(bytes);
}
@deprecated
class PDFTTFFont extends PdfTtfFont {
PDFTTFFont(PdfDocument pdfDocument, ByteData bytes)
: super(pdfDocument, bytes);
}
@deprecated
class PDFXObject extends PdfXObject {
PDFXObject(PdfDocument pdfDocument, String subtype)
: super(pdfDocument, subtype);
}
@deprecated
enum PDFPageMode { NONE, OUTLINES, THUMBS, FULLSCREEN }
@deprecated
enum PDFLineCap { JOIN_MITER, JOIN_ROUND, JOIN_BEVEL }
@deprecated
class PDFXref extends PdfXref {
PDFXref(int id, int offset) : super(id, offset);
}
... ...
... ... @@ -18,65 +18,63 @@
part of pdf;
enum PDFPageMode {
enum PdfPageMode {
/// This page mode indicates that the document
/// should be opened just with the page visible. This is the default
NONE,
none,
/// This page mode indicates that the Outlines
/// should also be displayed when the document is opened.
OUTLINES,
outlines,
/// This page mode indicates that the Thumbnails should be visible when the
/// document first opens.
THUMBS,
thumbs,
/// This page mode indicates that when the document is opened, it is displayed
/// in full-screen-mode. There is no menu bar, window controls nor any other
/// window present.
FULLSCREEN
fullscreen
}
typedef List<int> DeflateCallback(List<int> data);
/// <p>This class is the base of the PDF generator. A PDFDocument class is
/// This class is the base of the Pdf generator. A [PdfDocument] class is
/// created for a document, and each page, object, annotation,
/// etc is added to the document.
/// Once complete, the document can be written to a Stream, and the PDF
/// Once complete, the document can be written to a Stream, and the Pdf
/// document's internal structures are kept in sync.
class PDFDocument {
class PdfDocument {
/// This is used to allocate objects a unique serial number in the document.
int _objser;
/// This vector contains each indirect object within the document.
final Set<PDFObject> objects = new Set<PDFObject>();
final Set<PdfObject> objects = new Set<PdfObject>();
/// This is the Catalog object, which is required by each PDF Document
PDFCatalog catalog;
/// This is the Catalog object, which is required by each Pdf Document
PdfCatalog catalog;
/// This is the info object. Although this is an optional object, we
/// include it.
PDFInfo info;
PdfInfo info;
/// This is the Pages object, which is required by each PDF Document
PDFPageList pdfPageList;
/// This is the Pages object, which is required by each Pdf Document
PdfPageList pdfPageList;
/// This is the Outline object, which is optional
PDFOutline _outline;
PdfOutline _outline;
/// This holds a PDFObject describing the default border for annotations.
/// This holds a [PdfObject] describing the default border for annotations.
/// It's only used when the document is being written.
PDFObject defaultOutlineBorder;
PdfObject defaultOutlineBorder;
/// Callback to compress the stream in the pdf file.
/// Use `deflate: zlib.encode` if using dart:io
/// No compression by default
final DeflateCallback deflate;
/// <p>
/// These map the page modes just defined to the pagemodes setting of PDF.
/// </p>
static const _PDF_PAGE_MODES = const [
/// These map the page modes just defined to the pagemodes setting of Pdf.
static const _PdfPageModes = const [
"/UseNone",
"/UseOutlines",
"/UseThumbs",
... ... @@ -84,38 +82,38 @@ class PDFDocument {
];
/// This holds the current fonts
final Set<PDFFont> fonts = new Set<PDFFont>();
final Set<PdfFont> fonts = new Set<PdfFont>();
/// Creates a new serial number
int _genSerial() => _objser++;
/// <p>This creates a PDF document</p>
/// This creates a Pdf document
/// @param pagemode an int, determines how the document will present itself to
/// the viewer when it first opens.
PDFDocument({PDFPageMode pageMode = PDFPageMode.NONE, this.deflate}) {
PdfDocument({PdfPageMode pageMode = PdfPageMode.none, this.deflate}) {
_objser = 1;
// Now create some standard objects
pdfPageList = new PDFPageList(this);
catalog = new PDFCatalog(this, pdfPageList, pageMode);
info = new PDFInfo(this);
pdfPageList = new PdfPageList(this);
catalog = new PdfCatalog(this, pdfPageList, pageMode);
info = new PdfInfo(this);
}
/// <p>This returns a specific page. It's used mainly when using a
/// Serialized template file.</p>
/// This returns a specific page. It's used mainly when using a
/// Serialized template file.
///
/// ?? How does a serialized template file work ???
///
/// @param page page number to return
/// @return PDFPage at that position
PDFPage page(int page) {
/// @return [PdfPage] at that position
PdfPage page(int page) {
return pdfPageList.getPage(page);
}
/// @return the root outline
PDFOutline get outline {
PdfOutline get outline {
if (_outline == null) {
_outline = new PDFOutline(this);
_outline = new PdfOutline(this);
catalog.outlines = _outline;
}
return _outline;
... ... @@ -123,21 +121,21 @@ class PDFDocument {
/// This writes the document to an OutputStream.
///
/// <p><b>Note:</b> You can call this as many times as you wish, as long as
/// Note: You can call this as many times as you wish, as long as
/// the calls are not running at the same time.
///
/// <p>Also, objects can be added or amended between these calls.
/// Also, objects can be added or amended between these calls.
///
/// <p>Also, the OutputStream is not closed, but will be flushed on
/// Also, the OutputStream is not closed, but will be flushed on
/// completion. It is up to the caller to close the stream.
///
/// @param os OutputStream to write the document to
void write(PDFStream os) {
PDFOutput pos = new PDFOutput(os);
void write(PdfStream os) {
PdfOutput pos = new PdfOutput(os);
// Write each object to the PDFStream. We call via the output
// Write each object to the [PdfStream]. We call via the output
// as that builds the xref table
for (PDFObject o in objects) {
for (PdfObject o in objects) {
pos.write(o);
}
... ... @@ -146,7 +144,7 @@ class PDFDocument {
}
List<int> save() {
PDFStream os = new PDFStream();
PdfStream os = new PdfStream();
write(os);
return os.output();
}
... ...
... ... @@ -18,21 +18,20 @@
part of pdf;
class PDFFont extends PDFObject {
/// The PDF type of the font, usually /Type1
class PdfFont extends PdfObject {
/// Thedf type of the font, usually /Type1
final String subtype;
/// The font's real name
String baseFont;
/// Constructs a PDFFont. This will attempt to map the font from a known
/// Java font name to that in PDF, defaulting to Helvetica if not possible.
/// Constructs a [PdfFont]. This will attempt to map the font from a known
/// font name to that in Pdf, defaulting to Helvetica if not possible.
///
/// @param name The document name, ie /F1
/// @param type The pdf type, ie /Type1
/// @param font The font name, ie Helvetica
/// @param style The java.awt.Font style, ie: Font.PLAIN
PDFFont(PDFDocument pdfDocument,
/// @param subtype The pdf type, ie /Type1
/// @param baseFont The font name, ie /Helvetica
PdfFont(PdfDocument pdfDocument,
{this.subtype = "/Type1", this.baseFont = "/Helvetica"})
: super(pdfDocument, "/Font") {
pdfDocument.fonts.add(this);
... ... @@ -45,24 +44,24 @@ class PDFFont extends PDFObject {
void prepare() {
super.prepare();
params["/Subtype"] = PDFStream.string(subtype);
params["/Name"] = PDFStream.string(name);
params["/BaseFont"] = PDFStream.string(baseFont);
params["/Encoding"] = PDFStream.string("/WinAnsiEncoding");
params["/Subtype"] = PdfStream.string(subtype);
params["/Name"] = PdfStream.string(name);
params["/BaseFont"] = PdfStream.string(baseFont);
params["/Encoding"] = PdfStream.string("/WinAnsiEncoding");
}
double glyphAdvance(int charCode) {
return 0.454;
}
PDFRect glyphBounds(int charCode) {
return const PDFRect(0.0, 0.0, 0.4, 1.0);
PdfRect glyphBounds(int charCode) {
return const PdfRect(0.0, 0.0, 0.4, 1.0);
}
PDFRect stringBounds(String s) {
PdfRect stringBounds(String s) {
var chars = latin1.encode(s);
if (chars.length == 0) return const PDFRect(0.0, 0.0, 0.0, 0.0);
if (chars.length == 0) return const PdfRect(0.0, 0.0, 0.0, 0.0);
var n = 0;
var c = chars[n];
... ... @@ -80,10 +79,10 @@ class PDFFont extends PDFObject {
w += n == chars.length - 1 ? r.w : glyphAdvance(c);
}
return new PDFRect(x, y, w, h);
return new PdfRect(x, y, w, h);
}
PDFPoint stringSize(String s) {
PdfPoint stringSize(String s) {
var chars = latin1.encode(s);
var w = 0.0;
... ... @@ -95,6 +94,6 @@ class PDFFont extends PDFObject {
w += glyphAdvance(c);
}
return new PDFPoint(w, h);
return new PdfPoint(w, h);
}
}
... ...
... ... @@ -18,31 +18,31 @@
part of pdf;
class PDFFontDescriptor extends PDFObject {
final PDFObjectStream file;
final PDFTTFFont ttfFont;
class PdfFontDescriptor extends PdfObject {
final PdfObjectStream file;
final PdfTtfFont ttfFont;
PDFFontDescriptor(this.ttfFont, this.file)
PdfFontDescriptor(this.ttfFont, this.file)
: super(ttfFont.pdfDocument, "/FontDescriptor");
@override
void prepare() {
super.prepare();
params["/FontName"] = PDFStream.string(ttfFont.baseFont);
params["/FontName"] = PdfStream.string(ttfFont.baseFont);
params["/FontFile2"] = file.ref();
params["/Flags"] = PDFStream.intNum(32);
params["/FontBBox"] = new PDFStream()
params["/Flags"] = PdfStream.intNum(32);
params["/FontBBox"] = new PdfStream()
..putStringArray([
ttfFont.font.xMin,
ttfFont.font.yMin,
ttfFont.font.xMax,
ttfFont.font.yMax
]);
params["/Ascent"] = PDFStream.intNum(ttfFont.font.ascent);
params["/Descent"] = PDFStream.intNum(ttfFont.font.descent);
params["/ItalicAngle"] = PDFStream.intNum(0);
params["/CapHeight"] = PDFStream.intNum(10);
params["/StemV"] = PDFStream.intNum(79);
params["/Ascent"] = PdfStream.intNum(ttfFont.font.ascent);
params["/Descent"] = PdfStream.intNum(ttfFont.font.descent);
params["/ItalicAngle"] = PdfStream.intNum(0);
params["/CapHeight"] = PdfStream.intNum(10);
params["/StemV"] = PdfStream.intNum(79);
}
}
... ...
... ... @@ -18,23 +18,23 @@
part of pdf;
class PDFFormXObject extends PDFXObject {
class PdfFormXObject extends PdfXObject {
/// The fonts associated with this page
final fonts = new Map<String, PDFFont>();
final fonts = new Map<String, PdfFont>();
/// The xobjects or other images in the pdf
final xobjects = new Map<String, PDFXObject>();
final xobjects = new Map<String, PdfXObject>();
PDFFormXObject(PDFDocument pdfDocument) : super(pdfDocument, '/Form') {
params["/FormType"] = PDFStream.string("1");
params["/BBox"] = PDFStream.string("[0 0 1000 1000]");
PdfFormXObject(PdfDocument pdfDocument) : super(pdfDocument, '/Form') {
params["/FormType"] = PdfStream.string("1");
params["/BBox"] = PdfStream.string("[0 0 1000 1000]");
}
/// set matrix
void setMatrix(Matrix4 t) {
var s = t.storage;
params["/Matrix"] =
PDFStream.string("[${s[0]} ${s[1]} ${s[4]} ${s[5]} ${s[12]} ${s[13]}]");
PdfStream.string("[${s[0]} ${s[1]} ${s[4]} ${s[5]} ${s[12]} ${s[13]}]");
}
@override
... ... @@ -43,20 +43,20 @@ class PDFFormXObject extends PDFXObject {
// Now the resources
/// This holds any resources for this FormXObject
final resources = new Map<String, PDFStream>();
final resources = new Map<String, PdfStream>();
// fonts
if (fonts.length > 0) {
resources["/Font"] = new PDFStream()..putObjectDictionary(fonts);
resources["/Font"] = new PdfStream()..putObjectDictionary(fonts);
}
// Now the XObjects
if (xobjects.length > 0) {
resources["/XObject"] = new PDFStream()..putObjectDictionary(xobjects);
resources["/XObject"] = new PdfStream()..putObjectDictionary(xobjects);
}
if (resources.length > 0) {
params["/Resources"] = PDFStream.dictionary(resources);
params["/Resources"] = PdfStream.dictionary(resources);
}
}
}
... ...
... ... @@ -18,21 +18,21 @@
part of pdf;
enum PDFLineCap { JOIN_MITER, JOIN_ROUND, JOIN_BEVEL }
enum PdfLineCap { joinMiter, joinRound, joinBevel }
class PDFGraphics {
class PdfGraphics {
/// Graphic context number
var _context = 0;
final PDFPage page;
final PdfPage page;
final PDFStream buf;
final PdfStream buf;
PDFGraphics(this.page, this.buf);
PdfGraphics(this.page, this.buf);
PDFFont get defaultFont {
PdfFont get defaultFont {
if (page.pdfDocument.fonts.length == 0) {
new PDFFont(page.pdfDocument);
new PdfFont(page.pdfDocument);
}
return page.pdfDocument.fonts.elementAt(0);
... ... @@ -54,16 +54,11 @@ class PDFGraphics {
buf.putString("W n\n");
}
/// <p>This releases any resources used by this Graphics object. You must use
/// this method once finished with it. Leaving it open will leave the PDF
/// stream in an inconsistent state, and will produce errors.</p>
/// <p>
/// <p>If this was created with Graphics.create() then the parent instance
/// can be used again. If not, then this closes the graphics operations for
/// this page when used with PDFJob.</p>
/// <p>
/// <p>When using PDFPage, you can create another fresh Graphics instance,
/// which will draw over this one.</p>
/// This releases any resources used by this Graphics object. You must use
/// this method once finished with it.
///
/// When using [PdfPage], you can create another fresh Graphics instance,
/// which will draw over this one.
void restoreContext() {
if (_context > 0) {
// restore graphics context
... ... @@ -78,21 +73,21 @@ class PDFGraphics {
_context++;
}
/// <p>Draws an image onto the page.</p>
/// <p>
/// <p>This method is implemented with ASCIIbase85 encoding and the
/// Draws an image onto the page.
///
/// This method is implemented with [Ascii85Encoder] encoding and the
/// zip stream deflater. It results in a stream that is anywhere
/// from 3 to 10 times as big as the image. This obviously needs some
/// improvement, but it works well for small images</p>
/// improvement, but it works well for small images
///
/// @param img The java.awt.Image
/// @param img The Image
/// @param x coordinate on page
/// @param y coordinate on page
/// @param w Width on page
/// @param h height on page
/// @param bgcolor Background colour
/// @return true if drawn
void drawImage(PDFImage img, double x, double y, [double w, double h]) {
void drawImage(PdfImage img, double x, double y, [double w, double h]) {
if (w == null) w = img.width.toDouble();
if (h == null) h = img.height.toDouble() * w / img.width.toDouble();
... ... @@ -104,7 +99,7 @@ class PDFGraphics {
}
/// Draws a line between two coordinates.
/// <p>
///
/// If the first coordinate is the same as the last one drawn
/// (i.e. a previous drawLine, moveto, etc) it is ignored.
///
... ... @@ -122,7 +117,7 @@ class PDFGraphics {
/// @param xp Array of x coordinates
/// @param yp Array of y coordinates
/// @param np number of points in polygon
void drawPolygon(Polygon p) {
void drawPolygon(PdfPolygon p) {
_polygon(p.points);
}
... ... @@ -144,7 +139,7 @@ class PDFGraphics {
}
/// We override Graphics.drawRect as it doesn't join the 4 lines.
/// Also, PDF provides us with a Rectangle operator, so we will use that.
/// Also, Pdf provides us with a Rectangle operator, so we will use that.
///
/// @param x coordinate
/// @param y coordinate
... ... @@ -164,7 +159,7 @@ class PDFGraphics {
/// @param x coordinate
/// @param y coordinate
/// @oaran s String to draw
void drawString(PDFFont font, size, String s, double x, double y) {
void drawString(PdfFont font, size, String s, double x, double y) {
if (!page.fonts.containsKey(font.name)) {
page.fonts[font.name] = font;
}
... ... @@ -177,7 +172,7 @@ class PDFGraphics {
/// Sets the color for drawing
///
/// @param c Color to use
void setColor(PDFColor color) {
void setColor(PdfColor color) {
buf.putString(
"${color.r} ${color.g} ${color.b} rg ${color.r} ${color.g} ${color.b} RG\n");
}
... ... @@ -234,18 +229,18 @@ class PDFGraphics {
/// @see #drawPolygon
/// @see #drawPolyline
/// @see #fillPolygon
void _polygon(List<PDFPoint> p) {
void _polygon(List<PdfPoint> p) {
// newPath() not needed here as moveto does it ;-)
moveTo(p[0].w, p[0].h);
moveTo(p[0].x, p[0].y);
for (int i = 1; i < p.length; i++) lineTo(p[i].w, p[i].h);
for (int i = 1; i < p.length; i++) lineTo(p[i].x, p[i].y);
}
void setLineCap(PDFLineCap cap) {
void setLineCap(PdfLineCap cap) {
buf.putString("${cap.index} J\n");
}
void setLineJoin(PDFLineCap join) {
void setLineJoin(PdfLineCap join) {
buf.putString("${join.index} j\n");
}
... ...
... ... @@ -18,7 +18,7 @@
part of pdf;
class PDFImage extends PDFXObject {
class PdfImage extends PdfXObject {
/// RGBA Image Data
final Uint8List image;
... ... @@ -36,15 +36,14 @@ class PDFImage extends PDFXObject {
/// Process alphaChannel only
final bool alphaChannel;
/// Creates a new <code>PDFImage</code> instance.
/// Creates a new [PdfImage] instance.
///
/// @param img an <code>Image</code> value
/// @param x an <code>int</code> value
/// @param y an <code>int</code> value
/// @param w an <code>int</code> value
/// @param h an <code>int</code> value
/// @param obs an <code>ImageObserver</code> value
PDFImage(PDFDocument pdfDocument,
/// @param imgage an [Uint8List] value
/// @param width
/// @param height
/// @param alpha if the image is transparent
/// @param alphaChannel if this is transparency mask
PdfImage(PdfDocument pdfDocument,
{@required this.image,
@required this.width,
@required this.height,
... ... @@ -55,25 +54,25 @@ class PDFImage extends PDFXObject {
assert(height != null),
super(pdfDocument, "/Image", isBinary: true) {
_name = "/Image$objser";
params["/Width"] = PDFStream.string(width.toString());
params["/Height"] = PDFStream.string(height.toString());
params["/BitsPerComponent"] = PDFStream.intNum(8);
params['/Name'] = PDFStream.string(_name);
params["/Width"] = PdfStream.string(width.toString());
params["/Height"] = PdfStream.string(height.toString());
params["/BitsPerComponent"] = PdfStream.intNum(8);
params['/Name'] = PdfStream.string(_name);
if (alphaChannel == false && alpha) {
var _sMask = new PDFImage(pdfDocument,
var _sMask = new PdfImage(pdfDocument,
image: image,
width: width,
height: height,
alpha: alpha,
alphaChannel: true);
params["/SMask"] = PDFStream.string("${_sMask.objser} 0 R");
params["/SMask"] = PdfStream.string("${_sMask.objser} 0 R");
}
if (alphaChannel) {
params["/ColorSpace"] = PDFStream.string("/DeviceGray");
params["/ColorSpace"] = PdfStream.string("/DeviceGray");
} else {
params["/ColorSpace"] = PDFStream.string("/DeviceRGB");
params["/ColorSpace"] = PdfStream.string("/DeviceRGB");
}
}
... ... @@ -107,6 +106,6 @@ class PDFImage extends PDFXObject {
/// Get the name
///
/// @return a <code>String</code> value
/// @return a String value
String get name => _name;
}
... ...
... ... @@ -18,7 +18,7 @@
part of pdf;
class PDFInfo extends PDFObject {
class PdfInfo extends PdfObject {
String author;
String creator;
String title;
... ... @@ -26,10 +26,10 @@ class PDFInfo extends PDFObject {
String keywords;
/// @param title Title of this document
PDFInfo(PDFDocument pdfDocument,
PdfInfo(PdfDocument pdfDocument,
{this.title, this.author, this.creator, this.subject, this.keywords})
: super(pdfDocument, null) {
params["/Producer"] = PDFStream.text("dpdf - David PHAM-VAN");
params["/Producer"] = PdfStream.text("dpdf - David PHAM-VAN");
}
/// @param os OutputStream to send the object to
... ... @@ -37,10 +37,10 @@ class PDFInfo extends PDFObject {
void prepare() {
super.prepare();
if (author != null) params["/Author"] = PDFStream.text(author);
if (creator != null) params["/Creator"] = PDFStream.text(creator);
if (title != null) params["/Title"] = PDFStream.text(title);
if (subject != null) params["/Subject"] = PDFStream.text(subject);
if (keywords != null) params["/Keywords"] = PDFStream.text(keywords);
if (author != null) params["/Author"] = PdfStream.text(author);
if (creator != null) params["/Creator"] = PdfStream.text(creator);
if (title != null) params["/Title"] = PdfStream.text(title);
if (subject != null) params["/Subject"] = PdfStream.text(subject);
if (keywords != null) params["/Keywords"] = PdfStream.text(keywords);
}
}
... ...
... ... @@ -18,9 +18,9 @@
part of pdf;
class PDFObject {
class PdfObject {
/// This is the object parameters.
final params = new Map<String, PDFStream>();
final params = new Map<String, PdfStream>();
/// This is the unique serial number for this object.
final int objser;
... ... @@ -28,29 +28,29 @@ class PDFObject {
/// This is the generation number for this object.
final int objgen = 0;
/// This allows any PDF object to refer to the document being constructed.
final PDFDocument pdfDocument;
/// This allows any Pdf object to refer to the document being constructed.
final PdfDocument pdfDocument;
/// This is usually called by extensors to this class, and sets the
/// PDF Object Type
/// @param type the PDF Object Type
PDFObject(this.pdfDocument, [String type])
/// Pdf Object Type
/// @param type the Pdf Object Type
PdfObject(this.pdfDocument, [String type])
: objser = pdfDocument._genSerial() {
if (type != null) {
params["/Type"] = PDFStream.string(type);
params["/Type"] = PdfStream.string(type);
}
pdfDocument.objects.add(this);
}
/// <p>Writes the object to the output stream.
/// This method must be overidden.</p>
/// Writes the object to the output stream.
/// This method must be overidden.
///
/// <p><b>Note:</b> It should not write any other objects, even if they are
/// it's Kids, as they will be written by the calling routine.</p>
/// Note: It should not write any other objects, even if they are
/// it's Kids, as they will be written by the calling routine.
///
/// @param os OutputStream to send the object to
void write(PDFStream os) {
void write(PdfStream os) {
prepare();
writeStart(os);
writeContent(os);
... ... @@ -64,14 +64,14 @@ class PDFObject {
/// The write method should call this before writing anything to the
/// OutputStream. This will send the standard header for each object.
///
/// <p>Note: There are a few rare cases where this method is not called.
/// Note: There are a few rare cases where this method is not called.
///
/// @param os OutputStream to write to
void writeStart(PDFStream os) {
void writeStart(PdfStream os) {
os.putString("$objser $objgen obj\n");
}
void writeContent(PDFStream os) {
void writeContent(PdfStream os) {
if (params.length > 0) {
os.putDictionary(params);
os.putString("\n");
... ... @@ -81,14 +81,14 @@ class PDFObject {
/// The write method should call this after writing anything to the
/// OutputStream. This will send the standard footer for each object.
///
/// <p>Note: There are a few rare cases where this method is not called.
/// Note: There are a few rare cases where this method is not called.
///
/// @param os OutputStream to write to
void writeEnd(PDFStream os) {
void writeEnd(PdfStream os) {
os.putString("endobj\n");
}
/// Returns the unique serial number in PDF format
/// @return the serial number in PDF format
PDFStream ref() => PDFStream.string("$objser $objgen R");
/// Returns the unique serial number in Pdf format
/// @return the serial number in Pdf format
PdfStream ref() => PdfStream.string("$objser $objgen R");
}
... ...
... ... @@ -18,20 +18,21 @@
part of pdf;
class PDFObjectStream extends PDFObject {
class PdfObjectStream extends PdfObject {
/// This holds the stream's content.
final PDFStream buf = new PDFStream();
final PdfStream buf = new PdfStream();
/// defines if the stream needs to be converted to ascii85
final bool isBinary;
/// Constructs a stream. The supplied type is stored in the stream's header
/// and is used by other objects that extend the PDFStream class (like
/// PDFImage).
/// <p>By default, the stream will be compressed.
/// and is used by other objects that extend the [PdfStream] class (like
/// [PdfImage]).
/// By default, the stream will be compressed.
///
/// @param type type for the stream
/// @see PDFImage
PDFObjectStream(PDFDocument pdfDocument, {String type, this.isBinary = false})
/// @see [PdfImage]
PdfObjectStream(PdfDocument pdfDocument, {String type, this.isBinary = false})
: super(pdfDocument, type);
List<int> _data;
... ... @@ -42,21 +43,21 @@ class PDFObjectStream extends PDFObject {
if (pdfDocument.deflate != null) {
_data = pdfDocument.deflate(buf.output());
params["/Filter"] = PDFStream.string("/FlateDecode");
params["/Filter"] = PdfStream.string("/FlateDecode");
} else if (isBinary) {
// This is a Ascii85 stream
var e = new Ascii85Encoder();
_data = e.convert(buf.output());
params["/Filter"] = PDFStream.string("/ASCII85Decode");
params["/Filter"] = PdfStream.string("/ASCII85Decode");
} else {
// This is a non-deflated stream
_data = buf.output();
}
params["/Length"] = PDFStream.intNum(_data.length);
params["/Length"] = PdfStream.intNum(_data.length);
}
@override
void writeContent(PDFStream os) {
void writeContent(PdfStream os) {
super.writeContent(os);
os.putString("stream\n");
... ...
... ... @@ -18,67 +18,63 @@
part of pdf;
class PDFOutline extends PDFObject {
enum PdfOutlineMode {
/// When jumping to the destination, display the whole page
fitpage,
/// When jumping to the destination, display the specified region
fitrect
}
class PdfOutline extends PdfObject {
/// This holds any outlines below us
List<PDFOutline> outlines = [];
List<PdfOutline> outlines = [];
/// For subentries, this points to it's parent outline
PDFOutline parent;
PdfOutline parent;
/// This is this outlines Title
final String title;
/// The destination page
PDFPage dest;
PdfPage dest;
/// The region on the destination page
final double l, b, r, t;
/// When jumping to the destination, display the whole page
static const bool FITPAGE = false;
/// When jumping to the destination, display the specified region
static const bool FITRECT = true;
final PdfRect rect;
/// How the destination is handled
bool destMode = FITPAGE;
PdfOutlineMode destMode = PdfOutlineMode.fitpage;
/// Constructs a PDF Outline object. When selected, the specified region
/// Constructs a Pdf Outline object. When selected, the specified region
/// is displayed.
///
/// @param title Title of the outline
/// @param dest The destination page
/// @param l left coordinate
/// @param b bottom coordinate
/// @param r right coordinate
/// @param t top coordinate
PDFOutline(PDFDocument pdfDocument,
{this.title, this.dest, this.l, this.b, this.r, this.t})
/// @param rect coordinate
PdfOutline(PdfDocument pdfDocument, {this.title, this.dest, this.rect})
: super(pdfDocument, "/Outlines");
/// This method creates an outline, and attaches it to this one.
/// When the outline is selected, the supplied region is displayed.
///
/// <p>Note: the coordiates are in Java space. They are converted to User
/// Note: the coordiates are in User space. They are converted to User
/// space.
///
/// <p>This allows you to have an outline for say a Chapter,
/// This allows you to have an outline for say a Chapter,
/// then under the chapter, one for each section. You are not really
/// limited on how deep you go, but it's best not to go below say 6 levels,
/// for the reader's sake.
///
/// @param title Title of the outline
/// @param dest The destination page
/// @param x coordinate of region in Java space
/// @param y coordinate of region in Java space
/// @param w width of region in Java space
/// @param h height of region in Java space
/// @return PDFOutline object created, for creating sub-outlines
PDFOutline add({String title, PDFPage dest, double x, y, w, h}) {
var xy1 = dest.cxy(x, y + h);
var xy2 = dest.cxy(x + w, y);
PDFOutline outline = new PDFOutline(pdfDocument,
title: title, dest: dest, l: xy1.w, b: xy1.h, r: xy2.w, t: xy2.h);
/// @param x coordinate of region in User space
/// @param y coordinate of region in User space
/// @param w width of region in User space
/// @param h height of region in User space
/// @return [PdfOutline] object created, for creating sub-outlines
PdfOutline add({String title, PdfPage dest, PdfRect rect}) {
PdfOutline outline =
new PdfOutline(pdfDocument, title: title, dest: dest, rect: rect);
// Tell the outline of ourselves
outline.parent = this;
return outline;
... ... @@ -91,23 +87,24 @@ class PDFOutline extends PDFObject {
// These are for kids only
if (parent != null) {
params["/Title"] = PDFStream.string(title);
var dests = new List<PDFStream>();
params["/Title"] = PdfStream.string(title);
var dests = new List<PdfStream>();
dests.add(dest.ref());
if (destMode == FITPAGE) {
dests.add(PDFStream.string("/Fit"));
if (destMode == PdfOutlineMode.fitpage) {
dests.add(PdfStream.string("/Fit"));
} else {
dests.add(PDFStream.string("/FitR $l $b $r $t"));
dests.add(
PdfStream.string("/FitR ${rect.l} ${rect.b} ${rect.r} ${rect.t}"));
}
params["/Parent"] = parent.ref();
params["/Dest"] = PDFStream.array(dests);
params["/Dest"] = PdfStream.array(dests);
// were a decendent, so by default we are closed. Find out how many
// entries are below us
int c = descendants();
if (c > 0) {
params["/Count"] = PDFStream.intNum(-c);
params["/Count"] = PdfStream.intNum(-c);
}
int index = parent.getIndex(this);
... ... @@ -123,7 +120,7 @@ class PDFOutline extends PDFObject {
} else {
// the number of outlines in this document
// were the top level node, so all are open by default
params["/Count"] = PDFStream.intNum(outlines.length);
params["/Count"] = PdfStream.intNum(outlines.length);
}
// These only valid if we have children
... ... @@ -139,9 +136,9 @@ class PDFOutline extends PDFObject {
/// This is called by children to find their position in this outlines
/// tree.
///
/// @param outline PDFOutline to search for
/// @param outline [PdfOutline] to search for
/// @return index within Vector
int getIndex(PDFOutline outline) => outlines.indexOf(outline);
int getIndex(PdfOutline outline) => outlines.indexOf(outline);
/// Returns the last index in this outline
/// @return last index in outline
... ... @@ -150,7 +147,7 @@ class PDFOutline extends PDFObject {
/// Returns the outline at a specified position.
/// @param i index
/// @return the node at index i
PDFOutline getNode(int i) => outlines[i];
PdfOutline getNode(int i) => outlines[i];
/// Returns the total number of descendants below this one.
/// @return the number of descendants below this one
... ... @@ -158,7 +155,7 @@ class PDFOutline extends PDFObject {
int c = outlines.length; // initially the number of kids
// now call each one for their descendants
for (PDFOutline o in outlines) {
for (PdfOutline o in outlines) {
c += o.descendants();
}
... ...
... ... @@ -18,37 +18,37 @@
part of pdf;
class PDFOutput {
/// This is the actual PDFStream used to write to.
final PDFStream os;
class PdfOutput {
/// This is the actual [PdfStream] used to write to.
final PdfStream os;
/// This vector contains offsets of each object
List<PDFXref> offsets = [];
List<PdfXref> offsets = [];
/// This is used to track the /Root object (catalog)
PDFObject rootID;
PdfObject rootID;
/// This is used to track the /Info object (info)
PDFObject infoID;
PdfObject infoID;
/// This creates a PDF PDFStream
/// This creates a Pdf [PdfStream]
///
/// @param os The output stream to write the PDF file to.
PDFOutput(this.os) {
/// @param os The output stream to write the Pdf file to.
PdfOutput(this.os) {
os.putString("%PDF-1.4\n");
os.putBytes([0x25, 0xC2, 0xA5, 0xC2, 0xB1, 0xC3, 0xAB, 0x0A]);
}
/// This method writes a PDFObject to the stream.
/// This method writes a [PdfObject] to the stream.
///
/// @param ob PDFObject Obeject to write
void write(PDFObject ob) {
/// @param ob [PdfObject] Obeject to write
void write(PdfObject ob) {
// Check the object to see if it's one that is needed in the trailer
// object
if (ob is PDFCatalog) rootID = ob;
if (ob is PDFInfo) infoID = ob;
if (ob is PdfCatalog) rootID = ob;
if (ob is PdfInfo) infoID = ob;
offsets.add(new PDFXref(ob.objser, os.offset));
offsets.add(new PdfXref(ob.objser, os.offset));
ob.write(os);
}
... ... @@ -56,7 +56,7 @@ class PDFOutput {
void close() {
// we use baos to speed things up a little.
// Also, offset is preserved, and marks the begining of this block.
// This is required by PDF at the end of the PDF file.
// This is required by Pdf at the end of the Pdf file.
int xref = os.offset;
... ... @@ -72,9 +72,9 @@ class PDFOutput {
var block = []; // xrefs in this block
// We need block 0 to exist
block.add(new PDFXref(0, 0, generation: 65535));
block.add(new PdfXref(0, 0, generation: 65535));
for (PDFXref x in offsets) {
for (PdfXref x in offsets) {
if (firstid == -1) firstid = x.id;
// check to see if block is in range (-1 means empty)
... ... @@ -120,14 +120,14 @@ class PDFOutput {
os.putString(">>\nstartxref\n$xref\n%%EOF\n");
}
/// Writes a block of references to the PDF file
/// Writes a block of references to the Pdf file
/// @param firstid ID of the first reference in this block
/// @param block Vector containing the references in this block
void writeblock(int firstid, var block) {
os.putString("$firstid ${block.length}\n");
//os.write("\n0000000000 65535 f\n");
for (PDFXref x in block) {
for (PdfXref x in block) {
os.putString(x.ref());
os.putString("\n");
}
... ...
... ... @@ -18,137 +18,62 @@
part of pdf;
class PDFPage extends PDFObject {
class PdfPage extends PdfObject {
/// This is this page format, ie the size of the page, margins, and rotation
PDFPageFormat pageFormat;
PdfPageFormat pageFormat;
/// This holds the contents of the page.
List<PDFObjectStream> contents = [];
List<PdfObjectStream> contents = [];
/// Object ID that contains a thumbnail sketch of the page.
/// -1 indicates no thumbnail.
PDFObject thumbnail;
PdfObject thumbnail;
/// This holds any Annotations contained within this page.
List<PDFAnnot> annotations = [];
List<PdfAnnot> annotations = [];
/// The fonts associated with this page
final fonts = new Map<String, PDFFont>();
final fonts = new Map<String, PdfFont>();
/// The xobjects or other images in the pdf
final xObjects = new Map<String, PDFXObject>();
final xObjects = new Map<String, PdfXObject>();
/// This constructs a Page object, which will hold any contents for this
/// page.
///
/// <p>Once created, it is added to the document via the PDF.add() method.
/// Once created, it is added to the document via the [PdfDocument.add()] method.
///
/// @param orientation Orientation: 0, 90 or 270
/// @see PageFormat#PORTRAIT
/// @see PageFormat#LANDSCAPE
/// @see PageFormat#REVERSE_LANDSCAPE
/// @param pageFormat PageFormat describing the page size
PDFPage(PDFDocument pdfDocument, {this.pageFormat})
/// @param pdfDocument Document
/// @param pageFormat [PdfPageFormat] describing the page size
PdfPage(PdfDocument pdfDocument, {this.pageFormat})
: super(pdfDocument, "/Page") {
pdfDocument.pdfPageList.pages.add(this);
if (pageFormat == null) pageFormat = PDFPageFormat.a4;
if (pageFormat == null) pageFormat = PdfPageFormat.a4;
}
/// This returns a PDFGraphics object, which can then be used to render
/// on to this page. If a previous PDFGraphics object was used, this object
/// This returns a [PdfGraphics] object, which can then be used to render
/// on to this page. If a previous [PdfGraphics] object was used, this object
/// is appended to the page, and will be drawn over the top of any previous
/// objects.
///
/// @return a new PDFGraphics object to be used to draw this page.
PDFGraphics getGraphics() {
var stream = new PDFObjectStream(pdfDocument);
var g = new PDFGraphics(this, stream.buf);
/// @return a new [PdfGraphics] object to be used to draw this page.
PdfGraphics getGraphics() {
var stream = new PdfObjectStream(pdfDocument);
var g = new PdfGraphics(this, stream.buf);
contents.add(stream);
return g;
}
/// Returns the page's PageFormat.
/// @return PageFormat describing the page size in device units (72dpi)
/// use pageFormat
@deprecated
PDFPageFormat getPageFormat() {
return pageFormat;
}
/// Gets the dimensions of the page.
/// @return a Dimension object containing the width and height of the page.
/// use pageFormat.dimension
@deprecated
PDFPoint getDimension() => new PDFPoint(pageFormat.width, pageFormat.height);
/// This adds an Annotation to the page.
///
/// <p>As with other objects, the annotation must be added to the pdf
/// document using PDF.add() before adding to the page.
/// As with other objects, the annotation must be added to the pdf
/// document using [PdfDocument.add()] before adding to the page.
///
/// @param ob Annotation to add.
void addAnnotation(PDFObject ob) {
void addAnnotation(PdfObject ob) {
annotations.add(ob);
}
/// This method adds a text note to the document.
/// @param note Text of the note
/// @param x Coordinate of note
/// @param y Coordinate of note
/// @param w Width of the note
/// @param h Height of the note
/// @return Returns the annotation, so other settings can be changed.
PDFAnnot addNote(String note, double x, y, w, h) {
var xy1 = cxy(x, y + h);
var xy2 = cxy(x + w, y);
PDFAnnot ob = new PDFAnnot.text(this, xy1.w, xy1.h, xy2.w, xy2.h, note);
return ob;
}
/// Adds a hyperlink to the document.
/// @param x Coordinate of active area
/// @param y Coordinate of active area
/// @param w Width of the active area
/// @param h Height of the active area
/// @param dest Page that will be displayed when the link is activated. When
/// displayed, the zoom factor will be changed to fit the display.
/// @param vx Coordinate of view area
/// @param vy Coordinate of view area
/// @param vw Width of the view area
/// @param vh Height of the view area
/// @return Returns the annotation, so other settings can be changed.
PDFAnnot addLink(double x, y, w, h, PDFObject dest,
[double vx = PDFAnnot.FULL_PAGE,
vy = PDFAnnot.FULL_PAGE,
vw = PDFAnnot.FULL_PAGE,
vh = PDFAnnot.FULL_PAGE]) {
var xy1 = cxy(x, y + h);
var xy2 = cxy(x + w, y);
var xy3 = cxy(vx, vy + vh);
var xy4 = cxy(vx + vw, vy);
PDFAnnot ob = new PDFAnnot.link(
this, xy1.w, xy1.h, xy2.w, xy2.h, dest, xy3.w, xy3.h, xy4.w, xy4.h);
return ob;
}
/// This method attaches an outline to the current page being generated. When
/// selected, the outline displays the top of the page.
/// @param title Outline title to attach
/// @param x Left coordinate of region
/// @param y Bottom coordinate of region
/// @param w Width of region
/// @param h Height coordinate of region
/// @return PDFOutline object created, for addSubOutline if required.
PDFOutline addOutline(String title,
{double x, double y, double w, double h}) {
PDFPoint xy1 = cxy(x, y + h);
PDFPoint xy2 = cxy(x + w, y);
PDFOutline outline = new PDFOutline(pdfDocument,
title: title, dest: this, l: xy1.w, b: xy1.h, r: xy2.w, t: xy2.h);
pdfDocument.outline.outlines.add(outline);
return outline;
}
/// @param os OutputStream to send the object to
@override
void prepare() {
... ... @@ -158,7 +83,7 @@ class PDFPage extends PDFObject {
params["/Parent"] = pdfDocument.pdfPageList.ref();
// the /MediaBox for the page size
params["/MediaBox"] = new PDFStream()
params["/MediaBox"] = new PdfStream()
..putStringArray([0, 0, pageFormat.width, pageFormat.height]);
// Rotation (if not zero)
... ... @@ -173,25 +98,25 @@ class PDFPage extends PDFObject {
if (contents.length == 1) {
params["/Contents"] = contents[0].ref();
} else {
params["/Contents"] = new PDFStream()..putObjectArray(contents);
params["/Contents"] = new PdfStream()..putObjectArray(contents);
}
}
// Now the resources
/// This holds any resources for this page
final resources = new Map<String, PDFStream>();
final resources = new Map<String, PdfStream>();
// fonts
if (fonts.length > 0) {
resources["/Font"] = new PDFStream()..putObjectDictionary(fonts);
resources["/Font"] = new PdfStream()..putObjectDictionary(fonts);
}
// Now the XObjects
if (xObjects.length > 0) {
resources["/XObject"] = new PDFStream()..putObjectDictionary(xObjects);
resources["/XObject"] = new PdfStream()..putObjectDictionary(xObjects);
}
params["/Resources"] = PDFStream.dictionary(resources);
params["/Resources"] = PdfStream.dictionary(resources);
// The thumbnail
if (thumbnail != null) {
... ... @@ -200,28 +125,7 @@ class PDFPage extends PDFObject {
// The /Annots object
if (annotations.length > 0) {
params["/Annots"] = new PDFStream()..putObjectArray(annotations);
params["/Annots"] = new PdfStream()..putObjectArray(annotations);
}
}
/// This utility method converts the y coordinate from Java to User space
/// within the page.
/// @param x Coordinate in Java space
/// @param y Coordinate in Java space
/// @return y Coordinate in User space
double cy(double x, double y) => cxy(x, y).h;
/// This utility method converts the y coordinate from Java to User space
/// within the page.
/// @param x Coordinate in Java space
/// @param y Coordinate in Java space
/// @return x Coordinate in User space
double cx(double x, double y) => cxy(x, y).w;
/// This utility method converts the Java coordinates to User space
/// within the page.
/// @param x Coordinate in Java space
/// @param y Coordinate in Java space
/// @return array containing the x & y Coordinate in User space
PDFPoint cxy(double x, double y) => new PDFPoint(x, pageFormat.height - y);
}
... ...
... ... @@ -18,49 +18,30 @@
part of pdf;
class PDFPageFormat {
static const a4 = const PDFPageFormat(595.28, 841.89);
static const a3 = const PDFPageFormat(841.89, 1190.55);
static const a5 = const PDFPageFormat(420.94, 595.28);
static const letter = const PDFPageFormat(612.0, 792.0);
static const legal = const PDFPageFormat(612.0, 1008.0);
class PdfPageFormat {
static const a4 = const PdfPageFormat(595.28, 841.89);
static const a3 = const PdfPageFormat(841.89, 1190.55);
static const a5 = const PdfPageFormat(420.94, 595.28);
static const letter = const PdfPageFormat(612.0, 792.0);
static const legal = const PdfPageFormat(612.0, 1008.0);
static const point = 1.0;
static const inch = 72.0;
static const cm = inch / 2.54;
static const mm = inch / 25.4;
@deprecated
static const A4 = a4;
@deprecated
static const A3 = a3;
@deprecated
static const A5 = a5;
@deprecated
static const LETTER = letter;
@deprecated
static const LEGAL = legal;
@deprecated
static const PT = point;
@deprecated
static const IN = inch;
@deprecated
static const CM = cm;
@deprecated
static const MM = mm;
final double width;
final double height;
const PDFPageFormat(this.width, this.height);
const PdfPageFormat(this.width, this.height);
PDFPoint get dimension => new PDFPoint(width, height);
PdfPoint get dimension => new PdfPoint(width, height);
PDFPageFormat get landscape =>
width >= height ? this : PDFPageFormat(height, width);
PdfPageFormat get landscape =>
width >= height ? this : PdfPageFormat(height, width);
PDFPageFormat get portrait =>
height >= width ? this : PDFPageFormat(height, width);
PdfPageFormat get portrait =>
height >= width ? this : PdfPageFormat(height, width);
@override
String toString() {
... ...
... ... @@ -18,24 +18,23 @@
part of pdf;
class PDFPageList extends PDFObject {
class PdfPageList extends PdfObject {
/// This holds the pages
final List<PDFPage> pages = [];
final List<PdfPage> pages = [];
/// This constructs a PDF Pages object.
PDFPageList(PDFDocument pdfDocument) : super(pdfDocument, "/Pages");
/// This constructs a [PdfPageList] object.
PdfPageList(PdfDocument pdfDocument) : super(pdfDocument, "/Pages");
/// This returns a specific page. Used by the PDF class.
/// This returns a specific page. Used by the Pdf class.
/// @param page page number to return
/// @return PDFPage at that position
PDFPage getPage(int page) => pages[page];
/// @return [PdfPage] at that position
PdfPage getPage(int page) => pages[page];
/// @param os OutputStream to send the object to
@override
void prepare() {
super.prepare();
params["/Kids"] = new PDFStream()..putObjectArray(pages);
params["/Count"] = PDFStream.intNum(pages.length);
params["/Kids"] = new PdfStream()..putObjectArray(pages);
params["/Count"] = PdfStream.intNum(pages.length);
}
}
... ...
... ... @@ -18,10 +18,12 @@
part of pdf;
class PDFPoint {
final double w, h;
const PDFPoint(this.w, this.h);
@immutable
class PdfPoint {
final double x, y;
const PdfPoint(this.x, this.y);
@override
String toString() => "PDFPoint($w, $h)";
String toString() => "PdfPoint($x, $y)";
}
... ...
... ... @@ -18,13 +18,13 @@
part of pdf;
class Polygon {
List<PDFPoint> points;
class PdfPolygon {
List<PdfPoint> points;
Polygon(this.points);
PdfPolygon(this.points);
PDFRect getBounds() {
PdfRect getBounds() {
// TODO: Implement properly
return const PDFRect(0.0, 0.0, 0.0, 0.0);
return const PdfRect(0.0, 0.0, 0.0, 0.0);
}
}
... ...
... ... @@ -18,10 +18,22 @@
part of pdf;
class PDFRect {
@immutable
class PdfRect {
final double x, y, w, h;
const PDFRect(this.x, this.y, this.w, this.h);
const PdfRect(this.x, this.y, this.w, this.h);
factory PdfRect.fromLTRB(
double left, double top, double right, double bottom) {
return PdfRect(left, top, right - left, bottom - top);
}
double get l => x;
double get b => y;
double get r => x + w;
double get t => y + h;
@override
String toString() => "PDFRect($x, $y, $w, $h)";
String toString() => "PdfRect($x, $y, $w, $h)";
}
... ...
... ... @@ -18,10 +18,10 @@
part of pdf;
class PDFStream {
class PdfStream {
final _stream = List<int>();
void putStream(PDFStream s) {
void putStream(PdfStream s) {
_stream.addAll(s._stream);
}
... ... @@ -35,7 +35,7 @@ class PDFStream {
}
}
static PDFStream string(String s) => new PDFStream()..putString(s);
static PdfStream string(String s) => new PdfStream()..putString(s);
void putStringUtf16(String s) {
for (int codeUnit in s.codeUnits) {
... ... @@ -52,8 +52,8 @@ class PDFStream {
putString(d.toString());
}
static PDFStream num(double d) => new PDFStream()..putNum(d);
static PDFStream intNum(int i) => new PDFStream()..putString(i.toString());
static PdfStream num(double d) => new PdfStream()..putNum(d);
static PdfStream intNum(int i) => new PdfStream()..putString(i.toString());
void putText(String s) {
// Escape special characters
... ... @@ -79,13 +79,13 @@ class PDFStream {
putBytes(latin1.encode('(' + s + ')'));
}
static PDFStream text(String s) => new PDFStream()..putText(s);
static PdfStream text(String s) => new PdfStream()..putText(s);
void putBool(bool value) {
putString(value ? "true" : "false");
}
void putArray(List<PDFStream> values) {
void putArray(List<PdfStream> values) {
putString("[");
for (var val in values) {
putStream(val);
... ... @@ -94,7 +94,7 @@ class PDFStream {
putString("]");
}
void putObjectArray(List<PDFObject> values) {
void putObjectArray(List<PdfObject> values) {
putString("[");
for (var val in values) {
putStream(val.ref());
... ... @@ -107,10 +107,10 @@ class PDFStream {
putString("[" + values.join(" ") + "]");
}
static PDFStream array(List<PDFStream> values) =>
new PDFStream()..putArray(values);
static PdfStream array(List<PdfStream> values) =>
new PdfStream()..putArray(values);
void putDictionary(Map<String, PDFStream> values) {
void putDictionary(Map<String, PdfStream> values) {
putString("<< ");
values.forEach((k, v) {
putString("$k ");
... ... @@ -120,10 +120,10 @@ class PDFStream {
putString(">>");
}
static PDFStream dictionary(Map<String, PDFStream> values) =>
new PDFStream()..putDictionary(values);
static PdfStream dictionary(Map<String, PdfStream> values) =>
new PdfStream()..putDictionary(values);
void putObjectDictionary(Map<String, PDFObject> values) {
void putObjectDictionary(Map<String, PdfObject> values) {
putString("<< ");
values.forEach((k, v) {
putString("$k ");
... ...
... ... @@ -18,7 +18,7 @@
part of pdf;
class TTFParser {
class TtfParser {
static const _HEAD = "head";
static const _NAME = "name";
static const _HMTX = "hmtx";
... ... @@ -34,9 +34,9 @@ class TTFParser {
final advanceWidth = new List<double>();
final charToGlyphIndexMap = new Map<int, int>();
final glyphOffsets = new List<int>();
final glyphInfoMap = new Map<int, PDFRect>();
final glyphInfoMap = new Map<int, PdfRect>();
TTFParser(this.bytes) {
TtfParser(this.bytes) {
final numTables = bytes.getUint16(4);
for (var i = 0; i < numTables; i++) {
... ... @@ -210,7 +210,7 @@ class TTFParser {
final yMin = bytes.getInt16(baseOffset + offset + 4); // 4
final xMax = bytes.getInt16(baseOffset + offset + 6); // 6
final yMax = bytes.getInt16(baseOffset + offset + 8); // 8
glyphInfoMap[glyphIndex] = new PDFRect(
glyphInfoMap[glyphIndex] = new PdfRect(
xMin.toDouble() / unitsPerEm,
yMin.toDouble() / unitsPerEm,
xMax.toDouble() / unitsPerEm,
... ...
... ... @@ -18,25 +18,25 @@
part of pdf;
class PDFTTFFont extends PDFFont {
PDFObject unicodeCMap;
PDFFontDescriptor descriptor;
PDFArrayObject widthsObject;
class PdfTtfFont extends PdfFont {
PdfObject unicodeCMap;
PdfFontDescriptor descriptor;
PdfArrayObject widthsObject;
final widths = new List<String>();
final TTFParser font;
final TtfParser font;
int _charMin;
int _charMax;
/// Constructs a PDFTTFFont
PDFTTFFont(PDFDocument pdfDocument, ByteData bytes)
: font = new TTFParser(bytes),
/// Constructs a [PdfTtfFont]
PdfTtfFont(PdfDocument pdfDocument, ByteData bytes)
: font = new TtfParser(bytes),
super(pdfDocument, subtype: "/TrueType") {
baseFont = "/" + font.fontName.replaceAll(" ", "");
PDFObjectStream file = new PDFObjectStream(pdfDocument, isBinary: true);
PdfObjectStream file = new PdfObjectStream(pdfDocument, isBinary: true);
final data = bytes.buffer.asUint8List();
file.buf.putBytes(data);
file.params["/Length1"] = PDFStream.intNum(data.length);
file.params["/Length1"] = PdfStream.intNum(data.length);
_charMin = 32;
_charMax = 255;
... ... @@ -45,9 +45,9 @@ class PDFTTFFont extends PDFFont {
widths.add((glyphAdvance(i) * 1000.0).toString());
}
unicodeCMap = new PDFObject(pdfDocument);
descriptor = new PDFFontDescriptor(this, file);
widthsObject = new PDFArrayObject(pdfDocument, widths);
unicodeCMap = new PdfObject(pdfDocument);
descriptor = new PdfFontDescriptor(this, file);
widthsObject = new PdfArrayObject(pdfDocument, widths);
}
@override
... ... @@ -63,7 +63,7 @@ class PDFTTFFont extends PDFFont {
}
@override
PDFRect glyphBounds(int charCode) {
PdfRect glyphBounds(int charCode) {
var g = font.charToGlyphIndexMap[charCode];
if (g == null) {
... ... @@ -77,11 +77,11 @@ class PDFTTFFont extends PDFFont {
void prepare() {
super.prepare();
params["/FirstChar"] = PDFStream.intNum(_charMin);
params["/LastChar"] = PDFStream.intNum(_charMax);
params["/FirstChar"] = PdfStream.intNum(_charMin);
params["/LastChar"] = PdfStream.intNum(_charMax);
params["/Widths"] = widthsObject.ref();
params["/FontDescriptor"] = descriptor.ref();
// params["/Encoding"] = PDFStream.string("/Identity-H");
// params["/Encoding"] = PdfStream.string("/Identity-H");
// params["/ToUnicode"] = unicodeCMap.ref();
}
}
... ...
... ... @@ -18,9 +18,9 @@
part of pdf;
class PDFXObject extends PDFObjectStream {
PDFXObject(PDFDocument pdfDocument, String subtype, {bool isBinary = false})
class PdfXObject extends PdfObjectStream {
PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false})
: super(pdfDocument, type: '/XObject', isBinary: isBinary) {
params['/Subtype'] = PDFStream.string(subtype);
params['/Subtype'] = PdfStream.string(subtype);
}
}
... ...
... ... @@ -18,23 +18,23 @@
part of pdf;
class PDFXref {
/// The id of a PDF Object
class PdfXref {
/// The id of a Pdf Object
int id;
/// The offset within the PDF file
/// The offset within the Pdf file
int offset;
/// The generation of the object, usually 0
int generation = 0;
/// Creates a crossreference for a PDF Object
/// Creates a crossreference for a Pdf Object
/// @param id The object's ID
/// @param offset The object's position in the file
/// @param generation The object's generation, usually 0
PDFXref(this.id, this.offset, {this.generation = 0});
PdfXref(this.id, this.offset, {this.generation = 0});
/// @return The xref in the format of the xref section in the PDF file
/// @return The xref in the format of the xref section in the Pdf file
String ref() {
String rs = offset.toString().padLeft(10, '0') +
" " +
... ...
... ... @@ -11,13 +11,13 @@ void main() {
var img = new Uint32List(10 * 10);
img.fillRange(0, img.length - 1, 0x12345678);
var pdf = new PDFDocument(deflate: zlib.encode);
var pdf = new PdfDocument(deflate: zlib.encode);
var i = pdf.info;
i.author = "David PHAM-VAN";
i.creator = i.author;
i.title = "My Title";
i.subject = "My Subject";
var page = new PDFPage(pdf, pageFormat: const PDFPageFormat(500.0, 300.0));
var page = new PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0));
var g = page.getGraphics();
g.saveContext();
... ... @@ -26,9 +26,9 @@ void main() {
g.setTransform(tm);
// g.drawShape("M37 0H9C6.24 0 4 2.24 4 5v38c0 2.76 2.24 5 5 5h28c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM23 46c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm15-8H8V6h30v32z");
g.restoreContext();
var font1 = new PDFFont(pdf);
var font1 = new PdfFont(pdf);
var font2 = new PDFTTFFont(
var font2 = new PdfTtfFont(
pdf,
(new File("open-sans.ttf").readAsBytesSync() as Uint8List)
.buffer
... ... @@ -36,21 +36,21 @@ void main() {
var s = "Hello World!";
var r = font2.stringBounds(s);
const FS = 20.0;
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0 + r.x * FS, 30.0 + r.y * FS, r.w * FS, r.h * FS);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(font2, FS, s, 50.0, 30.0);
g.setColor(new PDFColor(1.0, 0.0, 0.0));
g.setColor(new PdfColor(1.0, 0.0, 0.0));
g.drawString(font2, 20.0, "Hé (Olà)", 50.0, 10.0);
g.drawLine(30.0, 30.0, 200.0, 200.0);
g.strokePath();
g.setColor(new PDFColor(1.0, 0.0, 0.0));
g.setColor(new PdfColor(1.0, 0.0, 0.0));
g.drawRect(300.0, 150.0, 50.0, 50.0);
g.fillPath();
g.setColor(new PDFColor(0.0, 0.5, 0.0));
var image = new PDFImage(pdf,
g.setColor(new PdfColor(0.0, 0.5, 0.0));
var image = new PdfImage(pdf,
image: img.buffer.asUint8List(), width: 10, height: 10);
for (var i = 10.0; i < 90.0; i += 5.0) {
g.saveContext();
... ...
... ... @@ -5,8 +5,8 @@ import "package:test/test.dart";
void main() {
test('Pdf1', () {
var pdf = new PDFDocument();
var page = new PDFPage(pdf, pageFormat: PDFPageFormat.a4);
var pdf = new PdfDocument();
var page = new PdfPage(pdf, pageFormat: PdfPageFormat.a4);
var g = page.getGraphics();
g.drawLine(30.0, 30.0, 200.0, 200.0);
... ...
... ... @@ -6,16 +6,16 @@ import 'package:test/test.dart';
void main() {
test('Pdf', () {
var pdf = new PDFDocument();
var pdf = new PdfDocument();
var i = pdf.info;
i.author = "David PHAM-VAN";
i.creator = i.author;
i.title = "My Title";
i.subject = "My Subject";
var page = new PDFPage(pdf, pageFormat: const PDFPageFormat(500.0, 300.0));
var page = new PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0));
var g = page.getGraphics();
var ttf = new PDFTTFFont(
var ttf = new PdfTtfFont(
pdf,
(new File("open-sans.ttf").readAsBytesSync() as Uint8List)
.buffer
... ... @@ -23,23 +23,23 @@ void main() {
var s = "Hello World!";
var r = ttf.stringBounds(s);
const FS = 20.0;
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0 + r.x * FS, 30.0 + r.y * FS, r.w * FS, r.h * FS);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(ttf, FS, s, 50.0, 30.0);
var roboto = new PDFTTFFont(
var roboto = new PdfTtfFont(
pdf,
(new File("roboto.ttf").readAsBytesSync() as Uint8List)
.buffer
.asByteData());
r = roboto.stringBounds(s);
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0 + r.x * FS, 130.0 + r.y * FS, r.w * FS, r.h * FS);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(roboto, FS, s, 50.0, 130.0);
var file = new File('file2.pdf');
... ...
... ... @@ -16,7 +16,7 @@ To load an image it is possible to use
var Image im;
var bytes = await im.toByteData(format: ui.ImageByteFormat.rawRgba);
PDFImage image = PDFImage(
PdfImage image = PdfImage(
pdf,
image: bytes.buffer.asUint8List(),
width: im.width,
... ... @@ -28,7 +28,7 @@ To use a TrueType font from a flutter bundle:
```dart
var font = await rootBundle.load("assets/open-sans.ttf");
PDFTTFFont ttf = new PDFTTFFont(pdf, font);
g.setColor(new PDFColor(0.3, 0.3, 0.3));
PdfTtfFont ttf = new PdfTtfFont(pdf, font);
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(ttf, 20.0, "Dart is awesome", 50.0, 30.0);
```
... ...
... ... @@ -19,21 +19,21 @@ class MyAppState extends State<MyApp> {
final shareWidget = new GlobalKey();
final previewContainer = new GlobalKey();
PDFDocument _generateDocument() {
final pdf = new PDFDocument(deflate: zlib.encode);
final page = new PDFPage(pdf, pageFormat: PDFPageFormat.a4);
PdfDocument _generateDocument() {
final pdf = new PdfDocument(deflate: zlib.encode);
final page = new PdfPage(pdf, pageFormat: PdfPageFormat.a4);
final g = page.getGraphics();
final font = new PDFFont(pdf);
final font = new PdfFont(pdf);
final top = page.pageFormat.height;
g.setColor(new PDFColor(0.0, 1.0, 1.0));
g.drawRect(50.0 * PDFPageFormat.mm, top - 80.0 * PDFPageFormat.mm,
100.0 * PDFPageFormat.mm, 50.0 * PDFPageFormat.mm);
g.setColor(new PdfColor(0.0, 1.0, 1.0));
g.drawRect(50.0 * PdfPageFormat.mm, top - 80.0 * PdfPageFormat.mm,
100.0 * PdfPageFormat.mm, 50.0 * PdfPageFormat.mm);
g.fillPath();
g.setColor(new PDFColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 10.0 * PDFPageFormat.mm,
top - 10.0 * PDFPageFormat.mm);
g.setColor(new PdfColor(0.3, 0.3, 0.3));
g.drawString(font, 12.0, "Hello World!", 10.0 * PdfPageFormat.mm,
top - 10.0 * PdfPageFormat.mm);
return pdf;
}
... ... @@ -61,9 +61,9 @@ class MyAppState extends State<MyApp> {
}
Future<void> _printScreen() async {
const margin = 10.0 * PDFPageFormat.mm;
final pdf = new PDFDocument(deflate: zlib.encode);
final page = new PDFPage(pdf, pageFormat: PDFPageFormat.a4);
const margin = 10.0 * PdfPageFormat.mm;
final pdf = new PdfDocument(deflate: zlib.encode);
final page = new PdfPage(pdf, pageFormat: PdfPageFormat.a4);
final g = page.getGraphics();
RenderRepaintBoundary boundary =
... ... @@ -84,7 +84,7 @@ class MyAppState extends State<MyApp> {
ih = im.height.toDouble() * iw / im.width.toDouble();
}
PDFImage image = PDFImage(pdf,
PdfImage image = PdfImage(pdf,
image: bytes.buffer.asUint8List(), width: im.width, height: im.height);
g.drawImage(image, margin + (w - iw) / 2.0,
page.pageFormat.height - margin - ih - (h - ih) / 2.0, iw, ih);
... ...
... ... @@ -27,7 +27,7 @@ import 'package:pdf/pdf.dart';
class Printing {
static const MethodChannel _channel = const MethodChannel('printing');
static Future<Null> printPdf({PDFDocument document, List<int> bytes}) async {
static Future<Null> printPdf({PdfDocument document, List<int> bytes}) async {
assert(document != null || bytes != null);
assert(!(document == null && bytes == null));
... ... @@ -41,7 +41,7 @@ class Printing {
}
static Future<Null> sharePdf(
{PDFDocument document, List<int> bytes, Rect bounds}) async {
{PdfDocument document, List<int> bytes, Rect bounds}) async {
assert(document != null || bytes != null);
assert(!(document == null && bytes == null));
... ...