int wmain(int argc, wchar_t* argv[]) { HRESULT hr = S_OK; HANDLE completionEvent = NULL; IXpsPrintJob* job = NULL; IXpsPrintJobStream* jobStream = NULL; IXpsOMObjectFactory* xpsFactory = NULL; IOpcPartUri* partUri = NULL; IXpsOMPackageWriter* packageWriter = NULL; XPS_SIZE pageSize = {816, 1056}; IXpsOMPage* xpsPage = NULL; IXpsOMFontResource* fontResource = NULL; XPS_POINT origin = {50.0f, 200.0f}; XPS_JOB_STATUS jobStatus = {}; if (argc < 2 || argc > 3) { Usage(argv[0]); return 1; } if (FAILED(hr = CoInitializeEx(0, COINIT_MULTITHREADED))) { fwprintf(stderr, L"ERROR: CoInitializeEx failed with HRESULT 0x%X\n", hr); return 1; } if (SUCCEEDED(hr)) { completionEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!completionEvent) { hr = HRESULT_FROM_WIN32(GetLastError()); fwprintf(stderr, L"ERROR: Could not create competion event: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = StartXpsPrintJob( argv[1], NULL, argc == 3 ? argv[2] : NULL, NULL, completionEvent, NULL, 0, &job, &jobStream, NULL ))) { fwprintf(stderr, L"ERROR: Could not start XPS print job: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = CoCreateInstance( __uuidof(XpsOMObjectFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXpsOMObjectFactory), reinterpret_cast<void**>(&xpsFactory) ) ) ) { fwprintf(stderr, L"ERROR: Could not create XPS OM Object Factory: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePartUri(L"/FixedDocumentSequence.fdseq", &partUri))) { fwprintf(stderr, L"ERROR: Could not create part URI: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePackageWriterOnStream( jobStream, TRUE, XPS_INTERLEAVING_ON, partUri, NULL, NULL, NULL, NULL, &packageWriter ) ) ) { fwprintf(stderr, L"ERROR: Could not create package writer: 0x%X\n", hr); } } if (partUri) { partUri->Release(); partUri = NULL; } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePartUri(L"/Documents/1/FixedDocument.fdoc", &partUri))) { fwprintf(stderr, L"ERROR: Could not create part URI: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = packageWriter->StartNewDocument(partUri, NULL, NULL, NULL, NULL))) { fwprintf(stderr, L"ERROR: Could not start new document: 0x%X\n", hr); } } if (partUri) { partUri->Release(); partUri = NULL; } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePartUri(L"/Documents/1/Pages/1.fpage", &partUri))) { fwprintf(stderr, L"ERROR: Could not create part URI: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = xpsFactory->CreatePage(&pageSize, L"en-US", partUri, &xpsPage))) { fwprintf(stderr, L"ERROR: Could not create page: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = CreateFontResourceForFont(xpsFactory, g_fontName, &fontResource))) { // Error already reported. } } if (SUCCEEDED(hr)) { if (FAILED(hr = AddGlyphs( xpsFactory, xpsPage, fontResource, L"XPS", &origin, 72.0f, XPS_STYLE_SIMULATION_NONE))) { // Error already reported. } } if (SUCCEEDED(hr)) { origin.x = 420.0f; origin.y = 300.0f; if (FAILED(hr = AddGlyphs( xpsFactory, xpsPage, fontResource, L"Print with Confidence", &origin, 36.0f, XPS_STYLE_SIMULATION_ITALIC))) { // Error already reported. } } if (SUCCEEDED(hr)) { if (FAILED(hr = packageWriter->AddPage( xpsPage, &pageSize, NULL, NULL, NULL, NULL ))) { fwprintf(stderr, L"ERROR: Could not add page to document: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = packageWriter->Close())) { fwprintf(stderr, L"ERROR: Could not close package writer: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = jobStream->Close())) { fwprintf(stderr, L"ERROR: Could not close job stream: %08X\n", hr); } } else { // Only cancel the job if we succeeded in creating one in the first place. if (job) { // Tell the XPS Print API that we're giving up. Don't overwrite hr with the return from // this function. job->Cancel(); } } if (SUCCEEDED(hr)) { wprintf(L"Waiting for job completion...\n"); if (WaitForSingleObject(completionEvent, INFINITE) != WAIT_OBJECT_0) { hr = HRESULT_FROM_WIN32(GetLastError()); fwprintf(stderr, L"ERROR: Wait for completion event failed: %08X\n", hr); } } if (SUCCEEDED(hr)) { if (FAILED(hr = job->GetJobStatus(&jobStatus))) { fwprintf(stderr, L"ERROR: Could not get job status: %08X\n", hr); } } if (SUCCEEDED(hr)) { switch (jobStatus.completion) { case XPS_JOB_COMPLETED: break; case XPS_JOB_CANCELLED: fwprintf(stderr, L"ERROR: job was cancelled\n"); hr = E_FAIL; break; case XPS_JOB_FAILED: fwprintf(stderr, L"ERROR: Print job failed: %08X\n", jobStatus.jobStatus); hr = E_FAIL; break; default: fwprintf(stderr, L"ERROR: unexpected failure\n"); hr = E_UNEXPECTED; break; } } if (SUCCEEDED(hr)) { wprintf(L"Done!\n"); } if (fontResource) { fontResource->Release(); fontResource = NULL; } if (xpsPage) { xpsPage->Release(); xpsPage = NULL; } if (packageWriter) { packageWriter->Release(); packageWriter = NULL; } if (partUri) { partUri->Release(); partUri = NULL; } if (xpsFactory) { xpsFactory->Release(); xpsFactory = NULL; } if (jobStream) { jobStream->Release(); jobStream = NULL; } if (job) { job->Release(); job = NULL; } if (completionEvent) { CloseHandle(completionEvent); completionEvent = NULL; } CoUninitialize(); return SUCCEEDED(hr) ? 0 : 1; }
void touchmind::print::XPSPrint::_PrintMapModel(const touchmind::model::MapModel *pMapModel) { HRESULT hr = S_OK; auto node = pMapModel->GetRootNodeModel(); XPSGeometryBuilder::CalculateTransformMatrix(m_pageSize, m_xpsMargin, node, m_xpsMatrix, m_scale); _CreateCanvas(); m_pTextRenderer = nullptr; CHK_HR(XpsDWriteTextRenderer::CreateInstance(m_pXpsFactory, &m_pTextRenderer)); m_pTextRenderer->SetXpsCanvas(m_pXpsCanvas); m_pTextRenderer->SetXpsDictionary(m_pXpsDictionary); m_pTextRenderer->SetXpsResources(m_pXpsResources); _PrintNodes(node); _PrintLinks(pMapModel); HANDLE completionEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); CHK_FATAL_NULL(completionEvent); IXpsPrintJob *job = nullptr; IXpsPrintJobStream *jobStream = nullptr; #ifdef PRINT_TICKET_SUPPORT IXpsPrintJobStream *printTicketStream = nullptr; #endif hr = StartXpsPrintJob( m_deviceName.c_str(), pMapModel->HasFileName() ? pMapModel->GetFileName().c_str() : nullptr, nullptr, nullptr, completionEvent, nullptr, 0, &job, &jobStream, #ifdef PRINT_TICKET_SUPPORT & printTicketStream #else nullptr #endif ); if (FAILED(hr)) { LOG(SEVERITY_LEVEL_ERROR) << L"StartXpsPrintJob failed, hr = " << std::hex << hr; } if (SUCCEEDED(hr)) { hr = m_pXpsPackage->WriteToStream(jobStream, FALSE); if (FAILED(hr)) { LOG(SEVERITY_LEVEL_ERROR) << L"IXpsOMPackage::WriteToStream failed, hr = " << std::hex << hr; } } #ifdef PRINT_TICKET_SUPPORT if (SUCCEEDED(hr)) { PrintTicketHelper::CreatePrintTicket(m_deviceName, m_pPDX, printTicketStream); } #endif hr = jobStream->Close(); #ifdef PRINT_TICKET_SUPPORT hr = printTicketStream->Close(); #endif if (WaitForSingleObject(completionEvent, INFINITE) == WAIT_OBJECT_0) { XPS_JOB_STATUS jobStatus; hr = job->GetJobStatus(&jobStatus); switch (jobStatus.completion) { case XPS_JOB_COMPLETED: hr = S_OK; break; case XPS_JOB_CANCELLED: hr = E_FAIL; break; case XPS_JOB_FAILED: hr = E_FAIL; break; default: hr = E_UNEXPECTED; break; } CloseHandle(completionEvent); } else { hr = HRESULT_FROM_WIN32(GetLastError()); } m_pTextRenderer->DiscardResources(); m_pTextRenderer->DeleteTemporaryFiles(); m_pTextRenderer = nullptr; }