Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 841475b

Browse files
[[ Bug 14278 ]] Workaround for Unicode output files on Windows
1 parent 161f2e0 commit 841475b

File tree

7 files changed

+117
-8
lines changed

7 files changed

+117
-8
lines changed

engine/src/w32printer.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,7 @@ const char *MCWindowsPrinterDevice::Error(void) const
11951195
}
11961196

11971197
// SN-2014-12-22: [[ Bug 14278 ]] Function updated to take wchar params
1198-
MCPrinterResult MCWindowsPrinterDevice::Start(HDC p_dc, const wchar *p_document_name, const wchar *p_output_file)
1198+
MCPrinterResult MCWindowsPrinterDevice::Start(HDC p_dc, const wchar_t *p_document_name, const wchar_t *p_output_file)
11991199
{
12001200
// SN-2014-12-22: [[ Bug 14278 ]] Document name and output file now encoded as UTF16 chars
12011201
DOCINFOW t_info;
@@ -1737,9 +1737,14 @@ MCPrinterResult MCWindowsPrinter::DoBeginPrint(MCStringRef p_document_name, MCPr
17371737
MCAutoStringRefAsWString t_doc_name, t_output_file;
17381738
/* UNCHECKED */ t_doc_name . Lock(p_document_name);
17391739

1740-
MCStringRef p_output_file_stringref;
1741-
MCStringCreateWithBytes(GetDeviceOutputLocation(), strlen(GetDeviceOutputLocation()), kMCStringEncodingUTF8, false, &t_output_file_stringref);
1742-
/* UNCHECKED */ t_output_file . Lock(*t_output_file_stringref);
1740+
MCAutoStringRef t_output_file_stringref;
1741+
if (GetDeviceOutputLocation() != NULL)
1742+
{
1743+
/* UNCHECKED */ MCStringCreateWithBytes((byte_t*)GetDeviceOutputLocation(), strlen(GetDeviceOutputLocation()), kMCStringEncodingUTF8, false, &t_output_file_stringref);
1744+
/* UNCHECKED */ t_output_file . Lock(*t_output_file_stringref);
1745+
}
1746+
else
1747+
t_output_file . Lock(kMCEmptyString);
17431748

17441749
t_result = t_device -> Start(t_dc, *t_doc_name, *t_output_file);
17451750

engine/src/w32printer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class MCWindowsPrinterDevice: public MCPrinterDevice
2929

3030
//
3131

32-
MCPrinterResult Start(HDC p_dc, const wchar *p_document_name, const wchar *p_output_file);
32+
MCPrinterResult Start(HDC p_dc, const wchar_t *p_document_name, const wchar_t *p_output_file);
3333
MCPrinterResult Finish(void);
3434

3535
//

revpdfprinter/src/revpdfprinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ bool MCPDFPrintingDevice::BeginDocument(const MCCustomPrinterDocument& p_documen
238238
bool t_success = true;
239239

240240
// SN-2014-12-22: [[ Bug 14278 ]] p_document.filename is now a UTF-8 string.
241-
t_success = MCCStringClone(p_document.filename, m_filename);
241+
t_success = get_filename(p_document.filename, m_filename);
242242

243243
if (t_success)
244244
{

revpdfprinter/src/revpdfprinter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class MCPDFPrintingDevice: public MCCustomPrintingDevice
7373
bool create_mask_surface_from_image(const MCCustomPrinterImage &p_image, cairo_surface_t* &r_surface);
7474
bool create_cairo_font_from_custom_printer_font(const MCCustomPrinterFont &p_cp_font, cairo_font_face_t* &r_cairo_font);
7575
bool set_cairo_pdf_datetime_to_now(cairo_pdf_datetime_t &r_datetime);
76+
bool get_filename(const char* p_utf8_path, char *& r_system_path);
7677

7778
private:
7879
struct FontCache

revpdfprinter/src/revpdfprinter_lnx.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,9 @@ bool MCPDFPrintingDevice::set_cairo_pdf_datetime_to_now(cairo_pdf_datetime_t &r_
9494

9595
return true;
9696
}
97+
98+
// SN-2014-12-23: [[ Bug 14278 ]] Added system-specific to get the path.
99+
bool MCPDFPrintingDevice::get_filename(const char* p_utf8_path, char *& r_system_path)
100+
{
101+
return MCCStringClone(p_utf8_path, r_system_path);
102+
}

revpdfprinter/src/revpdfprinter_osx.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,10 @@ bool MCPDFPrintingDevice::set_cairo_pdf_datetime_to_now(cairo_pdf_datetime_t &r_
4949
r_datetime.utc_minute_offset = 0;
5050

5151
return true;
52-
}
52+
}
53+
54+
// SN-2014-12-23: [[ Bug 14278 ]] Added system-specific to get the path.
55+
bool MCPDFPrintingDevice::get_filename(const char* p_utf8_path, char *& r_system_path)
56+
{
57+
return MCCStringClone(p_utf8_path, r_system_path);
58+
}

revpdfprinter/src/revpdfprinter_w32.cpp

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2020

2121
#include <windows.h>
2222

23+
#include <Shlwapi.h>
24+
2325
#include <cairo-pdf.h>
2426

2527
bool MCPDFPrintingDevice::create_cairo_font_from_custom_printer_font(const MCCustomPrinterFont &p_cp_font, cairo_font_face_t* &r_cairo_font)
@@ -50,4 +52,93 @@ bool MCPDFPrintingDevice::set_cairo_pdf_datetime_to_now(cairo_pdf_datetime_t &r_
5052
r_datetime.utc_minute_offset = 0;
5153

5254
return true;
53-
}
55+
}
56+
57+
// SN-2014-12-23: [[ Bug 14178 ]] Windows doesn't support UTF-8 filepaths
58+
bool MCPDFPrintingDevice::get_filename(const char* p_utf8_path, char *& r_system_path)
59+
{
60+
bool t_success;
61+
t_success = true;
62+
63+
LPWSTR t_wstring;
64+
DWORD t_wlength;
65+
t_wstring = NULL;
66+
67+
LPWSTR t_shortpath;
68+
DWORD t_shortpath_length;
69+
t_shortpath = NULL;
70+
71+
LPSTR t_system_path;
72+
DWORD t_sys_length;
73+
74+
uint32_t t_size = strlen(p_utf8_path);
75+
76+
t_wlength = MultiByteToWideChar(CP_UTF8, 0, p_utf8_path, strlen(p_utf8_path), 0, 0);
77+
78+
t_success = t_wlength != 0;
79+
80+
if (t_success)
81+
{
82+
t_wstring = (LPWSTR)calloc(t_wlength + 1, sizeof(WCHAR));
83+
MultiByteToWideChar(CP_UTF8, 0, p_utf8_path, strlen(p_utf8_path), t_wstring, t_wlength);
84+
}
85+
86+
// Create a file if needed, otherwise GetShortPathName does not work.
87+
DWORD t_attrs;
88+
t_attrs = GetFileAttributesW(t_wstring);
89+
90+
bool t_file_created;
91+
t_file_created = false;
92+
93+
if (t_success && t_attrs == INVALID_FILE_ATTRIBUTES)
94+
{
95+
HANDLE t_file_handle = CreateFileW(t_wstring, GENERIC_WRITE, 0, NULL,
96+
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
97+
98+
if (t_file_handle == NULL)
99+
t_success = false;
100+
else
101+
{
102+
CloseHandle(t_file_handle);
103+
t_file_created = true;
104+
}
105+
}
106+
107+
if (t_success)
108+
{
109+
t_shortpath_length = GetShortPathNameW(t_wstring, NULL, 0);
110+
111+
if (t_shortpath_length == 0)
112+
t_success = false;
113+
}
114+
115+
if (t_success)
116+
{
117+
t_shortpath = (LPWSTR)calloc(t_shortpath_length + 1, sizeof(WCHAR));
118+
GetShortPathName(t_wstring, t_shortpath, t_shortpath_length);
119+
}
120+
121+
if (t_success)
122+
{
123+
t_sys_length = WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, t_shortpath, t_shortpath_length, 0, 0, 0, 0);
124+
t_success = t_sys_length != 0;
125+
}
126+
127+
if (t_success)
128+
{
129+
t_system_path = (LPSTR)calloc(t_sys_length + 1, sizeof(CHAR));
130+
WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, t_shortpath, t_shortpath_length, t_system_path, t_sys_length, 0, 0);
131+
}
132+
133+
// Memory cleanup
134+
if (!t_success && t_file_created)
135+
DeleteFileW(t_wstring);
136+
137+
delete t_wstring;
138+
delete t_shortpath;
139+
140+
if (t_success)
141+
r_system_path = (char*)t_system_path;
142+
143+
return t_success;
144+
}

0 commit comments

Comments
 (0)