Этот вопрос является конкретным вопросом о PoDoFo библиотека.
Как мне получить доступ к /Differences
запись массива в словаре кодирования ресурса Font?
После того, как я прочитал название шрифта из Tf
оператор, я могу получить шрифт через PoDoFo::PdfPage::GetFromResources
, Однако пока PdfFont
класс имеет PoDoFo::PdfFont::GetEncoding
Я не вижу, как вы дойдете до /Differences
массив оттуда.
Из PDFSpec (я беспокоюсь только о шрифтах типа 1):
кодирование
(Необязательно) Спецификация кодировки символов шрифта, если
отличается от встроенной кодировки. Значение кодирования должно быть
либо имя предопределенной кодировки (MacRomanEncoding,
MacExpertEncoding или WinAnsiEncoding, как описано в Приложении D) или
словарь кодирования, который должен указывать отличия от шрифта
встроенная кодировка или из указанной предварительно определенной кодировки (см. 9.6.6,
«Кодировка символов»).
Означает ли это PdfEncoding
объект вернулся из PoDoFo::PdfFont::GetEncoding
содержит массив различий (если он есть)?
(Я спрашивал в списке рассылки PoDoFo некоторое время назад, но отправляю сюда, чтобы увидеть, если кто-то со знанием PoDoFo
и PDF могут помочь).
PoDoFo знает много разных классов кодирования, ср. фабрика объектов кодирования:
if (pObject->IsName ())
{
const PdfName & rName = pObject->GetName ();
if (rName == PdfName ("WinAnsiEncoding"))
return PdfEncodingFactory::GlobalWinAnsiEncodingInstance ();
else if (rName == PdfName ("MacRomanEncoding"))
return PdfEncodingFactory::GlobalMacRomanEncodingInstance ();
else if (rName == PdfName ("StandardEncoding")) // OC 13.08.2010
return PdfEncodingFactory::GlobalStandardEncodingInstance ();
else if (rName == PdfName ("MacExpertEncoding")) // OC 13.08.2010 TODO solved
return PdfEncodingFactory::GlobalMacExpertEncodingInstance ();
else if (rName == PdfName ("SymbolEncoding")) // OC 13.08.2010
return PdfEncodingFactory::GlobalSymbolEncodingInstance ();
else if (rName == PdfName ("ZapfDingbatsEncoding")) // OC 13.08.2010
return PdfEncodingFactory::GlobalZapfDingbatsEncodingInstance ();
else if (rName == PdfName ("Identity-H"))
return new PdfIdentityEncoding ();
}
else if (pObject->HasStream ()) // Code for /ToUnicode object
{
return new PdfCMapEncoding(pObject);
}
else if (pObject->IsDictionary ())
{
return new PdfDifferenceEncoding (pObject);
}
(PoDoFo / SRC / DOC / PdfEncodingObjectFactory.cpp)
Вы заинтересованы в последнем случае. Таким образом, если имеющийся у вас объект кодирования является экземпляром PdfDifferenceEncoding, вы можете использовать:
/** PdfDifferenceEncoding is an encoding, which is based
* on either the fonts encoding or a predefined encoding
* and defines differences to this base encoding.
*/
class PODOFO_DOC_API PdfDifferenceEncoding : public PdfEncoding, private PdfElement {
public:
[...]
/**
* Get read-only access to the object containing the actual
* differences.
*
* \returns the container with the actual differences
*/
inline const PdfEncodingDifference & GetDifferences() const;
[...]
};
(PoDoFo / SRC / DOC / PdfDifferenceEncoding.h)
PdfDifferenceEncoding
объявлен в том же классе заголовка и предлагает несколько интересных методов:
/** A helper class for PdfDifferenceEncoding that
* can be used to create a differences array.
*/
class PODOFO_DOC_API PdfEncodingDifference {
struct TDifference {
int nCode;
PdfName name;
pdf_utf16be unicodeValue;
};
typedef std::vector<TDifference> TVecDifferences;
typedef std::vector<TDifference>::iterator TIVecDifferences;
typedef std::vector<TDifference>::const_iterator TCIVecDifferences;
public:
/** Create a PdfEncodingDifference object.
*/
PdfEncodingDifference();
/** Copy a PdfEncodingDifference object.
*/
PdfEncodingDifference( const PdfEncodingDifference & rhs );
/** Copy a PdfEncodingDifference object.
*/
const PdfEncodingDifference & operator=( const PdfEncodingDifference & rhs );
/** Add a difference to the object.
*
* \param nCode unicode code point of the difference (0 to 255 are legal values)
*
* \see AddDifference if you know the name of the code point
* use the overload below which is faster
*/
void AddDifference( int nCode );
/** Add a difference to the object.
*
* \param nCode unicode code point of the difference (0 to 255 are legal values)
* \param rName name of the different code point or .notdef if none
*/
void AddDifference( int nCode, const PdfName & rName );
/** Tests if the specified code is part of the
* differences.
*
* \param nCode test if the given code is part of the differences
* \param rName write the associated name into this object if the
* code is part of the difference
* \param rValue write the associated unicode value of the name to this value
*
* \returns true if the code is part of the difference
*/
bool Contains( int nCode, PdfName & rName, pdf_utf16be & rValue ) const;
/** Convert the PdfEncodingDifference to an array
*
* \param rArray write to this array
*/
void ToArray( PdfArray & rArray );
/** Get the number of differences in this object.
* If the user added .notdef as a difference it is
* counted, even it is no real difference in the final encoding.
*
* \returns the number of differences in this object
*/
inline size_t GetCount() const;
private:
struct DifferenceComparatorPredicate {
public:
inline bool operator()( const TDifference & rDif1,
const TDifference & rDif2 ) const {
return rDif1.nCode < rDif2.nCode;
}
};
TVecDifferences m_vecDifferences;
};
(PoDoFo / SRC / DOC / PdfDifferenceEncoding.h)
Как только у вас есть указатель на PoDoFo::PdfFont
, вы можете добраться до базового объекта с помощью вызова GetObject
так как он наследует его от PoDoFo :: PdfElement. Оттуда позвоните GetIndirectKey("Encoding")
получить указатель на словарь кодирования, который содержит массив различий, и передать его PoDoFo::PdfDifferenceEncoding
конструктор.
PoDoFo::PdfObject* fntobj = fnt->GetObject();
if (fntobj)
{
PoDoFo::PdfObject* fntdic = fntobj->GetIndirectKey("Encoding");
if (fntdic)
{
PoDoFo::PdfDifferenceEncoding diff(fntdic);
PoDoFo::PdfArray diffarray;
PoDoFo::PdfEncodingDifference d(diff.GetDifferences());
d.ToArray(diffarray);
}
}