Commit 8049a064 authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Добавлена функция для кроссплатформенной конвертации UTF16->Unicode...

Добавлена функция для кроссплатформенной конвертации  UTF16->Unicode (std::string). Исправлен баг в WMF, когда заданы плохие размеры.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62365 954022d7-b5bf-4e40-9824-e11837661b57
parent 320dce8d
......@@ -129,6 +129,49 @@ namespace NSString
return s;
}
static std::wstring GetUnicodeFromUTF16(const unsigned short* pData, LONG lCount)
{
if (0 == lCount)
return L"";
if (2 == sizeof(wchar_t))
return std::wstring((wchar_t*)pData, lCount);
wchar_t* pUnicode = new wchar_t[lCount + 1];
if (!pUnicode)
return L"";
wchar_t* pCur = pUnicode;
int nCurPos = 0;
while (nCurPos < lCount)
{
int nLeading = pData[nCurPos]; nCurPos++;
if (nLeading < 0xD800 || nLeading > 0xDFFF)
{
*pCur = (wchar_t)nLeading;
pCur++;
}
else
{
if (nCurPos >= lCount)
break;
int nTrailing = pData[nCurPos]; nCurPos++;
if (nTrailing >= 0xDC00 && nTrailing <= 0xDFFF)
{
*pCur = (wchar_t)(((nLeading & 0x03FF) << 10) | (nTrailing & 0x03FF));
pCur++;
}
}
}
if (0 == pCur - pUnicode)
return L"";
std::wstring sRet(pUnicode, pCur - pUnicode);
RELEASEARRAYOBJECTS(pUnicode);
return sRet;
}
};
};
......
......@@ -13,6 +13,8 @@
#include "../../../fontengine/FontManager.h"
#include <iostream>
#include "../Common/MetaFile.h"
#include "../../../common/String.h"
#include "../../../common/File.h"
namespace MetaFile
{
......@@ -376,7 +378,6 @@ namespace MetaFile
return true;
}
void MoveTo(TEmfPointL& oPoint)
{
MoveTo(oPoint.x, oPoint.y);
......@@ -506,13 +507,58 @@ namespace MetaFile
if (!oText.OutputString)
return SetError();
// TODO: Unicode.
std::wstring wsText;
for (unsigned int unIndex = 0; unIndex < oText.Chars; unIndex++)
IFont* pFont = GetFont();
NSString::CConverter::ESingleByteEncoding eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;
if (pFont)
{
// Charset -> Codepage: http://support.microsoft.com/kb/165478
// http://msdn.microsoft.com/en-us/library/cc194829.aspx
// Charset Name Charset Value(hex) Codepage number
// ------------------------------------------------------
//
// DEFAULT_CHARSET 1 (x01)
// SYMBOL_CHARSET 2 (x02)
// OEM_CHARSET 255 (xFF)
// ANSI_CHARSET 0 (x00) 1252
// RUSSIAN_CHARSET 204 (xCC) 1251
// EASTEUROPE_CHARSET 238 (xEE) 1250
// GREEK_CHARSET 161 (xA1) 1253
// TURKISH_CHARSET 162 (xA2) 1254
// BALTIC_CHARSET 186 (xBA) 1257
// HEBREW_CHARSET 177 (xB1) 1255
// ARABIC _CHARSET 178 (xB2) 1256
// SHIFTJIS_CHARSET 128 (x80) 932
// HANGEUL_CHARSET 129 (x81) 949
// GB2313_CHARSET 134 (x86) 936
// CHINESEBIG5_CHARSET 136 (x88) 950
// THAI_CHARSET 222 (xDE) 874
// JOHAB_CHARSET 130 (x82) 1361
// VIETNAMESE_CHARSET 163 (xA3) 1258
switch (pFont->GetCharSet())
{
wchar_t wUnicode = ((unsigned char*)oText.OutputString)[unIndex];
wsText += wUnicode;
}
default:
case DEFAULT_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break;
case SYMBOL_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break;
case ANSI_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break;
case RUSSIAN_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break;
case EASTEUROPE_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break;
case GREEK_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break;
case TURKISH_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break;
case BALTIC_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break;
case HEBREW_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break;
case ARABIC_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break;
case SHIFTJIS_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break;
case HANGEUL_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break;
case 134/*GB2313_CHARSET*/: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break;
case CHINESEBIG5_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break;
case THAI_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break;
case JOHAB_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break;
case VIETNAMESE_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break;
}
}
std::wstring wsText = NSString::CConverter::GetUnicodeFromSingleByteString((unsigned char*)oText.OutputString, oText.Chars, eCharSet);
int nTextW = 0;
bool bWithOutLast = false;
......@@ -538,7 +584,7 @@ namespace MetaFile
if (!oText.OutputString)
return SetError();
std::wstring wsText((wchar_t*)oText.OutputString);
std::wstring wsText = NSString::CConverter::GetUnicodeFromUTF16((unsigned short*)oText.OutputString, oText.Chars);
int nTextW = 0;
bool bWithOutLast = false;
......@@ -1252,7 +1298,6 @@ namespace MetaFile
{
TEmfExtTextoutW oText;
m_oStream >> oText;
DrawTextW(oText.wEmrText);
}
void Read_EMR_LINETO()
......
......@@ -31,13 +31,7 @@ namespace MetaFile
TRectD GetBounds()
{
TRect oBB;
if (IsPlaceable())
oBB = m_oPlaceable.BoundingBox;
else
oBB = m_oBoundingBox;
TRectD oBounds = oBB;
TRectD oBounds = GetBoundingBox();
if (IsPlaceable())
{
double dLogicalToMM = 25.4 / 72;
......@@ -332,6 +326,36 @@ namespace MetaFile
private:
TRect GetBoundingBox()
{
TRect oBB;
if (IsPlaceable())
{
oBB = m_oPlaceable.BoundingBox;
// Иногда m_oPlaceable.BoundingBox задается нулевой ширины и высоты
if (abs(oBB.nRight - oBB.nLeft) <= 1)
{
oBB.nRight = m_oBoundingBox.nRight;
oBB.nLeft = m_oBoundingBox.nLeft;
}
if (abs(oBB.nBottom - oBB.nTop) <= 1)
{
oBB.nTop = m_oBoundingBox.nTop;
oBB.nBottom = m_oBoundingBox.nBottom;
}
}
else
oBB = m_oBoundingBox;
if (abs(oBB.nRight - oBB.nLeft) <= 1)
oBB.nRight = oBB.nLeft + 1024;
if (abs(oBB.nBottom - oBB.nTop) <= 1)
oBB.nBottom = m_oBoundingBox.nTop + 1024;
return oBB;
}
bool IsPlaceable()
{
return (0x9AC6CDD7 == m_oPlaceable.Key);
......@@ -568,11 +592,7 @@ namespace MetaFile
// Во время сканирования мы регистрируем все точки и вычисляем BoundingBox
if (m_pOutput)
{
if (IsPlaceable())
m_oRect = m_oPlaceable.BoundingBox;
else
m_oRect = m_oBoundingBox;
m_oRect = GetBoundingBox();
m_pDC->SetWindowOff(m_oRect.nLeft, m_oRect.nTop);
m_pDC->SetWindowExt(m_oRect.nRight - m_oRect.nLeft, m_oRect.nBottom - m_oRect.nTop);
}
......@@ -834,29 +854,41 @@ namespace MetaFile
pString[shStringLength] = 0x00;
m_oStream.ReadBytes(pString, shStringLength);
short* pDx = NULL;
if (GetRecordRemainingBytesCount() > shStringLength * 2)
int nTextW = 0;
bool bWithOutLast = false;
if (shStringLength > 1 && ((GetRecordRemainingBytesCount() >= shStringLength * 2 && !(ushFwOptions & ETO_PDY)) || (GetRecordRemainingBytesCount() >= shStringLength * 4 && ushFwOptions & ETO_PDY)))
{
if (shStringLength & 1) // Если длина нечетная, тогда пропускаем 1 байт, т.к. тут прилегание по 2 байта
m_oStream.Skip(1);
// TODO: Тут еще надо смотреть на ETO_PDY
pDx = new short[shStringLength + 1];
if (!pDx)
short shLetterW = 0;
if (ushFwOptions & ETO_PDY)
{
delete[] pString;
return SetError();
for (short shIndex = 0; shIndex < shStringLength; shIndex++)
{
m_oStream >> shLetterW;
m_oStream.Skip(2);
nTextW += shLetterW;
}
}
else
{
for (short shIndex = 0; shIndex < shStringLength; shIndex++)
{
m_oStream >> shLetterW;
nTextW += shLetterW;
}
m_oStream.ReadBytes(pDx, shStringLength);
}
DrawText(pString, shStringLength, shX, shY, 0, false);
// Иногда у последнего символа не указывается ширина или она указывается неверное, поэтому не учитываем её.
nTextW -= shLetterW;
bWithOutLast = true;
}
DrawText(pString, shStringLength, shX, shY, nTextW, bWithOutLast);
if (pString)
delete[] pString;
if (pDx)
delete[] pDx;
}
void Read_META_FILLREGION()
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment