From 060eea09303757757bd8443ad61cc40605b677f1 Mon Sep 17 00:00:00 2001 From: "Ilya.Kirillov" Date: Fri, 10 Jul 2015 13:56:16 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D1=86=D0=B5=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BF=D0=B0=D1=80=D1=81=D0=B5=D1=80=20=D0=B0=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=B1=D1=83=D1=82=D0=BE=D0=B2=20Indices=20=D0=B8?= =?UTF-8?q?=20UnicodeString=20=D1=83=20=D0=BD=D0=BE=D0=B4=D1=8B=20Glyph.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63459 954022d7-b5bf-4e40-9824-e11837661b57 --- XpsFile/XpsLib/Page.cpp | 95 ++++++---- XpsFile/XpsLib/Page.h | 1 + XpsFile/XpsLib/Utils.cpp | 395 +++++++++++++++++++++++++++++++++------ XpsFile/XpsLib/Utils.h | 26 +++ 4 files changed, 427 insertions(+), 90 deletions(-) diff --git a/XpsFile/XpsLib/Page.cpp b/XpsFile/XpsLib/Page.cpp index 08fca95b9e..30250094cf 100644 --- a/XpsFile/XpsLib/Page.cpp +++ b/XpsFile/XpsLib/Page.cpp @@ -218,14 +218,18 @@ namespace XPS int nBgr = 0, nAlpha = 255; double dFontSize = 10.0; bool bTransform = false, bClip = false, bOpacity = false; - int nTextLen = 0; - std::wstring wsText; + unsigned int unTextLen = 0; double dX = 0; double dY = 0; std::wstring wsFontPath; std::wstring wsIndicies; int nBidiLevel = 0; CWString wsClip, wsTransform; + unsigned int* pUnicodes = NULL; + unsigned int* pUnicodesPtr = NULL; + + CWString wsUnicodeString, wsIndices; + if (oReader.MoveToFirstAttribute()) { std::wstring wsAttrName = oReader.GetName(); @@ -282,14 +286,20 @@ namespace XPS } else if (L"UnicodeString" == wsAttrName) { - wsText = oReader.GetText(); - nTextLen = wsText.length(); + wsUnicodeString.create(oReader.GetText(), true); - if (nTextLen >= 2 && '{' == wsText.at(0) && '}' == wsText.at(1)) + pUnicodesPtr = NSStringExt::CConverter::GetUtf32FromUnicode(wsUnicodeString.c_str(), unTextLen); + + if (unTextLen >= 2 && '{' == pUnicodesPtr[0] && '}' == pUnicodesPtr[1]) { - wsText = wsText.substr(2); - nTextLen -= 2; + pUnicodes = pUnicodesPtr + 2; + unTextLen -= 2; } + else + { + pUnicodes = pUnicodesPtr; + } + } else if (L"OriginX" == wsAttrName) { @@ -303,6 +313,7 @@ namespace XPS } else if (L"Indices" == wsAttrName) { + wsIndices.create(oReader.GetText(), true); wsIndicies = oReader.GetText(); } else if (L"BidiLevel" == wsAttrName) @@ -357,46 +368,60 @@ namespace XPS pRenderer->put_BrushType(c_BrushTypeSolid); pRenderer->put_FontSize(dFontSize * 0.75); - std::wstring wsChar = wsText.substr(0, 1); - std::vector> arrElements = Split(wsIndicies, L';', L','); + TIndicesEntry oEntry; + int nIndicesPos = 0, nIndicesLen = wsIndices.size(); + int nUtf16Pos = 0, nUtf16Len = wsUnicodeString.size(); + while (GetNextGlyph(wsIndices.c_str(), nIndicesPos, nIndicesLen, (unsigned short*)wsUnicodeString.c_str(), nUtf16Pos, nUtf16Len, oEntry)) + { + int k = 10; + k++; + } + std::vector> arrElements = Split(wsIndicies, L';', L','); bool bRtoL = (nBidiLevel % 2 ? true : false); m_pFontManager->LoadFontFromFile(wsFontPath, 0, (float)(dFontSize * 0.75), 96, 96); - for (int nIndex = 0; nIndex < nTextLen; nIndex++) + if (pUnicodesPtr) { - if (nIndex >= arrElements.size()) - arrElements.push_back(std::vector()); - - if (bRtoL) + for (int nIndex = 0; nIndex < unTextLen; nIndex++) { - if (arrElements.at(nIndex).size() >= 2) + std::wstring wsChar = NSStringExt::CConverter::GetUnicodeFromUTF32((const unsigned int*)(pUnicodes + nIndex), 1); + if (nIndex >= arrElements.size()) + arrElements.push_back(std::vector()); + + if (bRtoL) { - dX -= GetDouble(arrElements.at(nIndex).at(1)) * dFontSize / 100.0; + if (arrElements.at(nIndex).size() >= 2) + { + dX -= GetDouble(arrElements.at(nIndex).at(1)) * dFontSize / 100.0; + } + else + { + m_pFontManager->LoadString1(wsChar, 0, 0); + TBBox oBox = m_pFontManager->MeasureString2(); + dX -= (oBox.fMaxX - oBox.fMinX); + } + pRenderer->CommandDrawTextEx(wsChar, L"", xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0, 0); } else { - m_pFontManager->LoadString1(wsChar, 0, 0); - TBBox oBox = m_pFontManager->MeasureString2(); - dX -= (oBox.fMaxX - oBox.fMinX); - } - pRenderer->CommandDrawText(wsChar, xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0); - } - else - { - pRenderer->CommandDrawText(wsChar, xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0); - if (arrElements.at(nIndex).size() >= 2) - { - dX += GetDouble(arrElements.at(nIndex).at(1)) * dFontSize / 100.0; - } - else - { - m_pFontManager->LoadString1(wsChar, 0, 0); - TBBox oBox = m_pFontManager->MeasureString2(); - dX += (oBox.fMaxX - oBox.fMinX); + pRenderer->CommandDrawTextEx(wsChar, L"", xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0, 0); + if (nIndex < unTextLen - 1) + { + if (arrElements.at(nIndex).size() >= 2) + { + dX += GetDouble(arrElements.at(nIndex).at(1)) * dFontSize / 100.0; + } + else + { + m_pFontManager->LoadString1(wsChar, 0, 0); + TBBox oBox = m_pFontManager->MeasureString2(); + dX += (oBox.fMaxX - oBox.fMinX); + } + } } } - wsChar = wsText.substr(nIndex + 1, 1); + delete[] pUnicodesPtr; } if (bClip) diff --git a/XpsFile/XpsLib/Page.h b/XpsFile/XpsLib/Page.h index 781bd53523..ae640c5159 100644 --- a/XpsFile/XpsLib/Page.h +++ b/XpsFile/XpsLib/Page.h @@ -41,6 +41,7 @@ namespace XPS CWString ReadMatrixTransform(XmlUtils::CXmlLiteReader& oReader); CWString ReadClip (XmlUtils::CXmlLiteReader& oReader); + private: std::wstring m_wsPagePath; diff --git a/XpsFile/XpsLib/Utils.cpp b/XpsFile/XpsLib/Utils.cpp index 96654aa155..af8b2cb74a 100644 --- a/XpsFile/XpsLib/Utils.cpp +++ b/XpsFile/XpsLib/Utils.cpp @@ -34,6 +34,24 @@ namespace XPS { static inline bool SkipWhiteSpaces(const wchar_t* wsString, int& nPos, const int& nLen) + { + while (1) + { + if (nPos >= nLen) + return false; + wchar_t wChar = LookChar(wsString, nPos); + if (' ' == wChar) + { + nPos++; + continue; + } + else + break; + } + + return true; + } + static inline bool SkipWhiteSpacesAndCommas(const wchar_t* wsString, int& nPos, const int& nLen) { while (1) { @@ -51,9 +69,9 @@ namespace XPS return true; } - static inline double GetNumber(const wchar_t* wsString, int& nPos, const int& nLen) + static inline double GetDouble(const wchar_t* wsString, int& nPos, const int& nLen) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) return 0.0; wchar_t wChar = GetChar(wsString, nPos); @@ -116,9 +134,48 @@ namespace XPS return 0.0; } - static inline bool GetBool(const wchar_t* wsString, int& nPos, const int& nLen) + static inline int GetInt (const wchar_t* wsString, int& nPos, const int& nLen) { if (!SkipWhiteSpaces(wsString, nPos, nLen)) + return 0; + + wchar_t wChar = GetChar(wsString, nPos); + if (IsNumber(wChar)) + { + bool bNegative = false; + int nInt = 0; + + if ('-' == wChar) + { + bNegative = true; + } + else + { + nInt = wChar - '0'; + } + + while (1) + { + wChar = LookChar(wsString, nPos); + if (isdigit(wChar)) + { + nPos++; + nInt = nInt * 10 + (wChar - '0'); + } + else + { + break; + } + } + + return (bNegative ? -nInt : nInt); + } + + return 0; + } + static inline bool GetBool(const wchar_t* wsString, int& nPos, const int& nLen) + { + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) return false; int nBufPos = 0; @@ -149,15 +206,15 @@ namespace XPS double x_cur_temp = dCurX; double y_cur_temp = dCurY; - double rx = GetNumber(wsString, nPos, nLen); - double ry = GetNumber(wsString, nPos, nLen); - double angle = GetNumber(wsString, nPos, nLen); + double rx = GetDouble(wsString, nPos, nLen); + double ry = GetDouble(wsString, nPos, nLen); + double angle = GetDouble(wsString, nPos, nLen); bool isLarge = GetBool(wsString, nPos, nLen); bool isCCW = !GetBool(wsString, nPos, nLen); - double x_end = GetNumber(wsString, nPos, nLen); - double y_end = GetNumber(wsString, nPos, nLen); + double x_end = GetDouble(wsString, nPos, nLen); + double y_end = GetDouble(wsString, nPos, nLen); tmatx.Translate(-dCurX, -dCurY); tmatx.TransformPoint(x_cur_temp, y_cur_temp); @@ -664,7 +721,7 @@ namespace XPS wchar_t wChar = 0x00; while (nPos < nLen) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; wChar = GetChar(wsString, nPos); @@ -672,7 +729,7 @@ namespace XPS { case 'F': { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; bWinding = GetBool(wsString, nPos, nLen); @@ -681,16 +738,16 @@ namespace XPS } case 'm': { - dCurX += GetNumber(wsString, nPos, nLen); - dCurY += GetNumber(wsString, nPos, nLen); + dCurX += GetDouble(wsString, nPos, nLen); + dCurY += GetDouble(wsString, nPos, nLen); pRenderer->PathCommandMoveTo(xpsUnitToMM(dCurX), xpsUnitToMM(dCurY)); bPrevCommandIsCurve = false; break; } case 'M': { - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); pRenderer->PathCommandMoveTo(xpsUnitToMM(dCurX), xpsUnitToMM(dCurY)); bPrevCommandIsCurve = false; break; @@ -704,7 +761,7 @@ namespace XPS { while (true) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; if (IsNumber(LookChar(wsString, nPos))) @@ -713,34 +770,34 @@ namespace XPS { case 'L': { - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); break; } case 'l': { - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); break; } case 'H': { - dCurX = GetNumber(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); break; } case 'h': { - dCurX += GetNumber(wsString, nPos, nLen); + dCurX += GetDouble(wsString, nPos, nLen); break; } case 'V': { - dCurY = GetNumber(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); break; } case 'v': { - dCurY += GetNumber(wsString, nPos, nLen); + dCurY += GetDouble(wsString, nPos, nLen); break; } } @@ -759,7 +816,7 @@ namespace XPS { while (true) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; if (IsNumber(LookChar(wsString, nPos))) @@ -775,7 +832,7 @@ namespace XPS { while (true) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; if (IsNumber(LookChar(wsString, nPos))) @@ -783,21 +840,21 @@ namespace XPS double dX1, dY1, dX2, dY2; if ('c' == wChar) { - dX1 = dCurX + GetNumber(wsString, nPos, nLen); - dY1 = dCurY + GetNumber(wsString, nPos, nLen); - dX2 = dCurX + GetNumber(wsString, nPos, nLen); - dY2 = dCurY + GetNumber(wsString, nPos, nLen); - dCurX += GetNumber(wsString, nPos, nLen); - dCurY += GetNumber(wsString, nPos, nLen); + dX1 = dCurX + GetDouble(wsString, nPos, nLen); + dY1 = dCurY + GetDouble(wsString, nPos, nLen); + dX2 = dCurX + GetDouble(wsString, nPos, nLen); + dY2 = dCurY + GetDouble(wsString, nPos, nLen); + dCurX += GetDouble(wsString, nPos, nLen); + dCurY += GetDouble(wsString, nPos, nLen); } else { - dX1 = GetNumber(wsString, nPos, nLen); - dY1 = GetNumber(wsString, nPos, nLen); - dX2 = GetNumber(wsString, nPos, nLen); - dY2 = GetNumber(wsString, nPos, nLen); - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dX1 = GetDouble(wsString, nPos, nLen); + dY1 = GetDouble(wsString, nPos, nLen); + dX2 = GetDouble(wsString, nPos, nLen); + dY2 = GetDouble(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); } pRenderer->PathCommandCurveTo(xpsUnitToMM(dX1), xpsUnitToMM(dY1), xpsUnitToMM(dX2), xpsUnitToMM(dY2), xpsUnitToMM(dCurX), xpsUnitToMM(dCurY)); dCpX = dX2; @@ -814,7 +871,7 @@ namespace XPS { while (true) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; if (IsNumber(LookChar(wsString, nPos))) @@ -822,17 +879,17 @@ namespace XPS double dX1, dY1; if ('q' == wChar) { - dX1 = dCurX + GetNumber(wsString, nPos, nLen); - dY1 = dCurY + GetNumber(wsString, nPos, nLen); - dCurX += GetNumber(wsString, nPos, nLen); - dCurY += GetNumber(wsString, nPos, nLen); + dX1 = dCurX + GetDouble(wsString, nPos, nLen); + dY1 = dCurY + GetDouble(wsString, nPos, nLen); + dCurX += GetDouble(wsString, nPos, nLen); + dCurY += GetDouble(wsString, nPos, nLen); } else { - dX1 = GetNumber(wsString, nPos, nLen); - dY1 = GetNumber(wsString, nPos, nLen); - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dX1 = GetDouble(wsString, nPos, nLen); + dY1 = GetDouble(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); } pRenderer->PathCommandCurveTo(xpsUnitToMM(dX1), xpsUnitToMM(dY1), xpsUnitToMM(dX1), xpsUnitToMM(dY1), xpsUnitToMM(dCurX), xpsUnitToMM(dCurY)); } @@ -847,7 +904,7 @@ namespace XPS { while (true) { - if (!SkipWhiteSpaces(wsString, nPos, nLen)) + if (!SkipWhiteSpacesAndCommas(wsString, nPos, nLen)) break; if (IsNumber(LookChar(wsString, nPos))) @@ -866,17 +923,17 @@ namespace XPS if ('s' == wChar) { - dX2 = dCurX + GetNumber(wsString, nPos, nLen); - dY2 = dCurX + GetNumber(wsString, nPos, nLen); - dCurX += GetNumber(wsString, nPos, nLen); - dCurY += GetNumber(wsString, nPos, nLen); + dX2 = dCurX + GetDouble(wsString, nPos, nLen); + dY2 = dCurX + GetDouble(wsString, nPos, nLen); + dCurX += GetDouble(wsString, nPos, nLen); + dCurY += GetDouble(wsString, nPos, nLen); } else { - dX2 = GetNumber(wsString, nPos, nLen); - dY2 = GetNumber(wsString, nPos, nLen); - dCurX = GetNumber(wsString, nPos, nLen); - dCurY = GetNumber(wsString, nPos, nLen); + dX2 = GetDouble(wsString, nPos, nLen); + dY2 = GetDouble(wsString, nPos, nLen); + dCurX = GetDouble(wsString, nPos, nLen); + dCurY = GetDouble(wsString, nPos, nLen); } pRenderer->PathCommandCurveTo(xpsUnitToMM(dX1), xpsUnitToMM(dY1), xpsUnitToMM(dX2), xpsUnitToMM(dY2), xpsUnitToMM(dCurX), xpsUnitToMM(dCurY)); @@ -901,4 +958,232 @@ namespace XPS return bWinding; } + bool GetNextGlyph(const wchar_t* wsIndices, int& nIndicesPos, const int& nIndicesLen, unsigned short* pUtf16, int& nUtf16Pos, const int& nUtf16Len, TIndicesEntry& oEntry) + { + if (!wsIndices || nIndicesPos >= nIndicesLen) + { + if (!pUtf16 || nUtf16Pos >= nUtf16Len) + return false; + + oEntry.nUnicode = pUtf16[nUtf16Pos++]; + oEntry.bUnicode = true; + oEntry.bGid = false; + oEntry.bAdvance = false; + oEntry.bHorOffset = false; + oEntry.bVerOffset = false; + return true; + } + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + wchar_t wChar = LookChar(wsIndices, nIndicesPos); + + int nCodeUnitCount = -1, nGlyphCount = -1; + if ('(' == wChar) + { + nIndicesPos++; + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + wChar = LookChar(wsIndices, nIndicesPos); + if (IsNumber(wChar)) + nCodeUnitCount = GetInt(wsIndices, nIndicesPos, nIndicesLen); + else + nCodeUnitCount = 1; + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + wChar = LookChar(wsIndices, nIndicesPos); + if (':' == wChar) + { + nIndicesPos++; + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + wChar = LookChar(wsIndices, nIndicesPos); + if (IsNumber(wChar)) + nGlyphCount = GetInt(wsIndices, nIndicesPos, nIndicesLen); + else + nGlyphCount = 1; + } + else + return false; + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + wChar = LookChar(wsIndices, nIndicesPos); + if (')' != wChar) + return false; // Такого не должно быть + + nIndicesPos++; + } + + if (nCodeUnitCount > 0 && nGlyphCount > 0) + { + oEntry.vRemainUnicodes.clear(); + // Нам нужно прочитать сколько реальных юникодных значений лежит в + // промежутке [pUnicode + nUnicodePos, pUnicode + nUnicodePos + nCodeUnitCount] + int nUnicodesCount = 0; + unsigned int* pUnicodes = NULL; + nCodeUnitCount = min(nUtf16Len - nUtf16Pos, nCodeUnitCount); + nUtf16Pos += nCodeUnitCount; + if (nCodeUnitCount) + { + pUnicodes = new unsigned int[nCodeUnitCount]; + if (!pUnicodes) + return false; + + unsigned short ushLeading, ushTraling; + unsigned int unCode; + int nCodeUnitPos = 0; + while (nCodeUnitPos < nCodeUnitCount) + { + ushLeading = pUtf16[nUtf16Pos + nCodeUnitPos++]; + if (ushLeading < 0xD800 || ushLeading > 0xDFFF) + { + pUnicodes[nUnicodesCount++] = (unsigned int)ushLeading; + } + else if (ushLeading >= 0xDC00) + { + // Такого не должно быть + continue; + } + else + { + if (nCodeUnitPos >= nCodeUnitCount) + break; + + unCode = (ushLeading & 0x3FF) << 10; + ushTraling = pUtf16[nUtf16Pos + nCodeUnitPos++]; + if (ushTraling < 0xDC00 || ushTraling > 0xDFFF) + { + // Такого не должно быть + continue; + } + else + { + pUnicodes[nUnicodesCount++] = (unCode | (ushTraling & 0x3FF) + 0x10000); + } + } + } + } + + // Равномерно распределяем юникоды по глифам, в идеале их количество должно совпадать. + // Если юникодов больше, то лишние удаляем, если их меньше, то недостающие заполняем пробелами. + nUnicodesCount = min(nUnicodesCount, nGlyphCount); + for (int nIndex = 0; nIndex < nGlyphCount; nIndex++) + { + if (nIndex < nUnicodesCount) + oEntry.vRemainUnicodes.push_back(pUnicodes[nIndex]); + else + oEntry.vRemainUnicodes.push_back(0x20); + } + + if (pUnicodes) + delete[] pUnicodes; + } + + if (oEntry.vRemainUnicodes.size() <= 0) + return false; + + // Теперь мы читаем ровно 1 глиф с возможными метриками + oEntry.nUnicode = oEntry.vRemainUnicodes.at(0); + oEntry.vRemainUnicodes.erase(oEntry.vRemainUnicodes.begin()); + + wChar = LookChar(wsIndices, nIndicesPos); + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return false; + + if (IsNumber(wChar)) + { + oEntry.nGid = GetInt(wsIndices, nIndicesPos, nIndicesLen); + oEntry.bGid = true; + } + else + { + oEntry.bGid = false; + } + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (',' == wChar) + { + nIndicesPos++; + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (IsNumber(wChar)) + { + oEntry.dAdvance = GetDouble(wsIndices, nIndicesPos, nIndicesLen); + oEntry.bAdvance = true; + } + else + { + oEntry.bAdvance = false; + } + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (',' == wChar) + { + nIndicesPos++; + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (IsNumber(wChar)) + { + oEntry.dHorOffset = GetDouble(wsIndices, nIndicesPos, nIndicesLen); + oEntry.bHorOffset = true; + } + else + { + oEntry.bHorOffset = false; + } + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (',' == wChar) + { + nIndicesPos++; + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (IsNumber(wChar)) + { + oEntry.dVerOffset = GetDouble(wsIndices, nIndicesPos, nIndicesLen); + oEntry.bVerOffset = true; + } + else + { + oEntry.bVerOffset = false; + } + } + } + } + + if (!SkipWhiteSpaces(wsIndices, nIndicesPos, nIndicesLen)) + return true; + + wChar = LookChar(wsIndices, nIndicesPos); + if (';' == wChar) + { + nIndicesPos++; + return true; + } + else + return false; // Такого не должно быть + } } \ No newline at end of file diff --git a/XpsFile/XpsLib/Utils.h b/XpsFile/XpsLib/Utils.h index 59cb2202b5..f689190bfa 100644 --- a/XpsFile/XpsLib/Utils.h +++ b/XpsFile/XpsLib/Utils.h @@ -41,6 +41,31 @@ namespace XPS unsigned int m_unLen; bool m_bOwnBuffer; }; + struct TIndicesEntry + { + public: + + TIndicesEntry() : nUnicode(0), nGid(0), dAdvance(0.0), dHorOffset(0.0), dVerOffset(0.0), + bUnicode(false), bGid(false), bAdvance(false), bHorOffset(false), bVerOffset(false) + { + } + + public: + + unsigned int nUnicode; + unsigned short nGid; + double dAdvance; + double dHorOffset; + double dVerOffset; + + bool bUnicode; + bool bGid; + bool bAdvance; + bool bHorOffset; + bool bVerOffset; + + std::vector vRemainUnicodes; + }; bool IsAlpha(wchar_t wChar); @@ -62,6 +87,7 @@ namespace XPS void ReadAttribute(XmlUtils::CXmlLiteReader& oReader, const wchar_t* wsAttrName, std::wstring& wsAttr); void ReadAttribute(XmlUtils::CXmlLiteReader& oReader, const wchar_t* wsAttrName, CWString& wsAttr); bool VmlToRenderer(const wchar_t* wsString, IRenderer* pRenderer); + bool GetNextGlyph(const wchar_t* wsIndices, int& nIndicesPos, const int& nIndicesLen, unsigned short* pUtf16, int& nUtf16Pos, const int& nUtf16Len, TIndicesEntry& oEntry); } #endif // _XPS_XPSLIB_UTILS_H \ No newline at end of file