From db449e3935bc8b765979e1d4a4ab3018908cbbd8 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 19 Nov 2016 15:27:15 +0100 Subject: [PATCH] Issue 5130 Fix the encoding of the PDF metadata when using guile-2.0 Postscript files are encoded in Latin1, but PDF metadata has to be encoded in UTF-16BE. ly:encode-string-for-pdf takes care of that but it was not working properly with guile-2.0 because the internal representation of strings in guile-2.0 has changed and the actual destination encoding has to be specified explicitly, especially when it's different from the current locale. Passing the encoded metadata as Latin1 corresponds to pass its raw byte representation, and this is enough to make things work. This also gets rid of a misleading warning: "`scm_take_str' is deprecated. Use scm_take_locale_stringn instead." This change is compatible with guile-1.8 so the FIXME comment in lily/pdf-scheme.cc has been removed. A note was added to scm/framework-ps.scm to suggest a possible implementation in scheme of ly_encode_for_pdf(), just in case of a possible future cleanup. --- lily/pdf-scheme.cc | 16 +++++++++------- scm/framework-ps.scm | 10 ++++++++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/lily/pdf-scheme.cc b/lily/pdf-scheme.cc index da2ce2cef3..61cf382e6b 100644 --- a/lily/pdf-scheme.cc +++ b/lily/pdf-scheme.cc @@ -84,14 +84,16 @@ LY_DEFINE (ly_encode_string_for_pdf, "ly:encode-string-for-pdf", free (p); /* Convert back to SCM object and return it */ - /* FIXME guile-2.0: With guile 2.0 the internal representation of a string - * has changed (char vector rather than binary bytes in - * UTF-8). However, with guile 2.0, ly:encode-string-for-pdf - * is no longer needed and can be replaced by the new - * (string->utf16 str 'big) - */ if (g) - return scm_take_str (g, bytes_written); // scm_take_str eventually frees g! + { + /* + * Return the raw byte representation of the UTF-16BE encoded string, + * in a locale independent way. + */ + SCM string = scm_from_latin1_stringn (g, bytes_written); + free(g); + return string; + } else return str; } diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm index 9498b2ac9d..2cd9b5edc6 100644 --- a/scm/framework-ps.scm +++ b/scm/framework-ps.scm @@ -599,8 +599,14 @@ (define (metadata-encode val) ;; First, call ly:encode-string-for-pdf to encode the string (latin1 or ;; utf-16be), then escape all parentheses and backslashes - ;; FIXME guile-2.0: use (string->utf16 str 'big) instead - + ;; + ;; NOTE: with guile-2.0+ ly:encode-string-for-pdf is not really needed and + ;; could be replaced with the following code: + ;; + ;; (let* ((utf16be-bom #vu8(#xFE #xFF))) + ;; (string-append (bytevector->string utf16be-bom "ISO-8859-1") + ;; (bytevector->string (string->utf16 val 'big) "ISO-8859-1"))) + ;; (ps-quote (ly:encode-string-for-pdf val))) (define (metadata-lookup-output overridevar fallbackvar field) (let* ((overrideval (ly:modules-lookup (list header) overridevar)) -- 2.39.2