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 ...@@ -129,6 +129,49 @@ namespace NSString
return s; 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 @@ ...@@ -13,6 +13,8 @@
#include "../../../fontengine/FontManager.h" #include "../../../fontengine/FontManager.h"
#include <iostream> #include <iostream>
#include "../Common/MetaFile.h" #include "../Common/MetaFile.h"
#include "../../../common/String.h"
#include "../../../common/File.h"
namespace MetaFile namespace MetaFile
{ {
...@@ -376,7 +378,6 @@ namespace MetaFile ...@@ -376,7 +378,6 @@ namespace MetaFile
return true; return true;
} }
void MoveTo(TEmfPointL& oPoint) void MoveTo(TEmfPointL& oPoint)
{ {
MoveTo(oPoint.x, oPoint.y); MoveTo(oPoint.x, oPoint.y);
...@@ -506,13 +507,58 @@ namespace MetaFile ...@@ -506,13 +507,58 @@ namespace MetaFile
if (!oText.OutputString) if (!oText.OutputString)
return SetError(); return SetError();
// TODO: Unicode. IFont* pFont = GetFont();
std::wstring wsText; NSString::CConverter::ESingleByteEncoding eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;
for (unsigned int unIndex = 0; unIndex < oText.Chars; unIndex++) 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]; default:
wsText += wUnicode; 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; int nTextW = 0;
bool bWithOutLast = false; bool bWithOutLast = false;
...@@ -538,7 +584,7 @@ namespace MetaFile ...@@ -538,7 +584,7 @@ namespace MetaFile
if (!oText.OutputString) if (!oText.OutputString)
return SetError(); return SetError();
std::wstring wsText((wchar_t*)oText.OutputString); std::wstring wsText = NSString::CConverter::GetUnicodeFromUTF16((unsigned short*)oText.OutputString, oText.Chars);
int nTextW = 0; int nTextW = 0;
bool bWithOutLast = false; bool bWithOutLast = false;
...@@ -1252,7 +1298,6 @@ namespace MetaFile ...@@ -1252,7 +1298,6 @@ namespace MetaFile
{ {
TEmfExtTextoutW oText; TEmfExtTextoutW oText;
m_oStream >> oText; m_oStream >> oText;
DrawTextW(oText.wEmrText); DrawTextW(oText.wEmrText);
} }
void Read_EMR_LINETO() void Read_EMR_LINETO()
......
...@@ -31,13 +31,7 @@ namespace MetaFile ...@@ -31,13 +31,7 @@ namespace MetaFile
TRectD GetBounds() TRectD GetBounds()
{ {
TRect oBB; TRectD oBounds = GetBoundingBox();
if (IsPlaceable())
oBB = m_oPlaceable.BoundingBox;
else
oBB = m_oBoundingBox;
TRectD oBounds = oBB;
if (IsPlaceable()) if (IsPlaceable())
{ {
double dLogicalToMM = 25.4 / 72; double dLogicalToMM = 25.4 / 72;
...@@ -332,6 +326,36 @@ namespace MetaFile ...@@ -332,6 +326,36 @@ namespace MetaFile
private: 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() bool IsPlaceable()
{ {
return (0x9AC6CDD7 == m_oPlaceable.Key); return (0x9AC6CDD7 == m_oPlaceable.Key);
...@@ -568,11 +592,7 @@ namespace MetaFile ...@@ -568,11 +592,7 @@ namespace MetaFile
// Во время сканирования мы регистрируем все точки и вычисляем BoundingBox // Во время сканирования мы регистрируем все точки и вычисляем BoundingBox
if (m_pOutput) if (m_pOutput)
{ {
if (IsPlaceable()) m_oRect = GetBoundingBox();
m_oRect = m_oPlaceable.BoundingBox;
else
m_oRect = m_oBoundingBox;
m_pDC->SetWindowOff(m_oRect.nLeft, m_oRect.nTop); m_pDC->SetWindowOff(m_oRect.nLeft, m_oRect.nTop);
m_pDC->SetWindowExt(m_oRect.nRight - m_oRect.nLeft, m_oRect.nBottom - m_oRect.nTop); m_pDC->SetWindowExt(m_oRect.nRight - m_oRect.nLeft, m_oRect.nBottom - m_oRect.nTop);
} }
...@@ -834,29 +854,41 @@ namespace MetaFile ...@@ -834,29 +854,41 @@ namespace MetaFile
pString[shStringLength] = 0x00; pString[shStringLength] = 0x00;
m_oStream.ReadBytes(pString, shStringLength); m_oStream.ReadBytes(pString, shStringLength);
short* pDx = NULL; int nTextW = 0;
if (GetRecordRemainingBytesCount() > shStringLength * 2) bool bWithOutLast = false;
if (shStringLength > 1 && ((GetRecordRemainingBytesCount() >= shStringLength * 2 && !(ushFwOptions & ETO_PDY)) || (GetRecordRemainingBytesCount() >= shStringLength * 4 && ushFwOptions & ETO_PDY)))
{ {
if (shStringLength & 1) // Если длина нечетная, тогда пропускаем 1 байт, т.к. тут прилегание по 2 байта if (shStringLength & 1) // Если длина нечетная, тогда пропускаем 1 байт, т.к. тут прилегание по 2 байта
m_oStream.Skip(1); m_oStream.Skip(1);
// TODO: Тут еще надо смотреть на ETO_PDY short shLetterW = 0;
pDx = new short[shStringLength + 1]; if (ushFwOptions & ETO_PDY)
if (!pDx)
{ {
delete[] pString; for (short shIndex = 0; shIndex < shStringLength; shIndex++)
return SetError(); {
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) if (pString)
delete[] pString; delete[] pString;
if (pDx)
delete[] pDx;
} }
void Read_META_FILLREGION() 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