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
2020-10-31 14:17:44 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
093b8bd8be189a565f274dda127c8105d78480d1
093b8bd8
1 parent
cd963330
Implement missing Windows features
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
320 additions
and
135 deletions
printing/CHANGELOG.md
printing/lib/src/interface.dart
printing/lib/src/method_channel.dart
printing/lib/src/printing.dart
printing/lib/src/printing_info.dart
printing/lib/src/printing_web.dart
printing/test/printing_test.dart
printing/windows/print_job.cpp
printing/windows/print_job.h
printing/windows/printing.cpp
printing/windows/printing.h
printing/windows/printing_plugin.cpp
printing/CHANGELOG.md
View file @
093b8bd
...
...
@@ -4,6 +4,7 @@
-
Fix Pdf Raster on WEB
-
Fix Windows memory leaks
-
Implement missing Windows features
## 3.7.0
...
...
printing/lib/src/interface.dart
View file @
093b8bd
...
...
@@ -65,6 +65,9 @@ abstract class PrintingPlatform extends PlatformInterface {
PdfPageFormat
format
,
);
/// Enumerate the available printers on the system.
Future
<
List
<
Printer
>>
listPrinters
();
/// Opens the native printer picker interface, and returns the URL of the selected printer.
Future
<
Printer
>
pickPrinter
(
Rect
bounds
);
...
...
printing/lib/src/method_channel.dart
View file @
093b8bd
...
...
@@ -152,6 +152,26 @@ class MethodChannelPrinting extends PrintingPlatform {
}
@override
Future
<
List
<
Printer
>>
listPrinters
()
async
{
final
params
=
<
String
,
dynamic
>{};
final
list
=
await
_channel
.
invokeMethod
<
List
<
dynamic
>>(
'listPrinters'
,
params
);
final
printers
=
<
Printer
>[];
for
(
final
printer
in
list
)
{
printers
.
add
(
Printer
(
url:
printer
[
'url'
],
name:
printer
[
'name'
],
model:
printer
[
'model'
],
location:
printer
[
'location'
],
));
}
return
printers
;
}
@override
Future
<
Printer
>
pickPrinter
(
Rect
bounds
)
async
{
final
params
=
<
String
,
dynamic
>{
'x'
:
bounds
.
left
,
...
...
@@ -191,7 +211,7 @@ class MethodChannelPrinting extends PrintingPlatform {
final
params
=
<
String
,
dynamic
>{
'name'
:
name
,
'printer'
:
printer
.
url
,
'doc'
:
Uint8List
.
fromList
(
bytes
)
,
'doc'
:
bytes
,
'job'
:
job
.
index
,
};
await
_channel
.
invokeMethod
<
int
>(
'directPrintPdf'
,
params
);
...
...
printing/lib/src/printing.dart
View file @
093b8bd
...
...
@@ -17,6 +17,7 @@
import
'dart:async'
;
import
'dart:typed_data'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
show
Rect
,
Offset
;
import
'package:meta/meta.dart'
;
import
'package:pdf/pdf.dart'
;
...
...
@@ -48,15 +49,49 @@ mixin Printing {
return
PrintingPlatform
.
instance
.
layoutPdf
(
onLayout
,
name
,
format
);
}
/// Enumerate the available printers on the system.
///
/// This is not supported on all platforms. Check the result of [info] to
/// find at runtime if this feature is available or not.
static
Future
<
List
<
Printer
>>
listPrinters
()
{
return
PrintingPlatform
.
instance
.
listPrinters
();
}
/// Opens the native printer picker interface, and returns the URL of the
/// selected printer.
///
/// This is not supported on all platforms. Check the result of [info] to
/// find at runtime if this feature is available or not.
static
Future
<
Printer
>
pickPrinter
({
Rect
bounds
})
{
static
Future
<
Printer
>
pickPrinter
({
@required
BuildContext
context
,
Rect
bounds
,
})
async
{
final
_info
=
await
info
();
if
(
_info
!=
null
&&
_info
.
canListPrinters
)
{
assert
(
context
!=
null
,
'Pass a BuildCOntext to pickPrinter to display a selection list'
,
);
final
printers
=
await
listPrinters
();
return
await
showDialog
<
Printer
>(
context:
context
,
builder:
(
context
)
=>
SimpleDialog
(
children:
printers
.
map
<
Widget
>(
(
e
)
=>
SimpleDialogOption
(
child:
Text
(
e
.
name
),
onPressed:
()
=>
Navigator
.
of
(
context
).
pop
(
e
),
),
)
.
toList
(),
),
);
}
bounds
??=
Rect
.
fromCircle
(
center:
Offset
.
zero
,
radius:
10
);
return
PrintingPlatform
.
instance
.
pickPrinter
(
bounds
);
return
await
PrintingPlatform
.
instance
.
pickPrinter
(
bounds
);
}
/// Prints a Pdf document to a specific local printer with no UI
...
...
printing/lib/src/printing_info.dart
View file @
093b8bd
...
...
@@ -22,12 +22,14 @@ class PrintingInfo {
this
.
dynamicLayout
=
false
,
this
.
canPrint
=
false
,
this
.
canConvertHtml
=
false
,
this
.
canListPrinters
=
false
,
this
.
canShare
=
false
,
this
.
canRaster
=
false
,
})
:
assert
(
directPrint
!=
null
),
assert
(
dynamicLayout
!=
null
),
assert
(
canPrint
!=
null
),
assert
(
canConvertHtml
!=
null
),
assert
(
canListPrinters
!=
null
),
assert
(
canShare
!=
null
),
assert
(
canRaster
!=
null
);
...
...
@@ -37,6 +39,7 @@ class PrintingInfo {
dynamicLayout:
map
[
'dynamicLayout'
]
??
false
,
canPrint:
map
[
'canPrint'
]
??
false
,
canConvertHtml:
map
[
'canConvertHtml'
]
??
false
,
canListPrinters:
map
[
'canListPrinters'
]
??
false
,
canShare:
map
[
'canShare'
]
??
false
,
canRaster:
map
[
'canRaster'
]
??
false
,
);
...
...
@@ -57,6 +60,9 @@ class PrintingInfo {
/// The platform implementation is able to convert an html document to Pdf
final
bool
canConvertHtml
;
/// The platform implementation is able list the available printers on the system
final
bool
canListPrinters
;
/// The platform implementation is able to share a Pdf document
/// to other applications
final
bool
canShare
;
...
...
@@ -71,6 +77,7 @@ class PrintingInfo {
directPrint:
$directPrint
dynamicLayout:
$dynamicLayout
canConvertHtml:
$canConvertHtml
canListPrinters:
$canListPrinters
canShare:
$canShare
canRaster:
$canRaster
'''
;
...
...
@@ -81,6 +88,7 @@ class PrintingInfo {
'directPrint'
:
directPrint
,
'dynamicLayout'
:
dynamicLayout
,
'canConvertHtml'
:
canConvertHtml
,
'canListPrinters'
:
canListPrinters
,
'canShare'
:
canShare
,
'canRaster'
:
canRaster
,
};
...
...
printing/lib/src/printing_web.dart
View file @
093b8bd
...
...
@@ -52,10 +52,7 @@ class PrintingPlugin extends PrintingPlatform {
]);
return
PrintingInfo
(
directPrint:
false
,
dynamicLayout:
false
,
canPrint:
true
,
canConvertHtml:
false
,
canShare:
true
,
canRaster:
workerSrc
,
);
...
...
@@ -159,6 +156,11 @@ class PrintingPlugin extends PrintingPlatform {
}
@override
Future
<
List
<
Printer
>>
listPrinters
()
{
throw
UnimplementedError
();
}
@override
Future
<
Printer
>
pickPrinter
(
Rect
bounds
,
)
{
...
...
printing/test/printing_test.dart
View file @
093b8bd
...
...
@@ -66,7 +66,7 @@ void main() {
test
(
'pickPrinter'
,
()
async
{
expect
(
await
Printing
.
pickPrinter
(),
await
Printing
.
pickPrinter
(
context:
null
),
null
,
);
});
...
...
printing/windows/print_job.cpp
View file @
093b8bd
...
...
@@ -30,16 +30,106 @@
namespace
nfet
{
const
auto
pdfDpi
=
72
;
std
::
string
toUtf8
(
std
::
wstring
wstr
)
{
int
cbMultiByte
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
wstr
.
c_str
(),
-
1
,
NULL
,
0
,
NULL
,
NULL
);
LPSTR
lpMultiByteStr
=
(
LPSTR
)
malloc
(
cbMultiByte
);
cbMultiByte
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
wstr
.
c_str
(),
-
1
,
lpMultiByteStr
,
cbMultiByte
,
NULL
,
NULL
);
std
::
string
ret
=
lpMultiByteStr
;
free
(
lpMultiByteStr
);
return
ret
;
}
std
::
string
toUtf8
(
TCHAR
*
tstr
)
{
#ifndef UNICODE
#error "Non unicode build not supported"
#endif
if
(
!
tstr
)
{
return
std
::
string
{};
}
return
toUtf8
(
std
::
wstring
{
tstr
});
}
std
::
wstring
fromUtf8
(
std
::
string
str
)
{
auto
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
str
.
c_str
(),
static_cast
<
int
>
(
str
.
length
()),
nullptr
,
0
);
if
(
len
<=
0
)
{
return
false
;
}
auto
wstr
=
std
::
wstring
{};
wstr
.
resize
(
len
);
MultiByteToWideChar
(
CP_ACP
,
0
,
str
.
c_str
(),
static_cast
<
int
>
(
str
.
length
()),
&
wstr
[
0
],
len
);
return
wstr
;
}
PrintJob
::
PrintJob
(
Printing
*
printing
,
int
index
)
:
printing
(
printing
),
index
(
index
)
{}
void
PrintJob
::
directPrintPdf
(
std
::
string
name
,
bool
PrintJob
::
directPrintPdf
(
std
::
string
name
,
std
::
vector
<
uint8_t
>
data
,
std
::
string
withPrinter
)
{}
std
::
string
withPrinter
)
{
FPDF_InitLibraryWithConfig
(
nullptr
);
auto
doc
=
FPDF_LoadMemDocument64
(
data
.
data
(),
data
.
size
(),
nullptr
);
if
(
!
doc
)
{
FPDF_DestroyLibrary
();
return
false
;
}
hDC
=
CreateDC
(
TEXT
(
"WINSPOOL"
),
fromUtf8
(
withPrinter
).
c_str
(),
NULL
,
NULL
);
if
(
!
hDC
)
{
FPDF_CloseDocument
(
doc
);
FPDF_DestroyLibrary
();
return
false
;
}
DOCINFO
docInfo
;
ZeroMemory
(
&
docInfo
,
sizeof
(
docInfo
));
docInfo
.
cbSize
=
sizeof
(
DOCINFO
);
auto
docName
=
fromUtf8
(
name
);
docInfo
.
lpszDocName
=
docName
.
c_str
();
StartDoc
(
hDC
,
&
docInfo
);
int
pageCount
=
FPDF_GetPageCount
(
doc
);
for
(
auto
i
=
0
;
i
<
pageCount
;
i
++
)
{
StartPage
(
hDC
);
auto
page
=
FPDF_LoadPage
(
doc
,
i
);
if
(
!
page
)
{
EndDoc
(
hDC
);
DeleteDC
(
hDC
);
FPDF_CloseDocument
(
doc
);
FPDF_DestroyLibrary
();
return
false
;
}
auto
pageWidth
=
FPDF_GetPageWidth
(
page
);
auto
pageHeight
=
FPDF_GetPageHeight
(
page
);
auto
dpiX
=
GetDeviceCaps
(
hDC
,
LOGPIXELSX
);
auto
dpiY
=
GetDeviceCaps
(
hDC
,
LOGPIXELSY
);
auto
width
=
static_cast
<
int
>
(
pageWidth
/
pdfDpi
*
dpiX
);
auto
height
=
static_cast
<
int
>
(
pageHeight
/
pdfDpi
*
dpiY
);
FPDF_RenderPage
(
hDC
,
page
,
0
,
0
,
width
,
height
,
0
,
FPDF_ANNOT
);
FPDF_ClosePage
(
page
);
EndPage
(
hDC
);
}
EndDoc
(
hDC
);
DeleteDC
(
hDC
);
FPDF_CloseDocument
(
doc
);
FPDF_DestroyLibrary
();
return
true
;
}
bool
PrintJob
::
printPdf
(
std
::
string
name
)
{
PRINTDLG
pd
;
// HWND hwnd;
// Initialize PRINTDLG
ZeroMemory
(
&
pd
,
sizeof
(
pd
));
...
...
@@ -60,20 +150,8 @@ bool PrintJob::printPdf(std::string name) {
auto
r
=
PrintDlg
(
&
pd
);
if
(
r
==
1
)
{
// printf("ncopies: %d\n", pd.nCopies);
// printf("hDevMode: %d\n", (int)pd.hDevMode);
// DEVMODE* b = static_cast<DEVMODE*>(GlobalLock(pd.hDevMode));
// auto pageDpi = b->dmPrintQuality;
// GlobalUnlock(pd.hDevMode);
// auto pageHeight = b->dmPaperLength;
// auto pageWidth = b->dmPaperWidth;
// auto pageScale = b->dmScale / 100;
auto
dpiX
=
static_cast
<
double
>
(
GetDeviceCaps
(
pd
.
hDC
,
LOGPIXELSX
))
/
72
;
auto
dpiY
=
static_cast
<
double
>
(
GetDeviceCaps
(
pd
.
hDC
,
LOGPIXELSY
))
/
72
;
auto
dpiX
=
static_cast
<
double
>
(
GetDeviceCaps
(
pd
.
hDC
,
LOGPIXELSX
))
/
pdfDpi
;
auto
dpiY
=
static_cast
<
double
>
(
GetDeviceCaps
(
pd
.
hDC
,
LOGPIXELSY
))
/
pdfDpi
;
auto
pageWidth
=
static_cast
<
double
>
(
GetDeviceCaps
(
pd
.
hDC
,
PHYSICALWIDTH
))
/
dpiX
;
auto
pageHeight
=
...
...
@@ -89,16 +167,10 @@ bool PrintJob::printPdf(std::string name) {
auto
marginRight
=
pageWidth
-
printableWidth
-
marginLeft
;
auto
marginBottom
=
pageHeight
-
printableHeight
-
marginTop
;
// printf("dpiX: %f\n", dpiX);
// printf("HORZRES: %d\n", GetDeviceCaps(pd.hDC, HORZRES));
// printf("PHYSICALOFFSETX: %d\n", GetDeviceCaps(pd.hDC, PHYSICALOFFSETX));
// printf("pageWidth: %f\n", pageWidth);
hDC
=
pd
.
hDC
;
hDevMode
=
pd
.
hDevMode
;
hDevNames
=
pd
.
hDevNames
;
// printf("HDC: %llu job: %d\n", (size_t)pd.hDC, index);
documentName
=
name
;
printing
->
onLayout
(
this
,
pageWidth
,
pageHeight
,
marginLeft
,
marginTop
,
marginRight
,
marginBottom
);
...
...
@@ -108,111 +180,106 @@ bool PrintJob::printPdf(std::string name) {
return
false
;
}
std
::
vector
<
Printer
>
PrintJob
::
listPrinters
()
{
auto
printers
=
std
::
vector
<
Printer
>
{};
DWORD
needed
=
0
;
DWORD
returned
=
0
;
const
auto
flags
=
PRINTER_ENUM_LOCAL
|
PRINTER_ENUM_CONNECTIONS
;
EnumPrinters
(
flags
,
nullptr
,
1
,
nullptr
,
0
,
&
needed
,
&
returned
);
auto
buffer
=
(
PRINTER_INFO_1
*
)
malloc
(
needed
);
if
(
!
buffer
)
{
return
printers
;
}
auto
result
=
EnumPrinters
(
flags
,
nullptr
,
1
,
(
LPBYTE
)
buffer
,
needed
,
&
needed
,
&
returned
);
if
(
result
==
0
)
{
free
(
buffer
);
return
printers
;
}
for
(
DWORD
i
=
0
;
i
<
returned
;
i
++
)
{
printers
.
push_back
(
Printer
{
toUtf8
(
buffer
[
i
].
pName
),
toUtf8
(
buffer
[
i
].
pName
),
toUtf8
(
buffer
[
i
].
pDescription
),
toUtf8
(
buffer
[
i
].
pComment
),
});
}
free
(
buffer
);
return
printers
;
}
void
PrintJob
::
writeJob
(
std
::
vector
<
uint8_t
>
data
)
{
// printf("hDC: %llu job: %d\n", (size_t)hDC, index);
auto
dpiX
=
static_cast
<
double
>
(
GetDeviceCaps
(
hDC
,
LOGPIXELSX
))
/
72
;
auto
dpiY
=
static_cast
<
double
>
(
GetDeviceCaps
(
hDC
,
LOGPIXELSY
))
/
72
;
// GlobalFree(pd.hDevMode);
// print(
// 'Paper size: ${pageWidth} ${pageHeight} scale: $pageScale dpi:
// $pageDpi');
// final printerDC = CreateDCW(nullptr, szPrinter,nullptr,
// devmode);
DOCINFO
info
;
// memset(&info, 0, sizeof(info));
ZeroMemory
(
&
info
,
sizeof
(
info
));
info
.
cbSize
=
sizeof
(
info
);
// info.fwType = 0;
// info.lpszDatatype = nullptr;
// info.lpszDocName = nullptr;
// info.lpszOutput = nullptr;
// auto printerDC = pd.hDC;
// print('hDC: ${pd.hDC}');
auto
r
=
StartDoc
(
hDC
,
&
info
);
// print('StartDoc = $r');
auto
dpiX
=
static_cast
<
double
>
(
GetDeviceCaps
(
hDC
,
LOGPIXELSX
))
/
pdfDpi
;
auto
dpiY
=
static_cast
<
double
>
(
GetDeviceCaps
(
hDC
,
LOGPIXELSY
))
/
pdfDpi
;
FPDF_InitLibraryWithConfig
(
nullptr
);
// final buffer = allocate<ffi.Uint8>(count : bytes.length);
// final nativeBuffer = buffer.asTypedList(bytes.length);
// nativeBuffer.setAll(0, bytes);
DOCINFO
docInfo
;
ZeroMemory
(
&
docInfo
,
sizeof
(
docInfo
));
docInfo
.
cbSize
=
sizeof
(
docInfo
);
auto
docName
=
fromUtf8
(
documentName
);
docInfo
.
lpszDocName
=
docName
.
c_str
();
// auto buffer = std::vector<uint8_t>{};
auto
r
=
StartDoc
(
hDC
,
&
docInfo
);
FPDF_InitLibraryWithConfig
(
nullptr
);
auto
doc
=
FPDF_LoadMemDocument64
(
data
.
data
(),
data
.
size
(),
nullptr
);
if
(
!
doc
)
{
// printf("Error loading the document: %d\n", FPDF_GetLastError()
);
FPDF_DestroyLibrary
(
);
return
;
}
auto
pages
=
FPDF_GetPageCount
(
doc
);
// printf("Page count: %d\n", pages);
for
(
auto
pageNum
=
0
;
pageNum
<
pages
;
pageNum
++
)
{
r
=
StartPage
(
hDC
);
// printf("StartPage = %d\n", r);
auto
page
=
FPDF_LoadPage
(
doc
,
pageNum
);
// print(FPDF_GetLastError());
if
(
!
page
)
{
EndPage
(
hDC
);
continue
;
}
auto
pdfWidth
=
FPDF_GetPageWidth
(
page
);
auto
pdfHeight
=
FPDF_GetPageHeight
(
page
);
// print('$width x $height');
// printf("pdfWidth: %f dpiX: %f \n", pdfWidth, dpiX);
int
bWidth
=
static_cast
<
int
>
(
pdfWidth
*
dpiX
);
int
bHeight
=
static_cast
<
int
>
(
pdfHeight
*
dpiY
);
// printf("bwidth/bheight: %d x %d\n", bWidth, bHeight);
FPDF_RenderPage
(
hDC
,
page
,
0
,
0
,
bWidth
,
bHeight
,
0
,
FPDF_ANNOT
);
r
=
EndPage
(
hDC
);
// printf("EndPage = %d\n", r);
}
FPDF_CloseDocument
(
doc
);
FPDF_DestroyLibrary
();
r
=
EndDoc
(
hDC
);
// printf("EndDoc = %d\n", r);
// DeleteDC(printerDC);
DeleteDC
(
hDC
);
GlobalFree
(
hDevNames
);
ClosePrinter
(
hDevMode
);
}
// namespace nfet
}
void
PrintJob
::
cancelJob
(
std
::
string
error
)
{}
bool
PrintJob
::
sharePdf
(
std
::
vector
<
uint8_t
>
data
,
std
::
string
name
)
{
TCHAR
lpTempPathBuffer
[
MAX_PATH
];
// TCHAR szTempFileName[MAX_PATH];
auto
ret
=
GetTempPath
(
MAX_PATH
,
lpTempPathBuffer
);
if
(
ret
>
MAX_PATH
||
(
ret
==
0
))
{
return
false
;
}
#ifndef UNICODE
#error "Non unicode build not supported"
#endif
auto
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
name
.
c_str
(),
static_cast
<
int
>
(
name
.
length
()),
nullptr
,
0
);
if
(
len
<=
0
)
{
return
false
;
}
auto
filename
=
fromUtf8
(
toUtf8
(
lpTempPathBuffer
)
+
"
\\
"
+
name
);
auto
w_name
=
std
::
wstring
{};
w_name
.
resize
(
len
);
MultiByteToWideChar
(
CP_ACP
,
0
,
name
.
c_str
(),
static_cast
<
int
>
(
name
.
length
()),
&
w_name
[
0
],
len
);
auto
filename
=
std
::
wstring
{
lpTempPathBuffer
}
+
L"
\\
"
+
w_name
;
auto
output_file
=
std
::
basic_ofstream
<
uint8_t
>
{
filename
,
std
::
ios
::
out
|
std
::
ios
::
binary
};
output_file
.
write
(
data
.
data
(),
data
.
size
());
...
...
@@ -231,7 +298,6 @@ bool PrintJob::sharePdf(std::vector<uint8_t> data, std::string name) {
ret
=
ShellExecuteEx
(
&
ShExecInfo
);
// CoTaskMemFree(pidlWinFiles);
return
ret
==
TRUE
;
}
...
...
@@ -244,13 +310,12 @@ void PrintJob::rasterPdf(std::vector<uint8_t> data,
auto
doc
=
FPDF_LoadMemDocument64
(
data
.
data
(),
data
.
size
(),
nullptr
);
if
(
!
doc
)
{
// printf(stderr, "Error: %d\n", FPDF_GetLastError()
);
FPDF_DestroyLibrary
(
);
printing
->
onPageRasterEnd
(
this
);
return
;
}
auto
pageCount
=
FPDF_GetPageCount
(
doc
);
// printf("pdf: pages:%d\n", pageCount);
if
(
pages
.
size
()
==
0
)
{
// Use all pages
...
...
@@ -265,15 +330,12 @@ void PrintJob::rasterPdf(std::vector<uint8_t> data,
auto
page
=
FPDF_LoadPage
(
doc
,
n
);
if
(
!
page
)
{
// printf("Page Error: %d\n", FPDF_GetLastError());
continue
;
}
auto
width
=
FPDF_GetPageWidth
(
page
);
auto
height
=
FPDF_GetPageHeight
(
page
);
// printf("pdf: page:%d w:%f h:%f\n", n, width, height);
auto
bWidth
=
static_cast
<
int
>
(
width
*
scale
);
auto
bHeight
=
static_cast
<
int
>
(
height
*
scale
);
...
...
@@ -308,12 +370,13 @@ void PrintJob::rasterPdf(std::vector<uint8_t> data,
FPDF_DestroyLibrary
();
printing
->
onPageRasterEnd
(
this
);
}
// namespace nfet
}
std
::
map
<
std
::
string
,
bool
>
PrintJob
::
printingInfo
()
{
return
std
::
map
<
std
::
string
,
bool
>
{
{
"directPrint"
,
true
},
{
"dynamicLayout"
,
true
},
{
"canPrint"
,
true
},
{
"canConvertHtml"
,
false
},
{
"canShare"
,
true
},
{
"canRaster"
,
true
},
{
"directPrint"
,
true
},
{
"dynamicLayout"
,
true
},
{
"canPrint"
,
true
},
{
"canListPrinters"
,
true
},
{
"canConvertHtml"
,
false
},
{
"canShare"
,
true
},
{
"canRaster"
,
true
},
};
}
...
...
printing/windows/print_job.h
View file @
093b8bd
...
...
@@ -30,6 +30,19 @@ namespace nfet {
class
Printing
;
struct
Printer
{
const
std
::
string
name
;
const
std
::
string
url
;
const
std
::
string
model
;
const
std
::
string
description
;
Printer
(
std
::
string
name
,
std
::
string
url
,
std
::
string
model
,
std
::
string
description
)
:
name
(
name
),
url
(
url
),
model
(
model
),
description
(
description
)
{}
};
class
PrintJob
{
private
:
Printing
*
printing
;
...
...
@@ -37,17 +50,18 @@ class PrintJob {
HGLOBAL
hDevMode
=
nullptr
;
HGLOBAL
hDevNames
=
nullptr
;
HDC
hDC
=
nullptr
;
std
::
string
documentName
;
public
:
PrintJob
(
Printing
*
printing
,
int
index
);
// ~PrintJob() { printf("Delete PrintJob #%d\n", index); }
int
id
()
{
return
index
;
}
void
directPrintPdf
(
std
::
string
name
,
std
::
vector
<
Printer
>
listPrinters
();
bool
directPrintPdf
(
std
::
string
name
,
std
::
vector
<
uint8_t
>
data
,
std
::
string
withP
rinter
);
std
::
string
p
rinter
);
bool
printPdf
(
std
::
string
name
);
...
...
printing/windows/printing.cpp
View file @
093b8bd
...
...
@@ -55,9 +55,7 @@ void Printing::onPageRasterEnd(PrintJob* job) {
class
OnLayoutResult
:
public
flutter
::
MethodResult
<
flutter
::
EncodableValue
>
{
public
:
OnLayoutResult
(
PrintJob
*
job
)
:
job
(
job
)
{
// printf("OnLayoutResult (%d) %p\n", job->id(), this);
}
OnLayoutResult
(
PrintJob
*
job
)
:
job
(
job
)
{}
private
:
PrintJob
*
job
;
...
...
@@ -65,7 +63,7 @@ class OnLayoutResult : public flutter::MethodResult<flutter::EncodableValue> {
protected
:
void
SuccessInternal
(
const
flutter
::
EncodableValue
*
result
)
{
auto
doc
=
std
::
get
<
std
::
vector
<
uint8_t
>>
(
*
result
);
// printf("Success! (%d) %llu bytes %p\n", job->id(), doc.size(), this);
job
->
writeJob
(
doc
);
delete
job
;
}
...
...
@@ -73,14 +71,10 @@ class OnLayoutResult : public flutter::MethodResult<flutter::EncodableValue> {
void
ErrorInternal
(
const
std
::
string
&
error_code
,
const
std
::
string
&
error_message
,
const
flutter
::
EncodableValue
*
error_details
)
{
printf
(
"Error!
\n
"
);
delete
job
;
}
void
NotImplementedInternal
()
{
printf
(
"NotImplemented!
\n
"
);
delete
job
;
}
void
NotImplementedInternal
()
{
delete
job
;
}
};
void
Printing
::
onLayout
(
PrintJob
*
job
,
...
...
@@ -90,12 +84,6 @@ void Printing::onLayout(PrintJob* job,
double
marginTop
,
double
marginRight
,
double
marginBottom
)
{
// printf("onLayout (%d) %fx%f %f %f %f %f\n", job->id(), pageWidth,
// pageHeight,
// marginLeft, marginTop, marginRight, marginBottom);
// auto result = std::make_unique<OnLayoutResult>(job);
channel
->
InvokeMethod
(
"onLayout"
,
std
::
make_unique
<
flutter
::
EncodableValue
>
(
flutter
::
EncodableValue
(
flutter
::
EncodableMap
{
...
...
@@ -117,4 +105,21 @@ void Printing::onLayout(PrintJob* job,
std
::
make_unique
<
OnLayoutResult
>
(
job
));
}
// send completion status to flutter
void
Printing
::
onCompleted
(
PrintJob
*
job
,
bool
completed
,
std
::
string
error
)
{
auto
map
=
flutter
::
EncodableMap
{
{
flutter
::
EncodableValue
(
"job"
),
flutter
::
EncodableValue
(
job
->
id
())},
{
flutter
::
EncodableValue
(
"completed"
),
flutter
::
EncodableValue
(
completed
)},
};
if
(
!
error
.
empty
())
{
map
[
flutter
::
EncodableValue
(
"error"
)]
=
flutter
::
EncodableValue
(
error
);
}
channel
->
InvokeMethod
(
"onCompleted"
,
std
::
make_unique
<
flutter
::
EncodableValue
>
(
flutter
::
EncodableValue
(
map
)));
}
}
// namespace nfet
...
...
printing/windows/printing.h
View file @
093b8bd
...
...
@@ -24,8 +24,6 @@
#include <flutter/method_channel.h>
// #include "print_job.h"
namespace
nfet
{
class
PrintJob
;
...
...
@@ -51,6 +49,8 @@ class Printing {
double
marginTop
,
double
marginRight
,
double
marginBottom
);
void
Printing
::
onCompleted
(
PrintJob
*
job
,
bool
completed
,
std
::
string
error
);
};
}
// namespace nfet
...
...
printing/windows/printing_plugin.cpp
View file @
093b8bd
...
...
@@ -58,6 +58,7 @@ class PrintingPlugin : public flutter::Plugin {
private
:
Printing
printing
{};
// Called when a method is called on this plugin's channel from Dart.
void
HandleMethodCall
(
const
flutter
::
MethodCall
<
flutter
::
EncodableValue
>&
method_call
,
...
...
@@ -66,9 +67,9 @@ class PrintingPlugin : public flutter::Plugin {
const
auto
*
arguments
=
std
::
get_if
<
flutter
::
EncodableMap
>
(
method_call
.
arguments
());
auto
vName
=
arguments
->
find
(
flutter
::
EncodableValue
(
"name"
));
auto
name
=
vName
!=
arguments
->
end
()
auto
name
=
vName
!=
arguments
->
end
()
&&
!
vName
->
second
.
IsNull
()
?
std
::
get
<
std
::
string
>
(
vName
->
second
)
:
std
::
string
{};
:
std
::
string
{
"document"
};
auto
vJob
=
arguments
->
find
(
flutter
::
EncodableValue
(
"job"
));
auto
jobNum
=
vJob
!=
arguments
->
end
()
?
std
::
get
<
int
>
(
vJob
->
second
)
:
-
1
;
auto
job
=
new
PrintJob
{
&
printing
,
jobNum
};
...
...
@@ -78,14 +79,31 @@ class PrintingPlugin : public flutter::Plugin {
}
result
->
Success
(
flutter
::
EncodableValue
(
res
?
1
:
0
));
}
else
if
(
method_call
.
method_name
().
compare
(
"directPrintPdf"
)
==
0
)
{
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
-
1
);
job
->
directPrintPdf
(
"name"
,
std
::
vector
<
uint8_t
>
{},
"withPrinter"
);
result
->
Success
(
nullptr
);
const
auto
*
arguments
=
std
::
get_if
<
flutter
::
EncodableMap
>
(
method_call
.
arguments
());
auto
vName
=
arguments
->
find
(
flutter
::
EncodableValue
(
"name"
));
auto
name
=
vName
!=
arguments
->
end
()
&&
!
vName
->
second
.
IsNull
()
?
std
::
get
<
std
::
string
>
(
vName
->
second
)
:
std
::
string
{
"document"
};
auto
vDoc
=
arguments
->
find
(
flutter
::
EncodableValue
(
"doc"
));
auto
doc
=
vDoc
!=
arguments
->
end
()
?
std
::
get
<
std
::
vector
<
uint8_t
>>
(
vDoc
->
second
)
:
std
::
vector
<
uint8_t
>
{};
auto
vPrinter
=
arguments
->
find
(
flutter
::
EncodableValue
(
"printer"
));
auto
printer
=
vPrinter
!=
arguments
->
end
()
?
std
::
get
<
std
::
string
>
(
vPrinter
->
second
)
:
std
::
string
{};
auto
vJob
=
arguments
->
find
(
flutter
::
EncodableValue
(
"job"
));
auto
jobNum
=
vJob
!=
arguments
->
end
()
?
std
::
get
<
int
>
(
vJob
->
second
)
:
-
1
;
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
jobNum
);
auto
res
=
job
->
directPrintPdf
(
name
,
doc
,
printer
);
result
->
Success
(
flutter
::
EncodableValue
(
1
));
printing
.
onCompleted
(
job
.
get
(),
res
,
""
);
}
else
if
(
method_call
.
method_name
().
compare
(
"sharePdf"
)
==
0
)
{
const
auto
*
arguments
=
std
::
get_if
<
flutter
::
EncodableMap
>
(
method_call
.
arguments
());
auto
vName
=
arguments
->
find
(
flutter
::
EncodableValue
(
"name"
));
auto
name
=
vName
!=
arguments
->
end
()
auto
name
=
vName
!=
arguments
->
end
()
&&
!
vName
->
second
.
IsNull
()
?
std
::
get
<
std
::
string
>
(
vName
->
second
)
:
std
::
string
{
"document.pdf"
};
auto
vDoc
=
arguments
->
find
(
flutter
::
EncodableValue
(
"doc"
));
...
...
@@ -95,10 +113,23 @@ class PrintingPlugin : public flutter::Plugin {
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
-
1
);
auto
res
=
job
->
sharePdf
(
doc
,
name
);
result
->
Success
(
flutter
::
EncodableValue
(
res
?
1
:
0
));
}
else
if
(
method_call
.
method_name
().
compare
(
"
pickPrinter
"
)
==
0
)
{
}
else
if
(
method_call
.
method_name
().
compare
(
"
listPrinters
"
)
==
0
)
{
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
-
1
);
job
->
pickPrinter
(
nullptr
);
result
->
Success
(
nullptr
);
auto
printers
=
job
->
listPrinters
();
auto
pl
=
flutter
::
EncodableList
{};
for
(
auto
printer
:
printers
)
{
auto
mp
=
flutter
::
EncodableMap
{};
mp
[
flutter
::
EncodableValue
(
"name"
)]
=
flutter
::
EncodableValue
(
printer
.
name
);
mp
[
flutter
::
EncodableValue
(
"url"
)]
=
flutter
::
EncodableValue
(
printer
.
url
);
mp
[
flutter
::
EncodableValue
(
"model"
)]
=
flutter
::
EncodableValue
(
printer
.
model
);
mp
[
flutter
::
EncodableValue
(
"description"
)]
=
flutter
::
EncodableValue
(
printer
.
description
);
pl
.
push_back
(
mp
);
}
result
->
Success
(
pl
);
}
else
if
(
method_call
.
method_name
().
compare
(
"rasterPdf"
)
==
0
)
{
const
auto
*
arguments
=
std
::
get_if
<
flutter
::
EncodableMap
>
(
method_call
.
arguments
());
...
...
@@ -106,18 +137,21 @@ class PrintingPlugin : public flutter::Plugin {
auto
doc
=
vDoc
!=
arguments
->
end
()
?
std
::
get
<
std
::
vector
<
uint8_t
>>
(
vDoc
->
second
)
:
std
::
vector
<
uint8_t
>
{};
// auto vPages = arguments->find(flutter::EncodableValue("pages"));
// auto pages = vPages != arguments->end()
// ? std::get<flutter
// ::EncodableList>(vPages->second) : flutter
// ::EncodableList{};
auto
vPages
=
arguments
->
find
(
flutter
::
EncodableValue
(
"pages"
));
auto
lPages
=
vPages
!=
arguments
->
end
()
&&
!
vPages
->
second
.
IsNull
()
?
std
::
get
<
flutter
::
EncodableList
>
(
vPages
->
second
)
:
flutter
::
EncodableList
{};
auto
pages
=
std
::
vector
<
int
>
{};
for
(
auto
page
:
lPages
)
{
pages
.
push_back
(
std
::
get
<
int
>
(
page
));
}
auto
vScale
=
arguments
->
find
(
flutter
::
EncodableValue
(
"scale"
));
auto
scale
=
vScale
!=
arguments
->
end
()
?
std
::
get
<
double
>
(
vScale
->
second
)
:
1
;
auto
vJob
=
arguments
->
find
(
flutter
::
EncodableValue
(
"job"
));
auto
jobNum
=
vJob
!=
arguments
->
end
()
?
std
::
get
<
int
>
(
vJob
->
second
)
:
-
1
;
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
jobNum
);
job
->
rasterPdf
(
doc
,
std
::
vector
<
int
>
{}
,
scale
);
job
->
rasterPdf
(
doc
,
pages
,
scale
);
result
->
Success
(
nullptr
);
}
else
if
(
method_call
.
method_name
().
compare
(
"printingInfo"
)
==
0
)
{
auto
job
=
std
::
make_unique
<
PrintJob
>
(
&
printing
,
-
1
);
...
...
Please
register
or
login
to post a comment