Example #1
0
HRESULT CTxtSlave::ComputeFormats(CFormatInfo* pCFI, CTreeNode* pNodeTarget)
{
    HRESULT         hr = S_OK;
    CTreeNode*      pNodeMaster = NULL;
    CElement*       pElemMaster = MarkupMaster();
    CDocument*      pDoc = Doc();
    THREADSTATE*    pts  = GetThreadState();
    BOOL            fComputeFFOnly = pNodeTarget->_iCF != -1;
    COMPUTEFORMATSTYPE eExtraValues = pCFI->_eExtraValues;

    Assert(pCFI);
    Assert(SameScope(this, pNodeTarget));
    Assert(eExtraValues!=ComputeFormatsType_Normal || ((pNodeTarget->_iCF==-1 && pNodeTarget->_iPF==-1) || pNodeTarget->_iFF==-1));

    if(pElemMaster)
    {
        pNodeMaster = pElemMaster->GetFirstBranch();

        // Get the format of our master before applying our own format.
        if(pNodeMaster)
        {
            // If the master node has not computed formats yet, recursively compute them
            if(pNodeMaster->_iCF==-1 || pNodeMaster->_iFF==-1
                || eExtraValues==ComputeFormatsType_GetInheritedValue)
            {

                hr = pElemMaster->ComputeFormats(pCFI, pNodeMaster);

                if(hr)
                {
                    goto Cleanup;
                }
            }

            Assert(pNodeMaster->_iCF >= 0);
            Assert(pNodeMaster->_iPF >= 0);
            Assert(pNodeMaster->_iFF >= 0);
        }
    }

    // NOTE: From this point forward any errors must goto Error instead of Cleanup!
    pCFI->Reset();
    pCFI->_pNodeContext = pNodeTarget;

    if(pNodeMaster)
    {
        // Inherit para format directly from the master node.
        pCFI->_iffSrc = pNodeMaster->_iFF;
        pCFI->_pffSrc = pCFI->_pff = &(*pts->_pFancyFormatCache)[pCFI->_iffSrc];
        pCFI->_fHasExpandos = (pCFI->_pff->_iExpandos >= 0);

        if(!fComputeFFOnly)
        {
            // Inherit the Char and Para formats from the master node
            pCFI->_icfSrc = pNodeMaster->_iCF;
            pCFI->_pcfSrc = pCFI->_pcf = &(*pts->_pCharFormatCache)[pCFI->_icfSrc];
            pCFI->_ipfSrc = pNodeMaster->_iPF;
            pCFI->_ppfSrc = pCFI->_ppf = &(*pts->_pParaFormatCache)[pCFI->_ipfSrc];

            // If the parent had layoutness, clear the inner formats
            if(pCFI->_pcf->_fHasDirtyInnerFormats)
            {
                pCFI->PrepareCharFormat();
                pCFI->_cf().ClearInnerFormats();
                pCFI->UnprepareForDebug();
            }
            if(pCFI->_ppf->_fHasDirtyInnerFormats)
            {
                pCFI->PrepareParaFormat();
                pCFI->_pf().ClearInnerFormats();
                pCFI->UnprepareForDebug();
            }
            if(pCFI->_ppf->_fPre != pCFI->_ppf->_fPreInner
                || pCFI->_ppf->_fInclEOLWhite != pCFI->_ppf->_fInclEOLWhiteInner
                || pCFI->_ppf->_bBlockAlign != pCFI->_ppf->_bBlockAlignInner)
            {
                pCFI->PrepareParaFormat();
                pCFI->_pf()._fPre = pCFI->_pf()._fPreInner;
                pCFI->_pf()._fInclEOLWhite = pCFI->_pf()._fInclEOLWhiteInner;
                pCFI->_pf()._bBlockAlign = pCFI->_pf()._bBlockAlignInner;
                pCFI->UnprepareForDebug();
            }

            if(pCFI->_pcf->_fNoBreak != pCFI->_pcf->_fNoBreakInner)
            {
                pCFI->PrepareCharFormat();
                pCFI->_cf()._fNoBreak = pCFI->_cf()._fNoBreakInner;
                pCFI->UnprepareForDebug();
            }
        }
        else
        {
            pCFI->_icfSrc = pDoc->_icfDefault;
            pCFI->_pcfSrc = pCFI->_pcf = pDoc->_pcfDefault;
            pCFI->_ipfSrc = pts->_ipfDefault;
            pCFI->_ppfSrc = pCFI->_ppf = pts->_ppfDefault;
        }
    }
    else
    {
        pCFI->_iffSrc = pts->_iffDefault;
        pCFI->_pffSrc = pCFI->_pff = pts->_pffDefault;
        pCFI->_icfSrc = pDoc->_icfDefault;
        pCFI->_pcfSrc = pCFI->_pcf = pDoc->_pcfDefault;
        pCFI->_ipfSrc = pts->_ipfDefault;
        pCFI->_ppfSrc = pCFI->_ppf = pts->_ppfDefault;

        Assert(pCFI->_pffSrc->_pszFilters == NULL);
    }

    if(pCFI->_pff->_fHasLayout || !pCFI->_pff->_fBlockNess)
    {
        pCFI->PrepareFancyFormat();
        pCFI->_ff()._fHasLayout = FALSE;
        pCFI->_ff()._fBlockNess = TRUE;
        pCFI->UnprepareForDebug();
    }

    if(eExtraValues == ComputeFormatsType_Normal)
    {
        hr = pNodeTarget->CacheNewFormats(pCFI);
        if(hr)
        {
            goto Error;
        }

        // Cache whether an element is a block element or not for fast retrieval.
        pNodeTarget->_fBlockNess = TRUE;

        pNodeTarget->_fHasLayout = FALSE;
    }

Cleanup:
    RRETURN(hr);

Error:
    pCFI->Cleanup();
    goto Cleanup;
}