Compare commits

..

6 Commits

15 changed files with 332 additions and 104 deletions

View File

@ -385,6 +385,78 @@ void oox2odf_converter::Impl::replace_cells_range(std::wstring& expr, bool bSele
return;
}
size_t getColAddressInv(const std::wstring & a_)
{
std::wstring a = a_;
::boost::algorithm::to_upper(a);
static const size_t r = (L'Z' - L'A' + 1);
size_t mul = 1;
bool f = true;
size_t res = 0;
for (int i = a.length() - 1; i >= 0; i--)
{
size_t v = a[i] - L'A';
if (f)
f = false;
else
v += 1;
res += v * mul;
mul *= r;
}
return res;
}
size_t getRowAdderssInv(const std::wstring & a_)
{
int sz = a_.length();
if (a_.length()>0)
{
return boost::lexical_cast<size_t>(a_)-1;
}
else
return 0;
}
void splitCellAddress(const std::wstring & a_, std::wstring & col, std::wstring & row)
{
std::wstring a = a_;
std::reverse(a.begin(), a.end());
::XmlUtils::replace_all( a, L"$", L"");
//::XmlUtils::replace_all( a, L"'", L"");
::boost::algorithm::to_upper(a);
for (size_t i = 0; i < a.length(); i++)
{
if (a[i] >= L'0' && a[i] <= L'9')
row += a[i];
else
col += a[i];
}
std::reverse(col.begin(), col.end());
std::reverse(row.begin(), row.end());
}
void getCellAddressInv(const std::wstring & a_, int & col, int & row)
{
std::wstring colStr=L"", rowStr=L"";
splitCellAddress(a_, colStr, rowStr);
col = getColAddressInv(colStr);
row = getRowAdderssInv(rowStr);
if (col > 16384) col= -1;
}
bool IsRefPresent(const std::wstring& ref_test)
{
int col = -1, row = -1;
getCellAddressInv(ref_test, col, row);
if (col >= 0 && row >=0) return true;
return false;
}
std::wstring oox2odf_converter::Impl::replace_cells_range_formater1(boost::wsmatch const & what)
{
const size_t sz = what.size();
@ -413,8 +485,21 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater1(boost::wsmat
if (!c2.empty() && c2.substr(0, 1) == L":")
c2 = c2.substr(1);
s = L"[" + sheet + L"." + c1 + (c2.empty() ? L"" : (L":" + sheet + L"." + c2)) + std::wstring(L"]");
bool bRefPresent = true;
if (sheet.empty() && c2.empty())
{
bRefPresent = IsRefPresent(c1);
}
if (bRefPresent)
{
s = L"[" + sheet + L"." + c1 + (c2.empty() ? L"" : (L":" + sheet + L"." + c2)) + std::wstring(L"]");
}
else
{
s = c1;
}
}
return s;
}
@ -856,67 +941,6 @@ std::wstring oox2odf_converter::convert_spacechar(std::wstring expr)
}
return expr;
}
size_t getColAddressInv(const std::wstring & a_)
{
std::wstring a = a_;
::boost::algorithm::to_upper(a);
static const size_t r = (L'Z' - L'A' + 1);
size_t mul = 1;
bool f = true;
size_t res = 0;
for (int i = a.length() - 1; i >= 0; i--)
{
size_t v = a[i] - L'A';
if (f)
f = false;
else
v += 1;
res += v * mul;
mul *= r;
}
return res;
}
size_t getRowAdderssInv(const std::wstring & a_)
{
int sz = a_.length();
if (a_.length()>0)
{
return boost::lexical_cast<size_t>(a_)-1;
}
else
return 0;
}
void splitCellAddress(const std::wstring & a_, std::wstring & col, std::wstring & row)
{
std::wstring a = a_;
std::reverse(a.begin(), a.end());
::XmlUtils::replace_all( a, L"$", L"");
//::XmlUtils::replace_all( a, L"'", L"");
::boost::algorithm::to_upper(a);
for (size_t i = 0; i < a.length(); i++)
{
if (a[i] >= L'0' && a[i] <= L'9')
row += a[i];
else
col += a[i];
}
std::reverse(col.begin(), col.end());
std::reverse(row.begin(), row.end());
}
void getCellAddressInv(const std::wstring & a_, int & col, int & row)
{
std::wstring colStr=L"", rowStr=L"";
splitCellAddress(a_, colStr, rowStr);
col = getColAddressInv(colStr);
row = getRowAdderssInv(rowStr);
}
int oox2odf_converter::get_count_value_points(std::wstring expr)
{
int count =0;

View File

@ -2411,7 +2411,8 @@ void XlsxConverter::convert(OOX::Spreadsheet::CXfs * xfc_style, int oox_id, bool
odf_writer::style_text_properties * text_properties = ods_context->styles_context()->last_state()->get_text_properties();
odf_writer::style_table_cell_properties * table_cell_properties = ods_context->styles_context()->last_state()->get_table_cell_properties();
if (xlsx_styles->m_oFonts.IsInit() && font_id >=0 && (id_parent < 0 || xfc_style->m_oApplyFont.IsInit()))
bool bApplyFont = xfc_style->m_oApplyFont.IsInit() ? xfc_style->m_oApplyFont->ToBool() : true;
if (xlsx_styles->m_oFonts.IsInit() && font_id >=0 && (id_parent < 0 || bApplyFont))
{
std::map<int, OOX::Spreadsheet::CFont*>::iterator pFind = xlsx_styles->m_oFonts->m_mapFonts.find(font_id);
if (pFind != xlsx_styles->m_oFonts->m_mapFonts.end())
@ -2419,7 +2420,8 @@ void XlsxConverter::convert(OOX::Spreadsheet::CXfs * xfc_style, int oox_id, bool
convert(pFind->second, text_properties);
}
}
if (xlsx_styles->m_oFills.IsInit() && fill_id >= 0 && (id_parent < 0 || xfc_style->m_oApplyFill.IsInit()))
bool bApplyFill = xfc_style->m_oApplyFill.IsInit() ? xfc_style->m_oApplyFill->ToBool() : true;
if (xlsx_styles->m_oFills.IsInit() && fill_id >= 0 && (id_parent < 0 || bApplyFill))
{
std::map<int, OOX::Spreadsheet::CFill*>::iterator pFind = xlsx_styles->m_oFills->m_mapFills.find(fill_id);
if (pFind != xlsx_styles->m_oFills->m_mapFills.end())
@ -2427,12 +2429,14 @@ void XlsxConverter::convert(OOX::Spreadsheet::CXfs * xfc_style, int oox_id, bool
convert(pFind->second, table_cell_properties);
}
}
if (numFmt_id >= 0/* && (id_parent < 0 || xfc_style->m_oApplyNumberFormat.IsInit())*/)
bool bApplyNumberFormat = xfc_style->m_oApplyNumberFormat.IsInit() ? xfc_style->m_oApplyNumberFormat->ToBool() : true;
if (numFmt_id >= 0 && (id_parent < 0 || bApplyNumberFormat))
{
ods_context->styles_context()->last_state()->set_data_style_name(ods_context->numbers_styles_context()->add_or_find(numFmt_id).style_name);
ods_context->styles_context()->last_state()->set_number_format(numFmt_id);
}
if (xlsx_styles->m_oBorders.IsInit() && border_id >=0 && (id_parent < 0 || xfc_style->m_oApplyBorder.IsInit()))
bool bApplyBorder = xfc_style->m_oApplyBorder.IsInit() ? xfc_style->m_oApplyBorder->ToBool() : true;
if (xlsx_styles->m_oBorders.IsInit() && border_id >=0 && (id_parent < 0 || bApplyBorder))
{
std::map<int, OOX::Spreadsheet::CBorder*>::iterator pFind = xlsx_styles->m_oBorders->m_mapBorders.find(border_id);
if (pFind != xlsx_styles->m_oBorders->m_mapBorders.end())

View File

@ -338,6 +338,10 @@ namespace SimpleTypes
SimpleType_Operator_Equal (CGuid)
bool IsZero()
{
return 0 == m_oGUID.a && 0 == m_oGUID.b && 0 == m_oGUID.c && 0 == m_oGUID.d && 0 == m_oGUID.e && 0 == m_oGUID.f && 0 == m_oGUID.g && 0 == m_oGUID.h && 0 == m_oGUID.i && 0 == m_oGUID.j && 0 == m_oGUID.k;
}
private:
bool HexToInt(std::wstring& sValue, T_ULONG64& unResult)

View File

@ -311,7 +311,7 @@ namespace XmlUtils
// CoTaskMemFree(guidString);
//#else
std::wstringstream sstream;
sstream << boost::wformat(L"%04X%04X-%04X-%04X-%04X-%04X%04X%04X") % Rand() % Rand() % Rand() % ((Rand() & 0x0fff) | 0x4000) % ((Rand() % 0x3fff) + 0x8000) % Rand() % Rand() % Rand();
sstream << boost::wformat(L"%04X%04X-%04X-%04X-%04X-%04X%04X%04X") % (Rand() & 0xff) % (Rand() & 0xff) % (Rand() & 0xff) % ((Rand() & 0x0fff) | 0x4000) % ((Rand() % 0x3fff) + 0x8000) % (Rand() & 0xff) % (Rand() & 0xff) % (Rand() & 0xff);
result = sstream.str();
//#endif
return result;

View File

@ -463,6 +463,12 @@ namespace OOX
WritingElement_ReadAttributes_End( oReader )
//todo IsZero() is added to fix comments with zero ids(5.4.0)(bug 42947). Remove after few releases
if(id.IsInit() && id->IsZero())
{
id = L"{" + XmlUtils::GenerateGuid() + L"}";
}
}
public:
nullable_string ref;
@ -580,16 +586,38 @@ namespace OOX
m_mapTopLevelThreadedComments[pThreadedComment->id->ToString()] = pThreadedComment;
}
}
//to remove reply duplicates
std::unordered_map<std::wstring, bool> mapUniqueue;
//add Replies
for(size_t i = 0; i < m_arrItems.size(); ++i)
{
CThreadedComment* pThreadedComment = m_arrItems[i];
if(pThreadedComment->parentId.IsInit())
{
std::unordered_map<std::wstring, CThreadedComment*>::const_iterator oFind = m_mapTopLevelThreadedComments.find(pThreadedComment->parentId->ToString());
if(m_mapTopLevelThreadedComments.end() != oFind)
//todo IsZero() is added to fix comments with zero ids(5.4.0)(bug 42947). Remove after few releases
if(pThreadedComment->parentId->IsZero() && pThreadedComment->ref.IsInit())
{
oFind->second->m_arrReplies.push_back(pThreadedComment);
if (pThreadedComment->dT.IsInit() && mapUniqueue.find(pThreadedComment->dT->ToString()) == mapUniqueue.end())
{
mapUniqueue[pThreadedComment->dT->ToString()] = true;
//find parents by ref
for (std::unordered_map<std::wstring, CThreadedComment*>::const_iterator it = m_mapTopLevelThreadedComments.begin(); it != m_mapTopLevelThreadedComments.end(); ++it)
{
if (it->second->ref.IsInit() && pThreadedComment->ref.get() == it->second->ref.get())
{
it->second->m_arrReplies.push_back(pThreadedComment);
break;
}
}
}
}
else
{
std::unordered_map<std::wstring, CThreadedComment*>::const_iterator oFind = m_mapTopLevelThreadedComments.find(pThreadedComment->parentId->ToString());
if(m_mapTopLevelThreadedComments.end() != oFind)
{
oFind->second->m_arrReplies.push_back(pThreadedComment);
}
}
}
}

View File

@ -38,6 +38,7 @@ namespace OOX
namespace SpreadsheetCommon
{
std::wstring WriteDouble(double dVal);
const int MAX_STRING_LEN = 0x7FFF;
}
}
}

View File

@ -280,7 +280,22 @@ namespace OOX
if(pComment->m_oUid.IsInit())
{
pFind = pThreadedComments->m_mapTopLevelThreadedComments.find(pComment->m_oUid->ToString());
//todo IsZero() is added to fix comments with zero ids(5.4.0)(bug 42947). Remove after few releases
if(pComment->m_oUid->IsZero() && pComment->m_oRef.IsInit())
{
for (std::unordered_map<std::wstring, CThreadedComment*>::iterator it = pThreadedComments->m_mapTopLevelThreadedComments.begin(); it != pThreadedComments->m_mapTopLevelThreadedComments.end(); ++it)
{
if (it->second->ref.IsInit() && pComment->m_oRef->GetValue() == it->second->ref.get())
{
pFind = it;
break;
}
}
}
else
{
pFind = pThreadedComments->m_mapTopLevelThreadedComments.find(pComment->m_oUid->ToString());
}
}
else if(pComment->m_oAuthorId.IsInit())
{

View File

@ -1352,17 +1352,9 @@ void CFontList::LoadFromArrayFiles(std::vector<std::wstring>& oArray, int nFlag)
continue;
}
std::string sFamilyName = "";
if (NULL != pFace->family_name)
sFamilyName = pFace->family_name;
std::wstring wsFamilyName = GetCorrectSfntName(pFace->family_name);
std::wstring wsStyleName = GetCorrectSfntName(pFace->style_name);
std::string sStyleName = "";
if (NULL != pFace->style_name)
sStyleName = pFace->style_name;
std::wstring wsFamilyName = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(sFamilyName);
std::wstring wsStyleName = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(sStyleName);
#ifdef _MAC
if (wsFamilyName.find(L".") == 0)
{

View File

@ -682,9 +682,9 @@ void CFontFile::CheckHintsSupport()
return;
}
std::string sFamilyName((NULL != m_pFace->family_name) ? m_pFace->family_name : "");
std::wstring sFamilyName = GetCorrectSfntName(m_pFace->family_name);
if (sFamilyName == "MS Mincho" || sFamilyName == "Castellar")
if (m_sName == L"MS Mincho" || m_sName == L"Castellar")
m_bHintsSupport = FALSE;
}

View File

@ -44,6 +44,35 @@
#include "FontPath.h"
#include "GlyphString.h"
#include "../common/File.h"
static std::wstring GetCorrectSfntName(const char* name)
{
if (NULL == name)
return L"";
const char* name_cur = name;
int name_len = 0;
while (*name_cur++)
++name_len;
bool isUtf8 = false;
if (6 < name_len)
{
if ('<' == name[0] || 'u' == name[1] || 't' == name[2] ||
'f' == name[3] || '8' == name[4] || '>' == name[5])
{
name_cur = name + 6;
name_len -= 6;
isUtf8 = true;
}
}
if (isUtf8)
{
return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)name_cur, (LONG)name_len);
}
return NSFile::CUtf8Converter::GetUnicodeFromCharPtr(name_cur, (LONG)name_len);
}
//-------------------------------------------------------------------------------------------------------------------------------
// TODO: RasterHeep

View File

@ -686,9 +686,9 @@ INT CFontManager::LoadFontFromFile(const std::wstring& sPath, const int& lFaceIn
m_pFont->SetSizeAndDpi(dSize, (UINT)dDpiX, (UINT)dDpiY);
m_sName = L"";
if (m_pFont->m_pFace && m_pFont->m_pFace->family_name)
if (m_pFont->m_pFace)
{
m_pFont->m_sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)m_pFont->m_pFace->family_name, strlen(m_pFont->m_pFace->family_name));
m_pFont->m_sName = GetCorrectSfntName(m_pFont->m_pFace->family_name);
m_sName = m_pFont->m_sName;
}
@ -710,9 +710,10 @@ INT CFontManager::LoadFontFromFile2(NSFonts::IFontsCache* pCache, const std::wst
m_pFont->SetSizeAndDpi(dSize, (UINT)dDpiX, (UINT)dDpiY);
m_sName = L"";
if (m_pFont->m_pFace && m_pFont->m_pFace->family_name)
if (m_pFont->m_pFace)
{
m_sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)m_pFont->m_pFace->family_name, strlen(m_pFont->m_pFace->family_name));
m_pFont->m_sName = GetCorrectSfntName(m_pFont->m_pFace->family_name);
m_sName = m_pFont->m_sName;
}
return TRUE;

View File

@ -561,35 +561,28 @@ namespace NSCommon
}
else if (pFile)
{
// у нас режим "без квадратов"
// но есть шрифты, в которых символы есть, но нулевой ширины.
// только из-за таких шрифтов делаем заглушку
int nFontNameLen = (int)sFontName.length();
bool bIsPresentAll = true;
bool bIsExistEmpty = false;
for (int nC = 0; nC < nFontNameLen; nC++)
{
int nCMapIndex = 0;
int nGid = pFile->SetCMapForCharCode(sFontName.at(nC), &nCMapIndex);
if (0 >= nGid)
if (0 < nGid && 0.0001 > pFile->GetCharWidth(nGid))
{
bIsPresentAll = false;
bIsExistEmpty = true;
break;
}
else
{
double offsetG = pFile->GetCharWidth(nGid);
if (offsetG < 0.0001)
{
bIsPresentAll = false;
break;
}
}
}
if (!bIsPresentAll)
if (bIsExistEmpty)
{
NSFonts::CFontSelectFormat oSelectFormat;
oSelectFormat.wsName = new std::wstring(L"Arial");
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
NSFonts::CFontInfo* pInfoCur = pManager->GetFontInfoByParams(oSelectFormat);
if (NULL != pInfoCur)
{
pManager->LoadFontFromFile(pInfoCur->m_wsFontPath, 0, 14, dDpi, dDpi);

View File

@ -44,8 +44,138 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_sfobjs
#ifdef FT_SUPPORT_UTF8_IN_NAMES
// common funcs
static void tt_name_entry_unicode_from_utf16(FT_Byte* string, FT_UShort len, FT_Int** out, FT_UShort* out_len, FT_Memory memory)
{
FT_Int* unicode = NULL;
FT_UShort alloc_len = len / 2;
FT_UShort n = 0;
FT_UShort cur = 0, cur2 = 0;
FT_UShort out_len_cur = 0;
FT_Error error;
*out = NULL;
*out_len = 0;
if ( FT_NEW_ARRAY( unicode, alloc_len ) )
return;
for ( n = 0; n < alloc_len; n++ )
{
cur = FT_NEXT_USHORT( string );
if ( cur == 0 )
break;
if (cur < 0xD800 || cur > 0xDBFF)
{
unicode[out_len_cur++] = cur;
}
else
{
cur2 = FT_NEXT_USHORT( string );
++n;
unicode[out_len_cur++] = ((((cur - 0xD800) & 0x03FF) << 10) | ((cur2 - 0xDC00) & 0x03FF)) + 0x10000;
}
}
*out = unicode;
*out_len = out_len_cur;
}
static FT_String* tt_name_entry_utf8_from_unicode(FT_Int* unicode, FT_UShort len, FT_Memory memory)
{
FT_String* ret = NULL;
FT_String* retCur = NULL;
FT_UShort index = 0;
FT_UInt alloc_len = 6 * len + 6 + 1;
FT_Int code;
FT_Error error;
if (0 == len)
return ret;
if ( FT_NEW_ARRAY( ret, alloc_len ) )
return ret;
retCur = ret;
*retCur++ = '<';
*retCur++ = 'u';
*retCur++ = 't';
*retCur++ = 'f';
*retCur++ = '8';
*retCur++ = '>';
for ( index = 0; index < len; index++ )
{
code = unicode[index];
if (code < 0x80)
{
*retCur++ = (FT_String)code;
}
else if (code < 0x0800)
{
*retCur++ = (0xC0 | (code >> 6));
*retCur++ = (0x80 | (code & 0x3F));
}
else if (code < 0x10000)
{
*retCur++ = (0xE0 | (code >> 12));
*retCur++ = (0x80 | (code >> 6 & 0x3F));
*retCur++ = (0x80 | (code & 0x3F));
}
else if (code < 0x1FFFFF)
{
*retCur++ = (0xF0 | (code >> 18));
*retCur++ = (0x80 | (code >> 12 & 0x3F));
*retCur++ = (0x80 | (code >> 6 & 0x3F));
*retCur++ = (0x80 | (code & 0x3F));
}
else if (code < 0x3FFFFFF)
{
*retCur++ = (0xF8 | (code >> 24));
*retCur++ = (0x80 | (code >> 18 & 0x3F));
*retCur++ = (0x80 | (code >> 12 & 0x3F));
*retCur++ = (0x80 | (code >> 6 & 0x3F));
*retCur++ = (0x80 | (code & 0x3F));
}
else if (code < 0x7FFFFFFF)
{
*retCur++ = (0xFC | (code >> 30));
*retCur++ = (0x80 | (code >> 24 & 0x3F));
*retCur++ = (0x80 | (code >> 18 & 0x3F));
*retCur++ = (0x80 | (code >> 12 & 0x3F));
*retCur++ = (0x80 | (code >> 6 & 0x3F));
*retCur++ = (0x80 | (code & 0x3F));
}
}
*retCur = 0;
return ret;
}
// ft interface
static FT_String* tt_name_entry_utf8_from_utf16(TT_NameEntry entry,
FT_Memory memory)
{
FT_Int* unicode = NULL;
FT_UShort unicode_len = 0;
FT_String* retValue = NULL;
tt_name_entry_unicode_from_utf16(entry->string, entry->stringLength, &unicode, &unicode_len, memory);
retValue = tt_name_entry_utf8_from_unicode(unicode, unicode_len, memory);
FT_FREE(unicode);
return retValue;
}
/* convert a UTF-16 name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_utf16( TT_NameEntry entry,
FT_Memory memory )
{
return tt_name_entry_utf8_from_utf16(entry, memory);
}
#else
/* convert a UTF-16 name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_utf16( TT_NameEntry entry,
@ -79,7 +209,7 @@
return string;
}
#endif
/* convert an Apple Roman or symbol name entry to ASCII */
static FT_String*

View File

@ -32,6 +32,8 @@ DEFINES += \
MNG_STORE_CHUNKS\
MNG_ERROR_TELLTALE
DEFINES += FT_SUPPORT_UTF8_IN_NAMES
core_linux {
DEFINES += \
HAVE_UNISTD_H

View File

@ -3333,6 +3333,11 @@ void BinaryCommentReader::addThreadedComment(OOX::Spreadsheet::CSi& oSi, OOX::Sp
pText->m_sText.append(L"\n\n");
}
}
//Fix Excel recovery error
if (pText->m_sText.length() > OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN)
{
pText->m_sText.erase(OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN);
}
oSi.m_arrItems.push_back(pText);
}