Logo Search packages:      
Sourcecode: ted version File versions

docRtfWrite.c

/************************************************************************/
/*                                                    */
/*  Save a BufferDocument into an RTF file.                       */
/*                                                    */
/************************************************************************/

#   include "tedConfig.h"

#   include <stdlib.h>
#   include <string.h>
#   include <stdio.h>
#   include <ctype.h>

#   include <bitmap.h>

#   include <appDebugon.h>

#   include <charnames.h>
#   include <psFont.h>
#   include "docRtf.h"

/************************************************************************/
/*                                                    */
/*  Forward declaration..                                   */
/*                                                    */
/************************************************************************/

static int docRtfSaveItem(    SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferItem *            bi,
                        const BufferDocument *        bd,
                        const DocumentSelection *     ds,
                        RtfWritingContext *           rwc );

/************************************************************************/
/*                                                    */
/*  Save a paragraph in RTF format.                         */
/*                                                    */
/*  Column counting is approximate as it is only for cosmetic reasons.  */
/*                                                    */
/************************************************************************/

static void docRtfParaSaveProperties( SimpleOutputStream *  sos,
                        int                     fromDefault,
                        int                     saveIntbl,
                        int *                   pPropertyChange,
                        int *                   pTabsSaved,
                        int *                   pCol,
                        const ParagraphProperties *   newPP,
                        const ParagraphProperties *   prevPP )
    {
    ParagraphProperties       ppp;
    PropertyMask        updMask;

    PROPmaskCLEAR( &updMask );

    if  ( ! fromDefault )
      {
      PROPmaskCLEAR( &updMask );
      PROPmaskFILL( &updMask, PPprop_COUNT );
      PROPmaskUNSET( &updMask, PPpropIN_TABLE );

      docParaPropertyDifference( &updMask, newPP, prevPP, &updMask );

      if  ( PROPmaskISEMPTY( &updMask ) )
          { return;     }
      }

    docInitParagraphProperties( &ppp );

    /*  1  */
    docRtfWriteTag( "\\pard", pCol, sos );
    *pPropertyChange= 1;

    if  ( saveIntbl && newPP->ppInTable )
      { docRtfWriteTag( "\\intbl", pCol, sos ); }

    PROPmaskCLEAR( &updMask );
    PROPmaskFILL( &updMask, PPprop_COUNT );
    PROPmaskUNSET( &updMask, PPpropIN_TABLE );

    docParaPropertyDifference( &updMask, newPP, &ppp, &updMask );

    docCleanParagraphProperties( &ppp );

    docRtfSaveParagraphProperties( sos, pCol, &updMask, newPP );

    if  ( PROPmaskISSET( &updMask, PPpropTAB_STOPS )  &&
        newPP->ppTabStopList.tslTabStopCount > 0      )
      { *pTabsSaved= 1; }

    return;
    }

int docRtfSaveRuler(    SimpleOutputStream *          sos,
                  const ParagraphProperties *   pp )
    {
    int                       col= 0;
    int                       propChange= 1;
    int                       tabsSaved= 0;
    int                       saveIntbl= 0;
    int                       noRestart= 0;

    ParagraphProperties       refPP;

    docInitParagraphProperties( &refPP );

    docRtfWriteDestinationBegin( "\\ruler", &col, sos );
    docRtfWriteTag( "\\pard", &col, sos );

    docRtfParaSaveProperties( sos, noRestart, saveIntbl,
                        &propChange, &tabsSaved, &col, pp, &refPP );

    docRtfWriteDestinationEnd( &col, sos );

    docCleanParagraphProperties( &refPP );

    return 0;
    }

static int docRtfSaveObject(  SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferItem *            bi,
                        const TextParticule *         tp )
    {
    InsertedObject *    io= bi->biParaObjects+ tp->tpObjectNumber;

    docRtfWriteNextLine( pCol, sos );

    switch( io->ioKind )
      {
      case DOCokPICTWMETAFILE:
          docRtfWriteDestinationBegin( "\\pict", pCol, sos );
          docRtfWriteArgTag( "\\wmetafile", pCol, io->ioMapMode, sos );

          if  ( io->ioMetafileIsBitmap )
            {
            docRtfWriteTag( "\\picbmp", pCol, sos );

            if  ( io->ioMetafileBitmapBpp > 0 )
                {
                docRtfWriteArgTag( "\\picbpp",
                              pCol, io->ioMetafileBitmapBpp, sos );
                }
            }

          docRtfSavePictureTags( io, pCol, sos );

          docRtfWriteMemoryBuffer( &(io->ioObjectData), pCol, sos );
          return 0;

      case DOCokMACPICT:
          docRtfWriteDestinationBegin( "\\pict", pCol, sos );
          docRtfWriteTag( "\\macpict", pCol, sos );

          docRtfSavePictureTags( io, pCol, sos );

          docRtfWriteMemoryBuffer( &(io->ioObjectData), pCol, sos );

          return 0;

      case DOCokPICTPNGBLIP:
          docRtfWriteDestinationBegin( "\\pict", pCol, sos );
          docRtfWriteTag( "\\pngblip", pCol, sos );

          docRtfSavePictureTags( io, pCol, sos );

          docRtfWriteMemoryBuffer( &(io->ioObjectData), pCol, sos );
          return 0;

      case DOCokPICTJPEGBLIP:
          docRtfWriteDestinationBegin( "\\pict", pCol, sos );
          docRtfWriteTag( "\\jpegblip", pCol, sos );

          docRtfSavePictureTags( io, pCol, sos );

          docRtfWriteMemoryBuffer( &(io->ioObjectData), pCol, sos );
          return 0;

      case DOCokPICTEMFBLIP:
          docRtfWriteDestinationBegin( "\\pict", pCol, sos );
          docRtfWriteTag( "\\emfblip", pCol, sos );

          docRtfSavePictureTags( io, pCol, sos );

          docRtfWriteMemoryBuffer( &(io->ioObjectData), pCol, sos );
          return 0;

      case DOCokOLEOBJECT:
          docRtfWriteDestinationBegin( "\\object", pCol, sos );


          switch( io->ioRtfEmbedKind )
            {
            case EMBEDkindOBJEMB:
                docRtfWriteTag( "\\objemb", pCol, sos );
                break;
            case EMBEDkindOBJLINK:
                docRtfWriteTag( "\\objlink", pCol, sos );
                break;
            case EMBEDkindOBJAUTLINK:
                docRtfWriteTag( "\\objautlink", pCol, sos );
                break;
            case EMBEDkindOBJSUB:
                docRtfWriteTag( "\\objsub", pCol, sos );
                break;
            case EMBEDkindOBJPUB:
                docRtfWriteTag( "\\objpub", pCol, sos );
                break;
            case EMBEDkindOBJICEMB:
                docRtfWriteTag( "\\objicemb", pCol, sos );
                break;
            case EMBEDkindOBJHTML:
                docRtfWriteTag( "\\objhtml", pCol, sos );
                break;
            case EMBEDkindOBJOCX:
                docRtfWriteTag( "\\objocx", pCol, sos );
                break;
            default:
                LDEB(io->ioRtfEmbedKind);
                break;
            }

          switch( io->ioRtfResultKind )
            {
            case RESULTkindUNKNOWN:
                break;
            case RESULTkindRTF:
                docRtfWriteTag( "\\rsltrtf", pCol, sos );
                break;
            case RESULTkindTXT:
                docRtfWriteTag( "\\rslttxt", pCol, sos );
                break;
            case RESULTkindPICT:
                docRtfWriteTag( "\\rsltpict", pCol, sos );
                break;
            case RESULTkindBMP:
                docRtfWriteTag( "\\rsltbmp", pCol, sos );
                break;
            case RESULTkindHTML:
                docRtfWriteTag( "\\rslthtml", pCol, sos );
                break;
            default:
                LDEB(io->ioRtfResultKind);
                break;
            }

          if  ( io->ioObjectClass )
            {
            docRtfWriteDestinationBegin( "\\*\\objclass ", pCol, sos );
            sioOutPutString( (char *)io->ioObjectClass, sos );
            docRtfWriteDestinationEnd( pCol, sos );
            }

          if  ( io->ioObjectName )
            {
            docRtfWriteDestinationBegin( "\\*\\objname ", pCol, sos );
            sioOutPutString( (char *)io->ioObjectName, sos );
            docRtfWriteDestinationEnd( pCol, sos );
            }

          docRtfWriteArgTag( "\\objw", pCol, io->ioTwipsWide, sos );
          docRtfWriteArgTag( "\\objh", pCol, io->ioTwipsHigh, sos );
          if  ( io->ioScaleX != 100 )
            { docRtfWriteArgTag( "\\objscalex", pCol, io->ioScaleX, sos ); }
          if  ( io->ioScaleY != 100 )
            { docRtfWriteArgTag( "\\objscaley", pCol, io->ioScaleY, sos ); }

          docRtfWriteDestinationBegin( "\\*\\objdata ", pCol, sos );
          docRtfWriteMemoryBuffer( &io->ioObjectData, pCol, sos );

          if  ( io->ioResultKind == DOCokPICTWMETAFILE )
            {
            docRtfWriteDestinationBegin(
                      "\\result {\\pict", pCol, sos );

            docRtfWriteArgTag( "\\wmetafile",
                                  pCol, io->ioResultMapMode, sos );

            docRtfSavePictureTags( io, pCol, sos );

            docRtfWriteMemoryBuffer( &io->ioResultData, pCol, sos );

            docRtfWriteDestinationEnd( pCol, sos );
            }

          docRtfWriteDestinationEnd( pCol, sos );
          return 0;

      case DOCokINCLUDEPICTURE:
          return 0;

      default:
          LDEB(io->ioKind); return -1;
      }

    /*  Not reached ..
    return 0;
    */
    }

/************************************************************************/
/*                                                    */
/*  Reserve a number of columns in the output file.               */
/*                                                    */
/************************************************************************/

static void docRtfReserveColumns(   SimpleOutputStream *    sos,
                              int               cols,
                              int *             pCol,
                              RtfWritingContext *     rwc )
    {
    int                       col= *pCol;

    if  ( *pCol > 0 && *pCol+ cols > 72 )
      {
      docRtfWriteNextLine( pCol, sos );
      rwc->rwcHasPrecedingTags= 0;
      }

    *pCol= col; return;
    }

/************************************************************************/
/*                                                    */
/*  Finish/Begin writing a hyperlink.                             */
/*                                                    */
/************************************************************************/

static void docRtfFinishFldrslt(    SimpleOutputStream *    sos,
                              int *             pCol,
                              RtfWritingContext *     rwc )
    {
    PushedAttribute *   pa;

    docRtfWriteDestinationEnd( pCol, sos );
    docRtfWriteDestinationEnd( pCol, sos );
    docRtfWriteDestinationEnd( pCol, sos );

    rwc->rwcHasPrecedingTags= 0;
    rwc->rwcInFldrslt--;

    pa= rwc->rwcOutsideFldrsltAttribute;
    if  ( ! pa )
      { XDEB(pa); return;     }

    rwc->rwcTextAttribute= pa->paTextAttribute;
    rwc->rwcOutsideFldrsltAttribute= pa->paNext;

    free( pa );

    return;
    }

static void docRtfWriteStartField(  SimpleOutputStream *    sos,
                              const DocumentField *   df,
                              int *             pCol,
                              RtfWritingContext *     rwc )
    {
    PushedAttribute *         pa;
    const unsigned char *     bytes= df->dfInstructions.mbBytes;
    int                       byteCount= df->dfInstructions.mbSize;

    docRtfWriteDestinationBegin( "\\field", pCol, sos );
    docRtfWriteDestinationBegin( "\\*\\fldinst", pCol, sos );
    docRtfWriteDestinationBegin( "", pCol, sos );

    while( byteCount > 1 && bytes[byteCount- 1] == ' ' )
      { byteCount--;    }

    docRtfReserveColumns( sos, byteCount, pCol, rwc );

    docRtfEscapeString( bytes, (const unsigned char *)0, pCol, byteCount, sos );

    sioOutPutCharacter( ' ', sos ); *pCol += 1;
    docRtfWriteDestinationEnd( pCol, sos );
    docRtfWriteDestinationEnd( pCol, sos );

    docRtfWriteDestinationBegin( "\\fldrslt", pCol, sos );
    docRtfWriteDestinationBegin( "", pCol, sos );

    rwc->rwcHasPrecedingTags= 0;
    rwc->rwcInFldrslt++;

    pa= malloc( sizeof( PushedAttribute ) );
    if  ( ! pa )
      { XDEB(pa); return;     }
    pa->paNext= rwc->rwcOutsideFldrsltAttribute;
    rwc->rwcOutsideFldrsltAttribute= pa;
    pa->paTextAttribute= rwc->rwcTextAttribute;

    return;
    }

static void docRtfStartBookmark(    SimpleOutputStream *    sos,
                              const DocumentField *   df,
                              int *             pCol,
                              RtfWritingContext *     rwc )
    {
    const char *        markName= (char *)0;
    int                       markSize;

    if  ( ! docFieldGetBookmark( df, &markName, &markSize ) )
      {
      docRtfWriteDestinationBegin( "\\*\\bkmkstart ", pCol, sos );

      docRtfEscapeString( (const unsigned char *)markName, 
                                        (const unsigned char *)0,
                                        pCol, markSize, sos );

      docRtfWriteDestinationEnd( pCol, sos );
      rwc->rwcHasPrecedingTags= 0;
      }

    return;
    }

static void docRtfFinishBookmark(   SimpleOutputStream *    sos,
                              const DocumentField *   df,
                              int *             pCol,
                              RtfWritingContext *     rwc )
    {
    const char *        markName= (char *)0;
    int                       markSize;

    if  ( ! docFieldGetBookmark( df, &markName, &markSize ) )
      {
      docRtfWriteDestinationBegin( "\\*\\bkmkend ", pCol, sos );

      docRtfEscapeString( (const unsigned char *)markName, 
                                        (const unsigned char *)0,
                                        pCol, markSize, sos );

      docRtfWriteDestinationEnd( pCol, sos );
      rwc->rwcHasPrecedingTags= 0;
      }

    return;
    }

/************************************************************************/
/*                                                    */
/*  Enter/Leave a table.                                    */
/*                                                    */
/************************************************************************/

static int docRtfPushTable(   RtfWritingContext *           rwc,
                        int *                   pCol,
                        SimpleOutputStream *          sos,
                        const BufferItem *            rowBi,
                        const DocumentSelection *     ds )
    {
    PropertyMask  ppChgMask;
    PropertyMask  ppUpdMask;

    int                 col0= -1;
    int                 col1= -1;

    const int * const   colorMap= (const int *)0;
    const int * const   listStyleMap= (const int *)0;

    docRtfWriteNextLine( pCol, sos );
    docRtfWriteDestinationBegin( "", pCol, sos );

    rwc->rwcInTable= 1;

    rwc->rwcOutsideTableTextAttribute= rwc->rwcTextAttribute;

    PROPmaskCLEAR( &ppChgMask );

    PROPmaskCLEAR( &ppUpdMask );
    PROPmaskFILL( &ppUpdMask, PPprop_COUNT );

    if  ( docUpdParaProperties( &ppChgMask,
                      &(rwc->rwcOutsideTableParagraphProperties),
                      &ppUpdMask, &(rwc->rwcParagraphProperties),
                      colorMap, listStyleMap ) )
      { LDEB(1); return -1;   }

    if  ( ds )
      { col0= ds->dsCol0; col1= ds->dsCol1;     }

    docRtfSaveRowProperties( &(rowBi->biRowProperties), pCol, col0, col1, sos );

    if  ( docCopyRowProperties( &(rwc->rwcRowProperties),
                        &(rowBi->biRowProperties), (const int *)0 ) )
      { LDEB(1); return -1;   }

    return 0;
    }

static int docRtfPopTable(    RtfWritingContext *     rwc,
                        int *             pCol,
                        SimpleOutputStream *    sos )
    {
    PropertyMask  ppChgMask;
    PropertyMask  ppUpdMask;

    const int * const   colorMap= (const int *)0;
    const int * const   listStyleMap= (const int *)0;

    docRtfWriteDestinationEnd( pCol, sos );
    docRtfWriteNextLine( pCol, sos );

    rwc->rwcInTable= 0;

    docCleanRowProperties( &(rwc->rwcRowProperties) );
    docInitRowProperties( &(rwc->rwcRowProperties) );

    rwc->rwcTextAttribute= rwc->rwcOutsideTableTextAttribute;

    PROPmaskCLEAR( &ppChgMask );

    PROPmaskCLEAR( &ppUpdMask );
    PROPmaskFILL( &ppUpdMask, PPprop_COUNT );

    if  ( docUpdParaProperties( &ppChgMask,
                      &(rwc->rwcParagraphProperties), &ppUpdMask,
                      &(rwc->rwcOutsideTableParagraphProperties),
                      colorMap, listStyleMap ) )
      { LDEB(1); return -1;   }

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Save an inidividual header, footer, or footnote.              */
/*                                                    */
/************************************************************************/

int docRtfSaveExternalItem(         SimpleOutputStream *    sos,
                              int *             pCol,
                              const BufferItem *      bi,
                              const BufferDocument *  bd,
                              const char *            tag,
                              RtfWritingContext *     rwc )
    {
    int                 i;

    int                 savedInTable= rwc->rwcInTable;
    TextAttribute taOutside;

    if  ( ! bi )
      { return 0; }

    if  ( bi->biLevel != DOClevSECT )
      { SDEB(docLevelStr(bi->biLevel)); return -1;    }

    taOutside= rwc->rwcTextAttribute;

    docRtfWriteDestinationBegin( tag, pCol, sos );

    docCleanParagraphProperties( &(rwc->rwcParagraphProperties) );
    docInitParagraphProperties( &(rwc->rwcParagraphProperties) );
    utilInitTextAttribute( &(rwc->rwcTextAttribute) );

    rwc->rwcInTable= 0;

    docRtfWriteTag( "\\pard", pCol, sos );
    docRtfWriteTag( "\\plain", pCol, sos );
    docRtfWriteNextLine( pCol, sos );

    for ( i= 0; i < bi->biChildCount; i++ )
      {
      if  ( docRtfSaveItem( sos, pCol, bi->biChildren[i], bd,
                                    (DocumentSelection *)0, rwc ) )
          { LDEB(i); return -1;     }
      }

    docCleanParagraphProperties( &(rwc->rwcParagraphProperties) );
    docInitParagraphProperties( &(rwc->rwcParagraphProperties) );
    utilInitTextAttribute( &(rwc->rwcTextAttribute) );

    while( rwc->rwcInFldrslt > 0 )
      { docRtfFinishFldrslt( sos, pCol, rwc );  }

    if  ( rwc->rwcInTable && docRtfPopTable( rwc, pCol, sos ) )
      { LDEB(1);  }

    docRtfWriteDestinationEnd( pCol, sos );
    docRtfWriteNextLine( pCol, sos );

    rwc->rwcTextAttribute= taOutside;
    rwc->rwcInTable= savedInTable;

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Save a paragraph.                                       */
/*                                                    */
/*  1)  When we are saving a selection, and the selection is inside a   */
/*    table cell, do not set the \intbl flag.                     */
/*  2)  To make WP 8 happy, always save 'intbl' for the first paragraph */
/*    in a table row.                                       */
/*                                                    */
/************************************************************************/

static void docRtfSwitchTextAttributes(   SimpleOutputStream *    sos,
                              int *             pCol,
                              const BufferDocument *  bd,
                              const TextParticule *   tp,
                              RtfWritingContext *     rwc )
    {
    TextAttribute       ta;

    utilGetTextAttributeByNumber( &ta, &(bd->bdTextAttributeList),
                                    tp->tpTextAttributeNumber );

    if  ( ta.taFontNumber >= 0 )
      {
      PropertyMask      chgMask;
      PropertyMask      updMask;

      PROPmaskCLEAR( &chgMask );
      PROPmaskFILL( &chgMask, TAprop_COUNT );

      PROPmaskCLEAR( &updMask );

      utilUpdateTextAttribute( &updMask, &(rwc->rwcTextAttribute),
                                              &ta, &chgMask );
      if  ( ! PROPmaskISEMPTY( &updMask ) )
          {
          const DocumentProperties *      dp= &(bd->bdProperties);
          const DocumentFontList *  dfl= &(dp->dpFontList);
          const DocumentFont *      df;

          docRtfSaveTextAttribute( sos, pCol, &updMask, &ta );
          rwc->rwcHasPrecedingTags= 1;

          df= dfl->dflFonts+ ta.taFontNumber;

          switch( df->dfCharset )
            {
            case FONTcharsetANSI:
                rwc->rwcTextOutputMapping= rwc->rwcDefaultOutputMapping;
                break;
            case FONTcharsetGREEK:
                rwc->rwcTextOutputMapping= docISO7_to_WIN1253;
                break;
            case FONTcharsetTURKISH:
                rwc->rwcTextOutputMapping= docISO9_to_WIN1254;
                break;
            case FONTcharsetBALTIC:
                rwc->rwcTextOutputMapping= docISO13_to_WIN1257;
                break;
            case FONTcharsetRUSSIAN:
                rwc->rwcTextOutputMapping= docISO5_to_WIN1251;
                break;
            case FONTcharsetEE:
                rwc->rwcTextOutputMapping= docISO2_to_WIN1250;
                break;

            default:
                rwc->rwcTextOutputMapping= rwc->rwcDefaultOutputMapping;
            }
          }
      }

    return;
    }

static int docRtfSaveParaItem(      SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferDocument *        bd,
                        const BufferItem *            bi,
                        const DocumentSelection *     ds,
                        RtfWritingContext *           rwc )
    {
    TextParticule *                 tp;
    unsigned char *                 s;

    int                             stroffUpto;
    int                             part= 0;
    int                             stroff= 0;

    int                             saveIntbl;
    int                             restartFromDefault= 0;
    int                             propChange= 0;
    int                             tabsSaved= 0;

    const DocumentField *           df;
    const FieldKindInformation *    fki;

    PropertyMask              ppChgMask;
    PropertyMask              ppUpdMask;

    const int * const               colorMap= (const int *)0;
    const int * const               listStyleMap= (const int *)0;

    saveIntbl= ! ds || ! docSelectionInsideCell( ds );

    if  ( saveIntbl )
      {
      /*  2  */
      if  ( bi->biParaInTable                   &&
            bi->biNumberInParent == 0                 &&
            bi->biParent                        &&
            bi->biParent->biNumberInParent == 0 )
          { restartFromDefault= 1; }
      }

    docRtfParaSaveProperties( sos, restartFromDefault, saveIntbl,
                              &propChange, &tabsSaved, pCol,
                              &(bi->biParaProperties),
                              &(rwc->rwcParagraphProperties) );

    if  ( propChange )
      { rwc->rwcHasPrecedingTags= 1;      }

    if  ( restartFromDefault || propChange )
      {
      /*  1  */
      utilInitTextAttribute( &(rwc->rwcTextAttribute) );
      rwc->rwcTextAttribute.taFontSizeHalfPoints= 24;

      /*  2  */
      docRtfWriteTag( "\\plain", pCol, sos );
      rwc->rwcHasPrecedingTags= 1;
      }

    if  ( bi->biParaParticuleCount == 0 )
      { LDEB(bi->biParaParticuleCount);   }

    if  ( ds && ds->dsBegin.dpBi == bi )
      {
      const int   lastOne= 1;

      stroff= ds->dsBegin.dpStroff;

      if  ( docFindParticuleOfPosition( &part, &(ds->dsBegin), lastOne ) )
          { LDEB(stroff); return -1;      }
      }

    tp= bi->biParaParticules+ part;
    s= bi->biParaString+ stroff;

    if  ( ds && ds->dsEnd.dpBi == bi )
      { stroffUpto= ds->dsEnd.dpStroff;   }
    else{ stroffUpto= -1;                 }

    for ( ; part < bi->biParaParticuleCount; part++, tp++ )
      {
      if  ( tp->tpKind == DOCkindTEXT           ||
            tp->tpStrlen > 0              )
          { docRtfSwitchTextAttributes( sos, pCol, bd, tp, rwc ); }

      if  ( rwc->rwcSaveAsLink )
          {
          docRtfWriteStartField( sos, &(rwc->rwcSaveAsHyperlinkField),
                                                pCol, rwc );

          rwc->rwcSaveAsLink= 0;

          if  ( rwc->rwcSaveAsLinkAsRef )
            {
            docRtfWriteStartField( sos, &(rwc->rwcSaveAsRefField),
                                                pCol, rwc );
            }
          else{
            if  ( rwc->rwcSaveAsLinkAsPageref )
                {
                docRtfWriteStartField( sos,
                            &(rwc->rwcSaveAsPagerefField), pCol, rwc );
                }
            }
          }

      switch( tp->tpKind )
          {
          int           n;

          case DOCkindCHFTNSEP:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\chftnsep", pCol, sos ); s++; stroff++;
            rwc->rwcHasPrecedingTags= 1;
            continue;

          case DOCkindCHFTNSEPC:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\chftnsepc", pCol, sos ); s++; stroff++;
            rwc->rwcHasPrecedingTags= 1;
            continue;

          case DOCkindTAB:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\tab", pCol, sos ); s++; stroff++;
            rwc->rwcHasPrecedingTags= 1;
            continue;

          case DOCkindLINEBREAK:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\line", pCol, sos );
            docRtfWriteNextLine( pCol, sos );
            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 1 */
            rwc->rwcHasPrecedingTags= 0;
            continue;

          case DOCkindPAGEBREAK:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\page", pCol, sos );
            docRtfWriteNextLine( pCol, sos );
            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 1 */
            rwc->rwcHasPrecedingTags= 0;
            continue;

          case DOCkindCOLUMNBREAK:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            docRtfWriteTag( "\\column", pCol, sos );
            docRtfWriteNextLine( pCol, sos );
            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 1 */
            rwc->rwcHasPrecedingTags= 0;
            continue;

          case DOCkindTEXT:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            if  ( stroffUpto >= 0                     &&
                  tp->tpStroff+ tp->tpStrlen > stroffUpto   )
                { n= stroffUpto- stroff;              }
            else{ n= tp->tpStroff+ tp->tpStrlen- stroff;    }

            if  ( *pCol > 0                           &&
                  *pCol+ n > 72                       &&
                  n < 72                              )
                { docRtfWriteNextLine( pCol, sos ); }

            if  ( rwc->rwcHasPrecedingTags )
                {
                if  ( *pCol > 0 )
                  { sioOutPutString( " ", sos ); *pCol += 1;      }
                rwc->rwcHasPrecedingTags= 0;
                }

            docRtfEscapeString( s, rwc->rwcTextOutputMapping, pCol, n, sos );
            stroff += n; s += n;

            continue;
          case DOCkindOBJECT:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            if  ( docRtfSaveObject( sos, pCol, bi, tp ) )
                { LDEB(tp->tpKind); }
            s += tp->tpStrlen; stroff += tp->tpStrlen;
            rwc->rwcHasPrecedingTags= 0;
            continue;

          case DOCkindNOTE:
            {
            DocumentNote *    dn;

            if  ( docGetNote( &dn, bd, bi, tp->tpStroff ) >= 0    &&
                  dn->dnExternalItem.eiItem                       )
                {
                switch( dn->dnExternalItemKind )
                  {
                  case DOCinFOOTNOTE:
                      if  ( docRtfSaveExternalItem( sos, pCol,
                              dn->dnExternalItem.eiItem,
                              bd, "\\footnote", rwc ) )
                        { LDEB(tp->tpKind); return -1;      }
                      break;

                  case DOCinENDNOTE:
                      if  ( docRtfSaveExternalItem( sos, pCol,
                              dn->dnExternalItem.eiItem,
                              bd, "\\footnote\\ftnalt", rwc )     )
                        { LDEB(tp->tpKind); return -1;      }
                      break;

                  default:
                      LDEB(dn->dnExternalItemKind);
                      break;
                  }
                }
            else{ LDEB(tp->tpObjectNumber);     }

            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 0 */
            }
            continue;

          case DOCkindFIELDSTART:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            df= bd->bdFieldList.dflFields+ tp->tpObjectNumber;
            fki= DOC_FieldKinds+ df->dfKind;

            if  ( fki->fkiIsFieldInRtf          &&
                  fki->fkiLevel == DOClevTEXT   )
                {
                docRtfWriteStartField( sos, df, pCol, rwc );
                rwc->rwcHasPrecedingTags= 0;
                }

            if  ( df->dfKind == DOCfkBOOKMARK   &&
                  rwc->rwcSaveBookmarks         )
                {
                docRtfStartBookmark( sos, df, pCol, rwc );
                rwc->rwcHasPrecedingTags= 0;
                }

            if  ( df->dfKind == DOCfkCHFTN )
                {
                int           count;

                count= docCountParticulesInField( bi, part,
                                    bi->biParaParticuleCount );

                docRtfWriteTag( "\\chftn", pCol, sos );
                rwc->rwcHasPrecedingTags= 1;

                part += count+ 1;
                tp += count+ 1;
                stroff= tp->tpStroff;
                s= bi->biParaString+ stroff;

                continue;
                }

            if  ( df->dfKind == DOCfkLISTTEXT   &&
                  bi->biParaListOverride > 0    )
                {
                docRtfWriteDestinationBegin( "\\listtext", pCol, sos );
                rwc->rwcHasPrecedingTags= 1;
                }

            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 0 */
            continue;

          case DOCkindFIELDEND:
            df= bd->bdFieldList.dflFields+ tp->tpObjectNumber;
            fki= DOC_FieldKinds+ df->dfKind;

            if  ( df->dfKind == DOCfkBOOKMARK   &&
                  rwc->rwcSaveBookmarks         )
                {
                docRtfFinishBookmark( sos, df, pCol, rwc );
                rwc->rwcHasPrecedingTags= 0;
                }

            if  ( fki->fkiIsFieldInRtf          &&
                  fki->fkiLevel == DOClevTEXT   )
                {
                if  ( rwc->rwcInFldrslt )
                  { docRtfFinishFldrslt( sos, pCol, rwc );  }
                }

            if  ( df->dfKind == DOCfkCHFTN )
                { /* nothing */     }

            if  ( df->dfKind == DOCfkLISTTEXT   &&
                  bi->biParaListOverride > 0    )
                {
                docRtfWriteDestinationEnd( pCol, sos );
                rwc->rwcHasPrecedingTags= 0;
                }

            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 0 */
            rwc->rwcHasPrecedingTags= 0;
            continue;

          case DOCkindXE:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            if  (  rwc->rwcSaveBookmarks )
                {
                df= bd->bdFieldList.dflFields+ tp->tpObjectNumber;

                sioOutPutString( "{\\xe {", sos ); *pCol += 5;
                docRtfEscapeString( df->dfInstructions.mbBytes,
                            (const unsigned char *)0,
                            pCol, df->dfInstructions.mbSize, sos );
                sioOutPutString( "}}", sos ); *pCol += 2;

                rwc->rwcHasPrecedingTags= 0;
                }
            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 0 */
            continue;

          case DOCkindTC:
            if  ( stroffUpto >= 0 && stroff >= stroffUpto )
                { break;      }

            if  (  rwc->rwcSaveBookmarks )
                {
                df= bd->bdFieldList.dflFields+ tp->tpObjectNumber;

                sioOutPutString( "{\\tc {", sos ); *pCol += 5;
                docRtfEscapeString( df->dfInstructions.mbBytes,
                            (const unsigned char *)0,
                            pCol, df->dfInstructions.mbSize, sos );
                sioOutPutString( "}}", sos ); *pCol += 2;

                rwc->rwcHasPrecedingTags= 0;
                }
            s += tp->tpStrlen; stroff += tp->tpStrlen; /* += 0 */
            continue;

          default:
            LDEB(tp->tpKind);
            s += tp->tpStrlen; stroff += tp->tpStrlen;
            continue;
          }

      break;
      }

    if  ( stroff == bi->biParaStrlen )
      {
      if  ( rwc->rwcSaveAsLinkAsRef       &&
            rwc->rwcSaveAsLinkAsPageref   )
          {
          if  ( rwc->rwcInFldrslt > 0 )
            { docRtfFinishFldrslt( sos, pCol, rwc );  }

          docRtfWriteTag( "\\tab", pCol, sos );

          docRtfWriteStartField( sos, &(rwc->rwcSaveAsPagerefField),
                                                pCol, rwc );

          sioOutPutString( "?", sos ); *pCol += 1;

          rwc->rwcSaveAsLinkAsRef= 0;
          rwc->rwcSaveAsLinkAsPageref= 0;
          }

      while( rwc->rwcInFldrslt > 0 )
          { docRtfFinishFldrslt( sos, pCol, rwc ); }

      if  ( ( ! bi->biParaInTable                     &&
              bi->biInExternalItem == DOCinBODY       )     ||
            tabsSaved                                       ||
            bi->biNumberInParent < bi->biParent->biChildCount- 1  )
          {
          docRtfWriteTag( "\\par", pCol, sos );
          docRtfWriteNextLine( pCol, sos );
          rwc->rwcHasPrecedingTags= 0;
          }
      }

    PROPmaskCLEAR( &ppChgMask );

    PROPmaskCLEAR( &ppUpdMask );
    PROPmaskFILL( &ppUpdMask, PPprop_COUNT );

    if  ( docUpdParaProperties( &ppChgMask, &(rwc->rwcParagraphProperties),
                  &ppUpdMask, &(bi->biParaProperties),
                  colorMap, listStyleMap ) )
      { LDEB(1); return -1;   }

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Save a Row level item.                                  */
/*                                                    */
/************************************************************************/

static int docRtfSaveRowItem( SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferDocument *        bd,
                        const BufferItem *            rowBi,
                        const DocumentSelection *     ds,
                        RtfWritingContext *           rwc )
    {
    int                       col;

    if  ( ! ds                                              ||
        ds->dsBegin.dpBi->biParent != ds->dsEnd.dpBi->biParent    )
      {
      if  ( ! docEqualRows( &(rowBi->biRowProperties),
                                    &(rwc->rwcRowProperties) ) )
          {
          if  ( rwc->rwcInTable && docRtfPopTable( rwc, pCol, sos ) )
            { LDEB(1);  }
          }

      if  ( ! rwc->rwcInTable                         &&
            docRtfPushTable( rwc, pCol, sos, rowBi, ds )    )
          { LDEB(1);    }
      }

    for ( col= 0; col < rowBi->biChildCount; col++ )
      {
      int         par;
      BufferItem *      cellBi= rowBi->biChildren[col];

      if  ( ds && docCompareItemPositions( cellBi, ds->dsBegin.dpBi ) < 0 )
          { continue;   }

      if  ( ds && docCompareItemPositions( cellBi, ds->dsEnd.dpBi ) > 0 )
          { continue;   }

      if  ( ! ds                                ||
            ( ( ds->dsCol0 < 0 || col >= ds->dsCol0 ) &&
            ( ds->dsCol1 < 0 || col <= ds->dsCol1 )   )     )
          {
          for ( par= 0; par < cellBi->biChildCount; par++ )
            {
            BufferItem *      paraBi= cellBi->biChildren[par];

            if  ( ds && docCompareItemPositions( paraBi,
                                        ds->dsBegin.dpBi ) < 0 )
                { continue;   }

            if  ( ds && docCompareItemPositions( paraBi,
                                        ds->dsEnd.dpBi ) > 0 )
                { continue;   }

            if  ( docRtfSaveParaItem( sos, pCol, bd, paraBi, ds, rwc ) )
                { LLDEB(col,par); return -1;    }
            }

          docRtfWriteTag( "\\cell", pCol, sos );
          if  ( col != rowBi->biChildCount- 1 )
            { docRtfWriteNextLine( pCol, sos ); }
          }
      }

    docRtfWriteTag( "\\row", pCol, sos );
    docRtfWriteNextLine( pCol, sos );

    return 0;
    }

static int docSaveSectionProperties(      SimpleOutputStream *          sos,
                              int *                   pCol,
                              const DocumentProperties *    dp,
                              const DocumentSelection *     ds,
                              const SectionProperties *     sp,
                              RtfWritingContext *           rwc )
    {
    SectionProperties         spDef;
    PropertyMask        updMask;

    docInitSectionProperties( &spDef );

    PROPmaskCLEAR( &updMask );
    PROPmaskFILL( &updMask, DGprop_COUNT );
    PROPmaskUNSET( &updMask, DGpropHEADER_POSITION );
    PROPmaskUNSET( &updMask, DGpropFOOTER_POSITION );

    appSetDocumentGeometry( &(spDef.spDocumentGeometry),
                            &(dp->dpGeometry), &updMask, &updMask );

    PROPmaskCLEAR( &updMask );
    PROPmaskFILL( &updMask, SPprop_COUNT );

    docSectPropertyDifference( &updMask, &spDef, sp, &updMask );

    docCleanSectionProperties( &spDef );
    if  ( ds )
      { PROPmaskUNSET( &updMask, SPpropTITLEPG );     }

    docRtfWriteNextLine( pCol, sos );
    docRtfWriteTag( "\\sectd", pCol, sos );

    docRtfSaveSectionProperties( sos,
                  rwc->rwcDefaultOutputMapping, pCol, &updMask, sp );

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Save a buffer item, hierarchically descending to the leaves of the  */
/*  document tree.                                          */
/*                                                    */
/************************************************************************/

static int docRtfSaveGroupItem(     SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferItem *            bi,
                        const BufferDocument *        bd,
                        const DocumentSelection *     ds,
                        RtfWritingContext *           rwc )
    {
    int                       i;

    for ( i= 0; i < bi->biChildCount; i++ )
      {
      if  ( docRtfSaveItem( sos, pCol, bi->biChildren[i], bd, ds, rwc ) )
          { LDEB(i); return -1;     }
      }

    return 0;
    }

static int docRtfSaveItem(    SimpleOutputStream *          sos,
                        int *                   pCol,
                        const BufferItem *            bi,
                        const BufferDocument *        bd,
                        const DocumentSelection *     ds,
                        RtfWritingContext *           rwc )
    {
    const DocumentProperties *      dp= &(bd->bdProperties);

    if  ( ds )
      {
      if  ( docCompareItemPositions( bi, ds->dsBegin.dpBi ) < 0   )
          { return 0;   }

      if  ( docCompareItemPositions( bi, ds->dsEnd.dpBi ) > 0           )
          { return 0;   }
      }

    switch( bi->biLevel )
      {
      case DOClevDOC:
      case DOClevCELL:
          if  ( docRtfSaveGroupItem( sos, pCol, bi, bd, ds, rwc ) )
            { LDEB(1); return -1;   }
          break;

      case DOClevSECT:

          if  ( docSaveSectionProperties( sos, pCol, dp, ds,
                                  &(bi->biSectProperties), rwc ) )
            { LDEB(1); return -1;   }

          if  ( ! ds                                        &&
              docRtfSaveSectHeadersFooters( sos, pCol, bi, bd, rwc ) )
            { LDEB(1); return -1;   }

          if  ( docRtfSaveGroupItem( sos, pCol, bi, bd, ds, rwc ) )
            { LDEB(1); return -1;   }

          if  ( rwc->rwcInTable && docRtfPopTable( rwc, pCol, sos ) )
            { LDEB(rwc->rwcInTable);      }

          while( rwc->rwcInFldrslt > 0 )
            { docRtfFinishFldrslt( sos, pCol, rwc );  }

          if  ( bi->biParent                                &&
              bi->biNumberInParent < bi->biParent->biChildCount- 1      )
            { docRtfWriteTag( "\\sect", pCol, sos );  }

          docRtfWriteNextLine( pCol, sos );
          break;

      case DOClevROW:
          if  ( ! bi->biRowHasTableParagraphs )
            {
            if  ( rwc->rwcInTable && docRtfPopTable( rwc, pCol, sos ) )
                { LDEB(1);    }

            if  ( docRtfSaveGroupItem( sos, pCol, bi, bd, ds, rwc ) )
                { LDEB(1); return -1;     }
            }
          else{
            if  ( docRtfSaveRowItem( sos, pCol, bd, bi, ds, rwc ) )
                { LDEB(1); return -1;     }
            }
          break;

      case DOClevPARA:
          if  ( docRtfSaveParaItem( sos, pCol, bd, bi, ds, rwc ) )
            { LDEB(1); return -1;   }
          break;

      default:
          LDEB(bi->biLevel); return -1;
      }

    return 0;
    }

static void docRtfInitWritingContext(     RtfWritingContext *     rwc )
    {
    int           i;

    utilInitTextAttribute( &(rwc->rwcTextAttribute) );
    docInitParagraphProperties( &(rwc->rwcParagraphProperties) );
    docInitRowProperties( &(rwc->rwcRowProperties) );

    utilInitTextAttribute( &(rwc->rwcOutsideTableTextAttribute) );
    docInitParagraphProperties( &(rwc->rwcOutsideTableParagraphProperties) );

    rwc->rwcOutsideFldrsltAttribute= (PushedAttribute *)0;

    rwc->rwcInFldrslt= 0;
    rwc->rwcInTable= 0;

    rwc->rwcSaveBookmarks= 1;

    rwc->rwcSaveAsLink= 0;
    rwc->rwcSaveAsLinkAsRef= 0;
    rwc->rwcSaveAsLinkAsPageref= 0;
    docInitField( &(rwc->rwcSaveAsHyperlinkField) );
    docInitField( &(rwc->rwcSaveAsRefField) );
    docInitField( &(rwc->rwcSaveAsPagerefField) );

    for ( i= 0; i < 256; i++ )
      { rwc->rwcDefaultOutputMapping[i]= i;     }

    rwc->rwcTextOutputMapping= rwc->rwcDefaultOutputMapping;
    }

static void docRtfCleanWritingContext(    RtfWritingContext *     rwc )
    {
    docCleanParagraphProperties( &rwc->rwcParagraphProperties );
    docCleanRowProperties( &rwc->rwcRowProperties );

    docCleanParagraphProperties( &rwc->rwcOutsideTableParagraphProperties );

    docCleanField( &(rwc->rwcSaveAsHyperlinkField) );
    docCleanField( &(rwc->rwcSaveAsRefField) );
    docCleanField( &(rwc->rwcSaveAsPagerefField) );
    }

int docRtfSaveDocument( SimpleOutputStream *          sos,
                  BufferDocument *        bd,
                  const DocumentSelection *     ds,
                  int                     saveBookmarks )
    {
    const BufferItem *        bi= &(bd->bdItem);
    int                       col= 0;

    RtfWritingContext         rwc;

    if  ( ds )
      {
      ExternalItem *    ei;
      BufferItem *      bodySectBi;

      bi= docGetSelectionRoot( &ei, &bodySectBi, bd, ds );
      if  ( ! bi )
          { XDEB(bi); return -1;    }
      }

    docRtfInitWritingContext( &rwc );
    rwc.rwcSaveBookmarks= saveBookmarks;

    docRtfWriteDestinationBegin( "\\rtf1\\ansi", &col, sos );
    docRtfWriteNextLine( &col, sos );

    if  ( docRtfSaveDocumentProperties( sos, &col, &rwc, bd ) )
      { LDEB(1); return -1;   }

    if  ( docRtfSaveDocNotesSeparators( sos, &col, bd, &rwc ) )
      { LDEB(1); docRtfCleanWritingContext( &rwc ); return -1;    }

    if  ( docRtfSaveItem( sos, &col, bi, bd, ds, &rwc ) )
      { LDEB(bi->biLevel); return -1; }

    while( rwc.rwcInFldrslt > 0 )
      { docRtfFinishFldrslt( sos, &col, &rwc ); }

    if  ( rwc.rwcInTable && docRtfPopTable( &rwc, &col, sos ) )
      { LDEB(rwc.rwcInTable); }

    docRtfWriteDestinationEnd( &col, sos );
    docRtfWriteNextLine( &col, sos );

    docRtfCleanWritingContext( &rwc );

    return 0;
    }

int docRtfSaveSelectionAsLink(      SimpleOutputStream *          sos,
                        const BufferDocument *        bd,
                        const DocumentSelection *     ds,
                        int                     asRef,
                        int                     asPageref,
                        const unsigned char *         fileName,
                        int                     fileSize,
                        const unsigned char *         markName,
                        int                     markSize )
    {
    const BufferItem *        bi= &(bd->bdItem);
    int                       col= 0;

    RtfWritingContext         rwc;

    docRtfInitWritingContext( &rwc );

    rwc.rwcSaveBookmarks= 0;
    rwc.rwcSaveAsLink= 1;
    rwc.rwcSaveAsLinkAsRef= asRef;
    rwc.rwcSaveAsLinkAsPageref= asPageref;

    if  ( docFieldSetHyperlink( &(rwc.rwcSaveAsHyperlinkField),
                                        fileName, fileSize,
                                        markName, markSize ) )
      { LDEB(1); docRtfCleanWritingContext( &rwc ); return -1;    }

    if  ( asRef && docFieldSetRef( &(rwc.rwcSaveAsRefField),
                                        markName, markSize ) )
      { LDEB(asRef); docRtfCleanWritingContext( &rwc ); return -1;      }

    if  ( asPageref && docFieldSetPageref( &(rwc.rwcSaveAsPagerefField),
                                        markName, markSize ) )
      { LDEB(asPageref); docRtfCleanWritingContext( &rwc ); return -1; }

    docRtfWriteDestinationBegin( "\\rtf0\\ansi", &col, sos );
    docRtfWriteNextLine( &col, sos );

    if  ( docRtfSaveDocumentProperties( sos, &col, &rwc, bd ) )
      { LDEB(1); docRtfCleanWritingContext( &rwc ); return -1;    }

    docRtfWriteNextLine( &col, sos );

    if  ( docRtfSaveItem( sos, &col, bi, bd, ds, &rwc ) )
      { LDEB(bi->biLevel); docRtfCleanWritingContext( &rwc ); return -1; }

    while( rwc.rwcInFldrslt > 0 )
      { docRtfFinishFldrslt( sos, &col, &rwc ); }

    if  ( rwc.rwcInTable && docRtfPopTable( &rwc, &col, sos ) )
      { LDEB(rwc.rwcInTable); }

    docRtfWriteDestinationEnd( &col, sos );
    docRtfWriteNextLine( &col, sos );

    docRtfCleanWritingContext( &rwc );

    return 0;
    }

Generated by  Doxygen 1.6.0   Back to index