사용자 도구

사이트 도구


kb:rtfwriter

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:rtfwriter [2014/11/10 19:35] (현재)
줄 1: 줄 1:
 +====== RTF Writer ======
 +RTF 파일 쓰기 클래스
 +
 +====== C++ Implementation ======
 +<file cpp RTF.h>
 +#ifndef __RTF_H__
 +#define __RTF_H__
 +
 +#include <​string>​
 +#include <set>
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \class RTF
 +/// \brief 간단한 RTF 파일 리포트 생성을 위한 클래스.
 +///
 +/// 어디까지나 간단한 레포트 출력만을 목표로 하는 클래스이기 때문에, 기능이
 +/// 매우 부실하고 느리다. 하지만 개선해야할 필요성을 못 느끼겠다.
 +///
 +/// <pre>
 +/// RTF rtf;
 +/// 
 +/// RTF::STYLES bold;
 +/// bold.insert(RTF::​BOLD);​
 +/// 
 +/// rtf.add(RTF::​DARK_BLUE,​ bold, "​제목"​);​
 +/// rtf.add("​\t첫번째 항목 : %s", "​뭐가 좋을까?"​);​
 +/// rtf.add("​\t두번째 항목 : %s", "​이것이 좋을까?"​);​
 +/// 
 +/// rtf.flush("​sample.rtf"​);​
 +/// </​pre>​
 +//////////////////////////////////////////////////////////////////////////////​
 +
 +class RTF
 +{
 +public:
 +    /// 색깔 배열
 +    enum Color
 +    {
 +        BLACK = 0, WHITE, GREY, RED, GREEN, BLUE, CYAN, YELLOW, MAGENTA, ​
 +        DARK_RED, DARK_GREEN, DARK_BLUE, LIGHT_RED, LIGHT_GREEN,​ LIGHT_BLUE,
 +ORANGE
 +    };
 +
 +    /// 스타일 배열
 +    enum Style
 +    {
 +        BOLD = 0, ITALIC, UNDERLINE, STRIKE
 +    };
 +
 +    typedef std::​set<​Style>​ STYLES;
 +
 +
 +private:
 +    /// 라인 정의
 +    typedef struct LINE
 +    {
 +        std::string text;    ///< 라인 문자열
 +        int         ​color; ​  ///<​ 라인 색깔
 +        STYLES ​     styles; ​ ///< 라인 스타일
 +    } LINE;
 +
 +    typedef std::​list<​LINE>​ LINES;
 +
 +    LINES  m_Lines; ​         ///< 기록할 라인들
 +    int    m_DefaultColor; ​  ///<​ 기본 색깔
 +    STYLES m_DefaultStyles; ​ ///< 기본 스타일
 +
 +
 +public:
 +    /// \brief 생성자
 +    RTF();
 +
 +    /// \brief 소멸자
 +    virtual ~RTF();
 +
 +
 +public:
 +    /// \brief 기본 색깔과 스타일을 가지는 라인을 추가한다.
 +    /// \param fmt 가변 인자 포맷
 +    /// \param ... 가변 인자들
 +    void add(const char* fmt, ...);
 +
 +    /// \brief 색깔과 스타일을 지정해서 라인을 추가한다.
 +    /// \param color 색깔
 +    /// \param styles 스타일
 +    /// \param fmt 가변 인자 포맷
 +    /// \param ... 가변 인자들
 +    void add(Color color, const STYLES& styles, const char* fmt, ...);
 +
 +    /// \brief 가지고 있는 내용을 실제 파일에다가 기록한다.
 +    /// \param filename 파일 이름
 +    void flush(const std::​string&​ filename);
 +
 +
 +public:
 +    /// \name 기본 색깔 반환/​설정
 +    /// \{ 
 +    int getDefaultColor() const { return m_DefaultColor;​ }
 +    void setDefaultColor(Color color) { m_DefaultColor = color; }
 +    /// \} 
 +
 +    /// \name 기본 스타일 반환/​설정
 +    /// \{ 
 +    const STYLES& getDefaultStyles() const { return m_DefaultStyles;​ }
 +    void setDefaultStyles(const STYLES& styles) { m_DefaultStyles = styles; }
 +    /// \} 
 +};
 +
 +#endif //__RTF_H__
 +</​file>​
 +
 +<file cpp RTF.cpp>
 +#include "​RTF.h"​
 +#include <​fstream>​
 +#include <​stdio.h>​
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \brief 생성자
 +//////////////////////////////////////////////////////////////////////////////​
 +RTF::RTF()
 +: m_DefaultColor(BLACK)
 +{
 +}
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \brief 소멸자
 +//////////////////////////////////////////////////////////////////////////////​
 +RTF::~RTF()
 +{
 +    m_Lines.clear();​
 +}
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \brief 기본 색깔과 스타일을 가지는 라인을 추가한다.
 +/// \param fmt 가변 인자 포맷
 +/// \param ... 가변 인자들
 +//////////////////////////////////////////////////////////////////////////////​
 +void RTF::​add(const char* fmt, ...)
 +{
 +    int nchars = 0;
 +    int buflen = 512;
 +    char* buf = NULL;
 +
 +    va_list valist;
 +    va_start(valist,​ fmt);
 +
 +    do {
 +        buflen = buflen * 2;
 +        buf = reinterpret_cast<​char*>​(::​realloc(buf,​ buflen));
 +        memset(buf, 0, buflen);
 +        nchars = vsprintf(buf,​ fmt, valist);
 +    } while (nchars < 0 || nchars > buflen);
 +
 +    va_end(valist);​
 +
 +    LINE line;
 +    line.text = buf;
 +    line.color = m_DefaultColor;​
 +    line.styles = m_DefaultStyles;​
 +    m_Lines.push_back(line);​
 +
 +    ::​free(buf);​
 +}
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \brief 색깔과 스타일을 지정해서 라인을 추가한다.
 +/// \param color 색깔
 +/// \param styles 스타일
 +/// \param fmt 가변 인자 포맷
 +/// \param ... 가변 인자들
 +//////////////////////////////////////////////////////////////////////////////​
 +void RTF::​add(Color color, const STYLES& styles, const char* fmt, ...)
 +{
 +    int nchars = 0;
 +    int buflen = 512;
 +    char* buf = NULL;
 +
 +    va_list valist;
 +    va_start(valist,​ fmt);
 +
 +    do {
 +        buflen = buflen * 2;
 +        buf = reinterpret_cast<​char*>​(::​realloc(buf,​ buflen));
 +        memset(buf, 0, buflen);
 +        nchars = vsprintf(buf,​ fmt, valist);
 +    } while (nchars < 0 || nchars > buflen);
 +
 +    va_end(valist);​
 +
 +    LINE line;
 +    line.text = buf;
 +    line.color = color;
 +    line.styles = styles;
 +    m_Lines.push_back(line);​
 +
 +    ::​free(buf);​
 +}
 +
 +//////////////////////////////////////////////////////////////////////////////​
 +/// \brief 가지고 있는 내용을 실제 파일에다가 기록한다.
 +/// \param filename 파일 이름
 +//////////////////////////////////////////////////////////////////////////////​
 +void RTF::​flush(const std::​string&​ filename)
 +{
 +    std::​ofstream file(filename.c_str(),​ std::​ios::​out | std::​ios::​trunc);​
 +    if (!file) return;
 +
 +    // RTF 헤더를 쓴다.
 +    file << "​{\\rtf1\\ansi\\ansicpg949\\deff0{\\fonttbl{\\f0
 +굴림체;​}}\\fs20\n"​ << std::endl;
 +
 +    // 컬러 테이블을 쓴다.
 +    file << "​{\\colortbl;"​ << std::endl;
 +    file << "​\\red255\\green255\\blue255;"​ << std::endl;
 +    file << "​\\red128\\green128\\blue128;"​ << std::endl;
 +    file << "​\\red255\\green0\\blue0;"​ << std::endl;
 +    file << "​\\red0\\green255\\blue0;"​ << std::endl;
 +    file << "​\\red0\\green0\\blue255;"​ << std::endl;
 +    file << "​\\red0\\green255\\blue255;"​ << std::endl;
 +    file << "​\\red255\\green255\\blue0;"​ << std::endl;
 +    file << "​\\red255\\green0\\blue255;"​ << std::endl;
 +    file << "​\\red128\\green0\\blue0;"​ << std::endl;
 +    file << "​\\red0\\green128\\blue0;"​ << std::endl;
 +    file << "​\\red0\\green0\\blue128;"​ << std::endl;
 +    file << "​\\red255\\green128\\blue128;"​ << std::endl;
 +    file << "​\\red128\\green255\\blue128;"​ << std::endl;
 +    file << "​\\red128\\green128\\blue255;"​ << std::endl;
 +    file << "​\\red255\\green128\\blue0;"​ << std::endl;
 +    file << "​}"​ << std::endl;
 +
 +    for (LINES::​const_iterator itr(m_Lines.begin());​
 +        itr != m_Lines.end();​ ++itr)
 +    {
 +        const LINE& line = *itr;
 +        file << "​{\\pard ";
 +
 +        if (line.styles.find(BOLD) != line.styles.end())
 +            file << "​\\b";​
 +
 +        if (line.styles.find(ITALIC) != line.styles.end())
 +            file << "​\\i";​
 +
 +        if (line.styles.find(UNDERLINE) != line.styles.end())
 +            file << "​\\ul";​
 +
 +        if (line.styles.find(STRIKE) != line.styles.end())
 +            file << "​\\strike";​
 +
 +        file << "​\\cf"​ << line.color << " ";
 +        file << line.text;
 +        file << "​\\par}";​
 +    }
 +
 +    // 끝 부분의 괄호를 써 준다.
 +    file << "​}"​ << std::endl;
 +}
 +</​file>​
 +
 +----
 +  * see also [[RtfFileProcessing]]
 +
  
kb/rtfwriter.txt · 마지막으로 수정됨: 2014/11/10 19:35 (바깥 편집)