首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

PDFlib 中文輸出實戰(一):使用 Acrobat 標準簡體中文字體與編碼對照表

     編輯:關於VC++

前言

PDFlib 是國際廣泛使用的伺服器端 PDF 生成庫,支援 C/C++、Java、Perl、PHP、Python、Tcl、RealBasic 等語言。本系列文章分享使用 PDFlib 輸出簡體中文的實戰經驗。第一篇介紹 PDFlib 內建的三款 Acrobat 標準簡體中文字體、支援的 14 種編碼格式、字體與編碼的最佳組合策略,並提供完整 C 語言範例程式碼。

PDFlib 內建三款 Acrobat 標準簡體中文字體

  • STSong-Light
  • AdobeSongStd-Light-Acro
  • STSongStd-Light-Acro

這三款字體均為 Acrobat 內建標準字體,無需額外安裝即可在 PDF 中正確顯示,適合跨平台文件交換。

支援的 14 種編碼格式完整對照表

編碼名稱字符集與文本格式
UniGB-UCS2-H / -VUnicode (UCS-2) 編碼,適用於 Adobe-GB1 字符集
UniGB-UTF16-H / -VUnicode (UTF-16BE) 編碼,含 GB18030-2000 所有字符映射
GB-EUC-H / -VMicrosoft Code Page 936 (charset 134),GB 2312-80,EUC-CN 編碼
GBpc-EUC-H / -VMacintosh,GB 2312-80,EUC-CN,Script Manager code 2
GBK-EUC-H / -VMicrosoft Code Page 936,GBK 字符集,GBK 編碼
GBKp-EUC-H / -V同 GBK-EUC-H,但半形拉丁字符改為比例字體,0x24 映射為 $ 而非 ¥
GBK2K-H / -VGB 18030-2000 字符集,混合 1/2/4 位元組編碼

命名規則:-H 為橫向輸出,-V 為縱向輸出;Uni 開頭為 Unicode 類編碼,GB 開頭為 CP936 類編碼。

字體與編碼組合策略

雖然理論上 3 種字體 × 14 種編碼 = 42 種組合,但 PDFlib 並非支援所有組合。最穩妥、相容性最好的組合是:

PDFlib 內建三種字體 + Unicode 類編碼 (UniGB-UCS2-H/V, UniGB-UTF16-H/V)

Unicode 編碼支援完整字符集,避免 CP936 編碼在某些字體組合下出現字符缺失或錯位問題。

調用方式

int Font_CS;
Font_CS = PDF_load_font(p, "STSong-Light", 0, "UniGB-UTF16-H", "");

完整 C 語言範例:遍歷所有字體與編碼組合

程式碼自動產生多頁 PDF,每頁展示一種字體搭配 14 種編碼的輸出效果。Unicode 編碼使用 Unicode 字串,CP936 編碼使用 CP936 字串,自動判斷橫向/縱向編碼調整行距。

/*******************************************************************/
/* This example demostrates the usage of PDFlib builtin fonts */
/* based on Chinese Simplifed Windows. */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdflib.h"

int main(void) {
    PDF *p = NULL;
    int i = 0, j = 0, Left = 50, Top = 800;
    int Font_E = 0, Font_CS = 0;
    char TextUnicode[] = "\x80\x7B\x53\x4F\x2D\x4E\x87\x65";
    char TextCp936[] = "\xBC\xF2\xCC\xE5\xD6\xD0\xCE\xC4";
    char EncodingName[100];
    static const char *ChineseFont[] = {"STSong-Light", "AdobeSongStd-Light-Acro", "STSongStd-Light-Acro", };
    static const char *Encoding[] = {
        "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF16-H", "UniGB-UTF16-V",
        "GB-EUC-H", "GB-EUC-V", "GBpc-EUC-H", "GBpc-EUC-V",
        "GBK-EUC-H", "GBK-EUC-V", "GBKp-EUC-H", "GBKp-EUC-V",
        "GBK2K-H", "GBK2K-V",
    };
    const int fsize = sizeof ChineseFont / sizeof (char *);
    const int esize = sizeof Encoding / sizeof (char *);

    /* create a new PDFlib object */
    if ((p = PDF_new()) == (PDF *) 0) {
        printf("Couldn't create PDFlib object (out of memory)!\n");
        return(2);
    }

    PDF_TRY(p) {
        if (PDF_begin_document(p, "pdflib_cs1.pdf", 0, "") == -1) {
            printf("Error: %s\n", PDF_get_errmsg(p));
            return(2);
        }
        PDF_set_info(p, "Creator", "pdflib_cs1.c");
        PDF_set_info(p, "Author", "bowriver2001@yahoo.ca");
        PDF_set_info(p, "Title", "Output Chinese Simplify with PDFlib builtin font");
        Font_E = PDF_load_font(p, "Helvetica-Bold", 0, "winansi", "");

        for (i = 0; i < fsize; i++) {
            /*Start a new page. */
            Top = 800;
            PDF_begin_page_ext(p, a4_width, a4_height, "");
            PDF_setfont(p, Font_E, 24);
            PDF_show_xy(p, ChineseFont[i] , Left + 50, Top);
            Top -= 30;

            for (j = 0; j < esize; j++) {
                Font_CS = PDF_load_font(p, ChineseFont[i], 0, Encoding[j], "");
                PDF_setfont(p, Font_E, 12);
                strcpy(EncodingName, "");
                strcat(EncodingName, Encoding[j]);
                strcat(EncodingName, ":");
                PDF_show_xy(p, EncodingName , Left, Top);
                PDF_setfont(p, Font_CS, 12);

                if (strstr(Encoding[j], "-H") != NULL) {
                    /* It's horizontal encoding. */
                    Top -= 15;
                }
                if (strstr(Encoding[j], "UniGB") != NULL) {
                    /* It's unicode encoding. */
                    PDF_show_xy2(p, TextUnicode, 8, Left, Top);
                } else {
                    /* It's code page 936 encoding. */
                    PDF_show_xy2(p, TextCp936, 8, Left, Top);
                }
                if (strstr(Encoding[j], "-H") != NULL) {
                    /* It's horizontal encoding. */
                    Top -= 25;
                } else {
                    /* It's vertical encoding. */
                    Top -= 65;
                }
            }
            /* End of page. */
            PDF_end_page_ext(p, "");
        }
        PDF_end_document(p, "");
    }
    PDF_CATCH(p) {
        printf("PDFlib exception occurred in pdflib_cs1 sample:\n");
        printf("[%d] %s: %s\n", PDF_get_errnum(p), PDF_get_apiname(p), PDF_get_errmsg(p));
        PDF_delete(p);
        return(2);
    }
    PDF_delete(p);
    return 0;
}

關鍵提醒

  1. 優先選 Unicode 編碼:UniGB-UTF16-H 含 GB18030 全字符集,相容性最佳。
  2. 避免 CP936 與非標準字體組合:可能導致字符缺失,除非確認該組合經過測試。
  3. 授權問題:無 License 時輸出 PDF 會帶 PDFlib 浮水印,正式產品需購買授權。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved