Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
dart_pdf
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David PHAM-VAN
2021-03-08 17:04:30 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
3258ca15829f13057c2e1d76a1c0ebd1660902b6
3258ca15
1 parent
6ee4d26a
Add dynamicLayout setting to prevent iOS to freeze
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
144 additions
and
40 deletions
printing/ios/Classes/PrintJob.swift
printing/ios/Classes/PrintingPlugin.swift
printing/lib/src/interface.dart
printing/lib/src/method_channel.dart
printing/lib/src/pdf_preview.dart
printing/lib/src/printing.dart
printing/macos/Classes/PrintJob.swift
printing/macos/Classes/PrintingPlugin.swift
printing/test/printing_test.dart
printing/ios/Classes/PrintJob.swift
View file @
3258ca1
...
...
@@ -27,8 +27,10 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
private
var
pdfDocument
:
CGPDFDocument
?
private
var
urlObservation
:
NSKeyValueObservation
?
private
var
jobName
:
String
?
private
var
printerName
:
String
?
private
var
orientation
:
UIPrintInfo
.
Orientation
?
private
let
semaphore
=
DispatchSemaphore
(
value
:
0
)
private
var
dynamic
=
false
public
init
(
printing
:
PrintingPlugin
,
index
:
Int
)
{
self
.
printing
=
printing
...
...
@@ -47,9 +49,13 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
}
}
func
cancelJob
(
_
:
String
?)
{
func
cancelJob
(
_
error
:
String
?)
{
pdfDocument
=
nil
semaphore
.
signal
()
if
dynamic
{
semaphore
.
signal
()
}
else
{
printing
.
onCompleted
(
printJob
:
self
,
completed
:
false
,
error
:
error
as
NSString
?)
}
}
func
setDocument
(
_
data
:
Data
?)
{
...
...
@@ -58,23 +64,57 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
let
dataProvider
=
CGDataProvider
(
dataInfo
:
nil
,
data
:
bytesPointer
,
size
:
data
?
.
count
??
0
,
releaseData
:
dataProviderReleaseDataCallback
)
pdfDocument
=
CGPDFDocument
(
dataProvider
!
)
// Unblock the main thread
semaphore
.
signal
()
if
dynamic
{
// Unblock the main thread
semaphore
.
signal
()
return
}
let
controller
=
UIPrintInteractionController
.
shared
controller
.
delegate
=
self
let
printInfo
=
UIPrintInfo
.
printInfo
()
printInfo
.
jobName
=
jobName
!
printInfo
.
outputType
=
.
general
if
orientation
!=
nil
{
printInfo
.
orientation
=
orientation
!
orientation
=
nil
}
controller
.
printInfo
=
printInfo
controller
.
printPageRenderer
=
self
DispatchQueue
.
main
.
async
{
if
self
.
printerName
!=
nil
{
let
printerURL
=
URL
(
string
:
self
.
printerName
!
)
if
printerURL
==
nil
{
self
.
printing
.
onCompleted
(
printJob
:
self
,
completed
:
false
,
error
:
"Unable to find printer URL"
)
return
}
let
printer
=
UIPrinter
(
url
:
printerURL
!
)
controller
.
print
(
to
:
printer
,
completionHandler
:
self
.
completionHandler
)
}
else
{
controller
.
present
(
animated
:
true
,
completionHandler
:
self
.
completionHandler
)
}
}
}
override
public
var
numberOfPages
:
Int
{
printing
.
onLayout
(
printJob
:
self
,
width
:
paperRect
.
size
.
width
,
height
:
paperRect
.
size
.
height
,
marginLeft
:
printableRect
.
origin
.
x
,
marginTop
:
printableRect
.
origin
.
y
,
marginRight
:
paperRect
.
size
.
width
-
(
printableRect
.
origin
.
x
+
printableRect
.
size
.
width
),
marginBottom
:
paperRect
.
size
.
height
-
(
printableRect
.
origin
.
y
+
printableRect
.
size
.
height
)
)
// Block the main thread, waiting for a document
semaphore
.
wait
()
if
dynamic
{
printing
.
onLayout
(
printJob
:
self
,
width
:
paperRect
.
size
.
width
,
height
:
paperRect
.
size
.
height
,
marginLeft
:
printableRect
.
origin
.
x
,
marginTop
:
printableRect
.
origin
.
y
,
marginRight
:
paperRect
.
size
.
width
-
(
printableRect
.
origin
.
x
+
printableRect
.
size
.
width
),
marginBottom
:
paperRect
.
size
.
height
-
(
printableRect
.
origin
.
y
+
printableRect
.
size
.
height
)
)
// Block the main thread, waiting for a document
semaphore
.
wait
()
}
return
pdfDocument
?
.
numberOfPages
??
0
}
...
...
@@ -87,7 +127,8 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
printing
.
onCompleted
(
printJob
:
self
,
completed
:
completed
,
error
:
error
?
.
localizedDescription
as
NSString
?)
}
func
printPdf
(
name
:
String
,
withPageSize
size
:
CGSize
,
andMargin
_
:
CGRect
,
withPrinter
printerID
:
String
?)
{
func
printPdf
(
name
:
String
,
withPageSize
size
:
CGSize
,
andMargin
margin
:
CGRect
,
withPrinter
printerID
:
String
?,
dynamically
dyn
:
Bool
)
{
dynamic
=
dyn
let
printing
=
UIPrintInteractionController
.
isPrintingAvailable
if
!
printing
{
self
.
printing
.
onCompleted
(
printJob
:
self
,
completed
:
false
,
error
:
"Printing not available"
)
...
...
@@ -99,6 +140,7 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
}
jobName
=
name
printerName
=
printerID
let
controller
=
UIPrintInteractionController
.
shared
controller
.
delegate
=
self
...
...
@@ -128,7 +170,20 @@ public class PrintJob: UIPrintPageRenderer, UIPrintInteractionControllerDelegate
return
}
controller
.
present
(
animated
:
true
,
completionHandler
:
completionHandler
)
if
dynamic
{
controller
.
present
(
animated
:
true
,
completionHandler
:
completionHandler
)
return
}
self
.
printing
.
onLayout
(
printJob
:
self
,
width
:
size
.
width
,
height
:
size
.
height
,
marginLeft
:
margin
.
minX
,
marginTop
:
margin
.
minY
,
marginRight
:
size
.
width
-
margin
.
maxX
,
marginBottom
:
size
.
height
-
margin
.
maxY
)
}
static
func
sharePdf
(
data
:
Data
,
withSourceRect
rect
:
CGRect
,
andName
name
:
String
)
{
...
...
printing/ios/Classes/PrintingPlugin.swift
View file @
3258ca1
...
...
@@ -59,6 +59,7 @@ public class PrintingPlugin: NSObject, FlutterPlugin {
let
marginRight
=
CGFloat
((
args
[
"marginRight"
]
as!
NSNumber
)
.
floatValue
)
let
marginBottom
=
CGFloat
((
args
[
"marginBottom"
]
as!
NSNumber
)
.
floatValue
)
let
printJob
=
PrintJob
(
printing
:
self
,
index
:
args
[
"job"
]
as!
Int
)
let
dynamic
=
args
[
"dynamic"
]
as!
Bool
jobs
[
args
[
"job"
]
as!
UInt32
]
=
printJob
printJob
.
printPdf
(
name
:
name
,
withPageSize
:
CGSize
(
...
...
@@ -70,7 +71,8 @@ public class PrintingPlugin: NSObject, FlutterPlugin {
y
:
marginTop
,
width
:
width
-
marginRight
-
marginLeft
,
height
:
height
-
marginBottom
-
marginTop
),
withPrinter
:
printer
)
),
withPrinter
:
printer
,
dynamically
:
dynamic
)
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"sharePdf"
{
let
object
=
args
[
"doc"
]
as!
FlutterStandardTypedData
...
...
printing/lib/src/interface.dart
View file @
3258ca1
...
...
@@ -64,6 +64,7 @@ abstract class PrintingPlatform extends PlatformInterface {
LayoutCallback
onLayout
,
String
name
,
PdfPageFormat
format
,
bool
dynamicLayout
,
);
/// Enumerate the available printers on the system.
...
...
printing/lib/src/method_channel.dart
View file @
3258ca1
...
...
@@ -142,6 +142,7 @@ class MethodChannelPrinting extends PrintingPlatform {
LayoutCallback
onLayout
,
String
name
,
PdfPageFormat
format
,
bool
dynamicLayout
,
)
async
{
final
job
=
_printJobs
.
add
(
onCompleted:
Completer
<
bool
>(),
...
...
@@ -158,6 +159,7 @@ class MethodChannelPrinting extends PrintingPlatform {
'marginTop'
:
format
.
marginTop
,
'marginRight'
:
format
.
marginRight
,
'marginBottom'
:
format
.
marginBottom
,
'dynamic'
:
dynamicLayout
,
};
await
_channel
.
invokeMethod
<
int
>(
'printPdf'
,
params
);
...
...
printing/lib/src/pdf_preview.dart
View file @
3258ca1
...
...
@@ -34,6 +34,7 @@ class PdfPreview extends StatefulWidget {
this
.
pdfFileName
,
this
.
useActions
=
true
,
this
.
pages
,
this
.
dynamicLayout
=
true
,
})
:
super
(
key:
key
);
/// Called when a pdf document is needed
...
...
@@ -90,6 +91,11 @@ class PdfPreview extends StatefulWidget {
/// Pages to display. Default will display all the pages.
final
List
<
int
>?
pages
;
/// Request page re-layout to match the printer paper and margins.
/// Mitigate an issue with iOS and macOS print dialog that prevent any
/// channel message while opened.
final
bool
dynamicLayout
;
@override
_PdfPreviewState
createState
()
=>
_PdfPreviewState
();
}
...
...
@@ -512,6 +518,7 @@ class _PdfPreviewState extends State<PdfPreview> {
onLayout:
widget
.
build
,
name:
widget
.
pdfFileName
??
'Document'
,
format:
format
,
dynamicLayout:
widget
.
dynamicLayout
,
);
if
(
result
&&
widget
.
onPrinted
!=
null
)
{
...
...
printing/lib/src/printing.dart
View file @
3258ca1
...
...
@@ -40,12 +40,14 @@ mixin Printing {
required
LayoutCallback
onLayout
,
String
name
=
'Document'
,
PdfPageFormat
format
=
PdfPageFormat
.
standard
,
bool
dynamicLayout
=
true
,
})
{
return
PrintingPlatform
.
instance
.
layoutPdf
(
null
,
onLayout
,
name
,
format
,
dynamicLayout
,
);
}
...
...
@@ -122,12 +124,14 @@ mixin Printing {
required
LayoutCallback
onLayout
,
String
name
=
'Document'
,
PdfPageFormat
format
=
PdfPageFormat
.
standard
,
bool
dynamicLayout
=
true
,
})
{
return
PrintingPlatform
.
instance
.
layoutPdf
(
printer
,
onLayout
,
name
,
format
,
dynamicLayout
,
);
}
...
...
printing/macos/Classes/PrintJob.swift
View file @
3258ca1
...
...
@@ -30,6 +30,7 @@ public class PrintJob: NSView, NSSharingServicePickerDelegate {
private
var
pdfDocument
:
CGPDFDocument
?
private
var
page
:
CGPDFPage
?
private
let
semaphore
=
DispatchSemaphore
(
value
:
0
)
private
var
dynamic
=
false
public
init
(
printing
:
PrintingPlugin
,
index
:
Int
)
{
self
.
printing
=
printing
...
...
@@ -49,18 +50,20 @@ public class PrintJob: NSView, NSSharingServicePickerDelegate {
setFrameSize
(
size
)
setBoundsSize
(
size
)
printing
.
onLayout
(
printJob
:
self
,
width
:
printOperation
!.
printInfo
.
paperSize
.
width
,
height
:
printOperation
!.
printInfo
.
paperSize
.
height
,
marginLeft
:
printOperation
!.
printInfo
.
leftMargin
,
marginTop
:
printOperation
!.
printInfo
.
topMargin
,
marginRight
:
printOperation
!.
printInfo
.
rightMargin
,
marginBottom
:
printOperation
!.
printInfo
.
bottomMargin
)
// Block the main thread, waiting for a document
semaphore
.
wait
()
if
dynamic
{
printing
.
onLayout
(
printJob
:
self
,
width
:
printOperation
!.
printInfo
.
paperSize
.
width
,
height
:
printOperation
!.
printInfo
.
paperSize
.
height
,
marginLeft
:
printOperation
!.
printInfo
.
leftMargin
,
marginTop
:
printOperation
!.
printInfo
.
topMargin
,
marginRight
:
printOperation
!.
printInfo
.
rightMargin
,
marginBottom
:
printOperation
!.
printInfo
.
bottomMargin
)
// Block the main thread, waiting for a document
semaphore
.
wait
()
}
if
pdfDocument
!=
nil
{
range
.
pointee
.
length
=
pdfDocument
!.
numberOfPages
...
...
@@ -90,8 +93,16 @@ public class PrintJob: NSView, NSSharingServicePickerDelegate {
let
dataProvider
=
CGDataProvider
(
dataInfo
:
nil
,
data
:
bytesPointer
,
size
:
data
?
.
count
??
0
,
releaseData
:
dataProviderReleaseDataCallback
)
pdfDocument
=
CGPDFDocument
(
dataProvider
!
)
// Unblock the main thread
semaphore
.
signal
()
if
dynamic
{
// Unblock the main thread
semaphore
.
signal
()
return
}
DispatchQueue
.
main
.
async
{
let
window
=
NSApplication
.
shared
.
mainWindow
!
self
.
printOperation
!.
runModal
(
for
:
window
,
delegate
:
self
,
didRun
:
#selector(
self.printOperationDidRun(printOperation:success:contextInfo:)
)
,
contextInfo
:
nil
)
}
}
override
public
func
draw
(
_
:
NSRect
)
{
...
...
@@ -119,7 +130,8 @@ public class PrintJob: NSView, NSSharingServicePickerDelegate {
return
printers
}
public
func
printPdf
(
name
:
String
,
withPageSize
size
:
CGSize
,
andMargin
_
:
CGRect
,
withPrinter
printer
:
String
?)
{
public
func
printPdf
(
name
:
String
,
withPageSize
size
:
CGSize
,
andMargin
_
:
CGRect
,
withPrinter
printer
:
String
?,
dynamically
dyn
:
Bool
)
{
dynamic
=
dyn
let
sharedInfo
=
NSPrintInfo
.
shared
let
sharedDict
=
sharedInfo
.
dictionary
()
let
printInfoDict
=
NSMutableDictionary
(
dictionary
:
sharedDict
)
...
...
@@ -133,20 +145,38 @@ public class PrintJob: NSView, NSSharingServicePickerDelegate {
// Print the custom view
printOperation
=
NSPrintOperation
(
view
:
self
,
printInfo
:
printInfo
)
printOperation
!.
jobTitle
=
name
printOperation
!.
printPanel
.
options
=
[
.
showsPreview
,
.
showsPaperSize
,
.
showsOrientation
]
printOperation
!.
printPanel
.
options
=
[
.
showsPreview
]
if
printer
!=
nil
{
printInfo
.
printer
=
NSPrinter
(
name
:
printer
!
)
!
printOperation
!.
showsPrintPanel
=
false
printOperation
!.
showsProgressPanel
=
false
}
let
window
=
NSApplication
.
shared
.
mainWindow
!
printOperation
!.
runModal
(
for
:
window
,
delegate
:
self
,
didRun
:
#selector(
printOperationDidRun(printOperation:success:contextInfo:)
)
,
contextInfo
:
nil
)
if
dynamic
{
let
window
=
NSApplication
.
shared
.
mainWindow
!
printOperation
!.
printPanel
.
options
=
[
.
showsPreview
,
.
showsPaperSize
,
.
showsOrientation
]
printOperation
!.
runModal
(
for
:
window
,
delegate
:
self
,
didRun
:
#selector(
printOperationDidRun(printOperation:success:contextInfo:)
)
,
contextInfo
:
nil
)
return
}
printing
.
onLayout
(
printJob
:
self
,
width
:
printOperation
!.
printInfo
.
paperSize
.
width
,
height
:
printOperation
!.
printInfo
.
paperSize
.
height
,
marginLeft
:
printOperation
!.
printInfo
.
leftMargin
,
marginTop
:
printOperation
!.
printInfo
.
topMargin
,
marginRight
:
printOperation
!.
printInfo
.
rightMargin
,
marginBottom
:
printOperation
!.
printInfo
.
bottomMargin
)
}
func
cancelJob
(
_
:
String
?)
{
func
cancelJob
(
_
error
:
String
?)
{
pdfDocument
=
nil
semaphore
.
signal
()
if
dynamic
{
semaphore
.
signal
()
}
else
{
printing
.
onCompleted
(
printJob
:
self
,
completed
:
false
,
error
:
error
as
NSString
?)
}
}
public
static
func
sharePdf
(
data
:
Data
,
withSourceRect
rect
:
CGRect
,
andName
name
:
String
)
{
...
...
printing/macos/Classes/PrintingPlugin.swift
View file @
3258ca1
...
...
@@ -59,6 +59,7 @@ public class PrintingPlugin: NSObject, FlutterPlugin {
let
marginRight
=
CGFloat
((
args
[
"marginRight"
]
as!
NSNumber
)
.
floatValue
)
let
marginBottom
=
CGFloat
((
args
[
"marginBottom"
]
as!
NSNumber
)
.
floatValue
)
let
printJob
=
PrintJob
(
printing
:
self
,
index
:
args
[
"job"
]
as!
Int
)
let
dynamic
=
args
[
"dynamic"
]
as!
Bool
jobs
[
args
[
"job"
]
as!
UInt32
]
=
printJob
printJob
.
printPdf
(
name
:
name
,
withPageSize
:
CGSize
(
...
...
@@ -70,7 +71,8 @@ public class PrintingPlugin: NSObject, FlutterPlugin {
y
:
marginTop
,
width
:
width
-
marginRight
-
marginLeft
,
height
:
height
-
marginBottom
-
marginTop
),
withPrinter
:
printer
)
),
withPrinter
:
printer
,
dynamically
:
dynamic
)
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"listPrinters"
{
let
printJob
=
PrintJob
(
printing
:
self
,
index
:
-
1
)
...
...
printing/test/printing_test.dart
View file @
3258ca1
...
...
@@ -113,6 +113,7 @@ class MockPrinting extends Mock
LayoutCallback
onLayout
,
String
name
,
PdfPageFormat
format
,
bool
dynamicLayout
,
)
async
=>
true
;
...
...
Please
register
or
login
to post a comment