Ticket #8873: 0001-rtf-output-it-rtf-translator.patch

File 0001-rtf-output-it-rtf-translator.patch, 8.8 KB (added by siarzhuk, 10 years ago)

Result of corresponding GCI 2013 task.

  • src/add-ons/translators/rtf/RTFTranslator.cpp

    From 93609532f673708ff3fb988d19058a67e4c9ab25 Mon Sep 17 00:00:00 2001
    From: Ezo <ezo.dev@gmail.com>
    Date: Sat, 30 Nov 2013 11:42:58 +0000
    Subject: [PATCH] rtf output it rtf translator
    
    ---
     src/add-ons/translators/rtf/RTFTranslator.cpp | 128 ++++++++++++++++++++------
     src/add-ons/translators/rtf/convert.cpp       |  98 ++++++++++++++++++++
     src/add-ons/translators/rtf/convert.h         |   6 +-
     3 files changed, 201 insertions(+), 31 deletions(-)
    
    diff --git a/src/add-ons/translators/rtf/RTFTranslator.cpp b/src/add-ons/translators/rtf/RTFTranslator.cpp
    index 1c107c9..6c9d785 100644
    a b  
    2121#define DATA_BUFFER_SIZE 64
    2222
    2323
     24#define TEXT_IN_QUALITY 0.4
     25#define TEXT_IN_CAPABILITY 0.6
     26
     27#define STXT_IN_QUALITY 0.5
     28#define STXT_IN_CAPABILITY 0.5
     29
     30#define RTF_OUT_QUALITY RTF_IN_QUALITY
     31#define RTF_OUT_CAPABILITY RTF_IN_CAPABILITY
     32
    2433// The input formats that this translator supports.
    2534static const translation_format sInputFormats[] = {
    2635    {
    static const translation_format sInputFormats[] = {  
    3039        RTF_IN_CAPABILITY,
    3140        "text/rtf",
    3241        "RichTextFormat file"
     42    },
     43    {
     44        B_TRANSLATOR_TEXT,
     45        B_TRANSLATOR_TEXT,
     46        TEXT_IN_QUALITY,
     47        TEXT_IN_CAPABILITY,
     48        "text/plain",
     49        "Plain text file"
     50    },
     51    {
     52        B_STYLED_TEXT_FORMAT,
     53        B_TRANSLATOR_TEXT,
     54        STXT_IN_QUALITY,
     55        STXT_IN_CAPABILITY,
     56        "text/x-vnd.Be-stxt",
     57        "Be styled text file"
    3358    }
    3459};
    3560
    static const translation_format sOutputFormats[] = {  
    5075        STXT_OUT_CAPABILITY,
    5176        "text/x-vnd.Be-stxt",
    5277        "Be styled text file"
     78    },
     79    {
     80        RTF_TEXT_FORMAT,
     81        B_TRANSLATOR_TEXT,
     82        RTF_OUT_QUALITY,
     83        RTF_OUT_CAPABILITY,
     84        "text/rtf",
     85        "RichTextFormat file"
    5386    }
    5487};
    5588
    status_t  
    118151RTFTranslator::Identify(BPositionIO *stream,
    119152    const translation_format *format, BMessage *ioExtension,
    120153    translator_info *info, uint32 outType)
    121 {
     154{   
    122155    if (!outType)
    123156        outType = B_TRANSLATOR_TEXT;
    124     if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT)
     157    else if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT
     158        && outType != RTF_TEXT_FORMAT)
    125159        return B_NO_TRANSLATOR;
    126160
     161   
    127162    RTF::Parser parser(*stream);
    128 
    129163    status_t status = parser.Identify();
    130     if (status != B_OK)
    131         return B_NO_TRANSLATOR;
    132 
    133     // return information about the data in the stream
    134     info->type = B_TRANSLATOR_TEXT; //RTF_TEXT_FORMAT;
    135     info->group = B_TRANSLATOR_TEXT;
    136     info->quality = RTF_IN_QUALITY;
    137     info->capability = RTF_IN_CAPABILITY;
    138     strlcpy(info->name, B_TRANSLATE("RichTextFormat file"),
    139         sizeof(info->name));
    140     strcpy(info->MIME, "text/rtf");
    141 
     164   
     165    if (status == B_OK) {
     166        // return information about the data in the stream
     167        info->type = B_TRANSLATOR_TEXT; //RTF_TEXT_FORMAT;
     168        info->group = B_TRANSLATOR_TEXT;
     169        info->quality = RTF_IN_QUALITY;
     170        info->capability = RTF_IN_CAPABILITY;
     171        strlcpy(info->name, B_TRANSLATE("RichTextFormat file"),
     172            sizeof(info->name));
     173        strcpy(info->MIME, "text/rtf");
     174    } else {
     175        stream->Seek(0, SEEK_SET);
     176        TranslatorStyledTextStreamHeader header;
     177        stream->Read(&header, sizeof(header));
     178        swap_data(B_UINT32_TYPE, &header, sizeof(header),
     179            B_SWAP_BENDIAN_TO_HOST);
     180        stream->Seek(0, SEEK_SET);
     181        if (header.header.magic == B_STYLED_TEXT_FORMAT
     182            && header.header.header_size == (int32)sizeof(header)
     183            && header.header.data_size == 0
     184            && header.version == 100) {
     185            info->type = B_STYLED_TEXT_FORMAT;
     186            info->group = B_TRANSLATOR_TEXT;
     187            info->quality = STXT_IN_QUALITY;
     188            info->capability = STXT_IN_CAPABILITY;
     189            strlcpy(info->name, B_TRANSLATE("Be style text file"),
     190                sizeof(info->name));
     191            strcpy(info->MIME, "text/x-vnd.Be-stxt");       
     192        } else {
     193            info->type = B_TRANSLATOR_TEXT;
     194            info->group = B_TRANSLATOR_TEXT;
     195            info->quality = TEXT_IN_QUALITY;
     196            info->capability = TEXT_IN_CAPABILITY;
     197            strlcpy(info->name, B_TRANSLATE("Plain text file"),
     198                sizeof(info->name));
     199            strcpy(info->MIME, "text/plain");
     200        }
     201    }
    142202    return B_OK;
    143203}
    144204
    RTFTranslator::Translate(BPositionIO *source,  
    153213
    154214    if (!outType)
    155215        outType = B_TRANSLATOR_TEXT;
    156     if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT)
     216    if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT
     217        && outType != RTF_TEXT_FORMAT)
    157218        return B_NO_TRANSLATOR;
    158 
    159     RTF::Parser parser(*source);
    160 
    161     RTF::Header header;
    162     status_t status = parser.Parse(header);
    163     if (status != B_OK)
    164         return status;
    165 
    166     // we support two different output formats
    167 
    168     if (outType == B_TRANSLATOR_TEXT)
    169         return convert_to_plain_text(header, *target);
    170 
    171     return convert_to_stxt(header, *target);
     219   
     220    if (strncmp(inInfo->MIME, "text/rtf", 8) == 0) {
     221        RTF::Parser parser(*source);
     222
     223        RTF::Header header;
     224        status_t status = parser.Parse(header);
     225        if (status != B_OK)
     226            return status;
     227
     228        if (outType == B_TRANSLATOR_TEXT)
     229            return convert_to_plain_text(header, *target);
     230        else
     231            return convert_to_stxt(header, *target);
     232           
     233    } else if (inInfo->type == B_TRANSLATOR_TEXT) {
     234        return convert_plain_text_to_rtf(*source, *target);
     235    } else if (inInfo->type == B_STYLED_TEXT_FORMAT) {
     236        return convert_styled_text_to_rtf(source, target); 
     237    } else
     238        return B_BAD_VALUE;
     239   
    172240}
    173241
    174242
  • src/add-ons/translators/rtf/convert.cpp

    diff --git a/src/add-ons/translators/rtf/convert.cpp b/src/add-ons/translators/rtf/convert.cpp
    index f198476..bc8d12f 100644
    a b  
    2121#include <stdlib.h>
    2222#include <stdio.h>
    2323#include <string.h>
     24#include <algorithm>
    2425
     26#include <fs_attr.h>
     27#define READ_BUFFER_SIZE 2048
    2528
    2629struct conversion_context {
    2730    conversion_context()
    convert_to_plain_text(RTF::Header &header, BPositionIO &target)  
    645648    free(flattenedRuns);
    646649    return B_OK;
    647650}
     651
     652
     653status_t convert_styled_text_to_rtf(
     654    BPositionIO* source, BPositionIO* target)
     655{
     656    if (source->Seek(0, SEEK_SET) != 0)
     657        return B_ERROR;
     658
     659    const ssize_t kstxtsize = sizeof(TranslatorStyledTextStreamHeader);
     660    const ssize_t ktxtsize = sizeof(TranslatorStyledTextTextHeader);
     661    TranslatorStyledTextStreamHeader stxtheader;
     662    TranslatorStyledTextTextHeader txtheader;
     663    char buffer[READ_BUFFER_SIZE];
     664   
     665    if (source->Read(&stxtheader, kstxtsize) != kstxtsize)
     666        return B_ERROR;
     667    if (source->Read(&txtheader, ktxtsize) != ktxtsize)
     668        return B_ERROR;
     669   
     670
     671    BString plainText; 
     672    ssize_t nread = 0, nreed = 0, ntotalread = 0;
     673    nreed = min((size_t)READ_BUFFER_SIZE,
     674        (size_t)txtheader.header.data_size - ntotalread);
     675    nread = source->Read(buffer, nreed);
     676    while (nread > 0) {
     677        plainText << buffer;
     678
     679        ntotalread += nread;
     680        nreed = min((size_t)READ_BUFFER_SIZE,
     681            (size_t)txtheader.header.data_size - ntotalread);
     682        nread = source->Read(buffer, nreed);
     683    }   
     684    if ((ssize_t)txtheader.header.data_size != ntotalread)
     685        return B_NO_TRANSLATOR;
     686       
     687    BString rtfFile =
     688        "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard ";
     689       
     690    rtfFile << plainText << " }";
     691    target->Write((const void*)rtfFile, rtfFile.Length());
     692   
     693
     694    BNode* node = (BNode*)source;
     695    const char* kAttrName = "styles";
     696    attr_info info;
     697   
     698    if (node->GetAttrInfo(kAttrName, &info) != B_OK
     699        || info.type != B_RAW_TYPE || info.size < 160)
     700        return B_ERROR;
     701
     702    uint8* flatRunArray = new (std::nothrow) uint8[info.size];
     703    if (flatRunArray == NULL)
     704        return B_NO_MEMORY;
     705
     706    if (node->ReadAttr(kAttrName, B_RAW_TYPE, 0, flatRunArray, info.size
     707        != info.size))
     708        return B_OK;
     709           
     710    //todo: convert stxt attributes to rtf commands
     711           
     712    //text_run_array* styles = (text_run_array*)flatRunArray;
     713    size_t stylesSize = info.size / 3;
     714   
     715    for(uint32 i = 0; i < stylesSize; i++) {
     716   
     717    }
     718   
     719    delete[] flatRunArray;
     720    return B_OK;
     721}
     722
     723       
     724status_t convert_plain_text_to_rtf(
     725    BPositionIO& source, BPositionIO& target)
     726{
     727    BString rtfFile =
     728        "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard ";
     729       
     730    BFile* fileSource = (BFile*)&source;
     731    off_t size;
     732    fileSource->GetSize(&size);
     733    char* sourceBuf = (char*)malloc(size);
     734    fileSource->Read((void*)sourceBuf, size);
     735   
     736    BString sourceTxt = sourceBuf;
     737    sourceTxt.CharacterEscape("\\{}", '\\');
     738    sourceTxt.ReplaceAll("\n", " \\par ");
     739    rtfFile << sourceTxt << " }";
     740   
     741    BFile* fileTarget = (BFile*)&target;
     742    fileTarget->Write((const void*)rtfFile, rtfFile.Length());
     743   
     744    return B_OK;
     745}
  • src/add-ons/translators/rtf/convert.h

    diff --git a/src/add-ons/translators/rtf/convert.h b/src/add-ons/translators/rtf/convert.h
    index 7bce2a9..7684057 100644
    a b  
    1212
    1313extern status_t convert_to_stxt(RTF::Header &header, BDataIO &target);
    1414extern status_t convert_to_plain_text(RTF::Header &header, BPositionIO &target);
    15 
     15extern status_t convert_styled_text_to_rtf(
     16    BPositionIO* source, BPositionIO* target);
     17extern status_t convert_plain_text_to_rtf(
     18    BPositionIO& source, BPositionIO& target);
     19   
    1620#endif  /* CONVERT_H */