ホーム > カテゴリ > フォーマット変換 >

TXTファイルをPDFファイルへ変換する(C++)

TXTファイルをPDFファイルへ変換する事のできるC++のソースコードです。クラスになっていますのでそのまま使用できます

ソースコード

10年以上前に作成した古いコードで私すら覚えていないのですが、何かのお役に立てると嬉しいです。

[main.cpp]

#include <stdio.h>
#include "txt2pdf.h"

int main(int argc,char *argv[])
{
  try
  {
     if (argc >= 2)
     {
       CTxt2pdf hoge;
       hoge.txt2pdf(argv[1],"C:\\test.pdf");     
     }
  }
  catch (char* S )
  {
    printf("ERROR : %s\n",S);
  }
  catch (...)
  {
    printf("ERROR : %s\n",PDF_ERROR_UNKNOWN);
  }

  return(0);
}

[txt2pdf.h]

/* -------------- Support Japanese charcode "ShiftJIS" Only! ---------------- */

#ifndef __TXT2PDF_H__
#define __TXT2PDF_H__

#include <stdio.h>
#include <malloc.h>
#include <string.h>

typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef unsigned long       DWORD;

#define FALSE               0
#define TRUE                1

#define PDF_ERROR_NOMEMORY     "メモリを確保できませんでした。" 
#define PDF_ERROR_ZERO         "初期サイズは0にはできません。" 
#define PDF_ERROR_INDEXOVER    "インデックスの指定が不正です。" 
#define PDF_ERROR_FILEREAD     "ファイルの読み込みに失敗しました。"
#define PDF_ERROR_FILECREATE   "ファイルの作成に失敗しました。" 
#define PDF_ERROR_FILEPOINTER  "ファイルポインタが無効です。" 
#define PDF_ERROR_UNKNOWN      "予期せぬ例外が発生しました。" 

////////////////////////////////////////////////////////////////////////////////
//   CPList (ポインタリスト)
////////////////////////////////////////////////////////////////////////////////
class CPList
{
  private:
     DWORD *FBuffer;
     int    FCount;
  protected:
  public:
     CPList(); 
     ~CPList();   
     void* operator[]( int Index );
     void* Get(int Index) const;
     int   Count()        const;     
     void  Add(void *P);    
     void  Clear();                 
};

////////////////////////////////////////////////////////////////////////////////
//   CPStringList (文字列リスト)
////////////////////////////////////////////////////////////////////////////////
class CPStringList
{
  private:
     CPList *FBuffer;
  protected:
  public: 
      CPStringList(); 
      CPStringList(const CPStringList& Value); 
     ~CPStringList();   
     const char*  operator[]( int Index );
     CPStringList& operator=(const CPStringList& Value);
     CPStringList& Assign(const CPStringList &Source); 
     void  Add(const char* S);
     const char* Get(int Index) const;
     int   Count()              const;     
     void  Clear();
     void  LoadFromFile(FILE *AStream);
     void  LoadFromFile(const char* Filename);
     void  SaveToFile(FILE *AStream,const char* LineFeed="\r\n")        const;
     void  SaveToFile(const char* Filename,const char* LineFeed="\r\n") const;
};

////////////////////////////////////////////////////////////////////////////////
//   CPDFObjMemManager (相互参照テーブル) [ 内部用 ]
////////////////////////////////////////////////////////////////////////////////
class CPDFObjMemManager
{
  private:
     DWORD *FBuffer;
     DWORD FObjectCount;
     DWORD FReallocCount;
  protected:
  public:
     DWORD ObjectIndex;
     DWORD *ObjectPosArray;
     CPDFObjMemManager(DWORD ObjectCount=1000, DWORD ReallocCount=1000); 
     ~CPDFObjMemManager();   
     void MemoryCheck();              
};

////////////////////////////////////////////////////////////////////////////////
//   CTxt2pdf (テキストPDF変換)
////////////////////////////////////////////////////////////////////////////////
class CTxt2pdf
{
  private:      
     WORD m_PageWidth;    
     WORD m_PageHeight;      
     BYTE m_MarginX ;        
     BYTE m_MarginY ;       
     BYTE m_FontSize;       
     char *m_FontEncoding;   
     char *m_FontWidth;      
     char *m_FontName;       
     void AsciiHexEncoding(FILE *AStream,const char *S);
     void Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],DWORD Count);
     void DrawText(FILE *AStream,int x,int y,CPStringList &Lines);
     int  GetTextWidth(const char* S);
     void AutoLineFeed(CPStringList &Lines);
     void Write_PageObject(FILE *AStream,CPDFObjMemManager &ObjectMem, CPStringList &Lines,CPStringList &PageList);
  protected:
  public:
     void txt2pdf(FILE *Input,FILE *Output,WORD PageWidth = 595,  // 用紙の横サイズ
                                           WORD PageHeight= 842,  // 用紙の縦サイズ
                                           BYTE MarginX   =  30,  // 余白 (← →)
                                           BYTE MarginY   =  30,  // 余白 (↑ ↓)
                                           BYTE FontSize  =  12); // フォントのサイズ (1-100ぐらいまで)
     void txt2pdf(const char *OpenName,const char *SaveName,WORD PageWidth = 595,   // 用紙の横サイズ
                                                            WORD PageHeight= 842,   // 用紙の縦サイズ
                                                            BYTE MarginX   =  30,   // 余白 (← →)
                                                            BYTE MarginY   =  30,   // 余白 (↑ ↓)
                                                            BYTE FontSize  =  12);  // フォントのサイズ (1-100ぐらいまで)
};

// ---------------------------
// 用紙サイズとポイントの関係
// ---------------------------
//  A3 842x1191  297x420mm
//  A4 595x842   210x297mm
//  A5 420x595   148x210mm
//  B4 729x1032  257x364mm
//  B5 516x729   182x257mm
// ---------------------------

#endif // __TXT2PDF_H__

[txt2pdf.cpp]

/* -------------- Support Japanese charcode "ShiftJIS" Only! ---------------- */

#include "txt2pdf.h"

////////////////////////////////////////////////////////////////////////////////
//   CPList (ポインタリスト)
////////////////////////////////////////////////////////////////////////////////

// コンストラクタ
CPList::CPList()
{
  FCount=0;
  FBuffer=NULL;
}

// デストラクタ
CPList::~CPList()
{
  this->Clear();
}

// オペレータ(添え字)
void* CPList::operator[](int Index)
{
  return (this->Get(Index));
}

// リストにポインタを追加
void CPList::Add(void *P) 
{
  FBuffer = (DWORD *)realloc(FBuffer, sizeof(DWORD) * (FCount+1));
  if (FBuffer!=NULL)
    FBuffer[FCount++]=(DWORD)P;
  else
    throw (PDF_ERROR_NOMEMORY);
}

// ポインタを返す
void* CPList::Get(int Index) const
{
 if (FCount==0)
   return (NULL) ;
    
 if ((Index >= 0) && (Index <=FCount-1))
     return ((void *)FBuffer[Index]);
 else
 {
     throw (PDF_ERROR_INDEXOVER);
     return (NULL);
 }
}

// カウントを返す
int CPList::Count() const
{
  return (FCount);
}

// クリア
void CPList::Clear()
{
   if (FBuffer!=NULL) 
     free(FBuffer);
   FBuffer=NULL; FCount =0;
}


////////////////////////////////////////////////////////////////////////////////
//   CPStringList (文字列リスト)
////////////////////////////////////////////////////////////////////////////////

// コンストラクタ
CPStringList::CPStringList()
{
  FBuffer =new CPList;
  if (FBuffer==0)
      throw  (PDF_ERROR_NOMEMORY);
}

// コンストラクタ(コピー)
CPStringList::CPStringList(const CPStringList& Value)
{
  FBuffer =new CPList;
  if (FBuffer==0)
      throw  (PDF_ERROR_NOMEMORY);
  this->Assign(Value);
} 

// デストラクタ
CPStringList::~CPStringList()
{
  this->Clear();
  delete FBuffer;
}

// オペレータ(添え字)
const char* CPStringList::operator[](int Index)
{
  return (this->Get(Index));
}

// オペレータ(代入)
CPStringList& CPStringList::operator=(const CPStringList& Value) 
{
  if( this != &Value )
    return (Assign(Value));
  else
    return (*this);
}

// アサイン 
CPStringList& CPStringList::Assign(const CPStringList& Source) 
{
 int i;

 this->Clear();
 for (i=0;i < Source.Count();i++)
    this->Add(Source.Get(i));    
 return (*this);
}

// リストに文字列を追加
void CPStringList::Add(const char *S)
{
  char *str;

  if ((S!=NULL) && (strlen(S)>0))
  {
     str=(char *)calloc(strlen(S)+1,1);
     if (str!=NULL)
       FBuffer->Add(strcpy(str,S));
     else
        throw  (PDF_ERROR_NOMEMORY);
  }
  else
    FBuffer->Add(NULL);
}

// 文字列を返す
const char* CPStringList::Get(int Index) const
{
  return ((char *)FBuffer->Get(Index));
}

// 配列数を返す
int CPStringList::Count() const
{
  return (FBuffer->Count());
}

// すべてクリア
void CPStringList::Clear()
{
  int i;
  for (i=0;i<FBuffer->Count();i++)
   if (FBuffer->Get(i)!=NULL)
     free(FBuffer->Get(i));

  FBuffer->Clear();
}

// ファイルを読み込む
void CPStringList::LoadFromFile(FILE *AStream)
{
  BYTE *Memory;
  char *Str;
  int  FileSize,LineSize;
  int  i=0,S_Pos=0,E_Pos=FALSE;

  if (AStream==NULL)
   throw (PDF_ERROR_FILEPOINTER);

  // ファイルサイズの取得
  fseek(AStream, 0, SEEK_END );    
  FileSize = ftell(AStream);    
  fseek(AStream, 0, SEEK_SET );

  // ダイレクトにメモリ確保 -);
  Memory=(BYTE *)malloc(FileSize);
  try
  {
      if (Memory==NULL)
        throw (PDF_ERROR_NOMEMORY);
      fread(Memory,1,FileSize,AStream);
      FBuffer->Clear();  
      while (1)
      {
         switch (Memory[i]) 
         {
            case 0x0d:
                   if ((i+1) < FileSize)
                   {
                      // CR+LF --------------------------------------------------- 
                      if (Memory[i+1]==0x0A)
                      {
                         i++;
                         E_Pos    = i-strlen("\r\n");
                           LineSize = E_Pos-S_Pos+1;
                         if (LineSize > 0)
                         {
                               Str=(char *)calloc(LineSize+1,1);
                     
                              if (Str!=NULL)
                              {
                                  memcpy(Str,&Memory[S_Pos],LineSize);
                                  strcat(Str,"");
                                  FBuffer->Add(Str); E_Pos=TRUE;
                              }
                              else                            
                                  throw (PDF_ERROR_NOMEMORY);
                          }
                          else
                          {                               
                              FBuffer->Add(NULL);
                              E_Pos=TRUE;
                          }                                    
                      }
                       // CR -------------------------------------------------------
                      else
                      {
                           E_Pos    = i-strlen("\r");
                           LineSize = E_Pos-S_Pos+1;
                           if (LineSize>0)
                           {
                                Str=(char *)calloc(LineSize+1,1);
                              if (Str!=NULL)
                              {
                                   memcpy(Str,&Memory[S_Pos],LineSize);
                                 strcat(Str,"");
                                 FBuffer->Add(Str); E_Pos=TRUE;
                              }
                              else
                                 throw (PDF_ERROR_NOMEMORY);
                           }    
                           else
                           {                               
                                FBuffer->Add(NULL);
                                E_Pos=TRUE;
                           }
                      }
                   }
                   // CR ----------------------------------------------------------
                   else
                   {
                      E_Pos    = i-strlen("\r");
                      LineSize = E_Pos-S_Pos+1;
                      if (LineSize>0)
                      {
                          Str=(char *)calloc(LineSize+1,1);
                          if (Str!=NULL)
                         {
                            memcpy(Str,&Memory[S_Pos],LineSize);
                            strcat(Str,"");
                            FBuffer->Add(Str); E_Pos=TRUE;
                         }
                         else
                            throw (PDF_ERROR_NOMEMORY);
                      }     
                      else
                      {
                         FBuffer->Add(NULL);
                         E_Pos=TRUE;                          
                      }
                     }
                     S_Pos=i+1;
                     break;
            case 0x0A:
                     // LF --------------------------------------------------------
                     E_Pos    = i-strlen("\n");
                     LineSize = E_Pos-S_Pos+1;
                     if (LineSize>0)
                     {
                          Str=(char *)calloc(LineSize+1,1);
                          if (Str!=NULL)
                         {
                             memcpy(Str,&Memory[S_Pos],LineSize);
                             strcat(Str,"");
                             FBuffer->Add(Str); E_Pos=TRUE;
                         }
                         else
                             throw (PDF_ERROR_NOMEMORY);  
                      }
                      else
                      {
                          FBuffer->Add(NULL);
                          E_Pos=TRUE;                          
                      }
                      S_Pos=i+1;
                      break;
             default : E_Pos=FALSE;          
                 
        } // end switch

        if (i>=FileSize-1) 
          break;
        i++;

      } // end while 

      // 残りを格納
      if (E_Pos==FALSE)
      {
          E_Pos =FileSize;
            LineSize =E_Pos-S_Pos; 
          if (LineSize>0)
          {
              Str=(char *)calloc(LineSize+1,1);
              if (Str!=NULL)
              {
                   memcpy(Str,&Memory[S_Pos],LineSize);
                 strcat(Str,"");
                 FBuffer->Add(Str); E_Pos=TRUE;
              }
              else
                 throw (PDF_ERROR_NOMEMORY);  
          }            
      }       
      free(Memory);   
    }
    catch (char * emsg)
    {
      if (Memory!=NULL) free(Memory);
      throw (emsg);
    }
    catch (...)
    {
      if (Memory!=NULL) free(Memory);
      throw (-1);    
    }
}

// ファイルを読み込む
void CPStringList::LoadFromFile(const char* Filename)
{
  FILE *AStream;

  AStream=fopen(Filename,"rb");
  if(AStream!=NULL)
  {
    this->LoadFromFile(AStream);
    fclose(AStream);
  }
  else
    throw (PDF_ERROR_FILEREAD);
}

// ファイルに保存
void CPStringList::SaveToFile(FILE *AStream,const char* LineFeed) const
{
  if (AStream==NULL)
   throw (PDF_ERROR_FILEPOINTER);
  
  int i;
  for (i=0; i < this->Count();i++)
  {    
      if (this->Get(i)!=NULL)
         fwrite(this->Get(i),1,strlen(this->Get(i)),AStream);
      fwrite(LineFeed,1,strlen(LineFeed),AStream);
  }
}

// ファイルに保存
void CPStringList::SaveToFile(const char* Filename,const char* LineFeed) const
{
  FILE *AStream;

  AStream=fopen(Filename,"wb");
  if(AStream!=NULL)
  {
    this->SaveToFile(AStream,LineFeed);
    fclose(AStream);
  }
  else
    throw (PDF_ERROR_FILECREATE);
}

////////////////////////////////////////////////////////////////////////////////
//   CPDFObjMemManager (相互参照テーブル) [ 内部用 ]
////////////////////////////////////////////////////////////////////////////////

// コンストラクタ
CPDFObjMemManager::CPDFObjMemManager(DWORD ObjectCount, DWORD ReallocCount)
{
  if ((ObjectCount==0) || (ReallocCount== 0)) 
    throw (PDF_ERROR_ZERO);

  ObjectIndex=0;
  FObjectCount  = ObjectCount;
  FReallocCount = ReallocCount;
  FBuffer=(DWORD *)malloc(FObjectCount * sizeof(DWORD));
  if (FBuffer==NULL)
    throw (PDF_ERROR_NOMEMORY);
  ObjectPosArray=FBuffer;
}

// デストラクタ
CPDFObjMemManager::~CPDFObjMemManager()
{
  free(FBuffer);
}

// メモリチェック
void CPDFObjMemManager::MemoryCheck()
{
  if (ObjectIndex >= FObjectCount)
  {
     FObjectCount=FObjectCount+FReallocCount;
     FBuffer = (DWORD *)realloc(FBuffer, sizeof(DWORD) * FObjectCount);
     if (FBuffer==NULL)
       throw (PDF_ERROR_NOMEMORY);
     ObjectPosArray=FBuffer;
  }
}

////////////////////////////////////////////////////////////////////////////////
//   CTxt2pdf (テキストPDF変換)
////////////////////////////////////////////////////////////////////////////////

// クロスリファレンステーブルの書き込み
void CTxt2pdf::Write_CrossReferenceTable(FILE *AStream,DWORD ObjectPosArray[],DWORD Count)
{
   DWORD i;

   fprintf(AStream,"xref\n");
   fprintf(AStream,"0 %d\n",Count+1);
   fprintf(AStream,"0000000000 65535 f \n");

   for (i= 0; i<=Count-1;i++)
      fprintf(AStream,"%0.10d 00000 n \n",ObjectPosArray[i]);
}

// 文字列を16表記で書き込む
void CTxt2pdf::AsciiHexEncoding(FILE *AStream,const char *S)
{
  int i;

  fprintf(AStream,"<");
   if (S!=NULL)
     for (i=0;S[i]!='\0';i++)
          fprintf(AStream,"%0.2x",(BYTE)S[i]);
  fprintf(AStream,">");
}

// PDFのページにテキストを描画
void CTxt2pdf::DrawText(FILE *AStream,int x,int y,CPStringList &Lines)
{
  int i;
  double Matrix;
    
  if (Lines.Count()==0)
    return;
  
  y  = m_PageHeight - y;
  Matrix =y - m_FontSize*0.87;

  fprintf(AStream,"BT\n");
  fprintf(AStream,"/%s %d Tf\n",m_FontName,m_FontSize);
  fprintf(AStream,"0 0 0 rg %d TL %d %f Td ",m_FontSize,x,Matrix);
  AsciiHexEncoding(AStream,Lines[0]);
  fprintf(AStream," Tj\n");

  if (Lines.Count()!=1)
  {
    for (i= 1 ;i < Lines.Count();i++)
    { 
      fprintf(AStream,"T* ");
      AsciiHexEncoding(AStream,Lines[i]);
      fprintf(AStream," Tj\n");
    }  
    fprintf(AStream,"ET\n");
  }
}

// テキストの幅を取得
int CTxt2pdf::GetTextWidth(const char* S)
{
  if (S!=NULL)
    return ( strlen(S) * (m_FontSize / 2));
  else
    return (0);
}

// 文字列の自動改行
void CTxt2pdf::AutoLineFeed(CPStringList &Lines)

{
  const char *P;
  char *S;
  int i,MaxWidth; 
  CPStringList StringList;

  MaxWidth =m_PageWidth-m_MarginX*2;
  S=(char *)malloc(MaxWidth*2);
  try
  {
      if (S==NULL)
          throw (PDF_ERROR_NOMEMORY);

      for (i= 0;i< Lines.Count();i++)
      {
         // テキストがページの描画範囲を越える場合は改行する
         if (GetTextWidth(Lines[i]) > MaxWidth )
         {
            memset(S,0,MaxWidth*2);
            P = Lines[i];
            while (*P!='\0')
            {
               // Sjis漢字コード
               if (  (((BYTE)*P>=0x81) && ((BYTE)*P<=0x9F)) || 
                     (((BYTE)*P>=0xE0) && ((BYTE)*P<=0xFC))  )
               {
                  strncat(S,P,2);P++;
  
                  if (GetTextWidth(S) > MaxWidth-(m_FontSize))
                  {
                     StringList.Add(S);
                     memset(S,0,MaxWidth*2);
                  }
                  if (*P=='\0') break;
               }
               // Ascii + 半角カタカナなど
               else
               {
                  strncat(S,P,1);
                  if (GetTextWidth(S) > MaxWidth-(m_FontSize / 2))
                  {
                     StringList.Add(S);
                     memset(S,0,MaxWidth*2);
                  }
               } 
               P++;
            }
            if (strlen(S) >0 )
              StringList.Add(S);
         }
         else
           StringList.Add(Lines[i]);
      }
      free(S);
      Lines = StringList;    
  }
  catch (char * emsg)
  {
    if (S!=NULL) free(S);
    throw (emsg);
  }
  catch (...)
  {
    if (S!=NULL) free(S);
    throw (-1);
  }
}

// ページオブジェクトの書き込み
void CTxt2pdf::Write_PageObject(FILE *AStream,CPDFObjMemManager &ObjectMem, CPStringList &Lines,CPStringList &PageList)
{
  CPStringList PageText;
  int i,j,k,Pages,Streamsize,MaxHeight,PageRows;
 
  // テキストの自動整形
  AutoLineFeed(Lines);

  // 1ページで描画可能なサイズ
  MaxHeight =m_PageHeight-m_MarginY*2;

  // 1ページに入る配列数
  PageRows =Lines.Count();
  for (i=1 ;i < Lines.Count()+1;i++)
  {
     if( MaxHeight <= i * m_FontSize)
     {
        PageRows=i-1;
        break;
     }  
  }

  // ページ数の計算
  if (Lines.Count()!=0)
  {
    Pages = (Lines.Count() / PageRows);
    if ((Lines.Count()-PageRows)!=0)
     Pages++;
  }
  else
    Pages=1;
  
  k=0;
  for (i=0;i<Pages;i++)
  {
      // 1ページ分の配列を受け取る 
      PageText.Clear();
      for (j=0;j<PageRows;j++)
      {
         if (k >=Lines.Count()) break;
         PageText.Add(Lines[k]);
         k++;
      }

      // IntToStr
      char *Str =(char *)malloc(20);
      sprintf(Str,"%d",ObjectMem.ObjectIndex+1);
         PageList.Add(Str);
      free(Str);

      // Kids Page
      ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex] =ftell(AStream);
        fprintf(AStream,"%d 0 obj\n",ObjectMem.ObjectIndex+1);
        fprintf(AStream,"<<\n");
        fprintf(AStream,"/Type /Page\n");
        fprintf(AStream,"/Parent 2 0 R\n");
        fprintf(AStream,"/Resources\n");
        fprintf(AStream,"<<\n");
        fprintf(AStream,"/Font << /%s 3 0 R >>\n",m_FontName);
        fprintf(AStream,"/ProcSet [ /PDF /Text ]\n");
        fprintf(AStream,">>\n");
        fprintf(AStream,"/MediaBox [ 0 0 %d %d ]\n",m_PageWidth,m_PageHeight);
        fprintf(AStream,"/Contents %d 0 R\n",ObjectMem.ObjectIndex+2);
        fprintf(AStream,">>\n");
        fprintf(AStream,"endobj\n");
      ObjectMem.ObjectIndex++;
      ObjectMem.MemoryCheck();
      
      // Contents Object
      ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex] =ftell(AStream);
        fprintf(AStream,"%d 0 obj\n",ObjectMem.ObjectIndex+1);
        fprintf(AStream,"<< /Length %d 0 R >>\n",ObjectMem.ObjectIndex+2);
        fprintf(AStream,"stream\n");

          // stream
          Streamsize = ftell(AStream);
          DrawText(AStream,m_MarginX,m_MarginY,PageText);
          Streamsize = ftell(AStream)-Streamsize;

        fprintf(AStream,"endstream\n");
        fprintf(AStream,"endobj\n");
      ObjectMem.ObjectIndex++;
      ObjectMem.MemoryCheck();

      // Length Object
      ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex] =ftell(AStream);
        fprintf(AStream,"%d 0 obj\n",ObjectMem.ObjectIndex+1);
        fprintf(AStream,"%d\n",Streamsize);
        fprintf(AStream,"endobj\n");
      ObjectMem.ObjectIndex++;
      ObjectMem.MemoryCheck();
  }
}

void CTxt2pdf::txt2pdf(const char *OpenName,const char *SaveName,WORD PageWidth,WORD PageHeight,BYTE MarginX,BYTE MarginY,BYTE FontSize)
{
  FILE  *fp,*op;
  fp=fopen(OpenName,"rb");
  if (fp!=NULL)
  {
     op=fopen(SaveName,"wb");
     if (op!=NULL)
     {
        txt2pdf(fp,op,PageWidth,PageHeight,MarginX,MarginY,FontSize);
        fclose(fp); fclose(op);
     }
     else
     {
        fclose(fp); 
        throw (PDF_ERROR_FILECREATE);
     }
  }
  else
    throw (PDF_ERROR_FILEREAD);  
}

void CTxt2pdf::txt2pdf(FILE *Input,FILE *Output,WORD PageWidth,WORD PageHeight,BYTE MarginX,BYTE MarginY,BYTE FontSize)
{
  if ((Input==NULL) || (Output==NULL)) 
   throw (PDF_ERROR_FILEPOINTER);

  m_FontName =new char[10];
  if (m_FontName==0)
    throw  (PDF_ERROR_NOMEMORY);

  m_FontEncoding =new char[50];
  if (m_FontEncoding==0)
  {
     delete [] m_FontName;
     throw  (PDF_ERROR_NOMEMORY);
  }

  m_FontWidth    =new char[50];
  if (m_FontWidth==0)
  {    
     delete [] m_FontName;
     delete [] m_FontEncoding;
     throw  (PDF_ERROR_NOMEMORY);
  }

  try
  {
      int i;
      CPDFObjMemManager ObjectMem;
      CPStringList PageList,StringList;

      memset(m_FontName,0,10);
      memset(m_FontEncoding,0,50);
      memset(m_FontEncoding,0,50);

      // フォントの変数名
      strcpy(m_FontName,"F0");
      // フォントのエンコーディング
      strcpy(m_FontEncoding,"90ms-RKSJ-H");
      // 1byteフォントの幅
      strcpy(m_FontWidth,"231 389 500 631 631 500");

      m_PageWidth  = PageWidth;  // 用紙の横サイズ
      m_PageHeight = PageHeight; // 用紙の縦サイズ
      m_MarginX    = MarginX;    // 余白 (← →)
      m_MarginY    = MarginY;    // 余白 (↑ ↓)
      m_FontSize   = FontSize;   // フォントのサイズ (1-100ぐらいまで)

      // ファイルの読み込み
      StringList.LoadFromFile(Input);
      // 最初のヘッダ部分は後で書き込む
      ObjectMem.ObjectIndex =ObjectMem.ObjectIndex+2;    

      // PDF version
      fprintf(Output,"%%PDF-1.2\n");

      // Font Resource
      ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex] =ftell(Output);
         fprintf(Output,"%d 0 obj\n",ObjectMem.ObjectIndex+1);
         fprintf(Output,"<<\n");
         fprintf(Output,"/Type /Font\n");
         fprintf(Output,"/Name /%s\n",m_FontName);
         fprintf(Output,"/BaseFont /HeiseiKakuGo-W5-%s\n",m_FontEncoding);
         fprintf(Output,"/Subtype /Type0\n");
         fprintf(Output,"/Encoding /%s\n",m_FontEncoding);
         fprintf(Output,"/DescendantFonts [ << /Type /Font /Subtype /CIDFontType0 /BaseFont /HeiseiKakuGo-W5\n");
         fprintf(Output,"/FontDescriptor << /Type /FontDescriptor /FontName /HeiseiKakuGo-W5 /ItalicAngle 0 /FontBBox [ -92 -250 1010 922 ]\n");
         fprintf(Output,"/Style << /Panose <");
         fprintf(Output,"0801020B0600000000000000");
         fprintf(Output,">>> /Ascent 752 /CapHeight 737 /Descent -221\n");
         fprintf(Output,"/Flags 4 /StemV 114 /XHeight 553 >>\n");
         fprintf(Output,"/CIDSystemInfo << /Registry (Adobe)/Ordering (Japan1)/Supplement 2 >>\n");
         fprintf(Output,"/DW 1000 /W [ %s ] >>\n",m_FontWidth);
         fprintf(Output,"]\n");
         fprintf(Output,">>\n");
         fprintf(Output,"endobj\n");
      ObjectMem.ObjectIndex++;
      ObjectMem.MemoryCheck();

      // Write Page
      Write_PageObject(Output,ObjectMem,StringList,PageList);

      // Catalog
      ObjectMem.ObjectPosArray[0] =ftell(Output);
         fprintf(Output,"1 0 obj\n");
         fprintf(Output,"<<\n");
         fprintf(Output,"/Type /Catalog\n");
         fprintf(Output,"/Pages 2 0 R\n");
         fprintf(Output,">>\n");
         fprintf(Output,"endobj\n");

      // Parent Pages
      ObjectMem.ObjectPosArray[1] =ftell(Output);
         fprintf(Output,"2 0 obj\n");
         fprintf(Output,"<<\n");
         fprintf(Output,"/Type /Pages\n");
           // Kids Pages
           fprintf(Output,"/Kids [\n");
           for (i=0;i<PageList.Count();i++)
             fprintf(Output," %s 0 R\n",PageList[i]);
         fprintf(Output," ]\n");
         fprintf(Output,"/Count %d\n",PageList.Count());
         fprintf(Output,">>\n");
         fprintf(Output,"endobj\n");

      // CrossReferenceTable
      ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex] =ftell(Output);
      Write_CrossReferenceTable(Output,ObjectMem.ObjectPosArray,ObjectMem.ObjectIndex);

      // trailer
      fprintf(Output,"trailer\n");
      fprintf(Output,"<<\n");
      fprintf(Output,"/Size %d\n",ObjectMem.ObjectIndex+1);
      fprintf(Output,"/Root 1 0 R\n");
      fprintf(Output,">>\n");
      fprintf(Output,"startxref\n");
      fprintf(Output,"%d\n",ObjectMem.ObjectPosArray[ObjectMem.ObjectIndex]);
      fprintf(Output,"%%%%EOF\n");
  }
  catch (char * emsg)
  {
    delete [] m_FontEncoding;
    delete [] m_FontWidth;
    delete [] m_FontName;    
    throw (emsg);
  }
  catch (...)
  {
    delete [] m_FontEncoding;
    delete [] m_FontWidth;
    delete [] m_FontName;    
    throw (-1);
  }
  
  delete [] m_FontEncoding;
  delete [] m_FontWidth;
  delete [] m_FontName;    
}




関連記事



公開日:2015年01月08日 最終更新日:2015年02月18日
記事NO:00092