rtf output it rtf translator

Signed-off-by: Markus Himmel <markus@himmel-villmar.de>
Signed-off-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Ezo 2013-11-30 11:42:58 +00:00 committed by Adrien Destugues
parent f978d9a815
commit fa267963e0
3 changed files with 199 additions and 29 deletions

View File

@ -21,6 +21,15 @@
#define DATA_BUFFER_SIZE 64 #define DATA_BUFFER_SIZE 64
#define TEXT_IN_QUALITY 0.4
#define TEXT_IN_CAPABILITY 0.6
#define STXT_IN_QUALITY 0.5
#define STXT_IN_CAPABILITY 0.5
#define RTF_OUT_QUALITY RTF_IN_QUALITY
#define RTF_OUT_CAPABILITY RTF_IN_CAPABILITY
// The input formats that this translator supports. // The input formats that this translator supports.
static const translation_format sInputFormats[] = { static const translation_format sInputFormats[] = {
{ {
@ -30,6 +39,22 @@ static const translation_format sInputFormats[] = {
RTF_IN_CAPABILITY, RTF_IN_CAPABILITY,
"text/rtf", "text/rtf",
"RichTextFormat file" "RichTextFormat file"
},
{
B_TRANSLATOR_TEXT,
B_TRANSLATOR_TEXT,
TEXT_IN_QUALITY,
TEXT_IN_CAPABILITY,
"text/plain",
"Plain text file"
},
{
B_STYLED_TEXT_FORMAT,
B_TRANSLATOR_TEXT,
STXT_IN_QUALITY,
STXT_IN_CAPABILITY,
"text/x-vnd.Be-stxt",
"Be styled text file"
} }
}; };
@ -50,6 +75,14 @@ static const translation_format sOutputFormats[] = {
STXT_OUT_CAPABILITY, STXT_OUT_CAPABILITY,
"text/x-vnd.Be-stxt", "text/x-vnd.Be-stxt",
"Be styled text file" "Be styled text file"
},
{
RTF_TEXT_FORMAT,
B_TRANSLATOR_TEXT,
RTF_OUT_QUALITY,
RTF_OUT_CAPABILITY,
"text/rtf",
"RichTextFormat file"
} }
}; };
@ -121,15 +154,15 @@ RTFTranslator::Identify(BPositionIO *stream,
{ {
if (!outType) if (!outType)
outType = B_TRANSLATOR_TEXT; outType = B_TRANSLATOR_TEXT;
if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT) else if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT
&& outType != RTF_TEXT_FORMAT)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
RTF::Parser parser(*stream); RTF::Parser parser(*stream);
status_t status = parser.Identify(); status_t status = parser.Identify();
if (status != B_OK)
return B_NO_TRANSLATOR;
if (status == B_OK) {
// return information about the data in the stream // return information about the data in the stream
info->type = B_TRANSLATOR_TEXT; //RTF_TEXT_FORMAT; info->type = B_TRANSLATOR_TEXT; //RTF_TEXT_FORMAT;
info->group = B_TRANSLATOR_TEXT; info->group = B_TRANSLATOR_TEXT;
@ -138,7 +171,34 @@ RTFTranslator::Identify(BPositionIO *stream,
strlcpy(info->name, B_TRANSLATE("RichTextFormat file"), strlcpy(info->name, B_TRANSLATE("RichTextFormat file"),
sizeof(info->name)); sizeof(info->name));
strcpy(info->MIME, "text/rtf"); strcpy(info->MIME, "text/rtf");
} else {
stream->Seek(0, SEEK_SET);
TranslatorStyledTextStreamHeader header;
stream->Read(&header, sizeof(header));
swap_data(B_UINT32_TYPE, &header, sizeof(header),
B_SWAP_BENDIAN_TO_HOST);
stream->Seek(0, SEEK_SET);
if (header.header.magic == B_STYLED_TEXT_FORMAT
&& header.header.header_size == (int32)sizeof(header)
&& header.header.data_size == 0
&& header.version == 100) {
info->type = B_STYLED_TEXT_FORMAT;
info->group = B_TRANSLATOR_TEXT;
info->quality = STXT_IN_QUALITY;
info->capability = STXT_IN_CAPABILITY;
strlcpy(info->name, B_TRANSLATE("Be style text file"),
sizeof(info->name));
strcpy(info->MIME, "text/x-vnd.Be-stxt");
} else {
info->type = B_TRANSLATOR_TEXT;
info->group = B_TRANSLATOR_TEXT;
info->quality = TEXT_IN_QUALITY;
info->capability = TEXT_IN_CAPABILITY;
strlcpy(info->name, B_TRANSLATE("Plain text file"),
sizeof(info->name));
strcpy(info->MIME, "text/plain");
}
}
return B_OK; return B_OK;
} }
@ -153,9 +213,11 @@ RTFTranslator::Translate(BPositionIO *source,
if (!outType) if (!outType)
outType = B_TRANSLATOR_TEXT; outType = B_TRANSLATOR_TEXT;
if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT) if (outType != B_TRANSLATOR_TEXT && outType != B_STYLED_TEXT_FORMAT
&& outType != RTF_TEXT_FORMAT)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
if (strncmp(inInfo->MIME, "text/rtf", 8) == 0) {
RTF::Parser parser(*source); RTF::Parser parser(*source);
RTF::Header header; RTF::Header header;
@ -163,12 +225,18 @@ RTFTranslator::Translate(BPositionIO *source,
if (status != B_OK) if (status != B_OK)
return status; return status;
// we support two different output formats
if (outType == B_TRANSLATOR_TEXT) if (outType == B_TRANSLATOR_TEXT)
return convert_to_plain_text(header, *target); return convert_to_plain_text(header, *target);
else
return convert_to_stxt(header, *target); return convert_to_stxt(header, *target);
} else if (inInfo->type == B_TRANSLATOR_TEXT) {
return convert_plain_text_to_rtf(*source, *target);
} else if (inInfo->type == B_STYLED_TEXT_FORMAT) {
return convert_styled_text_to_rtf(source, target);
} else
return B_BAD_VALUE;
} }

View File

@ -21,7 +21,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <algorithm>
#include <fs_attr.h>
#define READ_BUFFER_SIZE 2048
struct conversion_context { struct conversion_context {
conversion_context() conversion_context()
@ -645,3 +648,98 @@ convert_to_plain_text(RTF::Header &header, BPositionIO &target)
free(flattenedRuns); free(flattenedRuns);
return B_OK; return B_OK;
} }
status_t convert_styled_text_to_rtf(
BPositionIO* source, BPositionIO* target)
{
if (source->Seek(0, SEEK_SET) != 0)
return B_ERROR;
const ssize_t kstxtsize = sizeof(TranslatorStyledTextStreamHeader);
const ssize_t ktxtsize = sizeof(TranslatorStyledTextTextHeader);
TranslatorStyledTextStreamHeader stxtheader;
TranslatorStyledTextTextHeader txtheader;
char buffer[READ_BUFFER_SIZE];
if (source->Read(&stxtheader, kstxtsize) != kstxtsize)
return B_ERROR;
if (source->Read(&txtheader, ktxtsize) != ktxtsize)
return B_ERROR;
BString plainText;
ssize_t nread = 0, nreed = 0, ntotalread = 0;
nreed = min((size_t)READ_BUFFER_SIZE,
(size_t)txtheader.header.data_size - ntotalread);
nread = source->Read(buffer, nreed);
while (nread > 0) {
plainText << buffer;
ntotalread += nread;
nreed = min((size_t)READ_BUFFER_SIZE,
(size_t)txtheader.header.data_size - ntotalread);
nread = source->Read(buffer, nreed);
}
if ((ssize_t)txtheader.header.data_size != ntotalread)
return B_NO_TRANSLATOR;
BString rtfFile =
"{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard ";
rtfFile << plainText << " }";
target->Write((const void*)rtfFile, rtfFile.Length());
BNode* node = (BNode*)source;
const char* kAttrName = "styles";
attr_info info;
if (node->GetAttrInfo(kAttrName, &info) != B_OK
|| info.type != B_RAW_TYPE || info.size < 160)
return B_ERROR;
uint8* flatRunArray = new (std::nothrow) uint8[info.size];
if (flatRunArray == NULL)
return B_NO_MEMORY;
if (node->ReadAttr(kAttrName, B_RAW_TYPE, 0, flatRunArray, info.size
!= info.size))
return B_OK;
//todo: convert stxt attributes to rtf commands
//text_run_array* styles = (text_run_array*)flatRunArray;
size_t stylesSize = info.size / 3;
for(uint32 i = 0; i < stylesSize; i++) {
}
delete[] flatRunArray;
return B_OK;
}
status_t convert_plain_text_to_rtf(
BPositionIO& source, BPositionIO& target)
{
BString rtfFile =
"{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard ";
BFile* fileSource = (BFile*)&source;
off_t size;
fileSource->GetSize(&size);
char* sourceBuf = (char*)malloc(size);
fileSource->Read((void*)sourceBuf, size);
BString sourceTxt = sourceBuf;
sourceTxt.CharacterEscape("\\{}", '\\');
sourceTxt.ReplaceAll("\n", " \\par ");
rtfFile << sourceTxt << " }";
BFile* fileTarget = (BFile*)&target;
fileTarget->Write((const void*)rtfFile, rtfFile.Length());
return B_OK;
}

View File

@ -12,5 +12,9 @@
extern status_t convert_to_stxt(RTF::Header &header, BDataIO &target); extern status_t convert_to_stxt(RTF::Header &header, BDataIO &target);
extern status_t convert_to_plain_text(RTF::Header &header, BPositionIO &target); extern status_t convert_to_plain_text(RTF::Header &header, BPositionIO &target);
extern status_t convert_styled_text_to_rtf(
BPositionIO* source, BPositionIO* target);
extern status_t convert_plain_text_to_rtf(
BPositionIO& source, BPositionIO& target);
#endif /* CONVERT_H */ #endif /* CONVERT_H */