cuốn sách gpt4 ai đã làm

Sự dịch chuyển ký tự không chính xác thu được bằng PoDoFo

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 12:58:21 29 4
mua khóa gpt4 Nike

Tôi đang sử dụng PoDoFo để trích xuất các chuyển vị ký tự nhằm cập nhật chính xác ma trận văn bản. Đây là một đoạn mã của tôi:

PdfString str, ucode_str;
std::stack *stack;
const PdfFontMetrics *f_metrics;
...

/*Chuyển chuỗi sang UTF8 */
str = stack->top().GetString();
ucode_str = ts->font->GetEncoding()->ConvertToUnicode(str, ts->font);
ngăn xếp->pop();
c_str = (char *) ucode_str.GetStringUtf8().c_str();

/* Số liệu phông chữ để có được độ dịch chuyển ký tự */
f_metrics = ts->font->GetFontMetrics();

for (j = 0; j < strlen(c_str); j++) {
str_w = f_metrics->CharWidth(c_str[j]);

/* Điều chỉnh ma trận văn bản bằng str_w */
...
}

Nó hoạt động với một số tệp PDF (str_w Chứa các chiều rộng hữu ích), nhưng không hoạt động với các tệp khác. Trong những trường hợp này,str_w 包含 0,0. Tôi đã kiểm tra PoDoFo 0,9,5 Mã nguồn, đã tìm thấy CharWidth() là dành cho Số liệu phông chữ Pdf Được thực hiện bởi tất cả các lớp con.

Tôi có thiếu điều gì quan trọng trong quá trình chuyển đổi chuỗi này không?

Cập nhật ngày 4 tháng 8 năm 2017

@mkl đã thực hiện rất tốt việc xem xét mã của PoDoFo. Tuy nhiên, tôi nhận ra rằng tôi phải lấy một số thông số khác. Nói chính xác hơn, tôi cần mộtđơn vị không gian văn bảnbày tỏchiều rộng glyph(参见Tài liệu tham khảo PDF 1.7,5.1.3 Định vị và chỉ báo Glyph),但是 CharWidth() 是在 PdfFontMetricsObject.cpp được thực hiện trong, ví dụ:

double PdfFontMetricsObject::CharWidth(unsigned char c) const
{
if (c >= m_nĐầu tiên && c <= m_nCuối &&
c - m_nFirst < static_cast(m_width.GetSize())) {
gấp đôi dWidth = m_width[c - m_nFirst].GetReal();

return (dWidth * m_matrix.front().GetReal() * this->GetFontSize() + this->GetFontCharSpace()) * this->GetFontScale() / 100.0;
}

nếu (m_missingWidth != NULL)
trả về m_missingWidth->GetReal();
khác
trả về m_dDefWidth;
}

Chiều rộng được tính bằng cách sử dụng các hệ số nhân bổ sung (chẳng hạn như cỡ chữ, khoảng cách ký tự, v.v.). tất cả những gì tôi thực sự cần là dWidth * m_matrix.front().GetReal(). Vì vậy tôi quyết định triển khai từ cùng một tệp GetGlyphWidth(int c),例如:

gấp đôi PdfFontMetricsObject::GetGlyphWidth(int c) const
{
if (c >= m_nĐầu tiên && c <= m_nCuối &&
c - m_nFirst < static_cast(m_width.GetSize())) {
gấp đôi dWidth = m_width[c - m_nFirst].GetReal();
trả về dWidth * m_matrix.front().GetReal();
}
trả về 0,0;
}

và gọi cái này thay vì cái đầu tiên trong danh sách CharWidth().

câu trả lời hay nhất

Nếu tôi hiểu chính xác mã Podofo (tôi thực sự không phải là chuyên gia về Podofo...),Đối tượng số liệu phông chữ Pdf Lớp được sử dụng để thể hiện các đặc tả phông chữ có trong các tệp PDF hiện có:

/** Tạo đối tượng số liệu phông chữ dựa trên PdfObject hiện có
*
* \param pObject một đối tượng mô tả phông chữ hiện có
* \param pEncoding một PdfEncoding sẽ KHÔNG thuộc sở hữu của PdfFontMetricsObject
*/
PdfFontMetricsObject( PdfObject* pFont, PdfObject* pDescriptor, const PdfEncoding* const pEncoding );

Đây là phương phápCharWidthĐây là cách nó đạt được:

double PdfFontMetricsObject::CharWidth( unsigned char c ) const
{
if( c >= m_nĐầu tiên && c <= m_nCuối cùng
&& c - m_nFirst < static_cast(m_width.GetSize()) )
{
gấp đôi dWidth = m_width[c - m_nFirst].GetReal();

return (dWidth * m_matrix.front().GetReal() * this->GetFontSize() + this->GetFontCharSpace()) * this->GetFontScale() / 100.0;
}

if( m_missingWidth != NULL )
trả về m_missingWidth->GetReal ();
khác
trả về m_dDefWidth;
}

Đặc biệt là nhìn thấy các thông số c Mã hóa không dựa trên mã hóa phông chữ mà được để tra cứu trong mảng độ rộng. Do đó, có vẻ như đầu vào dự kiến ​​cho phương thức này không phải là mã ký tự ASCII hoặc ANSI mà là ID glyph thô.

Mặt khác, mã của bạn đã chuyển đổi ID glyph thành Unicode trong UTF-8, vì vậy về cơ bản nó đang cố tra cứu bằng mã ký tự ANSI.


Điều này sẽ khớp với tài liệu mẫu, bảng mã phông chữ điển hình trong tệp PDF xử lý lỗi như sau

28 0 đối tượng
<<
/sự khác biệt[0/B/G/W/a/d/e/f/g 9/i/l/n/o/p/r/dấu cách/t/w]
/BaseEncoding/MacRomanEncoding
/Loại/Mã hóa
>>
endobj

Mã Glyph bắt đầu từ 0 (đầu tiênchar) đến 17 (LastChar),hoặc

12 0 đối tượng
<<
/Sự khác biệt[1/A/B/C/D/F/I/L/M/N/O/P/R/T/U/a/c/d
/độ/e/tám/f/năm/bốn/g/h
27/i/l/m/n/o/one/p/parenleft/parenright
/thời gian/r/đã đăng ký/s/dấu cách
/t/ba/hai/u/w/zero]
/BaseEncoding/MacRomanEncoding
/Loại/Mã hóa
>>
endobj

Mã Glyph bắt đầu từ 1 (đầu tiênchar) đến 46 (LastChar).

Vì vậy, các mã hóa này xử lý mã glyph cho tất cả các glyph bắt buộc bắt đầu từ 0 và không thực sự bao gồm nhiều glyph đó

Do đó, đối với tất cả các giá trị ký tự lớn hơn 17 hoặc lớn hơn 46,CharWidth sẽ trở lại 0, có nghĩa là tất cả (trong trường hợp trước) hoặc hầu hết (trong trường hợp sau) các ký tự không điều khiển ANSI.

Mặt khác, mã hóa phông chữ điển hình trong tệp PDF được xử lý đúng cách sẽ trông như thế này:

1511 0 đối tượng
<<
/Loại/Mã hóa
/BaseEncoding/WinAnsiEncoding
/Sự khác biệt[
1/Đồng bằng/Theta
8/Phi
11/ff/fi/fl/ffi
39/trích dẫn
]
>>
endobj

Mã Glyph bắt đầu từ 1 (đầu tiênchar) đến 122 (LastChar).

Các mã hóa này về cơ bản là WinAnsiEncoding, một lượng nhỏ nội dung đã được thêm vào các giá trị thấp hơn, đặc biệt là các giá trị ký tự điều khiển.


Vì vậy, những gì bạn có thể làm là lặp đi lặp lại str Mã Glyph trong (cho phép bạn gọi CharWidth) và chuyển đổi chúng riêng lẻ sang Unicode nếu cần trước tiên bằng cách str Chuyển đổi sang Unicode ucode_str, sau đó lặp lại ucode_str Các ký tự ANSI trong .

Về c++ - dịch chuyển ký tự thu được bằng PoDoFo là không chính xác, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/45483845/

29 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress