Hi Dominik

The problem I'm still having is an EXC_BAD_ACCESS when trying to access the 
destination object of the annotation (have a look at the commented 
->GetDestination() line of the original example source I posted). There doesn't 
appear to be a similar bool inverting bug with HasDestination() as there was 
with HasValue(), at least. The annotation definitely does have a destination in 
this case. 

This crash with ann->GetDestination() is actually why I started delving into 
the names tree, to piece together the page number and fit information for the 
link destination from the dictionary retrieved for the destination object name 
from the names tree instead of getting it from the PdfDestination object. I 
worked out a way to construct a PdfDestination from the object as follows:

if (ann->HasDestination()) {
        if (ann->HasAction()) {
                MTLog(@"Link has both a destination and an action");
        }
        //PdfDestination destination = ann->GetDestination(); //this crashes 
with an EXC_BAD_ACCESS!
        
        PdfDictionary dict = ann->GetObject()->GetDictionary();
        PdfObject *indirKey = ann->GetObject()->GetIndirectKey("Dest");
        PdfString str = indirKey->GetString();
        
        if (namesTree->GetValue(PdfName("Dests"),str)) {
                PdfObject *destObj = namesTree->GetValue(PdfName("Dests"), str);
                
                if (destObj) {
                        if (destObj->GetDataType() == ePdfDataType_Dictionary) {
                                PdfDictionary destObjDict = 
destObj->GetDictionary();
                                
                                if (destObjDict.GetKey(PdfName("D")) != NULL) {
                                        PdfDestination destination = 
PdfDestination(destObjDict.GetKey(PdfName("D")));
                                        //PdfPage *page = 
destination.GetPage(); //this also crashes with EXC_BAD_ACCESS!
                                }
                        }
                }
        } else {
                cerr << "No such destination\n";
        }
}

The crash in PdfDestination::GetPage() occurs here:

PdfPage* PdfDestination::GetPage()
{
    if( !m_array.size() )
        return NULL;

    PdfDocument* pDoc = m_pObject->GetOwner()->GetParentDocument(); 
//EXC_BAD_ACCESS here
    if( !pDoc ) 
        return NULL;

    // first entry in the array is the page - so just make a new page from it!
    return pDoc->GetPagesTree()->GetPage( m_array[0].GetReference() );
}


GetParentDocument simply looks like this:

inline PdfDocument* PdfVecObjects::GetParentDocument() const
{
    return m_pDocument;
}

So, m_pDocument is not what it should. What am I doing wrong?


On 6 Jan 2011, at 17:54, Dominik Seichter wrote:

> Hi Matias,
> 
> You are obviously right! I fixed the implementation of PdfNamesTree::HasValue.
> Does this change fix the first problem you reported?
> 
> Cheers,
>       Dominik
> 
> On Thursday, January 06, 2011 04:54:48 pm Matias wrote:
>> I found a seeming bug in PdfNamesTree::HasValue whilst trying to debug this
>> issue. As Leonard helpfully pointed out, I should drop the / from in front
>> of the name. I put it there in confusion because HasValue returned false
>> if I queried for the key name without the slash. Well, as it turns out,
>> the definition of PdfNamesTree::HasValue is as follows:
>> 
>> bool PdfNamesTree::HasValue( const PdfName & tree, const PdfString & key )
>> const {
>>    return ( this->GetValue( tree, key) == NULL );
>> }
>> 
>> Surely it should be != NULL ?
>> 
>>> I have a PdfAnnotation* stored in a variable named ann. The destination
>>> of this PDF annotation is a named object in the document (a page
>>> object). I've checked that ann->HasDestination() returns true for it.
>>> However, if I try the following, I get an EXC_BAD_ACCESS: PdfDestination
>>> destination = ann->GetDestination();
>>> 
>>> Furthermore, if I try and resolve the destination of the object in the
>>> following way through the /Dests names tree of the document, I get a
>>> NULL back:
>>> 
>>> PdfDictionary dict = ann->GetObject()->GetDictionary();
>>> PdfObject *indirKey = ann->GetObject()->GetIndirectKey("Dest");
>>> cerr << indirKey->GetString().GetStringUtf8(); //returns the name of the
>>> named object correctly
>>> 
>>> PdfNamesTree *namesTree = doc->GetNamesTree();
>>> PdfObject *dests = namesTree->GetDestsNode();
>>> PdfString str = indirKey->GetString();
>>> PdfObject *indirObj = dests->GetIndirectKey(str.GetStringUtf8());
>>> 
>>> if (namesTree->HasValue(PdfName("/Dests"),str)) {
>>> 
>>>     PdfObject *destObj = namesTree->GetValue(PdfName("/Dests"),
>>>     indirKey->GetString());
>>>     
>>>     if (!destObj) {
>>>     
>>>             cerr << "Value is NULL!"; //this code is reached, and it 
>>> shouldn't?
>>>     
>>>     }
>>> 
>>> }
>>> 
>>> Any ideas of what I am doing wrong? Does this have something to do with
>>> lazy loading and accessing an indirect key perhaps?
>>> ------------------------------------------------------------------------
>>> ------ Learn how Oracle Real Application Clusters (RAC) One Node allows
>>> customers to consolidate database storage, standardize their database
>>> environment, and, should the need arise, upgrade to a full multi-node
>>> Oracle RAC database without downtime or disruption
>>> http://p.sf.net/sfu/oracle-sfdevnl
>>> _______________________________________________
>>> Podofo-users mailing list
>>> [email protected]
>>> https://lists.sourceforge.net/lists/listinfo/podofo-users
>> 
>> ---------------------------------------------------------------------------
>> --- Learn how Oracle Real Application Clusters (RAC) One Node allows
>> customers to consolidate database storage, standardize their database
>> environment, and, should the need arise, upgrade to a full multi-node
>> Oracle RAC database without downtime or disruption
>> http://p.sf.net/sfu/oracle-sfdevnl
>> _______________________________________________
>> Podofo-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/podofo-users

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to